]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
Fix ICE on empty FIQ interrupt handler on ARM
[thirdparty/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 ;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4 ;; and Martin Simmons (@harleqn.co.uk).
5 ;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published
11 ;; by the Free Software Foundation; either version 3, or (at your
12 ;; option) any later version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 \f
26 ;;---------------------------------------------------------------------------
27 ;; Constants
28
29 ;; Register numbers -- All machine registers should be defined here
30 (define_constants
31 [(R0_REGNUM 0) ; First CORE register
32 (R1_REGNUM 1) ; Second CORE register
33 (IP_REGNUM 12) ; Scratch register
34 (SP_REGNUM 13) ; Stack pointer
35 (LR_REGNUM 14) ; Return address register
36 (PC_REGNUM 15) ; Program counter
37 (LAST_ARM_REGNUM 15) ;
38 (CC_REGNUM 100) ; Condition code pseudo register
39 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
40 ]
41 )
42 ;; 3rd operand to select_dominance_cc_mode
43 (define_constants
44 [(DOM_CC_X_AND_Y 0)
45 (DOM_CC_NX_OR_Y 1)
46 (DOM_CC_X_OR_Y 2)
47 ]
48 )
49 ;; conditional compare combination
50 (define_constants
51 [(CMP_CMP 0)
52 (CMN_CMP 1)
53 (CMP_CMN 2)
54 (CMN_CMN 3)
55 (NUM_OF_COND_CMP 4)
56 ]
57 )
58
59 \f
60 ;;---------------------------------------------------------------------------
61 ;; Attributes
62
63 ;; Processor type. This is created automatically from arm-cores.def.
64 (include "arm-tune.md")
65
66 ;; Instruction classification types
67 (include "types.md")
68
69 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
70 ; generating ARM code. This is used to control the length of some insn
71 ; patterns that share the same RTL in both ARM and Thumb code.
72 (define_attr "is_thumb" "yes,no"
73 (const (if_then_else (symbol_ref "TARGET_THUMB")
74 (const_string "yes") (const_string "no"))))
75
76 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
77 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
78
79 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
80 (define_attr "is_thumb1" "yes,no"
81 (const (if_then_else (symbol_ref "TARGET_THUMB1")
82 (const_string "yes") (const_string "no"))))
83
84 ; We use this attribute to disable alternatives that can produce 32-bit
85 ; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
86 ; that contain 32-bit instructions.
87 (define_attr "enabled_for_depr_it" "no,yes" (const_string "yes"))
88
89 ; This attribute is used to disable a predicated alternative when we have
90 ; arm_restrict_it.
91 (define_attr "predicable_short_it" "no,yes" (const_string "yes"))
92
93 ;; Operand number of an input operand that is shifted. Zero if the
94 ;; given instruction does not shift one of its input operands.
95 (define_attr "shift" "" (const_int 0))
96
97 ;; [For compatibility with AArch64 in pipeline models]
98 ;; Attribute that specifies whether or not the instruction touches fp
99 ;; registers.
100 (define_attr "fp" "no,yes" (const_string "no"))
101
102 ; Floating Point Unit. If we only have floating point emulation, then there
103 ; is no point in scheduling the floating point insns. (Well, for best
104 ; performance we should try and group them together).
105 (define_attr "fpu" "none,vfp"
106 (const (symbol_ref "arm_fpu_attr")))
107
108 ; Predicated means that the insn form is conditionally executed based on a
109 ; predicate. We default to 'no' because no Thumb patterns match this rule
110 ; and not all ARM insns do.
111 (define_attr "predicated" "yes,no" (const_string "no"))
112
113 ; LENGTH of an instruction (in bytes)
114 (define_attr "length" ""
115 (const_int 4))
116
117 ; The architecture which supports the instruction (or alternative).
118 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
119 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
120 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
121 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
122 ; Baseline. This attribute is used to compute attribute "enabled",
123 ; use type "any" to enable an alternative in all cases.
124 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
125 (const_string "any"))
126
127 (define_attr "arch_enabled" "no,yes"
128 (cond [(eq_attr "arch" "any")
129 (const_string "yes")
130
131 (and (eq_attr "arch" "a")
132 (match_test "TARGET_ARM"))
133 (const_string "yes")
134
135 (and (eq_attr "arch" "t")
136 (match_test "TARGET_THUMB"))
137 (const_string "yes")
138
139 (and (eq_attr "arch" "t1")
140 (match_test "TARGET_THUMB1"))
141 (const_string "yes")
142
143 (and (eq_attr "arch" "t2")
144 (match_test "TARGET_THUMB2"))
145 (const_string "yes")
146
147 (and (eq_attr "arch" "32")
148 (match_test "TARGET_32BIT"))
149 (const_string "yes")
150
151 (and (eq_attr "arch" "v6")
152 (match_test "TARGET_32BIT && arm_arch6"))
153 (const_string "yes")
154
155 (and (eq_attr "arch" "nov6")
156 (match_test "TARGET_32BIT && !arm_arch6"))
157 (const_string "yes")
158
159 (and (eq_attr "arch" "v6t2")
160 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
161 (const_string "yes")
162
163 (and (eq_attr "arch" "v8mb")
164 (match_test "TARGET_THUMB1 && arm_arch8"))
165 (const_string "yes")
166
167 (and (eq_attr "arch" "avoid_neon_for_64bits")
168 (match_test "TARGET_NEON")
169 (not (match_test "TARGET_PREFER_NEON_64BITS")))
170 (const_string "yes")
171
172 (and (eq_attr "arch" "neon_for_64bits")
173 (match_test "TARGET_NEON")
174 (match_test "TARGET_PREFER_NEON_64BITS"))
175 (const_string "yes")
176
177 (and (eq_attr "arch" "iwmmxt2")
178 (match_test "TARGET_REALLY_IWMMXT2"))
179 (const_string "yes")
180
181 (and (eq_attr "arch" "armv6_or_vfpv3")
182 (match_test "arm_arch6 || TARGET_VFP3"))
183 (const_string "yes")
184
185 (and (eq_attr "arch" "neon")
186 (match_test "TARGET_NEON"))
187 (const_string "yes")
188 ]
189
190 (const_string "no")))
191
192 (define_attr "opt" "any,speed,size"
193 (const_string "any"))
194
195 (define_attr "opt_enabled" "no,yes"
196 (cond [(eq_attr "opt" "any")
197 (const_string "yes")
198
199 (and (eq_attr "opt" "speed")
200 (match_test "optimize_function_for_speed_p (cfun)"))
201 (const_string "yes")
202
203 (and (eq_attr "opt" "size")
204 (match_test "optimize_function_for_size_p (cfun)"))
205 (const_string "yes")]
206 (const_string "no")))
207
208 (define_attr "use_literal_pool" "no,yes"
209 (cond [(and (eq_attr "type" "f_loads,f_loadd")
210 (match_test "CONSTANT_P (operands[1])"))
211 (const_string "yes")]
212 (const_string "no")))
213
214 ; Enable all alternatives that are both arch_enabled and insn_enabled.
215 ; FIXME:: opt_enabled has been temporarily removed till the time we have
216 ; an attribute that allows the use of such alternatives.
217 ; This depends on caching of speed_p, size_p on a per
218 ; alternative basis. The problem is that the enabled attribute
219 ; cannot depend on any state that is not cached or is not constant
220 ; for a compilation unit. We probably need a generic "hot/cold"
221 ; alternative which if implemented can help with this. We disable this
222 ; until such a time as this is implemented and / or the improvements or
223 ; regressions with removing this attribute are double checked.
224 ; See ashldi3_neon and <shift>di3_neon in neon.md.
225
226 (define_attr "enabled" "no,yes"
227 (cond [(and (eq_attr "predicable_short_it" "no")
228 (and (eq_attr "predicated" "yes")
229 (match_test "arm_restrict_it")))
230 (const_string "no")
231
232 (and (eq_attr "enabled_for_depr_it" "no")
233 (match_test "arm_restrict_it"))
234 (const_string "no")
235
236 (and (eq_attr "use_literal_pool" "yes")
237 (match_test "arm_disable_literal_pool"))
238 (const_string "no")
239
240 (eq_attr "arch_enabled" "no")
241 (const_string "no")]
242 (const_string "yes")))
243
244 ; POOL_RANGE is how far away from a constant pool entry that this insn
245 ; can be placed. If the distance is zero, then this insn will never
246 ; reference the pool.
247 ; Note that for Thumb constant pools the PC value is rounded down to the
248 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
249 ; Thumb insns) should be set to <max_range> - 2.
250 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
251 ; before its address. It is set to <max_range> - (8 + <data_size>).
252 (define_attr "arm_pool_range" "" (const_int 0))
253 (define_attr "thumb2_pool_range" "" (const_int 0))
254 (define_attr "arm_neg_pool_range" "" (const_int 0))
255 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
256
257 (define_attr "pool_range" ""
258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
259 (attr "arm_pool_range")))
260 (define_attr "neg_pool_range" ""
261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
262 (attr "arm_neg_pool_range")))
263
264 ; An assembler sequence may clobber the condition codes without us knowing.
265 ; If such an insn references the pool, then we have no way of knowing how,
266 ; so use the most conservative value for pool_range.
267 (define_asm_attributes
268 [(set_attr "conds" "clob")
269 (set_attr "length" "4")
270 (set_attr "pool_range" "250")])
271
272 ; Load scheduling, set from the arm_ld_sched variable
273 ; initialized by arm_option_override()
274 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
275
276 ; condition codes: this one is used by final_prescan_insn to speed up
277 ; conditionalizing instructions. It saves having to scan the rtl to see if
278 ; it uses or alters the condition codes.
279 ;
280 ; USE means that the condition codes are used by the insn in the process of
281 ; outputting code, this means (at present) that we can't use the insn in
282 ; inlined branches
283 ;
284 ; SET means that the purpose of the insn is to set the condition codes in a
285 ; well defined manner.
286 ;
287 ; CLOB means that the condition codes are altered in an undefined manner, if
288 ; they are altered at all
289 ;
290 ; UNCONDITIONAL means the instruction can not be conditionally executed and
291 ; that the instruction does not use or alter the condition codes.
292 ;
293 ; NOCOND means that the instruction does not use or alter the condition
294 ; codes but can be converted into a conditionally exectuted instruction.
295
296 (define_attr "conds" "use,set,clob,unconditional,nocond"
297 (if_then_else
298 (ior (eq_attr "is_thumb1" "yes")
299 (eq_attr "type" "call"))
300 (const_string "clob")
301 (if_then_else (eq_attr "is_neon_type" "no")
302 (const_string "nocond")
303 (const_string "unconditional"))))
304
305 ; Predicable means that the insn can be conditionally executed based on
306 ; an automatically added predicate (additional patterns are generated by
307 ; gen...). We default to 'no' because no Thumb patterns match this rule
308 ; and not all ARM patterns do.
309 (define_attr "predicable" "no,yes" (const_string "no"))
310
311 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
312 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
313 ; suffer blockages enough to warrant modelling this (and it can adversely
314 ; affect the schedule).
315 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
316
317 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
318 ; to stall the processor. Used with model_wbuf above.
319 (define_attr "write_conflict" "no,yes"
320 (if_then_else (eq_attr "type"
321 "block,call,load1")
322 (const_string "yes")
323 (const_string "no")))
324
325 ; Classify the insns into those that take one cycle and those that take more
326 ; than one on the main cpu execution unit.
327 (define_attr "core_cycles" "single,multi"
328 (if_then_else (eq_attr "type"
329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
345 (const_string "single")
346 (const_string "multi")))
347
348 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
349 ;; distant label. Only applicable to Thumb code.
350 (define_attr "far_jump" "yes,no" (const_string "no"))
351
352
353 ;; The number of machine instructions this pattern expands to.
354 ;; Used for Thumb-2 conditional execution.
355 (define_attr "ce_count" "" (const_int 1))
356
357 ;;---------------------------------------------------------------------------
358 ;; Unspecs
359
360 (include "unspecs.md")
361
362 ;;---------------------------------------------------------------------------
363 ;; Mode iterators
364
365 (include "iterators.md")
366
367 ;;---------------------------------------------------------------------------
368 ;; Predicates
369
370 (include "predicates.md")
371 (include "constraints.md")
372
373 ;;---------------------------------------------------------------------------
374 ;; Pipeline descriptions
375
376 (define_attr "tune_cortexr4" "yes,no"
377 (const (if_then_else
378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
379 (const_string "yes")
380 (const_string "no"))))
381
382 ;; True if the generic scheduling description should be used.
383
384 (define_attr "generic_sched" "yes,no"
385 (const (if_then_else
386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
387 arm926ejs,arm1020e,arm1026ejs,arm1136js,\
388 arm1136jfs,cortexa5,cortexa7,cortexa8,\
389 cortexa9,cortexa12,cortexa15,cortexa17,\
390 cortexa53,cortexa57,cortexm4,cortexm7,\
391 exynosm1,marvell_pj4,xgene1")
392 (eq_attr "tune_cortexr4" "yes"))
393 (const_string "no")
394 (const_string "yes"))))
395
396 (define_attr "generic_vfp" "yes,no"
397 (const (if_then_else
398 (and (eq_attr "fpu" "vfp")
399 (eq_attr "tune" "!arm1020e,arm1022e,cortexa5,cortexa7,\
400 cortexa8,cortexa9,cortexa53,cortexm4,\
401 cortexm7,marvell_pj4,xgene1")
402 (eq_attr "tune_cortexr4" "no"))
403 (const_string "yes")
404 (const_string "no"))))
405
406 (include "marvell-f-iwmmxt.md")
407 (include "arm-generic.md")
408 (include "arm926ejs.md")
409 (include "arm1020e.md")
410 (include "arm1026ejs.md")
411 (include "arm1136jfs.md")
412 (include "fa526.md")
413 (include "fa606te.md")
414 (include "fa626te.md")
415 (include "fmp626.md")
416 (include "fa726te.md")
417 (include "cortex-a5.md")
418 (include "cortex-a7.md")
419 (include "cortex-a8.md")
420 (include "cortex-a9.md")
421 (include "cortex-a15.md")
422 (include "cortex-a17.md")
423 (include "cortex-a53.md")
424 (include "cortex-a57.md")
425 (include "cortex-r4.md")
426 (include "cortex-r4f.md")
427 (include "cortex-m7.md")
428 (include "cortex-m4.md")
429 (include "cortex-m4-fpu.md")
430 (include "exynos-m1.md")
431 (include "vfp11.md")
432 (include "marvell-pj4.md")
433 (include "xgene1.md")
434
435 \f
436 ;;---------------------------------------------------------------------------
437 ;; Insn patterns
438 ;;
439 ;; Addition insns.
440
441 ;; Note: For DImode insns, there is normally no reason why operands should
442 ;; not be in the same register, what we don't want is for something being
443 ;; written to partially overlap something that is an input.
444
445 (define_expand "adddi3"
446 [(parallel
447 [(set (match_operand:DI 0 "s_register_operand" "")
448 (plus:DI (match_operand:DI 1 "s_register_operand" "")
449 (match_operand:DI 2 "arm_adddi_operand" "")))
450 (clobber (reg:CC CC_REGNUM))])]
451 "TARGET_EITHER"
452 "
453 if (TARGET_THUMB1)
454 {
455 if (!REG_P (operands[1]))
456 operands[1] = force_reg (DImode, operands[1]);
457 if (!REG_P (operands[2]))
458 operands[2] = force_reg (DImode, operands[2]);
459 }
460 "
461 )
462
463 (define_insn_and_split "*arm_adddi3"
464 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
465 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
466 (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
467 (clobber (reg:CC CC_REGNUM))]
468 "TARGET_32BIT && !TARGET_NEON"
469 "#"
470 "TARGET_32BIT && reload_completed
471 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))"
472 [(parallel [(set (reg:CC_C CC_REGNUM)
473 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
474 (match_dup 1)))
475 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
476 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
477 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
478 "
479 {
480 operands[3] = gen_highpart (SImode, operands[0]);
481 operands[0] = gen_lowpart (SImode, operands[0]);
482 operands[4] = gen_highpart (SImode, operands[1]);
483 operands[1] = gen_lowpart (SImode, operands[1]);
484 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
485 operands[2] = gen_lowpart (SImode, operands[2]);
486 }"
487 [(set_attr "conds" "clob")
488 (set_attr "length" "8")
489 (set_attr "type" "multiple")]
490 )
491
492 (define_insn_and_split "*adddi_sesidi_di"
493 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
494 (plus:DI (sign_extend:DI
495 (match_operand:SI 2 "s_register_operand" "r,r"))
496 (match_operand:DI 1 "s_register_operand" "0,r")))
497 (clobber (reg:CC CC_REGNUM))]
498 "TARGET_32BIT"
499 "#"
500 "TARGET_32BIT && reload_completed"
501 [(parallel [(set (reg:CC_C CC_REGNUM)
502 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
503 (match_dup 1)))
504 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
505 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
506 (const_int 31))
507 (match_dup 4))
508 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
509 "
510 {
511 operands[3] = gen_highpart (SImode, operands[0]);
512 operands[0] = gen_lowpart (SImode, operands[0]);
513 operands[4] = gen_highpart (SImode, operands[1]);
514 operands[1] = gen_lowpart (SImode, operands[1]);
515 operands[2] = gen_lowpart (SImode, operands[2]);
516 }"
517 [(set_attr "conds" "clob")
518 (set_attr "length" "8")
519 (set_attr "type" "multiple")]
520 )
521
522 (define_insn_and_split "*adddi_zesidi_di"
523 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
524 (plus:DI (zero_extend:DI
525 (match_operand:SI 2 "s_register_operand" "r,r"))
526 (match_operand:DI 1 "s_register_operand" "0,r")))
527 (clobber (reg:CC CC_REGNUM))]
528 "TARGET_32BIT"
529 "#"
530 "TARGET_32BIT && reload_completed"
531 [(parallel [(set (reg:CC_C CC_REGNUM)
532 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
533 (match_dup 1)))
534 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
535 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
536 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
537 "
538 {
539 operands[3] = gen_highpart (SImode, operands[0]);
540 operands[0] = gen_lowpart (SImode, operands[0]);
541 operands[4] = gen_highpart (SImode, operands[1]);
542 operands[1] = gen_lowpart (SImode, operands[1]);
543 operands[2] = gen_lowpart (SImode, operands[2]);
544 }"
545 [(set_attr "conds" "clob")
546 (set_attr "length" "8")
547 (set_attr "type" "multiple")]
548 )
549
550 (define_expand "addv<mode>4"
551 [(match_operand:SIDI 0 "register_operand")
552 (match_operand:SIDI 1 "register_operand")
553 (match_operand:SIDI 2 "register_operand")
554 (match_operand 3 "")]
555 "TARGET_32BIT"
556 {
557 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
558 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
559
560 DONE;
561 })
562
563 (define_expand "uaddv<mode>4"
564 [(match_operand:SIDI 0 "register_operand")
565 (match_operand:SIDI 1 "register_operand")
566 (match_operand:SIDI 2 "register_operand")
567 (match_operand 3 "")]
568 "TARGET_32BIT"
569 {
570 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
571 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
572
573 DONE;
574 })
575
576 (define_expand "addsi3"
577 [(set (match_operand:SI 0 "s_register_operand" "")
578 (plus:SI (match_operand:SI 1 "s_register_operand" "")
579 (match_operand:SI 2 "reg_or_int_operand" "")))]
580 "TARGET_EITHER"
581 "
582 if (TARGET_32BIT && CONST_INT_P (operands[2]))
583 {
584 arm_split_constant (PLUS, SImode, NULL_RTX,
585 INTVAL (operands[2]), operands[0], operands[1],
586 optimize && can_create_pseudo_p ());
587 DONE;
588 }
589 "
590 )
591
592 ; If there is a scratch available, this will be faster than synthesizing the
593 ; addition.
594 (define_peephole2
595 [(match_scratch:SI 3 "r")
596 (set (match_operand:SI 0 "arm_general_register_operand" "")
597 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
598 (match_operand:SI 2 "const_int_operand" "")))]
599 "TARGET_32BIT &&
600 !(const_ok_for_arm (INTVAL (operands[2]))
601 || const_ok_for_arm (-INTVAL (operands[2])))
602 && const_ok_for_arm (~INTVAL (operands[2]))"
603 [(set (match_dup 3) (match_dup 2))
604 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
605 ""
606 )
607
608 ;; The r/r/k alternative is required when reloading the address
609 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
610 ;; put the duplicated register first, and not try the commutative version.
611 (define_insn_and_split "*arm_addsi3"
612 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
613 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk")
614 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
615 "TARGET_32BIT"
616 "@
617 add%?\\t%0, %0, %2
618 add%?\\t%0, %1, %2
619 add%?\\t%0, %1, %2
620 add%?\\t%0, %1, %2
621 add%?\\t%0, %1, %2
622 add%?\\t%0, %1, %2
623 add%?\\t%0, %2, %1
624 add%?\\t%0, %1, %2
625 addw%?\\t%0, %1, %2
626 addw%?\\t%0, %1, %2
627 sub%?\\t%0, %1, #%n2
628 sub%?\\t%0, %1, #%n2
629 sub%?\\t%0, %1, #%n2
630 subw%?\\t%0, %1, #%n2
631 subw%?\\t%0, %1, #%n2
632 #"
633 "TARGET_32BIT
634 && CONST_INT_P (operands[2])
635 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
636 && (reload_completed || !arm_eliminable_register (operands[1]))"
637 [(clobber (const_int 0))]
638 "
639 arm_split_constant (PLUS, SImode, curr_insn,
640 INTVAL (operands[2]), operands[0],
641 operands[1], 0);
642 DONE;
643 "
644 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
645 (set_attr "predicable" "yes")
646 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
647 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
648 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
649 (const_string "alu_imm")
650 (const_string "alu_sreg")))
651 ]
652 )
653
654 (define_insn_and_split "adddi3_compareV"
655 [(set (reg:CC_V CC_REGNUM)
656 (ne:CC_V
657 (plus:TI
658 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
659 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
660 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
661 (set (match_operand:DI 0 "register_operand" "=&r")
662 (plus:DI (match_dup 1) (match_dup 2)))]
663 "TARGET_32BIT"
664 "#"
665 "&& reload_completed"
666 [(parallel [(set (reg:CC_C CC_REGNUM)
667 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
668 (match_dup 1)))
669 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
670 (parallel [(set (reg:CC_V CC_REGNUM)
671 (ne:CC_V
672 (plus:DI (plus:DI
673 (sign_extend:DI (match_dup 4))
674 (sign_extend:DI (match_dup 5)))
675 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
676 (plus:DI (sign_extend:DI
677 (plus:SI (match_dup 4) (match_dup 5)))
678 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
679 (set (match_dup 3) (plus:SI (plus:SI
680 (match_dup 4) (match_dup 5))
681 (ltu:SI (reg:CC_C CC_REGNUM)
682 (const_int 0))))])]
683 "
684 {
685 operands[3] = gen_highpart (SImode, operands[0]);
686 operands[0] = gen_lowpart (SImode, operands[0]);
687 operands[4] = gen_highpart (SImode, operands[1]);
688 operands[1] = gen_lowpart (SImode, operands[1]);
689 operands[5] = gen_highpart (SImode, operands[2]);
690 operands[2] = gen_lowpart (SImode, operands[2]);
691 }"
692 [(set_attr "conds" "set")
693 (set_attr "length" "8")
694 (set_attr "type" "multiple")]
695 )
696
697 (define_insn "addsi3_compareV"
698 [(set (reg:CC_V CC_REGNUM)
699 (ne:CC_V
700 (plus:DI
701 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
702 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
703 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
704 (set (match_operand:SI 0 "register_operand" "=r")
705 (plus:SI (match_dup 1) (match_dup 2)))]
706 "TARGET_32BIT"
707 "adds%?\\t%0, %1, %2"
708 [(set_attr "conds" "set")
709 (set_attr "type" "alus_sreg")]
710 )
711
712 (define_insn "*addsi3_compareV_upper"
713 [(set (reg:CC_V CC_REGNUM)
714 (ne:CC_V
715 (plus:DI
716 (plus:DI
717 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
718 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
719 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
720 (plus:DI (sign_extend:DI
721 (plus:SI (match_dup 1) (match_dup 2)))
722 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
723 (set (match_operand:SI 0 "register_operand" "=r")
724 (plus:SI
725 (plus:SI (match_dup 1) (match_dup 2))
726 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
727 "TARGET_32BIT"
728 "adcs%?\\t%0, %1, %2"
729 [(set_attr "conds" "set")
730 (set_attr "type" "adcs_reg")]
731 )
732
733 (define_insn_and_split "adddi3_compareC"
734 [(set (reg:CC_C CC_REGNUM)
735 (ne:CC_C
736 (plus:TI
737 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
738 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
739 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
740 (set (match_operand:DI 0 "register_operand" "=&r")
741 (plus:DI (match_dup 1) (match_dup 2)))]
742 "TARGET_32BIT"
743 "#"
744 "&& reload_completed"
745 [(parallel [(set (reg:CC_C CC_REGNUM)
746 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
747 (match_dup 1)))
748 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
749 (parallel [(set (reg:CC_C CC_REGNUM)
750 (ne:CC_C
751 (plus:DI (plus:DI
752 (zero_extend:DI (match_dup 4))
753 (zero_extend:DI (match_dup 5)))
754 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
755 (plus:DI (zero_extend:DI
756 (plus:SI (match_dup 4) (match_dup 5)))
757 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
758 (set (match_dup 3) (plus:SI
759 (plus:SI (match_dup 4) (match_dup 5))
760 (ltu:SI (reg:CC_C CC_REGNUM)
761 (const_int 0))))])]
762 "
763 {
764 operands[3] = gen_highpart (SImode, operands[0]);
765 operands[0] = gen_lowpart (SImode, operands[0]);
766 operands[4] = gen_highpart (SImode, operands[1]);
767 operands[5] = gen_highpart (SImode, operands[2]);
768 operands[1] = gen_lowpart (SImode, operands[1]);
769 operands[2] = gen_lowpart (SImode, operands[2]);
770 }"
771 [(set_attr "conds" "set")
772 (set_attr "length" "8")
773 (set_attr "type" "multiple")]
774 )
775
776 (define_insn "*addsi3_compareC_upper"
777 [(set (reg:CC_C CC_REGNUM)
778 (ne:CC_C
779 (plus:DI
780 (plus:DI
781 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
782 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
783 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
784 (plus:DI (zero_extend:DI
785 (plus:SI (match_dup 1) (match_dup 2)))
786 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
787 (set (match_operand:SI 0 "register_operand" "=r")
788 (plus:SI
789 (plus:SI (match_dup 1) (match_dup 2))
790 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
791 "TARGET_32BIT"
792 "adcs%?\\t%0, %1, %2"
793 [(set_attr "conds" "set")
794 (set_attr "type" "adcs_reg")]
795 )
796
797 (define_insn "addsi3_compareC"
798 [(set (reg:CC_C CC_REGNUM)
799 (ne:CC_C
800 (plus:DI
801 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
802 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
803 (zero_extend:DI
804 (plus:SI (match_dup 1) (match_dup 2)))))
805 (set (match_operand:SI 0 "register_operand" "=r")
806 (plus:SI (match_dup 1) (match_dup 2)))]
807 "TARGET_32BIT"
808 "adds%?\\t%0, %1, %2"
809 [(set_attr "conds" "set")
810 (set_attr "type" "alus_sreg")]
811 )
812
813 (define_insn "addsi3_compare0"
814 [(set (reg:CC_NOOV CC_REGNUM)
815 (compare:CC_NOOV
816 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
817 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
818 (const_int 0)))
819 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
820 (plus:SI (match_dup 1) (match_dup 2)))]
821 "TARGET_ARM"
822 "@
823 adds%?\\t%0, %1, %2
824 subs%?\\t%0, %1, #%n2
825 adds%?\\t%0, %1, %2"
826 [(set_attr "conds" "set")
827 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
828 )
829
830 (define_insn "*addsi3_compare0_scratch"
831 [(set (reg:CC_NOOV CC_REGNUM)
832 (compare:CC_NOOV
833 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
834 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
835 (const_int 0)))]
836 "TARGET_ARM"
837 "@
838 cmn%?\\t%0, %1
839 cmp%?\\t%0, #%n1
840 cmn%?\\t%0, %1"
841 [(set_attr "conds" "set")
842 (set_attr "predicable" "yes")
843 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
844 )
845
846 (define_insn "*compare_negsi_si"
847 [(set (reg:CC_Z CC_REGNUM)
848 (compare:CC_Z
849 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
850 (match_operand:SI 1 "s_register_operand" "l,r")))]
851 "TARGET_32BIT"
852 "cmn%?\\t%1, %0"
853 [(set_attr "conds" "set")
854 (set_attr "predicable" "yes")
855 (set_attr "arch" "t2,*")
856 (set_attr "length" "2,4")
857 (set_attr "predicable_short_it" "yes,no")
858 (set_attr "type" "alus_sreg")]
859 )
860
861 ;; This is the canonicalization of addsi3_compare0_for_combiner when the
862 ;; addend is a constant.
863 (define_insn "cmpsi2_addneg"
864 [(set (reg:CC CC_REGNUM)
865 (compare:CC
866 (match_operand:SI 1 "s_register_operand" "r,r")
867 (match_operand:SI 2 "arm_addimm_operand" "L,I")))
868 (set (match_operand:SI 0 "s_register_operand" "=r,r")
869 (plus:SI (match_dup 1)
870 (match_operand:SI 3 "arm_addimm_operand" "I,L")))]
871 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])"
872 "@
873 adds%?\\t%0, %1, %3
874 subs%?\\t%0, %1, #%n3"
875 [(set_attr "conds" "set")
876 (set_attr "type" "alus_sreg")]
877 )
878
879 ;; Convert the sequence
880 ;; sub rd, rn, #1
881 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
882 ;; bne dest
883 ;; into
884 ;; subs rd, rn, #1
885 ;; bcs dest ((unsigned)rn >= 1)
886 ;; similarly for the beq variant using bcc.
887 ;; This is a common looping idiom (while (n--))
888 (define_peephole2
889 [(set (match_operand:SI 0 "arm_general_register_operand" "")
890 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
891 (const_int -1)))
892 (set (match_operand 2 "cc_register" "")
893 (compare (match_dup 0) (const_int -1)))
894 (set (pc)
895 (if_then_else (match_operator 3 "equality_operator"
896 [(match_dup 2) (const_int 0)])
897 (match_operand 4 "" "")
898 (match_operand 5 "" "")))]
899 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
900 [(parallel[
901 (set (match_dup 2)
902 (compare:CC
903 (match_dup 1) (const_int 1)))
904 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
905 (set (pc)
906 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
907 (match_dup 4)
908 (match_dup 5)))]
909 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
910 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
911 ? GEU : LTU),
912 VOIDmode,
913 operands[2], const0_rtx);"
914 )
915
916 ;; The next four insns work because they compare the result with one of
917 ;; the operands, and we know that the use of the condition code is
918 ;; either GEU or LTU, so we can use the carry flag from the addition
919 ;; instead of doing the compare a second time.
920 (define_insn "*addsi3_compare_op1"
921 [(set (reg:CC_C CC_REGNUM)
922 (compare:CC_C
923 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
924 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
925 (match_dup 1)))
926 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
927 (plus:SI (match_dup 1) (match_dup 2)))]
928 "TARGET_32BIT"
929 "@
930 adds%?\\t%0, %1, %2
931 subs%?\\t%0, %1, #%n2
932 adds%?\\t%0, %1, %2"
933 [(set_attr "conds" "set")
934 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
935 )
936
937 (define_insn "*addsi3_compare_op2"
938 [(set (reg:CC_C CC_REGNUM)
939 (compare:CC_C
940 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
941 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
942 (match_dup 2)))
943 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
944 (plus:SI (match_dup 1) (match_dup 2)))]
945 "TARGET_32BIT"
946 "@
947 adds%?\\t%0, %1, %2
948 subs%?\\t%0, %1, #%n2
949 adds%?\\t%0, %1, %2"
950 [(set_attr "conds" "set")
951 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
952 )
953
954 (define_insn "*compare_addsi2_op0"
955 [(set (reg:CC_C CC_REGNUM)
956 (compare:CC_C
957 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
958 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
959 (match_dup 0)))]
960 "TARGET_32BIT"
961 "@
962 cmp%?\\t%0, #%n1
963 cmn%?\\t%0, %1
964 cmn%?\\t%0, %1
965 cmp%?\\t%0, #%n1
966 cmn%?\\t%0, %1"
967 [(set_attr "conds" "set")
968 (set_attr "predicable" "yes")
969 (set_attr "arch" "t2,t2,*,*,*")
970 (set_attr "predicable_short_it" "yes,yes,no,no,no")
971 (set_attr "length" "2,2,4,4,4")
972 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
973 )
974
975 (define_insn "*compare_addsi2_op1"
976 [(set (reg:CC_C CC_REGNUM)
977 (compare:CC_C
978 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
979 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
980 (match_dup 1)))]
981 "TARGET_32BIT"
982 "@
983 cmp%?\\t%0, #%n1
984 cmn%?\\t%0, %1
985 cmn%?\\t%0, %1
986 cmp%?\\t%0, #%n1
987 cmn%?\\t%0, %1"
988 [(set_attr "conds" "set")
989 (set_attr "predicable" "yes")
990 (set_attr "arch" "t2,t2,*,*,*")
991 (set_attr "predicable_short_it" "yes,yes,no,no,no")
992 (set_attr "length" "2,2,4,4,4")
993 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
994 )
995
996 (define_insn "*addsi3_carryin_<optab>"
997 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
998 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
999 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1000 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1001 "TARGET_32BIT"
1002 "@
1003 adc%?\\t%0, %1, %2
1004 adc%?\\t%0, %1, %2
1005 sbc%?\\t%0, %1, #%B2"
1006 [(set_attr "conds" "use")
1007 (set_attr "predicable" "yes")
1008 (set_attr "arch" "t2,*,*")
1009 (set_attr "length" "4")
1010 (set_attr "predicable_short_it" "yes,no,no")
1011 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1012 )
1013
1014 (define_insn "*addsi3_carryin_alt2_<optab>"
1015 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1016 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1017 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1018 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1019 "TARGET_32BIT"
1020 "@
1021 adc%?\\t%0, %1, %2
1022 adc%?\\t%0, %1, %2
1023 sbc%?\\t%0, %1, #%B2"
1024 [(set_attr "conds" "use")
1025 (set_attr "predicable" "yes")
1026 (set_attr "arch" "t2,*,*")
1027 (set_attr "length" "4")
1028 (set_attr "predicable_short_it" "yes,no,no")
1029 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1030 )
1031
1032 (define_insn "*addsi3_carryin_shift_<optab>"
1033 [(set (match_operand:SI 0 "s_register_operand" "=r")
1034 (plus:SI (plus:SI
1035 (match_operator:SI 2 "shift_operator"
1036 [(match_operand:SI 3 "s_register_operand" "r")
1037 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1038 (match_operand:SI 1 "s_register_operand" "r"))
1039 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1040 "TARGET_32BIT"
1041 "adc%?\\t%0, %1, %3%S2"
1042 [(set_attr "conds" "use")
1043 (set_attr "predicable" "yes")
1044 (set_attr "predicable_short_it" "no")
1045 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1046 (const_string "alu_shift_imm")
1047 (const_string "alu_shift_reg")))]
1048 )
1049
1050 (define_insn "*addsi3_carryin_clobercc_<optab>"
1051 [(set (match_operand:SI 0 "s_register_operand" "=r")
1052 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1053 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1054 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1055 (clobber (reg:CC CC_REGNUM))]
1056 "TARGET_32BIT"
1057 "adcs%?\\t%0, %1, %2"
1058 [(set_attr "conds" "set")
1059 (set_attr "type" "adcs_reg")]
1060 )
1061
1062 (define_expand "subv<mode>4"
1063 [(match_operand:SIDI 0 "register_operand")
1064 (match_operand:SIDI 1 "register_operand")
1065 (match_operand:SIDI 2 "register_operand")
1066 (match_operand 3 "")]
1067 "TARGET_32BIT"
1068 {
1069 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1070 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1071
1072 DONE;
1073 })
1074
1075 (define_expand "usubv<mode>4"
1076 [(match_operand:SIDI 0 "register_operand")
1077 (match_operand:SIDI 1 "register_operand")
1078 (match_operand:SIDI 2 "register_operand")
1079 (match_operand 3 "")]
1080 "TARGET_32BIT"
1081 {
1082 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1083 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1084
1085 DONE;
1086 })
1087
1088 (define_insn_and_split "subdi3_compare1"
1089 [(set (reg:CC CC_REGNUM)
1090 (compare:CC
1091 (match_operand:DI 1 "register_operand" "r")
1092 (match_operand:DI 2 "register_operand" "r")))
1093 (set (match_operand:DI 0 "register_operand" "=&r")
1094 (minus:DI (match_dup 1) (match_dup 2)))]
1095 "TARGET_32BIT"
1096 "#"
1097 "&& reload_completed"
1098 [(parallel [(set (reg:CC CC_REGNUM)
1099 (compare:CC (match_dup 1) (match_dup 2)))
1100 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1101 (parallel [(set (reg:CC CC_REGNUM)
1102 (compare:CC (match_dup 4) (match_dup 5)))
1103 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1104 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
1105 {
1106 operands[3] = gen_highpart (SImode, operands[0]);
1107 operands[0] = gen_lowpart (SImode, operands[0]);
1108 operands[4] = gen_highpart (SImode, operands[1]);
1109 operands[1] = gen_lowpart (SImode, operands[1]);
1110 operands[5] = gen_highpart (SImode, operands[2]);
1111 operands[2] = gen_lowpart (SImode, operands[2]);
1112 }
1113 [(set_attr "conds" "set")
1114 (set_attr "length" "8")
1115 (set_attr "type" "multiple")]
1116 )
1117
1118 (define_insn "subsi3_compare1"
1119 [(set (reg:CC CC_REGNUM)
1120 (compare:CC
1121 (match_operand:SI 1 "register_operand" "r")
1122 (match_operand:SI 2 "register_operand" "r")))
1123 (set (match_operand:SI 0 "register_operand" "=r")
1124 (minus:SI (match_dup 1) (match_dup 2)))]
1125 "TARGET_32BIT"
1126 "subs%?\\t%0, %1, %2"
1127 [(set_attr "conds" "set")
1128 (set_attr "type" "alus_sreg")]
1129 )
1130
1131 (define_insn "*subsi3_carryin"
1132 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1133 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I")
1134 (match_operand:SI 2 "s_register_operand" "r,r"))
1135 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1136 "TARGET_32BIT"
1137 "@
1138 sbc%?\\t%0, %1, %2
1139 rsc%?\\t%0, %2, %1"
1140 [(set_attr "conds" "use")
1141 (set_attr "arch" "*,a")
1142 (set_attr "predicable" "yes")
1143 (set_attr "predicable_short_it" "no")
1144 (set_attr "type" "adc_reg,adc_imm")]
1145 )
1146
1147 (define_insn "*subsi3_carryin_const"
1148 [(set (match_operand:SI 0 "s_register_operand" "=r")
1149 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
1150 (match_operand:SI 2 "arm_not_immediate_operand" "K"))
1151 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1152 "TARGET_32BIT"
1153 "sbc\\t%0, %1, #%B2"
1154 [(set_attr "conds" "use")
1155 (set_attr "type" "adc_imm")]
1156 )
1157
1158 (define_insn "*subsi3_carryin_compare"
1159 [(set (reg:CC CC_REGNUM)
1160 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1161 (match_operand:SI 2 "s_register_operand" "r")))
1162 (set (match_operand:SI 0 "s_register_operand" "=r")
1163 (minus:SI (minus:SI (match_dup 1)
1164 (match_dup 2))
1165 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1166 "TARGET_32BIT"
1167 "sbcs\\t%0, %1, %2"
1168 [(set_attr "conds" "set")
1169 (set_attr "type" "adcs_reg")]
1170 )
1171
1172 (define_insn "*subsi3_carryin_compare_const"
1173 [(set (reg:CC CC_REGNUM)
1174 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1175 (match_operand:SI 2 "arm_not_operand" "K")))
1176 (set (match_operand:SI 0 "s_register_operand" "=r")
1177 (minus:SI (plus:SI (match_dup 1)
1178 (match_dup 2))
1179 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1180 "TARGET_32BIT"
1181 "sbcs\\t%0, %1, #%B2"
1182 [(set_attr "conds" "set")
1183 (set_attr "type" "adcs_imm")]
1184 )
1185
1186 (define_insn "*subsi3_carryin_shift"
1187 [(set (match_operand:SI 0 "s_register_operand" "=r")
1188 (minus:SI (minus:SI
1189 (match_operand:SI 1 "s_register_operand" "r")
1190 (match_operator:SI 2 "shift_operator"
1191 [(match_operand:SI 3 "s_register_operand" "r")
1192 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1193 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1194 "TARGET_32BIT"
1195 "sbc%?\\t%0, %1, %3%S2"
1196 [(set_attr "conds" "use")
1197 (set_attr "predicable" "yes")
1198 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1199 (const_string "alu_shift_imm")
1200 (const_string "alu_shift_reg")))]
1201 )
1202
1203 (define_insn "*rsbsi3_carryin_shift"
1204 [(set (match_operand:SI 0 "s_register_operand" "=r")
1205 (minus:SI (minus:SI
1206 (match_operator:SI 2 "shift_operator"
1207 [(match_operand:SI 3 "s_register_operand" "r")
1208 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1209 (match_operand:SI 1 "s_register_operand" "r"))
1210 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1211 "TARGET_ARM"
1212 "rsc%?\\t%0, %1, %3%S2"
1213 [(set_attr "conds" "use")
1214 (set_attr "predicable" "yes")
1215 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1216 (const_string "alu_shift_imm")
1217 (const_string "alu_shift_reg")))]
1218 )
1219
1220 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1221 (define_split
1222 [(set (match_operand:SI 0 "s_register_operand" "")
1223 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1224 (match_operand:SI 2 "s_register_operand" ""))
1225 (const_int -1)))
1226 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1227 "TARGET_32BIT"
1228 [(set (match_dup 3) (match_dup 1))
1229 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1230 "
1231 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1232 ")
1233
1234 (define_expand "addsf3"
1235 [(set (match_operand:SF 0 "s_register_operand" "")
1236 (plus:SF (match_operand:SF 1 "s_register_operand" "")
1237 (match_operand:SF 2 "s_register_operand" "")))]
1238 "TARGET_32BIT && TARGET_HARD_FLOAT"
1239 "
1240 ")
1241
1242 (define_expand "adddf3"
1243 [(set (match_operand:DF 0 "s_register_operand" "")
1244 (plus:DF (match_operand:DF 1 "s_register_operand" "")
1245 (match_operand:DF 2 "s_register_operand" "")))]
1246 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1247 "
1248 ")
1249
1250 (define_expand "subdi3"
1251 [(parallel
1252 [(set (match_operand:DI 0 "s_register_operand" "")
1253 (minus:DI (match_operand:DI 1 "s_register_operand" "")
1254 (match_operand:DI 2 "s_register_operand" "")))
1255 (clobber (reg:CC CC_REGNUM))])]
1256 "TARGET_EITHER"
1257 "
1258 if (TARGET_THUMB1)
1259 {
1260 if (!REG_P (operands[1]))
1261 operands[1] = force_reg (DImode, operands[1]);
1262 if (!REG_P (operands[2]))
1263 operands[2] = force_reg (DImode, operands[2]);
1264 }
1265 "
1266 )
1267
1268 (define_insn_and_split "*arm_subdi3"
1269 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r")
1270 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0")
1271 (match_operand:DI 2 "s_register_operand" "r,0,0")))
1272 (clobber (reg:CC CC_REGNUM))]
1273 "TARGET_32BIT && !TARGET_NEON"
1274 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1275 "&& reload_completed"
1276 [(parallel [(set (reg:CC CC_REGNUM)
1277 (compare:CC (match_dup 1) (match_dup 2)))
1278 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1279 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1280 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1281 {
1282 operands[3] = gen_highpart (SImode, operands[0]);
1283 operands[0] = gen_lowpart (SImode, operands[0]);
1284 operands[4] = gen_highpart (SImode, operands[1]);
1285 operands[1] = gen_lowpart (SImode, operands[1]);
1286 operands[5] = gen_highpart (SImode, operands[2]);
1287 operands[2] = gen_lowpart (SImode, operands[2]);
1288 }
1289 [(set_attr "conds" "clob")
1290 (set_attr "length" "8")
1291 (set_attr "type" "multiple")]
1292 )
1293
1294 (define_insn_and_split "*subdi_di_zesidi"
1295 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1296 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1297 (zero_extend:DI
1298 (match_operand:SI 2 "s_register_operand" "r,r"))))
1299 (clobber (reg:CC CC_REGNUM))]
1300 "TARGET_32BIT"
1301 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1302 "&& reload_completed"
1303 [(parallel [(set (reg:CC CC_REGNUM)
1304 (compare:CC (match_dup 1) (match_dup 2)))
1305 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1306 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5))
1307 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1308 {
1309 operands[3] = gen_highpart (SImode, operands[0]);
1310 operands[0] = gen_lowpart (SImode, operands[0]);
1311 operands[4] = gen_highpart (SImode, operands[1]);
1312 operands[1] = gen_lowpart (SImode, operands[1]);
1313 operands[5] = GEN_INT (~0);
1314 }
1315 [(set_attr "conds" "clob")
1316 (set_attr "length" "8")
1317 (set_attr "type" "multiple")]
1318 )
1319
1320 (define_insn_and_split "*subdi_di_sesidi"
1321 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1322 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1323 (sign_extend:DI
1324 (match_operand:SI 2 "s_register_operand" "r,r"))))
1325 (clobber (reg:CC CC_REGNUM))]
1326 "TARGET_32BIT"
1327 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1328 "&& reload_completed"
1329 [(parallel [(set (reg:CC CC_REGNUM)
1330 (compare:CC (match_dup 1) (match_dup 2)))
1331 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1332 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1333 (ashiftrt:SI (match_dup 2)
1334 (const_int 31)))
1335 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1336 {
1337 operands[3] = gen_highpart (SImode, operands[0]);
1338 operands[0] = gen_lowpart (SImode, operands[0]);
1339 operands[4] = gen_highpart (SImode, operands[1]);
1340 operands[1] = gen_lowpart (SImode, operands[1]);
1341 }
1342 [(set_attr "conds" "clob")
1343 (set_attr "length" "8")
1344 (set_attr "type" "multiple")]
1345 )
1346
1347 (define_insn_and_split "*subdi_zesidi_di"
1348 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1349 (minus:DI (zero_extend:DI
1350 (match_operand:SI 2 "s_register_operand" "r,r"))
1351 (match_operand:DI 1 "s_register_operand" "0,r")))
1352 (clobber (reg:CC CC_REGNUM))]
1353 "TARGET_ARM"
1354 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1355 ; is equivalent to:
1356 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1357 "&& reload_completed"
1358 [(parallel [(set (reg:CC CC_REGNUM)
1359 (compare:CC (match_dup 2) (match_dup 1)))
1360 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1361 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1362 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1363 {
1364 operands[3] = gen_highpart (SImode, operands[0]);
1365 operands[0] = gen_lowpart (SImode, operands[0]);
1366 operands[4] = gen_highpart (SImode, operands[1]);
1367 operands[1] = gen_lowpart (SImode, operands[1]);
1368 }
1369 [(set_attr "conds" "clob")
1370 (set_attr "length" "8")
1371 (set_attr "type" "multiple")]
1372 )
1373
1374 (define_insn_and_split "*subdi_sesidi_di"
1375 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1376 (minus:DI (sign_extend:DI
1377 (match_operand:SI 2 "s_register_operand" "r,r"))
1378 (match_operand:DI 1 "s_register_operand" "0,r")))
1379 (clobber (reg:CC CC_REGNUM))]
1380 "TARGET_ARM"
1381 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1382 ; is equivalent to:
1383 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1384 "&& reload_completed"
1385 [(parallel [(set (reg:CC CC_REGNUM)
1386 (compare:CC (match_dup 2) (match_dup 1)))
1387 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1388 (set (match_dup 3) (minus:SI (minus:SI
1389 (ashiftrt:SI (match_dup 2)
1390 (const_int 31))
1391 (match_dup 4))
1392 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1393 {
1394 operands[3] = gen_highpart (SImode, operands[0]);
1395 operands[0] = gen_lowpart (SImode, operands[0]);
1396 operands[4] = gen_highpart (SImode, operands[1]);
1397 operands[1] = gen_lowpart (SImode, operands[1]);
1398 }
1399 [(set_attr "conds" "clob")
1400 (set_attr "length" "8")
1401 (set_attr "type" "multiple")]
1402 )
1403
1404 (define_insn_and_split "*subdi_zesidi_zesidi"
1405 [(set (match_operand:DI 0 "s_register_operand" "=r")
1406 (minus:DI (zero_extend:DI
1407 (match_operand:SI 1 "s_register_operand" "r"))
1408 (zero_extend:DI
1409 (match_operand:SI 2 "s_register_operand" "r"))))
1410 (clobber (reg:CC CC_REGNUM))]
1411 "TARGET_32BIT"
1412 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1413 "&& reload_completed"
1414 [(parallel [(set (reg:CC CC_REGNUM)
1415 (compare:CC (match_dup 1) (match_dup 2)))
1416 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1417 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1418 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
1419 {
1420 operands[3] = gen_highpart (SImode, operands[0]);
1421 operands[0] = gen_lowpart (SImode, operands[0]);
1422 }
1423 [(set_attr "conds" "clob")
1424 (set_attr "length" "8")
1425 (set_attr "type" "multiple")]
1426 )
1427
1428 (define_expand "subsi3"
1429 [(set (match_operand:SI 0 "s_register_operand" "")
1430 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "")
1431 (match_operand:SI 2 "s_register_operand" "")))]
1432 "TARGET_EITHER"
1433 "
1434 if (CONST_INT_P (operands[1]))
1435 {
1436 if (TARGET_32BIT)
1437 {
1438 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1439 operands[1] = force_reg (SImode, operands[1]);
1440 else
1441 {
1442 arm_split_constant (MINUS, SImode, NULL_RTX,
1443 INTVAL (operands[1]), operands[0],
1444 operands[2],
1445 optimize && can_create_pseudo_p ());
1446 DONE;
1447 }
1448 }
1449 else /* TARGET_THUMB1 */
1450 operands[1] = force_reg (SImode, operands[1]);
1451 }
1452 "
1453 )
1454
1455 ; ??? Check Thumb-2 split length
1456 (define_insn_and_split "*arm_subsi3_insn"
1457 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1458 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1459 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1460 "TARGET_32BIT"
1461 "@
1462 sub%?\\t%0, %1, %2
1463 sub%?\\t%0, %2
1464 sub%?\\t%0, %1, %2
1465 rsb%?\\t%0, %2, %1
1466 rsb%?\\t%0, %2, %1
1467 sub%?\\t%0, %1, %2
1468 sub%?\\t%0, %1, %2
1469 sub%?\\t%0, %1, %2
1470 #"
1471 "&& (CONST_INT_P (operands[1])
1472 && !const_ok_for_arm (INTVAL (operands[1])))"
1473 [(clobber (const_int 0))]
1474 "
1475 arm_split_constant (MINUS, SImode, curr_insn,
1476 INTVAL (operands[1]), operands[0], operands[2], 0);
1477 DONE;
1478 "
1479 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1480 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1481 (set_attr "predicable" "yes")
1482 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1483 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1484 )
1485
1486 (define_peephole2
1487 [(match_scratch:SI 3 "r")
1488 (set (match_operand:SI 0 "arm_general_register_operand" "")
1489 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1490 (match_operand:SI 2 "arm_general_register_operand" "")))]
1491 "TARGET_32BIT
1492 && !const_ok_for_arm (INTVAL (operands[1]))
1493 && const_ok_for_arm (~INTVAL (operands[1]))"
1494 [(set (match_dup 3) (match_dup 1))
1495 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1496 ""
1497 )
1498
1499 (define_insn "subsi3_compare0"
1500 [(set (reg:CC_NOOV CC_REGNUM)
1501 (compare:CC_NOOV
1502 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1503 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1504 (const_int 0)))
1505 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1506 (minus:SI (match_dup 1) (match_dup 2)))]
1507 "TARGET_32BIT"
1508 "@
1509 subs%?\\t%0, %1, %2
1510 subs%?\\t%0, %1, %2
1511 rsbs%?\\t%0, %2, %1"
1512 [(set_attr "conds" "set")
1513 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1514 )
1515
1516 (define_insn "subsi3_compare"
1517 [(set (reg:CC CC_REGNUM)
1518 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1519 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1520 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1521 (minus:SI (match_dup 1) (match_dup 2)))]
1522 "TARGET_32BIT"
1523 "@
1524 subs%?\\t%0, %1, %2
1525 subs%?\\t%0, %1, %2
1526 rsbs%?\\t%0, %2, %1"
1527 [(set_attr "conds" "set")
1528 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1529 )
1530
1531 (define_expand "subsf3"
1532 [(set (match_operand:SF 0 "s_register_operand" "")
1533 (minus:SF (match_operand:SF 1 "s_register_operand" "")
1534 (match_operand:SF 2 "s_register_operand" "")))]
1535 "TARGET_32BIT && TARGET_HARD_FLOAT"
1536 "
1537 ")
1538
1539 (define_expand "subdf3"
1540 [(set (match_operand:DF 0 "s_register_operand" "")
1541 (minus:DF (match_operand:DF 1 "s_register_operand" "")
1542 (match_operand:DF 2 "s_register_operand" "")))]
1543 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1544 "
1545 ")
1546
1547 \f
1548 ;; Multiplication insns
1549
1550 (define_expand "mulhi3"
1551 [(set (match_operand:HI 0 "s_register_operand" "")
1552 (mult:HI (match_operand:HI 1 "s_register_operand" "")
1553 (match_operand:HI 2 "s_register_operand" "")))]
1554 "TARGET_DSP_MULTIPLY"
1555 "
1556 {
1557 rtx result = gen_reg_rtx (SImode);
1558 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1559 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1560 DONE;
1561 }"
1562 )
1563
1564 (define_expand "mulsi3"
1565 [(set (match_operand:SI 0 "s_register_operand" "")
1566 (mult:SI (match_operand:SI 2 "s_register_operand" "")
1567 (match_operand:SI 1 "s_register_operand" "")))]
1568 "TARGET_EITHER"
1569 ""
1570 )
1571
1572 ;; Use `&' and then `0' to prevent the operands 0 and 1 being the same
1573 (define_insn "*arm_mulsi3"
1574 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1575 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
1576 (match_operand:SI 1 "s_register_operand" "%0,r")))]
1577 "TARGET_32BIT && !arm_arch6"
1578 "mul%?\\t%0, %2, %1"
1579 [(set_attr "type" "mul")
1580 (set_attr "predicable" "yes")]
1581 )
1582
1583 (define_insn "*arm_mulsi3_v6"
1584 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1585 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r")
1586 (match_operand:SI 2 "s_register_operand" "l,0,r")))]
1587 "TARGET_32BIT && arm_arch6"
1588 "mul%?\\t%0, %1, %2"
1589 [(set_attr "type" "mul")
1590 (set_attr "predicable" "yes")
1591 (set_attr "arch" "t2,t2,*")
1592 (set_attr "length" "4")
1593 (set_attr "predicable_short_it" "yes,yes,no")]
1594 )
1595
1596 (define_insn "*mulsi3_compare0"
1597 [(set (reg:CC_NOOV CC_REGNUM)
1598 (compare:CC_NOOV (mult:SI
1599 (match_operand:SI 2 "s_register_operand" "r,r")
1600 (match_operand:SI 1 "s_register_operand" "%0,r"))
1601 (const_int 0)))
1602 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1603 (mult:SI (match_dup 2) (match_dup 1)))]
1604 "TARGET_ARM && !arm_arch6"
1605 "muls%?\\t%0, %2, %1"
1606 [(set_attr "conds" "set")
1607 (set_attr "type" "muls")]
1608 )
1609
1610 (define_insn "*mulsi3_compare0_v6"
1611 [(set (reg:CC_NOOV CC_REGNUM)
1612 (compare:CC_NOOV (mult:SI
1613 (match_operand:SI 2 "s_register_operand" "r")
1614 (match_operand:SI 1 "s_register_operand" "r"))
1615 (const_int 0)))
1616 (set (match_operand:SI 0 "s_register_operand" "=r")
1617 (mult:SI (match_dup 2) (match_dup 1)))]
1618 "TARGET_ARM && arm_arch6 && optimize_size"
1619 "muls%?\\t%0, %2, %1"
1620 [(set_attr "conds" "set")
1621 (set_attr "type" "muls")]
1622 )
1623
1624 (define_insn "*mulsi_compare0_scratch"
1625 [(set (reg:CC_NOOV CC_REGNUM)
1626 (compare:CC_NOOV (mult:SI
1627 (match_operand:SI 2 "s_register_operand" "r,r")
1628 (match_operand:SI 1 "s_register_operand" "%0,r"))
1629 (const_int 0)))
1630 (clobber (match_scratch:SI 0 "=&r,&r"))]
1631 "TARGET_ARM && !arm_arch6"
1632 "muls%?\\t%0, %2, %1"
1633 [(set_attr "conds" "set")
1634 (set_attr "type" "muls")]
1635 )
1636
1637 (define_insn "*mulsi_compare0_scratch_v6"
1638 [(set (reg:CC_NOOV CC_REGNUM)
1639 (compare:CC_NOOV (mult:SI
1640 (match_operand:SI 2 "s_register_operand" "r")
1641 (match_operand:SI 1 "s_register_operand" "r"))
1642 (const_int 0)))
1643 (clobber (match_scratch:SI 0 "=r"))]
1644 "TARGET_ARM && arm_arch6 && optimize_size"
1645 "muls%?\\t%0, %2, %1"
1646 [(set_attr "conds" "set")
1647 (set_attr "type" "muls")]
1648 )
1649
1650 ;; Unnamed templates to match MLA instruction.
1651
1652 (define_insn "*mulsi3addsi"
1653 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1654 (plus:SI
1655 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1656 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1657 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))]
1658 "TARGET_32BIT && !arm_arch6"
1659 "mla%?\\t%0, %2, %1, %3"
1660 [(set_attr "type" "mla")
1661 (set_attr "predicable" "yes")]
1662 )
1663
1664 (define_insn "*mulsi3addsi_v6"
1665 [(set (match_operand:SI 0 "s_register_operand" "=r")
1666 (plus:SI
1667 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1668 (match_operand:SI 1 "s_register_operand" "r"))
1669 (match_operand:SI 3 "s_register_operand" "r")))]
1670 "TARGET_32BIT && arm_arch6"
1671 "mla%?\\t%0, %2, %1, %3"
1672 [(set_attr "type" "mla")
1673 (set_attr "predicable" "yes")
1674 (set_attr "predicable_short_it" "no")]
1675 )
1676
1677 (define_insn "*mulsi3addsi_compare0"
1678 [(set (reg:CC_NOOV CC_REGNUM)
1679 (compare:CC_NOOV
1680 (plus:SI (mult:SI
1681 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1682 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1683 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1684 (const_int 0)))
1685 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1686 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1687 (match_dup 3)))]
1688 "TARGET_ARM && arm_arch6"
1689 "mlas%?\\t%0, %2, %1, %3"
1690 [(set_attr "conds" "set")
1691 (set_attr "type" "mlas")]
1692 )
1693
1694 (define_insn "*mulsi3addsi_compare0_v6"
1695 [(set (reg:CC_NOOV CC_REGNUM)
1696 (compare:CC_NOOV
1697 (plus:SI (mult:SI
1698 (match_operand:SI 2 "s_register_operand" "r")
1699 (match_operand:SI 1 "s_register_operand" "r"))
1700 (match_operand:SI 3 "s_register_operand" "r"))
1701 (const_int 0)))
1702 (set (match_operand:SI 0 "s_register_operand" "=r")
1703 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1704 (match_dup 3)))]
1705 "TARGET_ARM && arm_arch6 && optimize_size"
1706 "mlas%?\\t%0, %2, %1, %3"
1707 [(set_attr "conds" "set")
1708 (set_attr "type" "mlas")]
1709 )
1710
1711 (define_insn "*mulsi3addsi_compare0_scratch"
1712 [(set (reg:CC_NOOV CC_REGNUM)
1713 (compare:CC_NOOV
1714 (plus:SI (mult:SI
1715 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1716 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1717 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1718 (const_int 0)))
1719 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1720 "TARGET_ARM && !arm_arch6"
1721 "mlas%?\\t%0, %2, %1, %3"
1722 [(set_attr "conds" "set")
1723 (set_attr "type" "mlas")]
1724 )
1725
1726 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1727 [(set (reg:CC_NOOV CC_REGNUM)
1728 (compare:CC_NOOV
1729 (plus:SI (mult:SI
1730 (match_operand:SI 2 "s_register_operand" "r")
1731 (match_operand:SI 1 "s_register_operand" "r"))
1732 (match_operand:SI 3 "s_register_operand" "r"))
1733 (const_int 0)))
1734 (clobber (match_scratch:SI 0 "=r"))]
1735 "TARGET_ARM && arm_arch6 && optimize_size"
1736 "mlas%?\\t%0, %2, %1, %3"
1737 [(set_attr "conds" "set")
1738 (set_attr "type" "mlas")]
1739 )
1740
1741 (define_insn "*mulsi3subsi"
1742 [(set (match_operand:SI 0 "s_register_operand" "=r")
1743 (minus:SI
1744 (match_operand:SI 3 "s_register_operand" "r")
1745 (mult:SI (match_operand:SI 2 "s_register_operand" "r")
1746 (match_operand:SI 1 "s_register_operand" "r"))))]
1747 "TARGET_32BIT && arm_arch_thumb2"
1748 "mls%?\\t%0, %2, %1, %3"
1749 [(set_attr "type" "mla")
1750 (set_attr "predicable" "yes")
1751 (set_attr "predicable_short_it" "no")]
1752 )
1753
1754 (define_expand "maddsidi4"
1755 [(set (match_operand:DI 0 "s_register_operand" "")
1756 (plus:DI
1757 (mult:DI
1758 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1759 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1760 (match_operand:DI 3 "s_register_operand" "")))]
1761 "TARGET_32BIT && arm_arch3m"
1762 "")
1763
1764 (define_insn "*mulsidi3adddi"
1765 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1766 (plus:DI
1767 (mult:DI
1768 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1769 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1770 (match_operand:DI 1 "s_register_operand" "0")))]
1771 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1772 "smlal%?\\t%Q0, %R0, %3, %2"
1773 [(set_attr "type" "smlal")
1774 (set_attr "predicable" "yes")]
1775 )
1776
1777 (define_insn "*mulsidi3adddi_v6"
1778 [(set (match_operand:DI 0 "s_register_operand" "=r")
1779 (plus:DI
1780 (mult:DI
1781 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1782 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1783 (match_operand:DI 1 "s_register_operand" "0")))]
1784 "TARGET_32BIT && arm_arch6"
1785 "smlal%?\\t%Q0, %R0, %3, %2"
1786 [(set_attr "type" "smlal")
1787 (set_attr "predicable" "yes")
1788 (set_attr "predicable_short_it" "no")]
1789 )
1790
1791 ;; 32x32->64 widening multiply.
1792 ;; As with mulsi3, the only difference between the v3-5 and v6+
1793 ;; versions of these patterns is the requirement that the output not
1794 ;; overlap the inputs, but that still means we have to have a named
1795 ;; expander and two different starred insns.
1796
1797 (define_expand "mulsidi3"
1798 [(set (match_operand:DI 0 "s_register_operand" "")
1799 (mult:DI
1800 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1801 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1802 "TARGET_32BIT && arm_arch3m"
1803 ""
1804 )
1805
1806 (define_insn "*mulsidi3_nov6"
1807 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1808 (mult:DI
1809 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1810 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1811 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1812 "smull%?\\t%Q0, %R0, %1, %2"
1813 [(set_attr "type" "smull")
1814 (set_attr "predicable" "yes")]
1815 )
1816
1817 (define_insn "*mulsidi3_v6"
1818 [(set (match_operand:DI 0 "s_register_operand" "=r")
1819 (mult:DI
1820 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1821 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1822 "TARGET_32BIT && arm_arch6"
1823 "smull%?\\t%Q0, %R0, %1, %2"
1824 [(set_attr "type" "smull")
1825 (set_attr "predicable" "yes")
1826 (set_attr "predicable_short_it" "no")]
1827 )
1828
1829 (define_expand "umulsidi3"
1830 [(set (match_operand:DI 0 "s_register_operand" "")
1831 (mult:DI
1832 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1833 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))]
1834 "TARGET_32BIT && arm_arch3m"
1835 ""
1836 )
1837
1838 (define_insn "*umulsidi3_nov6"
1839 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1840 (mult:DI
1841 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1842 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1843 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1844 "umull%?\\t%Q0, %R0, %1, %2"
1845 [(set_attr "type" "umull")
1846 (set_attr "predicable" "yes")]
1847 )
1848
1849 (define_insn "*umulsidi3_v6"
1850 [(set (match_operand:DI 0 "s_register_operand" "=r")
1851 (mult:DI
1852 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1853 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1854 "TARGET_32BIT && arm_arch6"
1855 "umull%?\\t%Q0, %R0, %1, %2"
1856 [(set_attr "type" "umull")
1857 (set_attr "predicable" "yes")
1858 (set_attr "predicable_short_it" "no")]
1859 )
1860
1861 (define_expand "umaddsidi4"
1862 [(set (match_operand:DI 0 "s_register_operand" "")
1863 (plus:DI
1864 (mult:DI
1865 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1866 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1867 (match_operand:DI 3 "s_register_operand" "")))]
1868 "TARGET_32BIT && arm_arch3m"
1869 "")
1870
1871 (define_insn "*umulsidi3adddi"
1872 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1873 (plus:DI
1874 (mult:DI
1875 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1876 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1877 (match_operand:DI 1 "s_register_operand" "0")))]
1878 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1879 "umlal%?\\t%Q0, %R0, %3, %2"
1880 [(set_attr "type" "umlal")
1881 (set_attr "predicable" "yes")]
1882 )
1883
1884 (define_insn "*umulsidi3adddi_v6"
1885 [(set (match_operand:DI 0 "s_register_operand" "=r")
1886 (plus:DI
1887 (mult:DI
1888 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1889 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1890 (match_operand:DI 1 "s_register_operand" "0")))]
1891 "TARGET_32BIT && arm_arch6"
1892 "umlal%?\\t%Q0, %R0, %3, %2"
1893 [(set_attr "type" "umlal")
1894 (set_attr "predicable" "yes")
1895 (set_attr "predicable_short_it" "no")]
1896 )
1897
1898 (define_expand "smulsi3_highpart"
1899 [(parallel
1900 [(set (match_operand:SI 0 "s_register_operand" "")
1901 (truncate:SI
1902 (lshiftrt:DI
1903 (mult:DI
1904 (sign_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1905 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1906 (const_int 32))))
1907 (clobber (match_scratch:SI 3 ""))])]
1908 "TARGET_32BIT && arm_arch3m"
1909 ""
1910 )
1911
1912 (define_insn "*smulsi3_highpart_nov6"
1913 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1914 (truncate:SI
1915 (lshiftrt:DI
1916 (mult:DI
1917 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1918 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1919 (const_int 32))))
1920 (clobber (match_scratch:SI 3 "=&r,&r"))]
1921 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1922 "smull%?\\t%3, %0, %2, %1"
1923 [(set_attr "type" "smull")
1924 (set_attr "predicable" "yes")]
1925 )
1926
1927 (define_insn "*smulsi3_highpart_v6"
1928 [(set (match_operand:SI 0 "s_register_operand" "=r")
1929 (truncate:SI
1930 (lshiftrt:DI
1931 (mult:DI
1932 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1933 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1934 (const_int 32))))
1935 (clobber (match_scratch:SI 3 "=r"))]
1936 "TARGET_32BIT && arm_arch6"
1937 "smull%?\\t%3, %0, %2, %1"
1938 [(set_attr "type" "smull")
1939 (set_attr "predicable" "yes")
1940 (set_attr "predicable_short_it" "no")]
1941 )
1942
1943 (define_expand "umulsi3_highpart"
1944 [(parallel
1945 [(set (match_operand:SI 0 "s_register_operand" "")
1946 (truncate:SI
1947 (lshiftrt:DI
1948 (mult:DI
1949 (zero_extend:DI (match_operand:SI 1 "s_register_operand" ""))
1950 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")))
1951 (const_int 32))))
1952 (clobber (match_scratch:SI 3 ""))])]
1953 "TARGET_32BIT && arm_arch3m"
1954 ""
1955 )
1956
1957 (define_insn "*umulsi3_highpart_nov6"
1958 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1959 (truncate:SI
1960 (lshiftrt:DI
1961 (mult:DI
1962 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r"))
1963 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r")))
1964 (const_int 32))))
1965 (clobber (match_scratch:SI 3 "=&r,&r"))]
1966 "TARGET_32BIT && arm_arch3m && !arm_arch6"
1967 "umull%?\\t%3, %0, %2, %1"
1968 [(set_attr "type" "umull")
1969 (set_attr "predicable" "yes")]
1970 )
1971
1972 (define_insn "*umulsi3_highpart_v6"
1973 [(set (match_operand:SI 0 "s_register_operand" "=r")
1974 (truncate:SI
1975 (lshiftrt:DI
1976 (mult:DI
1977 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1978 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")))
1979 (const_int 32))))
1980 (clobber (match_scratch:SI 3 "=r"))]
1981 "TARGET_32BIT && arm_arch6"
1982 "umull%?\\t%3, %0, %2, %1"
1983 [(set_attr "type" "umull")
1984 (set_attr "predicable" "yes")
1985 (set_attr "predicable_short_it" "no")]
1986 )
1987
1988 (define_insn "mulhisi3"
1989 [(set (match_operand:SI 0 "s_register_operand" "=r")
1990 (mult:SI (sign_extend:SI
1991 (match_operand:HI 1 "s_register_operand" "%r"))
1992 (sign_extend:SI
1993 (match_operand:HI 2 "s_register_operand" "r"))))]
1994 "TARGET_DSP_MULTIPLY"
1995 "smulbb%?\\t%0, %1, %2"
1996 [(set_attr "type" "smulxy")
1997 (set_attr "predicable" "yes")]
1998 )
1999
2000 (define_insn "*mulhisi3tb"
2001 [(set (match_operand:SI 0 "s_register_operand" "=r")
2002 (mult:SI (ashiftrt:SI
2003 (match_operand:SI 1 "s_register_operand" "r")
2004 (const_int 16))
2005 (sign_extend:SI
2006 (match_operand:HI 2 "s_register_operand" "r"))))]
2007 "TARGET_DSP_MULTIPLY"
2008 "smultb%?\\t%0, %1, %2"
2009 [(set_attr "type" "smulxy")
2010 (set_attr "predicable" "yes")
2011 (set_attr "predicable_short_it" "no")]
2012 )
2013
2014 (define_insn "*mulhisi3bt"
2015 [(set (match_operand:SI 0 "s_register_operand" "=r")
2016 (mult:SI (sign_extend:SI
2017 (match_operand:HI 1 "s_register_operand" "r"))
2018 (ashiftrt:SI
2019 (match_operand:SI 2 "s_register_operand" "r")
2020 (const_int 16))))]
2021 "TARGET_DSP_MULTIPLY"
2022 "smulbt%?\\t%0, %1, %2"
2023 [(set_attr "type" "smulxy")
2024 (set_attr "predicable" "yes")
2025 (set_attr "predicable_short_it" "no")]
2026 )
2027
2028 (define_insn "*mulhisi3tt"
2029 [(set (match_operand:SI 0 "s_register_operand" "=r")
2030 (mult:SI (ashiftrt:SI
2031 (match_operand:SI 1 "s_register_operand" "r")
2032 (const_int 16))
2033 (ashiftrt:SI
2034 (match_operand:SI 2 "s_register_operand" "r")
2035 (const_int 16))))]
2036 "TARGET_DSP_MULTIPLY"
2037 "smultt%?\\t%0, %1, %2"
2038 [(set_attr "type" "smulxy")
2039 (set_attr "predicable" "yes")
2040 (set_attr "predicable_short_it" "no")]
2041 )
2042
2043 (define_insn "maddhisi4"
2044 [(set (match_operand:SI 0 "s_register_operand" "=r")
2045 (plus:SI (mult:SI (sign_extend:SI
2046 (match_operand:HI 1 "s_register_operand" "r"))
2047 (sign_extend:SI
2048 (match_operand:HI 2 "s_register_operand" "r")))
2049 (match_operand:SI 3 "s_register_operand" "r")))]
2050 "TARGET_DSP_MULTIPLY"
2051 "smlabb%?\\t%0, %1, %2, %3"
2052 [(set_attr "type" "smlaxy")
2053 (set_attr "predicable" "yes")
2054 (set_attr "predicable_short_it" "no")]
2055 )
2056
2057 ;; Note: there is no maddhisi4ibt because this one is canonical form
2058 (define_insn "*maddhisi4tb"
2059 [(set (match_operand:SI 0 "s_register_operand" "=r")
2060 (plus:SI (mult:SI (ashiftrt:SI
2061 (match_operand:SI 1 "s_register_operand" "r")
2062 (const_int 16))
2063 (sign_extend:SI
2064 (match_operand:HI 2 "s_register_operand" "r")))
2065 (match_operand:SI 3 "s_register_operand" "r")))]
2066 "TARGET_DSP_MULTIPLY"
2067 "smlatb%?\\t%0, %1, %2, %3"
2068 [(set_attr "type" "smlaxy")
2069 (set_attr "predicable" "yes")
2070 (set_attr "predicable_short_it" "no")]
2071 )
2072
2073 (define_insn "*maddhisi4tt"
2074 [(set (match_operand:SI 0 "s_register_operand" "=r")
2075 (plus:SI (mult:SI (ashiftrt:SI
2076 (match_operand:SI 1 "s_register_operand" "r")
2077 (const_int 16))
2078 (ashiftrt:SI
2079 (match_operand:SI 2 "s_register_operand" "r")
2080 (const_int 16)))
2081 (match_operand:SI 3 "s_register_operand" "r")))]
2082 "TARGET_DSP_MULTIPLY"
2083 "smlatt%?\\t%0, %1, %2, %3"
2084 [(set_attr "type" "smlaxy")
2085 (set_attr "predicable" "yes")
2086 (set_attr "predicable_short_it" "no")]
2087 )
2088
2089 (define_insn "maddhidi4"
2090 [(set (match_operand:DI 0 "s_register_operand" "=r")
2091 (plus:DI
2092 (mult:DI (sign_extend:DI
2093 (match_operand:HI 1 "s_register_operand" "r"))
2094 (sign_extend:DI
2095 (match_operand:HI 2 "s_register_operand" "r")))
2096 (match_operand:DI 3 "s_register_operand" "0")))]
2097 "TARGET_DSP_MULTIPLY"
2098 "smlalbb%?\\t%Q0, %R0, %1, %2"
2099 [(set_attr "type" "smlalxy")
2100 (set_attr "predicable" "yes")
2101 (set_attr "predicable_short_it" "no")])
2102
2103 ;; Note: there is no maddhidi4ibt because this one is canonical form
2104 (define_insn "*maddhidi4tb"
2105 [(set (match_operand:DI 0 "s_register_operand" "=r")
2106 (plus:DI
2107 (mult:DI (sign_extend:DI
2108 (ashiftrt:SI
2109 (match_operand:SI 1 "s_register_operand" "r")
2110 (const_int 16)))
2111 (sign_extend:DI
2112 (match_operand:HI 2 "s_register_operand" "r")))
2113 (match_operand:DI 3 "s_register_operand" "0")))]
2114 "TARGET_DSP_MULTIPLY"
2115 "smlaltb%?\\t%Q0, %R0, %1, %2"
2116 [(set_attr "type" "smlalxy")
2117 (set_attr "predicable" "yes")
2118 (set_attr "predicable_short_it" "no")])
2119
2120 (define_insn "*maddhidi4tt"
2121 [(set (match_operand:DI 0 "s_register_operand" "=r")
2122 (plus:DI
2123 (mult:DI (sign_extend:DI
2124 (ashiftrt:SI
2125 (match_operand:SI 1 "s_register_operand" "r")
2126 (const_int 16)))
2127 (sign_extend:DI
2128 (ashiftrt:SI
2129 (match_operand:SI 2 "s_register_operand" "r")
2130 (const_int 16))))
2131 (match_operand:DI 3 "s_register_operand" "0")))]
2132 "TARGET_DSP_MULTIPLY"
2133 "smlaltt%?\\t%Q0, %R0, %1, %2"
2134 [(set_attr "type" "smlalxy")
2135 (set_attr "predicable" "yes")
2136 (set_attr "predicable_short_it" "no")])
2137
2138 (define_expand "mulsf3"
2139 [(set (match_operand:SF 0 "s_register_operand" "")
2140 (mult:SF (match_operand:SF 1 "s_register_operand" "")
2141 (match_operand:SF 2 "s_register_operand" "")))]
2142 "TARGET_32BIT && TARGET_HARD_FLOAT"
2143 "
2144 ")
2145
2146 (define_expand "muldf3"
2147 [(set (match_operand:DF 0 "s_register_operand" "")
2148 (mult:DF (match_operand:DF 1 "s_register_operand" "")
2149 (match_operand:DF 2 "s_register_operand" "")))]
2150 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2151 "
2152 ")
2153 \f
2154 ;; Division insns
2155
2156 (define_expand "divsf3"
2157 [(set (match_operand:SF 0 "s_register_operand" "")
2158 (div:SF (match_operand:SF 1 "s_register_operand" "")
2159 (match_operand:SF 2 "s_register_operand" "")))]
2160 "TARGET_32BIT && TARGET_HARD_FLOAT"
2161 "")
2162
2163 (define_expand "divdf3"
2164 [(set (match_operand:DF 0 "s_register_operand" "")
2165 (div:DF (match_operand:DF 1 "s_register_operand" "")
2166 (match_operand:DF 2 "s_register_operand" "")))]
2167 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2168 "")
2169 \f
2170 ;; Boolean and,ior,xor insns
2171
2172 ;; Split up double word logical operations
2173
2174 ;; Split up simple DImode logical operations. Simply perform the logical
2175 ;; operation on the upper and lower halves of the registers.
2176 (define_split
2177 [(set (match_operand:DI 0 "s_register_operand" "")
2178 (match_operator:DI 6 "logical_binary_operator"
2179 [(match_operand:DI 1 "s_register_operand" "")
2180 (match_operand:DI 2 "s_register_operand" "")]))]
2181 "TARGET_32BIT && reload_completed
2182 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2183 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2184 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2185 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2186 "
2187 {
2188 operands[3] = gen_highpart (SImode, operands[0]);
2189 operands[0] = gen_lowpart (SImode, operands[0]);
2190 operands[4] = gen_highpart (SImode, operands[1]);
2191 operands[1] = gen_lowpart (SImode, operands[1]);
2192 operands[5] = gen_highpart (SImode, operands[2]);
2193 operands[2] = gen_lowpart (SImode, operands[2]);
2194 }"
2195 )
2196
2197 (define_split
2198 [(set (match_operand:DI 0 "s_register_operand" "")
2199 (match_operator:DI 6 "logical_binary_operator"
2200 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2201 (match_operand:DI 1 "s_register_operand" "")]))]
2202 "TARGET_32BIT && reload_completed"
2203 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2204 (set (match_dup 3) (match_op_dup:SI 6
2205 [(ashiftrt:SI (match_dup 2) (const_int 31))
2206 (match_dup 4)]))]
2207 "
2208 {
2209 operands[3] = gen_highpart (SImode, operands[0]);
2210 operands[0] = gen_lowpart (SImode, operands[0]);
2211 operands[4] = gen_highpart (SImode, operands[1]);
2212 operands[1] = gen_lowpart (SImode, operands[1]);
2213 operands[5] = gen_highpart (SImode, operands[2]);
2214 operands[2] = gen_lowpart (SImode, operands[2]);
2215 }"
2216 )
2217
2218 ;; The zero extend of operand 2 means we can just copy the high part of
2219 ;; operand1 into operand0.
2220 (define_split
2221 [(set (match_operand:DI 0 "s_register_operand" "")
2222 (ior:DI
2223 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2224 (match_operand:DI 1 "s_register_operand" "")))]
2225 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2226 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
2227 (set (match_dup 3) (match_dup 4))]
2228 "
2229 {
2230 operands[4] = gen_highpart (SImode, operands[1]);
2231 operands[3] = gen_highpart (SImode, operands[0]);
2232 operands[0] = gen_lowpart (SImode, operands[0]);
2233 operands[1] = gen_lowpart (SImode, operands[1]);
2234 }"
2235 )
2236
2237 ;; The zero extend of operand 2 means we can just copy the high part of
2238 ;; operand1 into operand0.
2239 (define_split
2240 [(set (match_operand:DI 0 "s_register_operand" "")
2241 (xor:DI
2242 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))
2243 (match_operand:DI 1 "s_register_operand" "")))]
2244 "TARGET_32BIT && operands[0] != operands[1] && reload_completed"
2245 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
2246 (set (match_dup 3) (match_dup 4))]
2247 "
2248 {
2249 operands[4] = gen_highpart (SImode, operands[1]);
2250 operands[3] = gen_highpart (SImode, operands[0]);
2251 operands[0] = gen_lowpart (SImode, operands[0]);
2252 operands[1] = gen_lowpart (SImode, operands[1]);
2253 }"
2254 )
2255
2256 (define_expand "anddi3"
2257 [(set (match_operand:DI 0 "s_register_operand" "")
2258 (and:DI (match_operand:DI 1 "s_register_operand" "")
2259 (match_operand:DI 2 "neon_inv_logic_op2" "")))]
2260 "TARGET_32BIT"
2261 ""
2262 )
2263
2264 (define_insn_and_split "*anddi3_insn"
2265 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
2266 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
2267 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))]
2268 "TARGET_32BIT && !TARGET_IWMMXT"
2269 {
2270 switch (which_alternative)
2271 {
2272 case 0: /* fall through */
2273 case 6: return "vand\t%P0, %P1, %P2";
2274 case 1: /* fall through */
2275 case 7: return neon_output_logic_immediate ("vand", &operands[2],
2276 DImode, 1, VALID_NEON_QREG_MODE (DImode));
2277 case 2:
2278 case 3:
2279 case 4:
2280 case 5: /* fall through */
2281 return "#";
2282 default: gcc_unreachable ();
2283 }
2284 }
2285 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
2286 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
2287 [(set (match_dup 3) (match_dup 4))
2288 (set (match_dup 5) (match_dup 6))]
2289 "
2290 {
2291 operands[3] = gen_lowpart (SImode, operands[0]);
2292 operands[5] = gen_highpart (SImode, operands[0]);
2293
2294 operands[4] = simplify_gen_binary (AND, SImode,
2295 gen_lowpart (SImode, operands[1]),
2296 gen_lowpart (SImode, operands[2]));
2297 operands[6] = simplify_gen_binary (AND, SImode,
2298 gen_highpart (SImode, operands[1]),
2299 gen_highpart_mode (SImode, DImode, operands[2]));
2300
2301 }"
2302 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\
2303 multiple,multiple,neon_logic,neon_logic")
2304 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
2305 avoid_neon_for_64bits,avoid_neon_for_64bits")
2306 (set_attr "length" "*,*,8,8,8,8,*,*")
2307 ]
2308 )
2309
2310 (define_insn_and_split "*anddi_zesidi_di"
2311 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2312 (and:DI (zero_extend:DI
2313 (match_operand:SI 2 "s_register_operand" "r,r"))
2314 (match_operand:DI 1 "s_register_operand" "0,r")))]
2315 "TARGET_32BIT"
2316 "#"
2317 "TARGET_32BIT && reload_completed"
2318 ; The zero extend of operand 2 clears the high word of the output
2319 ; operand.
2320 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
2321 (set (match_dup 3) (const_int 0))]
2322 "
2323 {
2324 operands[3] = gen_highpart (SImode, operands[0]);
2325 operands[0] = gen_lowpart (SImode, operands[0]);
2326 operands[1] = gen_lowpart (SImode, operands[1]);
2327 }"
2328 [(set_attr "length" "8")
2329 (set_attr "type" "multiple")]
2330 )
2331
2332 (define_insn "*anddi_sesdi_di"
2333 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2334 (and:DI (sign_extend:DI
2335 (match_operand:SI 2 "s_register_operand" "r,r"))
2336 (match_operand:DI 1 "s_register_operand" "0,r")))]
2337 "TARGET_32BIT"
2338 "#"
2339 [(set_attr "length" "8")
2340 (set_attr "type" "multiple")]
2341 )
2342
2343 (define_expand "andsi3"
2344 [(set (match_operand:SI 0 "s_register_operand" "")
2345 (and:SI (match_operand:SI 1 "s_register_operand" "")
2346 (match_operand:SI 2 "reg_or_int_operand" "")))]
2347 "TARGET_EITHER"
2348 "
2349 if (TARGET_32BIT)
2350 {
2351 if (CONST_INT_P (operands[2]))
2352 {
2353 if (INTVAL (operands[2]) == 255 && arm_arch6)
2354 {
2355 operands[1] = convert_to_mode (QImode, operands[1], 1);
2356 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2357 operands[1]));
2358 DONE;
2359 }
2360 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2361 operands[2] = force_reg (SImode, operands[2]);
2362 else
2363 {
2364 arm_split_constant (AND, SImode, NULL_RTX,
2365 INTVAL (operands[2]), operands[0],
2366 operands[1],
2367 optimize && can_create_pseudo_p ());
2368
2369 DONE;
2370 }
2371 }
2372 }
2373 else /* TARGET_THUMB1 */
2374 {
2375 if (!CONST_INT_P (operands[2]))
2376 {
2377 rtx tmp = force_reg (SImode, operands[2]);
2378 if (rtx_equal_p (operands[0], operands[1]))
2379 operands[2] = tmp;
2380 else
2381 {
2382 operands[2] = operands[1];
2383 operands[1] = tmp;
2384 }
2385 }
2386 else
2387 {
2388 int i;
2389
2390 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2391 {
2392 operands[2] = force_reg (SImode,
2393 GEN_INT (~INTVAL (operands[2])));
2394
2395 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2396
2397 DONE;
2398 }
2399
2400 for (i = 9; i <= 31; i++)
2401 {
2402 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2403 {
2404 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2405 const0_rtx));
2406 DONE;
2407 }
2408 else if ((HOST_WIDE_INT_1 << i) - 1
2409 == ~INTVAL (operands[2]))
2410 {
2411 rtx shift = GEN_INT (i);
2412 rtx reg = gen_reg_rtx (SImode);
2413
2414 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2415 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2416
2417 DONE;
2418 }
2419 }
2420
2421 operands[2] = force_reg (SImode, operands[2]);
2422 }
2423 }
2424 "
2425 )
2426
2427 ; ??? Check split length for Thumb-2
2428 (define_insn_and_split "*arm_andsi3_insn"
2429 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2430 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2431 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2432 "TARGET_32BIT"
2433 "@
2434 and%?\\t%0, %1, %2
2435 and%?\\t%0, %1, %2
2436 bic%?\\t%0, %1, #%B2
2437 and%?\\t%0, %1, %2
2438 #"
2439 "TARGET_32BIT
2440 && CONST_INT_P (operands[2])
2441 && !(const_ok_for_arm (INTVAL (operands[2]))
2442 || const_ok_for_arm (~INTVAL (operands[2])))"
2443 [(clobber (const_int 0))]
2444 "
2445 arm_split_constant (AND, SImode, curr_insn,
2446 INTVAL (operands[2]), operands[0], operands[1], 0);
2447 DONE;
2448 "
2449 [(set_attr "length" "4,4,4,4,16")
2450 (set_attr "predicable" "yes")
2451 (set_attr "predicable_short_it" "no,yes,no,no,no")
2452 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2453 )
2454
2455 (define_insn "*andsi3_compare0"
2456 [(set (reg:CC_NOOV CC_REGNUM)
2457 (compare:CC_NOOV
2458 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2459 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2460 (const_int 0)))
2461 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2462 (and:SI (match_dup 1) (match_dup 2)))]
2463 "TARGET_32BIT"
2464 "@
2465 ands%?\\t%0, %1, %2
2466 bics%?\\t%0, %1, #%B2
2467 ands%?\\t%0, %1, %2"
2468 [(set_attr "conds" "set")
2469 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2470 )
2471
2472 (define_insn "*andsi3_compare0_scratch"
2473 [(set (reg:CC_NOOV CC_REGNUM)
2474 (compare:CC_NOOV
2475 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2476 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2477 (const_int 0)))
2478 (clobber (match_scratch:SI 2 "=X,r,X"))]
2479 "TARGET_32BIT"
2480 "@
2481 tst%?\\t%0, %1
2482 bics%?\\t%2, %0, #%B1
2483 tst%?\\t%0, %1"
2484 [(set_attr "conds" "set")
2485 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2486 )
2487
2488 (define_insn "*zeroextractsi_compare0_scratch"
2489 [(set (reg:CC_NOOV CC_REGNUM)
2490 (compare:CC_NOOV (zero_extract:SI
2491 (match_operand:SI 0 "s_register_operand" "r")
2492 (match_operand 1 "const_int_operand" "n")
2493 (match_operand 2 "const_int_operand" "n"))
2494 (const_int 0)))]
2495 "TARGET_32BIT
2496 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2497 && INTVAL (operands[1]) > 0
2498 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2499 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2500 "*
2501 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2502 << INTVAL (operands[2]));
2503 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2504 return \"\";
2505 "
2506 [(set_attr "conds" "set")
2507 (set_attr "predicable" "yes")
2508 (set_attr "predicable_short_it" "no")
2509 (set_attr "type" "logics_imm")]
2510 )
2511
2512 (define_insn_and_split "*ne_zeroextractsi"
2513 [(set (match_operand:SI 0 "s_register_operand" "=r")
2514 (ne:SI (zero_extract:SI
2515 (match_operand:SI 1 "s_register_operand" "r")
2516 (match_operand:SI 2 "const_int_operand" "n")
2517 (match_operand:SI 3 "const_int_operand" "n"))
2518 (const_int 0)))
2519 (clobber (reg:CC CC_REGNUM))]
2520 "TARGET_32BIT
2521 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2522 && INTVAL (operands[2]) > 0
2523 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2524 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2525 "#"
2526 "TARGET_32BIT
2527 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2528 && INTVAL (operands[2]) > 0
2529 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2530 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2531 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2532 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2533 (const_int 0)))
2534 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2535 (set (match_dup 0)
2536 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2537 (match_dup 0) (const_int 1)))]
2538 "
2539 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2540 << INTVAL (operands[3]));
2541 "
2542 [(set_attr "conds" "clob")
2543 (set (attr "length")
2544 (if_then_else (eq_attr "is_thumb" "yes")
2545 (const_int 12)
2546 (const_int 8)))
2547 (set_attr "type" "multiple")]
2548 )
2549
2550 (define_insn_and_split "*ne_zeroextractsi_shifted"
2551 [(set (match_operand:SI 0 "s_register_operand" "=r")
2552 (ne:SI (zero_extract:SI
2553 (match_operand:SI 1 "s_register_operand" "r")
2554 (match_operand:SI 2 "const_int_operand" "n")
2555 (const_int 0))
2556 (const_int 0)))
2557 (clobber (reg:CC CC_REGNUM))]
2558 "TARGET_ARM"
2559 "#"
2560 "TARGET_ARM"
2561 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2562 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2563 (const_int 0)))
2564 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2565 (set (match_dup 0)
2566 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2567 (match_dup 0) (const_int 1)))]
2568 "
2569 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2570 "
2571 [(set_attr "conds" "clob")
2572 (set_attr "length" "8")
2573 (set_attr "type" "multiple")]
2574 )
2575
2576 (define_insn_and_split "*ite_ne_zeroextractsi"
2577 [(set (match_operand:SI 0 "s_register_operand" "=r")
2578 (if_then_else:SI (ne (zero_extract:SI
2579 (match_operand:SI 1 "s_register_operand" "r")
2580 (match_operand:SI 2 "const_int_operand" "n")
2581 (match_operand:SI 3 "const_int_operand" "n"))
2582 (const_int 0))
2583 (match_operand:SI 4 "arm_not_operand" "rIK")
2584 (const_int 0)))
2585 (clobber (reg:CC CC_REGNUM))]
2586 "TARGET_ARM
2587 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2588 && INTVAL (operands[2]) > 0
2589 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2590 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2591 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2592 "#"
2593 "TARGET_ARM
2594 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2595 && INTVAL (operands[2]) > 0
2596 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2597 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2598 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2599 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2600 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2601 (const_int 0)))
2602 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2603 (set (match_dup 0)
2604 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2605 (match_dup 0) (match_dup 4)))]
2606 "
2607 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2608 << INTVAL (operands[3]));
2609 "
2610 [(set_attr "conds" "clob")
2611 (set_attr "length" "8")
2612 (set_attr "type" "multiple")]
2613 )
2614
2615 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2616 [(set (match_operand:SI 0 "s_register_operand" "=r")
2617 (if_then_else:SI (ne (zero_extract:SI
2618 (match_operand:SI 1 "s_register_operand" "r")
2619 (match_operand:SI 2 "const_int_operand" "n")
2620 (const_int 0))
2621 (const_int 0))
2622 (match_operand:SI 3 "arm_not_operand" "rIK")
2623 (const_int 0)))
2624 (clobber (reg:CC CC_REGNUM))]
2625 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2626 "#"
2627 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2628 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2629 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2630 (const_int 0)))
2631 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2632 (set (match_dup 0)
2633 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2634 (match_dup 0) (match_dup 3)))]
2635 "
2636 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2637 "
2638 [(set_attr "conds" "clob")
2639 (set_attr "length" "8")
2640 (set_attr "type" "multiple")]
2641 )
2642
2643 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2644 (define_split
2645 [(set (match_operand:SI 0 "s_register_operand" "")
2646 (match_operator:SI 1 "shiftable_operator"
2647 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2648 (match_operand:SI 3 "const_int_operand" "")
2649 (match_operand:SI 4 "const_int_operand" ""))
2650 (match_operand:SI 5 "s_register_operand" "")]))
2651 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2652 "TARGET_ARM"
2653 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2654 (set (match_dup 0)
2655 (match_op_dup 1
2656 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2657 (match_dup 5)]))]
2658 "{
2659 HOST_WIDE_INT temp = INTVAL (operands[3]);
2660
2661 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2662 operands[4] = GEN_INT (32 - temp);
2663 }"
2664 )
2665
2666 (define_split
2667 [(set (match_operand:SI 0 "s_register_operand" "")
2668 (match_operator:SI 1 "shiftable_operator"
2669 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2670 (match_operand:SI 3 "const_int_operand" "")
2671 (match_operand:SI 4 "const_int_operand" ""))
2672 (match_operand:SI 5 "s_register_operand" "")]))
2673 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2674 "TARGET_ARM"
2675 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2676 (set (match_dup 0)
2677 (match_op_dup 1
2678 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2679 (match_dup 5)]))]
2680 "{
2681 HOST_WIDE_INT temp = INTVAL (operands[3]);
2682
2683 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2684 operands[4] = GEN_INT (32 - temp);
2685 }"
2686 )
2687
2688 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2689 ;;; represented by the bitfield, then this will produce incorrect results.
2690 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2691 ;;; which have a real bit-field insert instruction, the truncation happens
2692 ;;; in the bit-field insert instruction itself. Since arm does not have a
2693 ;;; bit-field insert instruction, we would have to emit code here to truncate
2694 ;;; the value before we insert. This loses some of the advantage of having
2695 ;;; this insv pattern, so this pattern needs to be reevalutated.
2696
2697 (define_expand "insv"
2698 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2699 (match_operand 1 "general_operand" "")
2700 (match_operand 2 "general_operand" ""))
2701 (match_operand 3 "reg_or_int_operand" ""))]
2702 "TARGET_ARM || arm_arch_thumb2"
2703 "
2704 {
2705 int start_bit = INTVAL (operands[2]);
2706 int width = INTVAL (operands[1]);
2707 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2708 rtx target, subtarget;
2709
2710 if (arm_arch_thumb2)
2711 {
2712 if (unaligned_access && MEM_P (operands[0])
2713 && s_register_operand (operands[3], GET_MODE (operands[3]))
2714 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2715 {
2716 rtx base_addr;
2717
2718 if (BYTES_BIG_ENDIAN)
2719 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2720 - start_bit;
2721
2722 if (width == 32)
2723 {
2724 base_addr = adjust_address (operands[0], SImode,
2725 start_bit / BITS_PER_UNIT);
2726 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2727 }
2728 else
2729 {
2730 rtx tmp = gen_reg_rtx (HImode);
2731
2732 base_addr = adjust_address (operands[0], HImode,
2733 start_bit / BITS_PER_UNIT);
2734 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2735 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2736 }
2737 DONE;
2738 }
2739 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2740 {
2741 bool use_bfi = TRUE;
2742
2743 if (CONST_INT_P (operands[3]))
2744 {
2745 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2746
2747 if (val == 0)
2748 {
2749 emit_insn (gen_insv_zero (operands[0], operands[1],
2750 operands[2]));
2751 DONE;
2752 }
2753
2754 /* See if the set can be done with a single orr instruction. */
2755 if (val == mask && const_ok_for_arm (val << start_bit))
2756 use_bfi = FALSE;
2757 }
2758
2759 if (use_bfi)
2760 {
2761 if (!REG_P (operands[3]))
2762 operands[3] = force_reg (SImode, operands[3]);
2763
2764 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2765 operands[3]));
2766 DONE;
2767 }
2768 }
2769 else
2770 FAIL;
2771 }
2772
2773 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2774 FAIL;
2775
2776 target = copy_rtx (operands[0]);
2777 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2778 subreg as the final target. */
2779 if (GET_CODE (target) == SUBREG)
2780 {
2781 subtarget = gen_reg_rtx (SImode);
2782 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2783 < GET_MODE_SIZE (SImode))
2784 target = SUBREG_REG (target);
2785 }
2786 else
2787 subtarget = target;
2788
2789 if (CONST_INT_P (operands[3]))
2790 {
2791 /* Since we are inserting a known constant, we may be able to
2792 reduce the number of bits that we have to clear so that
2793 the mask becomes simple. */
2794 /* ??? This code does not check to see if the new mask is actually
2795 simpler. It may not be. */
2796 rtx op1 = gen_reg_rtx (SImode);
2797 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2798 start of this pattern. */
2799 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2800 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2801
2802 emit_insn (gen_andsi3 (op1, operands[0],
2803 gen_int_mode (~mask2, SImode)));
2804 emit_insn (gen_iorsi3 (subtarget, op1,
2805 gen_int_mode (op3_value << start_bit, SImode)));
2806 }
2807 else if (start_bit == 0
2808 && !(const_ok_for_arm (mask)
2809 || const_ok_for_arm (~mask)))
2810 {
2811 /* A Trick, since we are setting the bottom bits in the word,
2812 we can shift operand[3] up, operand[0] down, OR them together
2813 and rotate the result back again. This takes 3 insns, and
2814 the third might be mergeable into another op. */
2815 /* The shift up copes with the possibility that operand[3] is
2816 wider than the bitfield. */
2817 rtx op0 = gen_reg_rtx (SImode);
2818 rtx op1 = gen_reg_rtx (SImode);
2819
2820 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2821 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2822 emit_insn (gen_iorsi3 (op1, op1, op0));
2823 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2824 }
2825 else if ((width + start_bit == 32)
2826 && !(const_ok_for_arm (mask)
2827 || const_ok_for_arm (~mask)))
2828 {
2829 /* Similar trick, but slightly less efficient. */
2830
2831 rtx op0 = gen_reg_rtx (SImode);
2832 rtx op1 = gen_reg_rtx (SImode);
2833
2834 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2835 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2836 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2837 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2838 }
2839 else
2840 {
2841 rtx op0 = gen_int_mode (mask, SImode);
2842 rtx op1 = gen_reg_rtx (SImode);
2843 rtx op2 = gen_reg_rtx (SImode);
2844
2845 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2846 {
2847 rtx tmp = gen_reg_rtx (SImode);
2848
2849 emit_insn (gen_movsi (tmp, op0));
2850 op0 = tmp;
2851 }
2852
2853 /* Mask out any bits in operand[3] that are not needed. */
2854 emit_insn (gen_andsi3 (op1, operands[3], op0));
2855
2856 if (CONST_INT_P (op0)
2857 && (const_ok_for_arm (mask << start_bit)
2858 || const_ok_for_arm (~(mask << start_bit))))
2859 {
2860 op0 = gen_int_mode (~(mask << start_bit), SImode);
2861 emit_insn (gen_andsi3 (op2, operands[0], op0));
2862 }
2863 else
2864 {
2865 if (CONST_INT_P (op0))
2866 {
2867 rtx tmp = gen_reg_rtx (SImode);
2868
2869 emit_insn (gen_movsi (tmp, op0));
2870 op0 = tmp;
2871 }
2872
2873 if (start_bit != 0)
2874 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2875
2876 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2877 }
2878
2879 if (start_bit != 0)
2880 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2881
2882 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2883 }
2884
2885 if (subtarget != target)
2886 {
2887 /* If TARGET is still a SUBREG, then it must be wider than a word,
2888 so we must be careful only to set the subword we were asked to. */
2889 if (GET_CODE (target) == SUBREG)
2890 emit_move_insn (target, subtarget);
2891 else
2892 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2893 }
2894
2895 DONE;
2896 }"
2897 )
2898
2899 (define_insn "insv_zero"
2900 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2901 (match_operand:SI 1 "const_int_M_operand" "M")
2902 (match_operand:SI 2 "const_int_M_operand" "M"))
2903 (const_int 0))]
2904 "arm_arch_thumb2"
2905 "bfc%?\t%0, %2, %1"
2906 [(set_attr "length" "4")
2907 (set_attr "predicable" "yes")
2908 (set_attr "predicable_short_it" "no")
2909 (set_attr "type" "bfm")]
2910 )
2911
2912 (define_insn "insv_t2"
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 (match_operand:SI 3 "s_register_operand" "r"))]
2917 "arm_arch_thumb2"
2918 "bfi%?\t%0, %3, %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 ; constants for op 2 will never be given to these patterns.
2926 (define_insn_and_split "*anddi_notdi_di"
2927 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2928 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
2929 (match_operand:DI 2 "s_register_operand" "r,0")))]
2930 "TARGET_32BIT"
2931 "#"
2932 "TARGET_32BIT && reload_completed
2933 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0])))
2934 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2935 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
2936 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
2937 "
2938 {
2939 operands[3] = gen_highpart (SImode, operands[0]);
2940 operands[0] = gen_lowpart (SImode, operands[0]);
2941 operands[4] = gen_highpart (SImode, operands[1]);
2942 operands[1] = gen_lowpart (SImode, operands[1]);
2943 operands[5] = gen_highpart (SImode, operands[2]);
2944 operands[2] = gen_lowpart (SImode, operands[2]);
2945 }"
2946 [(set_attr "length" "8")
2947 (set_attr "predicable" "yes")
2948 (set_attr "type" "multiple")]
2949 )
2950
2951 (define_insn_and_split "*anddi_notzesidi_di"
2952 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
2953 (and:DI (not:DI (zero_extend:DI
2954 (match_operand:SI 2 "s_register_operand" "r,r")))
2955 (match_operand:DI 1 "s_register_operand" "0,?r")))]
2956 "TARGET_32BIT"
2957 "@
2958 bic%?\\t%Q0, %Q1, %2
2959 #"
2960 ; (not (zero_extend ...)) allows us to just copy the high word from
2961 ; operand1 to operand0.
2962 "TARGET_32BIT
2963 && reload_completed
2964 && operands[0] != operands[1]"
2965 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2966 (set (match_dup 3) (match_dup 4))]
2967 "
2968 {
2969 operands[3] = gen_highpart (SImode, operands[0]);
2970 operands[0] = gen_lowpart (SImode, operands[0]);
2971 operands[4] = gen_highpart (SImode, operands[1]);
2972 operands[1] = gen_lowpart (SImode, operands[1]);
2973 }"
2974 [(set_attr "length" "4,8")
2975 (set_attr "predicable" "yes")
2976 (set_attr "predicable_short_it" "no")
2977 (set_attr "type" "multiple")]
2978 )
2979
2980 (define_insn_and_split "*anddi_notdi_zesidi"
2981 [(set (match_operand:DI 0 "s_register_operand" "=r")
2982 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r"))
2983 (zero_extend:DI
2984 (match_operand:SI 1 "s_register_operand" "r"))))]
2985 "TARGET_32BIT"
2986 "#"
2987 "TARGET_32BIT && reload_completed"
2988 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
2989 (set (match_dup 3) (const_int 0))]
2990 "
2991 {
2992 operands[3] = gen_highpart (SImode, operands[0]);
2993 operands[0] = gen_lowpart (SImode, operands[0]);
2994 operands[2] = gen_lowpart (SImode, operands[2]);
2995 }"
2996 [(set_attr "length" "8")
2997 (set_attr "predicable" "yes")
2998 (set_attr "predicable_short_it" "no")
2999 (set_attr "type" "multiple")]
3000 )
3001
3002 (define_insn_and_split "*anddi_notsesidi_di"
3003 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3004 (and:DI (not:DI (sign_extend:DI
3005 (match_operand:SI 2 "s_register_operand" "r,r")))
3006 (match_operand:DI 1 "s_register_operand" "0,r")))]
3007 "TARGET_32BIT"
3008 "#"
3009 "TARGET_32BIT && reload_completed"
3010 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1)))
3011 (set (match_dup 3) (and:SI (not:SI
3012 (ashiftrt:SI (match_dup 2) (const_int 31)))
3013 (match_dup 4)))]
3014 "
3015 {
3016 operands[3] = gen_highpart (SImode, operands[0]);
3017 operands[0] = gen_lowpart (SImode, operands[0]);
3018 operands[4] = gen_highpart (SImode, operands[1]);
3019 operands[1] = gen_lowpart (SImode, operands[1]);
3020 }"
3021 [(set_attr "length" "8")
3022 (set_attr "predicable" "yes")
3023 (set_attr "predicable_short_it" "no")
3024 (set_attr "type" "multiple")]
3025 )
3026
3027 (define_insn "andsi_notsi_si"
3028 [(set (match_operand:SI 0 "s_register_operand" "=r")
3029 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3030 (match_operand:SI 1 "s_register_operand" "r")))]
3031 "TARGET_32BIT"
3032 "bic%?\\t%0, %1, %2"
3033 [(set_attr "predicable" "yes")
3034 (set_attr "predicable_short_it" "no")
3035 (set_attr "type" "logic_reg")]
3036 )
3037
3038 (define_insn "andsi_not_shiftsi_si"
3039 [(set (match_operand:SI 0 "s_register_operand" "=r")
3040 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
3041 [(match_operand:SI 2 "s_register_operand" "r")
3042 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
3043 (match_operand:SI 1 "s_register_operand" "r")))]
3044 "TARGET_ARM"
3045 "bic%?\\t%0, %1, %2%S4"
3046 [(set_attr "predicable" "yes")
3047 (set_attr "shift" "2")
3048 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
3049 (const_string "logic_shift_imm")
3050 (const_string "logic_shift_reg")))]
3051 )
3052
3053 ;; Shifted bics pattern used to set up CC status register and not reusing
3054 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
3055 ;; does not support shift by register.
3056 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
3057 [(set (reg:CC_NOOV CC_REGNUM)
3058 (compare:CC_NOOV
3059 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3060 [(match_operand:SI 1 "s_register_operand" "r")
3061 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3062 (match_operand:SI 3 "s_register_operand" "r"))
3063 (const_int 0)))
3064 (clobber (match_scratch:SI 4 "=r"))]
3065 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3066 "bics%?\\t%4, %3, %1%S0"
3067 [(set_attr "predicable" "yes")
3068 (set_attr "predicable_short_it" "no")
3069 (set_attr "conds" "set")
3070 (set_attr "shift" "1")
3071 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3072 (const_string "logic_shift_imm")
3073 (const_string "logic_shift_reg")))]
3074 )
3075
3076 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
3077 ;; getting reused later.
3078 (define_insn "andsi_not_shiftsi_si_scc"
3079 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
3080 (compare:CC_NOOV
3081 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
3082 [(match_operand:SI 1 "s_register_operand" "r")
3083 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
3084 (match_operand:SI 3 "s_register_operand" "r"))
3085 (const_int 0)))
3086 (set (match_operand:SI 4 "s_register_operand" "=r")
3087 (and:SI (not:SI (match_op_dup 0
3088 [(match_dup 1)
3089 (match_dup 2)]))
3090 (match_dup 3)))])]
3091 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
3092 "bics%?\\t%4, %3, %1%S0"
3093 [(set_attr "predicable" "yes")
3094 (set_attr "predicable_short_it" "no")
3095 (set_attr "conds" "set")
3096 (set_attr "shift" "1")
3097 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
3098 (const_string "logic_shift_imm")
3099 (const_string "logic_shift_reg")))]
3100 )
3101
3102 (define_insn "*andsi_notsi_si_compare0"
3103 [(set (reg:CC_NOOV CC_REGNUM)
3104 (compare:CC_NOOV
3105 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3106 (match_operand:SI 1 "s_register_operand" "r"))
3107 (const_int 0)))
3108 (set (match_operand:SI 0 "s_register_operand" "=r")
3109 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
3110 "TARGET_32BIT"
3111 "bics\\t%0, %1, %2"
3112 [(set_attr "conds" "set")
3113 (set_attr "type" "logics_shift_reg")]
3114 )
3115
3116 (define_insn "*andsi_notsi_si_compare0_scratch"
3117 [(set (reg:CC_NOOV CC_REGNUM)
3118 (compare:CC_NOOV
3119 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
3120 (match_operand:SI 1 "s_register_operand" "r"))
3121 (const_int 0)))
3122 (clobber (match_scratch:SI 0 "=r"))]
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_expand "iordi3"
3130 [(set (match_operand:DI 0 "s_register_operand" "")
3131 (ior:DI (match_operand:DI 1 "s_register_operand" "")
3132 (match_operand:DI 2 "neon_logic_op2" "")))]
3133 "TARGET_32BIT"
3134 ""
3135 )
3136
3137 (define_insn_and_split "*iordi3_insn"
3138 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w")
3139 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0")
3140 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))]
3141 "TARGET_32BIT && !TARGET_IWMMXT"
3142 {
3143 switch (which_alternative)
3144 {
3145 case 0: /* fall through */
3146 case 6: return "vorr\t%P0, %P1, %P2";
3147 case 1: /* fall through */
3148 case 7: return neon_output_logic_immediate ("vorr", &operands[2],
3149 DImode, 0, VALID_NEON_QREG_MODE (DImode));
3150 case 2:
3151 case 3:
3152 case 4:
3153 case 5:
3154 return "#";
3155 default: gcc_unreachable ();
3156 }
3157 }
3158 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3159 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3160 [(set (match_dup 3) (match_dup 4))
3161 (set (match_dup 5) (match_dup 6))]
3162 "
3163 {
3164 operands[3] = gen_lowpart (SImode, operands[0]);
3165 operands[5] = gen_highpart (SImode, operands[0]);
3166
3167 operands[4] = simplify_gen_binary (IOR, SImode,
3168 gen_lowpart (SImode, operands[1]),
3169 gen_lowpart (SImode, operands[2]));
3170 operands[6] = simplify_gen_binary (IOR, SImode,
3171 gen_highpart (SImode, operands[1]),
3172 gen_highpart_mode (SImode, DImode, operands[2]));
3173
3174 }"
3175 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\
3176 multiple,neon_logic,neon_logic")
3177 (set_attr "length" "*,*,8,8,8,8,*,*")
3178 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
3179 )
3180
3181 (define_insn "*iordi_zesidi_di"
3182 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3183 (ior:DI (zero_extend:DI
3184 (match_operand:SI 2 "s_register_operand" "r,r"))
3185 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3186 "TARGET_32BIT"
3187 "@
3188 orr%?\\t%Q0, %Q1, %2
3189 #"
3190 [(set_attr "length" "4,8")
3191 (set_attr "predicable" "yes")
3192 (set_attr "predicable_short_it" "no")
3193 (set_attr "type" "logic_reg,multiple")]
3194 )
3195
3196 (define_insn "*iordi_sesidi_di"
3197 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3198 (ior:DI (sign_extend:DI
3199 (match_operand:SI 2 "s_register_operand" "r,r"))
3200 (match_operand:DI 1 "s_register_operand" "0,r")))]
3201 "TARGET_32BIT"
3202 "#"
3203 [(set_attr "length" "8")
3204 (set_attr "predicable" "yes")
3205 (set_attr "type" "multiple")]
3206 )
3207
3208 (define_expand "iorsi3"
3209 [(set (match_operand:SI 0 "s_register_operand" "")
3210 (ior:SI (match_operand:SI 1 "s_register_operand" "")
3211 (match_operand:SI 2 "reg_or_int_operand" "")))]
3212 "TARGET_EITHER"
3213 "
3214 if (CONST_INT_P (operands[2]))
3215 {
3216 if (TARGET_32BIT)
3217 {
3218 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
3219 operands[2] = force_reg (SImode, operands[2]);
3220 else
3221 {
3222 arm_split_constant (IOR, SImode, NULL_RTX,
3223 INTVAL (operands[2]), operands[0],
3224 operands[1],
3225 optimize && can_create_pseudo_p ());
3226 DONE;
3227 }
3228 }
3229 else /* TARGET_THUMB1 */
3230 {
3231 rtx tmp = force_reg (SImode, operands[2]);
3232 if (rtx_equal_p (operands[0], operands[1]))
3233 operands[2] = tmp;
3234 else
3235 {
3236 operands[2] = operands[1];
3237 operands[1] = tmp;
3238 }
3239 }
3240 }
3241 "
3242 )
3243
3244 (define_insn_and_split "*iorsi3_insn"
3245 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
3246 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
3247 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
3248 "TARGET_32BIT"
3249 "@
3250 orr%?\\t%0, %1, %2
3251 orr%?\\t%0, %1, %2
3252 orn%?\\t%0, %1, #%B2
3253 orr%?\\t%0, %1, %2
3254 #"
3255 "TARGET_32BIT
3256 && CONST_INT_P (operands[2])
3257 && !(const_ok_for_arm (INTVAL (operands[2]))
3258 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
3259 [(clobber (const_int 0))]
3260 {
3261 arm_split_constant (IOR, SImode, curr_insn,
3262 INTVAL (operands[2]), operands[0], operands[1], 0);
3263 DONE;
3264 }
3265 [(set_attr "length" "4,4,4,4,16")
3266 (set_attr "arch" "32,t2,t2,32,32")
3267 (set_attr "predicable" "yes")
3268 (set_attr "predicable_short_it" "no,yes,no,no,no")
3269 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
3270 )
3271
3272 (define_peephole2
3273 [(match_scratch:SI 3 "r")
3274 (set (match_operand:SI 0 "arm_general_register_operand" "")
3275 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
3276 (match_operand:SI 2 "const_int_operand" "")))]
3277 "TARGET_ARM
3278 && !const_ok_for_arm (INTVAL (operands[2]))
3279 && const_ok_for_arm (~INTVAL (operands[2]))"
3280 [(set (match_dup 3) (match_dup 2))
3281 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
3282 ""
3283 )
3284
3285 (define_insn "*iorsi3_compare0"
3286 [(set (reg:CC_NOOV CC_REGNUM)
3287 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3288 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3289 (const_int 0)))
3290 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3291 (ior:SI (match_dup 1) (match_dup 2)))]
3292 "TARGET_32BIT"
3293 "orrs%?\\t%0, %1, %2"
3294 [(set_attr "conds" "set")
3295 (set_attr "type" "logics_imm,logics_reg")]
3296 )
3297
3298 (define_insn "*iorsi3_compare0_scratch"
3299 [(set (reg:CC_NOOV CC_REGNUM)
3300 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r")
3301 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3302 (const_int 0)))
3303 (clobber (match_scratch:SI 0 "=r,r"))]
3304 "TARGET_32BIT"
3305 "orrs%?\\t%0, %1, %2"
3306 [(set_attr "conds" "set")
3307 (set_attr "type" "logics_imm,logics_reg")]
3308 )
3309
3310 (define_expand "xordi3"
3311 [(set (match_operand:DI 0 "s_register_operand" "")
3312 (xor:DI (match_operand:DI 1 "s_register_operand" "")
3313 (match_operand:DI 2 "arm_xordi_operand" "")))]
3314 "TARGET_32BIT"
3315 ""
3316 )
3317
3318 (define_insn_and_split "*xordi3_insn"
3319 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w")
3320 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w")
3321 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))]
3322 "TARGET_32BIT && !TARGET_IWMMXT"
3323 {
3324 switch (which_alternative)
3325 {
3326 case 1:
3327 case 2:
3328 case 3:
3329 case 4: /* fall through */
3330 return "#";
3331 case 0: /* fall through */
3332 case 5: return "veor\t%P0, %P1, %P2";
3333 default: gcc_unreachable ();
3334 }
3335 }
3336 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed
3337 && !(IS_VFP_REGNUM (REGNO (operands[0])))"
3338 [(set (match_dup 3) (match_dup 4))
3339 (set (match_dup 5) (match_dup 6))]
3340 "
3341 {
3342 operands[3] = gen_lowpart (SImode, operands[0]);
3343 operands[5] = gen_highpart (SImode, operands[0]);
3344
3345 operands[4] = simplify_gen_binary (XOR, SImode,
3346 gen_lowpart (SImode, operands[1]),
3347 gen_lowpart (SImode, operands[2]));
3348 operands[6] = simplify_gen_binary (XOR, SImode,
3349 gen_highpart (SImode, operands[1]),
3350 gen_highpart_mode (SImode, DImode, operands[2]));
3351
3352 }"
3353 [(set_attr "length" "*,8,8,8,8,*")
3354 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic")
3355 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
3356 )
3357
3358 (define_insn "*xordi_zesidi_di"
3359 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3360 (xor:DI (zero_extend:DI
3361 (match_operand:SI 2 "s_register_operand" "r,r"))
3362 (match_operand:DI 1 "s_register_operand" "0,?r")))]
3363 "TARGET_32BIT"
3364 "@
3365 eor%?\\t%Q0, %Q1, %2
3366 #"
3367 [(set_attr "length" "4,8")
3368 (set_attr "predicable" "yes")
3369 (set_attr "predicable_short_it" "no")
3370 (set_attr "type" "logic_reg")]
3371 )
3372
3373 (define_insn "*xordi_sesidi_di"
3374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
3375 (xor:DI (sign_extend:DI
3376 (match_operand:SI 2 "s_register_operand" "r,r"))
3377 (match_operand:DI 1 "s_register_operand" "0,r")))]
3378 "TARGET_32BIT"
3379 "#"
3380 [(set_attr "length" "8")
3381 (set_attr "predicable" "yes")
3382 (set_attr "type" "multiple")]
3383 )
3384
3385 (define_expand "xorsi3"
3386 [(set (match_operand:SI 0 "s_register_operand" "")
3387 (xor:SI (match_operand:SI 1 "s_register_operand" "")
3388 (match_operand:SI 2 "reg_or_int_operand" "")))]
3389 "TARGET_EITHER"
3390 "if (CONST_INT_P (operands[2]))
3391 {
3392 if (TARGET_32BIT)
3393 {
3394 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
3395 operands[2] = force_reg (SImode, operands[2]);
3396 else
3397 {
3398 arm_split_constant (XOR, SImode, NULL_RTX,
3399 INTVAL (operands[2]), operands[0],
3400 operands[1],
3401 optimize && can_create_pseudo_p ());
3402 DONE;
3403 }
3404 }
3405 else /* TARGET_THUMB1 */
3406 {
3407 rtx tmp = force_reg (SImode, operands[2]);
3408 if (rtx_equal_p (operands[0], operands[1]))
3409 operands[2] = tmp;
3410 else
3411 {
3412 operands[2] = operands[1];
3413 operands[1] = tmp;
3414 }
3415 }
3416 }"
3417 )
3418
3419 (define_insn_and_split "*arm_xorsi3"
3420 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
3421 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
3422 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
3423 "TARGET_32BIT"
3424 "@
3425 eor%?\\t%0, %1, %2
3426 eor%?\\t%0, %1, %2
3427 eor%?\\t%0, %1, %2
3428 #"
3429 "TARGET_32BIT
3430 && CONST_INT_P (operands[2])
3431 && !const_ok_for_arm (INTVAL (operands[2]))"
3432 [(clobber (const_int 0))]
3433 {
3434 arm_split_constant (XOR, SImode, curr_insn,
3435 INTVAL (operands[2]), operands[0], operands[1], 0);
3436 DONE;
3437 }
3438 [(set_attr "length" "4,4,4,16")
3439 (set_attr "predicable" "yes")
3440 (set_attr "predicable_short_it" "no,yes,no,no")
3441 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
3442 )
3443
3444 (define_insn "*xorsi3_compare0"
3445 [(set (reg:CC_NOOV CC_REGNUM)
3446 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
3447 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
3448 (const_int 0)))
3449 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3450 (xor:SI (match_dup 1) (match_dup 2)))]
3451 "TARGET_32BIT"
3452 "eors%?\\t%0, %1, %2"
3453 [(set_attr "conds" "set")
3454 (set_attr "type" "logics_imm,logics_reg")]
3455 )
3456
3457 (define_insn "*xorsi3_compare0_scratch"
3458 [(set (reg:CC_NOOV CC_REGNUM)
3459 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3460 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3461 (const_int 0)))]
3462 "TARGET_32BIT"
3463 "teq%?\\t%0, %1"
3464 [(set_attr "conds" "set")
3465 (set_attr "type" "logics_imm,logics_reg")]
3466 )
3467
3468 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3469 ; (NOT D) we can sometimes merge the final NOT into one of the following
3470 ; insns.
3471
3472 (define_split
3473 [(set (match_operand:SI 0 "s_register_operand" "")
3474 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3475 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3476 (match_operand:SI 3 "arm_rhs_operand" "")))
3477 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3478 "TARGET_32BIT"
3479 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3480 (not:SI (match_dup 3))))
3481 (set (match_dup 0) (not:SI (match_dup 4)))]
3482 ""
3483 )
3484
3485 (define_insn_and_split "*andsi_iorsi3_notsi"
3486 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3487 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3488 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3489 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3490 "TARGET_32BIT"
3491 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3492 "&& reload_completed"
3493 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3494 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3495 {
3496 /* If operands[3] is a constant make sure to fold the NOT into it
3497 to avoid creating a NOT of a CONST_INT. */
3498 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3499 if (CONST_INT_P (not_rtx))
3500 {
3501 operands[4] = operands[0];
3502 operands[5] = not_rtx;
3503 }
3504 else
3505 {
3506 operands[5] = operands[0];
3507 operands[4] = not_rtx;
3508 }
3509 }
3510 [(set_attr "length" "8")
3511 (set_attr "ce_count" "2")
3512 (set_attr "predicable" "yes")
3513 (set_attr "predicable_short_it" "no")
3514 (set_attr "type" "multiple")]
3515 )
3516
3517 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3518 ; insns are available?
3519 (define_split
3520 [(set (match_operand:SI 0 "s_register_operand" "")
3521 (match_operator:SI 1 "logical_binary_operator"
3522 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3523 (match_operand:SI 3 "const_int_operand" "")
3524 (match_operand:SI 4 "const_int_operand" ""))
3525 (match_operator:SI 9 "logical_binary_operator"
3526 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3527 (match_operand:SI 6 "const_int_operand" ""))
3528 (match_operand:SI 7 "s_register_operand" "")])]))
3529 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3530 "TARGET_32BIT
3531 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3532 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3533 [(set (match_dup 8)
3534 (match_op_dup 1
3535 [(ashift:SI (match_dup 2) (match_dup 4))
3536 (match_dup 5)]))
3537 (set (match_dup 0)
3538 (match_op_dup 1
3539 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3540 (match_dup 7)]))]
3541 "
3542 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3543 ")
3544
3545 (define_split
3546 [(set (match_operand:SI 0 "s_register_operand" "")
3547 (match_operator:SI 1 "logical_binary_operator"
3548 [(match_operator:SI 9 "logical_binary_operator"
3549 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3550 (match_operand:SI 6 "const_int_operand" ""))
3551 (match_operand:SI 7 "s_register_operand" "")])
3552 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3553 (match_operand:SI 3 "const_int_operand" "")
3554 (match_operand:SI 4 "const_int_operand" ""))]))
3555 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3556 "TARGET_32BIT
3557 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3558 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3559 [(set (match_dup 8)
3560 (match_op_dup 1
3561 [(ashift:SI (match_dup 2) (match_dup 4))
3562 (match_dup 5)]))
3563 (set (match_dup 0)
3564 (match_op_dup 1
3565 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3566 (match_dup 7)]))]
3567 "
3568 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3569 ")
3570
3571 (define_split
3572 [(set (match_operand:SI 0 "s_register_operand" "")
3573 (match_operator:SI 1 "logical_binary_operator"
3574 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3575 (match_operand:SI 3 "const_int_operand" "")
3576 (match_operand:SI 4 "const_int_operand" ""))
3577 (match_operator:SI 9 "logical_binary_operator"
3578 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3579 (match_operand:SI 6 "const_int_operand" ""))
3580 (match_operand:SI 7 "s_register_operand" "")])]))
3581 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3582 "TARGET_32BIT
3583 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3584 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3585 [(set (match_dup 8)
3586 (match_op_dup 1
3587 [(ashift:SI (match_dup 2) (match_dup 4))
3588 (match_dup 5)]))
3589 (set (match_dup 0)
3590 (match_op_dup 1
3591 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3592 (match_dup 7)]))]
3593 "
3594 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3595 ")
3596
3597 (define_split
3598 [(set (match_operand:SI 0 "s_register_operand" "")
3599 (match_operator:SI 1 "logical_binary_operator"
3600 [(match_operator:SI 9 "logical_binary_operator"
3601 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3602 (match_operand:SI 6 "const_int_operand" ""))
3603 (match_operand:SI 7 "s_register_operand" "")])
3604 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3605 (match_operand:SI 3 "const_int_operand" "")
3606 (match_operand:SI 4 "const_int_operand" ""))]))
3607 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3608 "TARGET_32BIT
3609 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3610 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3611 [(set (match_dup 8)
3612 (match_op_dup 1
3613 [(ashift:SI (match_dup 2) (match_dup 4))
3614 (match_dup 5)]))
3615 (set (match_dup 0)
3616 (match_op_dup 1
3617 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3618 (match_dup 7)]))]
3619 "
3620 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3621 ")
3622 \f
3623
3624 ;; Minimum and maximum insns
3625
3626 (define_expand "smaxsi3"
3627 [(parallel [
3628 (set (match_operand:SI 0 "s_register_operand" "")
3629 (smax:SI (match_operand:SI 1 "s_register_operand" "")
3630 (match_operand:SI 2 "arm_rhs_operand" "")))
3631 (clobber (reg:CC CC_REGNUM))])]
3632 "TARGET_32BIT"
3633 "
3634 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3635 {
3636 /* No need for a clobber of the condition code register here. */
3637 emit_insn (gen_rtx_SET (operands[0],
3638 gen_rtx_SMAX (SImode, operands[1],
3639 operands[2])));
3640 DONE;
3641 }
3642 ")
3643
3644 (define_insn "*smax_0"
3645 [(set (match_operand:SI 0 "s_register_operand" "=r")
3646 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3647 (const_int 0)))]
3648 "TARGET_32BIT"
3649 "bic%?\\t%0, %1, %1, asr #31"
3650 [(set_attr "predicable" "yes")
3651 (set_attr "predicable_short_it" "no")
3652 (set_attr "type" "logic_shift_reg")]
3653 )
3654
3655 (define_insn "*smax_m1"
3656 [(set (match_operand:SI 0 "s_register_operand" "=r")
3657 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3658 (const_int -1)))]
3659 "TARGET_32BIT"
3660 "orr%?\\t%0, %1, %1, asr #31"
3661 [(set_attr "predicable" "yes")
3662 (set_attr "predicable_short_it" "no")
3663 (set_attr "type" "logic_shift_reg")]
3664 )
3665
3666 (define_insn_and_split "*arm_smax_insn"
3667 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3668 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3669 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3670 (clobber (reg:CC CC_REGNUM))]
3671 "TARGET_ARM"
3672 "#"
3673 ; cmp\\t%1, %2\;movlt\\t%0, %2
3674 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3675 "TARGET_ARM"
3676 [(set (reg:CC CC_REGNUM)
3677 (compare:CC (match_dup 1) (match_dup 2)))
3678 (set (match_dup 0)
3679 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3680 (match_dup 1)
3681 (match_dup 2)))]
3682 ""
3683 [(set_attr "conds" "clob")
3684 (set_attr "length" "8,12")
3685 (set_attr "type" "multiple")]
3686 )
3687
3688 (define_expand "sminsi3"
3689 [(parallel [
3690 (set (match_operand:SI 0 "s_register_operand" "")
3691 (smin:SI (match_operand:SI 1 "s_register_operand" "")
3692 (match_operand:SI 2 "arm_rhs_operand" "")))
3693 (clobber (reg:CC CC_REGNUM))])]
3694 "TARGET_32BIT"
3695 "
3696 if (operands[2] == const0_rtx)
3697 {
3698 /* No need for a clobber of the condition code register here. */
3699 emit_insn (gen_rtx_SET (operands[0],
3700 gen_rtx_SMIN (SImode, operands[1],
3701 operands[2])));
3702 DONE;
3703 }
3704 ")
3705
3706 (define_insn "*smin_0"
3707 [(set (match_operand:SI 0 "s_register_operand" "=r")
3708 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3709 (const_int 0)))]
3710 "TARGET_32BIT"
3711 "and%?\\t%0, %1, %1, asr #31"
3712 [(set_attr "predicable" "yes")
3713 (set_attr "predicable_short_it" "no")
3714 (set_attr "type" "logic_shift_reg")]
3715 )
3716
3717 (define_insn_and_split "*arm_smin_insn"
3718 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3719 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3720 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3721 (clobber (reg:CC CC_REGNUM))]
3722 "TARGET_ARM"
3723 "#"
3724 ; cmp\\t%1, %2\;movge\\t%0, %2
3725 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3726 "TARGET_ARM"
3727 [(set (reg:CC CC_REGNUM)
3728 (compare:CC (match_dup 1) (match_dup 2)))
3729 (set (match_dup 0)
3730 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3731 (match_dup 1)
3732 (match_dup 2)))]
3733 ""
3734 [(set_attr "conds" "clob")
3735 (set_attr "length" "8,12")
3736 (set_attr "type" "multiple,multiple")]
3737 )
3738
3739 (define_expand "umaxsi3"
3740 [(parallel [
3741 (set (match_operand:SI 0 "s_register_operand" "")
3742 (umax:SI (match_operand:SI 1 "s_register_operand" "")
3743 (match_operand:SI 2 "arm_rhs_operand" "")))
3744 (clobber (reg:CC CC_REGNUM))])]
3745 "TARGET_32BIT"
3746 ""
3747 )
3748
3749 (define_insn_and_split "*arm_umaxsi3"
3750 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3751 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3752 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3753 (clobber (reg:CC CC_REGNUM))]
3754 "TARGET_ARM"
3755 "#"
3756 ; cmp\\t%1, %2\;movcc\\t%0, %2
3757 ; cmp\\t%1, %2\;movcs\\t%0, %1
3758 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3759 "TARGET_ARM"
3760 [(set (reg:CC CC_REGNUM)
3761 (compare:CC (match_dup 1) (match_dup 2)))
3762 (set (match_dup 0)
3763 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3764 (match_dup 1)
3765 (match_dup 2)))]
3766 ""
3767 [(set_attr "conds" "clob")
3768 (set_attr "length" "8,8,12")
3769 (set_attr "type" "store1")]
3770 )
3771
3772 (define_expand "uminsi3"
3773 [(parallel [
3774 (set (match_operand:SI 0 "s_register_operand" "")
3775 (umin:SI (match_operand:SI 1 "s_register_operand" "")
3776 (match_operand:SI 2 "arm_rhs_operand" "")))
3777 (clobber (reg:CC CC_REGNUM))])]
3778 "TARGET_32BIT"
3779 ""
3780 )
3781
3782 (define_insn_and_split "*arm_uminsi3"
3783 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3784 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3785 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3786 (clobber (reg:CC CC_REGNUM))]
3787 "TARGET_ARM"
3788 "#"
3789 ; cmp\\t%1, %2\;movcs\\t%0, %2
3790 ; cmp\\t%1, %2\;movcc\\t%0, %1
3791 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3792 "TARGET_ARM"
3793 [(set (reg:CC CC_REGNUM)
3794 (compare:CC (match_dup 1) (match_dup 2)))
3795 (set (match_dup 0)
3796 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3797 (match_dup 1)
3798 (match_dup 2)))]
3799 ""
3800 [(set_attr "conds" "clob")
3801 (set_attr "length" "8,8,12")
3802 (set_attr "type" "store1")]
3803 )
3804
3805 (define_insn "*store_minmaxsi"
3806 [(set (match_operand:SI 0 "memory_operand" "=m")
3807 (match_operator:SI 3 "minmax_operator"
3808 [(match_operand:SI 1 "s_register_operand" "r")
3809 (match_operand:SI 2 "s_register_operand" "r")]))
3810 (clobber (reg:CC CC_REGNUM))]
3811 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3812 "*
3813 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3814 operands[1], operands[2]);
3815 output_asm_insn (\"cmp\\t%1, %2\", operands);
3816 if (TARGET_THUMB2)
3817 output_asm_insn (\"ite\t%d3\", operands);
3818 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3819 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3820 return \"\";
3821 "
3822 [(set_attr "conds" "clob")
3823 (set (attr "length")
3824 (if_then_else (eq_attr "is_thumb" "yes")
3825 (const_int 14)
3826 (const_int 12)))
3827 (set_attr "type" "store1")]
3828 )
3829
3830 ; Reject the frame pointer in operand[1], since reloading this after
3831 ; it has been eliminated can cause carnage.
3832 (define_insn "*minmax_arithsi"
3833 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3834 (match_operator:SI 4 "shiftable_operator"
3835 [(match_operator:SI 5 "minmax_operator"
3836 [(match_operand:SI 2 "s_register_operand" "r,r")
3837 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3838 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3839 (clobber (reg:CC CC_REGNUM))]
3840 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3841 "*
3842 {
3843 enum rtx_code code = GET_CODE (operands[4]);
3844 bool need_else;
3845
3846 if (which_alternative != 0 || operands[3] != const0_rtx
3847 || (code != PLUS && code != IOR && code != XOR))
3848 need_else = true;
3849 else
3850 need_else = false;
3851
3852 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3853 operands[2], operands[3]);
3854 output_asm_insn (\"cmp\\t%2, %3\", operands);
3855 if (TARGET_THUMB2)
3856 {
3857 if (need_else)
3858 output_asm_insn (\"ite\\t%d5\", operands);
3859 else
3860 output_asm_insn (\"it\\t%d5\", operands);
3861 }
3862 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3863 if (need_else)
3864 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3865 return \"\";
3866 }"
3867 [(set_attr "conds" "clob")
3868 (set (attr "length")
3869 (if_then_else (eq_attr "is_thumb" "yes")
3870 (const_int 14)
3871 (const_int 12)))
3872 (set_attr "type" "multiple")]
3873 )
3874
3875 ; Reject the frame pointer in operand[1], since reloading this after
3876 ; it has been eliminated can cause carnage.
3877 (define_insn_and_split "*minmax_arithsi_non_canon"
3878 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3879 (minus:SI
3880 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3881 (match_operator:SI 4 "minmax_operator"
3882 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3883 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3884 (clobber (reg:CC CC_REGNUM))]
3885 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3886 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3887 "#"
3888 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3889 [(set (reg:CC CC_REGNUM)
3890 (compare:CC (match_dup 2) (match_dup 3)))
3891
3892 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3893 (set (match_dup 0)
3894 (minus:SI (match_dup 1)
3895 (match_dup 2))))
3896 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3897 (set (match_dup 0)
3898 (match_dup 6)))]
3899 {
3900 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3901 operands[2], operands[3]);
3902 enum rtx_code rc = minmax_code (operands[4]);
3903 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3904 operands[2], operands[3]);
3905
3906 if (mode == CCFPmode || mode == CCFPEmode)
3907 rc = reverse_condition_maybe_unordered (rc);
3908 else
3909 rc = reverse_condition (rc);
3910 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3911 if (CONST_INT_P (operands[3]))
3912 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3913 else
3914 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3915 }
3916 [(set_attr "conds" "clob")
3917 (set (attr "length")
3918 (if_then_else (eq_attr "is_thumb" "yes")
3919 (const_int 14)
3920 (const_int 12)))
3921 (set_attr "type" "multiple")]
3922 )
3923
3924 (define_code_iterator SAT [smin smax])
3925 (define_code_iterator SATrev [smin smax])
3926 (define_code_attr SATlo [(smin "1") (smax "2")])
3927 (define_code_attr SAThi [(smin "2") (smax "1")])
3928
3929 (define_insn "*satsi_<SAT:code>"
3930 [(set (match_operand:SI 0 "s_register_operand" "=r")
3931 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
3932 (match_operand:SI 1 "const_int_operand" "i"))
3933 (match_operand:SI 2 "const_int_operand" "i")))]
3934 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3935 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3936 {
3937 int mask;
3938 bool signed_sat;
3939 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3940 &mask, &signed_sat))
3941 gcc_unreachable ();
3942
3943 operands[1] = GEN_INT (mask);
3944 if (signed_sat)
3945 return "ssat%?\t%0, %1, %3";
3946 else
3947 return "usat%?\t%0, %1, %3";
3948 }
3949 [(set_attr "predicable" "yes")
3950 (set_attr "predicable_short_it" "no")
3951 (set_attr "type" "alus_imm")]
3952 )
3953
3954 (define_insn "*satsi_<SAT:code>_shift"
3955 [(set (match_operand:SI 0 "s_register_operand" "=r")
3956 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
3957 [(match_operand:SI 4 "s_register_operand" "r")
3958 (match_operand:SI 5 "const_int_operand" "i")])
3959 (match_operand:SI 1 "const_int_operand" "i"))
3960 (match_operand:SI 2 "const_int_operand" "i")))]
3961 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
3962 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3963 {
3964 int mask;
3965 bool signed_sat;
3966 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3967 &mask, &signed_sat))
3968 gcc_unreachable ();
3969
3970 operands[1] = GEN_INT (mask);
3971 if (signed_sat)
3972 return "ssat%?\t%0, %1, %4%S3";
3973 else
3974 return "usat%?\t%0, %1, %4%S3";
3975 }
3976 [(set_attr "predicable" "yes")
3977 (set_attr "predicable_short_it" "no")
3978 (set_attr "shift" "3")
3979 (set_attr "type" "logic_shift_reg")])
3980 \f
3981 ;; Shift and rotation insns
3982
3983 (define_expand "ashldi3"
3984 [(set (match_operand:DI 0 "s_register_operand" "")
3985 (ashift:DI (match_operand:DI 1 "s_register_operand" "")
3986 (match_operand:SI 2 "general_operand" "")))]
3987 "TARGET_32BIT"
3988 "
3989 if (TARGET_NEON)
3990 {
3991 /* Delay the decision whether to use NEON or core-regs until
3992 register allocation. */
3993 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2]));
3994 DONE;
3995 }
3996 else
3997 {
3998 /* Only the NEON case can handle in-memory shift counts. */
3999 if (!reg_or_int_operand (operands[2], SImode))
4000 operands[2] = force_reg (SImode, operands[2]);
4001 }
4002
4003 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4004 ; /* No special preparation statements; expand pattern as above. */
4005 else
4006 {
4007 rtx scratch1, scratch2;
4008
4009 if (operands[2] == CONST1_RTX (SImode))
4010 {
4011 emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
4012 DONE;
4013 }
4014
4015 /* Ideally we should use iwmmxt here if we could know that operands[1]
4016 ends up already living in an iwmmxt register. Otherwise it's
4017 cheaper to have the alternate code being generated than moving
4018 values to iwmmxt regs and back. */
4019
4020 /* Expand operation using core-registers.
4021 'FAIL' would achieve the same thing, but this is a bit smarter. */
4022 scratch1 = gen_reg_rtx (SImode);
4023 scratch2 = gen_reg_rtx (SImode);
4024 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
4025 operands[2], scratch1, scratch2);
4026 DONE;
4027 }
4028 "
4029 )
4030
4031 (define_insn "arm_ashldi3_1bit"
4032 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4033 (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r")
4034 (const_int 1)))
4035 (clobber (reg:CC CC_REGNUM))]
4036 "TARGET_32BIT"
4037 "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1"
4038 [(set_attr "conds" "clob")
4039 (set_attr "length" "8")
4040 (set_attr "type" "multiple")]
4041 )
4042
4043 (define_expand "ashlsi3"
4044 [(set (match_operand:SI 0 "s_register_operand" "")
4045 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
4046 (match_operand:SI 2 "arm_rhs_operand" "")))]
4047 "TARGET_EITHER"
4048 "
4049 if (CONST_INT_P (operands[2])
4050 && (UINTVAL (operands[2])) > 31)
4051 {
4052 emit_insn (gen_movsi (operands[0], const0_rtx));
4053 DONE;
4054 }
4055 "
4056 )
4057
4058 (define_expand "ashrdi3"
4059 [(set (match_operand:DI 0 "s_register_operand" "")
4060 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4061 (match_operand:SI 2 "reg_or_int_operand" "")))]
4062 "TARGET_32BIT"
4063 "
4064 if (TARGET_NEON)
4065 {
4066 /* Delay the decision whether to use NEON or core-regs until
4067 register allocation. */
4068 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2]));
4069 DONE;
4070 }
4071
4072 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4073 ; /* No special preparation statements; expand pattern as above. */
4074 else
4075 {
4076 rtx scratch1, scratch2;
4077
4078 if (operands[2] == CONST1_RTX (SImode))
4079 {
4080 emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1]));
4081 DONE;
4082 }
4083
4084 /* Ideally we should use iwmmxt here if we could know that operands[1]
4085 ends up already living in an iwmmxt register. Otherwise it's
4086 cheaper to have the alternate code being generated than moving
4087 values to iwmmxt regs and back. */
4088
4089 /* Expand operation using core-registers.
4090 'FAIL' would achieve the same thing, but this is a bit smarter. */
4091 scratch1 = gen_reg_rtx (SImode);
4092 scratch2 = gen_reg_rtx (SImode);
4093 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
4094 operands[2], scratch1, scratch2);
4095 DONE;
4096 }
4097 "
4098 )
4099
4100 (define_insn "arm_ashrdi3_1bit"
4101 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4102 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4103 (const_int 1)))
4104 (clobber (reg:CC CC_REGNUM))]
4105 "TARGET_32BIT"
4106 "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx"
4107 [(set_attr "conds" "clob")
4108 (set_attr "length" "8")
4109 (set_attr "type" "multiple")]
4110 )
4111
4112 (define_expand "ashrsi3"
4113 [(set (match_operand:SI 0 "s_register_operand" "")
4114 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4115 (match_operand:SI 2 "arm_rhs_operand" "")))]
4116 "TARGET_EITHER"
4117 "
4118 if (CONST_INT_P (operands[2])
4119 && UINTVAL (operands[2]) > 31)
4120 operands[2] = GEN_INT (31);
4121 "
4122 )
4123
4124 (define_expand "lshrdi3"
4125 [(set (match_operand:DI 0 "s_register_operand" "")
4126 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "")
4127 (match_operand:SI 2 "reg_or_int_operand" "")))]
4128 "TARGET_32BIT"
4129 "
4130 if (TARGET_NEON)
4131 {
4132 /* Delay the decision whether to use NEON or core-regs until
4133 register allocation. */
4134 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2]));
4135 DONE;
4136 }
4137
4138 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT)
4139 ; /* No special preparation statements; expand pattern as above. */
4140 else
4141 {
4142 rtx scratch1, scratch2;
4143
4144 if (operands[2] == CONST1_RTX (SImode))
4145 {
4146 emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1]));
4147 DONE;
4148 }
4149
4150 /* Ideally we should use iwmmxt here if we could know that operands[1]
4151 ends up already living in an iwmmxt register. Otherwise it's
4152 cheaper to have the alternate code being generated than moving
4153 values to iwmmxt regs and back. */
4154
4155 /* Expand operation using core-registers.
4156 'FAIL' would achieve the same thing, but this is a bit smarter. */
4157 scratch1 = gen_reg_rtx (SImode);
4158 scratch2 = gen_reg_rtx (SImode);
4159 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
4160 operands[2], scratch1, scratch2);
4161 DONE;
4162 }
4163 "
4164 )
4165
4166 (define_insn "arm_lshrdi3_1bit"
4167 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4168 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r")
4169 (const_int 1)))
4170 (clobber (reg:CC CC_REGNUM))]
4171 "TARGET_32BIT"
4172 "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx"
4173 [(set_attr "conds" "clob")
4174 (set_attr "length" "8")
4175 (set_attr "type" "multiple")]
4176 )
4177
4178 (define_expand "lshrsi3"
4179 [(set (match_operand:SI 0 "s_register_operand" "")
4180 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "")
4181 (match_operand:SI 2 "arm_rhs_operand" "")))]
4182 "TARGET_EITHER"
4183 "
4184 if (CONST_INT_P (operands[2])
4185 && (UINTVAL (operands[2])) > 31)
4186 {
4187 emit_insn (gen_movsi (operands[0], const0_rtx));
4188 DONE;
4189 }
4190 "
4191 )
4192
4193 (define_expand "rotlsi3"
4194 [(set (match_operand:SI 0 "s_register_operand" "")
4195 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4196 (match_operand:SI 2 "reg_or_int_operand" "")))]
4197 "TARGET_32BIT"
4198 "
4199 if (CONST_INT_P (operands[2]))
4200 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
4201 else
4202 {
4203 rtx reg = gen_reg_rtx (SImode);
4204 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
4205 operands[2] = reg;
4206 }
4207 "
4208 )
4209
4210 (define_expand "rotrsi3"
4211 [(set (match_operand:SI 0 "s_register_operand" "")
4212 (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
4213 (match_operand:SI 2 "arm_rhs_operand" "")))]
4214 "TARGET_EITHER"
4215 "
4216 if (TARGET_32BIT)
4217 {
4218 if (CONST_INT_P (operands[2])
4219 && UINTVAL (operands[2]) > 31)
4220 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
4221 }
4222 else /* TARGET_THUMB1 */
4223 {
4224 if (CONST_INT_P (operands [2]))
4225 operands [2] = force_reg (SImode, operands[2]);
4226 }
4227 "
4228 )
4229
4230 (define_insn "*arm_shiftsi3"
4231 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
4232 (match_operator:SI 3 "shift_operator"
4233 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
4234 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
4235 "TARGET_32BIT"
4236 "* return arm_output_shift(operands, 0);"
4237 [(set_attr "predicable" "yes")
4238 (set_attr "arch" "t2,t2,*,*")
4239 (set_attr "predicable_short_it" "yes,yes,no,no")
4240 (set_attr "length" "4")
4241 (set_attr "shift" "1")
4242 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
4243 )
4244
4245 (define_insn "*shiftsi3_compare0"
4246 [(set (reg:CC_NOOV CC_REGNUM)
4247 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4248 [(match_operand:SI 1 "s_register_operand" "r,r")
4249 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4250 (const_int 0)))
4251 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4252 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
4253 "TARGET_32BIT"
4254 "* return arm_output_shift(operands, 1);"
4255 [(set_attr "conds" "set")
4256 (set_attr "shift" "1")
4257 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
4258 )
4259
4260 (define_insn "*shiftsi3_compare0_scratch"
4261 [(set (reg:CC_NOOV CC_REGNUM)
4262 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
4263 [(match_operand:SI 1 "s_register_operand" "r,r")
4264 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
4265 (const_int 0)))
4266 (clobber (match_scratch:SI 0 "=r,r"))]
4267 "TARGET_32BIT"
4268 "* return arm_output_shift(operands, 1);"
4269 [(set_attr "conds" "set")
4270 (set_attr "shift" "1")
4271 (set_attr "type" "shift_imm,shift_reg")]
4272 )
4273
4274 (define_insn "*not_shiftsi"
4275 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4276 (not:SI (match_operator:SI 3 "shift_operator"
4277 [(match_operand:SI 1 "s_register_operand" "r,r")
4278 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
4279 "TARGET_32BIT"
4280 "mvn%?\\t%0, %1%S3"
4281 [(set_attr "predicable" "yes")
4282 (set_attr "predicable_short_it" "no")
4283 (set_attr "shift" "1")
4284 (set_attr "arch" "32,a")
4285 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4286
4287 (define_insn "*not_shiftsi_compare0"
4288 [(set (reg:CC_NOOV CC_REGNUM)
4289 (compare:CC_NOOV
4290 (not:SI (match_operator:SI 3 "shift_operator"
4291 [(match_operand:SI 1 "s_register_operand" "r,r")
4292 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4293 (const_int 0)))
4294 (set (match_operand:SI 0 "s_register_operand" "=r,r")
4295 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
4296 "TARGET_32BIT"
4297 "mvns%?\\t%0, %1%S3"
4298 [(set_attr "conds" "set")
4299 (set_attr "shift" "1")
4300 (set_attr "arch" "32,a")
4301 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4302
4303 (define_insn "*not_shiftsi_compare0_scratch"
4304 [(set (reg:CC_NOOV CC_REGNUM)
4305 (compare:CC_NOOV
4306 (not:SI (match_operator:SI 3 "shift_operator"
4307 [(match_operand:SI 1 "s_register_operand" "r,r")
4308 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
4309 (const_int 0)))
4310 (clobber (match_scratch:SI 0 "=r,r"))]
4311 "TARGET_32BIT"
4312 "mvns%?\\t%0, %1%S3"
4313 [(set_attr "conds" "set")
4314 (set_attr "shift" "1")
4315 (set_attr "arch" "32,a")
4316 (set_attr "type" "mvn_shift,mvn_shift_reg")])
4317
4318 ;; We don't really have extzv, but defining this using shifts helps
4319 ;; to reduce register pressure later on.
4320
4321 (define_expand "extzv"
4322 [(set (match_operand 0 "s_register_operand" "")
4323 (zero_extract (match_operand 1 "nonimmediate_operand" "")
4324 (match_operand 2 "const_int_operand" "")
4325 (match_operand 3 "const_int_operand" "")))]
4326 "TARGET_THUMB1 || arm_arch_thumb2"
4327 "
4328 {
4329 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
4330 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
4331
4332 if (arm_arch_thumb2)
4333 {
4334 HOST_WIDE_INT width = INTVAL (operands[2]);
4335 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4336
4337 if (unaligned_access && MEM_P (operands[1])
4338 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
4339 {
4340 rtx base_addr;
4341
4342 if (BYTES_BIG_ENDIAN)
4343 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
4344 - bitpos;
4345
4346 if (width == 32)
4347 {
4348 base_addr = adjust_address (operands[1], SImode,
4349 bitpos / BITS_PER_UNIT);
4350 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4351 }
4352 else
4353 {
4354 rtx dest = operands[0];
4355 rtx tmp = gen_reg_rtx (SImode);
4356
4357 /* We may get a paradoxical subreg here. Strip it off. */
4358 if (GET_CODE (dest) == SUBREG
4359 && GET_MODE (dest) == SImode
4360 && GET_MODE (SUBREG_REG (dest)) == HImode)
4361 dest = SUBREG_REG (dest);
4362
4363 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4364 FAIL;
4365
4366 base_addr = adjust_address (operands[1], HImode,
4367 bitpos / BITS_PER_UNIT);
4368 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
4369 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4370 }
4371 DONE;
4372 }
4373 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
4374 {
4375 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
4376 operands[3]));
4377 DONE;
4378 }
4379 else
4380 FAIL;
4381 }
4382
4383 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4384 FAIL;
4385
4386 operands[3] = GEN_INT (rshift);
4387
4388 if (lshift == 0)
4389 {
4390 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
4391 DONE;
4392 }
4393
4394 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
4395 operands[3], gen_reg_rtx (SImode)));
4396 DONE;
4397 }"
4398 )
4399
4400 ;; Helper for extzv, for the Thumb-1 register-shifts case.
4401
4402 (define_expand "extzv_t1"
4403 [(set (match_operand:SI 4 "s_register_operand" "")
4404 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
4405 (match_operand:SI 2 "const_int_operand" "")))
4406 (set (match_operand:SI 0 "s_register_operand" "")
4407 (lshiftrt:SI (match_dup 4)
4408 (match_operand:SI 3 "const_int_operand" "")))]
4409 "TARGET_THUMB1"
4410 "")
4411
4412 (define_expand "extv"
4413 [(set (match_operand 0 "s_register_operand" "")
4414 (sign_extract (match_operand 1 "nonimmediate_operand" "")
4415 (match_operand 2 "const_int_operand" "")
4416 (match_operand 3 "const_int_operand" "")))]
4417 "arm_arch_thumb2"
4418 {
4419 HOST_WIDE_INT width = INTVAL (operands[2]);
4420 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
4421
4422 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
4423 && (bitpos % BITS_PER_UNIT) == 0)
4424 {
4425 rtx base_addr;
4426
4427 if (BYTES_BIG_ENDIAN)
4428 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
4429
4430 if (width == 32)
4431 {
4432 base_addr = adjust_address (operands[1], SImode,
4433 bitpos / BITS_PER_UNIT);
4434 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
4435 }
4436 else
4437 {
4438 rtx dest = operands[0];
4439 rtx tmp = gen_reg_rtx (SImode);
4440
4441 /* We may get a paradoxical subreg here. Strip it off. */
4442 if (GET_CODE (dest) == SUBREG
4443 && GET_MODE (dest) == SImode
4444 && GET_MODE (SUBREG_REG (dest)) == HImode)
4445 dest = SUBREG_REG (dest);
4446
4447 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
4448 FAIL;
4449
4450 base_addr = adjust_address (operands[1], HImode,
4451 bitpos / BITS_PER_UNIT);
4452 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
4453 emit_move_insn (gen_lowpart (SImode, dest), tmp);
4454 }
4455
4456 DONE;
4457 }
4458 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
4459 FAIL;
4460 else if (GET_MODE (operands[0]) == SImode
4461 && GET_MODE (operands[1]) == SImode)
4462 {
4463 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
4464 operands[3]));
4465 DONE;
4466 }
4467
4468 FAIL;
4469 })
4470
4471 ; Helper to expand register forms of extv with the proper modes.
4472
4473 (define_expand "extv_regsi"
4474 [(set (match_operand:SI 0 "s_register_operand" "")
4475 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
4476 (match_operand 2 "const_int_operand" "")
4477 (match_operand 3 "const_int_operand" "")))]
4478 ""
4479 {
4480 })
4481
4482 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
4483
4484 (define_insn "unaligned_loadsi"
4485 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4486 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")]
4487 UNSPEC_UNALIGNED_LOAD))]
4488 "unaligned_access"
4489 "ldr%?\t%0, %1\t@ unaligned"
4490 [(set_attr "arch" "t2,any")
4491 (set_attr "length" "2,4")
4492 (set_attr "predicable" "yes")
4493 (set_attr "predicable_short_it" "yes,no")
4494 (set_attr "type" "load1")])
4495
4496 (define_insn "unaligned_loadhis"
4497 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4498 (sign_extend:SI
4499 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,Uh")]
4500 UNSPEC_UNALIGNED_LOAD)))]
4501 "unaligned_access"
4502 "ldrsh%?\t%0, %1\t@ unaligned"
4503 [(set_attr "arch" "t2,any")
4504 (set_attr "length" "2,4")
4505 (set_attr "predicable" "yes")
4506 (set_attr "predicable_short_it" "yes,no")
4507 (set_attr "type" "load_byte")])
4508
4509 (define_insn "unaligned_loadhiu"
4510 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4511 (zero_extend:SI
4512 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")]
4513 UNSPEC_UNALIGNED_LOAD)))]
4514 "unaligned_access"
4515 "ldrh%?\t%0, %1\t@ unaligned"
4516 [(set_attr "arch" "t2,any")
4517 (set_attr "length" "2,4")
4518 (set_attr "predicable" "yes")
4519 (set_attr "predicable_short_it" "yes,no")
4520 (set_attr "type" "load_byte")])
4521
4522 (define_insn "unaligned_storesi"
4523 [(set (match_operand:SI 0 "memory_operand" "=Uw,m")
4524 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")]
4525 UNSPEC_UNALIGNED_STORE))]
4526 "unaligned_access"
4527 "str%?\t%1, %0\t@ unaligned"
4528 [(set_attr "arch" "t2,any")
4529 (set_attr "length" "2,4")
4530 (set_attr "predicable" "yes")
4531 (set_attr "predicable_short_it" "yes,no")
4532 (set_attr "type" "store1")])
4533
4534 (define_insn "unaligned_storehi"
4535 [(set (match_operand:HI 0 "memory_operand" "=Uw,m")
4536 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")]
4537 UNSPEC_UNALIGNED_STORE))]
4538 "unaligned_access"
4539 "strh%?\t%1, %0\t@ unaligned"
4540 [(set_attr "arch" "t2,any")
4541 (set_attr "length" "2,4")
4542 (set_attr "predicable" "yes")
4543 (set_attr "predicable_short_it" "yes,no")
4544 (set_attr "type" "store1")])
4545
4546
4547 (define_insn "*extv_reg"
4548 [(set (match_operand:SI 0 "s_register_operand" "=r")
4549 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4550 (match_operand:SI 2 "const_int_operand" "n")
4551 (match_operand:SI 3 "const_int_operand" "n")))]
4552 "arm_arch_thumb2
4553 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4554 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4555 "sbfx%?\t%0, %1, %3, %2"
4556 [(set_attr "length" "4")
4557 (set_attr "predicable" "yes")
4558 (set_attr "predicable_short_it" "no")
4559 (set_attr "type" "bfm")]
4560 )
4561
4562 (define_insn "extzv_t2"
4563 [(set (match_operand:SI 0 "s_register_operand" "=r")
4564 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4565 (match_operand:SI 2 "const_int_operand" "n")
4566 (match_operand:SI 3 "const_int_operand" "n")))]
4567 "arm_arch_thumb2
4568 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4569 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4570 "ubfx%?\t%0, %1, %3, %2"
4571 [(set_attr "length" "4")
4572 (set_attr "predicable" "yes")
4573 (set_attr "predicable_short_it" "no")
4574 (set_attr "type" "bfm")]
4575 )
4576
4577
4578 ;; Division instructions
4579 (define_insn "divsi3"
4580 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4581 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4582 (match_operand:SI 2 "s_register_operand" "r,r")))]
4583 "TARGET_IDIV"
4584 "@
4585 sdiv%?\t%0, %1, %2
4586 sdiv\t%0, %1, %2"
4587 [(set_attr "arch" "32,v8mb")
4588 (set_attr "predicable" "yes")
4589 (set_attr "predicable_short_it" "no")
4590 (set_attr "type" "sdiv")]
4591 )
4592
4593 (define_insn "udivsi3"
4594 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4595 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4596 (match_operand:SI 2 "s_register_operand" "r,r")))]
4597 "TARGET_IDIV"
4598 "@
4599 udiv%?\t%0, %1, %2
4600 udiv\t%0, %1, %2"
4601 [(set_attr "arch" "32,v8mb")
4602 (set_attr "predicable" "yes")
4603 (set_attr "predicable_short_it" "no")
4604 (set_attr "type" "udiv")]
4605 )
4606
4607 \f
4608 ;; Unary arithmetic insns
4609
4610 (define_expand "negvsi3"
4611 [(match_operand:SI 0 "register_operand")
4612 (match_operand:SI 1 "register_operand")
4613 (match_operand 2 "")]
4614 "TARGET_32BIT"
4615 {
4616 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4617 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4618
4619 DONE;
4620 })
4621
4622 (define_expand "negvdi3"
4623 [(match_operand:DI 0 "register_operand")
4624 (match_operand:DI 1 "register_operand")
4625 (match_operand 2 "")]
4626 "TARGET_ARM"
4627 {
4628 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4629 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4630
4631 DONE;
4632 })
4633
4634
4635 (define_insn_and_split "negdi2_compare"
4636 [(set (reg:CC CC_REGNUM)
4637 (compare:CC
4638 (const_int 0)
4639 (match_operand:DI 1 "register_operand" "0,r")))
4640 (set (match_operand:DI 0 "register_operand" "=r,&r")
4641 (minus:DI (const_int 0) (match_dup 1)))]
4642 "TARGET_ARM"
4643 "#"
4644 "&& reload_completed"
4645 [(parallel [(set (reg:CC CC_REGNUM)
4646 (compare:CC (const_int 0) (match_dup 1)))
4647 (set (match_dup 0) (minus:SI (const_int 0)
4648 (match_dup 1)))])
4649 (parallel [(set (reg:CC CC_REGNUM)
4650 (compare:CC (const_int 0) (match_dup 3)))
4651 (set (match_dup 2)
4652 (minus:SI
4653 (minus:SI (const_int 0) (match_dup 3))
4654 (ltu:SI (reg:CC_C CC_REGNUM)
4655 (const_int 0))))])]
4656 {
4657 operands[2] = gen_highpart (SImode, operands[0]);
4658 operands[0] = gen_lowpart (SImode, operands[0]);
4659 operands[3] = gen_highpart (SImode, operands[1]);
4660 operands[1] = gen_lowpart (SImode, operands[1]);
4661 }
4662 [(set_attr "conds" "set")
4663 (set_attr "length" "8")
4664 (set_attr "type" "multiple")]
4665 )
4666
4667 (define_expand "negdi2"
4668 [(parallel
4669 [(set (match_operand:DI 0 "s_register_operand" "")
4670 (neg:DI (match_operand:DI 1 "s_register_operand" "")))
4671 (clobber (reg:CC CC_REGNUM))])]
4672 "TARGET_EITHER"
4673 {
4674 if (TARGET_NEON)
4675 {
4676 emit_insn (gen_negdi2_neon (operands[0], operands[1]));
4677 DONE;
4678 }
4679 }
4680 )
4681
4682 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4683 ;; The first alternative allows the common case of a *full* overlap.
4684 (define_insn_and_split "*arm_negdi2"
4685 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4686 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4687 (clobber (reg:CC CC_REGNUM))]
4688 "TARGET_ARM"
4689 "#" ; "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0"
4690 "&& reload_completed"
4691 [(parallel [(set (reg:CC CC_REGNUM)
4692 (compare:CC (const_int 0) (match_dup 1)))
4693 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4694 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4695 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4696 {
4697 operands[2] = gen_highpart (SImode, operands[0]);
4698 operands[0] = gen_lowpart (SImode, operands[0]);
4699 operands[3] = gen_highpart (SImode, operands[1]);
4700 operands[1] = gen_lowpart (SImode, operands[1]);
4701 }
4702 [(set_attr "conds" "clob")
4703 (set_attr "length" "8")
4704 (set_attr "type" "multiple")]
4705 )
4706
4707 (define_insn "*negsi2_carryin_compare"
4708 [(set (reg:CC CC_REGNUM)
4709 (compare:CC (const_int 0)
4710 (match_operand:SI 1 "s_register_operand" "r")))
4711 (set (match_operand:SI 0 "s_register_operand" "=r")
4712 (minus:SI (minus:SI (const_int 0)
4713 (match_dup 1))
4714 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4715 "TARGET_ARM"
4716 "rscs\\t%0, %1, #0"
4717 [(set_attr "conds" "set")
4718 (set_attr "type" "alus_imm")]
4719 )
4720
4721 (define_expand "negsi2"
4722 [(set (match_operand:SI 0 "s_register_operand" "")
4723 (neg:SI (match_operand:SI 1 "s_register_operand" "")))]
4724 "TARGET_EITHER"
4725 ""
4726 )
4727
4728 (define_insn "*arm_negsi2"
4729 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4730 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4731 "TARGET_32BIT"
4732 "rsb%?\\t%0, %1, #0"
4733 [(set_attr "predicable" "yes")
4734 (set_attr "predicable_short_it" "yes,no")
4735 (set_attr "arch" "t2,*")
4736 (set_attr "length" "4")
4737 (set_attr "type" "alu_sreg")]
4738 )
4739
4740 (define_expand "negsf2"
4741 [(set (match_operand:SF 0 "s_register_operand" "")
4742 (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
4743 "TARGET_32BIT && TARGET_HARD_FLOAT"
4744 ""
4745 )
4746
4747 (define_expand "negdf2"
4748 [(set (match_operand:DF 0 "s_register_operand" "")
4749 (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
4750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4751 "")
4752
4753 (define_insn_and_split "*zextendsidi_negsi"
4754 [(set (match_operand:DI 0 "s_register_operand" "=r")
4755 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4756 "TARGET_32BIT"
4757 "#"
4758 ""
4759 [(set (match_dup 2)
4760 (neg:SI (match_dup 1)))
4761 (set (match_dup 3)
4762 (const_int 0))]
4763 {
4764 operands[2] = gen_lowpart (SImode, operands[0]);
4765 operands[3] = gen_highpart (SImode, operands[0]);
4766 }
4767 [(set_attr "length" "8")
4768 (set_attr "type" "multiple")]
4769 )
4770
4771 ;; Negate an extended 32-bit value.
4772 (define_insn_and_split "*negdi_extendsidi"
4773 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4774 (neg:DI (sign_extend:DI
4775 (match_operand:SI 1 "s_register_operand" "l,r"))))
4776 (clobber (reg:CC CC_REGNUM))]
4777 "TARGET_32BIT"
4778 "#"
4779 "&& reload_completed"
4780 [(const_int 0)]
4781 {
4782 rtx low = gen_lowpart (SImode, operands[0]);
4783 rtx high = gen_highpart (SImode, operands[0]);
4784
4785 if (reg_overlap_mentioned_p (low, operands[1]))
4786 {
4787 /* Input overlaps the low word of the output. Use:
4788 asr Rhi, Rin, #31
4789 rsbs Rlo, Rin, #0
4790 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4791 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
4792
4793 emit_insn (gen_rtx_SET (high,
4794 gen_rtx_ASHIFTRT (SImode, operands[1],
4795 GEN_INT (31))));
4796
4797 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4798 if (TARGET_ARM)
4799 emit_insn (gen_rtx_SET (high,
4800 gen_rtx_MINUS (SImode,
4801 gen_rtx_MINUS (SImode,
4802 const0_rtx,
4803 high),
4804 gen_rtx_LTU (SImode,
4805 cc_reg,
4806 const0_rtx))));
4807 else
4808 {
4809 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4810 emit_insn (gen_rtx_SET (high,
4811 gen_rtx_MINUS (SImode,
4812 gen_rtx_MINUS (SImode,
4813 high,
4814 two_x),
4815 gen_rtx_LTU (SImode,
4816 cc_reg,
4817 const0_rtx))));
4818 }
4819 }
4820 else
4821 {
4822 /* No overlap, or overlap on high word. Use:
4823 rsb Rlo, Rin, #0
4824 bic Rhi, Rlo, Rin
4825 asr Rhi, Rhi, #31
4826 Flags not needed for this sequence. */
4827 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4828 emit_insn (gen_rtx_SET (high,
4829 gen_rtx_AND (SImode,
4830 gen_rtx_NOT (SImode, operands[1]),
4831 low)));
4832 emit_insn (gen_rtx_SET (high,
4833 gen_rtx_ASHIFTRT (SImode, high,
4834 GEN_INT (31))));
4835 }
4836 DONE;
4837 }
4838 [(set_attr "length" "12")
4839 (set_attr "arch" "t2,*")
4840 (set_attr "type" "multiple")]
4841 )
4842
4843 (define_insn_and_split "*negdi_zero_extendsidi"
4844 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4845 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4846 (clobber (reg:CC CC_REGNUM))]
4847 "TARGET_32BIT"
4848 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4849 ;; Don't care what register is input to sbc,
4850 ;; since we just need to propagate the carry.
4851 "&& reload_completed"
4852 [(parallel [(set (reg:CC CC_REGNUM)
4853 (compare:CC (const_int 0) (match_dup 1)))
4854 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4855 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4856 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
4857 {
4858 operands[2] = gen_highpart (SImode, operands[0]);
4859 operands[0] = gen_lowpart (SImode, operands[0]);
4860 }
4861 [(set_attr "conds" "clob")
4862 (set_attr "length" "8")
4863 (set_attr "type" "multiple")] ;; length in thumb is 4
4864 )
4865
4866 ;; abssi2 doesn't really clobber the condition codes if a different register
4867 ;; is being set. To keep things simple, assume during rtl manipulations that
4868 ;; it does, but tell the final scan operator the truth. Similarly for
4869 ;; (neg (abs...))
4870
4871 (define_expand "abssi2"
4872 [(parallel
4873 [(set (match_operand:SI 0 "s_register_operand" "")
4874 (abs:SI (match_operand:SI 1 "s_register_operand" "")))
4875 (clobber (match_dup 2))])]
4876 "TARGET_EITHER"
4877 "
4878 if (TARGET_THUMB1)
4879 operands[2] = gen_rtx_SCRATCH (SImode);
4880 else
4881 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4882 ")
4883
4884 (define_insn_and_split "*arm_abssi2"
4885 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4886 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4887 (clobber (reg:CC CC_REGNUM))]
4888 "TARGET_ARM"
4889 "#"
4890 "&& reload_completed"
4891 [(const_int 0)]
4892 {
4893 /* if (which_alternative == 0) */
4894 if (REGNO(operands[0]) == REGNO(operands[1]))
4895 {
4896 /* Emit the pattern:
4897 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4898 [(set (reg:CC CC_REGNUM)
4899 (compare:CC (match_dup 0) (const_int 0)))
4900 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4901 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4902 */
4903 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4904 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4905 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4906 (gen_rtx_LT (SImode,
4907 gen_rtx_REG (CCmode, CC_REGNUM),
4908 const0_rtx)),
4909 (gen_rtx_SET (operands[0],
4910 (gen_rtx_MINUS (SImode,
4911 const0_rtx,
4912 operands[1]))))));
4913 DONE;
4914 }
4915 else
4916 {
4917 /* Emit the pattern:
4918 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4919 [(set (match_dup 0)
4920 (xor:SI (match_dup 1)
4921 (ashiftrt:SI (match_dup 1) (const_int 31))))
4922 (set (match_dup 0)
4923 (minus:SI (match_dup 0)
4924 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4925 */
4926 emit_insn (gen_rtx_SET (operands[0],
4927 gen_rtx_XOR (SImode,
4928 gen_rtx_ASHIFTRT (SImode,
4929 operands[1],
4930 GEN_INT (31)),
4931 operands[1])));
4932 emit_insn (gen_rtx_SET (operands[0],
4933 gen_rtx_MINUS (SImode,
4934 operands[0],
4935 gen_rtx_ASHIFTRT (SImode,
4936 operands[1],
4937 GEN_INT (31)))));
4938 DONE;
4939 }
4940 }
4941 [(set_attr "conds" "clob,*")
4942 (set_attr "shift" "1")
4943 (set_attr "predicable" "no, yes")
4944 (set_attr "length" "8")
4945 (set_attr "type" "multiple")]
4946 )
4947
4948 (define_insn_and_split "*arm_neg_abssi2"
4949 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4950 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4951 (clobber (reg:CC CC_REGNUM))]
4952 "TARGET_ARM"
4953 "#"
4954 "&& reload_completed"
4955 [(const_int 0)]
4956 {
4957 /* if (which_alternative == 0) */
4958 if (REGNO (operands[0]) == REGNO (operands[1]))
4959 {
4960 /* Emit the pattern:
4961 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4962 */
4963 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4964 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4965 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4966 gen_rtx_GT (SImode,
4967 gen_rtx_REG (CCmode, CC_REGNUM),
4968 const0_rtx),
4969 gen_rtx_SET (operands[0],
4970 (gen_rtx_MINUS (SImode,
4971 const0_rtx,
4972 operands[1])))));
4973 }
4974 else
4975 {
4976 /* Emit the pattern:
4977 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4978 */
4979 emit_insn (gen_rtx_SET (operands[0],
4980 gen_rtx_XOR (SImode,
4981 gen_rtx_ASHIFTRT (SImode,
4982 operands[1],
4983 GEN_INT (31)),
4984 operands[1])));
4985 emit_insn (gen_rtx_SET (operands[0],
4986 gen_rtx_MINUS (SImode,
4987 gen_rtx_ASHIFTRT (SImode,
4988 operands[1],
4989 GEN_INT (31)),
4990 operands[0])));
4991 }
4992 DONE;
4993 }
4994 [(set_attr "conds" "clob,*")
4995 (set_attr "shift" "1")
4996 (set_attr "predicable" "no, yes")
4997 (set_attr "length" "8")
4998 (set_attr "type" "multiple")]
4999 )
5000
5001 (define_expand "abssf2"
5002 [(set (match_operand:SF 0 "s_register_operand" "")
5003 (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
5004 "TARGET_32BIT && TARGET_HARD_FLOAT"
5005 "")
5006
5007 (define_expand "absdf2"
5008 [(set (match_operand:DF 0 "s_register_operand" "")
5009 (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
5010 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5011 "")
5012
5013 (define_expand "sqrtsf2"
5014 [(set (match_operand:SF 0 "s_register_operand" "")
5015 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
5016 "TARGET_32BIT && TARGET_HARD_FLOAT"
5017 "")
5018
5019 (define_expand "sqrtdf2"
5020 [(set (match_operand:DF 0 "s_register_operand" "")
5021 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
5022 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
5023 "")
5024
5025 (define_insn_and_split "one_cmpldi2"
5026 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w")
5027 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))]
5028 "TARGET_32BIT"
5029 "@
5030 vmvn\t%P0, %P1
5031 #
5032 #
5033 vmvn\t%P0, %P1"
5034 "TARGET_32BIT && reload_completed
5035 && arm_general_register_operand (operands[0], DImode)"
5036 [(set (match_dup 0) (not:SI (match_dup 1)))
5037 (set (match_dup 2) (not:SI (match_dup 3)))]
5038 "
5039 {
5040 operands[2] = gen_highpart (SImode, operands[0]);
5041 operands[0] = gen_lowpart (SImode, operands[0]);
5042 operands[3] = gen_highpart (SImode, operands[1]);
5043 operands[1] = gen_lowpart (SImode, operands[1]);
5044 }"
5045 [(set_attr "length" "*,8,8,*")
5046 (set_attr "predicable" "no,yes,yes,no")
5047 (set_attr "type" "neon_move,multiple,multiple,neon_move")
5048 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
5049 )
5050
5051 (define_expand "one_cmplsi2"
5052 [(set (match_operand:SI 0 "s_register_operand" "")
5053 (not:SI (match_operand:SI 1 "s_register_operand" "")))]
5054 "TARGET_EITHER"
5055 ""
5056 )
5057
5058 (define_insn "*arm_one_cmplsi2"
5059 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
5060 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
5061 "TARGET_32BIT"
5062 "mvn%?\\t%0, %1"
5063 [(set_attr "predicable" "yes")
5064 (set_attr "predicable_short_it" "yes,no")
5065 (set_attr "arch" "t2,*")
5066 (set_attr "length" "4")
5067 (set_attr "type" "mvn_reg")]
5068 )
5069
5070 (define_insn "*notsi_compare0"
5071 [(set (reg:CC_NOOV CC_REGNUM)
5072 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5073 (const_int 0)))
5074 (set (match_operand:SI 0 "s_register_operand" "=r")
5075 (not:SI (match_dup 1)))]
5076 "TARGET_32BIT"
5077 "mvns%?\\t%0, %1"
5078 [(set_attr "conds" "set")
5079 (set_attr "type" "mvn_reg")]
5080 )
5081
5082 (define_insn "*notsi_compare0_scratch"
5083 [(set (reg:CC_NOOV CC_REGNUM)
5084 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
5085 (const_int 0)))
5086 (clobber (match_scratch:SI 0 "=r"))]
5087 "TARGET_32BIT"
5088 "mvns%?\\t%0, %1"
5089 [(set_attr "conds" "set")
5090 (set_attr "type" "mvn_reg")]
5091 )
5092 \f
5093 ;; Fixed <--> Floating conversion insns
5094
5095 (define_expand "floatsihf2"
5096 [(set (match_operand:HF 0 "general_operand" "")
5097 (float:HF (match_operand:SI 1 "general_operand" "")))]
5098 "TARGET_EITHER"
5099 "
5100 {
5101 rtx op1 = gen_reg_rtx (SFmode);
5102 expand_float (op1, operands[1], 0);
5103 op1 = convert_to_mode (HFmode, op1, 0);
5104 emit_move_insn (operands[0], op1);
5105 DONE;
5106 }"
5107 )
5108
5109 (define_expand "floatdihf2"
5110 [(set (match_operand:HF 0 "general_operand" "")
5111 (float:HF (match_operand:DI 1 "general_operand" "")))]
5112 "TARGET_EITHER"
5113 "
5114 {
5115 rtx op1 = gen_reg_rtx (SFmode);
5116 expand_float (op1, operands[1], 0);
5117 op1 = convert_to_mode (HFmode, op1, 0);
5118 emit_move_insn (operands[0], op1);
5119 DONE;
5120 }"
5121 )
5122
5123 (define_expand "floatsisf2"
5124 [(set (match_operand:SF 0 "s_register_operand" "")
5125 (float:SF (match_operand:SI 1 "s_register_operand" "")))]
5126 "TARGET_32BIT && TARGET_HARD_FLOAT"
5127 "
5128 ")
5129
5130 (define_expand "floatsidf2"
5131 [(set (match_operand:DF 0 "s_register_operand" "")
5132 (float:DF (match_operand:SI 1 "s_register_operand" "")))]
5133 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5134 "
5135 ")
5136
5137 (define_expand "fix_trunchfsi2"
5138 [(set (match_operand:SI 0 "general_operand" "")
5139 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5140 "TARGET_EITHER"
5141 "
5142 {
5143 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5144 expand_fix (operands[0], op1, 0);
5145 DONE;
5146 }"
5147 )
5148
5149 (define_expand "fix_trunchfdi2"
5150 [(set (match_operand:DI 0 "general_operand" "")
5151 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))]
5152 "TARGET_EITHER"
5153 "
5154 {
5155 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
5156 expand_fix (operands[0], op1, 0);
5157 DONE;
5158 }"
5159 )
5160
5161 (define_expand "fix_truncsfsi2"
5162 [(set (match_operand:SI 0 "s_register_operand" "")
5163 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
5164 "TARGET_32BIT && TARGET_HARD_FLOAT"
5165 "
5166 ")
5167
5168 (define_expand "fix_truncdfsi2"
5169 [(set (match_operand:SI 0 "s_register_operand" "")
5170 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
5171 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5172 "
5173 ")
5174
5175 ;; Truncation insns
5176
5177 (define_expand "truncdfsf2"
5178 [(set (match_operand:SF 0 "s_register_operand" "")
5179 (float_truncate:SF
5180 (match_operand:DF 1 "s_register_operand" "")))]
5181 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5182 ""
5183 )
5184
5185 ;; DFmode to HFmode conversions have to go through SFmode.
5186 (define_expand "truncdfhf2"
5187 [(set (match_operand:HF 0 "general_operand" "")
5188 (float_truncate:HF
5189 (match_operand:DF 1 "general_operand" "")))]
5190 "TARGET_EITHER"
5191 "
5192 {
5193 rtx op1;
5194 op1 = convert_to_mode (SFmode, operands[1], 0);
5195 op1 = convert_to_mode (HFmode, op1, 0);
5196 emit_move_insn (operands[0], op1);
5197 DONE;
5198 }"
5199 )
5200 \f
5201 ;; Zero and sign extension instructions.
5202
5203 (define_insn "zero_extend<mode>di2"
5204 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w")
5205 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
5206 "<qhs_zextenddi_cstr>")))]
5207 "TARGET_32BIT <qhs_zextenddi_cond>"
5208 "#"
5209 [(set_attr "length" "8,4,8,8")
5210 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")
5211 (set_attr "ce_count" "2")
5212 (set_attr "predicable" "yes")
5213 (set_attr "type" "multiple,mov_reg,multiple,multiple")]
5214 )
5215
5216 (define_insn "extend<mode>di2"
5217 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w")
5218 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
5219 "<qhs_extenddi_cstr>")))]
5220 "TARGET_32BIT <qhs_sextenddi_cond>"
5221 "#"
5222 [(set_attr "length" "8,4,8,8,8")
5223 (set_attr "ce_count" "2")
5224 (set_attr "shift" "1")
5225 (set_attr "predicable" "yes")
5226 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
5227 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
5228 )
5229
5230 ;; Splits for all extensions to DImode
5231 (define_split
5232 [(set (match_operand:DI 0 "s_register_operand" "")
5233 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5234 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5235 [(set (match_dup 0) (match_dup 1))]
5236 {
5237 rtx lo_part = gen_lowpart (SImode, operands[0]);
5238 machine_mode src_mode = GET_MODE (operands[1]);
5239
5240 if (REG_P (operands[0])
5241 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5242 emit_clobber (operands[0]);
5243 if (!REG_P (lo_part) || src_mode != SImode
5244 || !rtx_equal_p (lo_part, operands[1]))
5245 {
5246 if (src_mode == SImode)
5247 emit_move_insn (lo_part, operands[1]);
5248 else
5249 emit_insn (gen_rtx_SET (lo_part,
5250 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
5251 operands[1] = lo_part;
5252 }
5253 operands[0] = gen_highpart (SImode, operands[0]);
5254 operands[1] = const0_rtx;
5255 })
5256
5257 (define_split
5258 [(set (match_operand:DI 0 "s_register_operand" "")
5259 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
5260 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))"
5261 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
5262 {
5263 rtx lo_part = gen_lowpart (SImode, operands[0]);
5264 machine_mode src_mode = GET_MODE (operands[1]);
5265
5266 if (REG_P (operands[0])
5267 && !reg_overlap_mentioned_p (operands[0], operands[1]))
5268 emit_clobber (operands[0]);
5269
5270 if (!REG_P (lo_part) || src_mode != SImode
5271 || !rtx_equal_p (lo_part, operands[1]))
5272 {
5273 if (src_mode == SImode)
5274 emit_move_insn (lo_part, operands[1]);
5275 else
5276 emit_insn (gen_rtx_SET (lo_part,
5277 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
5278 operands[1] = lo_part;
5279 }
5280 operands[0] = gen_highpart (SImode, operands[0]);
5281 })
5282
5283 (define_expand "zero_extendhisi2"
5284 [(set (match_operand:SI 0 "s_register_operand" "")
5285 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5286 "TARGET_EITHER"
5287 {
5288 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
5289 {
5290 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
5291 DONE;
5292 }
5293 if (!arm_arch6 && !MEM_P (operands[1]))
5294 {
5295 rtx t = gen_lowpart (SImode, operands[1]);
5296 rtx tmp = gen_reg_rtx (SImode);
5297 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5298 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
5299 DONE;
5300 }
5301 })
5302
5303 (define_split
5304 [(set (match_operand:SI 0 "s_register_operand" "")
5305 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
5306 "!TARGET_THUMB2 && !arm_arch6"
5307 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5308 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
5309 {
5310 operands[2] = gen_lowpart (SImode, operands[1]);
5311 })
5312
5313 (define_insn "*arm_zero_extendhisi2"
5314 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5315 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
5316 "TARGET_ARM && arm_arch4 && !arm_arch6"
5317 "@
5318 #
5319 ldrh%?\\t%0, %1"
5320 [(set_attr "type" "alu_shift_reg,load_byte")
5321 (set_attr "predicable" "yes")]
5322 )
5323
5324 (define_insn "*arm_zero_extendhisi2_v6"
5325 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5326 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5327 "TARGET_ARM && arm_arch6"
5328 "@
5329 uxth%?\\t%0, %1
5330 ldrh%?\\t%0, %1"
5331 [(set_attr "predicable" "yes")
5332 (set_attr "type" "extend,load_byte")]
5333 )
5334
5335 (define_insn "*arm_zero_extendhisi2addsi"
5336 [(set (match_operand:SI 0 "s_register_operand" "=r")
5337 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5338 (match_operand:SI 2 "s_register_operand" "r")))]
5339 "TARGET_INT_SIMD"
5340 "uxtah%?\\t%0, %2, %1"
5341 [(set_attr "type" "alu_shift_reg")
5342 (set_attr "predicable" "yes")
5343 (set_attr "predicable_short_it" "no")]
5344 )
5345
5346 (define_expand "zero_extendqisi2"
5347 [(set (match_operand:SI 0 "s_register_operand" "")
5348 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
5349 "TARGET_EITHER"
5350 {
5351 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
5352 {
5353 emit_insn (gen_andsi3 (operands[0],
5354 gen_lowpart (SImode, operands[1]),
5355 GEN_INT (255)));
5356 DONE;
5357 }
5358 if (!arm_arch6 && !MEM_P (operands[1]))
5359 {
5360 rtx t = gen_lowpart (SImode, operands[1]);
5361 rtx tmp = gen_reg_rtx (SImode);
5362 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5363 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
5364 DONE;
5365 }
5366 })
5367
5368 (define_split
5369 [(set (match_operand:SI 0 "s_register_operand" "")
5370 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
5371 "!arm_arch6"
5372 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5373 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
5374 {
5375 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5376 if (TARGET_ARM)
5377 {
5378 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
5379 DONE;
5380 }
5381 })
5382
5383 (define_insn "*arm_zero_extendqisi2"
5384 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5385 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
5386 "TARGET_ARM && !arm_arch6"
5387 "@
5388 #
5389 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5390 [(set_attr "length" "8,4")
5391 (set_attr "type" "alu_shift_reg,load_byte")
5392 (set_attr "predicable" "yes")]
5393 )
5394
5395 (define_insn "*arm_zero_extendqisi2_v6"
5396 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5397 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
5398 "TARGET_ARM && arm_arch6"
5399 "@
5400 uxtb%?\\t%0, %1
5401 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
5402 [(set_attr "type" "extend,load_byte")
5403 (set_attr "predicable" "yes")]
5404 )
5405
5406 (define_insn "*arm_zero_extendqisi2addsi"
5407 [(set (match_operand:SI 0 "s_register_operand" "=r")
5408 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5409 (match_operand:SI 2 "s_register_operand" "r")))]
5410 "TARGET_INT_SIMD"
5411 "uxtab%?\\t%0, %2, %1"
5412 [(set_attr "predicable" "yes")
5413 (set_attr "predicable_short_it" "no")
5414 (set_attr "type" "alu_shift_reg")]
5415 )
5416
5417 (define_split
5418 [(set (match_operand:SI 0 "s_register_operand" "")
5419 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
5420 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5421 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
5422 [(set (match_dup 2) (match_dup 1))
5423 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5424 ""
5425 )
5426
5427 (define_split
5428 [(set (match_operand:SI 0 "s_register_operand" "")
5429 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
5430 (clobber (match_operand:SI 2 "s_register_operand" ""))]
5431 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
5432 [(set (match_dup 2) (match_dup 1))
5433 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
5434 ""
5435 )
5436
5437
5438 (define_split
5439 [(set (match_operand:SI 0 "s_register_operand" "")
5440 (IOR_XOR:SI (and:SI (ashift:SI
5441 (match_operand:SI 1 "s_register_operand" "")
5442 (match_operand:SI 2 "const_int_operand" ""))
5443 (match_operand:SI 3 "const_int_operand" ""))
5444 (zero_extend:SI
5445 (match_operator 5 "subreg_lowpart_operator"
5446 [(match_operand:SI 4 "s_register_operand" "")]))))]
5447 "TARGET_32BIT
5448 && (UINTVAL (operands[3])
5449 == (GET_MODE_MASK (GET_MODE (operands[5]))
5450 & (GET_MODE_MASK (GET_MODE (operands[5]))
5451 << (INTVAL (operands[2])))))"
5452 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
5453 (match_dup 4)))
5454 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
5455 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
5456 )
5457
5458 (define_insn "*compareqi_eq0"
5459 [(set (reg:CC_Z CC_REGNUM)
5460 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
5461 (const_int 0)))]
5462 "TARGET_32BIT"
5463 "tst%?\\t%0, #255"
5464 [(set_attr "conds" "set")
5465 (set_attr "predicable" "yes")
5466 (set_attr "predicable_short_it" "no")
5467 (set_attr "type" "logic_imm")]
5468 )
5469
5470 (define_expand "extendhisi2"
5471 [(set (match_operand:SI 0 "s_register_operand" "")
5472 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
5473 "TARGET_EITHER"
5474 {
5475 if (TARGET_THUMB1)
5476 {
5477 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
5478 DONE;
5479 }
5480 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
5481 {
5482 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
5483 DONE;
5484 }
5485
5486 if (!arm_arch6 && !MEM_P (operands[1]))
5487 {
5488 rtx t = gen_lowpart (SImode, operands[1]);
5489 rtx tmp = gen_reg_rtx (SImode);
5490 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
5491 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
5492 DONE;
5493 }
5494 })
5495
5496 (define_split
5497 [(parallel
5498 [(set (match_operand:SI 0 "register_operand" "")
5499 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
5500 (clobber (match_scratch:SI 2 ""))])]
5501 "!arm_arch6"
5502 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5503 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5504 {
5505 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5506 })
5507
5508 ;; This pattern will only be used when ldsh is not available
5509 (define_expand "extendhisi2_mem"
5510 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
5511 (set (match_dup 3)
5512 (zero_extend:SI (match_dup 7)))
5513 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
5514 (set (match_operand:SI 0 "" "")
5515 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
5516 "TARGET_ARM"
5517 "
5518 {
5519 rtx mem1, mem2;
5520 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
5521
5522 mem1 = change_address (operands[1], QImode, addr);
5523 mem2 = change_address (operands[1], QImode,
5524 plus_constant (Pmode, addr, 1));
5525 operands[0] = gen_lowpart (SImode, operands[0]);
5526 operands[1] = mem1;
5527 operands[2] = gen_reg_rtx (SImode);
5528 operands[3] = gen_reg_rtx (SImode);
5529 operands[6] = gen_reg_rtx (SImode);
5530 operands[7] = mem2;
5531
5532 if (BYTES_BIG_ENDIAN)
5533 {
5534 operands[4] = operands[2];
5535 operands[5] = operands[3];
5536 }
5537 else
5538 {
5539 operands[4] = operands[3];
5540 operands[5] = operands[2];
5541 }
5542 }"
5543 )
5544
5545 (define_split
5546 [(set (match_operand:SI 0 "register_operand" "")
5547 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
5548 "!arm_arch6"
5549 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
5550 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
5551 {
5552 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
5553 })
5554
5555 (define_insn "*arm_extendhisi2"
5556 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5557 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5558 "TARGET_ARM && arm_arch4 && !arm_arch6"
5559 "@
5560 #
5561 ldrsh%?\\t%0, %1"
5562 [(set_attr "length" "8,4")
5563 (set_attr "type" "alu_shift_reg,load_byte")
5564 (set_attr "predicable" "yes")]
5565 )
5566
5567 ;; ??? Check Thumb-2 pool range
5568 (define_insn "*arm_extendhisi2_v6"
5569 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5570 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
5571 "TARGET_32BIT && arm_arch6"
5572 "@
5573 sxth%?\\t%0, %1
5574 ldrsh%?\\t%0, %1"
5575 [(set_attr "type" "extend,load_byte")
5576 (set_attr "predicable" "yes")
5577 (set_attr "predicable_short_it" "no")]
5578 )
5579
5580 (define_insn "*arm_extendhisi2addsi"
5581 [(set (match_operand:SI 0 "s_register_operand" "=r")
5582 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
5583 (match_operand:SI 2 "s_register_operand" "r")))]
5584 "TARGET_INT_SIMD"
5585 "sxtah%?\\t%0, %2, %1"
5586 [(set_attr "type" "alu_shift_reg")]
5587 )
5588
5589 (define_expand "extendqihi2"
5590 [(set (match_dup 2)
5591 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")
5592 (const_int 24)))
5593 (set (match_operand:HI 0 "s_register_operand" "")
5594 (ashiftrt:SI (match_dup 2)
5595 (const_int 24)))]
5596 "TARGET_ARM"
5597 "
5598 {
5599 if (arm_arch4 && MEM_P (operands[1]))
5600 {
5601 emit_insn (gen_rtx_SET (operands[0],
5602 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5603 DONE;
5604 }
5605 if (!s_register_operand (operands[1], QImode))
5606 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5607 operands[0] = gen_lowpart (SImode, operands[0]);
5608 operands[1] = gen_lowpart (SImode, operands[1]);
5609 operands[2] = gen_reg_rtx (SImode);
5610 }"
5611 )
5612
5613 (define_insn "*arm_extendqihi_insn"
5614 [(set (match_operand:HI 0 "s_register_operand" "=r")
5615 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5616 "TARGET_ARM && arm_arch4"
5617 "ldrsb%?\\t%0, %1"
5618 [(set_attr "type" "load_byte")
5619 (set_attr "predicable" "yes")]
5620 )
5621
5622 (define_expand "extendqisi2"
5623 [(set (match_operand:SI 0 "s_register_operand" "")
5624 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))]
5625 "TARGET_EITHER"
5626 {
5627 if (!arm_arch4 && MEM_P (operands[1]))
5628 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5629
5630 if (!arm_arch6 && !MEM_P (operands[1]))
5631 {
5632 rtx t = gen_lowpart (SImode, operands[1]);
5633 rtx tmp = gen_reg_rtx (SImode);
5634 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5635 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5636 DONE;
5637 }
5638 })
5639
5640 (define_split
5641 [(set (match_operand:SI 0 "register_operand" "")
5642 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5643 "!arm_arch6"
5644 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5645 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5646 {
5647 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5648 })
5649
5650 (define_insn "*arm_extendqisi"
5651 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5652 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5653 "TARGET_ARM && arm_arch4 && !arm_arch6"
5654 "@
5655 #
5656 ldrsb%?\\t%0, %1"
5657 [(set_attr "length" "8,4")
5658 (set_attr "type" "alu_shift_reg,load_byte")
5659 (set_attr "predicable" "yes")]
5660 )
5661
5662 (define_insn "*arm_extendqisi_v6"
5663 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5664 (sign_extend:SI
5665 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5666 "TARGET_ARM && arm_arch6"
5667 "@
5668 sxtb%?\\t%0, %1
5669 ldrsb%?\\t%0, %1"
5670 [(set_attr "type" "extend,load_byte")
5671 (set_attr "predicable" "yes")]
5672 )
5673
5674 (define_insn "*arm_extendqisi2addsi"
5675 [(set (match_operand:SI 0 "s_register_operand" "=r")
5676 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5677 (match_operand:SI 2 "s_register_operand" "r")))]
5678 "TARGET_INT_SIMD"
5679 "sxtab%?\\t%0, %2, %1"
5680 [(set_attr "type" "alu_shift_reg")
5681 (set_attr "predicable" "yes")
5682 (set_attr "predicable_short_it" "no")]
5683 )
5684
5685 (define_expand "extendsfdf2"
5686 [(set (match_operand:DF 0 "s_register_operand" "")
5687 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
5688 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5689 ""
5690 )
5691
5692 ;; HFmode -> DFmode conversions have to go through SFmode.
5693 (define_expand "extendhfdf2"
5694 [(set (match_operand:DF 0 "general_operand" "")
5695 (float_extend:DF (match_operand:HF 1 "general_operand" "")))]
5696 "TARGET_EITHER"
5697 "
5698 {
5699 rtx op1;
5700 op1 = convert_to_mode (SFmode, operands[1], 0);
5701 op1 = convert_to_mode (DFmode, op1, 0);
5702 emit_insn (gen_movdf (operands[0], op1));
5703 DONE;
5704 }"
5705 )
5706 \f
5707 ;; Move insns (including loads and stores)
5708
5709 ;; XXX Just some ideas about movti.
5710 ;; I don't think these are a good idea on the arm, there just aren't enough
5711 ;; registers
5712 ;;(define_expand "loadti"
5713 ;; [(set (match_operand:TI 0 "s_register_operand" "")
5714 ;; (mem:TI (match_operand:SI 1 "address_operand" "")))]
5715 ;; "" "")
5716
5717 ;;(define_expand "storeti"
5718 ;; [(set (mem:TI (match_operand:TI 0 "address_operand" ""))
5719 ;; (match_operand:TI 1 "s_register_operand" ""))]
5720 ;; "" "")
5721
5722 ;;(define_expand "movti"
5723 ;; [(set (match_operand:TI 0 "general_operand" "")
5724 ;; (match_operand:TI 1 "general_operand" ""))]
5725 ;; ""
5726 ;; "
5727 ;;{
5728 ;; rtx insn;
5729 ;;
5730 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5731 ;; operands[1] = copy_to_reg (operands[1]);
5732 ;; if (MEM_P (operands[0]))
5733 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5734 ;; else if (MEM_P (operands[1]))
5735 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5736 ;; else
5737 ;; FAIL;
5738 ;;
5739 ;; emit_insn (insn);
5740 ;; DONE;
5741 ;;}")
5742
5743 ;; Recognize garbage generated above.
5744
5745 ;;(define_insn ""
5746 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5747 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5748 ;; ""
5749 ;; "*
5750 ;; {
5751 ;; register mem = (which_alternative < 3);
5752 ;; register const char *template;
5753 ;;
5754 ;; operands[mem] = XEXP (operands[mem], 0);
5755 ;; switch (which_alternative)
5756 ;; {
5757 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5758 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5759 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5760 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5761 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5762 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5763 ;; }
5764 ;; output_asm_insn (template, operands);
5765 ;; return \"\";
5766 ;; }")
5767
5768 (define_expand "movdi"
5769 [(set (match_operand:DI 0 "general_operand" "")
5770 (match_operand:DI 1 "general_operand" ""))]
5771 "TARGET_EITHER"
5772 "
5773 if (can_create_pseudo_p ())
5774 {
5775 if (!REG_P (operands[0]))
5776 operands[1] = force_reg (DImode, operands[1]);
5777 }
5778 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5779 && !HARD_REGNO_MODE_OK (REGNO (operands[0]), DImode))
5780 {
5781 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5782 when expanding function calls. */
5783 gcc_assert (can_create_pseudo_p ());
5784 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5785 {
5786 /* Perform load into legal reg pair first, then move. */
5787 rtx reg = gen_reg_rtx (DImode);
5788 emit_insn (gen_movdi (reg, operands[1]));
5789 operands[1] = reg;
5790 }
5791 emit_move_insn (gen_lowpart (SImode, operands[0]),
5792 gen_lowpart (SImode, operands[1]));
5793 emit_move_insn (gen_highpart (SImode, operands[0]),
5794 gen_highpart (SImode, operands[1]));
5795 DONE;
5796 }
5797 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5798 && !HARD_REGNO_MODE_OK (REGNO (operands[1]), DImode))
5799 {
5800 /* Avoid STRD's from an odd-numbered register pair in ARM state
5801 when expanding function prologue. */
5802 gcc_assert (can_create_pseudo_p ());
5803 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5804 ? gen_reg_rtx (DImode)
5805 : operands[0];
5806 emit_move_insn (gen_lowpart (SImode, split_dest),
5807 gen_lowpart (SImode, operands[1]));
5808 emit_move_insn (gen_highpart (SImode, split_dest),
5809 gen_highpart (SImode, operands[1]));
5810 if (split_dest != operands[0])
5811 emit_insn (gen_movdi (operands[0], split_dest));
5812 DONE;
5813 }
5814 "
5815 )
5816
5817 (define_insn "*arm_movdi"
5818 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m")
5819 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))]
5820 "TARGET_32BIT
5821 && !(TARGET_HARD_FLOAT)
5822 && !TARGET_IWMMXT
5823 && ( register_operand (operands[0], DImode)
5824 || register_operand (operands[1], DImode))"
5825 "*
5826 switch (which_alternative)
5827 {
5828 case 0:
5829 case 1:
5830 case 2:
5831 return \"#\";
5832 default:
5833 return output_move_double (operands, true, NULL);
5834 }
5835 "
5836 [(set_attr "length" "8,12,16,8,8")
5837 (set_attr "type" "multiple,multiple,multiple,load2,store2")
5838 (set_attr "arm_pool_range" "*,*,*,1020,*")
5839 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5840 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5841 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5842 )
5843
5844 (define_split
5845 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5846 (match_operand:ANY64 1 "immediate_operand" ""))]
5847 "TARGET_32BIT
5848 && reload_completed
5849 && (arm_const_double_inline_cost (operands[1])
5850 <= arm_max_const_double_inline_cost ())"
5851 [(const_int 0)]
5852 "
5853 arm_split_constant (SET, SImode, curr_insn,
5854 INTVAL (gen_lowpart (SImode, operands[1])),
5855 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5856 arm_split_constant (SET, SImode, curr_insn,
5857 INTVAL (gen_highpart_mode (SImode,
5858 GET_MODE (operands[0]),
5859 operands[1])),
5860 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5861 DONE;
5862 "
5863 )
5864
5865 ; If optimizing for size, or if we have load delay slots, then
5866 ; we want to split the constant into two separate operations.
5867 ; In both cases this may split a trivial part into a single data op
5868 ; leaving a single complex constant to load. We can also get longer
5869 ; offsets in a LDR which means we get better chances of sharing the pool
5870 ; entries. Finally, we can normally do a better job of scheduling
5871 ; LDR instructions than we can with LDM.
5872 ; This pattern will only match if the one above did not.
5873 (define_split
5874 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5875 (match_operand:ANY64 1 "const_double_operand" ""))]
5876 "TARGET_ARM && reload_completed
5877 && arm_const_double_by_parts (operands[1])"
5878 [(set (match_dup 0) (match_dup 1))
5879 (set (match_dup 2) (match_dup 3))]
5880 "
5881 operands[2] = gen_highpart (SImode, operands[0]);
5882 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5883 operands[1]);
5884 operands[0] = gen_lowpart (SImode, operands[0]);
5885 operands[1] = gen_lowpart (SImode, operands[1]);
5886 "
5887 )
5888
5889 (define_split
5890 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5891 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5892 "TARGET_EITHER && reload_completed"
5893 [(set (match_dup 0) (match_dup 1))
5894 (set (match_dup 2) (match_dup 3))]
5895 "
5896 operands[2] = gen_highpart (SImode, operands[0]);
5897 operands[3] = gen_highpart (SImode, operands[1]);
5898 operands[0] = gen_lowpart (SImode, operands[0]);
5899 operands[1] = gen_lowpart (SImode, operands[1]);
5900
5901 /* Handle a partial overlap. */
5902 if (rtx_equal_p (operands[0], operands[3]))
5903 {
5904 rtx tmp0 = operands[0];
5905 rtx tmp1 = operands[1];
5906
5907 operands[0] = operands[2];
5908 operands[1] = operands[3];
5909 operands[2] = tmp0;
5910 operands[3] = tmp1;
5911 }
5912 "
5913 )
5914
5915 ;; We can't actually do base+index doubleword loads if the index and
5916 ;; destination overlap. Split here so that we at least have chance to
5917 ;; schedule.
5918 (define_split
5919 [(set (match_operand:DI 0 "s_register_operand" "")
5920 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5921 (match_operand:SI 2 "s_register_operand" ""))))]
5922 "TARGET_LDRD
5923 && reg_overlap_mentioned_p (operands[0], operands[1])
5924 && reg_overlap_mentioned_p (operands[0], operands[2])"
5925 [(set (match_dup 4)
5926 (plus:SI (match_dup 1)
5927 (match_dup 2)))
5928 (set (match_dup 0)
5929 (mem:DI (match_dup 4)))]
5930 "
5931 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5932 "
5933 )
5934
5935 (define_expand "movsi"
5936 [(set (match_operand:SI 0 "general_operand" "")
5937 (match_operand:SI 1 "general_operand" ""))]
5938 "TARGET_EITHER"
5939 "
5940 {
5941 rtx base, offset, tmp;
5942
5943 if (TARGET_32BIT)
5944 {
5945 /* Everything except mem = const or mem = mem can be done easily. */
5946 if (MEM_P (operands[0]))
5947 operands[1] = force_reg (SImode, operands[1]);
5948 if (arm_general_register_operand (operands[0], SImode)
5949 && CONST_INT_P (operands[1])
5950 && !(const_ok_for_arm (INTVAL (operands[1]))
5951 || const_ok_for_arm (~INTVAL (operands[1]))))
5952 {
5953 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5954 {
5955 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5956 DONE;
5957 }
5958 else
5959 {
5960 arm_split_constant (SET, SImode, NULL_RTX,
5961 INTVAL (operands[1]), operands[0], NULL_RTX,
5962 optimize && can_create_pseudo_p ());
5963 DONE;
5964 }
5965 }
5966 }
5967 else /* TARGET_THUMB1... */
5968 {
5969 if (can_create_pseudo_p ())
5970 {
5971 if (!REG_P (operands[0]))
5972 operands[1] = force_reg (SImode, operands[1]);
5973 }
5974 }
5975
5976 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
5977 {
5978 split_const (operands[1], &base, &offset);
5979 if (GET_CODE (base) == SYMBOL_REF
5980 && !offset_within_block_p (base, INTVAL (offset)))
5981 {
5982 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5983 emit_move_insn (tmp, base);
5984 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5985 DONE;
5986 }
5987 }
5988
5989 /* Recognize the case where operand[1] is a reference to thread-local
5990 data and load its address to a register. */
5991 if (arm_tls_referenced_p (operands[1]))
5992 {
5993 rtx tmp = operands[1];
5994 rtx addend = NULL;
5995
5996 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
5997 {
5998 addend = XEXP (XEXP (tmp, 0), 1);
5999 tmp = XEXP (XEXP (tmp, 0), 0);
6000 }
6001
6002 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6003 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
6004
6005 tmp = legitimize_tls_address (tmp,
6006 !can_create_pseudo_p () ? operands[0] : 0);
6007 if (addend)
6008 {
6009 tmp = gen_rtx_PLUS (SImode, tmp, addend);
6010 tmp = force_operand (tmp, operands[0]);
6011 }
6012 operands[1] = tmp;
6013 }
6014 else if (flag_pic
6015 && (CONSTANT_P (operands[1])
6016 || symbol_mentioned_p (operands[1])
6017 || label_mentioned_p (operands[1])))
6018 operands[1] = legitimize_pic_address (operands[1], SImode,
6019 (!can_create_pseudo_p ()
6020 ? operands[0]
6021 : 0));
6022 }
6023 "
6024 )
6025
6026 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
6027 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
6028 ;; so this does not matter.
6029 (define_insn "*arm_movt"
6030 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
6031 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6032 (match_operand:SI 2 "general_operand" "i,i")))]
6033 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
6034 "@
6035 movt%?\t%0, #:upper16:%c2
6036 movt\t%0, #:upper16:%c2"
6037 [(set_attr "arch" "32,v8mb")
6038 (set_attr "predicable" "yes")
6039 (set_attr "predicable_short_it" "no")
6040 (set_attr "length" "4")
6041 (set_attr "type" "alu_sreg")]
6042 )
6043
6044 (define_insn "*arm_movsi_insn"
6045 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
6046 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
6047 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
6048 && ( register_operand (operands[0], SImode)
6049 || register_operand (operands[1], SImode))"
6050 "@
6051 mov%?\\t%0, %1
6052 mov%?\\t%0, %1
6053 mvn%?\\t%0, #%B1
6054 movw%?\\t%0, %1
6055 ldr%?\\t%0, %1
6056 str%?\\t%1, %0"
6057 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load1,store1")
6058 (set_attr "predicable" "yes")
6059 (set_attr "arch" "*,*,*,v6t2,*,*")
6060 (set_attr "pool_range" "*,*,*,*,4096,*")
6061 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
6062 )
6063
6064 (define_split
6065 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6066 (match_operand:SI 1 "const_int_operand" ""))]
6067 "TARGET_32BIT
6068 && (!(const_ok_for_arm (INTVAL (operands[1]))
6069 || const_ok_for_arm (~INTVAL (operands[1]))))"
6070 [(clobber (const_int 0))]
6071 "
6072 arm_split_constant (SET, SImode, NULL_RTX,
6073 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
6074 DONE;
6075 "
6076 )
6077
6078 ;; A normal way to do (symbol + offset) requires three instructions at least
6079 ;; (depends on how big the offset is) as below:
6080 ;; movw r0, #:lower16:g
6081 ;; movw r0, #:upper16:g
6082 ;; adds r0, #4
6083 ;;
6084 ;; A better way would be:
6085 ;; movw r0, #:lower16:g+4
6086 ;; movw r0, #:upper16:g+4
6087 ;;
6088 ;; The limitation of this way is that the length of offset should be a 16-bit
6089 ;; signed value, because current assembler only supports REL type relocation for
6090 ;; such case. If the more powerful RELA type is supported in future, we should
6091 ;; update this pattern to go with better way.
6092 (define_split
6093 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6094 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
6095 (match_operand:SI 2 "const_int_operand" ""))))]
6096 "TARGET_THUMB
6097 && TARGET_HAVE_MOVT
6098 && arm_disable_literal_pool
6099 && reload_completed
6100 && GET_CODE (operands[1]) == SYMBOL_REF"
6101 [(clobber (const_int 0))]
6102 "
6103 int offset = INTVAL (operands[2]);
6104
6105 if (offset < -0x8000 || offset > 0x7fff)
6106 {
6107 arm_emit_movpair (operands[0], operands[1]);
6108 emit_insn (gen_rtx_SET (operands[0],
6109 gen_rtx_PLUS (SImode, operands[0], operands[2])));
6110 }
6111 else
6112 {
6113 rtx op = gen_rtx_CONST (SImode,
6114 gen_rtx_PLUS (SImode, operands[1], operands[2]));
6115 arm_emit_movpair (operands[0], op);
6116 }
6117 "
6118 )
6119
6120 ;; Split symbol_refs at the later stage (after cprop), instead of generating
6121 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
6122 ;; and lo_sum would be merged back into memory load at cprop. However,
6123 ;; if the default is to prefer movt/movw rather than a load from the constant
6124 ;; pool, the performance is better.
6125 (define_split
6126 [(set (match_operand:SI 0 "arm_general_register_operand" "")
6127 (match_operand:SI 1 "general_operand" ""))]
6128 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
6129 && !flag_pic && !target_word_relocations
6130 && !arm_tls_referenced_p (operands[1])"
6131 [(clobber (const_int 0))]
6132 {
6133 arm_emit_movpair (operands[0], operands[1]);
6134 DONE;
6135 })
6136
6137 ;; When generating pic, we need to load the symbol offset into a register.
6138 ;; So that the optimizer does not confuse this with a normal symbol load
6139 ;; we use an unspec. The offset will be loaded from a constant pool entry,
6140 ;; since that is the only type of relocation we can use.
6141
6142 ;; Wrap calculation of the whole PIC address in a single pattern for the
6143 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
6144 ;; a PIC address involves two loads from memory, so we want to CSE it
6145 ;; as often as possible.
6146 ;; This pattern will be split into one of the pic_load_addr_* patterns
6147 ;; and a move after GCSE optimizations.
6148 ;;
6149 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
6150 (define_expand "calculate_pic_address"
6151 [(set (match_operand:SI 0 "register_operand" "")
6152 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6153 (unspec:SI [(match_operand:SI 2 "" "")]
6154 UNSPEC_PIC_SYM))))]
6155 "flag_pic"
6156 )
6157
6158 ;; Split calculate_pic_address into pic_load_addr_* and a move.
6159 (define_split
6160 [(set (match_operand:SI 0 "register_operand" "")
6161 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
6162 (unspec:SI [(match_operand:SI 2 "" "")]
6163 UNSPEC_PIC_SYM))))]
6164 "flag_pic"
6165 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
6166 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
6167 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
6168 )
6169
6170 ;; operand1 is the memory address to go into
6171 ;; pic_load_addr_32bit.
6172 ;; operand2 is the PIC label to be emitted
6173 ;; from pic_add_dot_plus_eight.
6174 ;; We do this to allow hoisting of the entire insn.
6175 (define_insn_and_split "pic_load_addr_unified"
6176 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
6177 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
6178 (match_operand:SI 2 "" "")]
6179 UNSPEC_PIC_UNIFIED))]
6180 "flag_pic"
6181 "#"
6182 "&& reload_completed"
6183 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
6184 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
6185 (match_dup 2)] UNSPEC_PIC_BASE))]
6186 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
6187 [(set_attr "type" "load1,load1,load1")
6188 (set_attr "pool_range" "4096,4094,1022")
6189 (set_attr "neg_pool_range" "4084,0,0")
6190 (set_attr "arch" "a,t2,t1")
6191 (set_attr "length" "8,6,4")]
6192 )
6193
6194 ;; The rather odd constraints on the following are to force reload to leave
6195 ;; the insn alone, and to force the minipool generation pass to then move
6196 ;; the GOT symbol to memory.
6197
6198 (define_insn "pic_load_addr_32bit"
6199 [(set (match_operand:SI 0 "s_register_operand" "=r")
6200 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6201 "TARGET_32BIT && flag_pic"
6202 "ldr%?\\t%0, %1"
6203 [(set_attr "type" "load1")
6204 (set (attr "pool_range")
6205 (if_then_else (eq_attr "is_thumb" "no")
6206 (const_int 4096)
6207 (const_int 4094)))
6208 (set (attr "neg_pool_range")
6209 (if_then_else (eq_attr "is_thumb" "no")
6210 (const_int 4084)
6211 (const_int 0)))]
6212 )
6213
6214 (define_insn "pic_load_addr_thumb1"
6215 [(set (match_operand:SI 0 "s_register_operand" "=l")
6216 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
6217 "TARGET_THUMB1 && flag_pic"
6218 "ldr\\t%0, %1"
6219 [(set_attr "type" "load1")
6220 (set (attr "pool_range") (const_int 1018))]
6221 )
6222
6223 (define_insn "pic_add_dot_plus_four"
6224 [(set (match_operand:SI 0 "register_operand" "=r")
6225 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
6226 (const_int 4)
6227 (match_operand 2 "" "")]
6228 UNSPEC_PIC_BASE))]
6229 "TARGET_THUMB"
6230 "*
6231 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6232 INTVAL (operands[2]));
6233 return \"add\\t%0, %|pc\";
6234 "
6235 [(set_attr "length" "2")
6236 (set_attr "type" "alu_sreg")]
6237 )
6238
6239 (define_insn "pic_add_dot_plus_eight"
6240 [(set (match_operand:SI 0 "register_operand" "=r")
6241 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6242 (const_int 8)
6243 (match_operand 2 "" "")]
6244 UNSPEC_PIC_BASE))]
6245 "TARGET_ARM"
6246 "*
6247 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6248 INTVAL (operands[2]));
6249 return \"add%?\\t%0, %|pc, %1\";
6250 "
6251 [(set_attr "predicable" "yes")
6252 (set_attr "type" "alu_sreg")]
6253 )
6254
6255 (define_insn "tls_load_dot_plus_eight"
6256 [(set (match_operand:SI 0 "register_operand" "=r")
6257 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
6258 (const_int 8)
6259 (match_operand 2 "" "")]
6260 UNSPEC_PIC_BASE)))]
6261 "TARGET_ARM"
6262 "*
6263 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
6264 INTVAL (operands[2]));
6265 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
6266 "
6267 [(set_attr "predicable" "yes")
6268 (set_attr "type" "load1")]
6269 )
6270
6271 ;; PIC references to local variables can generate pic_add_dot_plus_eight
6272 ;; followed by a load. These sequences can be crunched down to
6273 ;; tls_load_dot_plus_eight by a peephole.
6274
6275 (define_peephole2
6276 [(set (match_operand:SI 0 "register_operand" "")
6277 (unspec:SI [(match_operand:SI 3 "register_operand" "")
6278 (const_int 8)
6279 (match_operand 1 "" "")]
6280 UNSPEC_PIC_BASE))
6281 (set (match_operand:SI 2 "arm_general_register_operand" "")
6282 (mem:SI (match_dup 0)))]
6283 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
6284 [(set (match_dup 2)
6285 (mem:SI (unspec:SI [(match_dup 3)
6286 (const_int 8)
6287 (match_dup 1)]
6288 UNSPEC_PIC_BASE)))]
6289 ""
6290 )
6291
6292 (define_insn "pic_offset_arm"
6293 [(set (match_operand:SI 0 "register_operand" "=r")
6294 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
6295 (unspec:SI [(match_operand:SI 2 "" "X")]
6296 UNSPEC_PIC_OFFSET))))]
6297 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
6298 "ldr%?\\t%0, [%1,%2]"
6299 [(set_attr "type" "load1")]
6300 )
6301
6302 (define_expand "builtin_setjmp_receiver"
6303 [(label_ref (match_operand 0 "" ""))]
6304 "flag_pic"
6305 "
6306 {
6307 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
6308 register. */
6309 if (arm_pic_register != INVALID_REGNUM)
6310 arm_load_pic_register (1UL << 3);
6311 DONE;
6312 }")
6313
6314 ;; If copying one reg to another we can set the condition codes according to
6315 ;; its value. Such a move is common after a return from subroutine and the
6316 ;; result is being tested against zero.
6317
6318 (define_insn "*movsi_compare0"
6319 [(set (reg:CC CC_REGNUM)
6320 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
6321 (const_int 0)))
6322 (set (match_operand:SI 0 "s_register_operand" "=r,r")
6323 (match_dup 1))]
6324 "TARGET_32BIT"
6325 "@
6326 cmp%?\\t%0, #0
6327 subs%?\\t%0, %1, #0"
6328 [(set_attr "conds" "set")
6329 (set_attr "type" "alus_imm,alus_imm")]
6330 )
6331
6332 ;; Subroutine to store a half word from a register into memory.
6333 ;; Operand 0 is the source register (HImode)
6334 ;; Operand 1 is the destination address in a register (SImode)
6335
6336 ;; In both this routine and the next, we must be careful not to spill
6337 ;; a memory address of reg+large_const into a separate PLUS insn, since this
6338 ;; can generate unrecognizable rtl.
6339
6340 (define_expand "storehi"
6341 [;; store the low byte
6342 (set (match_operand 1 "" "") (match_dup 3))
6343 ;; extract the high byte
6344 (set (match_dup 2)
6345 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6346 ;; store the high byte
6347 (set (match_dup 4) (match_dup 5))]
6348 "TARGET_ARM"
6349 "
6350 {
6351 rtx op1 = operands[1];
6352 rtx addr = XEXP (op1, 0);
6353 enum rtx_code code = GET_CODE (addr);
6354
6355 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6356 || code == MINUS)
6357 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
6358
6359 operands[4] = adjust_address (op1, QImode, 1);
6360 operands[1] = adjust_address (operands[1], QImode, 0);
6361 operands[3] = gen_lowpart (QImode, operands[0]);
6362 operands[0] = gen_lowpart (SImode, operands[0]);
6363 operands[2] = gen_reg_rtx (SImode);
6364 operands[5] = gen_lowpart (QImode, operands[2]);
6365 }"
6366 )
6367
6368 (define_expand "storehi_bigend"
6369 [(set (match_dup 4) (match_dup 3))
6370 (set (match_dup 2)
6371 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
6372 (set (match_operand 1 "" "") (match_dup 5))]
6373 "TARGET_ARM"
6374 "
6375 {
6376 rtx op1 = operands[1];
6377 rtx addr = XEXP (op1, 0);
6378 enum rtx_code code = GET_CODE (addr);
6379
6380 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6381 || code == MINUS)
6382 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
6383
6384 operands[4] = adjust_address (op1, QImode, 1);
6385 operands[1] = adjust_address (operands[1], QImode, 0);
6386 operands[3] = gen_lowpart (QImode, operands[0]);
6387 operands[0] = gen_lowpart (SImode, operands[0]);
6388 operands[2] = gen_reg_rtx (SImode);
6389 operands[5] = gen_lowpart (QImode, operands[2]);
6390 }"
6391 )
6392
6393 ;; Subroutine to store a half word integer constant into memory.
6394 (define_expand "storeinthi"
6395 [(set (match_operand 0 "" "")
6396 (match_operand 1 "" ""))
6397 (set (match_dup 3) (match_dup 2))]
6398 "TARGET_ARM"
6399 "
6400 {
6401 HOST_WIDE_INT value = INTVAL (operands[1]);
6402 rtx addr = XEXP (operands[0], 0);
6403 rtx op0 = operands[0];
6404 enum rtx_code code = GET_CODE (addr);
6405
6406 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
6407 || code == MINUS)
6408 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
6409
6410 operands[1] = gen_reg_rtx (SImode);
6411 if (BYTES_BIG_ENDIAN)
6412 {
6413 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
6414 if ((value & 255) == ((value >> 8) & 255))
6415 operands[2] = operands[1];
6416 else
6417 {
6418 operands[2] = gen_reg_rtx (SImode);
6419 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
6420 }
6421 }
6422 else
6423 {
6424 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
6425 if ((value & 255) == ((value >> 8) & 255))
6426 operands[2] = operands[1];
6427 else
6428 {
6429 operands[2] = gen_reg_rtx (SImode);
6430 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
6431 }
6432 }
6433
6434 operands[3] = adjust_address (op0, QImode, 1);
6435 operands[0] = adjust_address (operands[0], QImode, 0);
6436 operands[2] = gen_lowpart (QImode, operands[2]);
6437 operands[1] = gen_lowpart (QImode, operands[1]);
6438 }"
6439 )
6440
6441 (define_expand "storehi_single_op"
6442 [(set (match_operand:HI 0 "memory_operand" "")
6443 (match_operand:HI 1 "general_operand" ""))]
6444 "TARGET_32BIT && arm_arch4"
6445 "
6446 if (!s_register_operand (operands[1], HImode))
6447 operands[1] = copy_to_mode_reg (HImode, operands[1]);
6448 "
6449 )
6450
6451 (define_expand "movhi"
6452 [(set (match_operand:HI 0 "general_operand" "")
6453 (match_operand:HI 1 "general_operand" ""))]
6454 "TARGET_EITHER"
6455 "
6456 if (TARGET_ARM)
6457 {
6458 if (can_create_pseudo_p ())
6459 {
6460 if (MEM_P (operands[0]))
6461 {
6462 if (arm_arch4)
6463 {
6464 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
6465 DONE;
6466 }
6467 if (CONST_INT_P (operands[1]))
6468 emit_insn (gen_storeinthi (operands[0], operands[1]));
6469 else
6470 {
6471 if (MEM_P (operands[1]))
6472 operands[1] = force_reg (HImode, operands[1]);
6473 if (BYTES_BIG_ENDIAN)
6474 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
6475 else
6476 emit_insn (gen_storehi (operands[1], operands[0]));
6477 }
6478 DONE;
6479 }
6480 /* Sign extend a constant, and keep it in an SImode reg. */
6481 else if (CONST_INT_P (operands[1]))
6482 {
6483 rtx reg = gen_reg_rtx (SImode);
6484 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6485
6486 /* If the constant is already valid, leave it alone. */
6487 if (!const_ok_for_arm (val))
6488 {
6489 /* If setting all the top bits will make the constant
6490 loadable in a single instruction, then set them.
6491 Otherwise, sign extend the number. */
6492
6493 if (const_ok_for_arm (~(val | ~0xffff)))
6494 val |= ~0xffff;
6495 else if (val & 0x8000)
6496 val |= ~0xffff;
6497 }
6498
6499 emit_insn (gen_movsi (reg, GEN_INT (val)));
6500 operands[1] = gen_lowpart (HImode, reg);
6501 }
6502 else if (arm_arch4 && optimize && can_create_pseudo_p ()
6503 && MEM_P (operands[1]))
6504 {
6505 rtx reg = gen_reg_rtx (SImode);
6506
6507 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6508 operands[1] = gen_lowpart (HImode, reg);
6509 }
6510 else if (!arm_arch4)
6511 {
6512 if (MEM_P (operands[1]))
6513 {
6514 rtx base;
6515 rtx offset = const0_rtx;
6516 rtx reg = gen_reg_rtx (SImode);
6517
6518 if ((REG_P (base = XEXP (operands[1], 0))
6519 || (GET_CODE (base) == PLUS
6520 && (CONST_INT_P (offset = XEXP (base, 1)))
6521 && ((INTVAL(offset) & 1) != 1)
6522 && REG_P (base = XEXP (base, 0))))
6523 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
6524 {
6525 rtx new_rtx;
6526
6527 new_rtx = widen_memory_access (operands[1], SImode,
6528 ((INTVAL (offset) & ~3)
6529 - INTVAL (offset)));
6530 emit_insn (gen_movsi (reg, new_rtx));
6531 if (((INTVAL (offset) & 2) != 0)
6532 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
6533 {
6534 rtx reg2 = gen_reg_rtx (SImode);
6535
6536 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
6537 reg = reg2;
6538 }
6539 }
6540 else
6541 emit_insn (gen_movhi_bytes (reg, operands[1]));
6542
6543 operands[1] = gen_lowpart (HImode, reg);
6544 }
6545 }
6546 }
6547 /* Handle loading a large integer during reload. */
6548 else if (CONST_INT_P (operands[1])
6549 && !const_ok_for_arm (INTVAL (operands[1]))
6550 && !const_ok_for_arm (~INTVAL (operands[1])))
6551 {
6552 /* Writing a constant to memory needs a scratch, which should
6553 be handled with SECONDARY_RELOADs. */
6554 gcc_assert (REG_P (operands[0]));
6555
6556 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6557 emit_insn (gen_movsi (operands[0], operands[1]));
6558 DONE;
6559 }
6560 }
6561 else if (TARGET_THUMB2)
6562 {
6563 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
6564 if (can_create_pseudo_p ())
6565 {
6566 if (!REG_P (operands[0]))
6567 operands[1] = force_reg (HImode, operands[1]);
6568 /* Zero extend a constant, and keep it in an SImode reg. */
6569 else if (CONST_INT_P (operands[1]))
6570 {
6571 rtx reg = gen_reg_rtx (SImode);
6572 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
6573
6574 emit_insn (gen_movsi (reg, GEN_INT (val)));
6575 operands[1] = gen_lowpart (HImode, reg);
6576 }
6577 }
6578 }
6579 else /* TARGET_THUMB1 */
6580 {
6581 if (can_create_pseudo_p ())
6582 {
6583 if (CONST_INT_P (operands[1]))
6584 {
6585 rtx reg = gen_reg_rtx (SImode);
6586
6587 emit_insn (gen_movsi (reg, operands[1]));
6588 operands[1] = gen_lowpart (HImode, reg);
6589 }
6590
6591 /* ??? We shouldn't really get invalid addresses here, but this can
6592 happen if we are passed a SP (never OK for HImode/QImode) or
6593 virtual register (also rejected as illegitimate for HImode/QImode)
6594 relative address. */
6595 /* ??? This should perhaps be fixed elsewhere, for instance, in
6596 fixup_stack_1, by checking for other kinds of invalid addresses,
6597 e.g. a bare reference to a virtual register. This may confuse the
6598 alpha though, which must handle this case differently. */
6599 if (MEM_P (operands[0])
6600 && !memory_address_p (GET_MODE (operands[0]),
6601 XEXP (operands[0], 0)))
6602 operands[0]
6603 = replace_equiv_address (operands[0],
6604 copy_to_reg (XEXP (operands[0], 0)));
6605
6606 if (MEM_P (operands[1])
6607 && !memory_address_p (GET_MODE (operands[1]),
6608 XEXP (operands[1], 0)))
6609 operands[1]
6610 = replace_equiv_address (operands[1],
6611 copy_to_reg (XEXP (operands[1], 0)));
6612
6613 if (MEM_P (operands[1]) && optimize > 0)
6614 {
6615 rtx reg = gen_reg_rtx (SImode);
6616
6617 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6618 operands[1] = gen_lowpart (HImode, reg);
6619 }
6620
6621 if (MEM_P (operands[0]))
6622 operands[1] = force_reg (HImode, operands[1]);
6623 }
6624 else if (CONST_INT_P (operands[1])
6625 && !satisfies_constraint_I (operands[1]))
6626 {
6627 /* Handle loading a large integer during reload. */
6628
6629 /* Writing a constant to memory needs a scratch, which should
6630 be handled with SECONDARY_RELOADs. */
6631 gcc_assert (REG_P (operands[0]));
6632
6633 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6634 emit_insn (gen_movsi (operands[0], operands[1]));
6635 DONE;
6636 }
6637 }
6638 "
6639 )
6640
6641 (define_expand "movhi_bytes"
6642 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6643 (set (match_dup 3)
6644 (zero_extend:SI (match_dup 6)))
6645 (set (match_operand:SI 0 "" "")
6646 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6647 "TARGET_ARM"
6648 "
6649 {
6650 rtx mem1, mem2;
6651 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6652
6653 mem1 = change_address (operands[1], QImode, addr);
6654 mem2 = change_address (operands[1], QImode,
6655 plus_constant (Pmode, addr, 1));
6656 operands[0] = gen_lowpart (SImode, operands[0]);
6657 operands[1] = mem1;
6658 operands[2] = gen_reg_rtx (SImode);
6659 operands[3] = gen_reg_rtx (SImode);
6660 operands[6] = mem2;
6661
6662 if (BYTES_BIG_ENDIAN)
6663 {
6664 operands[4] = operands[2];
6665 operands[5] = operands[3];
6666 }
6667 else
6668 {
6669 operands[4] = operands[3];
6670 operands[5] = operands[2];
6671 }
6672 }"
6673 )
6674
6675 (define_expand "movhi_bigend"
6676 [(set (match_dup 2)
6677 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0)
6678 (const_int 16)))
6679 (set (match_dup 3)
6680 (ashiftrt:SI (match_dup 2) (const_int 16)))
6681 (set (match_operand:HI 0 "s_register_operand" "")
6682 (match_dup 4))]
6683 "TARGET_ARM"
6684 "
6685 operands[2] = gen_reg_rtx (SImode);
6686 operands[3] = gen_reg_rtx (SImode);
6687 operands[4] = gen_lowpart (HImode, operands[3]);
6688 "
6689 )
6690
6691 ;; Pattern to recognize insn generated default case above
6692 (define_insn "*movhi_insn_arch4"
6693 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6694 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6695 "TARGET_ARM
6696 && arm_arch4 && !TARGET_HARD_FLOAT
6697 && (register_operand (operands[0], HImode)
6698 || register_operand (operands[1], HImode))"
6699 "@
6700 mov%?\\t%0, %1\\t%@ movhi
6701 mvn%?\\t%0, #%B1\\t%@ movhi
6702 movw%?\\t%0, %L1\\t%@ movhi
6703 strh%?\\t%1, %0\\t%@ movhi
6704 ldrh%?\\t%0, %1\\t%@ movhi"
6705 [(set_attr "predicable" "yes")
6706 (set_attr "pool_range" "*,*,*,*,256")
6707 (set_attr "neg_pool_range" "*,*,*,*,244")
6708 (set_attr "arch" "*,*,v6t2,*,*")
6709 (set_attr_alternative "type"
6710 [(if_then_else (match_operand 1 "const_int_operand" "")
6711 (const_string "mov_imm" )
6712 (const_string "mov_reg"))
6713 (const_string "mvn_imm")
6714 (const_string "mov_imm")
6715 (const_string "store1")
6716 (const_string "load1")])]
6717 )
6718
6719 (define_insn "*movhi_bytes"
6720 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6721 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6722 "TARGET_ARM && !TARGET_HARD_FLOAT"
6723 "@
6724 mov%?\\t%0, %1\\t%@ movhi
6725 mov%?\\t%0, %1\\t%@ movhi
6726 mvn%?\\t%0, #%B1\\t%@ movhi"
6727 [(set_attr "predicable" "yes")
6728 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6729 )
6730
6731 ;; We use a DImode scratch because we may occasionally need an additional
6732 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6733 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6734 (define_expand "reload_outhi"
6735 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6736 (match_operand:HI 1 "s_register_operand" "r")
6737 (match_operand:DI 2 "s_register_operand" "=&l")])]
6738 "TARGET_EITHER"
6739 "if (TARGET_ARM)
6740 arm_reload_out_hi (operands);
6741 else
6742 thumb_reload_out_hi (operands);
6743 DONE;
6744 "
6745 )
6746
6747 (define_expand "reload_inhi"
6748 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6749 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6750 (match_operand:DI 2 "s_register_operand" "=&r")])]
6751 "TARGET_EITHER"
6752 "
6753 if (TARGET_ARM)
6754 arm_reload_in_hi (operands);
6755 else
6756 thumb_reload_out_hi (operands);
6757 DONE;
6758 ")
6759
6760 (define_expand "movqi"
6761 [(set (match_operand:QI 0 "general_operand" "")
6762 (match_operand:QI 1 "general_operand" ""))]
6763 "TARGET_EITHER"
6764 "
6765 /* Everything except mem = const or mem = mem can be done easily */
6766
6767 if (can_create_pseudo_p ())
6768 {
6769 if (CONST_INT_P (operands[1]))
6770 {
6771 rtx reg = gen_reg_rtx (SImode);
6772
6773 /* For thumb we want an unsigned immediate, then we are more likely
6774 to be able to use a movs insn. */
6775 if (TARGET_THUMB)
6776 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6777
6778 emit_insn (gen_movsi (reg, operands[1]));
6779 operands[1] = gen_lowpart (QImode, reg);
6780 }
6781
6782 if (TARGET_THUMB)
6783 {
6784 /* ??? We shouldn't really get invalid addresses here, but this can
6785 happen if we are passed a SP (never OK for HImode/QImode) or
6786 virtual register (also rejected as illegitimate for HImode/QImode)
6787 relative address. */
6788 /* ??? This should perhaps be fixed elsewhere, for instance, in
6789 fixup_stack_1, by checking for other kinds of invalid addresses,
6790 e.g. a bare reference to a virtual register. This may confuse the
6791 alpha though, which must handle this case differently. */
6792 if (MEM_P (operands[0])
6793 && !memory_address_p (GET_MODE (operands[0]),
6794 XEXP (operands[0], 0)))
6795 operands[0]
6796 = replace_equiv_address (operands[0],
6797 copy_to_reg (XEXP (operands[0], 0)));
6798 if (MEM_P (operands[1])
6799 && !memory_address_p (GET_MODE (operands[1]),
6800 XEXP (operands[1], 0)))
6801 operands[1]
6802 = replace_equiv_address (operands[1],
6803 copy_to_reg (XEXP (operands[1], 0)));
6804 }
6805
6806 if (MEM_P (operands[1]) && optimize > 0)
6807 {
6808 rtx reg = gen_reg_rtx (SImode);
6809
6810 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6811 operands[1] = gen_lowpart (QImode, reg);
6812 }
6813
6814 if (MEM_P (operands[0]))
6815 operands[1] = force_reg (QImode, operands[1]);
6816 }
6817 else if (TARGET_THUMB
6818 && CONST_INT_P (operands[1])
6819 && !satisfies_constraint_I (operands[1]))
6820 {
6821 /* Handle loading a large integer during reload. */
6822
6823 /* Writing a constant to memory needs a scratch, which should
6824 be handled with SECONDARY_RELOADs. */
6825 gcc_assert (REG_P (operands[0]));
6826
6827 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6828 emit_insn (gen_movsi (operands[0], operands[1]));
6829 DONE;
6830 }
6831 "
6832 )
6833
6834 (define_insn "*arm_movqi_insn"
6835 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6836 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6837 "TARGET_32BIT
6838 && ( register_operand (operands[0], QImode)
6839 || register_operand (operands[1], QImode))"
6840 "@
6841 mov%?\\t%0, %1
6842 mov%?\\t%0, %1
6843 mov%?\\t%0, %1
6844 mov%?\\t%0, %1
6845 mvn%?\\t%0, #%B1
6846 ldrb%?\\t%0, %1
6847 strb%?\\t%1, %0
6848 ldrb%?\\t%0, %1
6849 strb%?\\t%1, %0"
6850 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load1,store1,load1,store1")
6851 (set_attr "predicable" "yes")
6852 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6853 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6854 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6855 )
6856
6857 ;; HFmode moves
6858 (define_expand "movhf"
6859 [(set (match_operand:HF 0 "general_operand" "")
6860 (match_operand:HF 1 "general_operand" ""))]
6861 "TARGET_EITHER"
6862 "
6863 if (TARGET_32BIT)
6864 {
6865 if (MEM_P (operands[0]))
6866 operands[1] = force_reg (HFmode, operands[1]);
6867 }
6868 else /* TARGET_THUMB1 */
6869 {
6870 if (can_create_pseudo_p ())
6871 {
6872 if (!REG_P (operands[0]))
6873 operands[1] = force_reg (HFmode, operands[1]);
6874 }
6875 }
6876 "
6877 )
6878
6879 (define_insn "*arm32_movhf"
6880 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6881 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6882 "TARGET_32BIT && !TARGET_HARD_FLOAT
6883 && ( s_register_operand (operands[0], HFmode)
6884 || s_register_operand (operands[1], HFmode))"
6885 "*
6886 switch (which_alternative)
6887 {
6888 case 0: /* ARM register from memory */
6889 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6890 case 1: /* memory from ARM register */
6891 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6892 case 2: /* ARM register from ARM register */
6893 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6894 case 3: /* ARM register from constant */
6895 {
6896 long bits;
6897 rtx ops[4];
6898
6899 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6900 HFmode);
6901 ops[0] = operands[0];
6902 ops[1] = GEN_INT (bits);
6903 ops[2] = GEN_INT (bits & 0xff00);
6904 ops[3] = GEN_INT (bits & 0x00ff);
6905
6906 if (arm_arch_thumb2)
6907 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6908 else
6909 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6910 return \"\";
6911 }
6912 default:
6913 gcc_unreachable ();
6914 }
6915 "
6916 [(set_attr "conds" "unconditional")
6917 (set_attr "type" "load1,store1,mov_reg,multiple")
6918 (set_attr "length" "4,4,4,8")
6919 (set_attr "predicable" "yes")
6920 (set_attr "predicable_short_it" "no")]
6921 )
6922
6923 (define_expand "movsf"
6924 [(set (match_operand:SF 0 "general_operand" "")
6925 (match_operand:SF 1 "general_operand" ""))]
6926 "TARGET_EITHER"
6927 "
6928 if (TARGET_32BIT)
6929 {
6930 if (MEM_P (operands[0]))
6931 operands[1] = force_reg (SFmode, operands[1]);
6932 }
6933 else /* TARGET_THUMB1 */
6934 {
6935 if (can_create_pseudo_p ())
6936 {
6937 if (!REG_P (operands[0]))
6938 operands[1] = force_reg (SFmode, operands[1]);
6939 }
6940 }
6941 "
6942 )
6943
6944 ;; Transform a floating-point move of a constant into a core register into
6945 ;; an SImode operation.
6946 (define_split
6947 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6948 (match_operand:SF 1 "immediate_operand" ""))]
6949 "TARGET_EITHER
6950 && reload_completed
6951 && CONST_DOUBLE_P (operands[1])"
6952 [(set (match_dup 2) (match_dup 3))]
6953 "
6954 operands[2] = gen_lowpart (SImode, operands[0]);
6955 operands[3] = gen_lowpart (SImode, operands[1]);
6956 if (operands[2] == 0 || operands[3] == 0)
6957 FAIL;
6958 "
6959 )
6960
6961 (define_insn "*arm_movsf_soft_insn"
6962 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6963 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6964 "TARGET_32BIT
6965 && TARGET_SOFT_FLOAT
6966 && (!MEM_P (operands[0])
6967 || register_operand (operands[1], SFmode))"
6968 "@
6969 mov%?\\t%0, %1
6970 ldr%?\\t%0, %1\\t%@ float
6971 str%?\\t%1, %0\\t%@ float"
6972 [(set_attr "predicable" "yes")
6973 (set_attr "predicable_short_it" "no")
6974 (set_attr "type" "mov_reg,load1,store1")
6975 (set_attr "arm_pool_range" "*,4096,*")
6976 (set_attr "thumb2_pool_range" "*,4094,*")
6977 (set_attr "arm_neg_pool_range" "*,4084,*")
6978 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6979 )
6980
6981 (define_expand "movdf"
6982 [(set (match_operand:DF 0 "general_operand" "")
6983 (match_operand:DF 1 "general_operand" ""))]
6984 "TARGET_EITHER"
6985 "
6986 if (TARGET_32BIT)
6987 {
6988 if (MEM_P (operands[0]))
6989 operands[1] = force_reg (DFmode, operands[1]);
6990 }
6991 else /* TARGET_THUMB */
6992 {
6993 if (can_create_pseudo_p ())
6994 {
6995 if (!REG_P (operands[0]))
6996 operands[1] = force_reg (DFmode, operands[1]);
6997 }
6998 }
6999 "
7000 )
7001
7002 ;; Reloading a df mode value stored in integer regs to memory can require a
7003 ;; scratch reg.
7004 (define_expand "reload_outdf"
7005 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
7006 (match_operand:DF 1 "s_register_operand" "r")
7007 (match_operand:SI 2 "s_register_operand" "=&r")]
7008 "TARGET_THUMB2"
7009 "
7010 {
7011 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
7012
7013 if (code == REG)
7014 operands[2] = XEXP (operands[0], 0);
7015 else if (code == POST_INC || code == PRE_DEC)
7016 {
7017 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7018 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
7019 emit_insn (gen_movdi (operands[0], operands[1]));
7020 DONE;
7021 }
7022 else if (code == PRE_INC)
7023 {
7024 rtx reg = XEXP (XEXP (operands[0], 0), 0);
7025
7026 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
7027 operands[2] = reg;
7028 }
7029 else if (code == POST_DEC)
7030 operands[2] = XEXP (XEXP (operands[0], 0), 0);
7031 else
7032 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
7033 XEXP (XEXP (operands[0], 0), 1)));
7034
7035 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
7036 operands[1]));
7037
7038 if (code == POST_DEC)
7039 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
7040
7041 DONE;
7042 }"
7043 )
7044
7045 (define_insn "*movdf_soft_insn"
7046 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m")
7047 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))]
7048 "TARGET_32BIT && TARGET_SOFT_FLOAT
7049 && ( register_operand (operands[0], DFmode)
7050 || register_operand (operands[1], DFmode))"
7051 "*
7052 switch (which_alternative)
7053 {
7054 case 0:
7055 case 1:
7056 case 2:
7057 return \"#\";
7058 default:
7059 return output_move_double (operands, true, NULL);
7060 }
7061 "
7062 [(set_attr "length" "8,12,16,8,8")
7063 (set_attr "type" "multiple,multiple,multiple,load2,store2")
7064 (set_attr "arm_pool_range" "*,*,*,1020,*")
7065 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
7066 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
7067 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
7068 )
7069 \f
7070
7071 ;; load- and store-multiple insns
7072 ;; The arm can load/store any set of registers, provided that they are in
7073 ;; ascending order, but these expanders assume a contiguous set.
7074
7075 (define_expand "load_multiple"
7076 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7077 (match_operand:SI 1 "" ""))
7078 (use (match_operand:SI 2 "" ""))])]
7079 "TARGET_32BIT"
7080 {
7081 HOST_WIDE_INT offset = 0;
7082
7083 /* Support only fixed point registers. */
7084 if (!CONST_INT_P (operands[2])
7085 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7086 || INTVAL (operands[2]) < 2
7087 || !MEM_P (operands[1])
7088 || !REG_P (operands[0])
7089 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
7090 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7091 FAIL;
7092
7093 operands[3]
7094 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
7095 INTVAL (operands[2]),
7096 force_reg (SImode, XEXP (operands[1], 0)),
7097 FALSE, operands[1], &offset);
7098 })
7099
7100 (define_expand "store_multiple"
7101 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
7102 (match_operand:SI 1 "" ""))
7103 (use (match_operand:SI 2 "" ""))])]
7104 "TARGET_32BIT"
7105 {
7106 HOST_WIDE_INT offset = 0;
7107
7108 /* Support only fixed point registers. */
7109 if (!CONST_INT_P (operands[2])
7110 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
7111 || INTVAL (operands[2]) < 2
7112 || !REG_P (operands[1])
7113 || !MEM_P (operands[0])
7114 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
7115 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
7116 FAIL;
7117
7118 operands[3]
7119 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
7120 INTVAL (operands[2]),
7121 force_reg (SImode, XEXP (operands[0], 0)),
7122 FALSE, operands[0], &offset);
7123 })
7124
7125
7126 (define_expand "setmemsi"
7127 [(match_operand:BLK 0 "general_operand" "")
7128 (match_operand:SI 1 "const_int_operand" "")
7129 (match_operand:SI 2 "const_int_operand" "")
7130 (match_operand:SI 3 "const_int_operand" "")]
7131 "TARGET_32BIT"
7132 {
7133 if (arm_gen_setmem (operands))
7134 DONE;
7135
7136 FAIL;
7137 })
7138
7139
7140 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
7141 ;; We could let this apply for blocks of less than this, but it clobbers so
7142 ;; many registers that there is then probably a better way.
7143
7144 (define_expand "movmemqi"
7145 [(match_operand:BLK 0 "general_operand" "")
7146 (match_operand:BLK 1 "general_operand" "")
7147 (match_operand:SI 2 "const_int_operand" "")
7148 (match_operand:SI 3 "const_int_operand" "")]
7149 ""
7150 "
7151 if (TARGET_32BIT)
7152 {
7153 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
7154 && !optimize_function_for_size_p (cfun))
7155 {
7156 if (gen_movmem_ldrd_strd (operands))
7157 DONE;
7158 FAIL;
7159 }
7160
7161 if (arm_gen_movmemqi (operands))
7162 DONE;
7163 FAIL;
7164 }
7165 else /* TARGET_THUMB1 */
7166 {
7167 if ( INTVAL (operands[3]) != 4
7168 || INTVAL (operands[2]) > 48)
7169 FAIL;
7170
7171 thumb_expand_movmemqi (operands);
7172 DONE;
7173 }
7174 "
7175 )
7176 \f
7177
7178 ;; Compare & branch insns
7179 ;; The range calculations are based as follows:
7180 ;; For forward branches, the address calculation returns the address of
7181 ;; the next instruction. This is 2 beyond the branch instruction.
7182 ;; For backward branches, the address calculation returns the address of
7183 ;; the first instruction in this pattern (cmp). This is 2 before the branch
7184 ;; instruction for the shortest sequence, and 4 before the branch instruction
7185 ;; if we have to jump around an unconditional branch.
7186 ;; To the basic branch range the PC offset must be added (this is +4).
7187 ;; So for forward branches we have
7188 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
7189 ;; And for backward branches we have
7190 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
7191 ;;
7192 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
7193 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
7194
7195 (define_expand "cbranchsi4"
7196 [(set (pc) (if_then_else
7197 (match_operator 0 "expandable_comparison_operator"
7198 [(match_operand:SI 1 "s_register_operand" "")
7199 (match_operand:SI 2 "nonmemory_operand" "")])
7200 (label_ref (match_operand 3 "" ""))
7201 (pc)))]
7202 "TARGET_EITHER"
7203 "
7204 if (!TARGET_THUMB1)
7205 {
7206 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7207 FAIL;
7208 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7209 operands[3]));
7210 DONE;
7211 }
7212 if (thumb1_cmpneg_operand (operands[2], SImode))
7213 {
7214 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
7215 operands[3], operands[0]));
7216 DONE;
7217 }
7218 if (!thumb1_cmp_operand (operands[2], SImode))
7219 operands[2] = force_reg (SImode, operands[2]);
7220 ")
7221
7222 (define_expand "cbranchsf4"
7223 [(set (pc) (if_then_else
7224 (match_operator 0 "expandable_comparison_operator"
7225 [(match_operand:SF 1 "s_register_operand" "")
7226 (match_operand:SF 2 "vfp_compare_operand" "")])
7227 (label_ref (match_operand 3 "" ""))
7228 (pc)))]
7229 "TARGET_32BIT && TARGET_HARD_FLOAT"
7230 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7231 operands[3])); DONE;"
7232 )
7233
7234 (define_expand "cbranchdf4"
7235 [(set (pc) (if_then_else
7236 (match_operator 0 "expandable_comparison_operator"
7237 [(match_operand:DF 1 "s_register_operand" "")
7238 (match_operand:DF 2 "vfp_compare_operand" "")])
7239 (label_ref (match_operand 3 "" ""))
7240 (pc)))]
7241 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7242 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7243 operands[3])); DONE;"
7244 )
7245
7246 (define_expand "cbranchdi4"
7247 [(set (pc) (if_then_else
7248 (match_operator 0 "expandable_comparison_operator"
7249 [(match_operand:DI 1 "s_register_operand" "")
7250 (match_operand:DI 2 "cmpdi_operand" "")])
7251 (label_ref (match_operand 3 "" ""))
7252 (pc)))]
7253 "TARGET_32BIT"
7254 "{
7255 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
7256 FAIL;
7257 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
7258 operands[3]));
7259 DONE;
7260 }"
7261 )
7262
7263 ;; Comparison and test insns
7264
7265 (define_insn "*arm_cmpsi_insn"
7266 [(set (reg:CC CC_REGNUM)
7267 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
7268 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
7269 "TARGET_32BIT"
7270 "@
7271 cmp%?\\t%0, %1
7272 cmp%?\\t%0, %1
7273 cmp%?\\t%0, %1
7274 cmp%?\\t%0, %1
7275 cmn%?\\t%0, #%n1"
7276 [(set_attr "conds" "set")
7277 (set_attr "arch" "t2,t2,any,any,any")
7278 (set_attr "length" "2,2,4,4,4")
7279 (set_attr "predicable" "yes")
7280 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
7281 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
7282 )
7283
7284 (define_insn "*cmpsi_shiftsi"
7285 [(set (reg:CC CC_REGNUM)
7286 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
7287 (match_operator:SI 3 "shift_operator"
7288 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7289 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
7290 "TARGET_32BIT"
7291 "cmp\\t%0, %1%S3"
7292 [(set_attr "conds" "set")
7293 (set_attr "shift" "1")
7294 (set_attr "arch" "32,a,a")
7295 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7296
7297 (define_insn "*cmpsi_shiftsi_swp"
7298 [(set (reg:CC_SWP CC_REGNUM)
7299 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
7300 [(match_operand:SI 1 "s_register_operand" "r,r,r")
7301 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
7302 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
7303 "TARGET_32BIT"
7304 "cmp%?\\t%0, %1%S3"
7305 [(set_attr "conds" "set")
7306 (set_attr "shift" "1")
7307 (set_attr "arch" "32,a,a")
7308 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
7309
7310 (define_insn "*arm_cmpsi_negshiftsi_si"
7311 [(set (reg:CC_Z CC_REGNUM)
7312 (compare:CC_Z
7313 (neg:SI (match_operator:SI 1 "shift_operator"
7314 [(match_operand:SI 2 "s_register_operand" "r")
7315 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
7316 (match_operand:SI 0 "s_register_operand" "r")))]
7317 "TARGET_ARM"
7318 "cmn%?\\t%0, %2%S1"
7319 [(set_attr "conds" "set")
7320 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
7321 (const_string "alus_shift_imm")
7322 (const_string "alus_shift_reg")))
7323 (set_attr "predicable" "yes")]
7324 )
7325
7326 ;; DImode comparisons. The generic code generates branches that
7327 ;; if-conversion can not reduce to a conditional compare, so we do
7328 ;; that directly.
7329
7330 (define_insn_and_split "*arm_cmpdi_insn"
7331 [(set (reg:CC_NCV CC_REGNUM)
7332 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
7333 (match_operand:DI 1 "arm_di_operand" "rDi")))
7334 (clobber (match_scratch:SI 2 "=r"))]
7335 "TARGET_32BIT"
7336 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
7337 "&& reload_completed"
7338 [(set (reg:CC CC_REGNUM)
7339 (compare:CC (match_dup 0) (match_dup 1)))
7340 (parallel [(set (reg:CC CC_REGNUM)
7341 (compare:CC (match_dup 3) (match_dup 4)))
7342 (set (match_dup 2)
7343 (minus:SI (match_dup 5)
7344 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
7345 {
7346 operands[3] = gen_highpart (SImode, operands[0]);
7347 operands[0] = gen_lowpart (SImode, operands[0]);
7348 if (CONST_INT_P (operands[1]))
7349 {
7350 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode,
7351 DImode,
7352 operands[1])));
7353 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]);
7354 }
7355 else
7356 {
7357 operands[4] = gen_highpart (SImode, operands[1]);
7358 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
7359 }
7360 operands[1] = gen_lowpart (SImode, operands[1]);
7361 operands[2] = gen_lowpart (SImode, operands[2]);
7362 }
7363 [(set_attr "conds" "set")
7364 (set_attr "length" "8")
7365 (set_attr "type" "multiple")]
7366 )
7367
7368 (define_insn_and_split "*arm_cmpdi_unsigned"
7369 [(set (reg:CC_CZ CC_REGNUM)
7370 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
7371 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
7372
7373 "TARGET_32BIT"
7374 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
7375 "&& reload_completed"
7376 [(set (reg:CC CC_REGNUM)
7377 (compare:CC (match_dup 2) (match_dup 3)))
7378 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
7379 (set (reg:CC CC_REGNUM)
7380 (compare:CC (match_dup 0) (match_dup 1))))]
7381 {
7382 operands[2] = gen_highpart (SImode, operands[0]);
7383 operands[0] = gen_lowpart (SImode, operands[0]);
7384 if (CONST_INT_P (operands[1]))
7385 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
7386 else
7387 operands[3] = gen_highpart (SImode, operands[1]);
7388 operands[1] = gen_lowpart (SImode, operands[1]);
7389 }
7390 [(set_attr "conds" "set")
7391 (set_attr "enabled_for_depr_it" "yes,yes,no,*")
7392 (set_attr "arch" "t2,t2,t2,a")
7393 (set_attr "length" "6,6,10,8")
7394 (set_attr "type" "multiple")]
7395 )
7396
7397 (define_insn "*arm_cmpdi_zero"
7398 [(set (reg:CC_Z CC_REGNUM)
7399 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
7400 (const_int 0)))
7401 (clobber (match_scratch:SI 1 "=r"))]
7402 "TARGET_32BIT"
7403 "orrs%?\\t%1, %Q0, %R0"
7404 [(set_attr "conds" "set")
7405 (set_attr "type" "logics_reg")]
7406 )
7407
7408 ; This insn allows redundant compares to be removed by cse, nothing should
7409 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
7410 ; is deleted later on. The match_dup will match the mode here, so that
7411 ; mode changes of the condition codes aren't lost by this even though we don't
7412 ; specify what they are.
7413
7414 (define_insn "*deleted_compare"
7415 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
7416 "TARGET_32BIT"
7417 "\\t%@ deleted compare"
7418 [(set_attr "conds" "set")
7419 (set_attr "length" "0")
7420 (set_attr "type" "no_insn")]
7421 )
7422
7423 \f
7424 ;; Conditional branch insns
7425
7426 (define_expand "cbranch_cc"
7427 [(set (pc)
7428 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
7429 (match_operand 2 "" "")])
7430 (label_ref (match_operand 3 "" ""))
7431 (pc)))]
7432 "TARGET_32BIT"
7433 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
7434 operands[1], operands[2], NULL_RTX);
7435 operands[2] = const0_rtx;"
7436 )
7437
7438 ;;
7439 ;; Patterns to match conditional branch insns.
7440 ;;
7441
7442 (define_insn "arm_cond_branch"
7443 [(set (pc)
7444 (if_then_else (match_operator 1 "arm_comparison_operator"
7445 [(match_operand 2 "cc_register" "") (const_int 0)])
7446 (label_ref (match_operand 0 "" ""))
7447 (pc)))]
7448 "TARGET_32BIT"
7449 "*
7450 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7451 {
7452 arm_ccfsm_state += 2;
7453 return \"\";
7454 }
7455 return \"b%d1\\t%l0\";
7456 "
7457 [(set_attr "conds" "use")
7458 (set_attr "type" "branch")
7459 (set (attr "length")
7460 (if_then_else
7461 (and (match_test "TARGET_THUMB2")
7462 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7463 (le (minus (match_dup 0) (pc)) (const_int 256))))
7464 (const_int 2)
7465 (const_int 4)))]
7466 )
7467
7468 (define_insn "*arm_cond_branch_reversed"
7469 [(set (pc)
7470 (if_then_else (match_operator 1 "arm_comparison_operator"
7471 [(match_operand 2 "cc_register" "") (const_int 0)])
7472 (pc)
7473 (label_ref (match_operand 0 "" ""))))]
7474 "TARGET_32BIT"
7475 "*
7476 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7477 {
7478 arm_ccfsm_state += 2;
7479 return \"\";
7480 }
7481 return \"b%D1\\t%l0\";
7482 "
7483 [(set_attr "conds" "use")
7484 (set_attr "type" "branch")
7485 (set (attr "length")
7486 (if_then_else
7487 (and (match_test "TARGET_THUMB2")
7488 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
7489 (le (minus (match_dup 0) (pc)) (const_int 256))))
7490 (const_int 2)
7491 (const_int 4)))]
7492 )
7493
7494 \f
7495
7496 ; scc insns
7497
7498 (define_expand "cstore_cc"
7499 [(set (match_operand:SI 0 "s_register_operand" "")
7500 (match_operator:SI 1 "" [(match_operand 2 "" "")
7501 (match_operand 3 "" "")]))]
7502 "TARGET_32BIT"
7503 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
7504 operands[2], operands[3], NULL_RTX);
7505 operands[3] = const0_rtx;"
7506 )
7507
7508 (define_insn_and_split "*mov_scc"
7509 [(set (match_operand:SI 0 "s_register_operand" "=r")
7510 (match_operator:SI 1 "arm_comparison_operator_mode"
7511 [(match_operand 2 "cc_register" "") (const_int 0)]))]
7512 "TARGET_ARM"
7513 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
7514 "TARGET_ARM"
7515 [(set (match_dup 0)
7516 (if_then_else:SI (match_dup 1)
7517 (const_int 1)
7518 (const_int 0)))]
7519 ""
7520 [(set_attr "conds" "use")
7521 (set_attr "length" "8")
7522 (set_attr "type" "multiple")]
7523 )
7524
7525 (define_insn_and_split "*mov_negscc"
7526 [(set (match_operand:SI 0 "s_register_operand" "=r")
7527 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7528 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7529 "TARGET_ARM"
7530 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7531 "TARGET_ARM"
7532 [(set (match_dup 0)
7533 (if_then_else:SI (match_dup 1)
7534 (match_dup 3)
7535 (const_int 0)))]
7536 {
7537 operands[3] = GEN_INT (~0);
7538 }
7539 [(set_attr "conds" "use")
7540 (set_attr "length" "8")
7541 (set_attr "type" "multiple")]
7542 )
7543
7544 (define_insn_and_split "*mov_notscc"
7545 [(set (match_operand:SI 0 "s_register_operand" "=r")
7546 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7547 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7548 "TARGET_ARM"
7549 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7550 "TARGET_ARM"
7551 [(set (match_dup 0)
7552 (if_then_else:SI (match_dup 1)
7553 (match_dup 3)
7554 (match_dup 4)))]
7555 {
7556 operands[3] = GEN_INT (~1);
7557 operands[4] = GEN_INT (~0);
7558 }
7559 [(set_attr "conds" "use")
7560 (set_attr "length" "8")
7561 (set_attr "type" "multiple")]
7562 )
7563
7564 (define_expand "cstoresi4"
7565 [(set (match_operand:SI 0 "s_register_operand" "")
7566 (match_operator:SI 1 "expandable_comparison_operator"
7567 [(match_operand:SI 2 "s_register_operand" "")
7568 (match_operand:SI 3 "reg_or_int_operand" "")]))]
7569 "TARGET_32BIT || TARGET_THUMB1"
7570 "{
7571 rtx op3, scratch, scratch2;
7572
7573 if (!TARGET_THUMB1)
7574 {
7575 if (!arm_add_operand (operands[3], SImode))
7576 operands[3] = force_reg (SImode, operands[3]);
7577 emit_insn (gen_cstore_cc (operands[0], operands[1],
7578 operands[2], operands[3]));
7579 DONE;
7580 }
7581
7582 if (operands[3] == const0_rtx)
7583 {
7584 switch (GET_CODE (operands[1]))
7585 {
7586 case EQ:
7587 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7588 break;
7589
7590 case NE:
7591 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7592 break;
7593
7594 case LE:
7595 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7596 NULL_RTX, 0, OPTAB_WIDEN);
7597 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7598 NULL_RTX, 0, OPTAB_WIDEN);
7599 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7600 operands[0], 1, OPTAB_WIDEN);
7601 break;
7602
7603 case GE:
7604 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7605 NULL_RTX, 1);
7606 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7607 NULL_RTX, 1, OPTAB_WIDEN);
7608 break;
7609
7610 case GT:
7611 scratch = expand_binop (SImode, ashr_optab, operands[2],
7612 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7613 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7614 NULL_RTX, 0, OPTAB_WIDEN);
7615 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7616 0, OPTAB_WIDEN);
7617 break;
7618
7619 /* LT is handled by generic code. No need for unsigned with 0. */
7620 default:
7621 FAIL;
7622 }
7623 DONE;
7624 }
7625
7626 switch (GET_CODE (operands[1]))
7627 {
7628 case EQ:
7629 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7630 NULL_RTX, 0, OPTAB_WIDEN);
7631 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7632 break;
7633
7634 case NE:
7635 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7636 NULL_RTX, 0, OPTAB_WIDEN);
7637 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7638 break;
7639
7640 case LE:
7641 op3 = force_reg (SImode, operands[3]);
7642
7643 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7644 NULL_RTX, 1, OPTAB_WIDEN);
7645 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7646 NULL_RTX, 0, OPTAB_WIDEN);
7647 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7648 op3, operands[2]));
7649 break;
7650
7651 case GE:
7652 op3 = operands[3];
7653 if (!thumb1_cmp_operand (op3, SImode))
7654 op3 = force_reg (SImode, op3);
7655 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7656 NULL_RTX, 0, OPTAB_WIDEN);
7657 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7658 NULL_RTX, 1, OPTAB_WIDEN);
7659 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7660 operands[2], op3));
7661 break;
7662
7663 case LEU:
7664 op3 = force_reg (SImode, operands[3]);
7665 scratch = force_reg (SImode, const0_rtx);
7666 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7667 op3, operands[2]));
7668 break;
7669
7670 case GEU:
7671 op3 = operands[3];
7672 if (!thumb1_cmp_operand (op3, SImode))
7673 op3 = force_reg (SImode, op3);
7674 scratch = force_reg (SImode, const0_rtx);
7675 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7676 operands[2], op3));
7677 break;
7678
7679 case LTU:
7680 op3 = operands[3];
7681 if (!thumb1_cmp_operand (op3, SImode))
7682 op3 = force_reg (SImode, op3);
7683 scratch = gen_reg_rtx (SImode);
7684 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7685 break;
7686
7687 case GTU:
7688 op3 = force_reg (SImode, operands[3]);
7689 scratch = gen_reg_rtx (SImode);
7690 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7691 break;
7692
7693 /* No good sequences for GT, LT. */
7694 default:
7695 FAIL;
7696 }
7697 DONE;
7698 }")
7699
7700 (define_expand "cstorehf4"
7701 [(set (match_operand:SI 0 "s_register_operand")
7702 (match_operator:SI 1 "expandable_comparison_operator"
7703 [(match_operand:HF 2 "s_register_operand")
7704 (match_operand:HF 3 "vfp_compare_operand")]))]
7705 "TARGET_VFP_FP16INST"
7706 {
7707 if (!arm_validize_comparison (&operands[1],
7708 &operands[2],
7709 &operands[3]))
7710 FAIL;
7711
7712 emit_insn (gen_cstore_cc (operands[0], operands[1],
7713 operands[2], operands[3]));
7714 DONE;
7715 }
7716 )
7717
7718 (define_expand "cstoresf4"
7719 [(set (match_operand:SI 0 "s_register_operand" "")
7720 (match_operator:SI 1 "expandable_comparison_operator"
7721 [(match_operand:SF 2 "s_register_operand" "")
7722 (match_operand:SF 3 "vfp_compare_operand" "")]))]
7723 "TARGET_32BIT && TARGET_HARD_FLOAT"
7724 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7725 operands[2], operands[3])); DONE;"
7726 )
7727
7728 (define_expand "cstoredf4"
7729 [(set (match_operand:SI 0 "s_register_operand" "")
7730 (match_operator:SI 1 "expandable_comparison_operator"
7731 [(match_operand:DF 2 "s_register_operand" "")
7732 (match_operand:DF 3 "vfp_compare_operand" "")]))]
7733 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7734 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7735 operands[2], operands[3])); DONE;"
7736 )
7737
7738 (define_expand "cstoredi4"
7739 [(set (match_operand:SI 0 "s_register_operand" "")
7740 (match_operator:SI 1 "expandable_comparison_operator"
7741 [(match_operand:DI 2 "s_register_operand" "")
7742 (match_operand:DI 3 "cmpdi_operand" "")]))]
7743 "TARGET_32BIT"
7744 "{
7745 if (!arm_validize_comparison (&operands[1],
7746 &operands[2],
7747 &operands[3]))
7748 FAIL;
7749 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7750 operands[3]));
7751 DONE;
7752 }"
7753 )
7754
7755 \f
7756 ;; Conditional move insns
7757
7758 (define_expand "movsicc"
7759 [(set (match_operand:SI 0 "s_register_operand" "")
7760 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "")
7761 (match_operand:SI 2 "arm_not_operand" "")
7762 (match_operand:SI 3 "arm_not_operand" "")))]
7763 "TARGET_32BIT"
7764 "
7765 {
7766 enum rtx_code code;
7767 rtx ccreg;
7768
7769 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7770 &XEXP (operands[1], 1)))
7771 FAIL;
7772
7773 code = GET_CODE (operands[1]);
7774 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7775 XEXP (operands[1], 1), NULL_RTX);
7776 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7777 }"
7778 )
7779
7780 (define_expand "movhfcc"
7781 [(set (match_operand:HF 0 "s_register_operand")
7782 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7783 (match_operand:HF 2 "s_register_operand")
7784 (match_operand:HF 3 "s_register_operand")))]
7785 "TARGET_VFP_FP16INST"
7786 "
7787 {
7788 enum rtx_code code = GET_CODE (operands[1]);
7789 rtx ccreg;
7790
7791 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7792 &XEXP (operands[1], 1)))
7793 FAIL;
7794
7795 code = GET_CODE (operands[1]);
7796 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7797 XEXP (operands[1], 1), NULL_RTX);
7798 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7799 }"
7800 )
7801
7802 (define_expand "movsfcc"
7803 [(set (match_operand:SF 0 "s_register_operand" "")
7804 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "")
7805 (match_operand:SF 2 "s_register_operand" "")
7806 (match_operand:SF 3 "s_register_operand" "")))]
7807 "TARGET_32BIT && TARGET_HARD_FLOAT"
7808 "
7809 {
7810 enum rtx_code code = GET_CODE (operands[1]);
7811 rtx ccreg;
7812
7813 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7814 &XEXP (operands[1], 1)))
7815 FAIL;
7816
7817 code = GET_CODE (operands[1]);
7818 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7819 XEXP (operands[1], 1), NULL_RTX);
7820 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7821 }"
7822 )
7823
7824 (define_expand "movdfcc"
7825 [(set (match_operand:DF 0 "s_register_operand" "")
7826 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "")
7827 (match_operand:DF 2 "s_register_operand" "")
7828 (match_operand:DF 3 "s_register_operand" "")))]
7829 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7830 "
7831 {
7832 enum rtx_code code = GET_CODE (operands[1]);
7833 rtx ccreg;
7834
7835 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7836 &XEXP (operands[1], 1)))
7837 FAIL;
7838 code = GET_CODE (operands[1]);
7839 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7840 XEXP (operands[1], 1), NULL_RTX);
7841 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7842 }"
7843 )
7844
7845 (define_insn "*cmov<mode>"
7846 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7847 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7848 [(match_operand 2 "cc_register" "") (const_int 0)])
7849 (match_operand:SDF 3 "s_register_operand"
7850 "<F_constraint>")
7851 (match_operand:SDF 4 "s_register_operand"
7852 "<F_constraint>")))]
7853 "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
7854 "*
7855 {
7856 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7857 switch (code)
7858 {
7859 case ARM_GE:
7860 case ARM_GT:
7861 case ARM_EQ:
7862 case ARM_VS:
7863 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7864 case ARM_LT:
7865 case ARM_LE:
7866 case ARM_NE:
7867 case ARM_VC:
7868 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7869 default:
7870 gcc_unreachable ();
7871 }
7872 return \"\";
7873 }"
7874 [(set_attr "conds" "use")
7875 (set_attr "type" "fcsel")]
7876 )
7877
7878 (define_insn "*cmovhf"
7879 [(set (match_operand:HF 0 "s_register_operand" "=t")
7880 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7881 [(match_operand 2 "cc_register" "") (const_int 0)])
7882 (match_operand:HF 3 "s_register_operand" "t")
7883 (match_operand:HF 4 "s_register_operand" "t")))]
7884 "TARGET_VFP_FP16INST"
7885 "*
7886 {
7887 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7888 switch (code)
7889 {
7890 case ARM_GE:
7891 case ARM_GT:
7892 case ARM_EQ:
7893 case ARM_VS:
7894 return \"vsel%d1.f16\\t%0, %3, %4\";
7895 case ARM_LT:
7896 case ARM_LE:
7897 case ARM_NE:
7898 case ARM_VC:
7899 return \"vsel%D1.f16\\t%0, %4, %3\";
7900 default:
7901 gcc_unreachable ();
7902 }
7903 return \"\";
7904 }"
7905 [(set_attr "conds" "use")
7906 (set_attr "type" "fcsel")]
7907 )
7908
7909 (define_insn_and_split "*movsicc_insn"
7910 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7911 (if_then_else:SI
7912 (match_operator 3 "arm_comparison_operator"
7913 [(match_operand 4 "cc_register" "") (const_int 0)])
7914 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7915 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7916 "TARGET_ARM"
7917 "@
7918 mov%D3\\t%0, %2
7919 mvn%D3\\t%0, #%B2
7920 mov%d3\\t%0, %1
7921 mvn%d3\\t%0, #%B1
7922 #
7923 #
7924 #
7925 #"
7926 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7927 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7928 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7929 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7930 "&& reload_completed"
7931 [(const_int 0)]
7932 {
7933 enum rtx_code rev_code;
7934 machine_mode mode;
7935 rtx rev_cond;
7936
7937 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7938 operands[3],
7939 gen_rtx_SET (operands[0], operands[1])));
7940
7941 rev_code = GET_CODE (operands[3]);
7942 mode = GET_MODE (operands[4]);
7943 if (mode == CCFPmode || mode == CCFPEmode)
7944 rev_code = reverse_condition_maybe_unordered (rev_code);
7945 else
7946 rev_code = reverse_condition (rev_code);
7947
7948 rev_cond = gen_rtx_fmt_ee (rev_code,
7949 VOIDmode,
7950 operands[4],
7951 const0_rtx);
7952 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7953 rev_cond,
7954 gen_rtx_SET (operands[0], operands[2])));
7955 DONE;
7956 }
7957 [(set_attr "length" "4,4,4,4,8,8,8,8")
7958 (set_attr "conds" "use")
7959 (set_attr_alternative "type"
7960 [(if_then_else (match_operand 2 "const_int_operand" "")
7961 (const_string "mov_imm")
7962 (const_string "mov_reg"))
7963 (const_string "mvn_imm")
7964 (if_then_else (match_operand 1 "const_int_operand" "")
7965 (const_string "mov_imm")
7966 (const_string "mov_reg"))
7967 (const_string "mvn_imm")
7968 (const_string "multiple")
7969 (const_string "multiple")
7970 (const_string "multiple")
7971 (const_string "multiple")])]
7972 )
7973
7974 (define_insn "*movsfcc_soft_insn"
7975 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7976 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7977 [(match_operand 4 "cc_register" "") (const_int 0)])
7978 (match_operand:SF 1 "s_register_operand" "0,r")
7979 (match_operand:SF 2 "s_register_operand" "r,0")))]
7980 "TARGET_ARM && TARGET_SOFT_FLOAT"
7981 "@
7982 mov%D3\\t%0, %2
7983 mov%d3\\t%0, %1"
7984 [(set_attr "conds" "use")
7985 (set_attr "type" "mov_reg")]
7986 )
7987
7988 \f
7989 ;; Jump and linkage insns
7990
7991 (define_expand "jump"
7992 [(set (pc)
7993 (label_ref (match_operand 0 "" "")))]
7994 "TARGET_EITHER"
7995 ""
7996 )
7997
7998 (define_insn "*arm_jump"
7999 [(set (pc)
8000 (label_ref (match_operand 0 "" "")))]
8001 "TARGET_32BIT"
8002 "*
8003 {
8004 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
8005 {
8006 arm_ccfsm_state += 2;
8007 return \"\";
8008 }
8009 return \"b%?\\t%l0\";
8010 }
8011 "
8012 [(set_attr "predicable" "yes")
8013 (set (attr "length")
8014 (if_then_else
8015 (and (match_test "TARGET_THUMB2")
8016 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
8017 (le (minus (match_dup 0) (pc)) (const_int 2048))))
8018 (const_int 2)
8019 (const_int 4)))
8020 (set_attr "type" "branch")]
8021 )
8022
8023 (define_expand "call"
8024 [(parallel [(call (match_operand 0 "memory_operand" "")
8025 (match_operand 1 "general_operand" ""))
8026 (use (match_operand 2 "" ""))
8027 (clobber (reg:SI LR_REGNUM))])]
8028 "TARGET_EITHER"
8029 "
8030 {
8031 rtx callee, pat;
8032
8033 /* In an untyped call, we can get NULL for operand 2. */
8034 if (operands[2] == NULL_RTX)
8035 operands[2] = const0_rtx;
8036
8037 /* Decide if we should generate indirect calls by loading the
8038 32-bit address of the callee into a register before performing the
8039 branch and link. */
8040 callee = XEXP (operands[0], 0);
8041 if (GET_CODE (callee) == SYMBOL_REF
8042 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8043 : !REG_P (callee))
8044 XEXP (operands[0], 0) = force_reg (Pmode, callee);
8045
8046 pat = gen_call_internal (operands[0], operands[1], operands[2]);
8047 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
8048 DONE;
8049 }"
8050 )
8051
8052 (define_expand "call_internal"
8053 [(parallel [(call (match_operand 0 "memory_operand" "")
8054 (match_operand 1 "general_operand" ""))
8055 (use (match_operand 2 "" ""))
8056 (clobber (reg:SI LR_REGNUM))])])
8057
8058 (define_insn "*call_reg_armv5"
8059 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8060 (match_operand 1 "" ""))
8061 (use (match_operand 2 "" ""))
8062 (clobber (reg:SI LR_REGNUM))]
8063 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8064 "blx%?\\t%0"
8065 [(set_attr "type" "call")]
8066 )
8067
8068 (define_insn "*call_reg_arm"
8069 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
8070 (match_operand 1 "" ""))
8071 (use (match_operand 2 "" ""))
8072 (clobber (reg:SI LR_REGNUM))]
8073 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8074 "*
8075 return output_call (operands);
8076 "
8077 ;; length is worst case, normally it is only two
8078 [(set_attr "length" "12")
8079 (set_attr "type" "call")]
8080 )
8081
8082
8083 (define_expand "call_value"
8084 [(parallel [(set (match_operand 0 "" "")
8085 (call (match_operand 1 "memory_operand" "")
8086 (match_operand 2 "general_operand" "")))
8087 (use (match_operand 3 "" ""))
8088 (clobber (reg:SI LR_REGNUM))])]
8089 "TARGET_EITHER"
8090 "
8091 {
8092 rtx pat, callee;
8093
8094 /* In an untyped call, we can get NULL for operand 2. */
8095 if (operands[3] == 0)
8096 operands[3] = const0_rtx;
8097
8098 /* Decide if we should generate indirect calls by loading the
8099 32-bit address of the callee into a register before performing the
8100 branch and link. */
8101 callee = XEXP (operands[1], 0);
8102 if (GET_CODE (callee) == SYMBOL_REF
8103 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
8104 : !REG_P (callee))
8105 XEXP (operands[1], 0) = force_reg (Pmode, callee);
8106
8107 pat = gen_call_value_internal (operands[0], operands[1],
8108 operands[2], operands[3]);
8109 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
8110 DONE;
8111 }"
8112 )
8113
8114 (define_expand "call_value_internal"
8115 [(parallel [(set (match_operand 0 "" "")
8116 (call (match_operand 1 "memory_operand" "")
8117 (match_operand 2 "general_operand" "")))
8118 (use (match_operand 3 "" ""))
8119 (clobber (reg:SI LR_REGNUM))])])
8120
8121 (define_insn "*call_value_reg_armv5"
8122 [(set (match_operand 0 "" "")
8123 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8124 (match_operand 2 "" "")))
8125 (use (match_operand 3 "" ""))
8126 (clobber (reg:SI LR_REGNUM))]
8127 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)"
8128 "blx%?\\t%1"
8129 [(set_attr "type" "call")]
8130 )
8131
8132 (define_insn "*call_value_reg_arm"
8133 [(set (match_operand 0 "" "")
8134 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
8135 (match_operand 2 "" "")))
8136 (use (match_operand 3 "" ""))
8137 (clobber (reg:SI LR_REGNUM))]
8138 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)"
8139 "*
8140 return output_call (&operands[1]);
8141 "
8142 [(set_attr "length" "12")
8143 (set_attr "type" "call")]
8144 )
8145
8146 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
8147 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
8148
8149 (define_insn "*call_symbol"
8150 [(call (mem:SI (match_operand:SI 0 "" ""))
8151 (match_operand 1 "" ""))
8152 (use (match_operand 2 "" ""))
8153 (clobber (reg:SI LR_REGNUM))]
8154 "TARGET_32BIT
8155 && !SIBLING_CALL_P (insn)
8156 && (GET_CODE (operands[0]) == SYMBOL_REF)
8157 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
8158 "*
8159 {
8160 rtx op = operands[0];
8161
8162 /* Switch mode now when possible. */
8163 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8164 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8165 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
8166
8167 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
8168 }"
8169 [(set_attr "type" "call")]
8170 )
8171
8172 (define_insn "*call_value_symbol"
8173 [(set (match_operand 0 "" "")
8174 (call (mem:SI (match_operand:SI 1 "" ""))
8175 (match_operand:SI 2 "" "")))
8176 (use (match_operand 3 "" ""))
8177 (clobber (reg:SI LR_REGNUM))]
8178 "TARGET_32BIT
8179 && !SIBLING_CALL_P (insn)
8180 && (GET_CODE (operands[1]) == SYMBOL_REF)
8181 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
8182 "*
8183 {
8184 rtx op = operands[1];
8185
8186 /* Switch mode now when possible. */
8187 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
8188 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
8189 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
8190
8191 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
8192 }"
8193 [(set_attr "type" "call")]
8194 )
8195
8196 (define_expand "sibcall_internal"
8197 [(parallel [(call (match_operand 0 "memory_operand" "")
8198 (match_operand 1 "general_operand" ""))
8199 (return)
8200 (use (match_operand 2 "" ""))])])
8201
8202 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
8203 (define_expand "sibcall"
8204 [(parallel [(call (match_operand 0 "memory_operand" "")
8205 (match_operand 1 "general_operand" ""))
8206 (return)
8207 (use (match_operand 2 "" ""))])]
8208 "TARGET_32BIT"
8209 "
8210 {
8211 rtx pat;
8212
8213 if ((!REG_P (XEXP (operands[0], 0))
8214 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
8215 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8216 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
8217 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8218
8219 if (operands[2] == NULL_RTX)
8220 operands[2] = const0_rtx;
8221
8222 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
8223 arm_emit_call_insn (pat, operands[0], true);
8224 DONE;
8225 }"
8226 )
8227
8228 (define_expand "sibcall_value_internal"
8229 [(parallel [(set (match_operand 0 "" "")
8230 (call (match_operand 1 "memory_operand" "")
8231 (match_operand 2 "general_operand" "")))
8232 (return)
8233 (use (match_operand 3 "" ""))])])
8234
8235 (define_expand "sibcall_value"
8236 [(parallel [(set (match_operand 0 "" "")
8237 (call (match_operand 1 "memory_operand" "")
8238 (match_operand 2 "general_operand" "")))
8239 (return)
8240 (use (match_operand 3 "" ""))])]
8241 "TARGET_32BIT"
8242 "
8243 {
8244 rtx pat;
8245
8246 if ((!REG_P (XEXP (operands[1], 0))
8247 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
8248 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8249 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
8250 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8251
8252 if (operands[3] == NULL_RTX)
8253 operands[3] = const0_rtx;
8254
8255 pat = gen_sibcall_value_internal (operands[0], operands[1],
8256 operands[2], operands[3]);
8257 arm_emit_call_insn (pat, operands[1], true);
8258 DONE;
8259 }"
8260 )
8261
8262 (define_insn "*sibcall_insn"
8263 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
8264 (match_operand 1 "" ""))
8265 (return)
8266 (use (match_operand 2 "" ""))]
8267 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8268 "*
8269 if (which_alternative == 1)
8270 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
8271 else
8272 {
8273 if (arm_arch5 || arm_arch4t)
8274 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
8275 else
8276 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
8277 }
8278 "
8279 [(set_attr "type" "call")]
8280 )
8281
8282 (define_insn "*sibcall_value_insn"
8283 [(set (match_operand 0 "" "")
8284 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
8285 (match_operand 2 "" "")))
8286 (return)
8287 (use (match_operand 3 "" ""))]
8288 "TARGET_32BIT && SIBLING_CALL_P (insn)"
8289 "*
8290 if (which_alternative == 1)
8291 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
8292 else
8293 {
8294 if (arm_arch5 || arm_arch4t)
8295 return \"bx%?\\t%1\";
8296 else
8297 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
8298 }
8299 "
8300 [(set_attr "type" "call")]
8301 )
8302
8303 (define_expand "<return_str>return"
8304 [(RETURNS)]
8305 "(TARGET_ARM || (TARGET_THUMB2
8306 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
8307 && !IS_STACKALIGN (arm_current_func_type ())))
8308 <return_cond_false>"
8309 "
8310 {
8311 if (TARGET_THUMB2)
8312 {
8313 thumb2_expand_return (<return_simple_p>);
8314 DONE;
8315 }
8316 }
8317 "
8318 )
8319
8320 ;; Often the return insn will be the same as loading from memory, so set attr
8321 (define_insn "*arm_return"
8322 [(return)]
8323 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
8324 "*
8325 {
8326 if (arm_ccfsm_state == 2)
8327 {
8328 arm_ccfsm_state += 2;
8329 return \"\";
8330 }
8331 return output_return_instruction (const_true_rtx, true, false, false);
8332 }"
8333 [(set_attr "type" "load1")
8334 (set_attr "length" "12")
8335 (set_attr "predicable" "yes")]
8336 )
8337
8338 (define_insn "*cond_<return_str>return"
8339 [(set (pc)
8340 (if_then_else (match_operator 0 "arm_comparison_operator"
8341 [(match_operand 1 "cc_register" "") (const_int 0)])
8342 (RETURNS)
8343 (pc)))]
8344 "TARGET_ARM <return_cond_true>"
8345 "*
8346 {
8347 if (arm_ccfsm_state == 2)
8348 {
8349 arm_ccfsm_state += 2;
8350 return \"\";
8351 }
8352 return output_return_instruction (operands[0], true, false,
8353 <return_simple_p>);
8354 }"
8355 [(set_attr "conds" "use")
8356 (set_attr "length" "12")
8357 (set_attr "type" "load1")]
8358 )
8359
8360 (define_insn "*cond_<return_str>return_inverted"
8361 [(set (pc)
8362 (if_then_else (match_operator 0 "arm_comparison_operator"
8363 [(match_operand 1 "cc_register" "") (const_int 0)])
8364 (pc)
8365 (RETURNS)))]
8366 "TARGET_ARM <return_cond_true>"
8367 "*
8368 {
8369 if (arm_ccfsm_state == 2)
8370 {
8371 arm_ccfsm_state += 2;
8372 return \"\";
8373 }
8374 return output_return_instruction (operands[0], true, true,
8375 <return_simple_p>);
8376 }"
8377 [(set_attr "conds" "use")
8378 (set_attr "length" "12")
8379 (set_attr "type" "load1")]
8380 )
8381
8382 (define_insn "*arm_simple_return"
8383 [(simple_return)]
8384 "TARGET_ARM"
8385 "*
8386 {
8387 if (arm_ccfsm_state == 2)
8388 {
8389 arm_ccfsm_state += 2;
8390 return \"\";
8391 }
8392 return output_return_instruction (const_true_rtx, true, false, true);
8393 }"
8394 [(set_attr "type" "branch")
8395 (set_attr "length" "4")
8396 (set_attr "predicable" "yes")]
8397 )
8398
8399 ;; Generate a sequence of instructions to determine if the processor is
8400 ;; in 26-bit or 32-bit mode, and return the appropriate return address
8401 ;; mask.
8402
8403 (define_expand "return_addr_mask"
8404 [(set (match_dup 1)
8405 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8406 (const_int 0)))
8407 (set (match_operand:SI 0 "s_register_operand" "")
8408 (if_then_else:SI (eq (match_dup 1) (const_int 0))
8409 (const_int -1)
8410 (const_int 67108860)))] ; 0x03fffffc
8411 "TARGET_ARM"
8412 "
8413 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
8414 ")
8415
8416 (define_insn "*check_arch2"
8417 [(set (match_operand:CC_NOOV 0 "cc_register" "")
8418 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
8419 (const_int 0)))]
8420 "TARGET_ARM"
8421 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8422 [(set_attr "length" "8")
8423 (set_attr "conds" "set")
8424 (set_attr "type" "multiple")]
8425 )
8426
8427 ;; Call subroutine returning any type.
8428
8429 (define_expand "untyped_call"
8430 [(parallel [(call (match_operand 0 "" "")
8431 (const_int 0))
8432 (match_operand 1 "" "")
8433 (match_operand 2 "" "")])]
8434 "TARGET_EITHER"
8435 "
8436 {
8437 int i;
8438 rtx par = gen_rtx_PARALLEL (VOIDmode,
8439 rtvec_alloc (XVECLEN (operands[2], 0)));
8440 rtx addr = gen_reg_rtx (Pmode);
8441 rtx mem;
8442 int size = 0;
8443
8444 emit_move_insn (addr, XEXP (operands[1], 0));
8445 mem = change_address (operands[1], BLKmode, addr);
8446
8447 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8448 {
8449 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8450
8451 /* Default code only uses r0 as a return value, but we could
8452 be using anything up to 4 registers. */
8453 if (REGNO (src) == R0_REGNUM)
8454 src = gen_rtx_REG (TImode, R0_REGNUM);
8455
8456 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8457 GEN_INT (size));
8458 size += GET_MODE_SIZE (GET_MODE (src));
8459 }
8460
8461 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8462
8463 size = 0;
8464
8465 for (i = 0; i < XVECLEN (par, 0); i++)
8466 {
8467 HOST_WIDE_INT offset = 0;
8468 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8469
8470 if (size != 0)
8471 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8472
8473 mem = change_address (mem, GET_MODE (reg), NULL);
8474 if (REGNO (reg) == R0_REGNUM)
8475 {
8476 /* On thumb we have to use a write-back instruction. */
8477 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8478 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8479 size = TARGET_ARM ? 16 : 0;
8480 }
8481 else
8482 {
8483 emit_move_insn (mem, reg);
8484 size = GET_MODE_SIZE (GET_MODE (reg));
8485 }
8486 }
8487
8488 /* The optimizer does not know that the call sets the function value
8489 registers we stored in the result block. We avoid problems by
8490 claiming that all hard registers are used and clobbered at this
8491 point. */
8492 emit_insn (gen_blockage ());
8493
8494 DONE;
8495 }"
8496 )
8497
8498 (define_expand "untyped_return"
8499 [(match_operand:BLK 0 "memory_operand" "")
8500 (match_operand 1 "" "")]
8501 "TARGET_EITHER"
8502 "
8503 {
8504 int i;
8505 rtx addr = gen_reg_rtx (Pmode);
8506 rtx mem;
8507 int size = 0;
8508
8509 emit_move_insn (addr, XEXP (operands[0], 0));
8510 mem = change_address (operands[0], BLKmode, addr);
8511
8512 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8513 {
8514 HOST_WIDE_INT offset = 0;
8515 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8516
8517 if (size != 0)
8518 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8519
8520 mem = change_address (mem, GET_MODE (reg), NULL);
8521 if (REGNO (reg) == R0_REGNUM)
8522 {
8523 /* On thumb we have to use a write-back instruction. */
8524 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8525 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8526 size = TARGET_ARM ? 16 : 0;
8527 }
8528 else
8529 {
8530 emit_move_insn (reg, mem);
8531 size = GET_MODE_SIZE (GET_MODE (reg));
8532 }
8533 }
8534
8535 /* Emit USE insns before the return. */
8536 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8537 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8538
8539 /* Construct the return. */
8540 expand_naked_return ();
8541
8542 DONE;
8543 }"
8544 )
8545
8546 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8547 ;; all of memory. This blocks insns from being moved across this point.
8548
8549 (define_insn "blockage"
8550 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8551 "TARGET_EITHER"
8552 ""
8553 [(set_attr "length" "0")
8554 (set_attr "type" "block")]
8555 )
8556
8557 (define_insn "probe_stack"
8558 [(set (match_operand:SI 0 "memory_operand" "=m")
8559 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8560 "TARGET_32BIT"
8561 "str%?\\tr0, %0"
8562 [(set_attr "type" "store1")
8563 (set_attr "predicable" "yes")]
8564 )
8565
8566 (define_insn "probe_stack_range"
8567 [(set (match_operand:SI 0 "register_operand" "=r")
8568 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8569 (match_operand:SI 2 "register_operand" "r")]
8570 VUNSPEC_PROBE_STACK_RANGE))]
8571 "TARGET_32BIT"
8572 {
8573 return output_probe_stack_range (operands[0], operands[2]);
8574 }
8575 [(set_attr "type" "multiple")
8576 (set_attr "conds" "clob")]
8577 )
8578
8579 (define_expand "casesi"
8580 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on
8581 (match_operand:SI 1 "const_int_operand" "") ; lower bound
8582 (match_operand:SI 2 "const_int_operand" "") ; total range
8583 (match_operand:SI 3 "" "") ; table label
8584 (match_operand:SI 4 "" "")] ; Out of range label
8585 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8586 "
8587 {
8588 enum insn_code code;
8589 if (operands[1] != const0_rtx)
8590 {
8591 rtx reg = gen_reg_rtx (SImode);
8592
8593 emit_insn (gen_addsi3 (reg, operands[0],
8594 gen_int_mode (-INTVAL (operands[1]),
8595 SImode)));
8596 operands[0] = reg;
8597 }
8598
8599 if (TARGET_ARM)
8600 code = CODE_FOR_arm_casesi_internal;
8601 else if (TARGET_THUMB1)
8602 code = CODE_FOR_thumb1_casesi_internal_pic;
8603 else if (flag_pic)
8604 code = CODE_FOR_thumb2_casesi_internal_pic;
8605 else
8606 code = CODE_FOR_thumb2_casesi_internal;
8607
8608 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8609 operands[2] = force_reg (SImode, operands[2]);
8610
8611 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8612 operands[3], operands[4]));
8613 DONE;
8614 }"
8615 )
8616
8617 ;; The USE in this pattern is needed to tell flow analysis that this is
8618 ;; a CASESI insn. It has no other purpose.
8619 (define_insn "arm_casesi_internal"
8620 [(parallel [(set (pc)
8621 (if_then_else
8622 (leu (match_operand:SI 0 "s_register_operand" "r")
8623 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8624 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8625 (label_ref (match_operand 2 "" ""))))
8626 (label_ref (match_operand 3 "" ""))))
8627 (clobber (reg:CC CC_REGNUM))
8628 (use (label_ref (match_dup 2)))])]
8629 "TARGET_ARM"
8630 "*
8631 if (flag_pic)
8632 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8633 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8634 "
8635 [(set_attr "conds" "clob")
8636 (set_attr "length" "12")
8637 (set_attr "type" "multiple")]
8638 )
8639
8640 (define_expand "indirect_jump"
8641 [(set (pc)
8642 (match_operand:SI 0 "s_register_operand" ""))]
8643 "TARGET_EITHER"
8644 "
8645 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8646 address and use bx. */
8647 if (TARGET_THUMB2)
8648 {
8649 rtx tmp;
8650 tmp = gen_reg_rtx (SImode);
8651 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8652 operands[0] = tmp;
8653 }
8654 "
8655 )
8656
8657 ;; NB Never uses BX.
8658 (define_insn "*arm_indirect_jump"
8659 [(set (pc)
8660 (match_operand:SI 0 "s_register_operand" "r"))]
8661 "TARGET_ARM"
8662 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8663 [(set_attr "predicable" "yes")
8664 (set_attr "type" "branch")]
8665 )
8666
8667 (define_insn "*load_indirect_jump"
8668 [(set (pc)
8669 (match_operand:SI 0 "memory_operand" "m"))]
8670 "TARGET_ARM"
8671 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8672 [(set_attr "type" "load1")
8673 (set_attr "pool_range" "4096")
8674 (set_attr "neg_pool_range" "4084")
8675 (set_attr "predicable" "yes")]
8676 )
8677
8678 \f
8679 ;; Misc insns
8680
8681 (define_insn "nop"
8682 [(const_int 0)]
8683 "TARGET_EITHER"
8684 "nop"
8685 [(set (attr "length")
8686 (if_then_else (eq_attr "is_thumb" "yes")
8687 (const_int 2)
8688 (const_int 4)))
8689 (set_attr "type" "mov_reg")]
8690 )
8691
8692 (define_insn "trap"
8693 [(trap_if (const_int 1) (const_int 0))]
8694 ""
8695 "*
8696 if (TARGET_ARM)
8697 return \".inst\\t0xe7f000f0\";
8698 else
8699 return \".inst\\t0xdeff\";
8700 "
8701 [(set (attr "length")
8702 (if_then_else (eq_attr "is_thumb" "yes")
8703 (const_int 2)
8704 (const_int 4)))
8705 (set_attr "type" "trap")
8706 (set_attr "conds" "unconditional")]
8707 )
8708
8709 \f
8710 ;; Patterns to allow combination of arithmetic, cond code and shifts
8711
8712 (define_insn "*<arith_shift_insn>_multsi"
8713 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8714 (SHIFTABLE_OPS:SI
8715 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8716 (match_operand:SI 3 "power_of_two_operand" ""))
8717 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8718 "TARGET_32BIT"
8719 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8720 [(set_attr "predicable" "yes")
8721 (set_attr "predicable_short_it" "no")
8722 (set_attr "shift" "2")
8723 (set_attr "arch" "a,t2")
8724 (set_attr "type" "alu_shift_imm")])
8725
8726 (define_insn "*<arith_shift_insn>_shiftsi"
8727 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8728 (SHIFTABLE_OPS:SI
8729 (match_operator:SI 2 "shift_nomul_operator"
8730 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8731 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8732 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8733 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8734 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8735 [(set_attr "predicable" "yes")
8736 (set_attr "predicable_short_it" "no")
8737 (set_attr "shift" "3")
8738 (set_attr "arch" "a,t2,a")
8739 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8740
8741 (define_split
8742 [(set (match_operand:SI 0 "s_register_operand" "")
8743 (match_operator:SI 1 "shiftable_operator"
8744 [(match_operator:SI 2 "shiftable_operator"
8745 [(match_operator:SI 3 "shift_operator"
8746 [(match_operand:SI 4 "s_register_operand" "")
8747 (match_operand:SI 5 "reg_or_int_operand" "")])
8748 (match_operand:SI 6 "s_register_operand" "")])
8749 (match_operand:SI 7 "arm_rhs_operand" "")]))
8750 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8751 "TARGET_32BIT"
8752 [(set (match_dup 8)
8753 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8754 (match_dup 6)]))
8755 (set (match_dup 0)
8756 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8757 "")
8758
8759 (define_insn "*arith_shiftsi_compare0"
8760 [(set (reg:CC_NOOV CC_REGNUM)
8761 (compare:CC_NOOV
8762 (match_operator:SI 1 "shiftable_operator"
8763 [(match_operator:SI 3 "shift_operator"
8764 [(match_operand:SI 4 "s_register_operand" "r,r")
8765 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8766 (match_operand:SI 2 "s_register_operand" "r,r")])
8767 (const_int 0)))
8768 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8769 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8770 (match_dup 2)]))]
8771 "TARGET_32BIT"
8772 "%i1s%?\\t%0, %2, %4%S3"
8773 [(set_attr "conds" "set")
8774 (set_attr "shift" "4")
8775 (set_attr "arch" "32,a")
8776 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8777
8778 (define_insn "*arith_shiftsi_compare0_scratch"
8779 [(set (reg:CC_NOOV CC_REGNUM)
8780 (compare:CC_NOOV
8781 (match_operator:SI 1 "shiftable_operator"
8782 [(match_operator:SI 3 "shift_operator"
8783 [(match_operand:SI 4 "s_register_operand" "r,r")
8784 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8785 (match_operand:SI 2 "s_register_operand" "r,r")])
8786 (const_int 0)))
8787 (clobber (match_scratch:SI 0 "=r,r"))]
8788 "TARGET_32BIT"
8789 "%i1s%?\\t%0, %2, %4%S3"
8790 [(set_attr "conds" "set")
8791 (set_attr "shift" "4")
8792 (set_attr "arch" "32,a")
8793 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8794
8795 (define_insn "*sub_shiftsi"
8796 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8797 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8798 (match_operator:SI 2 "shift_operator"
8799 [(match_operand:SI 3 "s_register_operand" "r,r")
8800 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8801 "TARGET_32BIT"
8802 "sub%?\\t%0, %1, %3%S2"
8803 [(set_attr "predicable" "yes")
8804 (set_attr "shift" "3")
8805 (set_attr "arch" "32,a")
8806 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8807
8808 (define_insn "*sub_shiftsi_compare0"
8809 [(set (reg:CC_NOOV CC_REGNUM)
8810 (compare:CC_NOOV
8811 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8812 (match_operator:SI 2 "shift_operator"
8813 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8814 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8815 (const_int 0)))
8816 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8817 (minus:SI (match_dup 1)
8818 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8819 "TARGET_32BIT"
8820 "subs%?\\t%0, %1, %3%S2"
8821 [(set_attr "conds" "set")
8822 (set_attr "shift" "3")
8823 (set_attr "arch" "32,a,a")
8824 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8825
8826 (define_insn "*sub_shiftsi_compare0_scratch"
8827 [(set (reg:CC_NOOV CC_REGNUM)
8828 (compare:CC_NOOV
8829 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8830 (match_operator:SI 2 "shift_operator"
8831 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8832 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8833 (const_int 0)))
8834 (clobber (match_scratch:SI 0 "=r,r,r"))]
8835 "TARGET_32BIT"
8836 "subs%?\\t%0, %1, %3%S2"
8837 [(set_attr "conds" "set")
8838 (set_attr "shift" "3")
8839 (set_attr "arch" "32,a,a")
8840 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8841 \f
8842
8843 (define_insn_and_split "*and_scc"
8844 [(set (match_operand:SI 0 "s_register_operand" "=r")
8845 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8846 [(match_operand 2 "cc_register" "") (const_int 0)])
8847 (match_operand:SI 3 "s_register_operand" "r")))]
8848 "TARGET_ARM"
8849 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8850 "&& reload_completed"
8851 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8852 (cond_exec (match_dup 4) (set (match_dup 0)
8853 (and:SI (match_dup 3) (const_int 1))))]
8854 {
8855 machine_mode mode = GET_MODE (operands[2]);
8856 enum rtx_code rc = GET_CODE (operands[1]);
8857
8858 /* Note that operands[4] is the same as operands[1],
8859 but with VOIDmode as the result. */
8860 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8861 if (mode == CCFPmode || mode == CCFPEmode)
8862 rc = reverse_condition_maybe_unordered (rc);
8863 else
8864 rc = reverse_condition (rc);
8865 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8866 }
8867 [(set_attr "conds" "use")
8868 (set_attr "type" "multiple")
8869 (set_attr "length" "8")]
8870 )
8871
8872 (define_insn_and_split "*ior_scc"
8873 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8874 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8875 [(match_operand 2 "cc_register" "") (const_int 0)])
8876 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8877 "TARGET_ARM"
8878 "@
8879 orr%d1\\t%0, %3, #1
8880 #"
8881 "&& reload_completed
8882 && REGNO (operands [0]) != REGNO (operands[3])"
8883 ;; && which_alternative == 1
8884 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8885 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8886 (cond_exec (match_dup 4) (set (match_dup 0)
8887 (ior:SI (match_dup 3) (const_int 1))))]
8888 {
8889 machine_mode mode = GET_MODE (operands[2]);
8890 enum rtx_code rc = GET_CODE (operands[1]);
8891
8892 /* Note that operands[4] is the same as operands[1],
8893 but with VOIDmode as the result. */
8894 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8895 if (mode == CCFPmode || mode == CCFPEmode)
8896 rc = reverse_condition_maybe_unordered (rc);
8897 else
8898 rc = reverse_condition (rc);
8899 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8900 }
8901 [(set_attr "conds" "use")
8902 (set_attr "length" "4,8")
8903 (set_attr "type" "logic_imm,multiple")]
8904 )
8905
8906 ; A series of splitters for the compare_scc pattern below. Note that
8907 ; order is important.
8908 (define_split
8909 [(set (match_operand:SI 0 "s_register_operand" "")
8910 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8911 (const_int 0)))
8912 (clobber (reg:CC CC_REGNUM))]
8913 "TARGET_32BIT && reload_completed"
8914 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8915
8916 (define_split
8917 [(set (match_operand:SI 0 "s_register_operand" "")
8918 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8919 (const_int 0)))
8920 (clobber (reg:CC CC_REGNUM))]
8921 "TARGET_32BIT && reload_completed"
8922 [(set (match_dup 0) (not:SI (match_dup 1)))
8923 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8924
8925 (define_split
8926 [(set (match_operand:SI 0 "s_register_operand" "")
8927 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8928 (const_int 0)))
8929 (clobber (reg:CC CC_REGNUM))]
8930 "arm_arch5 && TARGET_32BIT"
8931 [(set (match_dup 0) (clz:SI (match_dup 1)))
8932 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8933 )
8934
8935 (define_split
8936 [(set (match_operand:SI 0 "s_register_operand" "")
8937 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8938 (const_int 0)))
8939 (clobber (reg:CC CC_REGNUM))]
8940 "TARGET_32BIT && reload_completed"
8941 [(parallel
8942 [(set (reg:CC CC_REGNUM)
8943 (compare:CC (const_int 1) (match_dup 1)))
8944 (set (match_dup 0)
8945 (minus:SI (const_int 1) (match_dup 1)))])
8946 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8947 (set (match_dup 0) (const_int 0)))])
8948
8949 (define_split
8950 [(set (match_operand:SI 0 "s_register_operand" "")
8951 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8952 (match_operand:SI 2 "const_int_operand" "")))
8953 (clobber (reg:CC CC_REGNUM))]
8954 "TARGET_32BIT && reload_completed"
8955 [(parallel
8956 [(set (reg:CC CC_REGNUM)
8957 (compare:CC (match_dup 1) (match_dup 2)))
8958 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8959 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8960 (set (match_dup 0) (const_int 1)))]
8961 {
8962 operands[3] = GEN_INT (-INTVAL (operands[2]));
8963 })
8964
8965 (define_split
8966 [(set (match_operand:SI 0 "s_register_operand" "")
8967 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8968 (match_operand:SI 2 "arm_add_operand" "")))
8969 (clobber (reg:CC CC_REGNUM))]
8970 "TARGET_32BIT && reload_completed"
8971 [(parallel
8972 [(set (reg:CC_NOOV CC_REGNUM)
8973 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8974 (const_int 0)))
8975 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8976 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8977 (set (match_dup 0) (const_int 1)))])
8978
8979 (define_insn_and_split "*compare_scc"
8980 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8981 (match_operator:SI 1 "arm_comparison_operator"
8982 [(match_operand:SI 2 "s_register_operand" "r,r")
8983 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8984 (clobber (reg:CC CC_REGNUM))]
8985 "TARGET_32BIT"
8986 "#"
8987 "&& reload_completed"
8988 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8989 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8990 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8991 {
8992 rtx tmp1;
8993 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8994 operands[2], operands[3]);
8995 enum rtx_code rc = GET_CODE (operands[1]);
8996
8997 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8998
8999 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9000 if (mode == CCFPmode || mode == CCFPEmode)
9001 rc = reverse_condition_maybe_unordered (rc);
9002 else
9003 rc = reverse_condition (rc);
9004 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
9005 }
9006 [(set_attr "type" "multiple")]
9007 )
9008
9009 ;; Attempt to improve the sequence generated by the compare_scc splitters
9010 ;; not to use conditional execution.
9011
9012 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
9013 ;; clz Rd, reg1
9014 ;; lsr Rd, Rd, #5
9015 (define_peephole2
9016 [(set (reg:CC CC_REGNUM)
9017 (compare:CC (match_operand:SI 1 "register_operand" "")
9018 (const_int 0)))
9019 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9020 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9021 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9022 (set (match_dup 0) (const_int 1)))]
9023 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9024 [(set (match_dup 0) (clz:SI (match_dup 1)))
9025 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9026 )
9027
9028 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
9029 ;; negs Rd, reg1
9030 ;; adc Rd, Rd, reg1
9031 (define_peephole2
9032 [(set (reg:CC CC_REGNUM)
9033 (compare:CC (match_operand:SI 1 "register_operand" "")
9034 (const_int 0)))
9035 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9036 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9037 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9038 (set (match_dup 0) (const_int 1)))
9039 (match_scratch:SI 2 "r")]
9040 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9041 [(parallel
9042 [(set (reg:CC CC_REGNUM)
9043 (compare:CC (const_int 0) (match_dup 1)))
9044 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
9045 (set (match_dup 0)
9046 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
9047 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9048 )
9049
9050 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
9051 ;; sub Rd, Reg1, reg2
9052 ;; clz Rd, Rd
9053 ;; lsr Rd, Rd, #5
9054 (define_peephole2
9055 [(set (reg:CC CC_REGNUM)
9056 (compare:CC (match_operand:SI 1 "register_operand" "")
9057 (match_operand:SI 2 "arm_rhs_operand" "")))
9058 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9059 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9060 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9061 (set (match_dup 0) (const_int 1)))]
9062 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
9063 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
9064 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
9065 (set (match_dup 0) (clz:SI (match_dup 0)))
9066 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
9067 )
9068
9069
9070 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
9071 ;; sub T1, Reg1, reg2
9072 ;; negs Rd, T1
9073 ;; adc Rd, Rd, T1
9074 (define_peephole2
9075 [(set (reg:CC CC_REGNUM)
9076 (compare:CC (match_operand:SI 1 "register_operand" "")
9077 (match_operand:SI 2 "arm_rhs_operand" "")))
9078 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
9079 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
9080 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
9081 (set (match_dup 0) (const_int 1)))
9082 (match_scratch:SI 3 "r")]
9083 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
9084 [(set (match_dup 3) (match_dup 4))
9085 (parallel
9086 [(set (reg:CC CC_REGNUM)
9087 (compare:CC (const_int 0) (match_dup 3)))
9088 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
9089 (set (match_dup 0)
9090 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
9091 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
9092 "
9093 if (CONST_INT_P (operands[2]))
9094 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
9095 else
9096 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
9097 ")
9098
9099 (define_insn "*cond_move"
9100 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9101 (if_then_else:SI (match_operator 3 "equality_operator"
9102 [(match_operator 4 "arm_comparison_operator"
9103 [(match_operand 5 "cc_register" "") (const_int 0)])
9104 (const_int 0)])
9105 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9106 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
9107 "TARGET_ARM"
9108 "*
9109 if (GET_CODE (operands[3]) == NE)
9110 {
9111 if (which_alternative != 1)
9112 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
9113 if (which_alternative != 0)
9114 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
9115 return \"\";
9116 }
9117 if (which_alternative != 0)
9118 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9119 if (which_alternative != 1)
9120 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
9121 return \"\";
9122 "
9123 [(set_attr "conds" "use")
9124 (set_attr_alternative "type"
9125 [(if_then_else (match_operand 2 "const_int_operand" "")
9126 (const_string "mov_imm")
9127 (const_string "mov_reg"))
9128 (if_then_else (match_operand 1 "const_int_operand" "")
9129 (const_string "mov_imm")
9130 (const_string "mov_reg"))
9131 (const_string "multiple")])
9132 (set_attr "length" "4,4,8")]
9133 )
9134
9135 (define_insn "*cond_arith"
9136 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9137 (match_operator:SI 5 "shiftable_operator"
9138 [(match_operator:SI 4 "arm_comparison_operator"
9139 [(match_operand:SI 2 "s_register_operand" "r,r")
9140 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9141 (match_operand:SI 1 "s_register_operand" "0,?r")]))
9142 (clobber (reg:CC CC_REGNUM))]
9143 "TARGET_ARM"
9144 "*
9145 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
9146 return \"%i5\\t%0, %1, %2, lsr #31\";
9147
9148 output_asm_insn (\"cmp\\t%2, %3\", operands);
9149 if (GET_CODE (operands[5]) == AND)
9150 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
9151 else if (GET_CODE (operands[5]) == MINUS)
9152 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
9153 else if (which_alternative != 0)
9154 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9155 return \"%i5%d4\\t%0, %1, #1\";
9156 "
9157 [(set_attr "conds" "clob")
9158 (set_attr "length" "12")
9159 (set_attr "type" "multiple")]
9160 )
9161
9162 (define_insn "*cond_sub"
9163 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9164 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
9165 (match_operator:SI 4 "arm_comparison_operator"
9166 [(match_operand:SI 2 "s_register_operand" "r,r")
9167 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9168 (clobber (reg:CC CC_REGNUM))]
9169 "TARGET_ARM"
9170 "*
9171 output_asm_insn (\"cmp\\t%2, %3\", operands);
9172 if (which_alternative != 0)
9173 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
9174 return \"sub%d4\\t%0, %1, #1\";
9175 "
9176 [(set_attr "conds" "clob")
9177 (set_attr "length" "8,12")
9178 (set_attr "type" "multiple")]
9179 )
9180
9181 (define_insn "*cmp_ite0"
9182 [(set (match_operand 6 "dominant_cc_register" "")
9183 (compare
9184 (if_then_else:SI
9185 (match_operator 4 "arm_comparison_operator"
9186 [(match_operand:SI 0 "s_register_operand"
9187 "l,l,l,r,r,r,r,r,r")
9188 (match_operand:SI 1 "arm_add_operand"
9189 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9190 (match_operator:SI 5 "arm_comparison_operator"
9191 [(match_operand:SI 2 "s_register_operand"
9192 "l,r,r,l,l,r,r,r,r")
9193 (match_operand:SI 3 "arm_add_operand"
9194 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9195 (const_int 0))
9196 (const_int 0)))]
9197 "TARGET_32BIT"
9198 "*
9199 {
9200 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9201 {
9202 {\"cmp%d5\\t%0, %1\",
9203 \"cmp%d4\\t%2, %3\"},
9204 {\"cmn%d5\\t%0, #%n1\",
9205 \"cmp%d4\\t%2, %3\"},
9206 {\"cmp%d5\\t%0, %1\",
9207 \"cmn%d4\\t%2, #%n3\"},
9208 {\"cmn%d5\\t%0, #%n1\",
9209 \"cmn%d4\\t%2, #%n3\"}
9210 };
9211 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9212 {
9213 {\"cmp\\t%2, %3\",
9214 \"cmp\\t%0, %1\"},
9215 {\"cmp\\t%2, %3\",
9216 \"cmn\\t%0, #%n1\"},
9217 {\"cmn\\t%2, #%n3\",
9218 \"cmp\\t%0, %1\"},
9219 {\"cmn\\t%2, #%n3\",
9220 \"cmn\\t%0, #%n1\"}
9221 };
9222 static const char * const ite[2] =
9223 {
9224 \"it\\t%d5\",
9225 \"it\\t%d4\"
9226 };
9227 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9228 CMP_CMP, CMN_CMP, CMP_CMP,
9229 CMN_CMP, CMP_CMN, CMN_CMN};
9230 int swap =
9231 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9232
9233 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9234 if (TARGET_THUMB2) {
9235 output_asm_insn (ite[swap], operands);
9236 }
9237 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9238 return \"\";
9239 }"
9240 [(set_attr "conds" "set")
9241 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9242 (set_attr "type" "multiple")
9243 (set_attr_alternative "length"
9244 [(const_int 6)
9245 (const_int 8)
9246 (const_int 8)
9247 (const_int 8)
9248 (const_int 8)
9249 (if_then_else (eq_attr "is_thumb" "no")
9250 (const_int 8)
9251 (const_int 10))
9252 (if_then_else (eq_attr "is_thumb" "no")
9253 (const_int 8)
9254 (const_int 10))
9255 (if_then_else (eq_attr "is_thumb" "no")
9256 (const_int 8)
9257 (const_int 10))
9258 (if_then_else (eq_attr "is_thumb" "no")
9259 (const_int 8)
9260 (const_int 10))])]
9261 )
9262
9263 (define_insn "*cmp_ite1"
9264 [(set (match_operand 6 "dominant_cc_register" "")
9265 (compare
9266 (if_then_else:SI
9267 (match_operator 4 "arm_comparison_operator"
9268 [(match_operand:SI 0 "s_register_operand"
9269 "l,l,l,r,r,r,r,r,r")
9270 (match_operand:SI 1 "arm_add_operand"
9271 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9272 (match_operator:SI 5 "arm_comparison_operator"
9273 [(match_operand:SI 2 "s_register_operand"
9274 "l,r,r,l,l,r,r,r,r")
9275 (match_operand:SI 3 "arm_add_operand"
9276 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9277 (const_int 1))
9278 (const_int 0)))]
9279 "TARGET_32BIT"
9280 "*
9281 {
9282 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9283 {
9284 {\"cmp\\t%0, %1\",
9285 \"cmp\\t%2, %3\"},
9286 {\"cmn\\t%0, #%n1\",
9287 \"cmp\\t%2, %3\"},
9288 {\"cmp\\t%0, %1\",
9289 \"cmn\\t%2, #%n3\"},
9290 {\"cmn\\t%0, #%n1\",
9291 \"cmn\\t%2, #%n3\"}
9292 };
9293 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9294 {
9295 {\"cmp%d4\\t%2, %3\",
9296 \"cmp%D5\\t%0, %1\"},
9297 {\"cmp%d4\\t%2, %3\",
9298 \"cmn%D5\\t%0, #%n1\"},
9299 {\"cmn%d4\\t%2, #%n3\",
9300 \"cmp%D5\\t%0, %1\"},
9301 {\"cmn%d4\\t%2, #%n3\",
9302 \"cmn%D5\\t%0, #%n1\"}
9303 };
9304 static const char * const ite[2] =
9305 {
9306 \"it\\t%d4\",
9307 \"it\\t%D5\"
9308 };
9309 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9310 CMP_CMP, CMN_CMP, CMP_CMP,
9311 CMN_CMP, CMP_CMN, CMN_CMN};
9312 int swap =
9313 comparison_dominates_p (GET_CODE (operands[5]),
9314 reverse_condition (GET_CODE (operands[4])));
9315
9316 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9317 if (TARGET_THUMB2) {
9318 output_asm_insn (ite[swap], operands);
9319 }
9320 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9321 return \"\";
9322 }"
9323 [(set_attr "conds" "set")
9324 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9325 (set_attr_alternative "length"
9326 [(const_int 6)
9327 (const_int 8)
9328 (const_int 8)
9329 (const_int 8)
9330 (const_int 8)
9331 (if_then_else (eq_attr "is_thumb" "no")
9332 (const_int 8)
9333 (const_int 10))
9334 (if_then_else (eq_attr "is_thumb" "no")
9335 (const_int 8)
9336 (const_int 10))
9337 (if_then_else (eq_attr "is_thumb" "no")
9338 (const_int 8)
9339 (const_int 10))
9340 (if_then_else (eq_attr "is_thumb" "no")
9341 (const_int 8)
9342 (const_int 10))])
9343 (set_attr "type" "multiple")]
9344 )
9345
9346 (define_insn "*cmp_and"
9347 [(set (match_operand 6 "dominant_cc_register" "")
9348 (compare
9349 (and:SI
9350 (match_operator 4 "arm_comparison_operator"
9351 [(match_operand:SI 0 "s_register_operand"
9352 "l,l,l,r,r,r,r,r,r")
9353 (match_operand:SI 1 "arm_add_operand"
9354 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9355 (match_operator:SI 5 "arm_comparison_operator"
9356 [(match_operand:SI 2 "s_register_operand"
9357 "l,r,r,l,l,r,r,r,r")
9358 (match_operand:SI 3 "arm_add_operand"
9359 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9360 (const_int 0)))]
9361 "TARGET_32BIT"
9362 "*
9363 {
9364 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9365 {
9366 {\"cmp%d5\\t%0, %1\",
9367 \"cmp%d4\\t%2, %3\"},
9368 {\"cmn%d5\\t%0, #%n1\",
9369 \"cmp%d4\\t%2, %3\"},
9370 {\"cmp%d5\\t%0, %1\",
9371 \"cmn%d4\\t%2, #%n3\"},
9372 {\"cmn%d5\\t%0, #%n1\",
9373 \"cmn%d4\\t%2, #%n3\"}
9374 };
9375 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9376 {
9377 {\"cmp\\t%2, %3\",
9378 \"cmp\\t%0, %1\"},
9379 {\"cmp\\t%2, %3\",
9380 \"cmn\\t%0, #%n1\"},
9381 {\"cmn\\t%2, #%n3\",
9382 \"cmp\\t%0, %1\"},
9383 {\"cmn\\t%2, #%n3\",
9384 \"cmn\\t%0, #%n1\"}
9385 };
9386 static const char *const ite[2] =
9387 {
9388 \"it\\t%d5\",
9389 \"it\\t%d4\"
9390 };
9391 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9392 CMP_CMP, CMN_CMP, CMP_CMP,
9393 CMN_CMP, CMP_CMN, CMN_CMN};
9394 int swap =
9395 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9396
9397 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9398 if (TARGET_THUMB2) {
9399 output_asm_insn (ite[swap], operands);
9400 }
9401 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9402 return \"\";
9403 }"
9404 [(set_attr "conds" "set")
9405 (set_attr "predicable" "no")
9406 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9407 (set_attr_alternative "length"
9408 [(const_int 6)
9409 (const_int 8)
9410 (const_int 8)
9411 (const_int 8)
9412 (const_int 8)
9413 (if_then_else (eq_attr "is_thumb" "no")
9414 (const_int 8)
9415 (const_int 10))
9416 (if_then_else (eq_attr "is_thumb" "no")
9417 (const_int 8)
9418 (const_int 10))
9419 (if_then_else (eq_attr "is_thumb" "no")
9420 (const_int 8)
9421 (const_int 10))
9422 (if_then_else (eq_attr "is_thumb" "no")
9423 (const_int 8)
9424 (const_int 10))])
9425 (set_attr "type" "multiple")]
9426 )
9427
9428 (define_insn "*cmp_ior"
9429 [(set (match_operand 6 "dominant_cc_register" "")
9430 (compare
9431 (ior:SI
9432 (match_operator 4 "arm_comparison_operator"
9433 [(match_operand:SI 0 "s_register_operand"
9434 "l,l,l,r,r,r,r,r,r")
9435 (match_operand:SI 1 "arm_add_operand"
9436 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9437 (match_operator:SI 5 "arm_comparison_operator"
9438 [(match_operand:SI 2 "s_register_operand"
9439 "l,r,r,l,l,r,r,r,r")
9440 (match_operand:SI 3 "arm_add_operand"
9441 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]))
9442 (const_int 0)))]
9443 "TARGET_32BIT"
9444 "*
9445 {
9446 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9447 {
9448 {\"cmp\\t%0, %1\",
9449 \"cmp\\t%2, %3\"},
9450 {\"cmn\\t%0, #%n1\",
9451 \"cmp\\t%2, %3\"},
9452 {\"cmp\\t%0, %1\",
9453 \"cmn\\t%2, #%n3\"},
9454 {\"cmn\\t%0, #%n1\",
9455 \"cmn\\t%2, #%n3\"}
9456 };
9457 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9458 {
9459 {\"cmp%D4\\t%2, %3\",
9460 \"cmp%D5\\t%0, %1\"},
9461 {\"cmp%D4\\t%2, %3\",
9462 \"cmn%D5\\t%0, #%n1\"},
9463 {\"cmn%D4\\t%2, #%n3\",
9464 \"cmp%D5\\t%0, %1\"},
9465 {\"cmn%D4\\t%2, #%n3\",
9466 \"cmn%D5\\t%0, #%n1\"}
9467 };
9468 static const char *const ite[2] =
9469 {
9470 \"it\\t%D4\",
9471 \"it\\t%D5\"
9472 };
9473 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9474 CMP_CMP, CMN_CMP, CMP_CMP,
9475 CMN_CMP, CMP_CMN, CMN_CMN};
9476 int swap =
9477 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9478
9479 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9480 if (TARGET_THUMB2) {
9481 output_asm_insn (ite[swap], operands);
9482 }
9483 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9484 return \"\";
9485 }
9486 "
9487 [(set_attr "conds" "set")
9488 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9489 (set_attr_alternative "length"
9490 [(const_int 6)
9491 (const_int 8)
9492 (const_int 8)
9493 (const_int 8)
9494 (const_int 8)
9495 (if_then_else (eq_attr "is_thumb" "no")
9496 (const_int 8)
9497 (const_int 10))
9498 (if_then_else (eq_attr "is_thumb" "no")
9499 (const_int 8)
9500 (const_int 10))
9501 (if_then_else (eq_attr "is_thumb" "no")
9502 (const_int 8)
9503 (const_int 10))
9504 (if_then_else (eq_attr "is_thumb" "no")
9505 (const_int 8)
9506 (const_int 10))])
9507 (set_attr "type" "multiple")]
9508 )
9509
9510 (define_insn_and_split "*ior_scc_scc"
9511 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9512 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9513 [(match_operand:SI 1 "s_register_operand" "r")
9514 (match_operand:SI 2 "arm_add_operand" "rIL")])
9515 (match_operator:SI 6 "arm_comparison_operator"
9516 [(match_operand:SI 4 "s_register_operand" "r")
9517 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9518 (clobber (reg:CC CC_REGNUM))]
9519 "TARGET_32BIT
9520 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9521 != CCmode)"
9522 "#"
9523 "TARGET_32BIT && reload_completed"
9524 [(set (match_dup 7)
9525 (compare
9526 (ior:SI
9527 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9528 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9529 (const_int 0)))
9530 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9531 "operands[7]
9532 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9533 DOM_CC_X_OR_Y),
9534 CC_REGNUM);"
9535 [(set_attr "conds" "clob")
9536 (set_attr "length" "16")
9537 (set_attr "type" "multiple")]
9538 )
9539
9540 ; If the above pattern is followed by a CMP insn, then the compare is
9541 ; redundant, since we can rework the conditional instruction that follows.
9542 (define_insn_and_split "*ior_scc_scc_cmp"
9543 [(set (match_operand 0 "dominant_cc_register" "")
9544 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9545 [(match_operand:SI 1 "s_register_operand" "r")
9546 (match_operand:SI 2 "arm_add_operand" "rIL")])
9547 (match_operator:SI 6 "arm_comparison_operator"
9548 [(match_operand:SI 4 "s_register_operand" "r")
9549 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9550 (const_int 0)))
9551 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9552 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9553 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9554 "TARGET_32BIT"
9555 "#"
9556 "TARGET_32BIT && reload_completed"
9557 [(set (match_dup 0)
9558 (compare
9559 (ior:SI
9560 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9561 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9562 (const_int 0)))
9563 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9564 ""
9565 [(set_attr "conds" "set")
9566 (set_attr "length" "16")
9567 (set_attr "type" "multiple")]
9568 )
9569
9570 (define_insn_and_split "*and_scc_scc"
9571 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
9572 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9573 [(match_operand:SI 1 "s_register_operand" "r")
9574 (match_operand:SI 2 "arm_add_operand" "rIL")])
9575 (match_operator:SI 6 "arm_comparison_operator"
9576 [(match_operand:SI 4 "s_register_operand" "r")
9577 (match_operand:SI 5 "arm_add_operand" "rIL")])))
9578 (clobber (reg:CC CC_REGNUM))]
9579 "TARGET_32BIT
9580 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9581 != CCmode)"
9582 "#"
9583 "TARGET_32BIT && reload_completed
9584 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9585 != CCmode)"
9586 [(set (match_dup 7)
9587 (compare
9588 (and:SI
9589 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9590 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9591 (const_int 0)))
9592 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9593 "operands[7]
9594 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9595 DOM_CC_X_AND_Y),
9596 CC_REGNUM);"
9597 [(set_attr "conds" "clob")
9598 (set_attr "length" "16")
9599 (set_attr "type" "multiple")]
9600 )
9601
9602 ; If the above pattern is followed by a CMP insn, then the compare is
9603 ; redundant, since we can rework the conditional instruction that follows.
9604 (define_insn_and_split "*and_scc_scc_cmp"
9605 [(set (match_operand 0 "dominant_cc_register" "")
9606 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9607 [(match_operand:SI 1 "s_register_operand" "r")
9608 (match_operand:SI 2 "arm_add_operand" "rIL")])
9609 (match_operator:SI 6 "arm_comparison_operator"
9610 [(match_operand:SI 4 "s_register_operand" "r")
9611 (match_operand:SI 5 "arm_add_operand" "rIL")]))
9612 (const_int 0)))
9613 (set (match_operand:SI 7 "s_register_operand" "=Ts")
9614 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9615 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9616 "TARGET_32BIT"
9617 "#"
9618 "TARGET_32BIT && reload_completed"
9619 [(set (match_dup 0)
9620 (compare
9621 (and:SI
9622 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9623 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9624 (const_int 0)))
9625 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9626 ""
9627 [(set_attr "conds" "set")
9628 (set_attr "length" "16")
9629 (set_attr "type" "multiple")]
9630 )
9631
9632 ;; If there is no dominance in the comparison, then we can still save an
9633 ;; instruction in the AND case, since we can know that the second compare
9634 ;; need only zero the value if false (if true, then the value is already
9635 ;; correct).
9636 (define_insn_and_split "*and_scc_scc_nodom"
9637 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9638 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9639 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9640 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9641 (match_operator:SI 6 "arm_comparison_operator"
9642 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9643 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9644 (clobber (reg:CC CC_REGNUM))]
9645 "TARGET_32BIT
9646 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9647 == CCmode)"
9648 "#"
9649 "TARGET_32BIT && reload_completed"
9650 [(parallel [(set (match_dup 0)
9651 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9652 (clobber (reg:CC CC_REGNUM))])
9653 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9654 (set (match_dup 0)
9655 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9656 (match_dup 0)
9657 (const_int 0)))]
9658 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9659 operands[4], operands[5]),
9660 CC_REGNUM);
9661 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9662 operands[5]);"
9663 [(set_attr "conds" "clob")
9664 (set_attr "length" "20")
9665 (set_attr "type" "multiple")]
9666 )
9667
9668 (define_split
9669 [(set (reg:CC_NOOV CC_REGNUM)
9670 (compare:CC_NOOV (ior:SI
9671 (and:SI (match_operand:SI 0 "s_register_operand" "")
9672 (const_int 1))
9673 (match_operator:SI 1 "arm_comparison_operator"
9674 [(match_operand:SI 2 "s_register_operand" "")
9675 (match_operand:SI 3 "arm_add_operand" "")]))
9676 (const_int 0)))
9677 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9678 "TARGET_ARM"
9679 [(set (match_dup 4)
9680 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9681 (match_dup 0)))
9682 (set (reg:CC_NOOV CC_REGNUM)
9683 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9684 (const_int 0)))]
9685 "")
9686
9687 (define_split
9688 [(set (reg:CC_NOOV CC_REGNUM)
9689 (compare:CC_NOOV (ior:SI
9690 (match_operator:SI 1 "arm_comparison_operator"
9691 [(match_operand:SI 2 "s_register_operand" "")
9692 (match_operand:SI 3 "arm_add_operand" "")])
9693 (and:SI (match_operand:SI 0 "s_register_operand" "")
9694 (const_int 1)))
9695 (const_int 0)))
9696 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9697 "TARGET_ARM"
9698 [(set (match_dup 4)
9699 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9700 (match_dup 0)))
9701 (set (reg:CC_NOOV CC_REGNUM)
9702 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9703 (const_int 0)))]
9704 "")
9705 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9706
9707 (define_insn_and_split "*negscc"
9708 [(set (match_operand:SI 0 "s_register_operand" "=r")
9709 (neg:SI (match_operator 3 "arm_comparison_operator"
9710 [(match_operand:SI 1 "s_register_operand" "r")
9711 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9712 (clobber (reg:CC CC_REGNUM))]
9713 "TARGET_ARM"
9714 "#"
9715 "&& reload_completed"
9716 [(const_int 0)]
9717 {
9718 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9719
9720 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9721 {
9722 /* Emit mov\\t%0, %1, asr #31 */
9723 emit_insn (gen_rtx_SET (operands[0],
9724 gen_rtx_ASHIFTRT (SImode,
9725 operands[1],
9726 GEN_INT (31))));
9727 DONE;
9728 }
9729 else if (GET_CODE (operands[3]) == NE)
9730 {
9731 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9732 if (CONST_INT_P (operands[2]))
9733 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9734 GEN_INT (- INTVAL (operands[2]))));
9735 else
9736 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9737
9738 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9739 gen_rtx_NE (SImode,
9740 cc_reg,
9741 const0_rtx),
9742 gen_rtx_SET (operands[0],
9743 GEN_INT (~0))));
9744 DONE;
9745 }
9746 else
9747 {
9748 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9749 emit_insn (gen_rtx_SET (cc_reg,
9750 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9751 enum rtx_code rc = GET_CODE (operands[3]);
9752
9753 rc = reverse_condition (rc);
9754 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9755 gen_rtx_fmt_ee (rc,
9756 VOIDmode,
9757 cc_reg,
9758 const0_rtx),
9759 gen_rtx_SET (operands[0], const0_rtx)));
9760 rc = GET_CODE (operands[3]);
9761 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9762 gen_rtx_fmt_ee (rc,
9763 VOIDmode,
9764 cc_reg,
9765 const0_rtx),
9766 gen_rtx_SET (operands[0],
9767 GEN_INT (~0))));
9768 DONE;
9769 }
9770 FAIL;
9771 }
9772 [(set_attr "conds" "clob")
9773 (set_attr "length" "12")
9774 (set_attr "type" "multiple")]
9775 )
9776
9777 (define_insn_and_split "movcond_addsi"
9778 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9779 (if_then_else:SI
9780 (match_operator 5 "comparison_operator"
9781 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9782 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9783 (const_int 0)])
9784 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9785 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9786 (clobber (reg:CC CC_REGNUM))]
9787 "TARGET_32BIT"
9788 "#"
9789 "&& reload_completed"
9790 [(set (reg:CC_NOOV CC_REGNUM)
9791 (compare:CC_NOOV
9792 (plus:SI (match_dup 3)
9793 (match_dup 4))
9794 (const_int 0)))
9795 (set (match_dup 0) (match_dup 1))
9796 (cond_exec (match_dup 6)
9797 (set (match_dup 0) (match_dup 2)))]
9798 "
9799 {
9800 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9801 operands[3], operands[4]);
9802 enum rtx_code rc = GET_CODE (operands[5]);
9803 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9804 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9805 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9806 rc = reverse_condition (rc);
9807 else
9808 std::swap (operands[1], operands[2]);
9809
9810 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9811 }
9812 "
9813 [(set_attr "conds" "clob")
9814 (set_attr "enabled_for_depr_it" "no,yes,yes")
9815 (set_attr "type" "multiple")]
9816 )
9817
9818 (define_insn "movcond"
9819 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9820 (if_then_else:SI
9821 (match_operator 5 "arm_comparison_operator"
9822 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9823 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9824 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9825 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9826 (clobber (reg:CC CC_REGNUM))]
9827 "TARGET_ARM"
9828 "*
9829 if (GET_CODE (operands[5]) == LT
9830 && (operands[4] == const0_rtx))
9831 {
9832 if (which_alternative != 1 && REG_P (operands[1]))
9833 {
9834 if (operands[2] == const0_rtx)
9835 return \"and\\t%0, %1, %3, asr #31\";
9836 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9837 }
9838 else if (which_alternative != 0 && REG_P (operands[2]))
9839 {
9840 if (operands[1] == const0_rtx)
9841 return \"bic\\t%0, %2, %3, asr #31\";
9842 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9843 }
9844 /* The only case that falls through to here is when both ops 1 & 2
9845 are constants. */
9846 }
9847
9848 if (GET_CODE (operands[5]) == GE
9849 && (operands[4] == const0_rtx))
9850 {
9851 if (which_alternative != 1 && REG_P (operands[1]))
9852 {
9853 if (operands[2] == const0_rtx)
9854 return \"bic\\t%0, %1, %3, asr #31\";
9855 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9856 }
9857 else if (which_alternative != 0 && REG_P (operands[2]))
9858 {
9859 if (operands[1] == const0_rtx)
9860 return \"and\\t%0, %2, %3, asr #31\";
9861 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9862 }
9863 /* The only case that falls through to here is when both ops 1 & 2
9864 are constants. */
9865 }
9866 if (CONST_INT_P (operands[4])
9867 && !const_ok_for_arm (INTVAL (operands[4])))
9868 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9869 else
9870 output_asm_insn (\"cmp\\t%3, %4\", operands);
9871 if (which_alternative != 0)
9872 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9873 if (which_alternative != 1)
9874 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9875 return \"\";
9876 "
9877 [(set_attr "conds" "clob")
9878 (set_attr "length" "8,8,12")
9879 (set_attr "type" "multiple")]
9880 )
9881
9882 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9883
9884 (define_insn "*ifcompare_plus_move"
9885 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9886 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9887 [(match_operand:SI 4 "s_register_operand" "r,r")
9888 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9889 (plus:SI
9890 (match_operand:SI 2 "s_register_operand" "r,r")
9891 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9892 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9893 (clobber (reg:CC CC_REGNUM))]
9894 "TARGET_ARM"
9895 "#"
9896 [(set_attr "conds" "clob")
9897 (set_attr "length" "8,12")
9898 (set_attr "type" "multiple")]
9899 )
9900
9901 (define_insn "*if_plus_move"
9902 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9903 (if_then_else:SI
9904 (match_operator 4 "arm_comparison_operator"
9905 [(match_operand 5 "cc_register" "") (const_int 0)])
9906 (plus:SI
9907 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9908 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9909 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9910 "TARGET_ARM"
9911 "@
9912 add%d4\\t%0, %2, %3
9913 sub%d4\\t%0, %2, #%n3
9914 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9915 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9916 [(set_attr "conds" "use")
9917 (set_attr "length" "4,4,8,8")
9918 (set_attr_alternative "type"
9919 [(if_then_else (match_operand 3 "const_int_operand" "")
9920 (const_string "alu_imm" )
9921 (const_string "alu_sreg"))
9922 (const_string "alu_imm")
9923 (const_string "multiple")
9924 (const_string "multiple")])]
9925 )
9926
9927 (define_insn "*ifcompare_move_plus"
9928 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9929 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9930 [(match_operand:SI 4 "s_register_operand" "r,r")
9931 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9932 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9933 (plus:SI
9934 (match_operand:SI 2 "s_register_operand" "r,r")
9935 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9936 (clobber (reg:CC CC_REGNUM))]
9937 "TARGET_ARM"
9938 "#"
9939 [(set_attr "conds" "clob")
9940 (set_attr "length" "8,12")
9941 (set_attr "type" "multiple")]
9942 )
9943
9944 (define_insn "*if_move_plus"
9945 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9946 (if_then_else:SI
9947 (match_operator 4 "arm_comparison_operator"
9948 [(match_operand 5 "cc_register" "") (const_int 0)])
9949 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9950 (plus:SI
9951 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9952 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9953 "TARGET_ARM"
9954 "@
9955 add%D4\\t%0, %2, %3
9956 sub%D4\\t%0, %2, #%n3
9957 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9958 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9959 [(set_attr "conds" "use")
9960 (set_attr "length" "4,4,8,8")
9961 (set_attr_alternative "type"
9962 [(if_then_else (match_operand 3 "const_int_operand" "")
9963 (const_string "alu_imm" )
9964 (const_string "alu_sreg"))
9965 (const_string "alu_imm")
9966 (const_string "multiple")
9967 (const_string "multiple")])]
9968 )
9969
9970 (define_insn "*ifcompare_arith_arith"
9971 [(set (match_operand:SI 0 "s_register_operand" "=r")
9972 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9973 [(match_operand:SI 5 "s_register_operand" "r")
9974 (match_operand:SI 6 "arm_add_operand" "rIL")])
9975 (match_operator:SI 8 "shiftable_operator"
9976 [(match_operand:SI 1 "s_register_operand" "r")
9977 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9978 (match_operator:SI 7 "shiftable_operator"
9979 [(match_operand:SI 3 "s_register_operand" "r")
9980 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9981 (clobber (reg:CC CC_REGNUM))]
9982 "TARGET_ARM"
9983 "#"
9984 [(set_attr "conds" "clob")
9985 (set_attr "length" "12")
9986 (set_attr "type" "multiple")]
9987 )
9988
9989 (define_insn "*if_arith_arith"
9990 [(set (match_operand:SI 0 "s_register_operand" "=r")
9991 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9992 [(match_operand 8 "cc_register" "") (const_int 0)])
9993 (match_operator:SI 6 "shiftable_operator"
9994 [(match_operand:SI 1 "s_register_operand" "r")
9995 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9996 (match_operator:SI 7 "shiftable_operator"
9997 [(match_operand:SI 3 "s_register_operand" "r")
9998 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9999 "TARGET_ARM"
10000 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
10001 [(set_attr "conds" "use")
10002 (set_attr "length" "8")
10003 (set_attr "type" "multiple")]
10004 )
10005
10006 (define_insn "*ifcompare_arith_move"
10007 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10008 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10009 [(match_operand:SI 2 "s_register_operand" "r,r")
10010 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
10011 (match_operator:SI 7 "shiftable_operator"
10012 [(match_operand:SI 4 "s_register_operand" "r,r")
10013 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
10014 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
10015 (clobber (reg:CC CC_REGNUM))]
10016 "TARGET_ARM"
10017 "*
10018 /* If we have an operation where (op x 0) is the identity operation and
10019 the conditional operator is LT or GE and we are comparing against zero and
10020 everything is in registers then we can do this in two instructions. */
10021 if (operands[3] == const0_rtx
10022 && GET_CODE (operands[7]) != AND
10023 && REG_P (operands[5])
10024 && REG_P (operands[1])
10025 && REGNO (operands[1]) == REGNO (operands[4])
10026 && REGNO (operands[4]) != REGNO (operands[0]))
10027 {
10028 if (GET_CODE (operands[6]) == LT)
10029 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10030 else if (GET_CODE (operands[6]) == GE)
10031 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
10032 }
10033 if (CONST_INT_P (operands[3])
10034 && !const_ok_for_arm (INTVAL (operands[3])))
10035 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
10036 else
10037 output_asm_insn (\"cmp\\t%2, %3\", operands);
10038 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
10039 if (which_alternative != 0)
10040 return \"mov%D6\\t%0, %1\";
10041 return \"\";
10042 "
10043 [(set_attr "conds" "clob")
10044 (set_attr "length" "8,12")
10045 (set_attr "type" "multiple")]
10046 )
10047
10048 (define_insn "*if_arith_move"
10049 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10050 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10051 [(match_operand 6 "cc_register" "") (const_int 0)])
10052 (match_operator:SI 5 "shiftable_operator"
10053 [(match_operand:SI 2 "s_register_operand" "r,r")
10054 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
10055 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
10056 "TARGET_ARM"
10057 "@
10058 %I5%d4\\t%0, %2, %3
10059 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
10060 [(set_attr "conds" "use")
10061 (set_attr "length" "4,8")
10062 (set_attr_alternative "type"
10063 [(if_then_else (match_operand 3 "const_int_operand" "")
10064 (const_string "alu_shift_imm" )
10065 (const_string "alu_shift_reg"))
10066 (const_string "multiple")])]
10067 )
10068
10069 (define_insn "*ifcompare_move_arith"
10070 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10071 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
10072 [(match_operand:SI 4 "s_register_operand" "r,r")
10073 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10074 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10075 (match_operator:SI 7 "shiftable_operator"
10076 [(match_operand:SI 2 "s_register_operand" "r,r")
10077 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
10078 (clobber (reg:CC CC_REGNUM))]
10079 "TARGET_ARM"
10080 "*
10081 /* If we have an operation where (op x 0) is the identity operation and
10082 the conditional operator is LT or GE and we are comparing against zero and
10083 everything is in registers then we can do this in two instructions */
10084 if (operands[5] == const0_rtx
10085 && GET_CODE (operands[7]) != AND
10086 && REG_P (operands[3])
10087 && REG_P (operands[1])
10088 && REGNO (operands[1]) == REGNO (operands[2])
10089 && REGNO (operands[2]) != REGNO (operands[0]))
10090 {
10091 if (GET_CODE (operands[6]) == GE)
10092 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10093 else if (GET_CODE (operands[6]) == LT)
10094 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
10095 }
10096
10097 if (CONST_INT_P (operands[5])
10098 && !const_ok_for_arm (INTVAL (operands[5])))
10099 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
10100 else
10101 output_asm_insn (\"cmp\\t%4, %5\", operands);
10102
10103 if (which_alternative != 0)
10104 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
10105 return \"%I7%D6\\t%0, %2, %3\";
10106 "
10107 [(set_attr "conds" "clob")
10108 (set_attr "length" "8,12")
10109 (set_attr "type" "multiple")]
10110 )
10111
10112 (define_insn "*if_move_arith"
10113 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10114 (if_then_else:SI
10115 (match_operator 4 "arm_comparison_operator"
10116 [(match_operand 6 "cc_register" "") (const_int 0)])
10117 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10118 (match_operator:SI 5 "shiftable_operator"
10119 [(match_operand:SI 2 "s_register_operand" "r,r")
10120 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
10121 "TARGET_ARM"
10122 "@
10123 %I5%D4\\t%0, %2, %3
10124 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
10125 [(set_attr "conds" "use")
10126 (set_attr "length" "4,8")
10127 (set_attr_alternative "type"
10128 [(if_then_else (match_operand 3 "const_int_operand" "")
10129 (const_string "alu_shift_imm" )
10130 (const_string "alu_shift_reg"))
10131 (const_string "multiple")])]
10132 )
10133
10134 (define_insn "*ifcompare_move_not"
10135 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10136 (if_then_else:SI
10137 (match_operator 5 "arm_comparison_operator"
10138 [(match_operand:SI 3 "s_register_operand" "r,r")
10139 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10140 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10141 (not:SI
10142 (match_operand:SI 2 "s_register_operand" "r,r"))))
10143 (clobber (reg:CC CC_REGNUM))]
10144 "TARGET_ARM"
10145 "#"
10146 [(set_attr "conds" "clob")
10147 (set_attr "length" "8,12")
10148 (set_attr "type" "multiple")]
10149 )
10150
10151 (define_insn "*if_move_not"
10152 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10153 (if_then_else:SI
10154 (match_operator 4 "arm_comparison_operator"
10155 [(match_operand 3 "cc_register" "") (const_int 0)])
10156 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10157 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
10158 "TARGET_ARM"
10159 "@
10160 mvn%D4\\t%0, %2
10161 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
10162 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
10163 [(set_attr "conds" "use")
10164 (set_attr "type" "mvn_reg")
10165 (set_attr "length" "4,8,8")
10166 (set_attr "type" "mvn_reg,multiple,multiple")]
10167 )
10168
10169 (define_insn "*ifcompare_not_move"
10170 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10171 (if_then_else:SI
10172 (match_operator 5 "arm_comparison_operator"
10173 [(match_operand:SI 3 "s_register_operand" "r,r")
10174 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10175 (not:SI
10176 (match_operand:SI 2 "s_register_operand" "r,r"))
10177 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10178 (clobber (reg:CC CC_REGNUM))]
10179 "TARGET_ARM"
10180 "#"
10181 [(set_attr "conds" "clob")
10182 (set_attr "length" "8,12")
10183 (set_attr "type" "multiple")]
10184 )
10185
10186 (define_insn "*if_not_move"
10187 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10188 (if_then_else:SI
10189 (match_operator 4 "arm_comparison_operator"
10190 [(match_operand 3 "cc_register" "") (const_int 0)])
10191 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
10192 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10193 "TARGET_ARM"
10194 "@
10195 mvn%d4\\t%0, %2
10196 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
10197 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
10198 [(set_attr "conds" "use")
10199 (set_attr "type" "mvn_reg,multiple,multiple")
10200 (set_attr "length" "4,8,8")]
10201 )
10202
10203 (define_insn "*ifcompare_shift_move"
10204 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10205 (if_then_else:SI
10206 (match_operator 6 "arm_comparison_operator"
10207 [(match_operand:SI 4 "s_register_operand" "r,r")
10208 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10209 (match_operator:SI 7 "shift_operator"
10210 [(match_operand:SI 2 "s_register_operand" "r,r")
10211 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10212 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10213 (clobber (reg:CC CC_REGNUM))]
10214 "TARGET_ARM"
10215 "#"
10216 [(set_attr "conds" "clob")
10217 (set_attr "length" "8,12")
10218 (set_attr "type" "multiple")]
10219 )
10220
10221 (define_insn "*if_shift_move"
10222 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10223 (if_then_else:SI
10224 (match_operator 5 "arm_comparison_operator"
10225 [(match_operand 6 "cc_register" "") (const_int 0)])
10226 (match_operator:SI 4 "shift_operator"
10227 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10228 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10229 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10230 "TARGET_ARM"
10231 "@
10232 mov%d5\\t%0, %2%S4
10233 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10234 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10235 [(set_attr "conds" "use")
10236 (set_attr "shift" "2")
10237 (set_attr "length" "4,8,8")
10238 (set_attr_alternative "type"
10239 [(if_then_else (match_operand 3 "const_int_operand" "")
10240 (const_string "mov_shift" )
10241 (const_string "mov_shift_reg"))
10242 (const_string "multiple")
10243 (const_string "multiple")])]
10244 )
10245
10246 (define_insn "*ifcompare_move_shift"
10247 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10248 (if_then_else:SI
10249 (match_operator 6 "arm_comparison_operator"
10250 [(match_operand:SI 4 "s_register_operand" "r,r")
10251 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10252 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10253 (match_operator:SI 7 "shift_operator"
10254 [(match_operand:SI 2 "s_register_operand" "r,r")
10255 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10256 (clobber (reg:CC CC_REGNUM))]
10257 "TARGET_ARM"
10258 "#"
10259 [(set_attr "conds" "clob")
10260 (set_attr "length" "8,12")
10261 (set_attr "type" "multiple")]
10262 )
10263
10264 (define_insn "*if_move_shift"
10265 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10266 (if_then_else:SI
10267 (match_operator 5 "arm_comparison_operator"
10268 [(match_operand 6 "cc_register" "") (const_int 0)])
10269 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10270 (match_operator:SI 4 "shift_operator"
10271 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10272 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10273 "TARGET_ARM"
10274 "@
10275 mov%D5\\t%0, %2%S4
10276 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10277 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10278 [(set_attr "conds" "use")
10279 (set_attr "shift" "2")
10280 (set_attr "length" "4,8,8")
10281 (set_attr_alternative "type"
10282 [(if_then_else (match_operand 3 "const_int_operand" "")
10283 (const_string "mov_shift" )
10284 (const_string "mov_shift_reg"))
10285 (const_string "multiple")
10286 (const_string "multiple")])]
10287 )
10288
10289 (define_insn "*ifcompare_shift_shift"
10290 [(set (match_operand:SI 0 "s_register_operand" "=r")
10291 (if_then_else:SI
10292 (match_operator 7 "arm_comparison_operator"
10293 [(match_operand:SI 5 "s_register_operand" "r")
10294 (match_operand:SI 6 "arm_add_operand" "rIL")])
10295 (match_operator:SI 8 "shift_operator"
10296 [(match_operand:SI 1 "s_register_operand" "r")
10297 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10298 (match_operator:SI 9 "shift_operator"
10299 [(match_operand:SI 3 "s_register_operand" "r")
10300 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10301 (clobber (reg:CC CC_REGNUM))]
10302 "TARGET_ARM"
10303 "#"
10304 [(set_attr "conds" "clob")
10305 (set_attr "length" "12")
10306 (set_attr "type" "multiple")]
10307 )
10308
10309 (define_insn "*if_shift_shift"
10310 [(set (match_operand:SI 0 "s_register_operand" "=r")
10311 (if_then_else:SI
10312 (match_operator 5 "arm_comparison_operator"
10313 [(match_operand 8 "cc_register" "") (const_int 0)])
10314 (match_operator:SI 6 "shift_operator"
10315 [(match_operand:SI 1 "s_register_operand" "r")
10316 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10317 (match_operator:SI 7 "shift_operator"
10318 [(match_operand:SI 3 "s_register_operand" "r")
10319 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10320 "TARGET_ARM"
10321 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10322 [(set_attr "conds" "use")
10323 (set_attr "shift" "1")
10324 (set_attr "length" "8")
10325 (set (attr "type") (if_then_else
10326 (and (match_operand 2 "const_int_operand" "")
10327 (match_operand 4 "const_int_operand" ""))
10328 (const_string "mov_shift")
10329 (const_string "mov_shift_reg")))]
10330 )
10331
10332 (define_insn "*ifcompare_not_arith"
10333 [(set (match_operand:SI 0 "s_register_operand" "=r")
10334 (if_then_else:SI
10335 (match_operator 6 "arm_comparison_operator"
10336 [(match_operand:SI 4 "s_register_operand" "r")
10337 (match_operand:SI 5 "arm_add_operand" "rIL")])
10338 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10339 (match_operator:SI 7 "shiftable_operator"
10340 [(match_operand:SI 2 "s_register_operand" "r")
10341 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10342 (clobber (reg:CC CC_REGNUM))]
10343 "TARGET_ARM"
10344 "#"
10345 [(set_attr "conds" "clob")
10346 (set_attr "length" "12")
10347 (set_attr "type" "multiple")]
10348 )
10349
10350 (define_insn "*if_not_arith"
10351 [(set (match_operand:SI 0 "s_register_operand" "=r")
10352 (if_then_else:SI
10353 (match_operator 5 "arm_comparison_operator"
10354 [(match_operand 4 "cc_register" "") (const_int 0)])
10355 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10356 (match_operator:SI 6 "shiftable_operator"
10357 [(match_operand:SI 2 "s_register_operand" "r")
10358 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10359 "TARGET_ARM"
10360 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10361 [(set_attr "conds" "use")
10362 (set_attr "type" "mvn_reg")
10363 (set_attr "length" "8")]
10364 )
10365
10366 (define_insn "*ifcompare_arith_not"
10367 [(set (match_operand:SI 0 "s_register_operand" "=r")
10368 (if_then_else:SI
10369 (match_operator 6 "arm_comparison_operator"
10370 [(match_operand:SI 4 "s_register_operand" "r")
10371 (match_operand:SI 5 "arm_add_operand" "rIL")])
10372 (match_operator:SI 7 "shiftable_operator"
10373 [(match_operand:SI 2 "s_register_operand" "r")
10374 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10375 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10376 (clobber (reg:CC CC_REGNUM))]
10377 "TARGET_ARM"
10378 "#"
10379 [(set_attr "conds" "clob")
10380 (set_attr "length" "12")
10381 (set_attr "type" "multiple")]
10382 )
10383
10384 (define_insn "*if_arith_not"
10385 [(set (match_operand:SI 0 "s_register_operand" "=r")
10386 (if_then_else:SI
10387 (match_operator 5 "arm_comparison_operator"
10388 [(match_operand 4 "cc_register" "") (const_int 0)])
10389 (match_operator:SI 6 "shiftable_operator"
10390 [(match_operand:SI 2 "s_register_operand" "r")
10391 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10392 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10393 "TARGET_ARM"
10394 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10395 [(set_attr "conds" "use")
10396 (set_attr "type" "multiple")
10397 (set_attr "length" "8")]
10398 )
10399
10400 (define_insn "*ifcompare_neg_move"
10401 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10402 (if_then_else:SI
10403 (match_operator 5 "arm_comparison_operator"
10404 [(match_operand:SI 3 "s_register_operand" "r,r")
10405 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10406 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10407 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10408 (clobber (reg:CC CC_REGNUM))]
10409 "TARGET_ARM"
10410 "#"
10411 [(set_attr "conds" "clob")
10412 (set_attr "length" "8,12")
10413 (set_attr "type" "multiple")]
10414 )
10415
10416 (define_insn_and_split "*if_neg_move"
10417 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10418 (if_then_else:SI
10419 (match_operator 4 "arm_comparison_operator"
10420 [(match_operand 3 "cc_register" "") (const_int 0)])
10421 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10422 (match_operand:SI 1 "s_register_operand" "0,0")))]
10423 "TARGET_32BIT"
10424 "#"
10425 "&& reload_completed"
10426 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10427 (set (match_dup 0) (neg:SI (match_dup 2))))]
10428 ""
10429 [(set_attr "conds" "use")
10430 (set_attr "length" "4")
10431 (set_attr "arch" "t2,32")
10432 (set_attr "enabled_for_depr_it" "yes,no")
10433 (set_attr "type" "logic_shift_imm")]
10434 )
10435
10436 (define_insn "*ifcompare_move_neg"
10437 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10438 (if_then_else:SI
10439 (match_operator 5 "arm_comparison_operator"
10440 [(match_operand:SI 3 "s_register_operand" "r,r")
10441 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10442 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10443 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10444 (clobber (reg:CC CC_REGNUM))]
10445 "TARGET_ARM"
10446 "#"
10447 [(set_attr "conds" "clob")
10448 (set_attr "length" "8,12")
10449 (set_attr "type" "multiple")]
10450 )
10451
10452 (define_insn_and_split "*if_move_neg"
10453 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10454 (if_then_else:SI
10455 (match_operator 4 "arm_comparison_operator"
10456 [(match_operand 3 "cc_register" "") (const_int 0)])
10457 (match_operand:SI 1 "s_register_operand" "0,0")
10458 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10459 "TARGET_32BIT"
10460 "#"
10461 "&& reload_completed"
10462 [(cond_exec (match_dup 5)
10463 (set (match_dup 0) (neg:SI (match_dup 2))))]
10464 {
10465 machine_mode mode = GET_MODE (operands[3]);
10466 rtx_code rc = GET_CODE (operands[4]);
10467
10468 if (mode == CCFPmode || mode == CCFPEmode)
10469 rc = reverse_condition_maybe_unordered (rc);
10470 else
10471 rc = reverse_condition (rc);
10472
10473 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10474 }
10475 [(set_attr "conds" "use")
10476 (set_attr "length" "4")
10477 (set_attr "arch" "t2,32")
10478 (set_attr "enabled_for_depr_it" "yes,no")
10479 (set_attr "type" "logic_shift_imm")]
10480 )
10481
10482 (define_insn "*arith_adjacentmem"
10483 [(set (match_operand:SI 0 "s_register_operand" "=r")
10484 (match_operator:SI 1 "shiftable_operator"
10485 [(match_operand:SI 2 "memory_operand" "m")
10486 (match_operand:SI 3 "memory_operand" "m")]))
10487 (clobber (match_scratch:SI 4 "=r"))]
10488 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10489 "*
10490 {
10491 rtx ldm[3];
10492 rtx arith[4];
10493 rtx base_reg;
10494 HOST_WIDE_INT val1 = 0, val2 = 0;
10495
10496 if (REGNO (operands[0]) > REGNO (operands[4]))
10497 {
10498 ldm[1] = operands[4];
10499 ldm[2] = operands[0];
10500 }
10501 else
10502 {
10503 ldm[1] = operands[0];
10504 ldm[2] = operands[4];
10505 }
10506
10507 base_reg = XEXP (operands[2], 0);
10508
10509 if (!REG_P (base_reg))
10510 {
10511 val1 = INTVAL (XEXP (base_reg, 1));
10512 base_reg = XEXP (base_reg, 0);
10513 }
10514
10515 if (!REG_P (XEXP (operands[3], 0)))
10516 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10517
10518 arith[0] = operands[0];
10519 arith[3] = operands[1];
10520
10521 if (val1 < val2)
10522 {
10523 arith[1] = ldm[1];
10524 arith[2] = ldm[2];
10525 }
10526 else
10527 {
10528 arith[1] = ldm[2];
10529 arith[2] = ldm[1];
10530 }
10531
10532 ldm[0] = base_reg;
10533 if (val1 !=0 && val2 != 0)
10534 {
10535 rtx ops[3];
10536
10537 if (val1 == 4 || val2 == 4)
10538 /* Other val must be 8, since we know they are adjacent and neither
10539 is zero. */
10540 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10541 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10542 {
10543 ldm[0] = ops[0] = operands[4];
10544 ops[1] = base_reg;
10545 ops[2] = GEN_INT (val1);
10546 output_add_immediate (ops);
10547 if (val1 < val2)
10548 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10549 else
10550 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10551 }
10552 else
10553 {
10554 /* Offset is out of range for a single add, so use two ldr. */
10555 ops[0] = ldm[1];
10556 ops[1] = base_reg;
10557 ops[2] = GEN_INT (val1);
10558 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10559 ops[0] = ldm[2];
10560 ops[2] = GEN_INT (val2);
10561 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10562 }
10563 }
10564 else if (val1 != 0)
10565 {
10566 if (val1 < val2)
10567 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10568 else
10569 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10570 }
10571 else
10572 {
10573 if (val1 < val2)
10574 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10575 else
10576 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10577 }
10578 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10579 return \"\";
10580 }"
10581 [(set_attr "length" "12")
10582 (set_attr "predicable" "yes")
10583 (set_attr "type" "load1")]
10584 )
10585
10586 ; This pattern is never tried by combine, so do it as a peephole
10587
10588 (define_peephole2
10589 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10590 (match_operand:SI 1 "arm_general_register_operand" ""))
10591 (set (reg:CC CC_REGNUM)
10592 (compare:CC (match_dup 1) (const_int 0)))]
10593 "TARGET_ARM"
10594 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10595 (set (match_dup 0) (match_dup 1))])]
10596 ""
10597 )
10598
10599 (define_split
10600 [(set (match_operand:SI 0 "s_register_operand" "")
10601 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10602 (const_int 0))
10603 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10604 [(match_operand:SI 3 "s_register_operand" "")
10605 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10606 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10607 "TARGET_ARM"
10608 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10609 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10610 (match_dup 5)))]
10611 ""
10612 )
10613
10614 ;; This split can be used because CC_Z mode implies that the following
10615 ;; branch will be an equality, or an unsigned inequality, so the sign
10616 ;; extension is not needed.
10617
10618 (define_split
10619 [(set (reg:CC_Z CC_REGNUM)
10620 (compare:CC_Z
10621 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10622 (const_int 24))
10623 (match_operand 1 "const_int_operand" "")))
10624 (clobber (match_scratch:SI 2 ""))]
10625 "TARGET_ARM
10626 && ((UINTVAL (operands[1]))
10627 == ((UINTVAL (operands[1])) >> 24) << 24)"
10628 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10629 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10630 "
10631 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10632 "
10633 )
10634 ;; ??? Check the patterns above for Thumb-2 usefulness
10635
10636 (define_expand "prologue"
10637 [(clobber (const_int 0))]
10638 "TARGET_EITHER"
10639 "if (TARGET_32BIT)
10640 arm_expand_prologue ();
10641 else
10642 thumb1_expand_prologue ();
10643 DONE;
10644 "
10645 )
10646
10647 (define_expand "epilogue"
10648 [(clobber (const_int 0))]
10649 "TARGET_EITHER"
10650 "
10651 if (crtl->calls_eh_return)
10652 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10653 if (TARGET_THUMB1)
10654 {
10655 thumb1_expand_epilogue ();
10656 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10657 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10658 }
10659 else if (HAVE_return)
10660 {
10661 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10662 no need for explicit testing again. */
10663 emit_jump_insn (gen_return ());
10664 }
10665 else if (TARGET_32BIT)
10666 {
10667 arm_expand_epilogue (true);
10668 }
10669 DONE;
10670 "
10671 )
10672
10673 ;; Note - although unspec_volatile's USE all hard registers,
10674 ;; USEs are ignored after relaod has completed. Thus we need
10675 ;; to add an unspec of the link register to ensure that flow
10676 ;; does not think that it is unused by the sibcall branch that
10677 ;; will replace the standard function epilogue.
10678 (define_expand "sibcall_epilogue"
10679 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10680 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10681 "TARGET_32BIT"
10682 "
10683 arm_expand_epilogue (false);
10684 DONE;
10685 "
10686 )
10687
10688 (define_expand "eh_epilogue"
10689 [(use (match_operand:SI 0 "register_operand" ""))
10690 (use (match_operand:SI 1 "register_operand" ""))
10691 (use (match_operand:SI 2 "register_operand" ""))]
10692 "TARGET_EITHER"
10693 "
10694 {
10695 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10696 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10697 {
10698 rtx ra = gen_rtx_REG (Pmode, 2);
10699
10700 emit_move_insn (ra, operands[2]);
10701 operands[2] = ra;
10702 }
10703 /* This is a hack -- we may have crystalized the function type too
10704 early. */
10705 cfun->machine->func_type = 0;
10706 }"
10707 )
10708
10709 ;; This split is only used during output to reduce the number of patterns
10710 ;; that need assembler instructions adding to them. We allowed the setting
10711 ;; of the conditions to be implicit during rtl generation so that
10712 ;; the conditional compare patterns would work. However this conflicts to
10713 ;; some extent with the conditional data operations, so we have to split them
10714 ;; up again here.
10715
10716 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10717 ;; conditional execution sufficient?
10718
10719 (define_split
10720 [(set (match_operand:SI 0 "s_register_operand" "")
10721 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10722 [(match_operand 2 "" "") (match_operand 3 "" "")])
10723 (match_dup 0)
10724 (match_operand 4 "" "")))
10725 (clobber (reg:CC CC_REGNUM))]
10726 "TARGET_ARM && reload_completed"
10727 [(set (match_dup 5) (match_dup 6))
10728 (cond_exec (match_dup 7)
10729 (set (match_dup 0) (match_dup 4)))]
10730 "
10731 {
10732 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10733 operands[2], operands[3]);
10734 enum rtx_code rc = GET_CODE (operands[1]);
10735
10736 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10737 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10738 if (mode == CCFPmode || mode == CCFPEmode)
10739 rc = reverse_condition_maybe_unordered (rc);
10740 else
10741 rc = reverse_condition (rc);
10742
10743 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10744 }"
10745 )
10746
10747 (define_split
10748 [(set (match_operand:SI 0 "s_register_operand" "")
10749 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10750 [(match_operand 2 "" "") (match_operand 3 "" "")])
10751 (match_operand 4 "" "")
10752 (match_dup 0)))
10753 (clobber (reg:CC CC_REGNUM))]
10754 "TARGET_ARM && reload_completed"
10755 [(set (match_dup 5) (match_dup 6))
10756 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10757 (set (match_dup 0) (match_dup 4)))]
10758 "
10759 {
10760 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10761 operands[2], operands[3]);
10762
10763 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10764 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10765 }"
10766 )
10767
10768 (define_split
10769 [(set (match_operand:SI 0 "s_register_operand" "")
10770 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10771 [(match_operand 2 "" "") (match_operand 3 "" "")])
10772 (match_operand 4 "" "")
10773 (match_operand 5 "" "")))
10774 (clobber (reg:CC CC_REGNUM))]
10775 "TARGET_ARM && reload_completed"
10776 [(set (match_dup 6) (match_dup 7))
10777 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10778 (set (match_dup 0) (match_dup 4)))
10779 (cond_exec (match_dup 8)
10780 (set (match_dup 0) (match_dup 5)))]
10781 "
10782 {
10783 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10784 operands[2], operands[3]);
10785 enum rtx_code rc = GET_CODE (operands[1]);
10786
10787 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10788 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10789 if (mode == CCFPmode || mode == CCFPEmode)
10790 rc = reverse_condition_maybe_unordered (rc);
10791 else
10792 rc = reverse_condition (rc);
10793
10794 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10795 }"
10796 )
10797
10798 (define_split
10799 [(set (match_operand:SI 0 "s_register_operand" "")
10800 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10801 [(match_operand:SI 2 "s_register_operand" "")
10802 (match_operand:SI 3 "arm_add_operand" "")])
10803 (match_operand:SI 4 "arm_rhs_operand" "")
10804 (not:SI
10805 (match_operand:SI 5 "s_register_operand" ""))))
10806 (clobber (reg:CC CC_REGNUM))]
10807 "TARGET_ARM && reload_completed"
10808 [(set (match_dup 6) (match_dup 7))
10809 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10810 (set (match_dup 0) (match_dup 4)))
10811 (cond_exec (match_dup 8)
10812 (set (match_dup 0) (not:SI (match_dup 5))))]
10813 "
10814 {
10815 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10816 operands[2], operands[3]);
10817 enum rtx_code rc = GET_CODE (operands[1]);
10818
10819 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10820 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10821 if (mode == CCFPmode || mode == CCFPEmode)
10822 rc = reverse_condition_maybe_unordered (rc);
10823 else
10824 rc = reverse_condition (rc);
10825
10826 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10827 }"
10828 )
10829
10830 (define_insn "*cond_move_not"
10831 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10832 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10833 [(match_operand 3 "cc_register" "") (const_int 0)])
10834 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10835 (not:SI
10836 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10837 "TARGET_ARM"
10838 "@
10839 mvn%D4\\t%0, %2
10840 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10841 [(set_attr "conds" "use")
10842 (set_attr "type" "mvn_reg,multiple")
10843 (set_attr "length" "4,8")]
10844 )
10845
10846 ;; The next two patterns occur when an AND operation is followed by a
10847 ;; scc insn sequence
10848
10849 (define_insn "*sign_extract_onebit"
10850 [(set (match_operand:SI 0 "s_register_operand" "=r")
10851 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10852 (const_int 1)
10853 (match_operand:SI 2 "const_int_operand" "n")))
10854 (clobber (reg:CC CC_REGNUM))]
10855 "TARGET_ARM"
10856 "*
10857 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10858 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10859 return \"mvnne\\t%0, #0\";
10860 "
10861 [(set_attr "conds" "clob")
10862 (set_attr "length" "8")
10863 (set_attr "type" "multiple")]
10864 )
10865
10866 (define_insn "*not_signextract_onebit"
10867 [(set (match_operand:SI 0 "s_register_operand" "=r")
10868 (not:SI
10869 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10870 (const_int 1)
10871 (match_operand:SI 2 "const_int_operand" "n"))))
10872 (clobber (reg:CC CC_REGNUM))]
10873 "TARGET_ARM"
10874 "*
10875 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10876 output_asm_insn (\"tst\\t%1, %2\", operands);
10877 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10878 return \"movne\\t%0, #0\";
10879 "
10880 [(set_attr "conds" "clob")
10881 (set_attr "length" "12")
10882 (set_attr "type" "multiple")]
10883 )
10884 ;; ??? The above patterns need auditing for Thumb-2
10885
10886 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10887 ;; expressions. For simplicity, the first register is also in the unspec
10888 ;; part.
10889 ;; To avoid the usage of GNU extension, the length attribute is computed
10890 ;; in a C function arm_attr_length_push_multi.
10891 (define_insn "*push_multi"
10892 [(match_parallel 2 "multi_register_push"
10893 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10894 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10895 UNSPEC_PUSH_MULT))])]
10896 ""
10897 "*
10898 {
10899 int num_saves = XVECLEN (operands[2], 0);
10900
10901 /* For the StrongARM at least it is faster to
10902 use STR to store only a single register.
10903 In Thumb mode always use push, and the assembler will pick
10904 something appropriate. */
10905 if (num_saves == 1 && TARGET_ARM)
10906 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10907 else
10908 {
10909 int i;
10910 char pattern[100];
10911
10912 if (TARGET_32BIT)
10913 strcpy (pattern, \"push%?\\t{%1\");
10914 else
10915 strcpy (pattern, \"push\\t{%1\");
10916
10917 for (i = 1; i < num_saves; i++)
10918 {
10919 strcat (pattern, \", %|\");
10920 strcat (pattern,
10921 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10922 }
10923
10924 strcat (pattern, \"}\");
10925 output_asm_insn (pattern, operands);
10926 }
10927
10928 return \"\";
10929 }"
10930 [(set_attr "type" "store4")
10931 (set (attr "length")
10932 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10933 )
10934
10935 (define_insn "stack_tie"
10936 [(set (mem:BLK (scratch))
10937 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10938 (match_operand:SI 1 "s_register_operand" "rk")]
10939 UNSPEC_PRLG_STK))]
10940 ""
10941 ""
10942 [(set_attr "length" "0")
10943 (set_attr "type" "block")]
10944 )
10945
10946 ;; Pop (as used in epilogue RTL)
10947 ;;
10948 (define_insn "*load_multiple_with_writeback"
10949 [(match_parallel 0 "load_multiple_operation"
10950 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10951 (plus:SI (match_dup 1)
10952 (match_operand:SI 2 "const_int_I_operand" "I")))
10953 (set (match_operand:SI 3 "s_register_operand" "=rk")
10954 (mem:SI (match_dup 1)))
10955 ])]
10956 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10957 "*
10958 {
10959 arm_output_multireg_pop (operands, /*return_pc=*/false,
10960 /*cond=*/const_true_rtx,
10961 /*reverse=*/false,
10962 /*update=*/true);
10963 return \"\";
10964 }
10965 "
10966 [(set_attr "type" "load4")
10967 (set_attr "predicable" "yes")
10968 (set (attr "length")
10969 (symbol_ref "arm_attr_length_pop_multi (operands,
10970 /*return_pc=*/false,
10971 /*write_back_p=*/true)"))]
10972 )
10973
10974 ;; Pop with return (as used in epilogue RTL)
10975 ;;
10976 ;; This instruction is generated when the registers are popped at the end of
10977 ;; epilogue. Here, instead of popping the value into LR and then generating
10978 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10979 ;; with (return).
10980 (define_insn "*pop_multiple_with_writeback_and_return"
10981 [(match_parallel 0 "pop_multiple_return"
10982 [(return)
10983 (set (match_operand:SI 1 "s_register_operand" "+rk")
10984 (plus:SI (match_dup 1)
10985 (match_operand:SI 2 "const_int_I_operand" "I")))
10986 (set (match_operand:SI 3 "s_register_operand" "=rk")
10987 (mem:SI (match_dup 1)))
10988 ])]
10989 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10990 "*
10991 {
10992 arm_output_multireg_pop (operands, /*return_pc=*/true,
10993 /*cond=*/const_true_rtx,
10994 /*reverse=*/false,
10995 /*update=*/true);
10996 return \"\";
10997 }
10998 "
10999 [(set_attr "type" "load4")
11000 (set_attr "predicable" "yes")
11001 (set (attr "length")
11002 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11003 /*write_back_p=*/true)"))]
11004 )
11005
11006 (define_insn "*pop_multiple_with_return"
11007 [(match_parallel 0 "pop_multiple_return"
11008 [(return)
11009 (set (match_operand:SI 2 "s_register_operand" "=rk")
11010 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11011 ])]
11012 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11013 "*
11014 {
11015 arm_output_multireg_pop (operands, /*return_pc=*/true,
11016 /*cond=*/const_true_rtx,
11017 /*reverse=*/false,
11018 /*update=*/false);
11019 return \"\";
11020 }
11021 "
11022 [(set_attr "type" "load4")
11023 (set_attr "predicable" "yes")
11024 (set (attr "length")
11025 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
11026 /*write_back_p=*/false)"))]
11027 )
11028
11029 ;; Load into PC and return
11030 (define_insn "*ldr_with_return"
11031 [(return)
11032 (set (reg:SI PC_REGNUM)
11033 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
11034 "TARGET_32BIT && (reload_in_progress || reload_completed)"
11035 "ldr%?\t%|pc, [%0], #4"
11036 [(set_attr "type" "load1")
11037 (set_attr "predicable" "yes")]
11038 )
11039 ;; Pop for floating point registers (as used in epilogue RTL)
11040 (define_insn "*vfp_pop_multiple_with_writeback"
11041 [(match_parallel 0 "pop_multiple_fp"
11042 [(set (match_operand:SI 1 "s_register_operand" "+rk")
11043 (plus:SI (match_dup 1)
11044 (match_operand:SI 2 "const_int_I_operand" "I")))
11045 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
11046 (mem:DF (match_dup 1)))])]
11047 "TARGET_32BIT && TARGET_HARD_FLOAT"
11048 "*
11049 {
11050 int num_regs = XVECLEN (operands[0], 0);
11051 char pattern[100];
11052 rtx op_list[2];
11053 strcpy (pattern, \"vldm\\t\");
11054 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
11055 strcat (pattern, \"!, {\");
11056 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
11057 strcat (pattern, \"%P0\");
11058 if ((num_regs - 1) > 1)
11059 {
11060 strcat (pattern, \"-%P1\");
11061 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
11062 }
11063
11064 strcat (pattern, \"}\");
11065 output_asm_insn (pattern, op_list);
11066 return \"\";
11067 }
11068 "
11069 [(set_attr "type" "load4")
11070 (set_attr "conds" "unconditional")
11071 (set_attr "predicable" "no")]
11072 )
11073
11074 ;; Special patterns for dealing with the constant pool
11075
11076 (define_insn "align_4"
11077 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
11078 "TARGET_EITHER"
11079 "*
11080 assemble_align (32);
11081 return \"\";
11082 "
11083 [(set_attr "type" "no_insn")]
11084 )
11085
11086 (define_insn "align_8"
11087 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
11088 "TARGET_EITHER"
11089 "*
11090 assemble_align (64);
11091 return \"\";
11092 "
11093 [(set_attr "type" "no_insn")]
11094 )
11095
11096 (define_insn "consttable_end"
11097 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
11098 "TARGET_EITHER"
11099 "*
11100 making_const_table = FALSE;
11101 return \"\";
11102 "
11103 [(set_attr "type" "no_insn")]
11104 )
11105
11106 (define_insn "consttable_1"
11107 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
11108 "TARGET_EITHER"
11109 "*
11110 making_const_table = TRUE;
11111 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
11112 assemble_zeros (3);
11113 return \"\";
11114 "
11115 [(set_attr "length" "4")
11116 (set_attr "type" "no_insn")]
11117 )
11118
11119 (define_insn "consttable_2"
11120 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
11121 "TARGET_EITHER"
11122 "*
11123 {
11124 rtx x = operands[0];
11125 making_const_table = TRUE;
11126 switch (GET_MODE_CLASS (GET_MODE (x)))
11127 {
11128 case MODE_FLOAT:
11129 arm_emit_fp16_const (x);
11130 break;
11131 default:
11132 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
11133 assemble_zeros (2);
11134 break;
11135 }
11136 return \"\";
11137 }"
11138 [(set_attr "length" "4")
11139 (set_attr "type" "no_insn")]
11140 )
11141
11142 (define_insn "consttable_4"
11143 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
11144 "TARGET_EITHER"
11145 "*
11146 {
11147 rtx x = operands[0];
11148 making_const_table = TRUE;
11149 switch (GET_MODE_CLASS (GET_MODE (x)))
11150 {
11151 case MODE_FLOAT:
11152 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), GET_MODE (x),
11153 BITS_PER_WORD);
11154 break;
11155 default:
11156 /* XXX: Sometimes gcc does something really dumb and ends up with
11157 a HIGH in a constant pool entry, usually because it's trying to
11158 load into a VFP register. We know this will always be used in
11159 combination with a LO_SUM which ignores the high bits, so just
11160 strip off the HIGH. */
11161 if (GET_CODE (x) == HIGH)
11162 x = XEXP (x, 0);
11163 assemble_integer (x, 4, BITS_PER_WORD, 1);
11164 mark_symbol_refs_as_used (x);
11165 break;
11166 }
11167 return \"\";
11168 }"
11169 [(set_attr "length" "4")
11170 (set_attr "type" "no_insn")]
11171 )
11172
11173 (define_insn "consttable_8"
11174 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
11175 "TARGET_EITHER"
11176 "*
11177 {
11178 making_const_table = TRUE;
11179 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11180 {
11181 case MODE_FLOAT:
11182 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11183 GET_MODE (operands[0]), BITS_PER_WORD);
11184 break;
11185 default:
11186 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
11187 break;
11188 }
11189 return \"\";
11190 }"
11191 [(set_attr "length" "8")
11192 (set_attr "type" "no_insn")]
11193 )
11194
11195 (define_insn "consttable_16"
11196 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
11197 "TARGET_EITHER"
11198 "*
11199 {
11200 making_const_table = TRUE;
11201 switch (GET_MODE_CLASS (GET_MODE (operands[0])))
11202 {
11203 case MODE_FLOAT:
11204 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
11205 GET_MODE (operands[0]), BITS_PER_WORD);
11206 break;
11207 default:
11208 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
11209 break;
11210 }
11211 return \"\";
11212 }"
11213 [(set_attr "length" "16")
11214 (set_attr "type" "no_insn")]
11215 )
11216
11217 ;; V5 Instructions,
11218
11219 (define_insn "clzsi2"
11220 [(set (match_operand:SI 0 "s_register_operand" "=r")
11221 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11222 "TARGET_32BIT && arm_arch5"
11223 "clz%?\\t%0, %1"
11224 [(set_attr "predicable" "yes")
11225 (set_attr "predicable_short_it" "no")
11226 (set_attr "type" "clz")])
11227
11228 (define_insn "rbitsi2"
11229 [(set (match_operand:SI 0 "s_register_operand" "=r")
11230 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11231 "TARGET_32BIT && arm_arch_thumb2"
11232 "rbit%?\\t%0, %1"
11233 [(set_attr "predicable" "yes")
11234 (set_attr "predicable_short_it" "no")
11235 (set_attr "type" "clz")])
11236
11237 ;; Keep this as a CTZ expression until after reload and then split
11238 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11239 ;; to fold with any other expression.
11240
11241 (define_insn_and_split "ctzsi2"
11242 [(set (match_operand:SI 0 "s_register_operand" "=r")
11243 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11244 "TARGET_32BIT && arm_arch_thumb2"
11245 "#"
11246 "&& reload_completed"
11247 [(const_int 0)]
11248 "
11249 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11250 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11251 DONE;
11252 ")
11253
11254 ;; V5E instructions.
11255
11256 (define_insn "prefetch"
11257 [(prefetch (match_operand:SI 0 "address_operand" "p")
11258 (match_operand:SI 1 "" "")
11259 (match_operand:SI 2 "" ""))]
11260 "TARGET_32BIT && arm_arch5e"
11261 "pld\\t%a0"
11262 [(set_attr "type" "load1")]
11263 )
11264
11265 ;; General predication pattern
11266
11267 (define_cond_exec
11268 [(match_operator 0 "arm_comparison_operator"
11269 [(match_operand 1 "cc_register" "")
11270 (const_int 0)])]
11271 "TARGET_32BIT
11272 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11273 ""
11274 [(set_attr "predicated" "yes")]
11275 )
11276
11277 (define_insn "force_register_use"
11278 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11279 ""
11280 "%@ %0 needed"
11281 [(set_attr "length" "0")
11282 (set_attr "type" "no_insn")]
11283 )
11284
11285
11286 ;; Patterns for exception handling
11287
11288 (define_expand "eh_return"
11289 [(use (match_operand 0 "general_operand" ""))]
11290 "TARGET_EITHER"
11291 "
11292 {
11293 if (TARGET_32BIT)
11294 emit_insn (gen_arm_eh_return (operands[0]));
11295 else
11296 emit_insn (gen_thumb_eh_return (operands[0]));
11297 DONE;
11298 }"
11299 )
11300
11301 ;; We can't expand this before we know where the link register is stored.
11302 (define_insn_and_split "arm_eh_return"
11303 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11304 VUNSPEC_EH_RETURN)
11305 (clobber (match_scratch:SI 1 "=&r"))]
11306 "TARGET_ARM"
11307 "#"
11308 "&& reload_completed"
11309 [(const_int 0)]
11310 "
11311 {
11312 arm_set_return_address (operands[0], operands[1]);
11313 DONE;
11314 }"
11315 )
11316
11317 \f
11318 ;; TLS support
11319
11320 (define_insn "load_tp_hard"
11321 [(set (match_operand:SI 0 "register_operand" "=r")
11322 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11323 "TARGET_HARD_TP"
11324 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11325 [(set_attr "predicable" "yes")
11326 (set_attr "type" "mrs")]
11327 )
11328
11329 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11330 (define_insn "load_tp_soft"
11331 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11332 (clobber (reg:SI LR_REGNUM))
11333 (clobber (reg:SI IP_REGNUM))
11334 (clobber (reg:CC CC_REGNUM))]
11335 "TARGET_SOFT_TP"
11336 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11337 [(set_attr "conds" "clob")
11338 (set_attr "type" "branch")]
11339 )
11340
11341 ;; tls descriptor call
11342 (define_insn "tlscall"
11343 [(set (reg:SI R0_REGNUM)
11344 (unspec:SI [(reg:SI R0_REGNUM)
11345 (match_operand:SI 0 "" "X")
11346 (match_operand 1 "" "")] UNSPEC_TLS))
11347 (clobber (reg:SI R1_REGNUM))
11348 (clobber (reg:SI LR_REGNUM))
11349 (clobber (reg:SI CC_REGNUM))]
11350 "TARGET_GNU2_TLS"
11351 {
11352 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11353 INTVAL (operands[1]));
11354 return "bl\\t%c0(tlscall)";
11355 }
11356 [(set_attr "conds" "clob")
11357 (set_attr "length" "4")
11358 (set_attr "type" "branch")]
11359 )
11360
11361 ;; For thread pointer builtin
11362 (define_expand "get_thread_pointersi"
11363 [(match_operand:SI 0 "s_register_operand" "=r")]
11364 ""
11365 "
11366 {
11367 arm_load_tp (operands[0]);
11368 DONE;
11369 }")
11370
11371 ;;
11372
11373 ;; We only care about the lower 16 bits of the constant
11374 ;; being inserted into the upper 16 bits of the register.
11375 (define_insn "*arm_movtas_ze"
11376 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11377 (const_int 16)
11378 (const_int 16))
11379 (match_operand:SI 1 "const_int_operand" ""))]
11380 "TARGET_HAVE_MOVT"
11381 "@
11382 movt%?\t%0, %L1
11383 movt\t%0, %L1"
11384 [(set_attr "arch" "32,v8mb")
11385 (set_attr "predicable" "yes")
11386 (set_attr "predicable_short_it" "no")
11387 (set_attr "length" "4")
11388 (set_attr "type" "alu_sreg")]
11389 )
11390
11391 (define_insn "*arm_rev"
11392 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11393 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11394 "arm_arch6"
11395 "@
11396 rev\t%0, %1
11397 rev%?\t%0, %1
11398 rev%?\t%0, %1"
11399 [(set_attr "arch" "t1,t2,32")
11400 (set_attr "length" "2,2,4")
11401 (set_attr "predicable" "no,yes,yes")
11402 (set_attr "predicable_short_it" "no")
11403 (set_attr "type" "rev")]
11404 )
11405
11406 (define_expand "arm_legacy_rev"
11407 [(set (match_operand:SI 2 "s_register_operand" "")
11408 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "")
11409 (const_int 16))
11410 (match_dup 1)))
11411 (set (match_dup 2)
11412 (lshiftrt:SI (match_dup 2)
11413 (const_int 8)))
11414 (set (match_operand:SI 3 "s_register_operand" "")
11415 (rotatert:SI (match_dup 1)
11416 (const_int 8)))
11417 (set (match_dup 2)
11418 (and:SI (match_dup 2)
11419 (const_int -65281)))
11420 (set (match_operand:SI 0 "s_register_operand" "")
11421 (xor:SI (match_dup 3)
11422 (match_dup 2)))]
11423 "TARGET_32BIT"
11424 ""
11425 )
11426
11427 ;; Reuse temporaries to keep register pressure down.
11428 (define_expand "thumb_legacy_rev"
11429 [(set (match_operand:SI 2 "s_register_operand" "")
11430 (ashift:SI (match_operand:SI 1 "s_register_operand" "")
11431 (const_int 24)))
11432 (set (match_operand:SI 3 "s_register_operand" "")
11433 (lshiftrt:SI (match_dup 1)
11434 (const_int 24)))
11435 (set (match_dup 3)
11436 (ior:SI (match_dup 3)
11437 (match_dup 2)))
11438 (set (match_operand:SI 4 "s_register_operand" "")
11439 (const_int 16))
11440 (set (match_operand:SI 5 "s_register_operand" "")
11441 (rotatert:SI (match_dup 1)
11442 (match_dup 4)))
11443 (set (match_dup 2)
11444 (ashift:SI (match_dup 5)
11445 (const_int 24)))
11446 (set (match_dup 5)
11447 (lshiftrt:SI (match_dup 5)
11448 (const_int 24)))
11449 (set (match_dup 5)
11450 (ior:SI (match_dup 5)
11451 (match_dup 2)))
11452 (set (match_dup 5)
11453 (rotatert:SI (match_dup 5)
11454 (match_dup 4)))
11455 (set (match_operand:SI 0 "s_register_operand" "")
11456 (ior:SI (match_dup 5)
11457 (match_dup 3)))]
11458 "TARGET_THUMB"
11459 ""
11460 )
11461
11462 ;; ARM-specific expansion of signed mod by power of 2
11463 ;; using conditional negate.
11464 ;; For r0 % n where n is a power of 2 produce:
11465 ;; rsbs r1, r0, #0
11466 ;; and r0, r0, #(n - 1)
11467 ;; and r1, r1, #(n - 1)
11468 ;; rsbpl r0, r1, #0
11469
11470 (define_expand "modsi3"
11471 [(match_operand:SI 0 "register_operand" "")
11472 (match_operand:SI 1 "register_operand" "")
11473 (match_operand:SI 2 "const_int_operand" "")]
11474 "TARGET_32BIT"
11475 {
11476 HOST_WIDE_INT val = INTVAL (operands[2]);
11477
11478 if (val <= 0
11479 || exact_log2 (val) <= 0)
11480 FAIL;
11481
11482 rtx mask = GEN_INT (val - 1);
11483
11484 /* In the special case of x0 % 2 we can do the even shorter:
11485 cmp r0, #0
11486 and r0, r0, #1
11487 rsblt r0, r0, #0. */
11488
11489 if (val == 2)
11490 {
11491 rtx cc_reg = arm_gen_compare_reg (LT,
11492 operands[1], const0_rtx, NULL_RTX);
11493 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11494 rtx masked = gen_reg_rtx (SImode);
11495
11496 emit_insn (gen_andsi3 (masked, operands[1], mask));
11497 emit_move_insn (operands[0],
11498 gen_rtx_IF_THEN_ELSE (SImode, cond,
11499 gen_rtx_NEG (SImode,
11500 masked),
11501 masked));
11502 DONE;
11503 }
11504
11505 rtx neg_op = gen_reg_rtx (SImode);
11506 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11507 operands[1]));
11508
11509 /* Extract the condition register and mode. */
11510 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11511 rtx cc_reg = SET_DEST (cmp);
11512 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11513
11514 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11515
11516 rtx masked_neg = gen_reg_rtx (SImode);
11517 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11518
11519 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11520 during expand does not always work. Do an IF_THEN_ELSE instead. */
11521 emit_move_insn (operands[0],
11522 gen_rtx_IF_THEN_ELSE (SImode, cond,
11523 gen_rtx_NEG (SImode, masked_neg),
11524 operands[0]));
11525
11526
11527 DONE;
11528 }
11529 )
11530
11531 (define_expand "bswapsi2"
11532 [(set (match_operand:SI 0 "s_register_operand" "=r")
11533 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
11534 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11535 "
11536 if (!arm_arch6)
11537 {
11538 rtx op2 = gen_reg_rtx (SImode);
11539 rtx op3 = gen_reg_rtx (SImode);
11540
11541 if (TARGET_THUMB)
11542 {
11543 rtx op4 = gen_reg_rtx (SImode);
11544 rtx op5 = gen_reg_rtx (SImode);
11545
11546 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11547 op2, op3, op4, op5));
11548 }
11549 else
11550 {
11551 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11552 op2, op3));
11553 }
11554
11555 DONE;
11556 }
11557 "
11558 )
11559
11560 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11561 ;; and unsigned variants, respectively. For rev16, expose
11562 ;; byte-swapping in the lower 16 bits only.
11563 (define_insn "*arm_revsh"
11564 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11565 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11566 "arm_arch6"
11567 "@
11568 revsh\t%0, %1
11569 revsh%?\t%0, %1
11570 revsh%?\t%0, %1"
11571 [(set_attr "arch" "t1,t2,32")
11572 (set_attr "length" "2,2,4")
11573 (set_attr "type" "rev")]
11574 )
11575
11576 (define_insn "*arm_rev16"
11577 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11578 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11579 "arm_arch6"
11580 "@
11581 rev16\t%0, %1
11582 rev16%?\t%0, %1
11583 rev16%?\t%0, %1"
11584 [(set_attr "arch" "t1,t2,32")
11585 (set_attr "length" "2,2,4")
11586 (set_attr "type" "rev")]
11587 )
11588
11589 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11590 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11591 ;; each valid permutation.
11592
11593 (define_insn "arm_rev16si2"
11594 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11595 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11596 (const_int 8))
11597 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11598 (and:SI (lshiftrt:SI (match_dup 1)
11599 (const_int 8))
11600 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11601 "arm_arch6
11602 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11603 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11604 "rev16\\t%0, %1"
11605 [(set_attr "arch" "t1,t2,32")
11606 (set_attr "length" "2,2,4")
11607 (set_attr "type" "rev")]
11608 )
11609
11610 (define_insn "arm_rev16si2_alt"
11611 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11612 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11613 (const_int 8))
11614 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11615 (and:SI (ashift:SI (match_dup 1)
11616 (const_int 8))
11617 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11618 "arm_arch6
11619 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11620 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11621 "rev16\\t%0, %1"
11622 [(set_attr "arch" "t1,t2,32")
11623 (set_attr "length" "2,2,4")
11624 (set_attr "type" "rev")]
11625 )
11626
11627 (define_expand "bswaphi2"
11628 [(set (match_operand:HI 0 "s_register_operand" "=r")
11629 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))]
11630 "arm_arch6"
11631 ""
11632 )
11633
11634 ;; Patterns for LDRD/STRD in Thumb2 mode
11635
11636 (define_insn "*thumb2_ldrd"
11637 [(set (match_operand:SI 0 "s_register_operand" "=r")
11638 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11639 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11640 (set (match_operand:SI 3 "s_register_operand" "=r")
11641 (mem:SI (plus:SI (match_dup 1)
11642 (match_operand:SI 4 "const_int_operand" ""))))]
11643 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11644 && current_tune->prefer_ldrd_strd
11645 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11646 && (operands_ok_ldrd_strd (operands[0], operands[3],
11647 operands[1], INTVAL (operands[2]),
11648 false, true))"
11649 "ldrd%?\t%0, %3, [%1, %2]"
11650 [(set_attr "type" "load2")
11651 (set_attr "predicable" "yes")
11652 (set_attr "predicable_short_it" "no")])
11653
11654 (define_insn "*thumb2_ldrd_base"
11655 [(set (match_operand:SI 0 "s_register_operand" "=r")
11656 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11657 (set (match_operand:SI 2 "s_register_operand" "=r")
11658 (mem:SI (plus:SI (match_dup 1)
11659 (const_int 4))))]
11660 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11661 && current_tune->prefer_ldrd_strd
11662 && (operands_ok_ldrd_strd (operands[0], operands[2],
11663 operands[1], 0, false, true))"
11664 "ldrd%?\t%0, %2, [%1]"
11665 [(set_attr "type" "load2")
11666 (set_attr "predicable" "yes")
11667 (set_attr "predicable_short_it" "no")])
11668
11669 (define_insn "*thumb2_ldrd_base_neg"
11670 [(set (match_operand:SI 0 "s_register_operand" "=r")
11671 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11672 (const_int -4))))
11673 (set (match_operand:SI 2 "s_register_operand" "=r")
11674 (mem:SI (match_dup 1)))]
11675 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11676 && current_tune->prefer_ldrd_strd
11677 && (operands_ok_ldrd_strd (operands[0], operands[2],
11678 operands[1], -4, false, true))"
11679 "ldrd%?\t%0, %2, [%1, #-4]"
11680 [(set_attr "type" "load2")
11681 (set_attr "predicable" "yes")
11682 (set_attr "predicable_short_it" "no")])
11683
11684 (define_insn "*thumb2_strd"
11685 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11686 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11687 (match_operand:SI 2 "s_register_operand" "r"))
11688 (set (mem:SI (plus:SI (match_dup 0)
11689 (match_operand:SI 3 "const_int_operand" "")))
11690 (match_operand:SI 4 "s_register_operand" "r"))]
11691 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11692 && current_tune->prefer_ldrd_strd
11693 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11694 && (operands_ok_ldrd_strd (operands[2], operands[4],
11695 operands[0], INTVAL (operands[1]),
11696 false, false))"
11697 "strd%?\t%2, %4, [%0, %1]"
11698 [(set_attr "type" "store2")
11699 (set_attr "predicable" "yes")
11700 (set_attr "predicable_short_it" "no")])
11701
11702 (define_insn "*thumb2_strd_base"
11703 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11704 (match_operand:SI 1 "s_register_operand" "r"))
11705 (set (mem:SI (plus:SI (match_dup 0)
11706 (const_int 4)))
11707 (match_operand:SI 2 "s_register_operand" "r"))]
11708 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11709 && current_tune->prefer_ldrd_strd
11710 && (operands_ok_ldrd_strd (operands[1], operands[2],
11711 operands[0], 0, false, false))"
11712 "strd%?\t%1, %2, [%0]"
11713 [(set_attr "type" "store2")
11714 (set_attr "predicable" "yes")
11715 (set_attr "predicable_short_it" "no")])
11716
11717 (define_insn "*thumb2_strd_base_neg"
11718 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11719 (const_int -4)))
11720 (match_operand:SI 1 "s_register_operand" "r"))
11721 (set (mem:SI (match_dup 0))
11722 (match_operand:SI 2 "s_register_operand" "r"))]
11723 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11724 && current_tune->prefer_ldrd_strd
11725 && (operands_ok_ldrd_strd (operands[1], operands[2],
11726 operands[0], -4, false, false))"
11727 "strd%?\t%1, %2, [%0, #-4]"
11728 [(set_attr "type" "store2")
11729 (set_attr "predicable" "yes")
11730 (set_attr "predicable_short_it" "no")])
11731
11732 ;; ARMv8 CRC32 instructions.
11733 (define_insn "<crc_variant>"
11734 [(set (match_operand:SI 0 "s_register_operand" "=r")
11735 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11736 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11737 CRC))]
11738 "TARGET_CRC32"
11739 "<crc_variant>\\t%0, %1, %2"
11740 [(set_attr "type" "crc")
11741 (set_attr "conds" "unconditional")]
11742 )
11743
11744 ;; Load the load/store double peephole optimizations.
11745 (include "ldrdstrd.md")
11746
11747 ;; Load the load/store multiple patterns
11748 (include "ldmstm.md")
11749
11750 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11751 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11752 (define_insn "*load_multiple"
11753 [(match_parallel 0 "load_multiple_operation"
11754 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11755 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11756 ])]
11757 "TARGET_32BIT"
11758 "*
11759 {
11760 arm_output_multireg_pop (operands, /*return_pc=*/false,
11761 /*cond=*/const_true_rtx,
11762 /*reverse=*/false,
11763 /*update=*/false);
11764 return \"\";
11765 }
11766 "
11767 [(set_attr "predicable" "yes")]
11768 )
11769
11770 (define_expand "copysignsf3"
11771 [(match_operand:SF 0 "register_operand")
11772 (match_operand:SF 1 "register_operand")
11773 (match_operand:SF 2 "register_operand")]
11774 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11775 "{
11776 emit_move_insn (operands[0], operands[2]);
11777 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11778 GEN_INT (31), GEN_INT (0),
11779 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11780 DONE;
11781 }"
11782 )
11783
11784 (define_expand "copysigndf3"
11785 [(match_operand:DF 0 "register_operand")
11786 (match_operand:DF 1 "register_operand")
11787 (match_operand:DF 2 "register_operand")]
11788 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11789 "{
11790 rtx op0_low = gen_lowpart (SImode, operands[0]);
11791 rtx op0_high = gen_highpart (SImode, operands[0]);
11792 rtx op1_low = gen_lowpart (SImode, operands[1]);
11793 rtx op1_high = gen_highpart (SImode, operands[1]);
11794 rtx op2_high = gen_highpart (SImode, operands[2]);
11795
11796 rtx scratch1 = gen_reg_rtx (SImode);
11797 rtx scratch2 = gen_reg_rtx (SImode);
11798 emit_move_insn (scratch1, op2_high);
11799 emit_move_insn (scratch2, op1_high);
11800
11801 emit_insn(gen_rtx_SET(scratch1,
11802 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11803 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11804 emit_move_insn (op0_low, op1_low);
11805 emit_move_insn (op0_high, scratch2);
11806
11807 DONE;
11808 }"
11809 )
11810
11811 ;; movmisalign patterns for HImode and SImode.
11812 (define_expand "movmisalign<mode>"
11813 [(match_operand:HSI 0 "general_operand")
11814 (match_operand:HSI 1 "general_operand")]
11815 "unaligned_access"
11816 {
11817 /* This pattern is not permitted to fail during expansion: if both arguments
11818 are non-registers (e.g. memory := constant), force operand 1 into a
11819 register. */
11820 rtx (* gen_unaligned_load)(rtx, rtx);
11821 rtx tmp_dest = operands[0];
11822 if (!s_register_operand (operands[0], <MODE>mode)
11823 && !s_register_operand (operands[1], <MODE>mode))
11824 operands[1] = force_reg (<MODE>mode, operands[1]);
11825
11826 if (<MODE>mode == HImode)
11827 {
11828 gen_unaligned_load = gen_unaligned_loadhiu;
11829 tmp_dest = gen_reg_rtx (SImode);
11830 }
11831 else
11832 gen_unaligned_load = gen_unaligned_loadsi;
11833
11834 if (MEM_P (operands[1]))
11835 {
11836 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11837 if (<MODE>mode == HImode)
11838 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11839 }
11840 else
11841 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11842
11843 DONE;
11844 })
11845
11846 ;; Vector bits common to IWMMXT and Neon
11847 (include "vec-common.md")
11848 ;; Load the Intel Wireless Multimedia Extension patterns
11849 (include "iwmmxt.md")
11850 ;; Load the VFP co-processor patterns
11851 (include "vfp.md")
11852 ;; Thumb-1 patterns
11853 (include "thumb1.md")
11854 ;; Thumb-2 patterns
11855 (include "thumb2.md")
11856 ;; Neon patterns
11857 (include "neon.md")
11858 ;; Crypto patterns
11859 (include "crypto.md")
11860 ;; Synchronization Primitives
11861 (include "sync.md")
11862 ;; Fixed-point patterns
11863 (include "arm-fixed.md")