]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/arm.md
[ARM] Cleanup highpart multiply patterns
[thirdparty/gcc.git] / gcc / config / arm / arm.md
1 ;;- Machine description for ARM for GNU compiler
2 ;; Copyright (C) 1991-2019 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 (R4_REGNUM 4) ; Fifth CORE register
34 (FDPIC_REGNUM 9) ; FDPIC register
35 (IP_REGNUM 12) ; Scratch register
36 (SP_REGNUM 13) ; Stack pointer
37 (LR_REGNUM 14) ; Return address register
38 (PC_REGNUM 15) ; Program counter
39 (LAST_ARM_REGNUM 15) ;
40 (CC_REGNUM 100) ; Condition code pseudo register
41 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register
42 ]
43 )
44 ;; 3rd operand to select_dominance_cc_mode
45 (define_constants
46 [(DOM_CC_X_AND_Y 0)
47 (DOM_CC_NX_OR_Y 1)
48 (DOM_CC_X_OR_Y 2)
49 ]
50 )
51 ;; conditional compare combination
52 (define_constants
53 [(CMP_CMP 0)
54 (CMN_CMP 1)
55 (CMP_CMN 2)
56 (CMN_CMN 3)
57 (NUM_OF_COND_CMP 4)
58 ]
59 )
60
61 \f
62 ;;---------------------------------------------------------------------------
63 ;; Attributes
64
65 ;; Processor type. This is created automatically from arm-cores.def.
66 (include "arm-tune.md")
67
68 ;; Instruction classification types
69 (include "types.md")
70
71 ; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
72 ; generating ARM code. This is used to control the length of some insn
73 ; patterns that share the same RTL in both ARM and Thumb code.
74 (define_attr "is_thumb" "yes,no"
75 (const (if_then_else (symbol_ref "TARGET_THUMB")
76 (const_string "yes") (const_string "no"))))
77
78 ; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
79 (define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
80
81 ; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
82 (define_attr "is_thumb1" "yes,no"
83 (const (if_then_else (symbol_ref "TARGET_THUMB1")
84 (const_string "yes") (const_string "no"))))
85
86 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
87 ; The arm_restrict_it flag enables the "short IT" feature which
88 ; restricts IT blocks to a single 16-bit instruction.
89 ; This attribute should only be used on 16-bit Thumb-2 instructions
90 ; which may be predicated (the "predicable" attribute must be set).
91 (define_attr "predicable_short_it" "no,yes" (const_string "no"))
92
93 ; Mark an instruction as suitable for "short IT" blocks in Thumb-2.
94 ; This attribute should only be used on instructions which may emit
95 ; an IT block in their expansion which is not a short IT.
96 (define_attr "enabled_for_short_it" "no,yes" (const_string "yes"))
97
98 ;; Operand number of an input operand that is shifted. Zero if the
99 ;; given instruction does not shift one of its input operands.
100 (define_attr "shift" "" (const_int 0))
101
102 ;; [For compatibility with AArch64 in pipeline models]
103 ;; Attribute that specifies whether or not the instruction touches fp
104 ;; registers.
105 (define_attr "fp" "no,yes" (const_string "no"))
106
107 ; Floating Point Unit. If we only have floating point emulation, then there
108 ; is no point in scheduling the floating point insns. (Well, for best
109 ; performance we should try and group them together).
110 (define_attr "fpu" "none,vfp"
111 (const (symbol_ref "arm_fpu_attr")))
112
113 ; Predicated means that the insn form is conditionally executed based on a
114 ; predicate. We default to 'no' because no Thumb patterns match this rule
115 ; and not all ARM insns do.
116 (define_attr "predicated" "yes,no" (const_string "no"))
117
118 ; LENGTH of an instruction (in bytes)
119 (define_attr "length" ""
120 (const_int 4))
121
122 ; The architecture which supports the instruction (or alternative).
123 ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
124 ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6"
125 ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
126 ; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M
127 ; Baseline. This attribute is used to compute attribute "enabled",
128 ; use type "any" to enable an alternative in all cases.
129 (define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
130 (const_string "any"))
131
132 (define_attr "arch_enabled" "no,yes"
133 (cond [(eq_attr "arch" "any")
134 (const_string "yes")
135
136 (and (eq_attr "arch" "a")
137 (match_test "TARGET_ARM"))
138 (const_string "yes")
139
140 (and (eq_attr "arch" "t")
141 (match_test "TARGET_THUMB"))
142 (const_string "yes")
143
144 (and (eq_attr "arch" "t1")
145 (match_test "TARGET_THUMB1"))
146 (const_string "yes")
147
148 (and (eq_attr "arch" "t2")
149 (match_test "TARGET_THUMB2"))
150 (const_string "yes")
151
152 (and (eq_attr "arch" "32")
153 (match_test "TARGET_32BIT"))
154 (const_string "yes")
155
156 (and (eq_attr "arch" "v6")
157 (match_test "TARGET_32BIT && arm_arch6"))
158 (const_string "yes")
159
160 (and (eq_attr "arch" "nov6")
161 (match_test "TARGET_32BIT && !arm_arch6"))
162 (const_string "yes")
163
164 (and (eq_attr "arch" "v6t2")
165 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2"))
166 (const_string "yes")
167
168 (and (eq_attr "arch" "v8mb")
169 (match_test "TARGET_THUMB1 && arm_arch8"))
170 (const_string "yes")
171
172 (and (eq_attr "arch" "iwmmxt2")
173 (match_test "TARGET_REALLY_IWMMXT2"))
174 (const_string "yes")
175
176 (and (eq_attr "arch" "armv6_or_vfpv3")
177 (match_test "arm_arch6 || TARGET_VFP3"))
178 (const_string "yes")
179
180 (and (eq_attr "arch" "neon")
181 (match_test "TARGET_NEON"))
182 (const_string "yes")
183 ]
184
185 (const_string "no")))
186
187 (define_attr "opt" "any,speed,size"
188 (const_string "any"))
189
190 (define_attr "opt_enabled" "no,yes"
191 (cond [(eq_attr "opt" "any")
192 (const_string "yes")
193
194 (and (eq_attr "opt" "speed")
195 (match_test "optimize_function_for_speed_p (cfun)"))
196 (const_string "yes")
197
198 (and (eq_attr "opt" "size")
199 (match_test "optimize_function_for_size_p (cfun)"))
200 (const_string "yes")]
201 (const_string "no")))
202
203 (define_attr "use_literal_pool" "no,yes"
204 (cond [(and (eq_attr "type" "f_loads,f_loadd")
205 (match_test "CONSTANT_P (operands[1])"))
206 (const_string "yes")]
207 (const_string "no")))
208
209 ; Enable all alternatives that are both arch_enabled and insn_enabled.
210 ; FIXME:: opt_enabled has been temporarily removed till the time we have
211 ; an attribute that allows the use of such alternatives.
212 ; This depends on caching of speed_p, size_p on a per
213 ; alternative basis. The problem is that the enabled attribute
214 ; cannot depend on any state that is not cached or is not constant
215 ; for a compilation unit. We probably need a generic "hot/cold"
216 ; alternative which if implemented can help with this. We disable this
217 ; until such a time as this is implemented and / or the improvements or
218 ; regressions with removing this attribute are double checked.
219 ; See ashldi3_neon and <shift>di3_neon in neon.md.
220
221 (define_attr "enabled" "no,yes"
222 (cond [(and (eq_attr "predicable_short_it" "no")
223 (and (eq_attr "predicated" "yes")
224 (match_test "arm_restrict_it")))
225 (const_string "no")
226
227 (and (eq_attr "enabled_for_short_it" "no")
228 (match_test "arm_restrict_it"))
229 (const_string "no")
230
231 (eq_attr "arch_enabled" "no")
232 (const_string "no")]
233 (const_string "yes")))
234
235 ; POOL_RANGE is how far away from a constant pool entry that this insn
236 ; can be placed. If the distance is zero, then this insn will never
237 ; reference the pool.
238 ; Note that for Thumb constant pools the PC value is rounded down to the
239 ; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for
240 ; Thumb insns) should be set to <max_range> - 2.
241 ; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry
242 ; before its address. It is set to <max_range> - (8 + <data_size>).
243 (define_attr "arm_pool_range" "" (const_int 0))
244 (define_attr "thumb2_pool_range" "" (const_int 0))
245 (define_attr "arm_neg_pool_range" "" (const_int 0))
246 (define_attr "thumb2_neg_pool_range" "" (const_int 0))
247
248 (define_attr "pool_range" ""
249 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")]
250 (attr "arm_pool_range")))
251 (define_attr "neg_pool_range" ""
252 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")]
253 (attr "arm_neg_pool_range")))
254
255 ; An assembler sequence may clobber the condition codes without us knowing.
256 ; If such an insn references the pool, then we have no way of knowing how,
257 ; so use the most conservative value for pool_range.
258 (define_asm_attributes
259 [(set_attr "conds" "clob")
260 (set_attr "length" "4")
261 (set_attr "pool_range" "250")])
262
263 ; Load scheduling, set from the arm_ld_sched variable
264 ; initialized by arm_option_override()
265 (define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
266
267 ; condition codes: this one is used by final_prescan_insn to speed up
268 ; conditionalizing instructions. It saves having to scan the rtl to see if
269 ; it uses or alters the condition codes.
270 ;
271 ; USE means that the condition codes are used by the insn in the process of
272 ; outputting code, this means (at present) that we can't use the insn in
273 ; inlined branches
274 ;
275 ; SET means that the purpose of the insn is to set the condition codes in a
276 ; well defined manner.
277 ;
278 ; CLOB means that the condition codes are altered in an undefined manner, if
279 ; they are altered at all
280 ;
281 ; UNCONDITIONAL means the instruction cannot be conditionally executed and
282 ; that the instruction does not use or alter the condition codes.
283 ;
284 ; NOCOND means that the instruction does not use or alter the condition
285 ; codes but can be converted into a conditionally exectuted instruction.
286
287 (define_attr "conds" "use,set,clob,unconditional,nocond"
288 (if_then_else
289 (ior (eq_attr "is_thumb1" "yes")
290 (eq_attr "type" "call"))
291 (const_string "clob")
292 (if_then_else (eq_attr "is_neon_type" "no")
293 (const_string "nocond")
294 (const_string "unconditional"))))
295
296 ; Predicable means that the insn can be conditionally executed based on
297 ; an automatically added predicate (additional patterns are generated by
298 ; gen...). We default to 'no' because no Thumb patterns match this rule
299 ; and not all ARM patterns do.
300 (define_attr "predicable" "no,yes" (const_string "no"))
301
302 ; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
303 ; have one. Later ones, such as StrongARM, have write-back caches, so don't
304 ; suffer blockages enough to warrant modelling this (and it can adversely
305 ; affect the schedule).
306 (define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf")))
307
308 ; WRITE_CONFLICT implies that a read following an unrelated write is likely
309 ; to stall the processor. Used with model_wbuf above.
310 (define_attr "write_conflict" "no,yes"
311 (if_then_else (eq_attr "type"
312 "block,call,load_4")
313 (const_string "yes")
314 (const_string "no")))
315
316 ; Classify the insns into those that take one cycle and those that take more
317 ; than one on the main cpu execution unit.
318 (define_attr "core_cycles" "single,multi"
319 (if_then_else (eq_attr "type"
320 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\
321 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\
322 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
323 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
324 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
325 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
326 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
327 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
328 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\
329 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\
330 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\
331 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\
332 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\
333 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\
334 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\
335 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge")
336 (const_string "single")
337 (const_string "multi")))
338
339 ;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a
340 ;; distant label. Only applicable to Thumb code.
341 (define_attr "far_jump" "yes,no" (const_string "no"))
342
343
344 ;; The number of machine instructions this pattern expands to.
345 ;; Used for Thumb-2 conditional execution.
346 (define_attr "ce_count" "" (const_int 1))
347
348 ;;---------------------------------------------------------------------------
349 ;; Unspecs
350
351 (include "unspecs.md")
352
353 ;;---------------------------------------------------------------------------
354 ;; Mode iterators
355
356 (include "iterators.md")
357
358 ;;---------------------------------------------------------------------------
359 ;; Predicates
360
361 (include "predicates.md")
362 (include "constraints.md")
363
364 ;;---------------------------------------------------------------------------
365 ;; Pipeline descriptions
366
367 (define_attr "tune_cortexr4" "yes,no"
368 (const (if_then_else
369 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5")
370 (const_string "yes")
371 (const_string "no"))))
372
373 ;; True if the generic scheduling description should be used.
374
375 (define_attr "generic_sched" "yes,no"
376 (const (if_then_else
377 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\
378 arm926ejs,arm10e,arm1026ejs,arm1136js,\
379 arm1136jfs,cortexa5,cortexa7,cortexa8,\
380 cortexa9,cortexa12,cortexa15,cortexa17,\
381 cortexa53,cortexa57,cortexm4,cortexm7,\
382 exynosm1,marvell_pj4,xgene1")
383 (eq_attr "tune_cortexr4" "yes"))
384 (const_string "no")
385 (const_string "yes"))))
386
387 (define_attr "generic_vfp" "yes,no"
388 (const (if_then_else
389 (and (eq_attr "fpu" "vfp")
390 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\
391 cortexa8,cortexa9,cortexa53,cortexm4,\
392 cortexm7,marvell_pj4,xgene1")
393 (eq_attr "tune_cortexr4" "no"))
394 (const_string "yes")
395 (const_string "no"))))
396
397 (include "marvell-f-iwmmxt.md")
398 (include "arm-generic.md")
399 (include "arm926ejs.md")
400 (include "arm1020e.md")
401 (include "arm1026ejs.md")
402 (include "arm1136jfs.md")
403 (include "fa526.md")
404 (include "fa606te.md")
405 (include "fa626te.md")
406 (include "fmp626.md")
407 (include "fa726te.md")
408 (include "cortex-a5.md")
409 (include "cortex-a7.md")
410 (include "cortex-a8.md")
411 (include "cortex-a9.md")
412 (include "cortex-a15.md")
413 (include "cortex-a17.md")
414 (include "cortex-a53.md")
415 (include "cortex-a57.md")
416 (include "cortex-r4.md")
417 (include "cortex-r4f.md")
418 (include "cortex-m7.md")
419 (include "cortex-m4.md")
420 (include "cortex-m4-fpu.md")
421 (include "exynos-m1.md")
422 (include "vfp11.md")
423 (include "marvell-pj4.md")
424 (include "xgene1.md")
425
426 \f
427 ;;---------------------------------------------------------------------------
428 ;; Insn patterns
429 ;;
430 ;; Addition insns.
431
432 ;; Note: For DImode insns, there is normally no reason why operands should
433 ;; not be in the same register, what we don't want is for something being
434 ;; written to partially overlap something that is an input.
435
436 (define_expand "adddi3"
437 [(parallel
438 [(set (match_operand:DI 0 "s_register_operand")
439 (plus:DI (match_operand:DI 1 "s_register_operand")
440 (match_operand:DI 2 "arm_adddi_operand")))
441 (clobber (reg:CC CC_REGNUM))])]
442 "TARGET_EITHER"
443 "
444 if (TARGET_THUMB1 && !REG_P (operands[2]))
445 operands[2] = force_reg (DImode, operands[2]);
446 "
447 )
448
449 (define_insn_and_split "*arm_adddi3"
450 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r")
451 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r")
452 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd")))
453 (clobber (reg:CC CC_REGNUM))]
454 "TARGET_32BIT"
455 "#"
456 "TARGET_32BIT"
457 [(parallel [(set (reg:CC_C CC_REGNUM)
458 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
459 (match_dup 1)))
460 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
461 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
462 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
463 "
464 {
465 operands[3] = gen_highpart (SImode, operands[0]);
466 operands[0] = gen_lowpart (SImode, operands[0]);
467 operands[4] = gen_highpart (SImode, operands[1]);
468 operands[1] = gen_lowpart (SImode, operands[1]);
469 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
470 operands[2] = gen_lowpart (SImode, operands[2]);
471 }"
472 [(set_attr "conds" "clob")
473 (set_attr "length" "8")
474 (set_attr "type" "multiple")]
475 )
476
477 (define_insn_and_split "*adddi_sesidi_di"
478 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
479 (plus:DI (sign_extend:DI
480 (match_operand:SI 2 "s_register_operand" "r,r"))
481 (match_operand:DI 1 "s_register_operand" "0,r")))
482 (clobber (reg:CC CC_REGNUM))]
483 "TARGET_32BIT"
484 "#"
485 "TARGET_32BIT && reload_completed"
486 [(parallel [(set (reg:CC_C CC_REGNUM)
487 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
488 (match_dup 1)))
489 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
490 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2)
491 (const_int 31))
492 (match_dup 4))
493 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
494 "
495 {
496 operands[3] = gen_highpart (SImode, operands[0]);
497 operands[0] = gen_lowpart (SImode, operands[0]);
498 operands[4] = gen_highpart (SImode, operands[1]);
499 operands[1] = gen_lowpart (SImode, operands[1]);
500 operands[2] = gen_lowpart (SImode, operands[2]);
501 }"
502 [(set_attr "conds" "clob")
503 (set_attr "length" "8")
504 (set_attr "type" "multiple")]
505 )
506
507 (define_insn_and_split "*adddi_zesidi_di"
508 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
509 (plus:DI (zero_extend:DI
510 (match_operand:SI 2 "s_register_operand" "r,r"))
511 (match_operand:DI 1 "s_register_operand" "0,r")))
512 (clobber (reg:CC CC_REGNUM))]
513 "TARGET_32BIT"
514 "#"
515 "TARGET_32BIT && reload_completed"
516 [(parallel [(set (reg:CC_C CC_REGNUM)
517 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
518 (match_dup 1)))
519 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
520 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0))
521 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
522 "
523 {
524 operands[3] = gen_highpart (SImode, operands[0]);
525 operands[0] = gen_lowpart (SImode, operands[0]);
526 operands[4] = gen_highpart (SImode, operands[1]);
527 operands[1] = gen_lowpart (SImode, operands[1]);
528 operands[2] = gen_lowpart (SImode, operands[2]);
529 }"
530 [(set_attr "conds" "clob")
531 (set_attr "length" "8")
532 (set_attr "type" "multiple")]
533 )
534
535 (define_expand "addv<mode>4"
536 [(match_operand:SIDI 0 "register_operand")
537 (match_operand:SIDI 1 "register_operand")
538 (match_operand:SIDI 2 "register_operand")
539 (match_operand 3 "")]
540 "TARGET_32BIT"
541 {
542 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2]));
543 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
544
545 DONE;
546 })
547
548 (define_expand "uaddv<mode>4"
549 [(match_operand:SIDI 0 "register_operand")
550 (match_operand:SIDI 1 "register_operand")
551 (match_operand:SIDI 2 "register_operand")
552 (match_operand 3 "")]
553 "TARGET_32BIT"
554 {
555 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2]));
556 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]);
557
558 DONE;
559 })
560
561 (define_expand "addsi3"
562 [(set (match_operand:SI 0 "s_register_operand")
563 (plus:SI (match_operand:SI 1 "s_register_operand")
564 (match_operand:SI 2 "reg_or_int_operand")))]
565 "TARGET_EITHER"
566 "
567 if (TARGET_32BIT && CONST_INT_P (operands[2]))
568 {
569 arm_split_constant (PLUS, SImode, NULL_RTX,
570 INTVAL (operands[2]), operands[0], operands[1],
571 optimize && can_create_pseudo_p ());
572 DONE;
573 }
574 "
575 )
576
577 ; If there is a scratch available, this will be faster than synthesizing the
578 ; addition.
579 (define_peephole2
580 [(match_scratch:SI 3 "r")
581 (set (match_operand:SI 0 "arm_general_register_operand" "")
582 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
583 (match_operand:SI 2 "const_int_operand" "")))]
584 "TARGET_32BIT &&
585 !(const_ok_for_arm (INTVAL (operands[2]))
586 || const_ok_for_arm (-INTVAL (operands[2])))
587 && const_ok_for_arm (~INTVAL (operands[2]))"
588 [(set (match_dup 3) (match_dup 2))
589 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]
590 ""
591 )
592
593 ;; The r/r/k alternative is required when reloading the address
594 ;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will
595 ;; put the duplicated register first, and not try the commutative version.
596 (define_insn_and_split "*arm_addsi3"
597 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r")
598 (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")
599 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))]
600 "TARGET_32BIT"
601 "@
602 add%?\\t%0, %0, %2
603 add%?\\t%0, %1, %2
604 add%?\\t%0, %1, %2
605 add%?\\t%0, %1, %2
606 add%?\\t%0, %1, %2
607 add%?\\t%0, %1, %2
608 add%?\\t%0, %2, %1
609 add%?\\t%0, %1, %2
610 addw%?\\t%0, %1, %2
611 addw%?\\t%0, %1, %2
612 sub%?\\t%0, %1, #%n2
613 sub%?\\t%0, %1, #%n2
614 sub%?\\t%0, %1, #%n2
615 subw%?\\t%0, %1, #%n2
616 subw%?\\t%0, %1, #%n2
617 #"
618 "TARGET_32BIT
619 && CONST_INT_P (operands[2])
620 && !const_ok_for_op (INTVAL (operands[2]), PLUS)
621 && (reload_completed || !arm_eliminable_register (operands[1]))"
622 [(clobber (const_int 0))]
623 "
624 arm_split_constant (PLUS, SImode, curr_insn,
625 INTVAL (operands[2]), operands[0],
626 operands[1], 0);
627 DONE;
628 "
629 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16")
630 (set_attr "predicable" "yes")
631 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no")
632 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*")
633 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
634 (const_string "alu_imm")
635 (const_string "alu_sreg")))
636 ]
637 )
638
639 (define_insn_and_split "adddi3_compareV"
640 [(set (reg:CC_V CC_REGNUM)
641 (ne:CC_V
642 (plus:TI
643 (sign_extend:TI (match_operand:DI 1 "register_operand" "r"))
644 (sign_extend:TI (match_operand:DI 2 "register_operand" "r")))
645 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
646 (set (match_operand:DI 0 "register_operand" "=&r")
647 (plus:DI (match_dup 1) (match_dup 2)))]
648 "TARGET_32BIT"
649 "#"
650 "&& reload_completed"
651 [(parallel [(set (reg:CC_C CC_REGNUM)
652 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
653 (match_dup 1)))
654 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
655 (parallel [(set (reg:CC_V CC_REGNUM)
656 (ne:CC_V
657 (plus:DI (plus:DI
658 (sign_extend:DI (match_dup 4))
659 (sign_extend:DI (match_dup 5)))
660 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
661 (plus:DI (sign_extend:DI
662 (plus:SI (match_dup 4) (match_dup 5)))
663 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
664 (set (match_dup 3) (plus:SI (plus:SI
665 (match_dup 4) (match_dup 5))
666 (ltu:SI (reg:CC_C CC_REGNUM)
667 (const_int 0))))])]
668 "
669 {
670 operands[3] = gen_highpart (SImode, operands[0]);
671 operands[0] = gen_lowpart (SImode, operands[0]);
672 operands[4] = gen_highpart (SImode, operands[1]);
673 operands[1] = gen_lowpart (SImode, operands[1]);
674 operands[5] = gen_highpart (SImode, operands[2]);
675 operands[2] = gen_lowpart (SImode, operands[2]);
676 }"
677 [(set_attr "conds" "set")
678 (set_attr "length" "8")
679 (set_attr "type" "multiple")]
680 )
681
682 (define_insn "addsi3_compareV"
683 [(set (reg:CC_V CC_REGNUM)
684 (ne:CC_V
685 (plus:DI
686 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
687 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
688 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2)))))
689 (set (match_operand:SI 0 "register_operand" "=r")
690 (plus:SI (match_dup 1) (match_dup 2)))]
691 "TARGET_32BIT"
692 "adds%?\\t%0, %1, %2"
693 [(set_attr "conds" "set")
694 (set_attr "type" "alus_sreg")]
695 )
696
697 (define_insn "*addsi3_compareV_upper"
698 [(set (reg:CC_V CC_REGNUM)
699 (ne:CC_V
700 (plus:DI
701 (plus:DI
702 (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
703 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
704 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
705 (plus:DI (sign_extend:DI
706 (plus:SI (match_dup 1) (match_dup 2)))
707 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
708 (set (match_operand:SI 0 "register_operand" "=r")
709 (plus:SI
710 (plus:SI (match_dup 1) (match_dup 2))
711 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
712 "TARGET_32BIT"
713 "adcs%?\\t%0, %1, %2"
714 [(set_attr "conds" "set")
715 (set_attr "type" "adcs_reg")]
716 )
717
718 (define_insn_and_split "adddi3_compareC"
719 [(set (reg:CC_C CC_REGNUM)
720 (ne:CC_C
721 (plus:TI
722 (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
723 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
724 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2)))))
725 (set (match_operand:DI 0 "register_operand" "=&r")
726 (plus:DI (match_dup 1) (match_dup 2)))]
727 "TARGET_32BIT"
728 "#"
729 "&& reload_completed"
730 [(parallel [(set (reg:CC_C CC_REGNUM)
731 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2))
732 (match_dup 1)))
733 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
734 (parallel [(set (reg:CC_C CC_REGNUM)
735 (ne:CC_C
736 (plus:DI (plus:DI
737 (zero_extend:DI (match_dup 4))
738 (zero_extend:DI (match_dup 5)))
739 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
740 (plus:DI (zero_extend:DI
741 (plus:SI (match_dup 4) (match_dup 5)))
742 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
743 (set (match_dup 3) (plus:SI
744 (plus:SI (match_dup 4) (match_dup 5))
745 (ltu:SI (reg:CC_C CC_REGNUM)
746 (const_int 0))))])]
747 "
748 {
749 operands[3] = gen_highpart (SImode, operands[0]);
750 operands[0] = gen_lowpart (SImode, operands[0]);
751 operands[4] = gen_highpart (SImode, operands[1]);
752 operands[5] = gen_highpart (SImode, operands[2]);
753 operands[1] = gen_lowpart (SImode, operands[1]);
754 operands[2] = gen_lowpart (SImode, operands[2]);
755 }"
756 [(set_attr "conds" "set")
757 (set_attr "length" "8")
758 (set_attr "type" "multiple")]
759 )
760
761 (define_insn "*addsi3_compareC_upper"
762 [(set (reg:CC_C CC_REGNUM)
763 (ne:CC_C
764 (plus:DI
765 (plus:DI
766 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
767 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
768 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))
769 (plus:DI (zero_extend:DI
770 (plus:SI (match_dup 1) (match_dup 2)))
771 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0)))))
772 (set (match_operand:SI 0 "register_operand" "=r")
773 (plus:SI
774 (plus:SI (match_dup 1) (match_dup 2))
775 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
776 "TARGET_32BIT"
777 "adcs%?\\t%0, %1, %2"
778 [(set_attr "conds" "set")
779 (set_attr "type" "adcs_reg")]
780 )
781
782 (define_insn "addsi3_compareC"
783 [(set (reg:CC_C CC_REGNUM)
784 (ne:CC_C
785 (plus:DI
786 (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
787 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
788 (zero_extend:DI
789 (plus:SI (match_dup 1) (match_dup 2)))))
790 (set (match_operand:SI 0 "register_operand" "=r")
791 (plus:SI (match_dup 1) (match_dup 2)))]
792 "TARGET_32BIT"
793 "adds%?\\t%0, %1, %2"
794 [(set_attr "conds" "set")
795 (set_attr "type" "alus_sreg")]
796 )
797
798 (define_insn "addsi3_compare0"
799 [(set (reg:CC_NOOV CC_REGNUM)
800 (compare:CC_NOOV
801 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r")
802 (match_operand:SI 2 "arm_add_operand" "I,L,r"))
803 (const_int 0)))
804 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
805 (plus:SI (match_dup 1) (match_dup 2)))]
806 "TARGET_ARM"
807 "@
808 adds%?\\t%0, %1, %2
809 subs%?\\t%0, %1, #%n2
810 adds%?\\t%0, %1, %2"
811 [(set_attr "conds" "set")
812 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
813 )
814
815 (define_insn "*addsi3_compare0_scratch"
816 [(set (reg:CC_NOOV CC_REGNUM)
817 (compare:CC_NOOV
818 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r")
819 (match_operand:SI 1 "arm_add_operand" "I,L, r"))
820 (const_int 0)))]
821 "TARGET_ARM"
822 "@
823 cmn%?\\t%0, %1
824 cmp%?\\t%0, #%n1
825 cmn%?\\t%0, %1"
826 [(set_attr "conds" "set")
827 (set_attr "predicable" "yes")
828 (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
829 )
830
831 (define_insn "*compare_negsi_si"
832 [(set (reg:CC_Z CC_REGNUM)
833 (compare:CC_Z
834 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r"))
835 (match_operand:SI 1 "s_register_operand" "l,r")))]
836 "TARGET_32BIT"
837 "cmn%?\\t%1, %0"
838 [(set_attr "conds" "set")
839 (set_attr "predicable" "yes")
840 (set_attr "arch" "t2,*")
841 (set_attr "length" "2,4")
842 (set_attr "predicable_short_it" "yes,no")
843 (set_attr "type" "alus_sreg")]
844 )
845
846 ;; This is the canonicalization of subsi3_compare when the
847 ;; addend is a constant.
848 (define_insn "cmpsi2_addneg"
849 [(set (reg:CC CC_REGNUM)
850 (compare:CC
851 (match_operand:SI 1 "s_register_operand" "r,r")
852 (match_operand:SI 2 "arm_addimm_operand" "I,L")))
853 (set (match_operand:SI 0 "s_register_operand" "=r,r")
854 (plus:SI (match_dup 1)
855 (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
856 "TARGET_32BIT
857 && (INTVAL (operands[2])
858 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
859 {
860 /* For 0 and INT_MIN it is essential that we use subs, as adds will result
861 in different condition codes (like cmn rather than like cmp), so that
862 alternative comes first. Both alternatives can match for any 0x??000000
863 where except for 0 and INT_MIN it doesn't matter what we choose, and also
864 for -1 and 1 with TARGET_THUMB2, in that case prefer instruction with #1
865 as it is shorter. */
866 if (which_alternative == 0 && operands[3] != const1_rtx)
867 return "subs%?\\t%0, %1, #%n3";
868 else
869 return "adds%?\\t%0, %1, %3";
870 }
871 [(set_attr "conds" "set")
872 (set_attr "type" "alus_sreg")]
873 )
874
875 ;; Convert the sequence
876 ;; sub rd, rn, #1
877 ;; cmn rd, #1 (equivalent to cmp rd, #-1)
878 ;; bne dest
879 ;; into
880 ;; subs rd, rn, #1
881 ;; bcs dest ((unsigned)rn >= 1)
882 ;; similarly for the beq variant using bcc.
883 ;; This is a common looping idiom (while (n--))
884 (define_peephole2
885 [(set (match_operand:SI 0 "arm_general_register_operand" "")
886 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "")
887 (const_int -1)))
888 (set (match_operand 2 "cc_register" "")
889 (compare (match_dup 0) (const_int -1)))
890 (set (pc)
891 (if_then_else (match_operator 3 "equality_operator"
892 [(match_dup 2) (const_int 0)])
893 (match_operand 4 "" "")
894 (match_operand 5 "" "")))]
895 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])"
896 [(parallel[
897 (set (match_dup 2)
898 (compare:CC
899 (match_dup 1) (const_int 1)))
900 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
901 (set (pc)
902 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
903 (match_dup 4)
904 (match_dup 5)))]
905 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
906 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
907 ? GEU : LTU),
908 VOIDmode,
909 operands[2], const0_rtx);"
910 )
911
912 ;; The next four insns work because they compare the result with one of
913 ;; the operands, and we know that the use of the condition code is
914 ;; either GEU or LTU, so we can use the carry flag from the addition
915 ;; instead of doing the compare a second time.
916 (define_insn "*addsi3_compare_op1"
917 [(set (reg:CC_C CC_REGNUM)
918 (compare:CC_C
919 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
920 (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
921 (match_dup 1)))
922 (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
923 (plus:SI (match_dup 1) (match_dup 2)))]
924 "TARGET_32BIT"
925 "@
926 adds%?\\t%0, %1, %2
927 adds%?\\t%0, %0, %2
928 subs%?\\t%0, %1, #%n2
929 subs%?\\t%0, %0, #%n2
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 "arch" "t2,t2,t2,t2,*,*,*")
935 (set_attr "length" "2,2,2,2,4,4,4")
936 (set_attr "type"
937 "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
938 )
939
940 (define_insn "*addsi3_compare_op2"
941 [(set (reg:CC_C CC_REGNUM)
942 (compare:CC_C
943 (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
944 (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
945 (match_dup 2)))
946 (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
947 (plus:SI (match_dup 1) (match_dup 2)))]
948 "TARGET_32BIT"
949 "@
950 adds%?\\t%0, %1, %2
951 adds%?\\t%0, %0, %2
952 subs%?\\t%0, %1, #%n2
953 subs%?\\t%0, %0, #%n2
954 adds%?\\t%0, %1, %2
955 subs%?\\t%0, %1, #%n2
956 adds%?\\t%0, %1, %2"
957 [(set_attr "conds" "set")
958 (set_attr "arch" "t2,t2,t2,t2,*,*,*")
959 (set_attr "length" "2,2,2,2,4,4,4")
960 (set_attr "type"
961 "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
962 )
963
964 (define_insn "*compare_addsi2_op0"
965 [(set (reg:CC_C CC_REGNUM)
966 (compare:CC_C
967 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
968 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
969 (match_dup 0)))]
970 "TARGET_32BIT"
971 "@
972 cmp%?\\t%0, #%n1
973 cmn%?\\t%0, %1
974 cmn%?\\t%0, %1
975 cmp%?\\t%0, #%n1
976 cmn%?\\t%0, %1"
977 [(set_attr "conds" "set")
978 (set_attr "predicable" "yes")
979 (set_attr "arch" "t2,t2,*,*,*")
980 (set_attr "predicable_short_it" "yes,yes,no,no,no")
981 (set_attr "length" "2,2,4,4,4")
982 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
983 )
984
985 (define_insn "*compare_addsi2_op1"
986 [(set (reg:CC_C CC_REGNUM)
987 (compare:CC_C
988 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r")
989 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r"))
990 (match_dup 1)))]
991 "TARGET_32BIT"
992 "@
993 cmp%?\\t%0, #%n1
994 cmn%?\\t%0, %1
995 cmn%?\\t%0, %1
996 cmp%?\\t%0, #%n1
997 cmn%?\\t%0, %1"
998 [(set_attr "conds" "set")
999 (set_attr "predicable" "yes")
1000 (set_attr "arch" "t2,t2,*,*,*")
1001 (set_attr "predicable_short_it" "yes,yes,no,no,no")
1002 (set_attr "length" "2,2,4,4,4")
1003 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")]
1004 )
1005
1006 (define_insn "*addsi3_carryin_<optab>"
1007 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1008 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r")
1009 (match_operand:SI 2 "arm_not_operand" "0,rI,K"))
1010 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1011 "TARGET_32BIT"
1012 "@
1013 adc%?\\t%0, %1, %2
1014 adc%?\\t%0, %1, %2
1015 sbc%?\\t%0, %1, #%B2"
1016 [(set_attr "conds" "use")
1017 (set_attr "predicable" "yes")
1018 (set_attr "arch" "t2,*,*")
1019 (set_attr "length" "4")
1020 (set_attr "predicable_short_it" "yes,no,no")
1021 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1022 )
1023
1024 (define_insn "*addsi3_carryin_alt2_<optab>"
1025 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r")
1026 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
1027 (match_operand:SI 1 "s_register_operand" "%l,r,r"))
1028 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))]
1029 "TARGET_32BIT"
1030 "@
1031 adc%?\\t%0, %1, %2
1032 adc%?\\t%0, %1, %2
1033 sbc%?\\t%0, %1, #%B2"
1034 [(set_attr "conds" "use")
1035 (set_attr "predicable" "yes")
1036 (set_attr "arch" "t2,*,*")
1037 (set_attr "length" "4")
1038 (set_attr "predicable_short_it" "yes,no,no")
1039 (set_attr "type" "adc_reg,adc_reg,adc_imm")]
1040 )
1041
1042 (define_insn "*addsi3_carryin_shift_<optab>"
1043 [(set (match_operand:SI 0 "s_register_operand" "=r")
1044 (plus:SI (plus:SI
1045 (match_operator:SI 2 "shift_operator"
1046 [(match_operand:SI 3 "s_register_operand" "r")
1047 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1048 (match_operand:SI 1 "s_register_operand" "r"))
1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
1050 "TARGET_32BIT"
1051 "adc%?\\t%0, %1, %3%S2"
1052 [(set_attr "conds" "use")
1053 (set_attr "predicable" "yes")
1054 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1055 (const_string "alu_shift_imm")
1056 (const_string "alu_shift_reg")))]
1057 )
1058
1059 (define_insn "*addsi3_carryin_clobercc_<optab>"
1060 [(set (match_operand:SI 0 "s_register_operand" "=r")
1061 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r")
1062 (match_operand:SI 2 "arm_rhs_operand" "rI"))
1063 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))
1064 (clobber (reg:CC CC_REGNUM))]
1065 "TARGET_32BIT"
1066 "adcs%?\\t%0, %1, %2"
1067 [(set_attr "conds" "set")
1068 (set_attr "type" "adcs_reg")]
1069 )
1070
1071 (define_expand "subv<mode>4"
1072 [(match_operand:SIDI 0 "register_operand")
1073 (match_operand:SIDI 1 "register_operand")
1074 (match_operand:SIDI 2 "register_operand")
1075 (match_operand 3 "")]
1076 "TARGET_32BIT"
1077 {
1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1079 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
1080
1081 DONE;
1082 })
1083
1084 (define_expand "usubv<mode>4"
1085 [(match_operand:SIDI 0 "register_operand")
1086 (match_operand:SIDI 1 "register_operand")
1087 (match_operand:SIDI 2 "register_operand")
1088 (match_operand 3 "")]
1089 "TARGET_32BIT"
1090 {
1091 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1092 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
1093
1094 DONE;
1095 })
1096
1097 (define_insn_and_split "subdi3_compare1"
1098 [(set (reg:CC CC_REGNUM)
1099 (compare:CC
1100 (match_operand:DI 1 "register_operand" "r")
1101 (match_operand:DI 2 "register_operand" "r")))
1102 (set (match_operand:DI 0 "register_operand" "=&r")
1103 (minus:DI (match_dup 1) (match_dup 2)))]
1104 "TARGET_32BIT"
1105 "#"
1106 "&& reload_completed"
1107 [(parallel [(set (reg:CC CC_REGNUM)
1108 (compare:CC (match_dup 1) (match_dup 2)))
1109 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1110 (parallel [(set (reg:CC CC_REGNUM)
1111 (compare:CC (match_dup 4) (match_dup 5)))
1112 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
1113 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
1114 {
1115 operands[3] = gen_highpart (SImode, operands[0]);
1116 operands[0] = gen_lowpart (SImode, operands[0]);
1117 operands[4] = gen_highpart (SImode, operands[1]);
1118 operands[1] = gen_lowpart (SImode, operands[1]);
1119 operands[5] = gen_highpart (SImode, operands[2]);
1120 operands[2] = gen_lowpart (SImode, operands[2]);
1121 }
1122 [(set_attr "conds" "set")
1123 (set_attr "length" "8")
1124 (set_attr "type" "multiple")]
1125 )
1126
1127 (define_insn "subsi3_compare1"
1128 [(set (reg:CC CC_REGNUM)
1129 (compare:CC
1130 (match_operand:SI 1 "register_operand" "r")
1131 (match_operand:SI 2 "register_operand" "r")))
1132 (set (match_operand:SI 0 "register_operand" "=r")
1133 (minus:SI (match_dup 1) (match_dup 2)))]
1134 "TARGET_32BIT"
1135 "subs%?\\t%0, %1, %2"
1136 [(set_attr "conds" "set")
1137 (set_attr "type" "alus_sreg")]
1138 )
1139
1140 (define_insn "*subsi3_carryin"
1141 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1142 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
1143 (match_operand:SI 2 "s_register_operand" "r,r,r"))
1144 (match_operand:SI 3 "arm_borrow_operation" "")))]
1145 "TARGET_32BIT"
1146 "@
1147 sbc%?\\t%0, %1, %2
1148 rsc%?\\t%0, %2, %1
1149 sbc%?\\t%0, %2, %2, lsl #1"
1150 [(set_attr "conds" "use")
1151 (set_attr "arch" "*,a,t2")
1152 (set_attr "predicable" "yes")
1153 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")]
1154 )
1155
1156 (define_insn "*subsi3_carryin_const"
1157 [(set (match_operand:SI 0 "s_register_operand" "=r")
1158 (minus:SI (plus:SI
1159 (match_operand:SI 1 "s_register_operand" "r")
1160 (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
1161 (match_operand:SI 3 "arm_borrow_operation" "")))]
1162 "TARGET_32BIT"
1163 "sbc\\t%0, %1, #%n2"
1164 [(set_attr "conds" "use")
1165 (set_attr "type" "adc_imm")]
1166 )
1167
1168 (define_insn "*subsi3_carryin_const0"
1169 [(set (match_operand:SI 0 "s_register_operand" "=r")
1170 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
1171 (match_operand:SI 2 "arm_borrow_operation" "")))]
1172 "TARGET_32BIT"
1173 "sbc\\t%0, %1, #0"
1174 [(set_attr "conds" "use")
1175 (set_attr "type" "adc_imm")]
1176 )
1177
1178 (define_insn "*subsi3_carryin_compare"
1179 [(set (reg:CC CC_REGNUM)
1180 (compare:CC (match_operand:SI 1 "s_register_operand" "r")
1181 (match_operand:SI 2 "s_register_operand" "r")))
1182 (set (match_operand:SI 0 "s_register_operand" "=r")
1183 (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1184 (match_operand:SI 3 "arm_borrow_operation" "")))]
1185 "TARGET_32BIT"
1186 "sbcs\\t%0, %1, %2"
1187 [(set_attr "conds" "set")
1188 (set_attr "type" "adcs_reg")]
1189 )
1190
1191 (define_insn "*subsi3_carryin_compare_const"
1192 [(set (reg:CC CC_REGNUM)
1193 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1194 (match_operand:SI 2 "const_int_I_operand" "I")))
1195 (set (match_operand:SI 0 "s_register_operand" "=r")
1196 (minus:SI (plus:SI
1197 (match_dup 1)
1198 (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
1199 (match_operand:SI 4 "arm_borrow_operation" "")))]
1200 "TARGET_32BIT
1201 && (INTVAL (operands[2])
1202 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
1203 "sbcs\\t%0, %1, #%n3"
1204 [(set_attr "conds" "set")
1205 (set_attr "type" "adcs_imm")]
1206 )
1207
1208 (define_insn "*subsi3_carryin_compare_const0"
1209 [(set (reg:CC CC_REGNUM)
1210 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
1211 (const_int 0)))
1212 (set (match_operand:SI 0 "s_register_operand" "=r")
1213 (minus:SI (match_dup 1)
1214 (match_operand:SI 2 "arm_borrow_operation" "")))]
1215 "TARGET_32BIT"
1216 "sbcs\\t%0, %1, #0"
1217 [(set_attr "conds" "set")
1218 (set_attr "type" "adcs_imm")]
1219 )
1220
1221 (define_insn "*subsi3_carryin_shift"
1222 [(set (match_operand:SI 0 "s_register_operand" "=r")
1223 (minus:SI (minus:SI
1224 (match_operand:SI 1 "s_register_operand" "r")
1225 (match_operator:SI 2 "shift_operator"
1226 [(match_operand:SI 3 "s_register_operand" "r")
1227 (match_operand:SI 4 "reg_or_int_operand" "rM")]))
1228 (match_operand:SI 5 "arm_borrow_operation" "")))]
1229 "TARGET_32BIT"
1230 "sbc%?\\t%0, %1, %3%S2"
1231 [(set_attr "conds" "use")
1232 (set_attr "predicable" "yes")
1233 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1234 (const_string "alu_shift_imm")
1235 (const_string "alu_shift_reg")))]
1236 )
1237
1238 (define_insn "*rsbsi3_carryin_shift"
1239 [(set (match_operand:SI 0 "s_register_operand" "=r")
1240 (minus:SI (minus:SI
1241 (match_operator:SI 2 "shift_operator"
1242 [(match_operand:SI 3 "s_register_operand" "r")
1243 (match_operand:SI 4 "reg_or_int_operand" "rM")])
1244 (match_operand:SI 1 "s_register_operand" "r"))
1245 (match_operand:SI 5 "arm_borrow_operation" "")))]
1246 "TARGET_ARM"
1247 "rsc%?\\t%0, %1, %3%S2"
1248 [(set_attr "conds" "use")
1249 (set_attr "predicable" "yes")
1250 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
1251 (const_string "alu_shift_imm")
1252 (const_string "alu_shift_reg")))]
1253 )
1254
1255 ; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
1256 (define_split
1257 [(set (match_operand:SI 0 "s_register_operand" "")
1258 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
1259 (match_operand:SI 2 "s_register_operand" ""))
1260 (const_int -1)))
1261 (clobber (match_operand:SI 3 "s_register_operand" ""))]
1262 "TARGET_32BIT"
1263 [(set (match_dup 3) (match_dup 1))
1264 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
1265 "
1266 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
1267 ")
1268
1269 (define_expand "addsf3"
1270 [(set (match_operand:SF 0 "s_register_operand")
1271 (plus:SF (match_operand:SF 1 "s_register_operand")
1272 (match_operand:SF 2 "s_register_operand")))]
1273 "TARGET_32BIT && TARGET_HARD_FLOAT"
1274 "
1275 ")
1276
1277 (define_expand "adddf3"
1278 [(set (match_operand:DF 0 "s_register_operand")
1279 (plus:DF (match_operand:DF 1 "s_register_operand")
1280 (match_operand:DF 2 "s_register_operand")))]
1281 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1282 "
1283 ")
1284
1285 (define_expand "subdi3"
1286 [(parallel
1287 [(set (match_operand:DI 0 "s_register_operand")
1288 (minus:DI (match_operand:DI 1 "s_register_operand")
1289 (match_operand:DI 2 "s_register_operand")))
1290 (clobber (reg:CC CC_REGNUM))])]
1291 "TARGET_EITHER"
1292 "
1293 ")
1294
1295 (define_insn_and_split "*arm_subdi3"
1296 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r")
1297 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0")
1298 (match_operand:DI 2 "arm_general_register_operand" "r,0,0")))
1299 (clobber (reg:CC CC_REGNUM))]
1300 "TARGET_32BIT"
1301 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2"
1302 "TARGET_32BIT"
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 (minus:SI (match_dup 4) (match_dup 5))
1307 (ltu:SI (reg:CC 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_highpart (SImode, operands[2]);
1314 operands[2] = gen_lowpart (SImode, operands[2]);
1315 }
1316 [(set_attr "conds" "clob")
1317 (set_attr "length" "8")
1318 (set_attr "type" "multiple")]
1319 )
1320
1321 (define_insn_and_split "*subdi_di_zesidi"
1322 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1323 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1324 (zero_extend:DI
1325 (match_operand:SI 2 "s_register_operand" "r,r"))))
1326 (clobber (reg:CC CC_REGNUM))]
1327 "TARGET_32BIT"
1328 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0"
1329 "&& reload_completed"
1330 [(parallel [(set (reg:CC CC_REGNUM)
1331 (compare:CC (match_dup 1) (match_dup 2)))
1332 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1333 (set (match_dup 3) (minus:SI (match_dup 4)
1334 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1335 {
1336 operands[3] = gen_highpart (SImode, operands[0]);
1337 operands[0] = gen_lowpart (SImode, operands[0]);
1338 operands[4] = gen_highpart (SImode, operands[1]);
1339 operands[1] = gen_lowpart (SImode, operands[1]);
1340 }
1341 [(set_attr "conds" "clob")
1342 (set_attr "length" "8")
1343 (set_attr "type" "multiple")]
1344 )
1345
1346 (define_insn_and_split "*subdi_di_sesidi"
1347 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1348 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r")
1349 (sign_extend:DI
1350 (match_operand:SI 2 "s_register_operand" "r,r"))))
1351 (clobber (reg:CC CC_REGNUM))]
1352 "TARGET_32BIT"
1353 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31"
1354 "&& reload_completed"
1355 [(parallel [(set (reg:CC CC_REGNUM)
1356 (compare:CC (match_dup 1) (match_dup 2)))
1357 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1358 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
1359 (ashiftrt:SI (match_dup 2)
1360 (const_int 31)))
1361 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1362 {
1363 operands[3] = gen_highpart (SImode, operands[0]);
1364 operands[0] = gen_lowpart (SImode, operands[0]);
1365 operands[4] = gen_highpart (SImode, operands[1]);
1366 operands[1] = gen_lowpart (SImode, operands[1]);
1367 }
1368 [(set_attr "conds" "clob")
1369 (set_attr "length" "8")
1370 (set_attr "type" "multiple")]
1371 )
1372
1373 (define_insn_and_split "*subdi_zesidi_di"
1374 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1375 (minus:DI (zero_extend:DI
1376 (match_operand:SI 2 "s_register_operand" "r,r"))
1377 (match_operand:DI 1 "s_register_operand" "0,r")))
1378 (clobber (reg:CC CC_REGNUM))]
1379 "TARGET_ARM"
1380 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0"
1381 ; is equivalent to:
1382 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0"
1383 "&& reload_completed"
1384 [(parallel [(set (reg:CC CC_REGNUM)
1385 (compare:CC (match_dup 2) (match_dup 1)))
1386 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1387 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
1388 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1389 {
1390 operands[3] = gen_highpart (SImode, operands[0]);
1391 operands[0] = gen_lowpart (SImode, operands[0]);
1392 operands[4] = gen_highpart (SImode, operands[1]);
1393 operands[1] = gen_lowpart (SImode, operands[1]);
1394 }
1395 [(set_attr "conds" "clob")
1396 (set_attr "length" "8")
1397 (set_attr "type" "multiple")]
1398 )
1399
1400 (define_insn_and_split "*subdi_sesidi_di"
1401 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1402 (minus:DI (sign_extend:DI
1403 (match_operand:SI 2 "s_register_operand" "r,r"))
1404 (match_operand:DI 1 "s_register_operand" "0,r")))
1405 (clobber (reg:CC CC_REGNUM))]
1406 "TARGET_ARM"
1407 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31"
1408 ; is equivalent to:
1409 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31"
1410 "&& reload_completed"
1411 [(parallel [(set (reg:CC CC_REGNUM)
1412 (compare:CC (match_dup 2) (match_dup 1)))
1413 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
1414 (set (match_dup 3) (minus:SI (minus:SI
1415 (ashiftrt:SI (match_dup 2)
1416 (const_int 31))
1417 (match_dup 4))
1418 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1419 {
1420 operands[3] = gen_highpart (SImode, operands[0]);
1421 operands[0] = gen_lowpart (SImode, operands[0]);
1422 operands[4] = gen_highpart (SImode, operands[1]);
1423 operands[1] = gen_lowpart (SImode, operands[1]);
1424 }
1425 [(set_attr "conds" "clob")
1426 (set_attr "length" "8")
1427 (set_attr "type" "multiple")]
1428 )
1429
1430 (define_insn_and_split "*subdi_zesidi_zesidi"
1431 [(set (match_operand:DI 0 "s_register_operand" "=r")
1432 (minus:DI (zero_extend:DI
1433 (match_operand:SI 1 "s_register_operand" "r"))
1434 (zero_extend:DI
1435 (match_operand:SI 2 "s_register_operand" "r"))))
1436 (clobber (reg:CC CC_REGNUM))]
1437 "TARGET_32BIT"
1438 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1"
1439 "&& reload_completed"
1440 [(parallel [(set (reg:CC CC_REGNUM)
1441 (compare:CC (match_dup 1) (match_dup 2)))
1442 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
1443 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
1444 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
1445 {
1446 operands[3] = gen_highpart (SImode, operands[0]);
1447 operands[0] = gen_lowpart (SImode, operands[0]);
1448 }
1449 [(set_attr "conds" "clob")
1450 (set_attr "length" "8")
1451 (set_attr "type" "multiple")]
1452 )
1453
1454 (define_expand "subsi3"
1455 [(set (match_operand:SI 0 "s_register_operand")
1456 (minus:SI (match_operand:SI 1 "reg_or_int_operand")
1457 (match_operand:SI 2 "s_register_operand")))]
1458 "TARGET_EITHER"
1459 "
1460 if (CONST_INT_P (operands[1]))
1461 {
1462 if (TARGET_32BIT)
1463 {
1464 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS))
1465 operands[1] = force_reg (SImode, operands[1]);
1466 else
1467 {
1468 arm_split_constant (MINUS, SImode, NULL_RTX,
1469 INTVAL (operands[1]), operands[0],
1470 operands[2],
1471 optimize && can_create_pseudo_p ());
1472 DONE;
1473 }
1474 }
1475 else /* TARGET_THUMB1 */
1476 operands[1] = force_reg (SImode, operands[1]);
1477 }
1478 "
1479 )
1480
1481 ; ??? Check Thumb-2 split length
1482 (define_insn_and_split "*arm_subsi3_insn"
1483 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r")
1484 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n")
1485 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))]
1486 "TARGET_32BIT"
1487 "@
1488 sub%?\\t%0, %1, %2
1489 sub%?\\t%0, %2
1490 sub%?\\t%0, %1, %2
1491 rsb%?\\t%0, %2, %1
1492 rsb%?\\t%0, %2, %1
1493 sub%?\\t%0, %1, %2
1494 sub%?\\t%0, %1, %2
1495 sub%?\\t%0, %1, %2
1496 #"
1497 "&& (CONST_INT_P (operands[1])
1498 && !const_ok_for_arm (INTVAL (operands[1])))"
1499 [(clobber (const_int 0))]
1500 "
1501 arm_split_constant (MINUS, SImode, curr_insn,
1502 INTVAL (operands[1]), operands[0], operands[2], 0);
1503 DONE;
1504 "
1505 [(set_attr "length" "4,4,4,4,4,4,4,4,16")
1506 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
1507 (set_attr "predicable" "yes")
1508 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
1509 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")]
1510 )
1511
1512 (define_peephole2
1513 [(match_scratch:SI 3 "r")
1514 (set (match_operand:SI 0 "arm_general_register_operand" "")
1515 (minus:SI (match_operand:SI 1 "const_int_operand" "")
1516 (match_operand:SI 2 "arm_general_register_operand" "")))]
1517 "TARGET_32BIT
1518 && !const_ok_for_arm (INTVAL (operands[1]))
1519 && const_ok_for_arm (~INTVAL (operands[1]))"
1520 [(set (match_dup 3) (match_dup 1))
1521 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))]
1522 ""
1523 )
1524
1525 (define_insn "subsi3_compare0"
1526 [(set (reg:CC_NOOV CC_REGNUM)
1527 (compare:CC_NOOV
1528 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1529 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))
1530 (const_int 0)))
1531 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1532 (minus:SI (match_dup 1) (match_dup 2)))]
1533 "TARGET_32BIT"
1534 "@
1535 subs%?\\t%0, %1, %2
1536 subs%?\\t%0, %1, %2
1537 rsbs%?\\t%0, %2, %1"
1538 [(set_attr "conds" "set")
1539 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1540 )
1541
1542 (define_insn "subsi3_compare"
1543 [(set (reg:CC CC_REGNUM)
1544 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
1545 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")))
1546 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1547 (minus:SI (match_dup 1) (match_dup 2)))]
1548 "TARGET_32BIT"
1549 "@
1550 subs%?\\t%0, %1, %2
1551 subs%?\\t%0, %1, %2
1552 rsbs%?\\t%0, %2, %1"
1553 [(set_attr "conds" "set")
1554 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")]
1555 )
1556
1557 (define_expand "subsf3"
1558 [(set (match_operand:SF 0 "s_register_operand")
1559 (minus:SF (match_operand:SF 1 "s_register_operand")
1560 (match_operand:SF 2 "s_register_operand")))]
1561 "TARGET_32BIT && TARGET_HARD_FLOAT"
1562 "
1563 ")
1564
1565 (define_expand "subdf3"
1566 [(set (match_operand:DF 0 "s_register_operand")
1567 (minus:DF (match_operand:DF 1 "s_register_operand")
1568 (match_operand:DF 2 "s_register_operand")))]
1569 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
1570 "
1571 ")
1572
1573 \f
1574 ;; Multiplication insns
1575
1576 (define_expand "mulhi3"
1577 [(set (match_operand:HI 0 "s_register_operand")
1578 (mult:HI (match_operand:HI 1 "s_register_operand")
1579 (match_operand:HI 2 "s_register_operand")))]
1580 "TARGET_DSP_MULTIPLY"
1581 "
1582 {
1583 rtx result = gen_reg_rtx (SImode);
1584 emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
1585 emit_move_insn (operands[0], gen_lowpart (HImode, result));
1586 DONE;
1587 }"
1588 )
1589
1590 (define_expand "mulsi3"
1591 [(set (match_operand:SI 0 "s_register_operand")
1592 (mult:SI (match_operand:SI 2 "s_register_operand")
1593 (match_operand:SI 1 "s_register_operand")))]
1594 "TARGET_EITHER"
1595 ""
1596 )
1597
1598 ;; Use `&' and then `0' to prevent operands 0 and 2 being the same
1599 (define_insn "*mul"
1600 [(set (match_operand:SI 0 "s_register_operand" "=l,r,&r,&r")
1601 (mult:SI (match_operand:SI 2 "s_register_operand" "l,r,r,r")
1602 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")))]
1603 "TARGET_32BIT"
1604 "mul%?\\t%0, %2, %1"
1605 [(set_attr "type" "mul")
1606 (set_attr "predicable" "yes")
1607 (set_attr "arch" "t2,v6,nov6,nov6")
1608 (set_attr "length" "4")
1609 (set_attr "predicable_short_it" "yes,no,*,*")]
1610 )
1611
1612 ;; MLA and MLS instruction. Use operand 1 for the accumulator to prefer
1613 ;; reusing the same register.
1614
1615 (define_insn "*mla"
1616 [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&r,&r")
1617 (plus:SI
1618 (mult:SI (match_operand:SI 3 "s_register_operand" "r,r,r,r")
1619 (match_operand:SI 2 "s_register_operand" "%r,r,0,r"))
1620 (match_operand:SI 1 "s_register_operand" "r,0,r,r")))]
1621 "TARGET_32BIT"
1622 "mla%?\\t%0, %3, %2, %1"
1623 [(set_attr "type" "mla")
1624 (set_attr "predicable" "yes")
1625 (set_attr "arch" "v6,nov6,nov6,nov6")]
1626 )
1627
1628 (define_insn "*mls"
1629 [(set (match_operand:SI 0 "s_register_operand" "=r")
1630 (minus:SI
1631 (match_operand:SI 1 "s_register_operand" "r")
1632 (mult:SI (match_operand:SI 3 "s_register_operand" "r")
1633 (match_operand:SI 2 "s_register_operand" "r"))))]
1634 "TARGET_32BIT && arm_arch_thumb2"
1635 "mls%?\\t%0, %3, %2, %1"
1636 [(set_attr "type" "mla")
1637 (set_attr "predicable" "yes")]
1638 )
1639
1640 (define_insn "*mulsi3_compare0"
1641 [(set (reg:CC_NOOV CC_REGNUM)
1642 (compare:CC_NOOV (mult:SI
1643 (match_operand:SI 2 "s_register_operand" "r,r")
1644 (match_operand:SI 1 "s_register_operand" "%0,r"))
1645 (const_int 0)))
1646 (set (match_operand:SI 0 "s_register_operand" "=&r,&r")
1647 (mult:SI (match_dup 2) (match_dup 1)))]
1648 "TARGET_ARM && !arm_arch6"
1649 "muls%?\\t%0, %2, %1"
1650 [(set_attr "conds" "set")
1651 (set_attr "type" "muls")]
1652 )
1653
1654 (define_insn "*mulsi3_compare0_v6"
1655 [(set (reg:CC_NOOV CC_REGNUM)
1656 (compare:CC_NOOV (mult:SI
1657 (match_operand:SI 2 "s_register_operand" "r")
1658 (match_operand:SI 1 "s_register_operand" "r"))
1659 (const_int 0)))
1660 (set (match_operand:SI 0 "s_register_operand" "=r")
1661 (mult:SI (match_dup 2) (match_dup 1)))]
1662 "TARGET_ARM && arm_arch6 && optimize_size"
1663 "muls%?\\t%0, %2, %1"
1664 [(set_attr "conds" "set")
1665 (set_attr "type" "muls")]
1666 )
1667
1668 (define_insn "*mulsi_compare0_scratch"
1669 [(set (reg:CC_NOOV CC_REGNUM)
1670 (compare:CC_NOOV (mult:SI
1671 (match_operand:SI 2 "s_register_operand" "r,r")
1672 (match_operand:SI 1 "s_register_operand" "%0,r"))
1673 (const_int 0)))
1674 (clobber (match_scratch:SI 0 "=&r,&r"))]
1675 "TARGET_ARM && !arm_arch6"
1676 "muls%?\\t%0, %2, %1"
1677 [(set_attr "conds" "set")
1678 (set_attr "type" "muls")]
1679 )
1680
1681 (define_insn "*mulsi_compare0_scratch_v6"
1682 [(set (reg:CC_NOOV CC_REGNUM)
1683 (compare:CC_NOOV (mult:SI
1684 (match_operand:SI 2 "s_register_operand" "r")
1685 (match_operand:SI 1 "s_register_operand" "r"))
1686 (const_int 0)))
1687 (clobber (match_scratch:SI 0 "=r"))]
1688 "TARGET_ARM && arm_arch6 && optimize_size"
1689 "muls%?\\t%0, %2, %1"
1690 [(set_attr "conds" "set")
1691 (set_attr "type" "muls")]
1692 )
1693
1694 (define_insn "*mulsi3addsi_compare0"
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,r,r,r")
1699 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1700 (match_operand:SI 3 "s_register_operand" "r,r,0,0"))
1701 (const_int 0)))
1702 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
1703 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1704 (match_dup 3)))]
1705 "TARGET_ARM && arm_arch6"
1706 "mlas%?\\t%0, %2, %1, %3"
1707 [(set_attr "conds" "set")
1708 (set_attr "type" "mlas")]
1709 )
1710
1711 (define_insn "*mulsi3addsi_compare0_v6"
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")
1716 (match_operand:SI 1 "s_register_operand" "r"))
1717 (match_operand:SI 3 "s_register_operand" "r"))
1718 (const_int 0)))
1719 (set (match_operand:SI 0 "s_register_operand" "=r")
1720 (plus:SI (mult:SI (match_dup 2) (match_dup 1))
1721 (match_dup 3)))]
1722 "TARGET_ARM && arm_arch6 && optimize_size"
1723 "mlas%?\\t%0, %2, %1, %3"
1724 [(set_attr "conds" "set")
1725 (set_attr "type" "mlas")]
1726 )
1727
1728 (define_insn "*mulsi3addsi_compare0_scratch"
1729 [(set (reg:CC_NOOV CC_REGNUM)
1730 (compare:CC_NOOV
1731 (plus:SI (mult:SI
1732 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
1733 (match_operand:SI 1 "s_register_operand" "%0,r,0,r"))
1734 (match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
1735 (const_int 0)))
1736 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
1737 "TARGET_ARM && !arm_arch6"
1738 "mlas%?\\t%0, %2, %1, %3"
1739 [(set_attr "conds" "set")
1740 (set_attr "type" "mlas")]
1741 )
1742
1743 (define_insn "*mulsi3addsi_compare0_scratch_v6"
1744 [(set (reg:CC_NOOV CC_REGNUM)
1745 (compare:CC_NOOV
1746 (plus:SI (mult:SI
1747 (match_operand:SI 2 "s_register_operand" "r")
1748 (match_operand:SI 1 "s_register_operand" "r"))
1749 (match_operand:SI 3 "s_register_operand" "r"))
1750 (const_int 0)))
1751 (clobber (match_scratch:SI 0 "=r"))]
1752 "TARGET_ARM && arm_arch6 && optimize_size"
1753 "mlas%?\\t%0, %2, %1, %3"
1754 [(set_attr "conds" "set")
1755 (set_attr "type" "mlas")]
1756 )
1757
1758 (define_expand "maddsidi4"
1759 [(set (match_operand:DI 0 "s_register_operand")
1760 (plus:DI
1761 (mult:DI
1762 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1763 (sign_extend:DI (match_operand:SI 2 "s_register_operand")))
1764 (match_operand:DI 3 "s_register_operand")))]
1765 "TARGET_32BIT"
1766 "")
1767
1768 (define_insn "*mulsidi3adddi"
1769 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1770 (plus:DI
1771 (mult:DI
1772 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1773 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1774 (match_operand:DI 1 "s_register_operand" "0")))]
1775 "TARGET_32BIT && !arm_arch6"
1776 "smlal%?\\t%Q0, %R0, %3, %2"
1777 [(set_attr "type" "smlal")
1778 (set_attr "predicable" "yes")]
1779 )
1780
1781 (define_insn "*mulsidi3adddi_v6"
1782 [(set (match_operand:DI 0 "s_register_operand" "=r")
1783 (plus:DI
1784 (mult:DI
1785 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1786 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1787 (match_operand:DI 1 "s_register_operand" "0")))]
1788 "TARGET_32BIT && arm_arch6"
1789 "smlal%?\\t%Q0, %R0, %3, %2"
1790 [(set_attr "type" "smlal")
1791 (set_attr "predicable" "yes")]
1792 )
1793
1794 ;; 32x32->64 widening multiply.
1795 ;; As with mulsi3, the only difference between the v3-5 and v6+
1796 ;; versions of these patterns is the requirement that the output not
1797 ;; overlap the inputs, but that still means we have to have a named
1798 ;; expander and two different starred insns.
1799
1800 (define_expand "mulsidi3"
1801 [(set (match_operand:DI 0 "s_register_operand")
1802 (mult:DI
1803 (sign_extend:DI (match_operand:SI 1 "s_register_operand"))
1804 (sign_extend:DI (match_operand:SI 2 "s_register_operand"))))]
1805 "TARGET_32BIT"
1806 ""
1807 )
1808
1809 (define_insn "*mulsidi3_nov6"
1810 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1811 (mult:DI
1812 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1813 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1814 "TARGET_32BIT && !arm_arch6"
1815 "smull%?\\t%Q0, %R0, %1, %2"
1816 [(set_attr "type" "smull")
1817 (set_attr "predicable" "yes")]
1818 )
1819
1820 (define_insn "*mulsidi3_v6"
1821 [(set (match_operand:DI 0 "s_register_operand" "=r")
1822 (mult:DI
1823 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1824 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1825 "TARGET_32BIT && arm_arch6"
1826 "smull%?\\t%Q0, %R0, %1, %2"
1827 [(set_attr "type" "smull")
1828 (set_attr "predicable" "yes")]
1829 )
1830
1831 (define_expand "umulsidi3"
1832 [(set (match_operand:DI 0 "s_register_operand")
1833 (mult:DI
1834 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1835 (zero_extend:DI (match_operand:SI 2 "s_register_operand"))))]
1836 "TARGET_32BIT"
1837 ""
1838 )
1839
1840 (define_insn "*umulsidi3_nov6"
1841 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1842 (mult:DI
1843 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r"))
1844 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1845 "TARGET_32BIT && !arm_arch6"
1846 "umull%?\\t%Q0, %R0, %1, %2"
1847 [(set_attr "type" "umull")
1848 (set_attr "predicable" "yes")]
1849 )
1850
1851 (define_insn "*umulsidi3_v6"
1852 [(set (match_operand:DI 0 "s_register_operand" "=r")
1853 (mult:DI
1854 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r"))
1855 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))]
1856 "TARGET_32BIT && arm_arch6"
1857 "umull%?\\t%Q0, %R0, %1, %2"
1858 [(set_attr "type" "umull")
1859 (set_attr "predicable" "yes")]
1860 )
1861
1862 (define_expand "umaddsidi4"
1863 [(set (match_operand:DI 0 "s_register_operand")
1864 (plus:DI
1865 (mult:DI
1866 (zero_extend:DI (match_operand:SI 1 "s_register_operand"))
1867 (zero_extend:DI (match_operand:SI 2 "s_register_operand")))
1868 (match_operand:DI 3 "s_register_operand")))]
1869 "TARGET_32BIT"
1870 "")
1871
1872 (define_insn "*umulsidi3adddi"
1873 [(set (match_operand:DI 0 "s_register_operand" "=&r")
1874 (plus:DI
1875 (mult:DI
1876 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r"))
1877 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1878 (match_operand:DI 1 "s_register_operand" "0")))]
1879 "TARGET_32BIT && !arm_arch6"
1880 "umlal%?\\t%Q0, %R0, %3, %2"
1881 [(set_attr "type" "umlal")
1882 (set_attr "predicable" "yes")]
1883 )
1884
1885 (define_insn "*umulsidi3adddi_v6"
1886 [(set (match_operand:DI 0 "s_register_operand" "=r")
1887 (plus:DI
1888 (mult:DI
1889 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))
1890 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r")))
1891 (match_operand:DI 1 "s_register_operand" "0")))]
1892 "TARGET_32BIT && arm_arch6"
1893 "umlal%?\\t%Q0, %R0, %3, %2"
1894 [(set_attr "type" "umlal")
1895 (set_attr "predicable" "yes")]
1896 )
1897
1898 (define_expand "<US>mulsi3_highpart"
1899 [(parallel
1900 [(set (match_operand:SI 0 "s_register_operand")
1901 (truncate:SI
1902 (lshiftrt:DI
1903 (mult:DI
1904 (SE:DI (match_operand:SI 1 "s_register_operand"))
1905 (SE:DI (match_operand:SI 2 "s_register_operand")))
1906 (const_int 32))))
1907 (clobber (match_scratch:SI 3 ""))])]
1908 "TARGET_32BIT"
1909 ""
1910 )
1911
1912 (define_insn "*<US>mull_high"
1913 [(set (match_operand:SI 0 "s_register_operand" "=r,&r,&r")
1914 (truncate:SI
1915 (lshiftrt:DI
1916 (mult:DI
1917 (SE:DI (match_operand:SI 1 "s_register_operand" "%r,0,r"))
1918 (SE:DI (match_operand:SI 2 "s_register_operand" "r,r,r")))
1919 (const_int 32))))
1920 (clobber (match_scratch:SI 3 "=r,&r,&r"))]
1921 "TARGET_32BIT"
1922 "<US>mull%?\\t%3, %0, %2, %1"
1923 [(set_attr "type" "umull")
1924 (set_attr "predicable" "yes")
1925 (set_attr "arch" "v6,nov6,nov6")]
1926 )
1927
1928 (define_insn "mulhisi3"
1929 [(set (match_operand:SI 0 "s_register_operand" "=r")
1930 (mult:SI (sign_extend:SI
1931 (match_operand:HI 1 "s_register_operand" "%r"))
1932 (sign_extend:SI
1933 (match_operand:HI 2 "s_register_operand" "r"))))]
1934 "TARGET_DSP_MULTIPLY"
1935 "smulbb%?\\t%0, %1, %2"
1936 [(set_attr "type" "smulxy")
1937 (set_attr "predicable" "yes")]
1938 )
1939
1940 (define_insn "*mulhisi3tb"
1941 [(set (match_operand:SI 0 "s_register_operand" "=r")
1942 (mult:SI (ashiftrt:SI
1943 (match_operand:SI 1 "s_register_operand" "r")
1944 (const_int 16))
1945 (sign_extend:SI
1946 (match_operand:HI 2 "s_register_operand" "r"))))]
1947 "TARGET_DSP_MULTIPLY"
1948 "smultb%?\\t%0, %1, %2"
1949 [(set_attr "type" "smulxy")
1950 (set_attr "predicable" "yes")]
1951 )
1952
1953 (define_insn "*mulhisi3bt"
1954 [(set (match_operand:SI 0 "s_register_operand" "=r")
1955 (mult:SI (sign_extend:SI
1956 (match_operand:HI 1 "s_register_operand" "r"))
1957 (ashiftrt:SI
1958 (match_operand:SI 2 "s_register_operand" "r")
1959 (const_int 16))))]
1960 "TARGET_DSP_MULTIPLY"
1961 "smulbt%?\\t%0, %1, %2"
1962 [(set_attr "type" "smulxy")
1963 (set_attr "predicable" "yes")]
1964 )
1965
1966 (define_insn "*mulhisi3tt"
1967 [(set (match_operand:SI 0 "s_register_operand" "=r")
1968 (mult:SI (ashiftrt:SI
1969 (match_operand:SI 1 "s_register_operand" "r")
1970 (const_int 16))
1971 (ashiftrt:SI
1972 (match_operand:SI 2 "s_register_operand" "r")
1973 (const_int 16))))]
1974 "TARGET_DSP_MULTIPLY"
1975 "smultt%?\\t%0, %1, %2"
1976 [(set_attr "type" "smulxy")
1977 (set_attr "predicable" "yes")]
1978 )
1979
1980 (define_insn "maddhisi4"
1981 [(set (match_operand:SI 0 "s_register_operand" "=r")
1982 (plus:SI (mult:SI (sign_extend:SI
1983 (match_operand:HI 1 "s_register_operand" "r"))
1984 (sign_extend:SI
1985 (match_operand:HI 2 "s_register_operand" "r")))
1986 (match_operand:SI 3 "s_register_operand" "r")))]
1987 "TARGET_DSP_MULTIPLY"
1988 "smlabb%?\\t%0, %1, %2, %3"
1989 [(set_attr "type" "smlaxy")
1990 (set_attr "predicable" "yes")]
1991 )
1992
1993 ;; Note: there is no maddhisi4ibt because this one is canonical form
1994 (define_insn "*maddhisi4tb"
1995 [(set (match_operand:SI 0 "s_register_operand" "=r")
1996 (plus:SI (mult:SI (ashiftrt:SI
1997 (match_operand:SI 1 "s_register_operand" "r")
1998 (const_int 16))
1999 (sign_extend:SI
2000 (match_operand:HI 2 "s_register_operand" "r")))
2001 (match_operand:SI 3 "s_register_operand" "r")))]
2002 "TARGET_DSP_MULTIPLY"
2003 "smlatb%?\\t%0, %1, %2, %3"
2004 [(set_attr "type" "smlaxy")
2005 (set_attr "predicable" "yes")]
2006 )
2007
2008 (define_insn "*maddhisi4tt"
2009 [(set (match_operand:SI 0 "s_register_operand" "=r")
2010 (plus:SI (mult:SI (ashiftrt:SI
2011 (match_operand:SI 1 "s_register_operand" "r")
2012 (const_int 16))
2013 (ashiftrt:SI
2014 (match_operand:SI 2 "s_register_operand" "r")
2015 (const_int 16)))
2016 (match_operand:SI 3 "s_register_operand" "r")))]
2017 "TARGET_DSP_MULTIPLY"
2018 "smlatt%?\\t%0, %1, %2, %3"
2019 [(set_attr "type" "smlaxy")
2020 (set_attr "predicable" "yes")]
2021 )
2022
2023 (define_insn "maddhidi4"
2024 [(set (match_operand:DI 0 "s_register_operand" "=r")
2025 (plus:DI
2026 (mult:DI (sign_extend:DI
2027 (match_operand:HI 1 "s_register_operand" "r"))
2028 (sign_extend:DI
2029 (match_operand:HI 2 "s_register_operand" "r")))
2030 (match_operand:DI 3 "s_register_operand" "0")))]
2031 "TARGET_DSP_MULTIPLY"
2032 "smlalbb%?\\t%Q0, %R0, %1, %2"
2033 [(set_attr "type" "smlalxy")
2034 (set_attr "predicable" "yes")])
2035
2036 ;; Note: there is no maddhidi4ibt because this one is canonical form
2037 (define_insn "*maddhidi4tb"
2038 [(set (match_operand:DI 0 "s_register_operand" "=r")
2039 (plus:DI
2040 (mult:DI (sign_extend:DI
2041 (ashiftrt:SI
2042 (match_operand:SI 1 "s_register_operand" "r")
2043 (const_int 16)))
2044 (sign_extend:DI
2045 (match_operand:HI 2 "s_register_operand" "r")))
2046 (match_operand:DI 3 "s_register_operand" "0")))]
2047 "TARGET_DSP_MULTIPLY"
2048 "smlaltb%?\\t%Q0, %R0, %1, %2"
2049 [(set_attr "type" "smlalxy")
2050 (set_attr "predicable" "yes")])
2051
2052 (define_insn "*maddhidi4tt"
2053 [(set (match_operand:DI 0 "s_register_operand" "=r")
2054 (plus:DI
2055 (mult:DI (sign_extend:DI
2056 (ashiftrt:SI
2057 (match_operand:SI 1 "s_register_operand" "r")
2058 (const_int 16)))
2059 (sign_extend:DI
2060 (ashiftrt:SI
2061 (match_operand:SI 2 "s_register_operand" "r")
2062 (const_int 16))))
2063 (match_operand:DI 3 "s_register_operand" "0")))]
2064 "TARGET_DSP_MULTIPLY"
2065 "smlaltt%?\\t%Q0, %R0, %1, %2"
2066 [(set_attr "type" "smlalxy")
2067 (set_attr "predicable" "yes")])
2068
2069 (define_expand "mulsf3"
2070 [(set (match_operand:SF 0 "s_register_operand")
2071 (mult:SF (match_operand:SF 1 "s_register_operand")
2072 (match_operand:SF 2 "s_register_operand")))]
2073 "TARGET_32BIT && TARGET_HARD_FLOAT"
2074 "
2075 ")
2076
2077 (define_expand "muldf3"
2078 [(set (match_operand:DF 0 "s_register_operand")
2079 (mult:DF (match_operand:DF 1 "s_register_operand")
2080 (match_operand:DF 2 "s_register_operand")))]
2081 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
2082 "
2083 ")
2084 \f
2085 ;; Division insns
2086
2087 (define_expand "divsf3"
2088 [(set (match_operand:SF 0 "s_register_operand")
2089 (div:SF (match_operand:SF 1 "s_register_operand")
2090 (match_operand:SF 2 "s_register_operand")))]
2091 "TARGET_32BIT && TARGET_HARD_FLOAT"
2092 "")
2093
2094 (define_expand "divdf3"
2095 [(set (match_operand:DF 0 "s_register_operand")
2096 (div:DF (match_operand:DF 1 "s_register_operand")
2097 (match_operand:DF 2 "s_register_operand")))]
2098 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
2099 "")
2100 \f
2101
2102 ;; Split DImode and, ior, xor operations. Simply perform the logical
2103 ;; operation on the upper and lower halves of the registers.
2104 ;; This is needed for atomic operations in arm_split_atomic_op.
2105 ;; Avoid splitting IWMMXT instructions.
2106 (define_split
2107 [(set (match_operand:DI 0 "s_register_operand" "")
2108 (match_operator:DI 6 "logical_binary_operator"
2109 [(match_operand:DI 1 "s_register_operand" "")
2110 (match_operand:DI 2 "s_register_operand" "")]))]
2111 "TARGET_32BIT && reload_completed
2112 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
2113 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
2114 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
2115 "
2116 {
2117 operands[3] = gen_highpart (SImode, operands[0]);
2118 operands[0] = gen_lowpart (SImode, operands[0]);
2119 operands[4] = gen_highpart (SImode, operands[1]);
2120 operands[1] = gen_lowpart (SImode, operands[1]);
2121 operands[5] = gen_highpart (SImode, operands[2]);
2122 operands[2] = gen_lowpart (SImode, operands[2]);
2123 }"
2124 )
2125
2126 ;; Split DImode not (needed for atomic operations in arm_split_atomic_op).
2127 ;; Unconditionally split since there is no SIMD DImode NOT pattern.
2128 (define_split
2129 [(set (match_operand:DI 0 "s_register_operand")
2130 (not:DI (match_operand:DI 1 "s_register_operand")))]
2131 "TARGET_32BIT"
2132 [(set (match_dup 0) (not:SI (match_dup 1)))
2133 (set (match_dup 2) (not:SI (match_dup 3)))]
2134 "
2135 {
2136 operands[2] = gen_highpart (SImode, operands[0]);
2137 operands[0] = gen_lowpart (SImode, operands[0]);
2138 operands[3] = gen_highpart (SImode, operands[1]);
2139 operands[1] = gen_lowpart (SImode, operands[1]);
2140 }"
2141 )
2142
2143 (define_expand "andsi3"
2144 [(set (match_operand:SI 0 "s_register_operand")
2145 (and:SI (match_operand:SI 1 "s_register_operand")
2146 (match_operand:SI 2 "reg_or_int_operand")))]
2147 "TARGET_EITHER"
2148 "
2149 if (TARGET_32BIT)
2150 {
2151 if (CONST_INT_P (operands[2]))
2152 {
2153 if (INTVAL (operands[2]) == 255 && arm_arch6)
2154 {
2155 operands[1] = convert_to_mode (QImode, operands[1], 1);
2156 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0],
2157 operands[1]));
2158 DONE;
2159 }
2160 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND))
2161 operands[2] = force_reg (SImode, operands[2]);
2162 else
2163 {
2164 arm_split_constant (AND, SImode, NULL_RTX,
2165 INTVAL (operands[2]), operands[0],
2166 operands[1],
2167 optimize && can_create_pseudo_p ());
2168
2169 DONE;
2170 }
2171 }
2172 }
2173 else /* TARGET_THUMB1 */
2174 {
2175 if (!CONST_INT_P (operands[2]))
2176 {
2177 rtx tmp = force_reg (SImode, operands[2]);
2178 if (rtx_equal_p (operands[0], operands[1]))
2179 operands[2] = tmp;
2180 else
2181 {
2182 operands[2] = operands[1];
2183 operands[1] = tmp;
2184 }
2185 }
2186 else
2187 {
2188 int i;
2189
2190 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256)
2191 {
2192 operands[2] = force_reg (SImode,
2193 GEN_INT (~INTVAL (operands[2])));
2194
2195 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1]));
2196
2197 DONE;
2198 }
2199
2200 for (i = 9; i <= 31; i++)
2201 {
2202 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2]))
2203 {
2204 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i),
2205 const0_rtx));
2206 DONE;
2207 }
2208 else if ((HOST_WIDE_INT_1 << i) - 1
2209 == ~INTVAL (operands[2]))
2210 {
2211 rtx shift = GEN_INT (i);
2212 rtx reg = gen_reg_rtx (SImode);
2213
2214 emit_insn (gen_lshrsi3 (reg, operands[1], shift));
2215 emit_insn (gen_ashlsi3 (operands[0], reg, shift));
2216
2217 DONE;
2218 }
2219 }
2220
2221 operands[2] = force_reg (SImode, operands[2]);
2222 }
2223 }
2224 "
2225 )
2226
2227 ; ??? Check split length for Thumb-2
2228 (define_insn_and_split "*arm_andsi3_insn"
2229 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2230 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2231 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2232 "TARGET_32BIT"
2233 "@
2234 and%?\\t%0, %1, %2
2235 and%?\\t%0, %1, %2
2236 bic%?\\t%0, %1, #%B2
2237 and%?\\t%0, %1, %2
2238 #"
2239 "TARGET_32BIT
2240 && CONST_INT_P (operands[2])
2241 && !(const_ok_for_arm (INTVAL (operands[2]))
2242 || const_ok_for_arm (~INTVAL (operands[2])))"
2243 [(clobber (const_int 0))]
2244 "
2245 arm_split_constant (AND, SImode, curr_insn,
2246 INTVAL (operands[2]), operands[0], operands[1], 0);
2247 DONE;
2248 "
2249 [(set_attr "length" "4,4,4,4,16")
2250 (set_attr "predicable" "yes")
2251 (set_attr "predicable_short_it" "no,yes,no,no,no")
2252 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
2253 )
2254
2255 (define_insn "*andsi3_compare0"
2256 [(set (reg:CC_NOOV CC_REGNUM)
2257 (compare:CC_NOOV
2258 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
2259 (match_operand:SI 2 "arm_not_operand" "I,K,r"))
2260 (const_int 0)))
2261 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
2262 (and:SI (match_dup 1) (match_dup 2)))]
2263 "TARGET_32BIT"
2264 "@
2265 ands%?\\t%0, %1, %2
2266 bics%?\\t%0, %1, #%B2
2267 ands%?\\t%0, %1, %2"
2268 [(set_attr "conds" "set")
2269 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2270 )
2271
2272 (define_insn "*andsi3_compare0_scratch"
2273 [(set (reg:CC_NOOV CC_REGNUM)
2274 (compare:CC_NOOV
2275 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r")
2276 (match_operand:SI 1 "arm_not_operand" "I,K,r"))
2277 (const_int 0)))
2278 (clobber (match_scratch:SI 2 "=X,r,X"))]
2279 "TARGET_32BIT"
2280 "@
2281 tst%?\\t%0, %1
2282 bics%?\\t%2, %0, #%B1
2283 tst%?\\t%0, %1"
2284 [(set_attr "conds" "set")
2285 (set_attr "type" "logics_imm,logics_imm,logics_reg")]
2286 )
2287
2288 (define_insn "*zeroextractsi_compare0_scratch"
2289 [(set (reg:CC_NOOV CC_REGNUM)
2290 (compare:CC_NOOV (zero_extract:SI
2291 (match_operand:SI 0 "s_register_operand" "r")
2292 (match_operand 1 "const_int_operand" "n")
2293 (match_operand 2 "const_int_operand" "n"))
2294 (const_int 0)))]
2295 "TARGET_32BIT
2296 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32
2297 && INTVAL (operands[1]) > 0
2298 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8
2299 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)"
2300 "*
2301 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1)
2302 << INTVAL (operands[2]));
2303 output_asm_insn (\"tst%?\\t%0, %1\", operands);
2304 return \"\";
2305 "
2306 [(set_attr "conds" "set")
2307 (set_attr "predicable" "yes")
2308 (set_attr "type" "logics_imm")]
2309 )
2310
2311 (define_insn_and_split "*ne_zeroextractsi"
2312 [(set (match_operand:SI 0 "s_register_operand" "=r")
2313 (ne:SI (zero_extract:SI
2314 (match_operand:SI 1 "s_register_operand" "r")
2315 (match_operand:SI 2 "const_int_operand" "n")
2316 (match_operand:SI 3 "const_int_operand" "n"))
2317 (const_int 0)))
2318 (clobber (reg:CC CC_REGNUM))]
2319 "TARGET_32BIT
2320 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2321 && INTVAL (operands[2]) > 0
2322 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2323 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2324 "#"
2325 "TARGET_32BIT
2326 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2327 && INTVAL (operands[2]) > 0
2328 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2329 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)"
2330 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2331 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2332 (const_int 0)))
2333 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2334 (set (match_dup 0)
2335 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2336 (match_dup 0) (const_int 1)))]
2337 "
2338 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2339 << INTVAL (operands[3]));
2340 "
2341 [(set_attr "conds" "clob")
2342 (set (attr "length")
2343 (if_then_else (eq_attr "is_thumb" "yes")
2344 (const_int 12)
2345 (const_int 8)))
2346 (set_attr "type" "multiple")]
2347 )
2348
2349 (define_insn_and_split "*ne_zeroextractsi_shifted"
2350 [(set (match_operand:SI 0 "s_register_operand" "=r")
2351 (ne:SI (zero_extract:SI
2352 (match_operand:SI 1 "s_register_operand" "r")
2353 (match_operand:SI 2 "const_int_operand" "n")
2354 (const_int 0))
2355 (const_int 0)))
2356 (clobber (reg:CC CC_REGNUM))]
2357 "TARGET_ARM"
2358 "#"
2359 "TARGET_ARM"
2360 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2361 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2362 (const_int 0)))
2363 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2364 (set (match_dup 0)
2365 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2366 (match_dup 0) (const_int 1)))]
2367 "
2368 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2369 "
2370 [(set_attr "conds" "clob")
2371 (set_attr "length" "8")
2372 (set_attr "type" "multiple")]
2373 )
2374
2375 (define_insn_and_split "*ite_ne_zeroextractsi"
2376 [(set (match_operand:SI 0 "s_register_operand" "=r")
2377 (if_then_else:SI (ne (zero_extract:SI
2378 (match_operand:SI 1 "s_register_operand" "r")
2379 (match_operand:SI 2 "const_int_operand" "n")
2380 (match_operand:SI 3 "const_int_operand" "n"))
2381 (const_int 0))
2382 (match_operand:SI 4 "arm_not_operand" "rIK")
2383 (const_int 0)))
2384 (clobber (reg:CC CC_REGNUM))]
2385 "TARGET_ARM
2386 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2387 && INTVAL (operands[2]) > 0
2388 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2389 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2390 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2391 "#"
2392 "TARGET_ARM
2393 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32
2394 && INTVAL (operands[2]) > 0
2395 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8
2396 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)
2397 && !reg_overlap_mentioned_p (operands[0], operands[4])"
2398 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2399 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2))
2400 (const_int 0)))
2401 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))])
2402 (set (match_dup 0)
2403 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2404 (match_dup 0) (match_dup 4)))]
2405 "
2406 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1)
2407 << INTVAL (operands[3]));
2408 "
2409 [(set_attr "conds" "clob")
2410 (set_attr "length" "8")
2411 (set_attr "type" "multiple")]
2412 )
2413
2414 (define_insn_and_split "*ite_ne_zeroextractsi_shifted"
2415 [(set (match_operand:SI 0 "s_register_operand" "=r")
2416 (if_then_else:SI (ne (zero_extract:SI
2417 (match_operand:SI 1 "s_register_operand" "r")
2418 (match_operand:SI 2 "const_int_operand" "n")
2419 (const_int 0))
2420 (const_int 0))
2421 (match_operand:SI 3 "arm_not_operand" "rIK")
2422 (const_int 0)))
2423 (clobber (reg:CC CC_REGNUM))]
2424 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2425 "#"
2426 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])"
2427 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2428 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
2429 (const_int 0)))
2430 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))])
2431 (set (match_dup 0)
2432 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0))
2433 (match_dup 0) (match_dup 3)))]
2434 "
2435 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2436 "
2437 [(set_attr "conds" "clob")
2438 (set_attr "length" "8")
2439 (set_attr "type" "multiple")]
2440 )
2441
2442 ;; ??? Use Thumb-2 has bitfield insert/extract instructions.
2443 (define_split
2444 [(set (match_operand:SI 0 "s_register_operand" "")
2445 (match_operator:SI 1 "shiftable_operator"
2446 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
2447 (match_operand:SI 3 "const_int_operand" "")
2448 (match_operand:SI 4 "const_int_operand" ""))
2449 (match_operand:SI 5 "s_register_operand" "")]))
2450 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2451 "TARGET_ARM"
2452 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2453 (set (match_dup 0)
2454 (match_op_dup 1
2455 [(lshiftrt:SI (match_dup 6) (match_dup 4))
2456 (match_dup 5)]))]
2457 "{
2458 HOST_WIDE_INT temp = INTVAL (operands[3]);
2459
2460 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2461 operands[4] = GEN_INT (32 - temp);
2462 }"
2463 )
2464
2465 (define_split
2466 [(set (match_operand:SI 0 "s_register_operand" "")
2467 (match_operator:SI 1 "shiftable_operator"
2468 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
2469 (match_operand:SI 3 "const_int_operand" "")
2470 (match_operand:SI 4 "const_int_operand" ""))
2471 (match_operand:SI 5 "s_register_operand" "")]))
2472 (clobber (match_operand:SI 6 "s_register_operand" ""))]
2473 "TARGET_ARM"
2474 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
2475 (set (match_dup 0)
2476 (match_op_dup 1
2477 [(ashiftrt:SI (match_dup 6) (match_dup 4))
2478 (match_dup 5)]))]
2479 "{
2480 HOST_WIDE_INT temp = INTVAL (operands[3]);
2481
2482 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
2483 operands[4] = GEN_INT (32 - temp);
2484 }"
2485 )
2486
2487 ;;; ??? This pattern is bogus. If operand3 has bits outside the range
2488 ;;; represented by the bitfield, then this will produce incorrect results.
2489 ;;; Somewhere, the value needs to be truncated. On targets like the m68k,
2490 ;;; which have a real bit-field insert instruction, the truncation happens
2491 ;;; in the bit-field insert instruction itself. Since arm does not have a
2492 ;;; bit-field insert instruction, we would have to emit code here to truncate
2493 ;;; the value before we insert. This loses some of the advantage of having
2494 ;;; this insv pattern, so this pattern needs to be reevalutated.
2495
2496 (define_expand "insv"
2497 [(set (zero_extract (match_operand 0 "nonimmediate_operand")
2498 (match_operand 1 "general_operand")
2499 (match_operand 2 "general_operand"))
2500 (match_operand 3 "reg_or_int_operand"))]
2501 "TARGET_ARM || arm_arch_thumb2"
2502 "
2503 {
2504 int start_bit = INTVAL (operands[2]);
2505 int width = INTVAL (operands[1]);
2506 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1;
2507 rtx target, subtarget;
2508
2509 if (arm_arch_thumb2)
2510 {
2511 if (unaligned_access && MEM_P (operands[0])
2512 && s_register_operand (operands[3], GET_MODE (operands[3]))
2513 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
2514 {
2515 rtx base_addr;
2516
2517 if (BYTES_BIG_ENDIAN)
2518 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
2519 - start_bit;
2520
2521 if (width == 32)
2522 {
2523 base_addr = adjust_address (operands[0], SImode,
2524 start_bit / BITS_PER_UNIT);
2525 emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
2526 }
2527 else
2528 {
2529 rtx tmp = gen_reg_rtx (HImode);
2530
2531 base_addr = adjust_address (operands[0], HImode,
2532 start_bit / BITS_PER_UNIT);
2533 emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
2534 emit_insn (gen_unaligned_storehi (base_addr, tmp));
2535 }
2536 DONE;
2537 }
2538 else if (s_register_operand (operands[0], GET_MODE (operands[0])))
2539 {
2540 bool use_bfi = TRUE;
2541
2542 if (CONST_INT_P (operands[3]))
2543 {
2544 HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
2545
2546 if (val == 0)
2547 {
2548 emit_insn (gen_insv_zero (operands[0], operands[1],
2549 operands[2]));
2550 DONE;
2551 }
2552
2553 /* See if the set can be done with a single orr instruction. */
2554 if (val == mask && const_ok_for_arm (val << start_bit))
2555 use_bfi = FALSE;
2556 }
2557
2558 if (use_bfi)
2559 {
2560 if (!REG_P (operands[3]))
2561 operands[3] = force_reg (SImode, operands[3]);
2562
2563 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
2564 operands[3]));
2565 DONE;
2566 }
2567 }
2568 else
2569 FAIL;
2570 }
2571
2572 if (!s_register_operand (operands[0], GET_MODE (operands[0])))
2573 FAIL;
2574
2575 target = copy_rtx (operands[0]);
2576 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
2577 subreg as the final target. */
2578 if (GET_CODE (target) == SUBREG)
2579 {
2580 subtarget = gen_reg_rtx (SImode);
2581 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
2582 < GET_MODE_SIZE (SImode))
2583 target = SUBREG_REG (target);
2584 }
2585 else
2586 subtarget = target;
2587
2588 if (CONST_INT_P (operands[3]))
2589 {
2590 /* Since we are inserting a known constant, we may be able to
2591 reduce the number of bits that we have to clear so that
2592 the mask becomes simple. */
2593 /* ??? This code does not check to see if the new mask is actually
2594 simpler. It may not be. */
2595 rtx op1 = gen_reg_rtx (SImode);
2596 /* ??? Truncate operand3 to fit in the bitfield. See comment before
2597 start of this pattern. */
2598 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]);
2599 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit);
2600
2601 emit_insn (gen_andsi3 (op1, operands[0],
2602 gen_int_mode (~mask2, SImode)));
2603 emit_insn (gen_iorsi3 (subtarget, op1,
2604 gen_int_mode (op3_value << start_bit, SImode)));
2605 }
2606 else if (start_bit == 0
2607 && !(const_ok_for_arm (mask)
2608 || const_ok_for_arm (~mask)))
2609 {
2610 /* A Trick, since we are setting the bottom bits in the word,
2611 we can shift operand[3] up, operand[0] down, OR them together
2612 and rotate the result back again. This takes 3 insns, and
2613 the third might be mergeable into another op. */
2614 /* The shift up copes with the possibility that operand[3] is
2615 wider than the bitfield. */
2616 rtx op0 = gen_reg_rtx (SImode);
2617 rtx op1 = gen_reg_rtx (SImode);
2618
2619 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2620 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1]));
2621 emit_insn (gen_iorsi3 (op1, op1, op0));
2622 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
2623 }
2624 else if ((width + start_bit == 32)
2625 && !(const_ok_for_arm (mask)
2626 || const_ok_for_arm (~mask)))
2627 {
2628 /* Similar trick, but slightly less efficient. */
2629
2630 rtx op0 = gen_reg_rtx (SImode);
2631 rtx op1 = gen_reg_rtx (SImode);
2632
2633 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width)));
2634 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
2635 emit_insn (gen_lshrsi3 (op1, op1, operands[1]));
2636 emit_insn (gen_iorsi3 (subtarget, op1, op0));
2637 }
2638 else
2639 {
2640 rtx op0 = gen_int_mode (mask, SImode);
2641 rtx op1 = gen_reg_rtx (SImode);
2642 rtx op2 = gen_reg_rtx (SImode);
2643
2644 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask)))
2645 {
2646 rtx tmp = gen_reg_rtx (SImode);
2647
2648 emit_insn (gen_movsi (tmp, op0));
2649 op0 = tmp;
2650 }
2651
2652 /* Mask out any bits in operand[3] that are not needed. */
2653 emit_insn (gen_andsi3 (op1, operands[3], op0));
2654
2655 if (CONST_INT_P (op0)
2656 && (const_ok_for_arm (mask << start_bit)
2657 || const_ok_for_arm (~(mask << start_bit))))
2658 {
2659 op0 = gen_int_mode (~(mask << start_bit), SImode);
2660 emit_insn (gen_andsi3 (op2, operands[0], op0));
2661 }
2662 else
2663 {
2664 if (CONST_INT_P (op0))
2665 {
2666 rtx tmp = gen_reg_rtx (SImode);
2667
2668 emit_insn (gen_movsi (tmp, op0));
2669 op0 = tmp;
2670 }
2671
2672 if (start_bit != 0)
2673 emit_insn (gen_ashlsi3 (op0, op0, operands[2]));
2674
2675 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0));
2676 }
2677
2678 if (start_bit != 0)
2679 emit_insn (gen_ashlsi3 (op1, op1, operands[2]));
2680
2681 emit_insn (gen_iorsi3 (subtarget, op1, op2));
2682 }
2683
2684 if (subtarget != target)
2685 {
2686 /* If TARGET is still a SUBREG, then it must be wider than a word,
2687 so we must be careful only to set the subword we were asked to. */
2688 if (GET_CODE (target) == SUBREG)
2689 emit_move_insn (target, subtarget);
2690 else
2691 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
2692 }
2693
2694 DONE;
2695 }"
2696 )
2697
2698 (define_insn "insv_zero"
2699 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2700 (match_operand:SI 1 "const_int_M_operand" "M")
2701 (match_operand:SI 2 "const_int_M_operand" "M"))
2702 (const_int 0))]
2703 "arm_arch_thumb2"
2704 "bfc%?\t%0, %2, %1"
2705 [(set_attr "length" "4")
2706 (set_attr "predicable" "yes")
2707 (set_attr "type" "bfm")]
2708 )
2709
2710 (define_insn "insv_t2"
2711 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r")
2712 (match_operand:SI 1 "const_int_M_operand" "M")
2713 (match_operand:SI 2 "const_int_M_operand" "M"))
2714 (match_operand:SI 3 "s_register_operand" "r"))]
2715 "arm_arch_thumb2"
2716 "bfi%?\t%0, %3, %2, %1"
2717 [(set_attr "length" "4")
2718 (set_attr "predicable" "yes")
2719 (set_attr "type" "bfm")]
2720 )
2721
2722 (define_insn "andsi_notsi_si"
2723 [(set (match_operand:SI 0 "s_register_operand" "=r")
2724 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2725 (match_operand:SI 1 "s_register_operand" "r")))]
2726 "TARGET_32BIT"
2727 "bic%?\\t%0, %1, %2"
2728 [(set_attr "predicable" "yes")
2729 (set_attr "type" "logic_reg")]
2730 )
2731
2732 (define_insn "andsi_not_shiftsi_si"
2733 [(set (match_operand:SI 0 "s_register_operand" "=r")
2734 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
2735 [(match_operand:SI 2 "s_register_operand" "r")
2736 (match_operand:SI 3 "arm_rhs_operand" "rM")]))
2737 (match_operand:SI 1 "s_register_operand" "r")))]
2738 "TARGET_ARM"
2739 "bic%?\\t%0, %1, %2%S4"
2740 [(set_attr "predicable" "yes")
2741 (set_attr "shift" "2")
2742 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
2743 (const_string "logic_shift_imm")
2744 (const_string "logic_shift_reg")))]
2745 )
2746
2747 ;; Shifted bics pattern used to set up CC status register and not reusing
2748 ;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2
2749 ;; does not support shift by register.
2750 (define_insn "andsi_not_shiftsi_si_scc_no_reuse"
2751 [(set (reg:CC_NOOV CC_REGNUM)
2752 (compare:CC_NOOV
2753 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2754 [(match_operand:SI 1 "s_register_operand" "r")
2755 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2756 (match_operand:SI 3 "s_register_operand" "r"))
2757 (const_int 0)))
2758 (clobber (match_scratch:SI 4 "=r"))]
2759 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2760 "bics%?\\t%4, %3, %1%S0"
2761 [(set_attr "predicable" "yes")
2762 (set_attr "conds" "set")
2763 (set_attr "shift" "1")
2764 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2765 (const_string "logic_shift_imm")
2766 (const_string "logic_shift_reg")))]
2767 )
2768
2769 ;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also
2770 ;; getting reused later.
2771 (define_insn "andsi_not_shiftsi_si_scc"
2772 [(parallel [(set (reg:CC_NOOV CC_REGNUM)
2773 (compare:CC_NOOV
2774 (and:SI (not:SI (match_operator:SI 0 "shift_operator"
2775 [(match_operand:SI 1 "s_register_operand" "r")
2776 (match_operand:SI 2 "arm_rhs_operand" "rM")]))
2777 (match_operand:SI 3 "s_register_operand" "r"))
2778 (const_int 0)))
2779 (set (match_operand:SI 4 "s_register_operand" "=r")
2780 (and:SI (not:SI (match_op_dup 0
2781 [(match_dup 1)
2782 (match_dup 2)]))
2783 (match_dup 3)))])]
2784 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))"
2785 "bics%?\\t%4, %3, %1%S0"
2786 [(set_attr "predicable" "yes")
2787 (set_attr "conds" "set")
2788 (set_attr "shift" "1")
2789 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
2790 (const_string "logic_shift_imm")
2791 (const_string "logic_shift_reg")))]
2792 )
2793
2794 (define_insn "*andsi_notsi_si_compare0"
2795 [(set (reg:CC_NOOV CC_REGNUM)
2796 (compare:CC_NOOV
2797 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2798 (match_operand:SI 1 "s_register_operand" "r"))
2799 (const_int 0)))
2800 (set (match_operand:SI 0 "s_register_operand" "=r")
2801 (and:SI (not:SI (match_dup 2)) (match_dup 1)))]
2802 "TARGET_32BIT"
2803 "bics\\t%0, %1, %2"
2804 [(set_attr "conds" "set")
2805 (set_attr "type" "logics_shift_reg")]
2806 )
2807
2808 (define_insn "*andsi_notsi_si_compare0_scratch"
2809 [(set (reg:CC_NOOV CC_REGNUM)
2810 (compare:CC_NOOV
2811 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
2812 (match_operand:SI 1 "s_register_operand" "r"))
2813 (const_int 0)))
2814 (clobber (match_scratch:SI 0 "=r"))]
2815 "TARGET_32BIT"
2816 "bics\\t%0, %1, %2"
2817 [(set_attr "conds" "set")
2818 (set_attr "type" "logics_shift_reg")]
2819 )
2820
2821 (define_expand "iorsi3"
2822 [(set (match_operand:SI 0 "s_register_operand")
2823 (ior:SI (match_operand:SI 1 "s_register_operand")
2824 (match_operand:SI 2 "reg_or_int_operand")))]
2825 "TARGET_EITHER"
2826 "
2827 if (CONST_INT_P (operands[2]))
2828 {
2829 if (TARGET_32BIT)
2830 {
2831 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR))
2832 operands[2] = force_reg (SImode, operands[2]);
2833 else
2834 {
2835 arm_split_constant (IOR, SImode, NULL_RTX,
2836 INTVAL (operands[2]), operands[0],
2837 operands[1],
2838 optimize && can_create_pseudo_p ());
2839 DONE;
2840 }
2841 }
2842 else /* TARGET_THUMB1 */
2843 {
2844 rtx tmp = force_reg (SImode, operands[2]);
2845 if (rtx_equal_p (operands[0], operands[1]))
2846 operands[2] = tmp;
2847 else
2848 {
2849 operands[2] = operands[1];
2850 operands[1] = tmp;
2851 }
2852 }
2853 }
2854 "
2855 )
2856
2857 (define_insn_and_split "*iorsi3_insn"
2858 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
2859 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
2860 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
2861 "TARGET_32BIT"
2862 "@
2863 orr%?\\t%0, %1, %2
2864 orr%?\\t%0, %1, %2
2865 orn%?\\t%0, %1, #%B2
2866 orr%?\\t%0, %1, %2
2867 #"
2868 "TARGET_32BIT
2869 && CONST_INT_P (operands[2])
2870 && !(const_ok_for_arm (INTVAL (operands[2]))
2871 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
2872 [(clobber (const_int 0))]
2873 {
2874 arm_split_constant (IOR, SImode, curr_insn,
2875 INTVAL (operands[2]), operands[0], operands[1], 0);
2876 DONE;
2877 }
2878 [(set_attr "length" "4,4,4,4,16")
2879 (set_attr "arch" "32,t2,t2,32,32")
2880 (set_attr "predicable" "yes")
2881 (set_attr "predicable_short_it" "no,yes,no,no,no")
2882 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
2883 )
2884
2885 (define_peephole2
2886 [(match_scratch:SI 3 "r")
2887 (set (match_operand:SI 0 "arm_general_register_operand" "")
2888 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
2889 (match_operand:SI 2 "const_int_operand" "")))]
2890 "TARGET_ARM
2891 && !const_ok_for_arm (INTVAL (operands[2]))
2892 && const_ok_for_arm (~INTVAL (operands[2]))"
2893 [(set (match_dup 3) (match_dup 2))
2894 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))]
2895 ""
2896 )
2897
2898 (define_insn "*iorsi3_compare0"
2899 [(set (reg:CC_NOOV CC_REGNUM)
2900 (compare:CC_NOOV
2901 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r")
2902 (match_operand:SI 2 "arm_rhs_operand" "I,l,r"))
2903 (const_int 0)))
2904 (set (match_operand:SI 0 "s_register_operand" "=r,l,r")
2905 (ior:SI (match_dup 1) (match_dup 2)))]
2906 "TARGET_32BIT"
2907 "orrs%?\\t%0, %1, %2"
2908 [(set_attr "conds" "set")
2909 (set_attr "arch" "*,t2,*")
2910 (set_attr "length" "4,2,4")
2911 (set_attr "type" "logics_imm,logics_reg,logics_reg")]
2912 )
2913
2914 (define_insn "*iorsi3_compare0_scratch"
2915 [(set (reg:CC_NOOV CC_REGNUM)
2916 (compare:CC_NOOV
2917 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r")
2918 (match_operand:SI 2 "arm_rhs_operand" "I,l,r"))
2919 (const_int 0)))
2920 (clobber (match_scratch:SI 0 "=r,l,r"))]
2921 "TARGET_32BIT"
2922 "orrs%?\\t%0, %1, %2"
2923 [(set_attr "conds" "set")
2924 (set_attr "arch" "*,t2,*")
2925 (set_attr "length" "4,2,4")
2926 (set_attr "type" "logics_imm,logics_reg,logics_reg")]
2927 )
2928
2929 (define_expand "xorsi3"
2930 [(set (match_operand:SI 0 "s_register_operand")
2931 (xor:SI (match_operand:SI 1 "s_register_operand")
2932 (match_operand:SI 2 "reg_or_int_operand")))]
2933 "TARGET_EITHER"
2934 "if (CONST_INT_P (operands[2]))
2935 {
2936 if (TARGET_32BIT)
2937 {
2938 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR))
2939 operands[2] = force_reg (SImode, operands[2]);
2940 else
2941 {
2942 arm_split_constant (XOR, SImode, NULL_RTX,
2943 INTVAL (operands[2]), operands[0],
2944 operands[1],
2945 optimize && can_create_pseudo_p ());
2946 DONE;
2947 }
2948 }
2949 else /* TARGET_THUMB1 */
2950 {
2951 rtx tmp = force_reg (SImode, operands[2]);
2952 if (rtx_equal_p (operands[0], operands[1]))
2953 operands[2] = tmp;
2954 else
2955 {
2956 operands[2] = operands[1];
2957 operands[1] = tmp;
2958 }
2959 }
2960 }"
2961 )
2962
2963 (define_insn_and_split "*arm_xorsi3"
2964 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
2965 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
2966 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
2967 "TARGET_32BIT"
2968 "@
2969 eor%?\\t%0, %1, %2
2970 eor%?\\t%0, %1, %2
2971 eor%?\\t%0, %1, %2
2972 #"
2973 "TARGET_32BIT
2974 && CONST_INT_P (operands[2])
2975 && !const_ok_for_arm (INTVAL (operands[2]))"
2976 [(clobber (const_int 0))]
2977 {
2978 arm_split_constant (XOR, SImode, curr_insn,
2979 INTVAL (operands[2]), operands[0], operands[1], 0);
2980 DONE;
2981 }
2982 [(set_attr "length" "4,4,4,16")
2983 (set_attr "predicable" "yes")
2984 (set_attr "predicable_short_it" "no,yes,no,no")
2985 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
2986 )
2987
2988 (define_insn "*xorsi3_compare0"
2989 [(set (reg:CC_NOOV CC_REGNUM)
2990 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r")
2991 (match_operand:SI 2 "arm_rhs_operand" "I,r"))
2992 (const_int 0)))
2993 (set (match_operand:SI 0 "s_register_operand" "=r,r")
2994 (xor:SI (match_dup 1) (match_dup 2)))]
2995 "TARGET_32BIT"
2996 "eors%?\\t%0, %1, %2"
2997 [(set_attr "conds" "set")
2998 (set_attr "type" "logics_imm,logics_reg")]
2999 )
3000
3001 (define_insn "*xorsi3_compare0_scratch"
3002 [(set (reg:CC_NOOV CC_REGNUM)
3003 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r")
3004 (match_operand:SI 1 "arm_rhs_operand" "I,r"))
3005 (const_int 0)))]
3006 "TARGET_32BIT"
3007 "teq%?\\t%0, %1"
3008 [(set_attr "conds" "set")
3009 (set_attr "type" "logics_imm,logics_reg")]
3010 )
3011
3012 ; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
3013 ; (NOT D) we can sometimes merge the final NOT into one of the following
3014 ; insns.
3015
3016 (define_split
3017 [(set (match_operand:SI 0 "s_register_operand" "")
3018 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" ""))
3019 (not:SI (match_operand:SI 2 "arm_rhs_operand" "")))
3020 (match_operand:SI 3 "arm_rhs_operand" "")))
3021 (clobber (match_operand:SI 4 "s_register_operand" ""))]
3022 "TARGET_32BIT"
3023 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2))
3024 (not:SI (match_dup 3))))
3025 (set (match_dup 0) (not:SI (match_dup 4)))]
3026 ""
3027 )
3028
3029 (define_insn_and_split "*andsi_iorsi3_notsi"
3030 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
3031 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r")
3032 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))
3033 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))]
3034 "TARGET_32BIT"
3035 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3"
3036 "&& reload_completed"
3037 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
3038 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))]
3039 {
3040 /* If operands[3] is a constant make sure to fold the NOT into it
3041 to avoid creating a NOT of a CONST_INT. */
3042 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode);
3043 if (CONST_INT_P (not_rtx))
3044 {
3045 operands[4] = operands[0];
3046 operands[5] = not_rtx;
3047 }
3048 else
3049 {
3050 operands[5] = operands[0];
3051 operands[4] = not_rtx;
3052 }
3053 }
3054 [(set_attr "length" "8")
3055 (set_attr "ce_count" "2")
3056 (set_attr "predicable" "yes")
3057 (set_attr "type" "multiple")]
3058 )
3059
3060 ; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
3061 ; insns are available?
3062 (define_split
3063 [(set (match_operand:SI 0 "s_register_operand" "")
3064 (match_operator:SI 1 "logical_binary_operator"
3065 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3066 (match_operand:SI 3 "const_int_operand" "")
3067 (match_operand:SI 4 "const_int_operand" ""))
3068 (match_operator:SI 9 "logical_binary_operator"
3069 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3070 (match_operand:SI 6 "const_int_operand" ""))
3071 (match_operand:SI 7 "s_register_operand" "")])]))
3072 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3073 "TARGET_32BIT
3074 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3075 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3076 [(set (match_dup 8)
3077 (match_op_dup 1
3078 [(ashift:SI (match_dup 2) (match_dup 4))
3079 (match_dup 5)]))
3080 (set (match_dup 0)
3081 (match_op_dup 1
3082 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3083 (match_dup 7)]))]
3084 "
3085 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3086 ")
3087
3088 (define_split
3089 [(set (match_operand:SI 0 "s_register_operand" "")
3090 (match_operator:SI 1 "logical_binary_operator"
3091 [(match_operator:SI 9 "logical_binary_operator"
3092 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3093 (match_operand:SI 6 "const_int_operand" ""))
3094 (match_operand:SI 7 "s_register_operand" "")])
3095 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
3096 (match_operand:SI 3 "const_int_operand" "")
3097 (match_operand:SI 4 "const_int_operand" ""))]))
3098 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3099 "TARGET_32BIT
3100 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3101 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3102 [(set (match_dup 8)
3103 (match_op_dup 1
3104 [(ashift:SI (match_dup 2) (match_dup 4))
3105 (match_dup 5)]))
3106 (set (match_dup 0)
3107 (match_op_dup 1
3108 [(lshiftrt:SI (match_dup 8) (match_dup 6))
3109 (match_dup 7)]))]
3110 "
3111 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3112 ")
3113
3114 (define_split
3115 [(set (match_operand:SI 0 "s_register_operand" "")
3116 (match_operator:SI 1 "logical_binary_operator"
3117 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3118 (match_operand:SI 3 "const_int_operand" "")
3119 (match_operand:SI 4 "const_int_operand" ""))
3120 (match_operator:SI 9 "logical_binary_operator"
3121 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3122 (match_operand:SI 6 "const_int_operand" ""))
3123 (match_operand:SI 7 "s_register_operand" "")])]))
3124 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3125 "TARGET_32BIT
3126 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3127 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3128 [(set (match_dup 8)
3129 (match_op_dup 1
3130 [(ashift:SI (match_dup 2) (match_dup 4))
3131 (match_dup 5)]))
3132 (set (match_dup 0)
3133 (match_op_dup 1
3134 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3135 (match_dup 7)]))]
3136 "
3137 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3138 ")
3139
3140 (define_split
3141 [(set (match_operand:SI 0 "s_register_operand" "")
3142 (match_operator:SI 1 "logical_binary_operator"
3143 [(match_operator:SI 9 "logical_binary_operator"
3144 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
3145 (match_operand:SI 6 "const_int_operand" ""))
3146 (match_operand:SI 7 "s_register_operand" "")])
3147 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
3148 (match_operand:SI 3 "const_int_operand" "")
3149 (match_operand:SI 4 "const_int_operand" ""))]))
3150 (clobber (match_operand:SI 8 "s_register_operand" ""))]
3151 "TARGET_32BIT
3152 && GET_CODE (operands[1]) == GET_CODE (operands[9])
3153 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
3154 [(set (match_dup 8)
3155 (match_op_dup 1
3156 [(ashift:SI (match_dup 2) (match_dup 4))
3157 (match_dup 5)]))
3158 (set (match_dup 0)
3159 (match_op_dup 1
3160 [(ashiftrt:SI (match_dup 8) (match_dup 6))
3161 (match_dup 7)]))]
3162 "
3163 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
3164 ")
3165 \f
3166
3167 ;; Minimum and maximum insns
3168
3169 (define_expand "smaxsi3"
3170 [(parallel [
3171 (set (match_operand:SI 0 "s_register_operand")
3172 (smax:SI (match_operand:SI 1 "s_register_operand")
3173 (match_operand:SI 2 "arm_rhs_operand")))
3174 (clobber (reg:CC CC_REGNUM))])]
3175 "TARGET_32BIT"
3176 "
3177 if (operands[2] == const0_rtx || operands[2] == constm1_rtx)
3178 {
3179 /* No need for a clobber of the condition code register here. */
3180 emit_insn (gen_rtx_SET (operands[0],
3181 gen_rtx_SMAX (SImode, operands[1],
3182 operands[2])));
3183 DONE;
3184 }
3185 ")
3186
3187 (define_insn "*smax_0"
3188 [(set (match_operand:SI 0 "s_register_operand" "=r")
3189 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3190 (const_int 0)))]
3191 "TARGET_32BIT"
3192 "bic%?\\t%0, %1, %1, asr #31"
3193 [(set_attr "predicable" "yes")
3194 (set_attr "type" "logic_shift_reg")]
3195 )
3196
3197 (define_insn "*smax_m1"
3198 [(set (match_operand:SI 0 "s_register_operand" "=r")
3199 (smax:SI (match_operand:SI 1 "s_register_operand" "r")
3200 (const_int -1)))]
3201 "TARGET_32BIT"
3202 "orr%?\\t%0, %1, %1, asr #31"
3203 [(set_attr "predicable" "yes")
3204 (set_attr "type" "logic_shift_reg")]
3205 )
3206
3207 (define_insn_and_split "*arm_smax_insn"
3208 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3209 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3210 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3211 (clobber (reg:CC CC_REGNUM))]
3212 "TARGET_ARM"
3213 "#"
3214 ; cmp\\t%1, %2\;movlt\\t%0, %2
3215 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2"
3216 "TARGET_ARM"
3217 [(set (reg:CC CC_REGNUM)
3218 (compare:CC (match_dup 1) (match_dup 2)))
3219 (set (match_dup 0)
3220 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0))
3221 (match_dup 1)
3222 (match_dup 2)))]
3223 ""
3224 [(set_attr "conds" "clob")
3225 (set_attr "length" "8,12")
3226 (set_attr "type" "multiple")]
3227 )
3228
3229 (define_expand "sminsi3"
3230 [(parallel [
3231 (set (match_operand:SI 0 "s_register_operand")
3232 (smin:SI (match_operand:SI 1 "s_register_operand")
3233 (match_operand:SI 2 "arm_rhs_operand")))
3234 (clobber (reg:CC CC_REGNUM))])]
3235 "TARGET_32BIT"
3236 "
3237 if (operands[2] == const0_rtx)
3238 {
3239 /* No need for a clobber of the condition code register here. */
3240 emit_insn (gen_rtx_SET (operands[0],
3241 gen_rtx_SMIN (SImode, operands[1],
3242 operands[2])));
3243 DONE;
3244 }
3245 ")
3246
3247 (define_insn "*smin_0"
3248 [(set (match_operand:SI 0 "s_register_operand" "=r")
3249 (smin:SI (match_operand:SI 1 "s_register_operand" "r")
3250 (const_int 0)))]
3251 "TARGET_32BIT"
3252 "and%?\\t%0, %1, %1, asr #31"
3253 [(set_attr "predicable" "yes")
3254 (set_attr "type" "logic_shift_reg")]
3255 )
3256
3257 (define_insn_and_split "*arm_smin_insn"
3258 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3259 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r")
3260 (match_operand:SI 2 "arm_rhs_operand" "rI,rI")))
3261 (clobber (reg:CC CC_REGNUM))]
3262 "TARGET_ARM"
3263 "#"
3264 ; cmp\\t%1, %2\;movge\\t%0, %2
3265 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2"
3266 "TARGET_ARM"
3267 [(set (reg:CC CC_REGNUM)
3268 (compare:CC (match_dup 1) (match_dup 2)))
3269 (set (match_dup 0)
3270 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0))
3271 (match_dup 1)
3272 (match_dup 2)))]
3273 ""
3274 [(set_attr "conds" "clob")
3275 (set_attr "length" "8,12")
3276 (set_attr "type" "multiple,multiple")]
3277 )
3278
3279 (define_expand "umaxsi3"
3280 [(parallel [
3281 (set (match_operand:SI 0 "s_register_operand")
3282 (umax:SI (match_operand:SI 1 "s_register_operand")
3283 (match_operand:SI 2 "arm_rhs_operand")))
3284 (clobber (reg:CC CC_REGNUM))])]
3285 "TARGET_32BIT"
3286 ""
3287 )
3288
3289 (define_insn_and_split "*arm_umaxsi3"
3290 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3291 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3292 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3293 (clobber (reg:CC CC_REGNUM))]
3294 "TARGET_ARM"
3295 "#"
3296 ; cmp\\t%1, %2\;movcc\\t%0, %2
3297 ; cmp\\t%1, %2\;movcs\\t%0, %1
3298 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2"
3299 "TARGET_ARM"
3300 [(set (reg:CC CC_REGNUM)
3301 (compare:CC (match_dup 1) (match_dup 2)))
3302 (set (match_dup 0)
3303 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
3304 (match_dup 1)
3305 (match_dup 2)))]
3306 ""
3307 [(set_attr "conds" "clob")
3308 (set_attr "length" "8,8,12")
3309 (set_attr "type" "store_4")]
3310 )
3311
3312 (define_expand "uminsi3"
3313 [(parallel [
3314 (set (match_operand:SI 0 "s_register_operand")
3315 (umin:SI (match_operand:SI 1 "s_register_operand")
3316 (match_operand:SI 2 "arm_rhs_operand")))
3317 (clobber (reg:CC CC_REGNUM))])]
3318 "TARGET_32BIT"
3319 ""
3320 )
3321
3322 (define_insn_and_split "*arm_uminsi3"
3323 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
3324 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
3325 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
3326 (clobber (reg:CC CC_REGNUM))]
3327 "TARGET_ARM"
3328 "#"
3329 ; cmp\\t%1, %2\;movcs\\t%0, %2
3330 ; cmp\\t%1, %2\;movcc\\t%0, %1
3331 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2"
3332 "TARGET_ARM"
3333 [(set (reg:CC CC_REGNUM)
3334 (compare:CC (match_dup 1) (match_dup 2)))
3335 (set (match_dup 0)
3336 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
3337 (match_dup 1)
3338 (match_dup 2)))]
3339 ""
3340 [(set_attr "conds" "clob")
3341 (set_attr "length" "8,8,12")
3342 (set_attr "type" "store_4")]
3343 )
3344
3345 (define_insn "*store_minmaxsi"
3346 [(set (match_operand:SI 0 "memory_operand" "=m")
3347 (match_operator:SI 3 "minmax_operator"
3348 [(match_operand:SI 1 "s_register_operand" "r")
3349 (match_operand:SI 2 "s_register_operand" "r")]))
3350 (clobber (reg:CC CC_REGNUM))]
3351 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it"
3352 "*
3353 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode,
3354 operands[1], operands[2]);
3355 output_asm_insn (\"cmp\\t%1, %2\", operands);
3356 if (TARGET_THUMB2)
3357 output_asm_insn (\"ite\t%d3\", operands);
3358 output_asm_insn (\"str%d3\\t%1, %0\", operands);
3359 output_asm_insn (\"str%D3\\t%2, %0\", operands);
3360 return \"\";
3361 "
3362 [(set_attr "conds" "clob")
3363 (set (attr "length")
3364 (if_then_else (eq_attr "is_thumb" "yes")
3365 (const_int 14)
3366 (const_int 12)))
3367 (set_attr "type" "store_4")]
3368 )
3369
3370 ; Reject the frame pointer in operand[1], since reloading this after
3371 ; it has been eliminated can cause carnage.
3372 (define_insn "*minmax_arithsi"
3373 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3374 (match_operator:SI 4 "shiftable_operator"
3375 [(match_operator:SI 5 "minmax_operator"
3376 [(match_operand:SI 2 "s_register_operand" "r,r")
3377 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
3378 (match_operand:SI 1 "s_register_operand" "0,?r")]))
3379 (clobber (reg:CC CC_REGNUM))]
3380 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it"
3381 "*
3382 {
3383 enum rtx_code code = GET_CODE (operands[4]);
3384 bool need_else;
3385
3386 if (which_alternative != 0 || operands[3] != const0_rtx
3387 || (code != PLUS && code != IOR && code != XOR))
3388 need_else = true;
3389 else
3390 need_else = false;
3391
3392 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode,
3393 operands[2], operands[3]);
3394 output_asm_insn (\"cmp\\t%2, %3\", operands);
3395 if (TARGET_THUMB2)
3396 {
3397 if (need_else)
3398 output_asm_insn (\"ite\\t%d5\", operands);
3399 else
3400 output_asm_insn (\"it\\t%d5\", operands);
3401 }
3402 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands);
3403 if (need_else)
3404 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands);
3405 return \"\";
3406 }"
3407 [(set_attr "conds" "clob")
3408 (set (attr "length")
3409 (if_then_else (eq_attr "is_thumb" "yes")
3410 (const_int 14)
3411 (const_int 12)))
3412 (set_attr "type" "multiple")]
3413 )
3414
3415 ; Reject the frame pointer in operand[1], since reloading this after
3416 ; it has been eliminated can cause carnage.
3417 (define_insn_and_split "*minmax_arithsi_non_canon"
3418 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
3419 (minus:SI
3420 (match_operand:SI 1 "s_register_operand" "0,?Ts")
3421 (match_operator:SI 4 "minmax_operator"
3422 [(match_operand:SI 2 "s_register_operand" "Ts,Ts")
3423 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")])))
3424 (clobber (reg:CC CC_REGNUM))]
3425 "TARGET_32BIT && !arm_eliminable_register (operands[1])
3426 && !(arm_restrict_it && CONST_INT_P (operands[3]))"
3427 "#"
3428 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed"
3429 [(set (reg:CC CC_REGNUM)
3430 (compare:CC (match_dup 2) (match_dup 3)))
3431
3432 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)])
3433 (set (match_dup 0)
3434 (minus:SI (match_dup 1)
3435 (match_dup 2))))
3436 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
3437 (set (match_dup 0)
3438 (match_dup 6)))]
3439 {
3440 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
3441 operands[2], operands[3]);
3442 enum rtx_code rc = minmax_code (operands[4]);
3443 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode,
3444 operands[2], operands[3]);
3445
3446 if (mode == CCFPmode || mode == CCFPEmode)
3447 rc = reverse_condition_maybe_unordered (rc);
3448 else
3449 rc = reverse_condition (rc);
3450 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
3451 if (CONST_INT_P (operands[3]))
3452 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
3453 else
3454 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
3455 }
3456 [(set_attr "conds" "clob")
3457 (set (attr "length")
3458 (if_then_else (eq_attr "is_thumb" "yes")
3459 (const_int 14)
3460 (const_int 12)))
3461 (set_attr "type" "multiple")]
3462 )
3463
3464 (define_code_iterator SAT [smin smax])
3465 (define_code_attr SATrev [(smin "smax") (smax "smin")])
3466 (define_code_attr SATlo [(smin "1") (smax "2")])
3467 (define_code_attr SAThi [(smin "2") (smax "1")])
3468
3469 (define_insn "*satsi_<SAT:code>"
3470 [(set (match_operand:SI 0 "s_register_operand" "=r")
3471 (SAT:SI (<SATrev>:SI (match_operand:SI 3 "s_register_operand" "r")
3472 (match_operand:SI 1 "const_int_operand" "i"))
3473 (match_operand:SI 2 "const_int_operand" "i")))]
3474 "TARGET_32BIT && arm_arch6
3475 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3476 {
3477 int mask;
3478 bool signed_sat;
3479 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3480 &mask, &signed_sat))
3481 gcc_unreachable ();
3482
3483 operands[1] = GEN_INT (mask);
3484 if (signed_sat)
3485 return "ssat%?\t%0, %1, %3";
3486 else
3487 return "usat%?\t%0, %1, %3";
3488 }
3489 [(set_attr "predicable" "yes")
3490 (set_attr "type" "alus_imm")]
3491 )
3492
3493 (define_insn "*satsi_<SAT:code>_shift"
3494 [(set (match_operand:SI 0 "s_register_operand" "=r")
3495 (SAT:SI (<SATrev>:SI (match_operator:SI 3 "sat_shift_operator"
3496 [(match_operand:SI 4 "s_register_operand" "r")
3497 (match_operand:SI 5 "const_int_operand" "i")])
3498 (match_operand:SI 1 "const_int_operand" "i"))
3499 (match_operand:SI 2 "const_int_operand" "i")))]
3500 "TARGET_32BIT && arm_arch6
3501 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
3502 {
3503 int mask;
3504 bool signed_sat;
3505 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>],
3506 &mask, &signed_sat))
3507 gcc_unreachable ();
3508
3509 operands[1] = GEN_INT (mask);
3510 if (signed_sat)
3511 return "ssat%?\t%0, %1, %4%S3";
3512 else
3513 return "usat%?\t%0, %1, %4%S3";
3514 }
3515 [(set_attr "predicable" "yes")
3516 (set_attr "shift" "3")
3517 (set_attr "type" "logic_shift_reg")])
3518 \f
3519 ;; Shift and rotation insns
3520
3521 (define_expand "ashldi3"
3522 [(set (match_operand:DI 0 "s_register_operand")
3523 (ashift:DI (match_operand:DI 1 "s_register_operand")
3524 (match_operand:SI 2 "reg_or_int_operand")))]
3525 "TARGET_32BIT"
3526 "
3527 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
3528 operands[2], gen_reg_rtx (SImode),
3529 gen_reg_rtx (SImode));
3530 DONE;
3531 ")
3532
3533 (define_expand "ashlsi3"
3534 [(set (match_operand:SI 0 "s_register_operand")
3535 (ashift:SI (match_operand:SI 1 "s_register_operand")
3536 (match_operand:SI 2 "arm_rhs_operand")))]
3537 "TARGET_EITHER"
3538 "
3539 if (CONST_INT_P (operands[2])
3540 && (UINTVAL (operands[2])) > 31)
3541 {
3542 emit_insn (gen_movsi (operands[0], const0_rtx));
3543 DONE;
3544 }
3545 "
3546 )
3547
3548 (define_expand "ashrdi3"
3549 [(set (match_operand:DI 0 "s_register_operand")
3550 (ashiftrt:DI (match_operand:DI 1 "s_register_operand")
3551 (match_operand:SI 2 "reg_or_int_operand")))]
3552 "TARGET_32BIT"
3553 "
3554 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1],
3555 operands[2], gen_reg_rtx (SImode),
3556 gen_reg_rtx (SImode));
3557 DONE;
3558 ")
3559
3560 (define_expand "ashrsi3"
3561 [(set (match_operand:SI 0 "s_register_operand")
3562 (ashiftrt:SI (match_operand:SI 1 "s_register_operand")
3563 (match_operand:SI 2 "arm_rhs_operand")))]
3564 "TARGET_EITHER"
3565 "
3566 if (CONST_INT_P (operands[2])
3567 && UINTVAL (operands[2]) > 31)
3568 operands[2] = GEN_INT (31);
3569 "
3570 )
3571
3572 (define_expand "lshrdi3"
3573 [(set (match_operand:DI 0 "s_register_operand")
3574 (lshiftrt:DI (match_operand:DI 1 "s_register_operand")
3575 (match_operand:SI 2 "reg_or_int_operand")))]
3576 "TARGET_32BIT"
3577 "
3578 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1],
3579 operands[2], gen_reg_rtx (SImode),
3580 gen_reg_rtx (SImode));
3581 DONE;
3582 ")
3583
3584 (define_expand "lshrsi3"
3585 [(set (match_operand:SI 0 "s_register_operand")
3586 (lshiftrt:SI (match_operand:SI 1 "s_register_operand")
3587 (match_operand:SI 2 "arm_rhs_operand")))]
3588 "TARGET_EITHER"
3589 "
3590 if (CONST_INT_P (operands[2])
3591 && (UINTVAL (operands[2])) > 31)
3592 {
3593 emit_insn (gen_movsi (operands[0], const0_rtx));
3594 DONE;
3595 }
3596 "
3597 )
3598
3599 (define_expand "rotlsi3"
3600 [(set (match_operand:SI 0 "s_register_operand")
3601 (rotatert:SI (match_operand:SI 1 "s_register_operand")
3602 (match_operand:SI 2 "reg_or_int_operand")))]
3603 "TARGET_32BIT"
3604 "
3605 if (CONST_INT_P (operands[2]))
3606 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32);
3607 else
3608 {
3609 rtx reg = gen_reg_rtx (SImode);
3610 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2]));
3611 operands[2] = reg;
3612 }
3613 "
3614 )
3615
3616 (define_expand "rotrsi3"
3617 [(set (match_operand:SI 0 "s_register_operand")
3618 (rotatert:SI (match_operand:SI 1 "s_register_operand")
3619 (match_operand:SI 2 "arm_rhs_operand")))]
3620 "TARGET_EITHER"
3621 "
3622 if (TARGET_32BIT)
3623 {
3624 if (CONST_INT_P (operands[2])
3625 && UINTVAL (operands[2]) > 31)
3626 operands[2] = GEN_INT (INTVAL (operands[2]) % 32);
3627 }
3628 else /* TARGET_THUMB1 */
3629 {
3630 if (CONST_INT_P (operands [2]))
3631 operands [2] = force_reg (SImode, operands[2]);
3632 }
3633 "
3634 )
3635
3636 (define_insn "*arm_shiftsi3"
3637 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r")
3638 (match_operator:SI 3 "shift_operator"
3639 [(match_operand:SI 1 "s_register_operand" "0,l,r,r")
3640 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))]
3641 "TARGET_32BIT"
3642 "* return arm_output_shift(operands, 0);"
3643 [(set_attr "predicable" "yes")
3644 (set_attr "arch" "t2,t2,*,*")
3645 (set_attr "predicable_short_it" "yes,yes,no,no")
3646 (set_attr "length" "4")
3647 (set_attr "shift" "1")
3648 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")]
3649 )
3650
3651 (define_insn "*shiftsi3_compare0"
3652 [(set (reg:CC_NOOV CC_REGNUM)
3653 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3654 [(match_operand:SI 1 "s_register_operand" "r,r")
3655 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3656 (const_int 0)))
3657 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3658 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))]
3659 "TARGET_32BIT"
3660 "* return arm_output_shift(operands, 1);"
3661 [(set_attr "conds" "set")
3662 (set_attr "shift" "1")
3663 (set_attr "type" "alus_shift_imm,alus_shift_reg")]
3664 )
3665
3666 (define_insn "*shiftsi3_compare0_scratch"
3667 [(set (reg:CC_NOOV CC_REGNUM)
3668 (compare:CC_NOOV (match_operator:SI 3 "shift_operator"
3669 [(match_operand:SI 1 "s_register_operand" "r,r")
3670 (match_operand:SI 2 "arm_rhs_operand" "M,r")])
3671 (const_int 0)))
3672 (clobber (match_scratch:SI 0 "=r,r"))]
3673 "TARGET_32BIT"
3674 "* return arm_output_shift(operands, 1);"
3675 [(set_attr "conds" "set")
3676 (set_attr "shift" "1")
3677 (set_attr "type" "shift_imm,shift_reg")]
3678 )
3679
3680 (define_insn "*not_shiftsi"
3681 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
3682 (not:SI (match_operator:SI 3 "shift_operator"
3683 [(match_operand:SI 1 "s_register_operand" "r,r")
3684 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
3685 "TARGET_32BIT"
3686 "mvn%?\\t%0, %1%S3"
3687 [(set_attr "predicable" "yes")
3688 (set_attr "shift" "1")
3689 (set_attr "arch" "32,a")
3690 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3691
3692 (define_insn "*not_shiftsi_compare0"
3693 [(set (reg:CC_NOOV CC_REGNUM)
3694 (compare:CC_NOOV
3695 (not:SI (match_operator:SI 3 "shift_operator"
3696 [(match_operand:SI 1 "s_register_operand" "r,r")
3697 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3698 (const_int 0)))
3699 (set (match_operand:SI 0 "s_register_operand" "=r,r")
3700 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
3701 "TARGET_32BIT"
3702 "mvns%?\\t%0, %1%S3"
3703 [(set_attr "conds" "set")
3704 (set_attr "shift" "1")
3705 (set_attr "arch" "32,a")
3706 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3707
3708 (define_insn "*not_shiftsi_compare0_scratch"
3709 [(set (reg:CC_NOOV CC_REGNUM)
3710 (compare:CC_NOOV
3711 (not:SI (match_operator:SI 3 "shift_operator"
3712 [(match_operand:SI 1 "s_register_operand" "r,r")
3713 (match_operand:SI 2 "shift_amount_operand" "M,rM")]))
3714 (const_int 0)))
3715 (clobber (match_scratch:SI 0 "=r,r"))]
3716 "TARGET_32BIT"
3717 "mvns%?\\t%0, %1%S3"
3718 [(set_attr "conds" "set")
3719 (set_attr "shift" "1")
3720 (set_attr "arch" "32,a")
3721 (set_attr "type" "mvn_shift,mvn_shift_reg")])
3722
3723 ;; We don't really have extzv, but defining this using shifts helps
3724 ;; to reduce register pressure later on.
3725
3726 (define_expand "extzv"
3727 [(set (match_operand 0 "s_register_operand")
3728 (zero_extract (match_operand 1 "nonimmediate_operand")
3729 (match_operand 2 "const_int_operand")
3730 (match_operand 3 "const_int_operand")))]
3731 "TARGET_THUMB1 || arm_arch_thumb2"
3732 "
3733 {
3734 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]);
3735 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]);
3736
3737 if (arm_arch_thumb2)
3738 {
3739 HOST_WIDE_INT width = INTVAL (operands[2]);
3740 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3741
3742 if (unaligned_access && MEM_P (operands[1])
3743 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0)
3744 {
3745 rtx base_addr;
3746
3747 if (BYTES_BIG_ENDIAN)
3748 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width
3749 - bitpos;
3750
3751 if (width == 32)
3752 {
3753 base_addr = adjust_address (operands[1], SImode,
3754 bitpos / BITS_PER_UNIT);
3755 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3756 }
3757 else
3758 {
3759 rtx dest = operands[0];
3760 rtx tmp = gen_reg_rtx (SImode);
3761
3762 /* We may get a paradoxical subreg here. Strip it off. */
3763 if (GET_CODE (dest) == SUBREG
3764 && GET_MODE (dest) == SImode
3765 && GET_MODE (SUBREG_REG (dest)) == HImode)
3766 dest = SUBREG_REG (dest);
3767
3768 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3769 FAIL;
3770
3771 base_addr = adjust_address (operands[1], HImode,
3772 bitpos / BITS_PER_UNIT);
3773 emit_insn (gen_unaligned_loadhiu (tmp, base_addr));
3774 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3775 }
3776 DONE;
3777 }
3778 else if (s_register_operand (operands[1], GET_MODE (operands[1])))
3779 {
3780 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2],
3781 operands[3]));
3782 DONE;
3783 }
3784 else
3785 FAIL;
3786 }
3787
3788 if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3789 FAIL;
3790
3791 operands[3] = GEN_INT (rshift);
3792
3793 if (lshift == 0)
3794 {
3795 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3]));
3796 DONE;
3797 }
3798
3799 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift),
3800 operands[3], gen_reg_rtx (SImode)));
3801 DONE;
3802 }"
3803 )
3804
3805 ;; Helper for extzv, for the Thumb-1 register-shifts case.
3806
3807 (define_expand "extzv_t1"
3808 [(set (match_operand:SI 4 "s_register_operand")
3809 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
3810 (match_operand:SI 2 "const_int_operand")))
3811 (set (match_operand:SI 0 "s_register_operand")
3812 (lshiftrt:SI (match_dup 4)
3813 (match_operand:SI 3 "const_int_operand")))]
3814 "TARGET_THUMB1"
3815 "")
3816
3817 (define_expand "extv"
3818 [(set (match_operand 0 "s_register_operand")
3819 (sign_extract (match_operand 1 "nonimmediate_operand")
3820 (match_operand 2 "const_int_operand")
3821 (match_operand 3 "const_int_operand")))]
3822 "arm_arch_thumb2"
3823 {
3824 HOST_WIDE_INT width = INTVAL (operands[2]);
3825 HOST_WIDE_INT bitpos = INTVAL (operands[3]);
3826
3827 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32)
3828 && (bitpos % BITS_PER_UNIT) == 0)
3829 {
3830 rtx base_addr;
3831
3832 if (BYTES_BIG_ENDIAN)
3833 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos;
3834
3835 if (width == 32)
3836 {
3837 base_addr = adjust_address (operands[1], SImode,
3838 bitpos / BITS_PER_UNIT);
3839 emit_insn (gen_unaligned_loadsi (operands[0], base_addr));
3840 }
3841 else
3842 {
3843 rtx dest = operands[0];
3844 rtx tmp = gen_reg_rtx (SImode);
3845
3846 /* We may get a paradoxical subreg here. Strip it off. */
3847 if (GET_CODE (dest) == SUBREG
3848 && GET_MODE (dest) == SImode
3849 && GET_MODE (SUBREG_REG (dest)) == HImode)
3850 dest = SUBREG_REG (dest);
3851
3852 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
3853 FAIL;
3854
3855 base_addr = adjust_address (operands[1], HImode,
3856 bitpos / BITS_PER_UNIT);
3857 emit_insn (gen_unaligned_loadhis (tmp, base_addr));
3858 emit_move_insn (gen_lowpart (SImode, dest), tmp);
3859 }
3860
3861 DONE;
3862 }
3863 else if (!s_register_operand (operands[1], GET_MODE (operands[1])))
3864 FAIL;
3865 else if (GET_MODE (operands[0]) == SImode
3866 && GET_MODE (operands[1]) == SImode)
3867 {
3868 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2],
3869 operands[3]));
3870 DONE;
3871 }
3872
3873 FAIL;
3874 })
3875
3876 ; Helper to expand register forms of extv with the proper modes.
3877
3878 (define_expand "extv_regsi"
3879 [(set (match_operand:SI 0 "s_register_operand")
3880 (sign_extract:SI (match_operand:SI 1 "s_register_operand")
3881 (match_operand 2 "const_int_operand")
3882 (match_operand 3 "const_int_operand")))]
3883 ""
3884 {
3885 })
3886
3887 ; ARMv6+ unaligned load/store instructions (used for packed structure accesses).
3888
3889 (define_insn "unaligned_loaddi"
3890 [(set (match_operand:DI 0 "s_register_operand" "=r")
3891 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")]
3892 UNSPEC_UNALIGNED_LOAD))]
3893 "TARGET_32BIT && TARGET_LDRD"
3894 "*
3895 return output_move_double (operands, true, NULL);
3896 "
3897 [(set_attr "length" "8")
3898 (set_attr "type" "load_8")])
3899
3900 (define_insn "unaligned_loadsi"
3901 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
3902 (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")]
3903 UNSPEC_UNALIGNED_LOAD))]
3904 "unaligned_access"
3905 "@
3906 ldr\t%0, %1\t@ unaligned
3907 ldr%?\t%0, %1\t@ unaligned
3908 ldr%?\t%0, %1\t@ unaligned"
3909 [(set_attr "arch" "t1,t2,32")
3910 (set_attr "length" "2,2,4")
3911 (set_attr "predicable" "no,yes,yes")
3912 (set_attr "predicable_short_it" "no,yes,no")
3913 (set_attr "type" "load_4")])
3914
3915 ;; The 16-bit Thumb1 variant of ldrsh requires two registers in the
3916 ;; address (there's no immediate format). That's tricky to support
3917 ;; here and we don't really need this pattern for that case, so only
3918 ;; enable for 32-bit ISAs.
3919 (define_insn "unaligned_loadhis"
3920 [(set (match_operand:SI 0 "s_register_operand" "=r")
3921 (sign_extend:SI
3922 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")]
3923 UNSPEC_UNALIGNED_LOAD)))]
3924 "unaligned_access && TARGET_32BIT"
3925 "ldrsh%?\t%0, %1\t@ unaligned"
3926 [(set_attr "predicable" "yes")
3927 (set_attr "type" "load_byte")])
3928
3929 (define_insn "unaligned_loadhiu"
3930 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
3931 (zero_extend:SI
3932 (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")]
3933 UNSPEC_UNALIGNED_LOAD)))]
3934 "unaligned_access"
3935 "@
3936 ldrh\t%0, %1\t@ unaligned
3937 ldrh%?\t%0, %1\t@ unaligned
3938 ldrh%?\t%0, %1\t@ unaligned"
3939 [(set_attr "arch" "t1,t2,32")
3940 (set_attr "length" "2,2,4")
3941 (set_attr "predicable" "no,yes,yes")
3942 (set_attr "predicable_short_it" "no,yes,no")
3943 (set_attr "type" "load_byte")])
3944
3945 (define_insn "unaligned_storedi"
3946 [(set (match_operand:DI 0 "memory_operand" "=m")
3947 (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
3948 UNSPEC_UNALIGNED_STORE))]
3949 "TARGET_32BIT && TARGET_LDRD"
3950 "*
3951 return output_move_double (operands, true, NULL);
3952 "
3953 [(set_attr "length" "8")
3954 (set_attr "type" "store_8")])
3955
3956 (define_insn "unaligned_storesi"
3957 [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m")
3958 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")]
3959 UNSPEC_UNALIGNED_STORE))]
3960 "unaligned_access"
3961 "@
3962 str\t%1, %0\t@ unaligned
3963 str%?\t%1, %0\t@ unaligned
3964 str%?\t%1, %0\t@ unaligned"
3965 [(set_attr "arch" "t1,t2,32")
3966 (set_attr "length" "2,2,4")
3967 (set_attr "predicable" "no,yes,yes")
3968 (set_attr "predicable_short_it" "no,yes,no")
3969 (set_attr "type" "store_4")])
3970
3971 (define_insn "unaligned_storehi"
3972 [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m")
3973 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")]
3974 UNSPEC_UNALIGNED_STORE))]
3975 "unaligned_access"
3976 "@
3977 strh\t%1, %0\t@ unaligned
3978 strh%?\t%1, %0\t@ unaligned
3979 strh%?\t%1, %0\t@ unaligned"
3980 [(set_attr "arch" "t1,t2,32")
3981 (set_attr "length" "2,2,4")
3982 (set_attr "predicable" "no,yes,yes")
3983 (set_attr "predicable_short_it" "no,yes,no")
3984 (set_attr "type" "store_4")])
3985
3986
3987 (define_insn "*extv_reg"
3988 [(set (match_operand:SI 0 "s_register_operand" "=r")
3989 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
3990 (match_operand:SI 2 "const_int_operand" "n")
3991 (match_operand:SI 3 "const_int_operand" "n")))]
3992 "arm_arch_thumb2
3993 && IN_RANGE (INTVAL (operands[3]), 0, 31)
3994 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
3995 "sbfx%?\t%0, %1, %3, %2"
3996 [(set_attr "length" "4")
3997 (set_attr "predicable" "yes")
3998 (set_attr "type" "bfm")]
3999 )
4000
4001 (define_insn "extzv_t2"
4002 [(set (match_operand:SI 0 "s_register_operand" "=r")
4003 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r")
4004 (match_operand:SI 2 "const_int_operand" "n")
4005 (match_operand:SI 3 "const_int_operand" "n")))]
4006 "arm_arch_thumb2
4007 && IN_RANGE (INTVAL (operands[3]), 0, 31)
4008 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))"
4009 "ubfx%?\t%0, %1, %3, %2"
4010 [(set_attr "length" "4")
4011 (set_attr "predicable" "yes")
4012 (set_attr "type" "bfm")]
4013 )
4014
4015
4016 ;; Division instructions
4017 (define_insn "divsi3"
4018 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4019 (div:SI (match_operand:SI 1 "s_register_operand" "r,r")
4020 (match_operand:SI 2 "s_register_operand" "r,r")))]
4021 "TARGET_IDIV"
4022 "@
4023 sdiv%?\t%0, %1, %2
4024 sdiv\t%0, %1, %2"
4025 [(set_attr "arch" "32,v8mb")
4026 (set_attr "predicable" "yes")
4027 (set_attr "type" "sdiv")]
4028 )
4029
4030 (define_insn "udivsi3"
4031 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4032 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r")
4033 (match_operand:SI 2 "s_register_operand" "r,r")))]
4034 "TARGET_IDIV"
4035 "@
4036 udiv%?\t%0, %1, %2
4037 udiv\t%0, %1, %2"
4038 [(set_attr "arch" "32,v8mb")
4039 (set_attr "predicable" "yes")
4040 (set_attr "type" "udiv")]
4041 )
4042
4043 \f
4044 ;; Unary arithmetic insns
4045
4046 (define_expand "negvsi3"
4047 [(match_operand:SI 0 "register_operand")
4048 (match_operand:SI 1 "register_operand")
4049 (match_operand 2 "")]
4050 "TARGET_32BIT"
4051 {
4052 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1]));
4053 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4054
4055 DONE;
4056 })
4057
4058 (define_expand "negvdi3"
4059 [(match_operand:DI 0 "register_operand")
4060 (match_operand:DI 1 "register_operand")
4061 (match_operand 2 "")]
4062 "TARGET_ARM"
4063 {
4064 emit_insn (gen_negdi2_compare (operands[0], operands[1]));
4065 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]);
4066
4067 DONE;
4068 })
4069
4070
4071 (define_insn_and_split "negdi2_compare"
4072 [(set (reg:CC CC_REGNUM)
4073 (compare:CC
4074 (const_int 0)
4075 (match_operand:DI 1 "register_operand" "0,r")))
4076 (set (match_operand:DI 0 "register_operand" "=r,&r")
4077 (minus:DI (const_int 0) (match_dup 1)))]
4078 "TARGET_ARM"
4079 "#"
4080 "&& reload_completed"
4081 [(parallel [(set (reg:CC CC_REGNUM)
4082 (compare:CC (const_int 0) (match_dup 1)))
4083 (set (match_dup 0) (minus:SI (const_int 0)
4084 (match_dup 1)))])
4085 (parallel [(set (reg:CC CC_REGNUM)
4086 (compare:CC (const_int 0) (match_dup 3)))
4087 (set (match_dup 2)
4088 (minus:SI
4089 (minus:SI (const_int 0) (match_dup 3))
4090 (ltu:SI (reg:CC CC_REGNUM)
4091 (const_int 0))))])]
4092 {
4093 operands[2] = gen_highpart (SImode, operands[0]);
4094 operands[0] = gen_lowpart (SImode, operands[0]);
4095 operands[3] = gen_highpart (SImode, operands[1]);
4096 operands[1] = gen_lowpart (SImode, operands[1]);
4097 }
4098 [(set_attr "conds" "set")
4099 (set_attr "length" "8")
4100 (set_attr "type" "multiple")]
4101 )
4102
4103 (define_expand "negdi2"
4104 [(parallel
4105 [(set (match_operand:DI 0 "s_register_operand")
4106 (neg:DI (match_operand:DI 1 "s_register_operand")))
4107 (clobber (reg:CC CC_REGNUM))])]
4108 "TARGET_EITHER"
4109 )
4110
4111 ;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1).
4112 ;; The first alternative allows the common case of a *full* overlap.
4113 (define_insn_and_split "*negdi2_insn"
4114 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4115 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r")))
4116 (clobber (reg:CC CC_REGNUM))]
4117 "TARGET_32BIT"
4118 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM)
4119 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2)
4120 "TARGET_32BIT"
4121 [(parallel [(set (reg:CC CC_REGNUM)
4122 (compare:CC (const_int 0) (match_dup 1)))
4123 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4124 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
4125 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
4126 {
4127 operands[2] = gen_highpart (SImode, operands[0]);
4128 operands[0] = gen_lowpart (SImode, operands[0]);
4129 operands[3] = gen_highpart (SImode, operands[1]);
4130 operands[1] = gen_lowpart (SImode, operands[1]);
4131 }
4132 [(set_attr "conds" "clob")
4133 (set_attr "length" "8")
4134 (set_attr "type" "multiple")]
4135 )
4136
4137 (define_insn "*negsi2_carryin_compare"
4138 [(set (reg:CC CC_REGNUM)
4139 (compare:CC (const_int 0)
4140 (match_operand:SI 1 "s_register_operand" "r")))
4141 (set (match_operand:SI 0 "s_register_operand" "=r")
4142 (minus:SI (minus:SI (const_int 0)
4143 (match_dup 1))
4144 (match_operand:SI 2 "arm_borrow_operation" "")))]
4145 "TARGET_ARM"
4146 "rscs\\t%0, %1, #0"
4147 [(set_attr "conds" "set")
4148 (set_attr "type" "alus_imm")]
4149 )
4150
4151 (define_expand "negsi2"
4152 [(set (match_operand:SI 0 "s_register_operand")
4153 (neg:SI (match_operand:SI 1 "s_register_operand")))]
4154 "TARGET_EITHER"
4155 ""
4156 )
4157
4158 (define_insn "*arm_negsi2"
4159 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4160 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4161 "TARGET_32BIT"
4162 "rsb%?\\t%0, %1, #0"
4163 [(set_attr "predicable" "yes")
4164 (set_attr "predicable_short_it" "yes,no")
4165 (set_attr "arch" "t2,*")
4166 (set_attr "length" "4")
4167 (set_attr "type" "alu_sreg")]
4168 )
4169
4170 (define_expand "negsf2"
4171 [(set (match_operand:SF 0 "s_register_operand")
4172 (neg:SF (match_operand:SF 1 "s_register_operand")))]
4173 "TARGET_32BIT && TARGET_HARD_FLOAT"
4174 ""
4175 )
4176
4177 (define_expand "negdf2"
4178 [(set (match_operand:DF 0 "s_register_operand")
4179 (neg:DF (match_operand:DF 1 "s_register_operand")))]
4180 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4181 "")
4182
4183 (define_insn_and_split "*zextendsidi_negsi"
4184 [(set (match_operand:DI 0 "s_register_operand" "=r")
4185 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))]
4186 "TARGET_32BIT"
4187 "#"
4188 ""
4189 [(set (match_dup 2)
4190 (neg:SI (match_dup 1)))
4191 (set (match_dup 3)
4192 (const_int 0))]
4193 {
4194 operands[2] = gen_lowpart (SImode, operands[0]);
4195 operands[3] = gen_highpart (SImode, operands[0]);
4196 }
4197 [(set_attr "length" "8")
4198 (set_attr "type" "multiple")]
4199 )
4200
4201 ;; Negate an extended 32-bit value.
4202 (define_insn_and_split "*negdi_extendsidi"
4203 [(set (match_operand:DI 0 "s_register_operand" "=l,r")
4204 (neg:DI (sign_extend:DI
4205 (match_operand:SI 1 "s_register_operand" "l,r"))))
4206 (clobber (reg:CC CC_REGNUM))]
4207 "TARGET_32BIT"
4208 "#"
4209 "&& reload_completed"
4210 [(const_int 0)]
4211 {
4212 rtx low = gen_lowpart (SImode, operands[0]);
4213 rtx high = gen_highpart (SImode, operands[0]);
4214
4215 if (reg_overlap_mentioned_p (low, operands[1]))
4216 {
4217 /* Input overlaps the low word of the output. Use:
4218 asr Rhi, Rin, #31
4219 rsbs Rlo, Rin, #0
4220 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
4221 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
4222
4223 emit_insn (gen_rtx_SET (high,
4224 gen_rtx_ASHIFTRT (SImode, operands[1],
4225 GEN_INT (31))));
4226
4227 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1]));
4228 if (TARGET_ARM)
4229 emit_insn (gen_rtx_SET (high,
4230 gen_rtx_MINUS (SImode,
4231 gen_rtx_MINUS (SImode,
4232 const0_rtx,
4233 high),
4234 gen_rtx_LTU (SImode,
4235 cc_reg,
4236 const0_rtx))));
4237 else
4238 {
4239 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1));
4240 emit_insn (gen_rtx_SET (high,
4241 gen_rtx_MINUS (SImode,
4242 gen_rtx_MINUS (SImode,
4243 high,
4244 two_x),
4245 gen_rtx_LTU (SImode,
4246 cc_reg,
4247 const0_rtx))));
4248 }
4249 }
4250 else
4251 {
4252 /* No overlap, or overlap on high word. Use:
4253 rsb Rlo, Rin, #0
4254 bic Rhi, Rlo, Rin
4255 asr Rhi, Rhi, #31
4256 Flags not needed for this sequence. */
4257 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1])));
4258 emit_insn (gen_rtx_SET (high,
4259 gen_rtx_AND (SImode,
4260 gen_rtx_NOT (SImode, operands[1]),
4261 low)));
4262 emit_insn (gen_rtx_SET (high,
4263 gen_rtx_ASHIFTRT (SImode, high,
4264 GEN_INT (31))));
4265 }
4266 DONE;
4267 }
4268 [(set_attr "length" "12")
4269 (set_attr "arch" "t2,*")
4270 (set_attr "type" "multiple")]
4271 )
4272
4273 (define_insn_and_split "*negdi_zero_extendsidi"
4274 [(set (match_operand:DI 0 "s_register_operand" "=r,&r")
4275 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))))
4276 (clobber (reg:CC CC_REGNUM))]
4277 "TARGET_32BIT"
4278 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0"
4279 ;; Don't care what register is input to sbc,
4280 ;; since we just need to propagate the carry.
4281 "&& reload_completed"
4282 [(parallel [(set (reg:CC CC_REGNUM)
4283 (compare:CC (const_int 0) (match_dup 1)))
4284 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
4285 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
4286 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
4287 {
4288 operands[2] = gen_highpart (SImode, operands[0]);
4289 operands[0] = gen_lowpart (SImode, operands[0]);
4290 }
4291 [(set_attr "conds" "clob")
4292 (set_attr "length" "8")
4293 (set_attr "type" "multiple")] ;; length in thumb is 4
4294 )
4295
4296 ;; abssi2 doesn't really clobber the condition codes if a different register
4297 ;; is being set. To keep things simple, assume during rtl manipulations that
4298 ;; it does, but tell the final scan operator the truth. Similarly for
4299 ;; (neg (abs...))
4300
4301 (define_expand "abssi2"
4302 [(parallel
4303 [(set (match_operand:SI 0 "s_register_operand")
4304 (abs:SI (match_operand:SI 1 "s_register_operand")))
4305 (clobber (match_dup 2))])]
4306 "TARGET_EITHER"
4307 "
4308 if (TARGET_THUMB1)
4309 operands[2] = gen_rtx_SCRATCH (SImode);
4310 else
4311 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
4312 ")
4313
4314 (define_insn_and_split "*arm_abssi2"
4315 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4316 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
4317 (clobber (reg:CC CC_REGNUM))]
4318 "TARGET_ARM"
4319 "#"
4320 "&& reload_completed"
4321 [(const_int 0)]
4322 {
4323 /* if (which_alternative == 0) */
4324 if (REGNO(operands[0]) == REGNO(operands[1]))
4325 {
4326 /* Emit the pattern:
4327 cmp\\t%0, #0\;rsblt\\t%0, %0, #0
4328 [(set (reg:CC CC_REGNUM)
4329 (compare:CC (match_dup 0) (const_int 0)))
4330 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0))
4331 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))]
4332 */
4333 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4334 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4335 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4336 (gen_rtx_LT (SImode,
4337 gen_rtx_REG (CCmode, CC_REGNUM),
4338 const0_rtx)),
4339 (gen_rtx_SET (operands[0],
4340 (gen_rtx_MINUS (SImode,
4341 const0_rtx,
4342 operands[1]))))));
4343 DONE;
4344 }
4345 else
4346 {
4347 /* Emit the pattern:
4348 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
4349 [(set (match_dup 0)
4350 (xor:SI (match_dup 1)
4351 (ashiftrt:SI (match_dup 1) (const_int 31))))
4352 (set (match_dup 0)
4353 (minus:SI (match_dup 0)
4354 (ashiftrt:SI (match_dup 1) (const_int 31))))]
4355 */
4356 emit_insn (gen_rtx_SET (operands[0],
4357 gen_rtx_XOR (SImode,
4358 gen_rtx_ASHIFTRT (SImode,
4359 operands[1],
4360 GEN_INT (31)),
4361 operands[1])));
4362 emit_insn (gen_rtx_SET (operands[0],
4363 gen_rtx_MINUS (SImode,
4364 operands[0],
4365 gen_rtx_ASHIFTRT (SImode,
4366 operands[1],
4367 GEN_INT (31)))));
4368 DONE;
4369 }
4370 }
4371 [(set_attr "conds" "clob,*")
4372 (set_attr "shift" "1")
4373 (set_attr "predicable" "no, yes")
4374 (set_attr "length" "8")
4375 (set_attr "type" "multiple")]
4376 )
4377
4378 (define_insn_and_split "*arm_neg_abssi2"
4379 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
4380 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
4381 (clobber (reg:CC CC_REGNUM))]
4382 "TARGET_ARM"
4383 "#"
4384 "&& reload_completed"
4385 [(const_int 0)]
4386 {
4387 /* if (which_alternative == 0) */
4388 if (REGNO (operands[0]) == REGNO (operands[1]))
4389 {
4390 /* Emit the pattern:
4391 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0
4392 */
4393 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
4394 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx)));
4395 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
4396 gen_rtx_GT (SImode,
4397 gen_rtx_REG (CCmode, CC_REGNUM),
4398 const0_rtx),
4399 gen_rtx_SET (operands[0],
4400 (gen_rtx_MINUS (SImode,
4401 const0_rtx,
4402 operands[1])))));
4403 }
4404 else
4405 {
4406 /* Emit the pattern:
4407 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
4408 */
4409 emit_insn (gen_rtx_SET (operands[0],
4410 gen_rtx_XOR (SImode,
4411 gen_rtx_ASHIFTRT (SImode,
4412 operands[1],
4413 GEN_INT (31)),
4414 operands[1])));
4415 emit_insn (gen_rtx_SET (operands[0],
4416 gen_rtx_MINUS (SImode,
4417 gen_rtx_ASHIFTRT (SImode,
4418 operands[1],
4419 GEN_INT (31)),
4420 operands[0])));
4421 }
4422 DONE;
4423 }
4424 [(set_attr "conds" "clob,*")
4425 (set_attr "shift" "1")
4426 (set_attr "predicable" "no, yes")
4427 (set_attr "length" "8")
4428 (set_attr "type" "multiple")]
4429 )
4430
4431 (define_expand "abssf2"
4432 [(set (match_operand:SF 0 "s_register_operand")
4433 (abs:SF (match_operand:SF 1 "s_register_operand")))]
4434 "TARGET_32BIT && TARGET_HARD_FLOAT"
4435 "")
4436
4437 (define_expand "absdf2"
4438 [(set (match_operand:DF 0 "s_register_operand")
4439 (abs:DF (match_operand:DF 1 "s_register_operand")))]
4440 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4441 "")
4442
4443 (define_expand "sqrtsf2"
4444 [(set (match_operand:SF 0 "s_register_operand")
4445 (sqrt:SF (match_operand:SF 1 "s_register_operand")))]
4446 "TARGET_32BIT && TARGET_HARD_FLOAT"
4447 "")
4448
4449 (define_expand "sqrtdf2"
4450 [(set (match_operand:DF 0 "s_register_operand")
4451 (sqrt:DF (match_operand:DF 1 "s_register_operand")))]
4452 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
4453 "")
4454
4455 (define_expand "one_cmplsi2"
4456 [(set (match_operand:SI 0 "s_register_operand")
4457 (not:SI (match_operand:SI 1 "s_register_operand")))]
4458 "TARGET_EITHER"
4459 ""
4460 )
4461
4462 (define_insn "*arm_one_cmplsi2"
4463 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
4464 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))]
4465 "TARGET_32BIT"
4466 "mvn%?\\t%0, %1"
4467 [(set_attr "predicable" "yes")
4468 (set_attr "predicable_short_it" "yes,no")
4469 (set_attr "arch" "t2,*")
4470 (set_attr "length" "4")
4471 (set_attr "type" "mvn_reg")]
4472 )
4473
4474 (define_insn "*notsi_compare0"
4475 [(set (reg:CC_NOOV CC_REGNUM)
4476 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4477 (const_int 0)))
4478 (set (match_operand:SI 0 "s_register_operand" "=r")
4479 (not:SI (match_dup 1)))]
4480 "TARGET_32BIT"
4481 "mvns%?\\t%0, %1"
4482 [(set_attr "conds" "set")
4483 (set_attr "type" "mvn_reg")]
4484 )
4485
4486 (define_insn "*notsi_compare0_scratch"
4487 [(set (reg:CC_NOOV CC_REGNUM)
4488 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r"))
4489 (const_int 0)))
4490 (clobber (match_scratch:SI 0 "=r"))]
4491 "TARGET_32BIT"
4492 "mvns%?\\t%0, %1"
4493 [(set_attr "conds" "set")
4494 (set_attr "type" "mvn_reg")]
4495 )
4496 \f
4497 ;; Fixed <--> Floating conversion insns
4498
4499 (define_expand "floatsihf2"
4500 [(set (match_operand:HF 0 "general_operand")
4501 (float:HF (match_operand:SI 1 "general_operand")))]
4502 "TARGET_EITHER"
4503 "
4504 {
4505 rtx op1 = gen_reg_rtx (SFmode);
4506 expand_float (op1, operands[1], 0);
4507 op1 = convert_to_mode (HFmode, op1, 0);
4508 emit_move_insn (operands[0], op1);
4509 DONE;
4510 }"
4511 )
4512
4513 (define_expand "floatdihf2"
4514 [(set (match_operand:HF 0 "general_operand")
4515 (float:HF (match_operand:DI 1 "general_operand")))]
4516 "TARGET_EITHER"
4517 "
4518 {
4519 rtx op1 = gen_reg_rtx (SFmode);
4520 expand_float (op1, operands[1], 0);
4521 op1 = convert_to_mode (HFmode, op1, 0);
4522 emit_move_insn (operands[0], op1);
4523 DONE;
4524 }"
4525 )
4526
4527 (define_expand "floatsisf2"
4528 [(set (match_operand:SF 0 "s_register_operand")
4529 (float:SF (match_operand:SI 1 "s_register_operand")))]
4530 "TARGET_32BIT && TARGET_HARD_FLOAT"
4531 "
4532 ")
4533
4534 (define_expand "floatsidf2"
4535 [(set (match_operand:DF 0 "s_register_operand")
4536 (float:DF (match_operand:SI 1 "s_register_operand")))]
4537 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4538 "
4539 ")
4540
4541 (define_expand "fix_trunchfsi2"
4542 [(set (match_operand:SI 0 "general_operand")
4543 (fix:SI (fix:HF (match_operand:HF 1 "general_operand"))))]
4544 "TARGET_EITHER"
4545 "
4546 {
4547 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4548 expand_fix (operands[0], op1, 0);
4549 DONE;
4550 }"
4551 )
4552
4553 (define_expand "fix_trunchfdi2"
4554 [(set (match_operand:DI 0 "general_operand")
4555 (fix:DI (fix:HF (match_operand:HF 1 "general_operand"))))]
4556 "TARGET_EITHER"
4557 "
4558 {
4559 rtx op1 = convert_to_mode (SFmode, operands[1], 0);
4560 expand_fix (operands[0], op1, 0);
4561 DONE;
4562 }"
4563 )
4564
4565 (define_expand "fix_truncsfsi2"
4566 [(set (match_operand:SI 0 "s_register_operand")
4567 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand"))))]
4568 "TARGET_32BIT && TARGET_HARD_FLOAT"
4569 "
4570 ")
4571
4572 (define_expand "fix_truncdfsi2"
4573 [(set (match_operand:SI 0 "s_register_operand")
4574 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand"))))]
4575 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4576 "
4577 ")
4578
4579 ;; Truncation insns
4580
4581 (define_expand "truncdfsf2"
4582 [(set (match_operand:SF 0 "s_register_operand")
4583 (float_truncate:SF
4584 (match_operand:DF 1 "s_register_operand")))]
4585 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
4586 ""
4587 )
4588
4589 ;; DFmode to HFmode conversions on targets without a single-step hardware
4590 ;; instruction for it would have to go through SFmode. This is dangerous
4591 ;; as it introduces double rounding.
4592 ;;
4593 ;; Disable this pattern unless we are in an unsafe math mode, or we have
4594 ;; a single-step instruction.
4595
4596 (define_expand "truncdfhf2"
4597 [(set (match_operand:HF 0 "s_register_operand")
4598 (float_truncate:HF
4599 (match_operand:DF 1 "s_register_operand")))]
4600 "(TARGET_EITHER && flag_unsafe_math_optimizations)
4601 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)"
4602 {
4603 /* We don't have a direct instruction for this, so we must be in
4604 an unsafe math mode, and going via SFmode. */
4605
4606 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
4607 {
4608 rtx op1;
4609 op1 = convert_to_mode (SFmode, operands[1], 0);
4610 op1 = convert_to_mode (HFmode, op1, 0);
4611 emit_move_insn (operands[0], op1);
4612 DONE;
4613 }
4614 /* Otherwise, we will pick this up as a single instruction with
4615 no intermediary rounding. */
4616 }
4617 )
4618 \f
4619 ;; Zero and sign extension instructions.
4620
4621 (define_insn "zero_extend<mode>di2"
4622 [(set (match_operand:DI 0 "s_register_operand" "=r,?r")
4623 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>"
4624 "<qhs_zextenddi_cstr>")))]
4625 "TARGET_32BIT <qhs_zextenddi_cond>"
4626 "#"
4627 [(set_attr "length" "4,8")
4628 (set_attr "arch" "*,*")
4629 (set_attr "ce_count" "2")
4630 (set_attr "predicable" "yes")
4631 (set_attr "type" "mov_reg,multiple")]
4632 )
4633
4634 (define_insn "extend<mode>di2"
4635 [(set (match_operand:DI 0 "s_register_operand" "=r,?r,?r")
4636 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>"
4637 "<qhs_extenddi_cstr>")))]
4638 "TARGET_32BIT <qhs_sextenddi_cond>"
4639 "#"
4640 [(set_attr "length" "4,8,8")
4641 (set_attr "ce_count" "2")
4642 (set_attr "shift" "1")
4643 (set_attr "predicable" "yes")
4644 (set_attr "arch" "*,a,t")
4645 (set_attr "type" "mov_reg,multiple,multiple")]
4646 )
4647
4648 ;; Splits for all extensions to DImode
4649 (define_split
4650 [(set (match_operand:DI 0 "s_register_operand" "")
4651 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4652 "TARGET_32BIT"
4653 [(set (match_dup 0) (match_dup 1))]
4654 {
4655 rtx lo_part = gen_lowpart (SImode, operands[0]);
4656 machine_mode src_mode = GET_MODE (operands[1]);
4657
4658 if (src_mode == SImode)
4659 emit_move_insn (lo_part, operands[1]);
4660 else
4661 emit_insn (gen_rtx_SET (lo_part,
4662 gen_rtx_ZERO_EXTEND (SImode, operands[1])));
4663 operands[0] = gen_highpart (SImode, operands[0]);
4664 operands[1] = const0_rtx;
4665 })
4666
4667 (define_split
4668 [(set (match_operand:DI 0 "s_register_operand" "")
4669 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))]
4670 "TARGET_32BIT"
4671 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
4672 {
4673 rtx lo_part = gen_lowpart (SImode, operands[0]);
4674 machine_mode src_mode = GET_MODE (operands[1]);
4675
4676 if (src_mode == SImode)
4677 emit_move_insn (lo_part, operands[1]);
4678 else
4679 emit_insn (gen_rtx_SET (lo_part,
4680 gen_rtx_SIGN_EXTEND (SImode, operands[1])));
4681 operands[1] = lo_part;
4682 operands[0] = gen_highpart (SImode, operands[0]);
4683 })
4684
4685 (define_expand "zero_extendhisi2"
4686 [(set (match_operand:SI 0 "s_register_operand")
4687 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
4688 "TARGET_EITHER"
4689 {
4690 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1]))
4691 {
4692 emit_insn (gen_movhi_bytes (operands[0], operands[1]));
4693 DONE;
4694 }
4695 if (!arm_arch6 && !MEM_P (operands[1]))
4696 {
4697 rtx t = gen_lowpart (SImode, operands[1]);
4698 rtx tmp = gen_reg_rtx (SImode);
4699 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4700 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16)));
4701 DONE;
4702 }
4703 })
4704
4705 (define_split
4706 [(set (match_operand:SI 0 "s_register_operand" "")
4707 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))]
4708 "!TARGET_THUMB2 && !arm_arch6"
4709 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4710 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4711 {
4712 operands[2] = gen_lowpart (SImode, operands[1]);
4713 })
4714
4715 (define_insn "*arm_zero_extendhisi2"
4716 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4717 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
4718 "TARGET_ARM && arm_arch4 && !arm_arch6"
4719 "@
4720 #
4721 ldrh%?\\t%0, %1"
4722 [(set_attr "type" "alu_shift_reg,load_byte")
4723 (set_attr "predicable" "yes")]
4724 )
4725
4726 (define_insn "*arm_zero_extendhisi2_v6"
4727 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4728 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4729 "TARGET_ARM && arm_arch6"
4730 "@
4731 uxth%?\\t%0, %1
4732 ldrh%?\\t%0, %1"
4733 [(set_attr "predicable" "yes")
4734 (set_attr "type" "extend,load_byte")]
4735 )
4736
4737 (define_insn "*arm_zero_extendhisi2addsi"
4738 [(set (match_operand:SI 0 "s_register_operand" "=r")
4739 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4740 (match_operand:SI 2 "s_register_operand" "r")))]
4741 "TARGET_INT_SIMD"
4742 "uxtah%?\\t%0, %2, %1"
4743 [(set_attr "type" "alu_shift_reg")
4744 (set_attr "predicable" "yes")]
4745 )
4746
4747 (define_expand "zero_extendqisi2"
4748 [(set (match_operand:SI 0 "s_register_operand")
4749 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand")))]
4750 "TARGET_EITHER"
4751 {
4752 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1]))
4753 {
4754 emit_insn (gen_andsi3 (operands[0],
4755 gen_lowpart (SImode, operands[1]),
4756 GEN_INT (255)));
4757 DONE;
4758 }
4759 if (!arm_arch6 && !MEM_P (operands[1]))
4760 {
4761 rtx t = gen_lowpart (SImode, operands[1]);
4762 rtx tmp = gen_reg_rtx (SImode);
4763 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
4764 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24)));
4765 DONE;
4766 }
4767 })
4768
4769 (define_split
4770 [(set (match_operand:SI 0 "s_register_operand" "")
4771 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))]
4772 "!arm_arch6"
4773 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4774 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
4775 {
4776 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
4777 if (TARGET_ARM)
4778 {
4779 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255)));
4780 DONE;
4781 }
4782 })
4783
4784 (define_insn "*arm_zero_extendqisi2"
4785 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4786 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
4787 "TARGET_ARM && !arm_arch6"
4788 "@
4789 #
4790 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
4791 [(set_attr "length" "8,4")
4792 (set_attr "type" "alu_shift_reg,load_byte")
4793 (set_attr "predicable" "yes")]
4794 )
4795
4796 (define_insn "*arm_zero_extendqisi2_v6"
4797 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4798 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))]
4799 "TARGET_ARM && arm_arch6"
4800 "@
4801 uxtb%?\\t%0, %1
4802 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
4803 [(set_attr "type" "extend,load_byte")
4804 (set_attr "predicable" "yes")]
4805 )
4806
4807 (define_insn "*arm_zero_extendqisi2addsi"
4808 [(set (match_operand:SI 0 "s_register_operand" "=r")
4809 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
4810 (match_operand:SI 2 "s_register_operand" "r")))]
4811 "TARGET_INT_SIMD"
4812 "uxtab%?\\t%0, %2, %1"
4813 [(set_attr "predicable" "yes")
4814 (set_attr "type" "alu_shift_reg")]
4815 )
4816
4817 (define_split
4818 [(set (match_operand:SI 0 "s_register_operand" "")
4819 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0)))
4820 (clobber (match_operand:SI 2 "s_register_operand" ""))]
4821 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN"
4822 [(set (match_dup 2) (match_dup 1))
4823 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4824 ""
4825 )
4826
4827 (define_split
4828 [(set (match_operand:SI 0 "s_register_operand" "")
4829 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3)))
4830 (clobber (match_operand:SI 2 "s_register_operand" ""))]
4831 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN"
4832 [(set (match_dup 2) (match_dup 1))
4833 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))]
4834 ""
4835 )
4836
4837
4838 (define_split
4839 [(set (match_operand:SI 0 "s_register_operand" "")
4840 (IOR_XOR:SI (and:SI (ashift:SI
4841 (match_operand:SI 1 "s_register_operand" "")
4842 (match_operand:SI 2 "const_int_operand" ""))
4843 (match_operand:SI 3 "const_int_operand" ""))
4844 (zero_extend:SI
4845 (match_operator 5 "subreg_lowpart_operator"
4846 [(match_operand:SI 4 "s_register_operand" "")]))))]
4847 "TARGET_32BIT
4848 && (UINTVAL (operands[3])
4849 == (GET_MODE_MASK (GET_MODE (operands[5]))
4850 & (GET_MODE_MASK (GET_MODE (operands[5]))
4851 << (INTVAL (operands[2])))))"
4852 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2))
4853 (match_dup 4)))
4854 (set (match_dup 0) (zero_extend:SI (match_dup 5)))]
4855 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);"
4856 )
4857
4858 (define_insn "*compareqi_eq0"
4859 [(set (reg:CC_Z CC_REGNUM)
4860 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r")
4861 (const_int 0)))]
4862 "TARGET_32BIT"
4863 "tst%?\\t%0, #255"
4864 [(set_attr "conds" "set")
4865 (set_attr "predicable" "yes")
4866 (set_attr "type" "logic_imm")]
4867 )
4868
4869 (define_expand "extendhisi2"
4870 [(set (match_operand:SI 0 "s_register_operand")
4871 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand")))]
4872 "TARGET_EITHER"
4873 {
4874 if (TARGET_THUMB1)
4875 {
4876 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1]));
4877 DONE;
4878 }
4879 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4)
4880 {
4881 emit_insn (gen_extendhisi2_mem (operands[0], operands[1]));
4882 DONE;
4883 }
4884
4885 if (!arm_arch6 && !MEM_P (operands[1]))
4886 {
4887 rtx t = gen_lowpart (SImode, operands[1]);
4888 rtx tmp = gen_reg_rtx (SImode);
4889 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16)));
4890 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16)));
4891 DONE;
4892 }
4893 })
4894
4895 (define_split
4896 [(parallel
4897 [(set (match_operand:SI 0 "register_operand" "")
4898 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))
4899 (clobber (match_scratch:SI 2 ""))])]
4900 "!arm_arch6"
4901 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4902 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4903 {
4904 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
4905 })
4906
4907 ;; This pattern will only be used when ldsh is not available
4908 (define_expand "extendhisi2_mem"
4909 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
4910 (set (match_dup 3)
4911 (zero_extend:SI (match_dup 7)))
4912 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24)))
4913 (set (match_operand:SI 0 "" "")
4914 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))]
4915 "TARGET_ARM"
4916 "
4917 {
4918 rtx mem1, mem2;
4919 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
4920
4921 mem1 = change_address (operands[1], QImode, addr);
4922 mem2 = change_address (operands[1], QImode,
4923 plus_constant (Pmode, addr, 1));
4924 operands[0] = gen_lowpart (SImode, operands[0]);
4925 operands[1] = mem1;
4926 operands[2] = gen_reg_rtx (SImode);
4927 operands[3] = gen_reg_rtx (SImode);
4928 operands[6] = gen_reg_rtx (SImode);
4929 operands[7] = mem2;
4930
4931 if (BYTES_BIG_ENDIAN)
4932 {
4933 operands[4] = operands[2];
4934 operands[5] = operands[3];
4935 }
4936 else
4937 {
4938 operands[4] = operands[3];
4939 operands[5] = operands[2];
4940 }
4941 }"
4942 )
4943
4944 (define_split
4945 [(set (match_operand:SI 0 "register_operand" "")
4946 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4947 "!arm_arch6"
4948 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4949 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4950 {
4951 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
4952 })
4953
4954 (define_insn "*arm_extendhisi2"
4955 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4956 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4957 "TARGET_ARM && arm_arch4 && !arm_arch6"
4958 "@
4959 #
4960 ldrsh%?\\t%0, %1"
4961 [(set_attr "length" "8,4")
4962 (set_attr "type" "alu_shift_reg,load_byte")
4963 (set_attr "predicable" "yes")]
4964 )
4965
4966 ;; ??? Check Thumb-2 pool range
4967 (define_insn "*arm_extendhisi2_v6"
4968 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
4969 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))]
4970 "TARGET_32BIT && arm_arch6"
4971 "@
4972 sxth%?\\t%0, %1
4973 ldrsh%?\\t%0, %1"
4974 [(set_attr "type" "extend,load_byte")
4975 (set_attr "predicable" "yes")]
4976 )
4977
4978 (define_insn "*arm_extendhisi2addsi"
4979 [(set (match_operand:SI 0 "s_register_operand" "=r")
4980 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r"))
4981 (match_operand:SI 2 "s_register_operand" "r")))]
4982 "TARGET_INT_SIMD"
4983 "sxtah%?\\t%0, %2, %1"
4984 [(set_attr "type" "alu_shift_reg")]
4985 )
4986
4987 (define_expand "extendqihi2"
4988 [(set (match_dup 2)
4989 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")
4990 (const_int 24)))
4991 (set (match_operand:HI 0 "s_register_operand")
4992 (ashiftrt:SI (match_dup 2)
4993 (const_int 24)))]
4994 "TARGET_ARM"
4995 "
4996 {
4997 if (arm_arch4 && MEM_P (operands[1]))
4998 {
4999 emit_insn (gen_rtx_SET (operands[0],
5000 gen_rtx_SIGN_EXTEND (HImode, operands[1])));
5001 DONE;
5002 }
5003 if (!s_register_operand (operands[1], QImode))
5004 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5005 operands[0] = gen_lowpart (SImode, operands[0]);
5006 operands[1] = gen_lowpart (SImode, operands[1]);
5007 operands[2] = gen_reg_rtx (SImode);
5008 }"
5009 )
5010
5011 (define_insn "*arm_extendqihi_insn"
5012 [(set (match_operand:HI 0 "s_register_operand" "=r")
5013 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))]
5014 "TARGET_ARM && arm_arch4"
5015 "ldrsb%?\\t%0, %1"
5016 [(set_attr "type" "load_byte")
5017 (set_attr "predicable" "yes")]
5018 )
5019
5020 (define_expand "extendqisi2"
5021 [(set (match_operand:SI 0 "s_register_operand")
5022 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op")))]
5023 "TARGET_EITHER"
5024 {
5025 if (!arm_arch4 && MEM_P (operands[1]))
5026 operands[1] = copy_to_mode_reg (QImode, operands[1]);
5027
5028 if (!arm_arch6 && !MEM_P (operands[1]))
5029 {
5030 rtx t = gen_lowpart (SImode, operands[1]);
5031 rtx tmp = gen_reg_rtx (SImode);
5032 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24)));
5033 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24)));
5034 DONE;
5035 }
5036 })
5037
5038 (define_split
5039 [(set (match_operand:SI 0 "register_operand" "")
5040 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
5041 "!arm_arch6"
5042 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
5043 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
5044 {
5045 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0);
5046 })
5047
5048 (define_insn "*arm_extendqisi"
5049 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5050 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5051 "TARGET_ARM && arm_arch4 && !arm_arch6"
5052 "@
5053 #
5054 ldrsb%?\\t%0, %1"
5055 [(set_attr "length" "8,4")
5056 (set_attr "type" "alu_shift_reg,load_byte")
5057 (set_attr "predicable" "yes")]
5058 )
5059
5060 (define_insn "*arm_extendqisi_v6"
5061 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
5062 (sign_extend:SI
5063 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))]
5064 "TARGET_ARM && arm_arch6"
5065 "@
5066 sxtb%?\\t%0, %1
5067 ldrsb%?\\t%0, %1"
5068 [(set_attr "type" "extend,load_byte")
5069 (set_attr "predicable" "yes")]
5070 )
5071
5072 (define_insn "*arm_extendqisi2addsi"
5073 [(set (match_operand:SI 0 "s_register_operand" "=r")
5074 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r"))
5075 (match_operand:SI 2 "s_register_operand" "r")))]
5076 "TARGET_INT_SIMD"
5077 "sxtab%?\\t%0, %2, %1"
5078 [(set_attr "type" "alu_shift_reg")
5079 (set_attr "predicable" "yes")]
5080 )
5081
5082 (define_expand "extendsfdf2"
5083 [(set (match_operand:DF 0 "s_register_operand")
5084 (float_extend:DF (match_operand:SF 1 "s_register_operand")))]
5085 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
5086 ""
5087 )
5088
5089 ;; HFmode -> DFmode conversions where we don't have an instruction for it
5090 ;; must go through SFmode.
5091 ;;
5092 ;; This is always safe for an extend.
5093
5094 (define_expand "extendhfdf2"
5095 [(set (match_operand:DF 0 "s_register_operand")
5096 (float_extend:DF (match_operand:HF 1 "s_register_operand")))]
5097 "TARGET_EITHER"
5098 {
5099 /* We don't have a direct instruction for this, so go via SFmode. */
5100 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE))
5101 {
5102 rtx op1;
5103 op1 = convert_to_mode (SFmode, operands[1], 0);
5104 op1 = convert_to_mode (DFmode, op1, 0);
5105 emit_insn (gen_movdf (operands[0], op1));
5106 DONE;
5107 }
5108 /* Otherwise, we're done producing RTL and will pick up the correct
5109 pattern to do this with one rounding-step in a single instruction. */
5110 }
5111 )
5112 \f
5113 ;; Move insns (including loads and stores)
5114
5115 ;; XXX Just some ideas about movti.
5116 ;; I don't think these are a good idea on the arm, there just aren't enough
5117 ;; registers
5118 ;;(define_expand "loadti"
5119 ;; [(set (match_operand:TI 0 "s_register_operand")
5120 ;; (mem:TI (match_operand:SI 1 "address_operand")))]
5121 ;; "" "")
5122
5123 ;;(define_expand "storeti"
5124 ;; [(set (mem:TI (match_operand:TI 0 "address_operand"))
5125 ;; (match_operand:TI 1 "s_register_operand"))]
5126 ;; "" "")
5127
5128 ;;(define_expand "movti"
5129 ;; [(set (match_operand:TI 0 "general_operand")
5130 ;; (match_operand:TI 1 "general_operand"))]
5131 ;; ""
5132 ;; "
5133 ;;{
5134 ;; rtx insn;
5135 ;;
5136 ;; if (MEM_P (operands[0]) && MEM_P (operands[1]))
5137 ;; operands[1] = copy_to_reg (operands[1]);
5138 ;; if (MEM_P (operands[0]))
5139 ;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);
5140 ;; else if (MEM_P (operands[1]))
5141 ;; insn = gen_loadti (operands[0], XEXP (operands[1], 0));
5142 ;; else
5143 ;; FAIL;
5144 ;;
5145 ;; emit_insn (insn);
5146 ;; DONE;
5147 ;;}")
5148
5149 ;; Recognize garbage generated above.
5150
5151 ;;(define_insn ""
5152 ;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m")
5153 ;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))]
5154 ;; ""
5155 ;; "*
5156 ;; {
5157 ;; register mem = (which_alternative < 3);
5158 ;; register const char *template;
5159 ;;
5160 ;; operands[mem] = XEXP (operands[mem], 0);
5161 ;; switch (which_alternative)
5162 ;; {
5163 ;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;
5164 ;; case 1: template = \"ldmia\\t%1!, %M0\"; break;
5165 ;; case 2: template = \"ldmia\\t%1, %M0\"; break;
5166 ;; case 3: template = \"stmdb\\t%0!, %M1\"; break;
5167 ;; case 4: template = \"stmia\\t%0!, %M1\"; break;
5168 ;; case 5: template = \"stmia\\t%0, %M1\"; break;
5169 ;; }
5170 ;; output_asm_insn (template, operands);
5171 ;; return \"\";
5172 ;; }")
5173
5174 (define_expand "movdi"
5175 [(set (match_operand:DI 0 "general_operand")
5176 (match_operand:DI 1 "general_operand"))]
5177 "TARGET_EITHER"
5178 "
5179 gcc_checking_assert (aligned_operand (operands[0], DImode));
5180 gcc_checking_assert (aligned_operand (operands[1], DImode));
5181 if (can_create_pseudo_p ())
5182 {
5183 if (!REG_P (operands[0]))
5184 operands[1] = force_reg (DImode, operands[1]);
5185 }
5186 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM
5187 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode))
5188 {
5189 /* Avoid LDRD's into an odd-numbered register pair in ARM state
5190 when expanding function calls. */
5191 gcc_assert (can_create_pseudo_p ());
5192 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))
5193 {
5194 /* Perform load into legal reg pair first, then move. */
5195 rtx reg = gen_reg_rtx (DImode);
5196 emit_insn (gen_movdi (reg, operands[1]));
5197 operands[1] = reg;
5198 }
5199 emit_move_insn (gen_lowpart (SImode, operands[0]),
5200 gen_lowpart (SImode, operands[1]));
5201 emit_move_insn (gen_highpart (SImode, operands[0]),
5202 gen_highpart (SImode, operands[1]));
5203 DONE;
5204 }
5205 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM
5206 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode))
5207 {
5208 /* Avoid STRD's from an odd-numbered register pair in ARM state
5209 when expanding function prologue. */
5210 gcc_assert (can_create_pseudo_p ());
5211 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
5212 ? gen_reg_rtx (DImode)
5213 : operands[0];
5214 emit_move_insn (gen_lowpart (SImode, split_dest),
5215 gen_lowpart (SImode, operands[1]));
5216 emit_move_insn (gen_highpart (SImode, split_dest),
5217 gen_highpart (SImode, operands[1]));
5218 if (split_dest != operands[0])
5219 emit_insn (gen_movdi (operands[0], split_dest));
5220 DONE;
5221 }
5222 "
5223 )
5224
5225 (define_insn "*arm_movdi"
5226 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
5227 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))]
5228 "TARGET_32BIT
5229 && !(TARGET_HARD_FLOAT)
5230 && !TARGET_IWMMXT
5231 && ( register_operand (operands[0], DImode)
5232 || register_operand (operands[1], DImode))"
5233 "*
5234 switch (which_alternative)
5235 {
5236 case 0:
5237 case 1:
5238 case 2:
5239 return \"#\";
5240 case 3:
5241 /* Cannot load it directly, split to load it via MOV / MOVT. */
5242 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
5243 return \"#\";
5244 /* Fall through. */
5245 default:
5246 return output_move_double (operands, true, NULL);
5247 }
5248 "
5249 [(set_attr "length" "8,12,16,8,8")
5250 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
5251 (set_attr "arm_pool_range" "*,*,*,1020,*")
5252 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
5253 (set_attr "thumb2_pool_range" "*,*,*,4094,*")
5254 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
5255 )
5256
5257 (define_split
5258 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5259 (match_operand:ANY64 1 "immediate_operand" ""))]
5260 "TARGET_32BIT
5261 && reload_completed
5262 && (arm_disable_literal_pool
5263 || (arm_const_double_inline_cost (operands[1])
5264 <= arm_max_const_double_inline_cost ()))"
5265 [(const_int 0)]
5266 "
5267 arm_split_constant (SET, SImode, curr_insn,
5268 INTVAL (gen_lowpart (SImode, operands[1])),
5269 gen_lowpart (SImode, operands[0]), NULL_RTX, 0);
5270 arm_split_constant (SET, SImode, curr_insn,
5271 INTVAL (gen_highpart_mode (SImode,
5272 GET_MODE (operands[0]),
5273 operands[1])),
5274 gen_highpart (SImode, operands[0]), NULL_RTX, 0);
5275 DONE;
5276 "
5277 )
5278
5279 ; If optimizing for size, or if we have load delay slots, then
5280 ; we want to split the constant into two separate operations.
5281 ; In both cases this may split a trivial part into a single data op
5282 ; leaving a single complex constant to load. We can also get longer
5283 ; offsets in a LDR which means we get better chances of sharing the pool
5284 ; entries. Finally, we can normally do a better job of scheduling
5285 ; LDR instructions than we can with LDM.
5286 ; This pattern will only match if the one above did not.
5287 (define_split
5288 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5289 (match_operand:ANY64 1 "const_double_operand" ""))]
5290 "TARGET_ARM && reload_completed
5291 && arm_const_double_by_parts (operands[1])"
5292 [(set (match_dup 0) (match_dup 1))
5293 (set (match_dup 2) (match_dup 3))]
5294 "
5295 operands[2] = gen_highpart (SImode, operands[0]);
5296 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]),
5297 operands[1]);
5298 operands[0] = gen_lowpart (SImode, operands[0]);
5299 operands[1] = gen_lowpart (SImode, operands[1]);
5300 "
5301 )
5302
5303 (define_split
5304 [(set (match_operand:ANY64 0 "arm_general_register_operand" "")
5305 (match_operand:ANY64 1 "arm_general_register_operand" ""))]
5306 "TARGET_EITHER && reload_completed"
5307 [(set (match_dup 0) (match_dup 1))
5308 (set (match_dup 2) (match_dup 3))]
5309 "
5310 operands[2] = gen_highpart (SImode, operands[0]);
5311 operands[3] = gen_highpart (SImode, operands[1]);
5312 operands[0] = gen_lowpart (SImode, operands[0]);
5313 operands[1] = gen_lowpart (SImode, operands[1]);
5314
5315 /* Handle a partial overlap. */
5316 if (rtx_equal_p (operands[0], operands[3]))
5317 {
5318 rtx tmp0 = operands[0];
5319 rtx tmp1 = operands[1];
5320
5321 operands[0] = operands[2];
5322 operands[1] = operands[3];
5323 operands[2] = tmp0;
5324 operands[3] = tmp1;
5325 }
5326 "
5327 )
5328
5329 ;; We can't actually do base+index doubleword loads if the index and
5330 ;; destination overlap. Split here so that we at least have chance to
5331 ;; schedule.
5332 (define_split
5333 [(set (match_operand:DI 0 "s_register_operand" "")
5334 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
5335 (match_operand:SI 2 "s_register_operand" ""))))]
5336 "TARGET_LDRD
5337 && reg_overlap_mentioned_p (operands[0], operands[1])
5338 && reg_overlap_mentioned_p (operands[0], operands[2])"
5339 [(set (match_dup 4)
5340 (plus:SI (match_dup 1)
5341 (match_dup 2)))
5342 (set (match_dup 0)
5343 (mem:DI (match_dup 4)))]
5344 "
5345 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
5346 "
5347 )
5348
5349 (define_expand "movsi"
5350 [(set (match_operand:SI 0 "general_operand")
5351 (match_operand:SI 1 "general_operand"))]
5352 "TARGET_EITHER"
5353 "
5354 {
5355 rtx base, offset, tmp;
5356
5357 gcc_checking_assert (aligned_operand (operands[0], SImode));
5358 gcc_checking_assert (aligned_operand (operands[1], SImode));
5359 if (TARGET_32BIT || TARGET_HAVE_MOVT)
5360 {
5361 /* Everything except mem = const or mem = mem can be done easily. */
5362 if (MEM_P (operands[0]))
5363 operands[1] = force_reg (SImode, operands[1]);
5364 if (arm_general_register_operand (operands[0], SImode)
5365 && CONST_INT_P (operands[1])
5366 && !(const_ok_for_arm (INTVAL (operands[1]))
5367 || const_ok_for_arm (~INTVAL (operands[1]))))
5368 {
5369 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET))
5370 {
5371 emit_insn (gen_rtx_SET (operands[0], operands[1]));
5372 DONE;
5373 }
5374 else
5375 {
5376 arm_split_constant (SET, SImode, NULL_RTX,
5377 INTVAL (operands[1]), operands[0], NULL_RTX,
5378 optimize && can_create_pseudo_p ());
5379 DONE;
5380 }
5381 }
5382 }
5383 else /* Target doesn't have MOVT... */
5384 {
5385 if (can_create_pseudo_p ())
5386 {
5387 if (!REG_P (operands[0]))
5388 operands[1] = force_reg (SImode, operands[1]);
5389 }
5390 }
5391
5392 split_const (operands[1], &base, &offset);
5393 if (INTVAL (offset) != 0
5394 && targetm.cannot_force_const_mem (SImode, operands[1]))
5395 {
5396 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
5397 emit_move_insn (tmp, base);
5398 emit_insn (gen_addsi3 (operands[0], tmp, offset));
5399 DONE;
5400 }
5401
5402 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0];
5403
5404 /* Recognize the case where operand[1] is a reference to thread-local
5405 data and load its address to a register. Offsets have been split off
5406 already. */
5407 if (arm_tls_referenced_p (operands[1]))
5408 operands[1] = legitimize_tls_address (operands[1], tmp);
5409 else if (flag_pic
5410 && (CONSTANT_P (operands[1])
5411 || symbol_mentioned_p (operands[1])
5412 || label_mentioned_p (operands[1])))
5413 operands[1] =
5414 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false);
5415 }
5416 "
5417 )
5418
5419 ;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and
5420 ;; LO_SUM adds in the high bits. Fortunately these are opaque operations
5421 ;; so this does not matter.
5422 (define_insn "*arm_movt"
5423 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
5424 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
5425 (match_operand:SI 2 "general_operand" "i,i")))]
5426 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])"
5427 "@
5428 movt%?\t%0, #:upper16:%c2
5429 movt\t%0, #:upper16:%c2"
5430 [(set_attr "arch" "32,v8mb")
5431 (set_attr "predicable" "yes")
5432 (set_attr "length" "4")
5433 (set_attr "type" "alu_sreg")]
5434 )
5435
5436 (define_insn "*arm_movsi_insn"
5437 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
5438 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))]
5439 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
5440 && ( register_operand (operands[0], SImode)
5441 || register_operand (operands[1], SImode))"
5442 "@
5443 mov%?\\t%0, %1
5444 mov%?\\t%0, %1
5445 mvn%?\\t%0, #%B1
5446 movw%?\\t%0, %1
5447 ldr%?\\t%0, %1
5448 str%?\\t%1, %0"
5449 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4")
5450 (set_attr "predicable" "yes")
5451 (set_attr "arch" "*,*,*,v6t2,*,*")
5452 (set_attr "pool_range" "*,*,*,*,4096,*")
5453 (set_attr "neg_pool_range" "*,*,*,*,4084,*")]
5454 )
5455
5456 (define_split
5457 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5458 (match_operand:SI 1 "const_int_operand" ""))]
5459 "(TARGET_32BIT || TARGET_HAVE_MOVT)
5460 && (!(const_ok_for_arm (INTVAL (operands[1]))
5461 || const_ok_for_arm (~INTVAL (operands[1]))))"
5462 [(clobber (const_int 0))]
5463 "
5464 arm_split_constant (SET, SImode, NULL_RTX,
5465 INTVAL (operands[1]), operands[0], NULL_RTX, 0);
5466 DONE;
5467 "
5468 )
5469
5470 ;; A normal way to do (symbol + offset) requires three instructions at least
5471 ;; (depends on how big the offset is) as below:
5472 ;; movw r0, #:lower16:g
5473 ;; movw r0, #:upper16:g
5474 ;; adds r0, #4
5475 ;;
5476 ;; A better way would be:
5477 ;; movw r0, #:lower16:g+4
5478 ;; movw r0, #:upper16:g+4
5479 ;;
5480 ;; The limitation of this way is that the length of offset should be a 16-bit
5481 ;; signed value, because current assembler only supports REL type relocation for
5482 ;; such case. If the more powerful RELA type is supported in future, we should
5483 ;; update this pattern to go with better way.
5484 (define_split
5485 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5486 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "")
5487 (match_operand:SI 2 "const_int_operand" ""))))]
5488 "TARGET_THUMB
5489 && TARGET_HAVE_MOVT
5490 && arm_disable_literal_pool
5491 && reload_completed
5492 && GET_CODE (operands[1]) == SYMBOL_REF"
5493 [(clobber (const_int 0))]
5494 "
5495 int offset = INTVAL (operands[2]);
5496
5497 if (offset < -0x8000 || offset > 0x7fff)
5498 {
5499 arm_emit_movpair (operands[0], operands[1]);
5500 emit_insn (gen_rtx_SET (operands[0],
5501 gen_rtx_PLUS (SImode, operands[0], operands[2])));
5502 }
5503 else
5504 {
5505 rtx op = gen_rtx_CONST (SImode,
5506 gen_rtx_PLUS (SImode, operands[1], operands[2]));
5507 arm_emit_movpair (operands[0], op);
5508 }
5509 "
5510 )
5511
5512 ;; Split symbol_refs at the later stage (after cprop), instead of generating
5513 ;; movt/movw pair directly at expand. Otherwise corresponding high_sum
5514 ;; and lo_sum would be merged back into memory load at cprop. However,
5515 ;; if the default is to prefer movt/movw rather than a load from the constant
5516 ;; pool, the performance is better.
5517 (define_split
5518 [(set (match_operand:SI 0 "arm_general_register_operand" "")
5519 (match_operand:SI 1 "general_operand" ""))]
5520 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF
5521 && !target_word_relocations
5522 && !arm_tls_referenced_p (operands[1])"
5523 [(clobber (const_int 0))]
5524 {
5525 arm_emit_movpair (operands[0], operands[1]);
5526 DONE;
5527 })
5528
5529 ;; When generating pic, we need to load the symbol offset into a register.
5530 ;; So that the optimizer does not confuse this with a normal symbol load
5531 ;; we use an unspec. The offset will be loaded from a constant pool entry,
5532 ;; since that is the only type of relocation we can use.
5533
5534 ;; Wrap calculation of the whole PIC address in a single pattern for the
5535 ;; benefit of optimizers, particularly, PRE and HOIST. Calculation of
5536 ;; a PIC address involves two loads from memory, so we want to CSE it
5537 ;; as often as possible.
5538 ;; This pattern will be split into one of the pic_load_addr_* patterns
5539 ;; and a move after GCSE optimizations.
5540 ;;
5541 ;; Note: Update arm.c: legitimize_pic_address() when changing this pattern.
5542 (define_expand "calculate_pic_address"
5543 [(set (match_operand:SI 0 "register_operand")
5544 (mem:SI (plus:SI (match_operand:SI 1 "register_operand")
5545 (unspec:SI [(match_operand:SI 2 "" "")]
5546 UNSPEC_PIC_SYM))))]
5547 "flag_pic"
5548 )
5549
5550 ;; Split calculate_pic_address into pic_load_addr_* and a move.
5551 (define_split
5552 [(set (match_operand:SI 0 "register_operand" "")
5553 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "")
5554 (unspec:SI [(match_operand:SI 2 "" "")]
5555 UNSPEC_PIC_SYM))))]
5556 "flag_pic"
5557 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM))
5558 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))]
5559 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];"
5560 )
5561
5562 ;; operand1 is the memory address to go into
5563 ;; pic_load_addr_32bit.
5564 ;; operand2 is the PIC label to be emitted
5565 ;; from pic_add_dot_plus_eight.
5566 ;; We do this to allow hoisting of the entire insn.
5567 (define_insn_and_split "pic_load_addr_unified"
5568 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l")
5569 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX")
5570 (match_operand:SI 2 "" "")]
5571 UNSPEC_PIC_UNIFIED))]
5572 "flag_pic"
5573 "#"
5574 "&& reload_completed"
5575 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM))
5576 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3)
5577 (match_dup 2)] UNSPEC_PIC_BASE))]
5578 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);"
5579 [(set_attr "type" "load_4,load_4,load_4")
5580 (set_attr "pool_range" "4096,4094,1022")
5581 (set_attr "neg_pool_range" "4084,0,0")
5582 (set_attr "arch" "a,t2,t1")
5583 (set_attr "length" "8,6,4")]
5584 )
5585
5586 ;; The rather odd constraints on the following are to force reload to leave
5587 ;; the insn alone, and to force the minipool generation pass to then move
5588 ;; the GOT symbol to memory.
5589
5590 (define_insn "pic_load_addr_32bit"
5591 [(set (match_operand:SI 0 "s_register_operand" "=r")
5592 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5593 "TARGET_32BIT && flag_pic"
5594 "ldr%?\\t%0, %1"
5595 [(set_attr "type" "load_4")
5596 (set (attr "pool_range")
5597 (if_then_else (eq_attr "is_thumb" "no")
5598 (const_int 4096)
5599 (const_int 4094)))
5600 (set (attr "neg_pool_range")
5601 (if_then_else (eq_attr "is_thumb" "no")
5602 (const_int 4084)
5603 (const_int 0)))]
5604 )
5605
5606 (define_insn "pic_load_addr_thumb1"
5607 [(set (match_operand:SI 0 "s_register_operand" "=l")
5608 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))]
5609 "TARGET_THUMB1 && flag_pic"
5610 "ldr\\t%0, %1"
5611 [(set_attr "type" "load_4")
5612 (set (attr "pool_range") (const_int 1018))]
5613 )
5614
5615 (define_insn "pic_add_dot_plus_four"
5616 [(set (match_operand:SI 0 "register_operand" "=r")
5617 (unspec:SI [(match_operand:SI 1 "register_operand" "0")
5618 (const_int 4)
5619 (match_operand 2 "" "")]
5620 UNSPEC_PIC_BASE))]
5621 "TARGET_THUMB"
5622 "*
5623 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5624 INTVAL (operands[2]));
5625 return \"add\\t%0, %|pc\";
5626 "
5627 [(set_attr "length" "2")
5628 (set_attr "type" "alu_sreg")]
5629 )
5630
5631 (define_insn "pic_add_dot_plus_eight"
5632 [(set (match_operand:SI 0 "register_operand" "=r")
5633 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5634 (const_int 8)
5635 (match_operand 2 "" "")]
5636 UNSPEC_PIC_BASE))]
5637 "TARGET_ARM"
5638 "*
5639 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5640 INTVAL (operands[2]));
5641 return \"add%?\\t%0, %|pc, %1\";
5642 "
5643 [(set_attr "predicable" "yes")
5644 (set_attr "type" "alu_sreg")]
5645 )
5646
5647 (define_insn "tls_load_dot_plus_eight"
5648 [(set (match_operand:SI 0 "register_operand" "=r")
5649 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
5650 (const_int 8)
5651 (match_operand 2 "" "")]
5652 UNSPEC_PIC_BASE)))]
5653 "TARGET_ARM"
5654 "*
5655 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
5656 INTVAL (operands[2]));
5657 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
5658 "
5659 [(set_attr "predicable" "yes")
5660 (set_attr "type" "load_4")]
5661 )
5662
5663 ;; PIC references to local variables can generate pic_add_dot_plus_eight
5664 ;; followed by a load. These sequences can be crunched down to
5665 ;; tls_load_dot_plus_eight by a peephole.
5666
5667 (define_peephole2
5668 [(set (match_operand:SI 0 "register_operand" "")
5669 (unspec:SI [(match_operand:SI 3 "register_operand" "")
5670 (const_int 8)
5671 (match_operand 1 "" "")]
5672 UNSPEC_PIC_BASE))
5673 (set (match_operand:SI 2 "arm_general_register_operand" "")
5674 (mem:SI (match_dup 0)))]
5675 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])"
5676 [(set (match_dup 2)
5677 (mem:SI (unspec:SI [(match_dup 3)
5678 (const_int 8)
5679 (match_dup 1)]
5680 UNSPEC_PIC_BASE)))]
5681 ""
5682 )
5683
5684 (define_insn "pic_offset_arm"
5685 [(set (match_operand:SI 0 "register_operand" "=r")
5686 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
5687 (unspec:SI [(match_operand:SI 2 "" "X")]
5688 UNSPEC_PIC_OFFSET))))]
5689 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic"
5690 "ldr%?\\t%0, [%1,%2]"
5691 [(set_attr "type" "load_4")]
5692 )
5693
5694 (define_expand "builtin_setjmp_receiver"
5695 [(label_ref (match_operand 0 "" ""))]
5696 "flag_pic"
5697 "
5698 {
5699 /* r3 is clobbered by set/longjmp, so we can use it as a scratch
5700 register. */
5701 if (arm_pic_register != INVALID_REGNUM)
5702 arm_load_pic_register (1UL << 3, NULL_RTX);
5703 DONE;
5704 }")
5705
5706 ;; If copying one reg to another we can set the condition codes according to
5707 ;; its value. Such a move is common after a return from subroutine and the
5708 ;; result is being tested against zero.
5709
5710 (define_insn "*movsi_compare0"
5711 [(set (reg:CC CC_REGNUM)
5712 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r")
5713 (const_int 0)))
5714 (set (match_operand:SI 0 "s_register_operand" "=r,r")
5715 (match_dup 1))]
5716 "TARGET_32BIT"
5717 "@
5718 cmp%?\\t%0, #0
5719 subs%?\\t%0, %1, #0"
5720 [(set_attr "conds" "set")
5721 (set_attr "type" "alus_imm,alus_imm")]
5722 )
5723
5724 ;; Subroutine to store a half word from a register into memory.
5725 ;; Operand 0 is the source register (HImode)
5726 ;; Operand 1 is the destination address in a register (SImode)
5727
5728 ;; In both this routine and the next, we must be careful not to spill
5729 ;; a memory address of reg+large_const into a separate PLUS insn, since this
5730 ;; can generate unrecognizable rtl.
5731
5732 (define_expand "storehi"
5733 [;; store the low byte
5734 (set (match_operand 1 "" "") (match_dup 3))
5735 ;; extract the high byte
5736 (set (match_dup 2)
5737 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5738 ;; store the high byte
5739 (set (match_dup 4) (match_dup 5))]
5740 "TARGET_ARM"
5741 "
5742 {
5743 rtx op1 = operands[1];
5744 rtx addr = XEXP (op1, 0);
5745 enum rtx_code code = GET_CODE (addr);
5746
5747 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5748 || code == MINUS)
5749 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr));
5750
5751 operands[4] = adjust_address (op1, QImode, 1);
5752 operands[1] = adjust_address (operands[1], QImode, 0);
5753 operands[3] = gen_lowpart (QImode, operands[0]);
5754 operands[0] = gen_lowpart (SImode, operands[0]);
5755 operands[2] = gen_reg_rtx (SImode);
5756 operands[5] = gen_lowpart (QImode, operands[2]);
5757 }"
5758 )
5759
5760 (define_expand "storehi_bigend"
5761 [(set (match_dup 4) (match_dup 3))
5762 (set (match_dup 2)
5763 (ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
5764 (set (match_operand 1 "" "") (match_dup 5))]
5765 "TARGET_ARM"
5766 "
5767 {
5768 rtx op1 = operands[1];
5769 rtx addr = XEXP (op1, 0);
5770 enum rtx_code code = GET_CODE (addr);
5771
5772 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5773 || code == MINUS)
5774 op1 = replace_equiv_address (op1, force_reg (SImode, addr));
5775
5776 operands[4] = adjust_address (op1, QImode, 1);
5777 operands[1] = adjust_address (operands[1], QImode, 0);
5778 operands[3] = gen_lowpart (QImode, operands[0]);
5779 operands[0] = gen_lowpart (SImode, operands[0]);
5780 operands[2] = gen_reg_rtx (SImode);
5781 operands[5] = gen_lowpart (QImode, operands[2]);
5782 }"
5783 )
5784
5785 ;; Subroutine to store a half word integer constant into memory.
5786 (define_expand "storeinthi"
5787 [(set (match_operand 0 "" "")
5788 (match_operand 1 "" ""))
5789 (set (match_dup 3) (match_dup 2))]
5790 "TARGET_ARM"
5791 "
5792 {
5793 HOST_WIDE_INT value = INTVAL (operands[1]);
5794 rtx addr = XEXP (operands[0], 0);
5795 rtx op0 = operands[0];
5796 enum rtx_code code = GET_CODE (addr);
5797
5798 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1)))
5799 || code == MINUS)
5800 op0 = replace_equiv_address (op0, force_reg (SImode, addr));
5801
5802 operands[1] = gen_reg_rtx (SImode);
5803 if (BYTES_BIG_ENDIAN)
5804 {
5805 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255)));
5806 if ((value & 255) == ((value >> 8) & 255))
5807 operands[2] = operands[1];
5808 else
5809 {
5810 operands[2] = gen_reg_rtx (SImode);
5811 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255)));
5812 }
5813 }
5814 else
5815 {
5816 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255)));
5817 if ((value & 255) == ((value >> 8) & 255))
5818 operands[2] = operands[1];
5819 else
5820 {
5821 operands[2] = gen_reg_rtx (SImode);
5822 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255)));
5823 }
5824 }
5825
5826 operands[3] = adjust_address (op0, QImode, 1);
5827 operands[0] = adjust_address (operands[0], QImode, 0);
5828 operands[2] = gen_lowpart (QImode, operands[2]);
5829 operands[1] = gen_lowpart (QImode, operands[1]);
5830 }"
5831 )
5832
5833 (define_expand "storehi_single_op"
5834 [(set (match_operand:HI 0 "memory_operand")
5835 (match_operand:HI 1 "general_operand"))]
5836 "TARGET_32BIT && arm_arch4"
5837 "
5838 if (!s_register_operand (operands[1], HImode))
5839 operands[1] = copy_to_mode_reg (HImode, operands[1]);
5840 "
5841 )
5842
5843 (define_expand "movhi"
5844 [(set (match_operand:HI 0 "general_operand")
5845 (match_operand:HI 1 "general_operand"))]
5846 "TARGET_EITHER"
5847 "
5848 gcc_checking_assert (aligned_operand (operands[0], HImode));
5849 gcc_checking_assert (aligned_operand (operands[1], HImode));
5850 if (TARGET_ARM)
5851 {
5852 if (can_create_pseudo_p ())
5853 {
5854 if (MEM_P (operands[0]))
5855 {
5856 if (arm_arch4)
5857 {
5858 emit_insn (gen_storehi_single_op (operands[0], operands[1]));
5859 DONE;
5860 }
5861 if (CONST_INT_P (operands[1]))
5862 emit_insn (gen_storeinthi (operands[0], operands[1]));
5863 else
5864 {
5865 if (MEM_P (operands[1]))
5866 operands[1] = force_reg (HImode, operands[1]);
5867 if (BYTES_BIG_ENDIAN)
5868 emit_insn (gen_storehi_bigend (operands[1], operands[0]));
5869 else
5870 emit_insn (gen_storehi (operands[1], operands[0]));
5871 }
5872 DONE;
5873 }
5874 /* Sign extend a constant, and keep it in an SImode reg. */
5875 else if (CONST_INT_P (operands[1]))
5876 {
5877 rtx reg = gen_reg_rtx (SImode);
5878 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5879
5880 /* If the constant is already valid, leave it alone. */
5881 if (!const_ok_for_arm (val))
5882 {
5883 /* If setting all the top bits will make the constant
5884 loadable in a single instruction, then set them.
5885 Otherwise, sign extend the number. */
5886
5887 if (const_ok_for_arm (~(val | ~0xffff)))
5888 val |= ~0xffff;
5889 else if (val & 0x8000)
5890 val |= ~0xffff;
5891 }
5892
5893 emit_insn (gen_movsi (reg, GEN_INT (val)));
5894 operands[1] = gen_lowpart (HImode, reg);
5895 }
5896 else if (arm_arch4 && optimize && can_create_pseudo_p ()
5897 && MEM_P (operands[1]))
5898 {
5899 rtx reg = gen_reg_rtx (SImode);
5900
5901 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
5902 operands[1] = gen_lowpart (HImode, reg);
5903 }
5904 else if (!arm_arch4)
5905 {
5906 if (MEM_P (operands[1]))
5907 {
5908 rtx base;
5909 rtx offset = const0_rtx;
5910 rtx reg = gen_reg_rtx (SImode);
5911
5912 if ((REG_P (base = XEXP (operands[1], 0))
5913 || (GET_CODE (base) == PLUS
5914 && (CONST_INT_P (offset = XEXP (base, 1)))
5915 && ((INTVAL(offset) & 1) != 1)
5916 && REG_P (base = XEXP (base, 0))))
5917 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32)
5918 {
5919 rtx new_rtx;
5920
5921 new_rtx = widen_memory_access (operands[1], SImode,
5922 ((INTVAL (offset) & ~3)
5923 - INTVAL (offset)));
5924 emit_insn (gen_movsi (reg, new_rtx));
5925 if (((INTVAL (offset) & 2) != 0)
5926 ^ (BYTES_BIG_ENDIAN ? 1 : 0))
5927 {
5928 rtx reg2 = gen_reg_rtx (SImode);
5929
5930 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16)));
5931 reg = reg2;
5932 }
5933 }
5934 else
5935 emit_insn (gen_movhi_bytes (reg, operands[1]));
5936
5937 operands[1] = gen_lowpart (HImode, reg);
5938 }
5939 }
5940 }
5941 /* Handle loading a large integer during reload. */
5942 else if (CONST_INT_P (operands[1])
5943 && !const_ok_for_arm (INTVAL (operands[1]))
5944 && !const_ok_for_arm (~INTVAL (operands[1])))
5945 {
5946 /* Writing a constant to memory needs a scratch, which should
5947 be handled with SECONDARY_RELOADs. */
5948 gcc_assert (REG_P (operands[0]));
5949
5950 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
5951 emit_insn (gen_movsi (operands[0], operands[1]));
5952 DONE;
5953 }
5954 }
5955 else if (TARGET_THUMB2)
5956 {
5957 /* Thumb-2 can do everything except mem=mem and mem=const easily. */
5958 if (can_create_pseudo_p ())
5959 {
5960 if (!REG_P (operands[0]))
5961 operands[1] = force_reg (HImode, operands[1]);
5962 /* Zero extend a constant, and keep it in an SImode reg. */
5963 else if (CONST_INT_P (operands[1]))
5964 {
5965 rtx reg = gen_reg_rtx (SImode);
5966 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff;
5967
5968 emit_insn (gen_movsi (reg, GEN_INT (val)));
5969 operands[1] = gen_lowpart (HImode, reg);
5970 }
5971 }
5972 }
5973 else /* TARGET_THUMB1 */
5974 {
5975 if (can_create_pseudo_p ())
5976 {
5977 if (CONST_INT_P (operands[1]))
5978 {
5979 rtx reg = gen_reg_rtx (SImode);
5980
5981 emit_insn (gen_movsi (reg, operands[1]));
5982 operands[1] = gen_lowpart (HImode, reg);
5983 }
5984
5985 /* ??? We shouldn't really get invalid addresses here, but this can
5986 happen if we are passed a SP (never OK for HImode/QImode) or
5987 virtual register (also rejected as illegitimate for HImode/QImode)
5988 relative address. */
5989 /* ??? This should perhaps be fixed elsewhere, for instance, in
5990 fixup_stack_1, by checking for other kinds of invalid addresses,
5991 e.g. a bare reference to a virtual register. This may confuse the
5992 alpha though, which must handle this case differently. */
5993 if (MEM_P (operands[0])
5994 && !memory_address_p (GET_MODE (operands[0]),
5995 XEXP (operands[0], 0)))
5996 operands[0]
5997 = replace_equiv_address (operands[0],
5998 copy_to_reg (XEXP (operands[0], 0)));
5999
6000 if (MEM_P (operands[1])
6001 && !memory_address_p (GET_MODE (operands[1]),
6002 XEXP (operands[1], 0)))
6003 operands[1]
6004 = replace_equiv_address (operands[1],
6005 copy_to_reg (XEXP (operands[1], 0)));
6006
6007 if (MEM_P (operands[1]) && optimize > 0)
6008 {
6009 rtx reg = gen_reg_rtx (SImode);
6010
6011 emit_insn (gen_zero_extendhisi2 (reg, operands[1]));
6012 operands[1] = gen_lowpart (HImode, reg);
6013 }
6014
6015 if (MEM_P (operands[0]))
6016 operands[1] = force_reg (HImode, operands[1]);
6017 }
6018 else if (CONST_INT_P (operands[1])
6019 && !satisfies_constraint_I (operands[1]))
6020 {
6021 /* Handle loading a large integer during reload. */
6022
6023 /* Writing a constant to memory needs a scratch, which should
6024 be handled with SECONDARY_RELOADs. */
6025 gcc_assert (REG_P (operands[0]));
6026
6027 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6028 emit_insn (gen_movsi (operands[0], operands[1]));
6029 DONE;
6030 }
6031 }
6032 "
6033 )
6034
6035 (define_expand "movhi_bytes"
6036 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" "")))
6037 (set (match_dup 3)
6038 (zero_extend:SI (match_dup 6)))
6039 (set (match_operand:SI 0 "" "")
6040 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))]
6041 "TARGET_ARM"
6042 "
6043 {
6044 rtx mem1, mem2;
6045 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
6046
6047 mem1 = change_address (operands[1], QImode, addr);
6048 mem2 = change_address (operands[1], QImode,
6049 plus_constant (Pmode, addr, 1));
6050 operands[0] = gen_lowpart (SImode, operands[0]);
6051 operands[1] = mem1;
6052 operands[2] = gen_reg_rtx (SImode);
6053 operands[3] = gen_reg_rtx (SImode);
6054 operands[6] = mem2;
6055
6056 if (BYTES_BIG_ENDIAN)
6057 {
6058 operands[4] = operands[2];
6059 operands[5] = operands[3];
6060 }
6061 else
6062 {
6063 operands[4] = operands[3];
6064 operands[5] = operands[2];
6065 }
6066 }"
6067 )
6068
6069 (define_expand "movhi_bigend"
6070 [(set (match_dup 2)
6071 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand") 0)
6072 (const_int 16)))
6073 (set (match_dup 3)
6074 (ashiftrt:SI (match_dup 2) (const_int 16)))
6075 (set (match_operand:HI 0 "s_register_operand")
6076 (match_dup 4))]
6077 "TARGET_ARM"
6078 "
6079 operands[2] = gen_reg_rtx (SImode);
6080 operands[3] = gen_reg_rtx (SImode);
6081 operands[4] = gen_lowpart (HImode, operands[3]);
6082 "
6083 )
6084
6085 ;; Pattern to recognize insn generated default case above
6086 (define_insn "*movhi_insn_arch4"
6087 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r")
6088 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))]
6089 "TARGET_ARM
6090 && arm_arch4 && !TARGET_HARD_FLOAT
6091 && (register_operand (operands[0], HImode)
6092 || register_operand (operands[1], HImode))"
6093 "@
6094 mov%?\\t%0, %1\\t%@ movhi
6095 mvn%?\\t%0, #%B1\\t%@ movhi
6096 movw%?\\t%0, %L1\\t%@ movhi
6097 strh%?\\t%1, %0\\t%@ movhi
6098 ldrh%?\\t%0, %1\\t%@ movhi"
6099 [(set_attr "predicable" "yes")
6100 (set_attr "pool_range" "*,*,*,*,256")
6101 (set_attr "neg_pool_range" "*,*,*,*,244")
6102 (set_attr "arch" "*,*,v6t2,*,*")
6103 (set_attr_alternative "type"
6104 [(if_then_else (match_operand 1 "const_int_operand" "")
6105 (const_string "mov_imm" )
6106 (const_string "mov_reg"))
6107 (const_string "mvn_imm")
6108 (const_string "mov_imm")
6109 (const_string "store_4")
6110 (const_string "load_4")])]
6111 )
6112
6113 (define_insn "*movhi_bytes"
6114 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r")
6115 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))]
6116 "TARGET_ARM && !TARGET_HARD_FLOAT"
6117 "@
6118 mov%?\\t%0, %1\\t%@ movhi
6119 mov%?\\t%0, %1\\t%@ movhi
6120 mvn%?\\t%0, #%B1\\t%@ movhi"
6121 [(set_attr "predicable" "yes")
6122 (set_attr "type" "mov_imm,mov_reg,mvn_imm")]
6123 )
6124
6125 ;; We use a DImode scratch because we may occasionally need an additional
6126 ;; temporary if the address isn't offsettable -- push_reload doesn't seem
6127 ;; to take any notice of the "o" constraints on reload_memory_operand operand.
6128 ;; The reload_in<m> and reload_out<m> patterns require special constraints
6129 ;; to be correctly handled in default_secondary_reload function.
6130 (define_expand "reload_outhi"
6131 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o")
6132 (match_operand:HI 1 "s_register_operand" "r")
6133 (match_operand:DI 2 "s_register_operand" "=&l")])]
6134 "TARGET_EITHER"
6135 "if (TARGET_ARM)
6136 arm_reload_out_hi (operands);
6137 else
6138 thumb_reload_out_hi (operands);
6139 DONE;
6140 "
6141 )
6142
6143 (define_expand "reload_inhi"
6144 [(parallel [(match_operand:HI 0 "s_register_operand" "=r")
6145 (match_operand:HI 1 "arm_reload_memory_operand" "o")
6146 (match_operand:DI 2 "s_register_operand" "=&r")])]
6147 "TARGET_EITHER"
6148 "
6149 if (TARGET_ARM)
6150 arm_reload_in_hi (operands);
6151 else
6152 thumb_reload_out_hi (operands);
6153 DONE;
6154 ")
6155
6156 (define_expand "movqi"
6157 [(set (match_operand:QI 0 "general_operand")
6158 (match_operand:QI 1 "general_operand"))]
6159 "TARGET_EITHER"
6160 "
6161 /* Everything except mem = const or mem = mem can be done easily */
6162
6163 if (can_create_pseudo_p ())
6164 {
6165 if (CONST_INT_P (operands[1]))
6166 {
6167 rtx reg = gen_reg_rtx (SImode);
6168
6169 /* For thumb we want an unsigned immediate, then we are more likely
6170 to be able to use a movs insn. */
6171 if (TARGET_THUMB)
6172 operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
6173
6174 emit_insn (gen_movsi (reg, operands[1]));
6175 operands[1] = gen_lowpart (QImode, reg);
6176 }
6177
6178 if (TARGET_THUMB)
6179 {
6180 /* ??? We shouldn't really get invalid addresses here, but this can
6181 happen if we are passed a SP (never OK for HImode/QImode) or
6182 virtual register (also rejected as illegitimate for HImode/QImode)
6183 relative address. */
6184 /* ??? This should perhaps be fixed elsewhere, for instance, in
6185 fixup_stack_1, by checking for other kinds of invalid addresses,
6186 e.g. a bare reference to a virtual register. This may confuse the
6187 alpha though, which must handle this case differently. */
6188 if (MEM_P (operands[0])
6189 && !memory_address_p (GET_MODE (operands[0]),
6190 XEXP (operands[0], 0)))
6191 operands[0]
6192 = replace_equiv_address (operands[0],
6193 copy_to_reg (XEXP (operands[0], 0)));
6194 if (MEM_P (operands[1])
6195 && !memory_address_p (GET_MODE (operands[1]),
6196 XEXP (operands[1], 0)))
6197 operands[1]
6198 = replace_equiv_address (operands[1],
6199 copy_to_reg (XEXP (operands[1], 0)));
6200 }
6201
6202 if (MEM_P (operands[1]) && optimize > 0)
6203 {
6204 rtx reg = gen_reg_rtx (SImode);
6205
6206 emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
6207 operands[1] = gen_lowpart (QImode, reg);
6208 }
6209
6210 if (MEM_P (operands[0]))
6211 operands[1] = force_reg (QImode, operands[1]);
6212 }
6213 else if (TARGET_THUMB
6214 && CONST_INT_P (operands[1])
6215 && !satisfies_constraint_I (operands[1]))
6216 {
6217 /* Handle loading a large integer during reload. */
6218
6219 /* Writing a constant to memory needs a scratch, which should
6220 be handled with SECONDARY_RELOADs. */
6221 gcc_assert (REG_P (operands[0]));
6222
6223 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
6224 emit_insn (gen_movsi (operands[0], operands[1]));
6225 DONE;
6226 }
6227 "
6228 )
6229
6230 (define_insn "*arm_movqi_insn"
6231 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m")
6232 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))]
6233 "TARGET_32BIT
6234 && ( register_operand (operands[0], QImode)
6235 || register_operand (operands[1], QImode))"
6236 "@
6237 mov%?\\t%0, %1
6238 mov%?\\t%0, %1
6239 mov%?\\t%0, %1
6240 mov%?\\t%0, %1
6241 mvn%?\\t%0, #%B1
6242 ldrb%?\\t%0, %1
6243 strb%?\\t%1, %0
6244 ldrb%?\\t%0, %1
6245 strb%?\\t%1, %0"
6246 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4")
6247 (set_attr "predicable" "yes")
6248 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no")
6249 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any")
6250 (set_attr "length" "2,4,4,2,4,2,2,4,4")]
6251 )
6252
6253 ;; HFmode moves
6254 (define_expand "movhf"
6255 [(set (match_operand:HF 0 "general_operand")
6256 (match_operand:HF 1 "general_operand"))]
6257 "TARGET_EITHER"
6258 "
6259 gcc_checking_assert (aligned_operand (operands[0], HFmode));
6260 gcc_checking_assert (aligned_operand (operands[1], HFmode));
6261 if (TARGET_32BIT)
6262 {
6263 if (MEM_P (operands[0]))
6264 operands[1] = force_reg (HFmode, operands[1]);
6265 }
6266 else /* TARGET_THUMB1 */
6267 {
6268 if (can_create_pseudo_p ())
6269 {
6270 if (!REG_P (operands[0]))
6271 operands[1] = force_reg (HFmode, operands[1]);
6272 }
6273 }
6274 "
6275 )
6276
6277 (define_insn "*arm32_movhf"
6278 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
6279 (match_operand:HF 1 "general_operand" " m,r,r,F"))]
6280 "TARGET_32BIT && !TARGET_HARD_FLOAT
6281 && ( s_register_operand (operands[0], HFmode)
6282 || s_register_operand (operands[1], HFmode))"
6283 "*
6284 switch (which_alternative)
6285 {
6286 case 0: /* ARM register from memory */
6287 return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
6288 case 1: /* memory from ARM register */
6289 return \"strh%?\\t%1, %0\\t%@ __fp16\";
6290 case 2: /* ARM register from ARM register */
6291 return \"mov%?\\t%0, %1\\t%@ __fp16\";
6292 case 3: /* ARM register from constant */
6293 {
6294 long bits;
6295 rtx ops[4];
6296
6297 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
6298 HFmode);
6299 ops[0] = operands[0];
6300 ops[1] = GEN_INT (bits);
6301 ops[2] = GEN_INT (bits & 0xff00);
6302 ops[3] = GEN_INT (bits & 0x00ff);
6303
6304 if (arm_arch_thumb2)
6305 output_asm_insn (\"movw%?\\t%0, %1\", ops);
6306 else
6307 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops);
6308 return \"\";
6309 }
6310 default:
6311 gcc_unreachable ();
6312 }
6313 "
6314 [(set_attr "conds" "unconditional")
6315 (set_attr "type" "load_4,store_4,mov_reg,multiple")
6316 (set_attr "length" "4,4,4,8")
6317 (set_attr "predicable" "yes")]
6318 )
6319
6320 (define_expand "movsf"
6321 [(set (match_operand:SF 0 "general_operand")
6322 (match_operand:SF 1 "general_operand"))]
6323 "TARGET_EITHER"
6324 "
6325 gcc_checking_assert (aligned_operand (operands[0], SFmode));
6326 gcc_checking_assert (aligned_operand (operands[1], SFmode));
6327 if (TARGET_32BIT)
6328 {
6329 if (MEM_P (operands[0]))
6330 operands[1] = force_reg (SFmode, operands[1]);
6331 }
6332 else /* TARGET_THUMB1 */
6333 {
6334 if (can_create_pseudo_p ())
6335 {
6336 if (!REG_P (operands[0]))
6337 operands[1] = force_reg (SFmode, operands[1]);
6338 }
6339 }
6340
6341 /* Cannot load it directly, generate a load with clobber so that it can be
6342 loaded via GPR with MOV / MOVT. */
6343 if (arm_disable_literal_pool
6344 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6345 && CONST_DOUBLE_P (operands[1])
6346 && TARGET_HARD_FLOAT
6347 && !vfp3_const_double_rtx (operands[1]))
6348 {
6349 rtx clobreg = gen_reg_rtx (SFmode);
6350 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1],
6351 clobreg));
6352 DONE;
6353 }
6354 "
6355 )
6356
6357 ;; Transform a floating-point move of a constant into a core register into
6358 ;; an SImode operation.
6359 (define_split
6360 [(set (match_operand:SF 0 "arm_general_register_operand" "")
6361 (match_operand:SF 1 "immediate_operand" ""))]
6362 "TARGET_EITHER
6363 && reload_completed
6364 && CONST_DOUBLE_P (operands[1])"
6365 [(set (match_dup 2) (match_dup 3))]
6366 "
6367 operands[2] = gen_lowpart (SImode, operands[0]);
6368 operands[3] = gen_lowpart (SImode, operands[1]);
6369 if (operands[2] == 0 || operands[3] == 0)
6370 FAIL;
6371 "
6372 )
6373
6374 (define_insn "*arm_movsf_soft_insn"
6375 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
6376 (match_operand:SF 1 "general_operand" "r,mE,r"))]
6377 "TARGET_32BIT
6378 && TARGET_SOFT_FLOAT
6379 && (!MEM_P (operands[0])
6380 || register_operand (operands[1], SFmode))"
6381 {
6382 switch (which_alternative)
6383 {
6384 case 0: return \"mov%?\\t%0, %1\";
6385 case 1:
6386 /* Cannot load it directly, split to load it via MOV / MOVT. */
6387 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6388 return \"#\";
6389 return \"ldr%?\\t%0, %1\\t%@ float\";
6390 case 2: return \"str%?\\t%1, %0\\t%@ float\";
6391 default: gcc_unreachable ();
6392 }
6393 }
6394 [(set_attr "predicable" "yes")
6395 (set_attr "type" "mov_reg,load_4,store_4")
6396 (set_attr "arm_pool_range" "*,4096,*")
6397 (set_attr "thumb2_pool_range" "*,4094,*")
6398 (set_attr "arm_neg_pool_range" "*,4084,*")
6399 (set_attr "thumb2_neg_pool_range" "*,0,*")]
6400 )
6401
6402 ;; Splitter for the above.
6403 (define_split
6404 [(set (match_operand:SF 0 "s_register_operand")
6405 (match_operand:SF 1 "const_double_operand"))]
6406 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6407 [(const_int 0)]
6408 {
6409 long buf;
6410 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
6411 rtx cst = gen_int_mode (buf, SImode);
6412 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst);
6413 DONE;
6414 }
6415 )
6416
6417 (define_expand "movdf"
6418 [(set (match_operand:DF 0 "general_operand")
6419 (match_operand:DF 1 "general_operand"))]
6420 "TARGET_EITHER"
6421 "
6422 gcc_checking_assert (aligned_operand (operands[0], DFmode));
6423 gcc_checking_assert (aligned_operand (operands[1], DFmode));
6424 if (TARGET_32BIT)
6425 {
6426 if (MEM_P (operands[0]))
6427 operands[1] = force_reg (DFmode, operands[1]);
6428 }
6429 else /* TARGET_THUMB */
6430 {
6431 if (can_create_pseudo_p ())
6432 {
6433 if (!REG_P (operands[0]))
6434 operands[1] = force_reg (DFmode, operands[1]);
6435 }
6436 }
6437
6438 /* Cannot load it directly, generate a load with clobber so that it can be
6439 loaded via GPR with MOV / MOVT. */
6440 if (arm_disable_literal_pool
6441 && (REG_P (operands[0]) || SUBREG_P (operands[0]))
6442 && CONSTANT_P (operands[1])
6443 && TARGET_HARD_FLOAT
6444 && !arm_const_double_rtx (operands[1])
6445 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1])))
6446 {
6447 rtx clobreg = gen_reg_rtx (DFmode);
6448 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1],
6449 clobreg));
6450 DONE;
6451 }
6452 "
6453 )
6454
6455 ;; Reloading a df mode value stored in integer regs to memory can require a
6456 ;; scratch reg.
6457 ;; Another reload_out<m> pattern that requires special constraints.
6458 (define_expand "reload_outdf"
6459 [(match_operand:DF 0 "arm_reload_memory_operand" "=o")
6460 (match_operand:DF 1 "s_register_operand" "r")
6461 (match_operand:SI 2 "s_register_operand" "=&r")]
6462 "TARGET_THUMB2"
6463 "
6464 {
6465 enum rtx_code code = GET_CODE (XEXP (operands[0], 0));
6466
6467 if (code == REG)
6468 operands[2] = XEXP (operands[0], 0);
6469 else if (code == POST_INC || code == PRE_DEC)
6470 {
6471 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6472 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6473 emit_insn (gen_movdi (operands[0], operands[1]));
6474 DONE;
6475 }
6476 else if (code == PRE_INC)
6477 {
6478 rtx reg = XEXP (XEXP (operands[0], 0), 0);
6479
6480 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8)));
6481 operands[2] = reg;
6482 }
6483 else if (code == POST_DEC)
6484 operands[2] = XEXP (XEXP (operands[0], 0), 0);
6485 else
6486 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0),
6487 XEXP (XEXP (operands[0], 0), 1)));
6488
6489 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]),
6490 operands[1]));
6491
6492 if (code == POST_DEC)
6493 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8)));
6494
6495 DONE;
6496 }"
6497 )
6498
6499 (define_insn "*movdf_soft_insn"
6500 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
6501 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
6502 "TARGET_32BIT && TARGET_SOFT_FLOAT
6503 && ( register_operand (operands[0], DFmode)
6504 || register_operand (operands[1], DFmode))"
6505 "*
6506 switch (which_alternative)
6507 {
6508 case 0:
6509 case 1:
6510 case 2:
6511 return \"#\";
6512 case 3:
6513 /* Cannot load it directly, split to load it via MOV / MOVT. */
6514 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
6515 return \"#\";
6516 /* Fall through. */
6517 default:
6518 return output_move_double (operands, true, NULL);
6519 }
6520 "
6521 [(set_attr "length" "8,12,16,8,8")
6522 (set_attr "type" "multiple,multiple,multiple,load_8,store_8")
6523 (set_attr "arm_pool_range" "*,*,*,1020,*")
6524 (set_attr "thumb2_pool_range" "*,*,*,1018,*")
6525 (set_attr "arm_neg_pool_range" "*,*,*,1004,*")
6526 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")]
6527 )
6528
6529 ;; Splitter for the above.
6530 (define_split
6531 [(set (match_operand:DF 0 "s_register_operand")
6532 (match_operand:DF 1 "const_double_operand"))]
6533 "arm_disable_literal_pool && TARGET_SOFT_FLOAT"
6534 [(const_int 0)]
6535 {
6536 long buf[2];
6537 int order = BYTES_BIG_ENDIAN ? 1 : 0;
6538 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
6539 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32);
6540 ival |= (zext_hwi (buf[1 - order], 32) << 32);
6541 rtx cst = gen_int_mode (ival, DImode);
6542 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst);
6543 DONE;
6544 }
6545 )
6546 \f
6547
6548 ;; load- and store-multiple insns
6549 ;; The arm can load/store any set of registers, provided that they are in
6550 ;; ascending order, but these expanders assume a contiguous set.
6551
6552 (define_expand "load_multiple"
6553 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6554 (match_operand:SI 1 "" ""))
6555 (use (match_operand:SI 2 "" ""))])]
6556 "TARGET_32BIT"
6557 {
6558 HOST_WIDE_INT offset = 0;
6559
6560 /* Support only fixed point registers. */
6561 if (!CONST_INT_P (operands[2])
6562 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6563 || INTVAL (operands[2]) < 2
6564 || !MEM_P (operands[1])
6565 || !REG_P (operands[0])
6566 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1)
6567 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6568 FAIL;
6569
6570 operands[3]
6571 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]),
6572 INTVAL (operands[2]),
6573 force_reg (SImode, XEXP (operands[1], 0)),
6574 FALSE, operands[1], &offset);
6575 })
6576
6577 (define_expand "store_multiple"
6578 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
6579 (match_operand:SI 1 "" ""))
6580 (use (match_operand:SI 2 "" ""))])]
6581 "TARGET_32BIT"
6582 {
6583 HOST_WIDE_INT offset = 0;
6584
6585 /* Support only fixed point registers. */
6586 if (!CONST_INT_P (operands[2])
6587 || INTVAL (operands[2]) > MAX_LDM_STM_OPS
6588 || INTVAL (operands[2]) < 2
6589 || !REG_P (operands[1])
6590 || !MEM_P (operands[0])
6591 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1)
6592 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM)
6593 FAIL;
6594
6595 operands[3]
6596 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]),
6597 INTVAL (operands[2]),
6598 force_reg (SImode, XEXP (operands[0], 0)),
6599 FALSE, operands[0], &offset);
6600 })
6601
6602
6603 (define_expand "setmemsi"
6604 [(match_operand:BLK 0 "general_operand")
6605 (match_operand:SI 1 "const_int_operand")
6606 (match_operand:SI 2 "const_int_operand")
6607 (match_operand:SI 3 "const_int_operand")]
6608 "TARGET_32BIT"
6609 {
6610 if (arm_gen_setmem (operands))
6611 DONE;
6612
6613 FAIL;
6614 })
6615
6616
6617 ;; Move a block of memory if it is word aligned and MORE than 2 words long.
6618 ;; We could let this apply for blocks of less than this, but it clobbers so
6619 ;; many registers that there is then probably a better way.
6620
6621 (define_expand "cpymemqi"
6622 [(match_operand:BLK 0 "general_operand")
6623 (match_operand:BLK 1 "general_operand")
6624 (match_operand:SI 2 "const_int_operand")
6625 (match_operand:SI 3 "const_int_operand")]
6626 ""
6627 "
6628 if (TARGET_32BIT)
6629 {
6630 if (TARGET_LDRD && current_tune->prefer_ldrd_strd
6631 && !optimize_function_for_size_p (cfun))
6632 {
6633 if (gen_cpymem_ldrd_strd (operands))
6634 DONE;
6635 FAIL;
6636 }
6637
6638 if (arm_gen_cpymemqi (operands))
6639 DONE;
6640 FAIL;
6641 }
6642 else /* TARGET_THUMB1 */
6643 {
6644 if ( INTVAL (operands[3]) != 4
6645 || INTVAL (operands[2]) > 48)
6646 FAIL;
6647
6648 thumb_expand_cpymemqi (operands);
6649 DONE;
6650 }
6651 "
6652 )
6653 \f
6654
6655 ;; Compare & branch insns
6656 ;; The range calculations are based as follows:
6657 ;; For forward branches, the address calculation returns the address of
6658 ;; the next instruction. This is 2 beyond the branch instruction.
6659 ;; For backward branches, the address calculation returns the address of
6660 ;; the first instruction in this pattern (cmp). This is 2 before the branch
6661 ;; instruction for the shortest sequence, and 4 before the branch instruction
6662 ;; if we have to jump around an unconditional branch.
6663 ;; To the basic branch range the PC offset must be added (this is +4).
6664 ;; So for forward branches we have
6665 ;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4).
6666 ;; And for backward branches we have
6667 ;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4).
6668 ;;
6669 ;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
6670 ;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
6671
6672 (define_expand "cbranchsi4"
6673 [(set (pc) (if_then_else
6674 (match_operator 0 "expandable_comparison_operator"
6675 [(match_operand:SI 1 "s_register_operand")
6676 (match_operand:SI 2 "nonmemory_operand")])
6677 (label_ref (match_operand 3 "" ""))
6678 (pc)))]
6679 "TARGET_EITHER"
6680 "
6681 if (!TARGET_THUMB1)
6682 {
6683 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6684 FAIL;
6685 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6686 operands[3]));
6687 DONE;
6688 }
6689 if (thumb1_cmpneg_operand (operands[2], SImode))
6690 {
6691 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
6692 operands[3], operands[0]));
6693 DONE;
6694 }
6695 if (!thumb1_cmp_operand (operands[2], SImode))
6696 operands[2] = force_reg (SImode, operands[2]);
6697 ")
6698
6699 (define_expand "cbranchsf4"
6700 [(set (pc) (if_then_else
6701 (match_operator 0 "expandable_comparison_operator"
6702 [(match_operand:SF 1 "s_register_operand")
6703 (match_operand:SF 2 "vfp_compare_operand")])
6704 (label_ref (match_operand 3 "" ""))
6705 (pc)))]
6706 "TARGET_32BIT && TARGET_HARD_FLOAT"
6707 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6708 operands[3])); DONE;"
6709 )
6710
6711 (define_expand "cbranchdf4"
6712 [(set (pc) (if_then_else
6713 (match_operator 0 "expandable_comparison_operator"
6714 [(match_operand:DF 1 "s_register_operand")
6715 (match_operand:DF 2 "vfp_compare_operand")])
6716 (label_ref (match_operand 3 "" ""))
6717 (pc)))]
6718 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
6719 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6720 operands[3])); DONE;"
6721 )
6722
6723 (define_expand "cbranchdi4"
6724 [(set (pc) (if_then_else
6725 (match_operator 0 "expandable_comparison_operator"
6726 [(match_operand:DI 1 "s_register_operand")
6727 (match_operand:DI 2 "cmpdi_operand")])
6728 (label_ref (match_operand 3 "" ""))
6729 (pc)))]
6730 "TARGET_32BIT"
6731 "{
6732 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2]))
6733 FAIL;
6734 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
6735 operands[3]));
6736 DONE;
6737 }"
6738 )
6739
6740 ;; Comparison and test insns
6741
6742 (define_insn "*arm_cmpsi_insn"
6743 [(set (reg:CC CC_REGNUM)
6744 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r")
6745 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))]
6746 "TARGET_32BIT"
6747 "@
6748 cmp%?\\t%0, %1
6749 cmp%?\\t%0, %1
6750 cmp%?\\t%0, %1
6751 cmp%?\\t%0, %1
6752 cmn%?\\t%0, #%n1"
6753 [(set_attr "conds" "set")
6754 (set_attr "arch" "t2,t2,any,any,any")
6755 (set_attr "length" "2,2,4,4,4")
6756 (set_attr "predicable" "yes")
6757 (set_attr "predicable_short_it" "yes,yes,yes,no,no")
6758 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")]
6759 )
6760
6761 (define_insn "*cmpsi_shiftsi"
6762 [(set (reg:CC CC_REGNUM)
6763 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
6764 (match_operator:SI 3 "shift_operator"
6765 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6766 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
6767 "TARGET_32BIT"
6768 "cmp\\t%0, %1%S3"
6769 [(set_attr "conds" "set")
6770 (set_attr "shift" "1")
6771 (set_attr "arch" "32,a,a")
6772 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6773
6774 (define_insn "*cmpsi_shiftsi_swp"
6775 [(set (reg:CC_SWP CC_REGNUM)
6776 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
6777 [(match_operand:SI 1 "s_register_operand" "r,r,r")
6778 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
6779 (match_operand:SI 0 "s_register_operand" "r,r,r")))]
6780 "TARGET_32BIT"
6781 "cmp%?\\t%0, %1%S3"
6782 [(set_attr "conds" "set")
6783 (set_attr "shift" "1")
6784 (set_attr "arch" "32,a,a")
6785 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
6786
6787 (define_insn "*arm_cmpsi_negshiftsi_si"
6788 [(set (reg:CC_Z CC_REGNUM)
6789 (compare:CC_Z
6790 (neg:SI (match_operator:SI 1 "shift_operator"
6791 [(match_operand:SI 2 "s_register_operand" "r")
6792 (match_operand:SI 3 "reg_or_int_operand" "rM")]))
6793 (match_operand:SI 0 "s_register_operand" "r")))]
6794 "TARGET_ARM"
6795 "cmn%?\\t%0, %2%S1"
6796 [(set_attr "conds" "set")
6797 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
6798 (const_string "alus_shift_imm")
6799 (const_string "alus_shift_reg")))
6800 (set_attr "predicable" "yes")]
6801 )
6802
6803 ;; DImode comparisons. The generic code generates branches that
6804 ;; if-conversion cannot reduce to a conditional compare, so we do
6805 ;; that directly.
6806
6807 (define_insn_and_split "*arm_cmpdi_insn"
6808 [(set (reg:CC_NCV CC_REGNUM)
6809 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r")
6810 (match_operand:DI 1 "arm_di_operand" "rDi")))
6811 (clobber (match_scratch:SI 2 "=r"))]
6812 "TARGET_32BIT"
6813 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
6814 "&& reload_completed"
6815 [(set (reg:CC CC_REGNUM)
6816 (compare:CC (match_dup 0) (match_dup 1)))
6817 (parallel [(set (reg:CC CC_REGNUM)
6818 (compare:CC (match_dup 3) (match_dup 4)))
6819 (set (match_dup 2)
6820 (minus:SI (match_dup 5)
6821 (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
6822 {
6823 operands[3] = gen_highpart (SImode, operands[0]);
6824 operands[0] = gen_lowpart (SImode, operands[0]);
6825 if (CONST_INT_P (operands[1]))
6826 {
6827 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);
6828 if (operands[4] == const0_rtx)
6829 operands[5] = operands[3];
6830 else
6831 operands[5] = gen_rtx_PLUS (SImode, operands[3],
6832 gen_int_mode (-UINTVAL (operands[4]),
6833 SImode));
6834 }
6835 else
6836 {
6837 operands[4] = gen_highpart (SImode, operands[1]);
6838 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]);
6839 }
6840 operands[1] = gen_lowpart (SImode, operands[1]);
6841 operands[2] = gen_lowpart (SImode, operands[2]);
6842 }
6843 [(set_attr "conds" "set")
6844 (set_attr "length" "8")
6845 (set_attr "type" "multiple")]
6846 )
6847
6848 (define_insn_and_split "*arm_cmpdi_unsigned"
6849 [(set (reg:CC_CZ CC_REGNUM)
6850 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r")
6851 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))]
6852
6853 "TARGET_32BIT"
6854 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
6855 "&& reload_completed"
6856 [(set (reg:CC CC_REGNUM)
6857 (compare:CC (match_dup 2) (match_dup 3)))
6858 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0))
6859 (set (reg:CC CC_REGNUM)
6860 (compare:CC (match_dup 0) (match_dup 1))))]
6861 {
6862 operands[2] = gen_highpart (SImode, operands[0]);
6863 operands[0] = gen_lowpart (SImode, operands[0]);
6864 if (CONST_INT_P (operands[1]))
6865 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6866 else
6867 operands[3] = gen_highpart (SImode, operands[1]);
6868 operands[1] = gen_lowpart (SImode, operands[1]);
6869 }
6870 [(set_attr "conds" "set")
6871 (set_attr "enabled_for_short_it" "yes,yes,no,*")
6872 (set_attr "arch" "t2,t2,t2,a")
6873 (set_attr "length" "6,6,10,8")
6874 (set_attr "type" "multiple")]
6875 )
6876
6877 (define_insn "*arm_cmpdi_zero"
6878 [(set (reg:CC_Z CC_REGNUM)
6879 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r")
6880 (const_int 0)))
6881 (clobber (match_scratch:SI 1 "=r"))]
6882 "TARGET_32BIT"
6883 "orrs%?\\t%1, %Q0, %R0"
6884 [(set_attr "conds" "set")
6885 (set_attr "type" "logics_reg")]
6886 )
6887
6888 ; This insn allows redundant compares to be removed by cse, nothing should
6889 ; ever appear in the output file since (set (reg x) (reg x)) is a no-op that
6890 ; is deleted later on. The match_dup will match the mode here, so that
6891 ; mode changes of the condition codes aren't lost by this even though we don't
6892 ; specify what they are.
6893
6894 (define_insn "*deleted_compare"
6895 [(set (match_operand 0 "cc_register" "") (match_dup 0))]
6896 "TARGET_32BIT"
6897 "\\t%@ deleted compare"
6898 [(set_attr "conds" "set")
6899 (set_attr "length" "0")
6900 (set_attr "type" "no_insn")]
6901 )
6902
6903 \f
6904 ;; Conditional branch insns
6905
6906 (define_expand "cbranch_cc"
6907 [(set (pc)
6908 (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
6909 (match_operand 2 "" "")])
6910 (label_ref (match_operand 3 "" ""))
6911 (pc)))]
6912 "TARGET_32BIT"
6913 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
6914 operands[1], operands[2], NULL_RTX);
6915 operands[2] = const0_rtx;"
6916 )
6917
6918 ;;
6919 ;; Patterns to match conditional branch insns.
6920 ;;
6921
6922 (define_insn "arm_cond_branch"
6923 [(set (pc)
6924 (if_then_else (match_operator 1 "arm_comparison_operator"
6925 [(match_operand 2 "cc_register" "") (const_int 0)])
6926 (label_ref (match_operand 0 "" ""))
6927 (pc)))]
6928 "TARGET_32BIT"
6929 "*
6930 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6931 {
6932 arm_ccfsm_state += 2;
6933 return \"\";
6934 }
6935 return \"b%d1\\t%l0\";
6936 "
6937 [(set_attr "conds" "use")
6938 (set_attr "type" "branch")
6939 (set (attr "length")
6940 (if_then_else
6941 (and (match_test "TARGET_THUMB2")
6942 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
6943 (le (minus (match_dup 0) (pc)) (const_int 256))))
6944 (const_int 2)
6945 (const_int 4)))]
6946 )
6947
6948 (define_insn "*arm_cond_branch_reversed"
6949 [(set (pc)
6950 (if_then_else (match_operator 1 "arm_comparison_operator"
6951 [(match_operand 2 "cc_register" "") (const_int 0)])
6952 (pc)
6953 (label_ref (match_operand 0 "" ""))))]
6954 "TARGET_32BIT"
6955 "*
6956 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
6957 {
6958 arm_ccfsm_state += 2;
6959 return \"\";
6960 }
6961 return \"b%D1\\t%l0\";
6962 "
6963 [(set_attr "conds" "use")
6964 (set_attr "type" "branch")
6965 (set (attr "length")
6966 (if_then_else
6967 (and (match_test "TARGET_THUMB2")
6968 (and (ge (minus (match_dup 0) (pc)) (const_int -250))
6969 (le (minus (match_dup 0) (pc)) (const_int 256))))
6970 (const_int 2)
6971 (const_int 4)))]
6972 )
6973
6974 \f
6975
6976 ; scc insns
6977
6978 (define_expand "cstore_cc"
6979 [(set (match_operand:SI 0 "s_register_operand")
6980 (match_operator:SI 1 "" [(match_operand 2 "" "")
6981 (match_operand 3 "" "")]))]
6982 "TARGET_32BIT"
6983 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
6984 operands[2], operands[3], NULL_RTX);
6985 operands[3] = const0_rtx;"
6986 )
6987
6988 (define_insn_and_split "*mov_scc"
6989 [(set (match_operand:SI 0 "s_register_operand" "=r")
6990 (match_operator:SI 1 "arm_comparison_operator_mode"
6991 [(match_operand 2 "cc_register" "") (const_int 0)]))]
6992 "TARGET_ARM"
6993 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
6994 "TARGET_ARM"
6995 [(set (match_dup 0)
6996 (if_then_else:SI (match_dup 1)
6997 (const_int 1)
6998 (const_int 0)))]
6999 ""
7000 [(set_attr "conds" "use")
7001 (set_attr "length" "8")
7002 (set_attr "type" "multiple")]
7003 )
7004
7005 (define_insn_and_split "*mov_negscc"
7006 [(set (match_operand:SI 0 "s_register_operand" "=r")
7007 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
7008 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7009 "TARGET_ARM"
7010 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
7011 "TARGET_ARM"
7012 [(set (match_dup 0)
7013 (if_then_else:SI (match_dup 1)
7014 (match_dup 3)
7015 (const_int 0)))]
7016 {
7017 operands[3] = GEN_INT (~0);
7018 }
7019 [(set_attr "conds" "use")
7020 (set_attr "length" "8")
7021 (set_attr "type" "multiple")]
7022 )
7023
7024 (define_insn_and_split "*mov_notscc"
7025 [(set (match_operand:SI 0 "s_register_operand" "=r")
7026 (not:SI (match_operator:SI 1 "arm_comparison_operator"
7027 [(match_operand 2 "cc_register" "") (const_int 0)])))]
7028 "TARGET_ARM"
7029 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
7030 "TARGET_ARM"
7031 [(set (match_dup 0)
7032 (if_then_else:SI (match_dup 1)
7033 (match_dup 3)
7034 (match_dup 4)))]
7035 {
7036 operands[3] = GEN_INT (~1);
7037 operands[4] = GEN_INT (~0);
7038 }
7039 [(set_attr "conds" "use")
7040 (set_attr "length" "8")
7041 (set_attr "type" "multiple")]
7042 )
7043
7044 (define_expand "cstoresi4"
7045 [(set (match_operand:SI 0 "s_register_operand")
7046 (match_operator:SI 1 "expandable_comparison_operator"
7047 [(match_operand:SI 2 "s_register_operand")
7048 (match_operand:SI 3 "reg_or_int_operand")]))]
7049 "TARGET_32BIT || TARGET_THUMB1"
7050 "{
7051 rtx op3, scratch, scratch2;
7052
7053 if (!TARGET_THUMB1)
7054 {
7055 if (!arm_add_operand (operands[3], SImode))
7056 operands[3] = force_reg (SImode, operands[3]);
7057 emit_insn (gen_cstore_cc (operands[0], operands[1],
7058 operands[2], operands[3]));
7059 DONE;
7060 }
7061
7062 if (operands[3] == const0_rtx)
7063 {
7064 switch (GET_CODE (operands[1]))
7065 {
7066 case EQ:
7067 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2]));
7068 break;
7069
7070 case NE:
7071 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2]));
7072 break;
7073
7074 case LE:
7075 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx,
7076 NULL_RTX, 0, OPTAB_WIDEN);
7077 scratch = expand_binop (SImode, ior_optab, operands[2], scratch,
7078 NULL_RTX, 0, OPTAB_WIDEN);
7079 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7080 operands[0], 1, OPTAB_WIDEN);
7081 break;
7082
7083 case GE:
7084 scratch = expand_unop (SImode, one_cmpl_optab, operands[2],
7085 NULL_RTX, 1);
7086 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31),
7087 NULL_RTX, 1, OPTAB_WIDEN);
7088 break;
7089
7090 case GT:
7091 scratch = expand_binop (SImode, ashr_optab, operands[2],
7092 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN);
7093 scratch = expand_binop (SImode, sub_optab, scratch, operands[2],
7094 NULL_RTX, 0, OPTAB_WIDEN);
7095 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0],
7096 0, OPTAB_WIDEN);
7097 break;
7098
7099 /* LT is handled by generic code. No need for unsigned with 0. */
7100 default:
7101 FAIL;
7102 }
7103 DONE;
7104 }
7105
7106 switch (GET_CODE (operands[1]))
7107 {
7108 case EQ:
7109 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7110 NULL_RTX, 0, OPTAB_WIDEN);
7111 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch));
7112 break;
7113
7114 case NE:
7115 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3],
7116 NULL_RTX, 0, OPTAB_WIDEN);
7117 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch));
7118 break;
7119
7120 case LE:
7121 op3 = force_reg (SImode, operands[3]);
7122
7123 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31),
7124 NULL_RTX, 1, OPTAB_WIDEN);
7125 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31),
7126 NULL_RTX, 0, OPTAB_WIDEN);
7127 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7128 op3, operands[2]));
7129 break;
7130
7131 case GE:
7132 op3 = operands[3];
7133 if (!thumb1_cmp_operand (op3, SImode))
7134 op3 = force_reg (SImode, op3);
7135 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31),
7136 NULL_RTX, 0, OPTAB_WIDEN);
7137 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31),
7138 NULL_RTX, 1, OPTAB_WIDEN);
7139 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2,
7140 operands[2], op3));
7141 break;
7142
7143 case LEU:
7144 op3 = force_reg (SImode, operands[3]);
7145 scratch = force_reg (SImode, const0_rtx);
7146 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7147 op3, operands[2]));
7148 break;
7149
7150 case GEU:
7151 op3 = operands[3];
7152 if (!thumb1_cmp_operand (op3, SImode))
7153 op3 = force_reg (SImode, op3);
7154 scratch = force_reg (SImode, const0_rtx);
7155 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch,
7156 operands[2], op3));
7157 break;
7158
7159 case LTU:
7160 op3 = operands[3];
7161 if (!thumb1_cmp_operand (op3, SImode))
7162 op3 = force_reg (SImode, op3);
7163 scratch = gen_reg_rtx (SImode);
7164 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3));
7165 break;
7166
7167 case GTU:
7168 op3 = force_reg (SImode, operands[3]);
7169 scratch = gen_reg_rtx (SImode);
7170 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2]));
7171 break;
7172
7173 /* No good sequences for GT, LT. */
7174 default:
7175 FAIL;
7176 }
7177 DONE;
7178 }")
7179
7180 (define_expand "cstorehf4"
7181 [(set (match_operand:SI 0 "s_register_operand")
7182 (match_operator:SI 1 "expandable_comparison_operator"
7183 [(match_operand:HF 2 "s_register_operand")
7184 (match_operand:HF 3 "vfp_compare_operand")]))]
7185 "TARGET_VFP_FP16INST"
7186 {
7187 if (!arm_validize_comparison (&operands[1],
7188 &operands[2],
7189 &operands[3]))
7190 FAIL;
7191
7192 emit_insn (gen_cstore_cc (operands[0], operands[1],
7193 operands[2], operands[3]));
7194 DONE;
7195 }
7196 )
7197
7198 (define_expand "cstoresf4"
7199 [(set (match_operand:SI 0 "s_register_operand")
7200 (match_operator:SI 1 "expandable_comparison_operator"
7201 [(match_operand:SF 2 "s_register_operand")
7202 (match_operand:SF 3 "vfp_compare_operand")]))]
7203 "TARGET_32BIT && TARGET_HARD_FLOAT"
7204 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7205 operands[2], operands[3])); DONE;"
7206 )
7207
7208 (define_expand "cstoredf4"
7209 [(set (match_operand:SI 0 "s_register_operand")
7210 (match_operator:SI 1 "expandable_comparison_operator"
7211 [(match_operand:DF 2 "s_register_operand")
7212 (match_operand:DF 3 "vfp_compare_operand")]))]
7213 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE"
7214 "emit_insn (gen_cstore_cc (operands[0], operands[1],
7215 operands[2], operands[3])); DONE;"
7216 )
7217
7218 (define_expand "cstoredi4"
7219 [(set (match_operand:SI 0 "s_register_operand")
7220 (match_operator:SI 1 "expandable_comparison_operator"
7221 [(match_operand:DI 2 "s_register_operand")
7222 (match_operand:DI 3 "cmpdi_operand")]))]
7223 "TARGET_32BIT"
7224 "{
7225 if (!arm_validize_comparison (&operands[1],
7226 &operands[2],
7227 &operands[3]))
7228 FAIL;
7229 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2],
7230 operands[3]));
7231 DONE;
7232 }"
7233 )
7234
7235 \f
7236 ;; Conditional move insns
7237
7238 (define_expand "movsicc"
7239 [(set (match_operand:SI 0 "s_register_operand")
7240 (if_then_else:SI (match_operand 1 "expandable_comparison_operator")
7241 (match_operand:SI 2 "arm_not_operand")
7242 (match_operand:SI 3 "arm_not_operand")))]
7243 "TARGET_32BIT"
7244 "
7245 {
7246 enum rtx_code code;
7247 rtx ccreg;
7248
7249 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7250 &XEXP (operands[1], 1)))
7251 FAIL;
7252
7253 code = GET_CODE (operands[1]);
7254 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7255 XEXP (operands[1], 1), NULL_RTX);
7256 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7257 }"
7258 )
7259
7260 (define_expand "movhfcc"
7261 [(set (match_operand:HF 0 "s_register_operand")
7262 (if_then_else:HF (match_operand 1 "arm_cond_move_operator")
7263 (match_operand:HF 2 "s_register_operand")
7264 (match_operand:HF 3 "s_register_operand")))]
7265 "TARGET_VFP_FP16INST"
7266 "
7267 {
7268 enum rtx_code code = GET_CODE (operands[1]);
7269 rtx ccreg;
7270
7271 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7272 &XEXP (operands[1], 1)))
7273 FAIL;
7274
7275 code = GET_CODE (operands[1]);
7276 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7277 XEXP (operands[1], 1), NULL_RTX);
7278 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7279 }"
7280 )
7281
7282 (define_expand "movsfcc"
7283 [(set (match_operand:SF 0 "s_register_operand")
7284 (if_then_else:SF (match_operand 1 "arm_cond_move_operator")
7285 (match_operand:SF 2 "s_register_operand")
7286 (match_operand:SF 3 "s_register_operand")))]
7287 "TARGET_32BIT && TARGET_HARD_FLOAT"
7288 "
7289 {
7290 enum rtx_code code = GET_CODE (operands[1]);
7291 rtx ccreg;
7292
7293 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7294 &XEXP (operands[1], 1)))
7295 FAIL;
7296
7297 code = GET_CODE (operands[1]);
7298 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7299 XEXP (operands[1], 1), NULL_RTX);
7300 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7301 }"
7302 )
7303
7304 (define_expand "movdfcc"
7305 [(set (match_operand:DF 0 "s_register_operand")
7306 (if_then_else:DF (match_operand 1 "arm_cond_move_operator")
7307 (match_operand:DF 2 "s_register_operand")
7308 (match_operand:DF 3 "s_register_operand")))]
7309 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
7310 "
7311 {
7312 enum rtx_code code = GET_CODE (operands[1]);
7313 rtx ccreg;
7314
7315 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0),
7316 &XEXP (operands[1], 1)))
7317 FAIL;
7318 code = GET_CODE (operands[1]);
7319 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
7320 XEXP (operands[1], 1), NULL_RTX);
7321 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
7322 }"
7323 )
7324
7325 (define_insn "*cmov<mode>"
7326 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
7327 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator"
7328 [(match_operand 2 "cc_register" "") (const_int 0)])
7329 (match_operand:SDF 3 "s_register_operand"
7330 "<F_constraint>")
7331 (match_operand:SDF 4 "s_register_operand"
7332 "<F_constraint>")))]
7333 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
7334 "*
7335 {
7336 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7337 switch (code)
7338 {
7339 case ARM_GE:
7340 case ARM_GT:
7341 case ARM_EQ:
7342 case ARM_VS:
7343 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\";
7344 case ARM_LT:
7345 case ARM_LE:
7346 case ARM_NE:
7347 case ARM_VC:
7348 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\";
7349 default:
7350 gcc_unreachable ();
7351 }
7352 return \"\";
7353 }"
7354 [(set_attr "conds" "use")
7355 (set_attr "type" "fcsel")]
7356 )
7357
7358 (define_insn "*cmovhf"
7359 [(set (match_operand:HF 0 "s_register_operand" "=t")
7360 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator"
7361 [(match_operand 2 "cc_register" "") (const_int 0)])
7362 (match_operand:HF 3 "s_register_operand" "t")
7363 (match_operand:HF 4 "s_register_operand" "t")))]
7364 "TARGET_VFP_FP16INST"
7365 "*
7366 {
7367 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]);
7368 switch (code)
7369 {
7370 case ARM_GE:
7371 case ARM_GT:
7372 case ARM_EQ:
7373 case ARM_VS:
7374 return \"vsel%d1.f16\\t%0, %3, %4\";
7375 case ARM_LT:
7376 case ARM_LE:
7377 case ARM_NE:
7378 case ARM_VC:
7379 return \"vsel%D1.f16\\t%0, %4, %3\";
7380 default:
7381 gcc_unreachable ();
7382 }
7383 return \"\";
7384 }"
7385 [(set_attr "conds" "use")
7386 (set_attr "type" "fcsel")]
7387 )
7388
7389 (define_insn_and_split "*movsicc_insn"
7390 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
7391 (if_then_else:SI
7392 (match_operator 3 "arm_comparison_operator"
7393 [(match_operand 4 "cc_register" "") (const_int 0)])
7394 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
7395 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
7396 "TARGET_ARM"
7397 "@
7398 mov%D3\\t%0, %2
7399 mvn%D3\\t%0, #%B2
7400 mov%d3\\t%0, %1
7401 mvn%d3\\t%0, #%B1
7402 #
7403 #
7404 #
7405 #"
7406 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2
7407 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
7408 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
7409 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
7410 "&& reload_completed"
7411 [(const_int 0)]
7412 {
7413 enum rtx_code rev_code;
7414 machine_mode mode;
7415 rtx rev_cond;
7416
7417 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7418 operands[3],
7419 gen_rtx_SET (operands[0], operands[1])));
7420
7421 rev_code = GET_CODE (operands[3]);
7422 mode = GET_MODE (operands[4]);
7423 if (mode == CCFPmode || mode == CCFPEmode)
7424 rev_code = reverse_condition_maybe_unordered (rev_code);
7425 else
7426 rev_code = reverse_condition (rev_code);
7427
7428 rev_cond = gen_rtx_fmt_ee (rev_code,
7429 VOIDmode,
7430 operands[4],
7431 const0_rtx);
7432 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
7433 rev_cond,
7434 gen_rtx_SET (operands[0], operands[2])));
7435 DONE;
7436 }
7437 [(set_attr "length" "4,4,4,4,8,8,8,8")
7438 (set_attr "conds" "use")
7439 (set_attr_alternative "type"
7440 [(if_then_else (match_operand 2 "const_int_operand" "")
7441 (const_string "mov_imm")
7442 (const_string "mov_reg"))
7443 (const_string "mvn_imm")
7444 (if_then_else (match_operand 1 "const_int_operand" "")
7445 (const_string "mov_imm")
7446 (const_string "mov_reg"))
7447 (const_string "mvn_imm")
7448 (const_string "multiple")
7449 (const_string "multiple")
7450 (const_string "multiple")
7451 (const_string "multiple")])]
7452 )
7453
7454 (define_insn "*movsfcc_soft_insn"
7455 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
7456 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
7457 [(match_operand 4 "cc_register" "") (const_int 0)])
7458 (match_operand:SF 1 "s_register_operand" "0,r")
7459 (match_operand:SF 2 "s_register_operand" "r,0")))]
7460 "TARGET_ARM && TARGET_SOFT_FLOAT"
7461 "@
7462 mov%D3\\t%0, %2
7463 mov%d3\\t%0, %1"
7464 [(set_attr "conds" "use")
7465 (set_attr "type" "mov_reg")]
7466 )
7467
7468 \f
7469 ;; Jump and linkage insns
7470
7471 (define_expand "jump"
7472 [(set (pc)
7473 (label_ref (match_operand 0 "" "")))]
7474 "TARGET_EITHER"
7475 ""
7476 )
7477
7478 (define_insn "*arm_jump"
7479 [(set (pc)
7480 (label_ref (match_operand 0 "" "")))]
7481 "TARGET_32BIT"
7482 "*
7483 {
7484 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2)
7485 {
7486 arm_ccfsm_state += 2;
7487 return \"\";
7488 }
7489 return \"b%?\\t%l0\";
7490 }
7491 "
7492 [(set_attr "predicable" "yes")
7493 (set (attr "length")
7494 (if_then_else
7495 (and (match_test "TARGET_THUMB2")
7496 (and (ge (minus (match_dup 0) (pc)) (const_int -2044))
7497 (le (minus (match_dup 0) (pc)) (const_int 2048))))
7498 (const_int 2)
7499 (const_int 4)))
7500 (set_attr "type" "branch")]
7501 )
7502
7503 (define_expand "call"
7504 [(parallel [(call (match_operand 0 "memory_operand")
7505 (match_operand 1 "general_operand"))
7506 (use (match_operand 2 "" ""))
7507 (clobber (reg:SI LR_REGNUM))])]
7508 "TARGET_EITHER"
7509 "
7510 {
7511 rtx callee, pat;
7512 tree addr = MEM_EXPR (operands[0]);
7513
7514 /* In an untyped call, we can get NULL for operand 2. */
7515 if (operands[2] == NULL_RTX)
7516 operands[2] = const0_rtx;
7517
7518 /* Decide if we should generate indirect calls by loading the
7519 32-bit address of the callee into a register before performing the
7520 branch and link. */
7521 callee = XEXP (operands[0], 0);
7522 if (GET_CODE (callee) == SYMBOL_REF
7523 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7524 : !REG_P (callee))
7525 XEXP (operands[0], 0) = force_reg (Pmode, callee);
7526
7527 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[0], 0)))
7528 /* Indirect call: set r9 with FDPIC value of callee. */
7529 XEXP (operands[0], 0)
7530 = arm_load_function_descriptor (XEXP (operands[0], 0));
7531
7532 if (detect_cmse_nonsecure_call (addr))
7533 {
7534 pat = gen_nonsecure_call_internal (operands[0], operands[1],
7535 operands[2]);
7536 emit_call_insn (pat);
7537 }
7538 else
7539 {
7540 pat = gen_call_internal (operands[0], operands[1], operands[2]);
7541 arm_emit_call_insn (pat, XEXP (operands[0], 0), false);
7542 }
7543
7544 /* Restore FDPIC register (r9) after call. */
7545 if (TARGET_FDPIC)
7546 {
7547 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7548 rtx initial_fdpic_reg
7549 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7550
7551 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7552 initial_fdpic_reg));
7553 }
7554
7555 DONE;
7556 }"
7557 )
7558
7559 (define_insn "restore_pic_register_after_call"
7560 [(set (match_operand:SI 0 "s_register_operand" "+r,r")
7561 (unspec:SI [(match_dup 0)
7562 (match_operand:SI 1 "nonimmediate_operand" "r,m")]
7563 UNSPEC_PIC_RESTORE))]
7564 ""
7565 "@
7566 mov\t%0, %1
7567 ldr\t%0, %1"
7568 )
7569
7570 (define_expand "call_internal"
7571 [(parallel [(call (match_operand 0 "memory_operand")
7572 (match_operand 1 "general_operand"))
7573 (use (match_operand 2 "" ""))
7574 (clobber (reg:SI LR_REGNUM))])])
7575
7576 (define_expand "nonsecure_call_internal"
7577 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand")]
7578 UNSPEC_NONSECURE_MEM)
7579 (match_operand 1 "general_operand"))
7580 (use (match_operand 2 "" ""))
7581 (clobber (reg:SI LR_REGNUM))])]
7582 "use_cmse"
7583 "
7584 {
7585 rtx tmp;
7586 tmp = copy_to_suggested_reg (XEXP (operands[0], 0),
7587 gen_rtx_REG (SImode, R4_REGNUM),
7588 SImode);
7589
7590 operands[0] = replace_equiv_address (operands[0], tmp);
7591 }")
7592
7593 (define_insn "*call_reg_armv5"
7594 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7595 (match_operand 1 "" ""))
7596 (use (match_operand 2 "" ""))
7597 (clobber (reg:SI LR_REGNUM))]
7598 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7599 "blx%?\\t%0"
7600 [(set_attr "type" "call")]
7601 )
7602
7603 (define_insn "*call_reg_arm"
7604 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
7605 (match_operand 1 "" ""))
7606 (use (match_operand 2 "" ""))
7607 (clobber (reg:SI LR_REGNUM))]
7608 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7609 "*
7610 return output_call (operands);
7611 "
7612 ;; length is worst case, normally it is only two
7613 [(set_attr "length" "12")
7614 (set_attr "type" "call")]
7615 )
7616
7617
7618 (define_expand "call_value"
7619 [(parallel [(set (match_operand 0 "" "")
7620 (call (match_operand 1 "memory_operand")
7621 (match_operand 2 "general_operand")))
7622 (use (match_operand 3 "" ""))
7623 (clobber (reg:SI LR_REGNUM))])]
7624 "TARGET_EITHER"
7625 "
7626 {
7627 rtx pat, callee;
7628 tree addr = MEM_EXPR (operands[1]);
7629
7630 /* In an untyped call, we can get NULL for operand 2. */
7631 if (operands[3] == 0)
7632 operands[3] = const0_rtx;
7633
7634 /* Decide if we should generate indirect calls by loading the
7635 32-bit address of the callee into a register before performing the
7636 branch and link. */
7637 callee = XEXP (operands[1], 0);
7638 if (GET_CODE (callee) == SYMBOL_REF
7639 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee))
7640 : !REG_P (callee))
7641 XEXP (operands[1], 0) = force_reg (Pmode, callee);
7642
7643 if (TARGET_FDPIC && !SYMBOL_REF_P (XEXP (operands[1], 0)))
7644 /* Indirect call: set r9 with FDPIC value of callee. */
7645 XEXP (operands[1], 0)
7646 = arm_load_function_descriptor (XEXP (operands[1], 0));
7647
7648 if (detect_cmse_nonsecure_call (addr))
7649 {
7650 pat = gen_nonsecure_call_value_internal (operands[0], operands[1],
7651 operands[2], operands[3]);
7652 emit_call_insn (pat);
7653 }
7654 else
7655 {
7656 pat = gen_call_value_internal (operands[0], operands[1],
7657 operands[2], operands[3]);
7658 arm_emit_call_insn (pat, XEXP (operands[1], 0), false);
7659 }
7660
7661 /* Restore FDPIC register (r9) after call. */
7662 if (TARGET_FDPIC)
7663 {
7664 rtx fdpic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
7665 rtx initial_fdpic_reg
7666 = get_hard_reg_initial_val (Pmode, FDPIC_REGNUM);
7667
7668 emit_insn (gen_restore_pic_register_after_call (fdpic_reg,
7669 initial_fdpic_reg));
7670 }
7671
7672 DONE;
7673 }"
7674 )
7675
7676 (define_expand "call_value_internal"
7677 [(parallel [(set (match_operand 0 "" "")
7678 (call (match_operand 1 "memory_operand")
7679 (match_operand 2 "general_operand")))
7680 (use (match_operand 3 "" ""))
7681 (clobber (reg:SI LR_REGNUM))])])
7682
7683 (define_expand "nonsecure_call_value_internal"
7684 [(parallel [(set (match_operand 0 "" "")
7685 (call (unspec:SI [(match_operand 1 "memory_operand")]
7686 UNSPEC_NONSECURE_MEM)
7687 (match_operand 2 "general_operand")))
7688 (use (match_operand 3 "" ""))
7689 (clobber (reg:SI LR_REGNUM))])]
7690 "use_cmse"
7691 "
7692 {
7693 rtx tmp;
7694 tmp = copy_to_suggested_reg (XEXP (operands[1], 0),
7695 gen_rtx_REG (SImode, R4_REGNUM),
7696 SImode);
7697
7698 operands[1] = replace_equiv_address (operands[1], tmp);
7699 }")
7700
7701 (define_insn "*call_value_reg_armv5"
7702 [(set (match_operand 0 "" "")
7703 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7704 (match_operand 2 "" "")))
7705 (use (match_operand 3 "" ""))
7706 (clobber (reg:SI LR_REGNUM))]
7707 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)"
7708 "blx%?\\t%1"
7709 [(set_attr "type" "call")]
7710 )
7711
7712 (define_insn "*call_value_reg_arm"
7713 [(set (match_operand 0 "" "")
7714 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
7715 (match_operand 2 "" "")))
7716 (use (match_operand 3 "" ""))
7717 (clobber (reg:SI LR_REGNUM))]
7718 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)"
7719 "*
7720 return output_call (&operands[1]);
7721 "
7722 [(set_attr "length" "12")
7723 (set_attr "type" "call")]
7724 )
7725
7726 ;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses
7727 ;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
7728
7729 (define_insn "*call_symbol"
7730 [(call (mem:SI (match_operand:SI 0 "" ""))
7731 (match_operand 1 "" ""))
7732 (use (match_operand 2 "" ""))
7733 (clobber (reg:SI LR_REGNUM))]
7734 "TARGET_32BIT
7735 && !SIBLING_CALL_P (insn)
7736 && (GET_CODE (operands[0]) == SYMBOL_REF)
7737 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
7738 "*
7739 {
7740 rtx op = operands[0];
7741
7742 /* Switch mode now when possible. */
7743 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7744 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7745 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
7746
7747 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
7748 }"
7749 [(set_attr "type" "call")]
7750 )
7751
7752 (define_insn "*call_value_symbol"
7753 [(set (match_operand 0 "" "")
7754 (call (mem:SI (match_operand:SI 1 "" ""))
7755 (match_operand:SI 2 "" "")))
7756 (use (match_operand 3 "" ""))
7757 (clobber (reg:SI LR_REGNUM))]
7758 "TARGET_32BIT
7759 && !SIBLING_CALL_P (insn)
7760 && (GET_CODE (operands[1]) == SYMBOL_REF)
7761 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
7762 "*
7763 {
7764 rtx op = operands[1];
7765
7766 /* Switch mode now when possible. */
7767 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
7768 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op)))
7769 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\";
7770
7771 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
7772 }"
7773 [(set_attr "type" "call")]
7774 )
7775
7776 (define_expand "sibcall_internal"
7777 [(parallel [(call (match_operand 0 "memory_operand")
7778 (match_operand 1 "general_operand"))
7779 (return)
7780 (use (match_operand 2 "" ""))])])
7781
7782 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
7783 (define_expand "sibcall"
7784 [(parallel [(call (match_operand 0 "memory_operand")
7785 (match_operand 1 "general_operand"))
7786 (return)
7787 (use (match_operand 2 "" ""))])]
7788 "TARGET_32BIT"
7789 "
7790 {
7791 rtx pat;
7792
7793 if ((!REG_P (XEXP (operands[0], 0))
7794 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
7795 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7796 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
7797 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
7798
7799 if (operands[2] == NULL_RTX)
7800 operands[2] = const0_rtx;
7801
7802 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]);
7803 arm_emit_call_insn (pat, operands[0], true);
7804 DONE;
7805 }"
7806 )
7807
7808 (define_expand "sibcall_value_internal"
7809 [(parallel [(set (match_operand 0 "" "")
7810 (call (match_operand 1 "memory_operand")
7811 (match_operand 2 "general_operand")))
7812 (return)
7813 (use (match_operand 3 "" ""))])])
7814
7815 (define_expand "sibcall_value"
7816 [(parallel [(set (match_operand 0 "" "")
7817 (call (match_operand 1 "memory_operand")
7818 (match_operand 2 "general_operand")))
7819 (return)
7820 (use (match_operand 3 "" ""))])]
7821 "TARGET_32BIT"
7822 "
7823 {
7824 rtx pat;
7825
7826 if ((!REG_P (XEXP (operands[1], 0))
7827 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
7828 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7829 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
7830 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
7831
7832 if (operands[3] == NULL_RTX)
7833 operands[3] = const0_rtx;
7834
7835 pat = gen_sibcall_value_internal (operands[0], operands[1],
7836 operands[2], operands[3]);
7837 arm_emit_call_insn (pat, operands[1], true);
7838 DONE;
7839 }"
7840 )
7841
7842 (define_insn "*sibcall_insn"
7843 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
7844 (match_operand 1 "" ""))
7845 (return)
7846 (use (match_operand 2 "" ""))]
7847 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7848 "*
7849 if (which_alternative == 1)
7850 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
7851 else
7852 {
7853 if (arm_arch5t || arm_arch4t)
7854 return \"bx%?\\t%0\\t%@ indirect register sibling call\";
7855 else
7856 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
7857 }
7858 "
7859 [(set_attr "type" "call")]
7860 )
7861
7862 (define_insn "*sibcall_value_insn"
7863 [(set (match_operand 0 "" "")
7864 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
7865 (match_operand 2 "" "")))
7866 (return)
7867 (use (match_operand 3 "" ""))]
7868 "TARGET_32BIT && SIBLING_CALL_P (insn)"
7869 "*
7870 if (which_alternative == 1)
7871 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
7872 else
7873 {
7874 if (arm_arch5t || arm_arch4t)
7875 return \"bx%?\\t%1\";
7876 else
7877 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
7878 }
7879 "
7880 [(set_attr "type" "call")]
7881 )
7882
7883 (define_expand "<return_str>return"
7884 [(RETURNS)]
7885 "(TARGET_ARM || (TARGET_THUMB2
7886 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL
7887 && !IS_STACKALIGN (arm_current_func_type ())))
7888 <return_cond_false>"
7889 "
7890 {
7891 if (TARGET_THUMB2)
7892 {
7893 thumb2_expand_return (<return_simple_p>);
7894 DONE;
7895 }
7896 }
7897 "
7898 )
7899
7900 ;; Often the return insn will be the same as loading from memory, so set attr
7901 (define_insn "*arm_return"
7902 [(return)]
7903 "TARGET_ARM && USE_RETURN_INSN (FALSE)"
7904 "*
7905 {
7906 if (arm_ccfsm_state == 2)
7907 {
7908 arm_ccfsm_state += 2;
7909 return \"\";
7910 }
7911 return output_return_instruction (const_true_rtx, true, false, false);
7912 }"
7913 [(set_attr "type" "load_4")
7914 (set_attr "length" "12")
7915 (set_attr "predicable" "yes")]
7916 )
7917
7918 (define_insn "*cond_<return_str>return"
7919 [(set (pc)
7920 (if_then_else (match_operator 0 "arm_comparison_operator"
7921 [(match_operand 1 "cc_register" "") (const_int 0)])
7922 (RETURNS)
7923 (pc)))]
7924 "TARGET_ARM <return_cond_true>"
7925 "*
7926 {
7927 if (arm_ccfsm_state == 2)
7928 {
7929 arm_ccfsm_state += 2;
7930 return \"\";
7931 }
7932 return output_return_instruction (operands[0], true, false,
7933 <return_simple_p>);
7934 }"
7935 [(set_attr "conds" "use")
7936 (set_attr "length" "12")
7937 (set_attr "type" "load_4")]
7938 )
7939
7940 (define_insn "*cond_<return_str>return_inverted"
7941 [(set (pc)
7942 (if_then_else (match_operator 0 "arm_comparison_operator"
7943 [(match_operand 1 "cc_register" "") (const_int 0)])
7944 (pc)
7945 (RETURNS)))]
7946 "TARGET_ARM <return_cond_true>"
7947 "*
7948 {
7949 if (arm_ccfsm_state == 2)
7950 {
7951 arm_ccfsm_state += 2;
7952 return \"\";
7953 }
7954 return output_return_instruction (operands[0], true, true,
7955 <return_simple_p>);
7956 }"
7957 [(set_attr "conds" "use")
7958 (set_attr "length" "12")
7959 (set_attr "type" "load_4")]
7960 )
7961
7962 (define_insn "*arm_simple_return"
7963 [(simple_return)]
7964 "TARGET_ARM"
7965 "*
7966 {
7967 if (arm_ccfsm_state == 2)
7968 {
7969 arm_ccfsm_state += 2;
7970 return \"\";
7971 }
7972 return output_return_instruction (const_true_rtx, true, false, true);
7973 }"
7974 [(set_attr "type" "branch")
7975 (set_attr "length" "4")
7976 (set_attr "predicable" "yes")]
7977 )
7978
7979 ;; Generate a sequence of instructions to determine if the processor is
7980 ;; in 26-bit or 32-bit mode, and return the appropriate return address
7981 ;; mask.
7982
7983 (define_expand "return_addr_mask"
7984 [(set (match_dup 1)
7985 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7986 (const_int 0)))
7987 (set (match_operand:SI 0 "s_register_operand")
7988 (if_then_else:SI (eq (match_dup 1) (const_int 0))
7989 (const_int -1)
7990 (const_int 67108860)))] ; 0x03fffffc
7991 "TARGET_ARM"
7992 "
7993 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
7994 ")
7995
7996 (define_insn "*check_arch2"
7997 [(set (match_operand:CC_NOOV 0 "cc_register" "")
7998 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH)
7999 (const_int 0)))]
8000 "TARGET_ARM"
8001 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
8002 [(set_attr "length" "8")
8003 (set_attr "conds" "set")
8004 (set_attr "type" "multiple")]
8005 )
8006
8007 ;; Call subroutine returning any type.
8008
8009 (define_expand "untyped_call"
8010 [(parallel [(call (match_operand 0 "" "")
8011 (const_int 0))
8012 (match_operand 1 "" "")
8013 (match_operand 2 "" "")])]
8014 "TARGET_EITHER && !TARGET_FDPIC"
8015 "
8016 {
8017 int i;
8018 rtx par = gen_rtx_PARALLEL (VOIDmode,
8019 rtvec_alloc (XVECLEN (operands[2], 0)));
8020 rtx addr = gen_reg_rtx (Pmode);
8021 rtx mem;
8022 int size = 0;
8023
8024 emit_move_insn (addr, XEXP (operands[1], 0));
8025 mem = change_address (operands[1], BLKmode, addr);
8026
8027 for (i = 0; i < XVECLEN (operands[2], 0); i++)
8028 {
8029 rtx src = SET_SRC (XVECEXP (operands[2], 0, i));
8030
8031 /* Default code only uses r0 as a return value, but we could
8032 be using anything up to 4 registers. */
8033 if (REGNO (src) == R0_REGNUM)
8034 src = gen_rtx_REG (TImode, R0_REGNUM);
8035
8036 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src,
8037 GEN_INT (size));
8038 size += GET_MODE_SIZE (GET_MODE (src));
8039 }
8040
8041 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL));
8042
8043 size = 0;
8044
8045 for (i = 0; i < XVECLEN (par, 0); i++)
8046 {
8047 HOST_WIDE_INT offset = 0;
8048 rtx reg = XEXP (XVECEXP (par, 0, i), 0);
8049
8050 if (size != 0)
8051 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8052
8053 mem = change_address (mem, GET_MODE (reg), NULL);
8054 if (REGNO (reg) == R0_REGNUM)
8055 {
8056 /* On thumb we have to use a write-back instruction. */
8057 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr,
8058 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8059 size = TARGET_ARM ? 16 : 0;
8060 }
8061 else
8062 {
8063 emit_move_insn (mem, reg);
8064 size = GET_MODE_SIZE (GET_MODE (reg));
8065 }
8066 }
8067
8068 /* The optimizer does not know that the call sets the function value
8069 registers we stored in the result block. We avoid problems by
8070 claiming that all hard registers are used and clobbered at this
8071 point. */
8072 emit_insn (gen_blockage ());
8073
8074 DONE;
8075 }"
8076 )
8077
8078 (define_expand "untyped_return"
8079 [(match_operand:BLK 0 "memory_operand")
8080 (match_operand 1 "" "")]
8081 "TARGET_EITHER && !TARGET_FDPIC"
8082 "
8083 {
8084 int i;
8085 rtx addr = gen_reg_rtx (Pmode);
8086 rtx mem;
8087 int size = 0;
8088
8089 emit_move_insn (addr, XEXP (operands[0], 0));
8090 mem = change_address (operands[0], BLKmode, addr);
8091
8092 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8093 {
8094 HOST_WIDE_INT offset = 0;
8095 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i));
8096
8097 if (size != 0)
8098 emit_move_insn (addr, plus_constant (Pmode, addr, size));
8099
8100 mem = change_address (mem, GET_MODE (reg), NULL);
8101 if (REGNO (reg) == R0_REGNUM)
8102 {
8103 /* On thumb we have to use a write-back instruction. */
8104 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr,
8105 TARGET_THUMB ? TRUE : FALSE, mem, &offset));
8106 size = TARGET_ARM ? 16 : 0;
8107 }
8108 else
8109 {
8110 emit_move_insn (reg, mem);
8111 size = GET_MODE_SIZE (GET_MODE (reg));
8112 }
8113 }
8114
8115 /* Emit USE insns before the return. */
8116 for (i = 0; i < XVECLEN (operands[1], 0); i++)
8117 emit_use (SET_DEST (XVECEXP (operands[1], 0, i)));
8118
8119 /* Construct the return. */
8120 expand_naked_return ();
8121
8122 DONE;
8123 }"
8124 )
8125
8126 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
8127 ;; all of memory. This blocks insns from being moved across this point.
8128
8129 (define_insn "blockage"
8130 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
8131 "TARGET_EITHER"
8132 ""
8133 [(set_attr "length" "0")
8134 (set_attr "type" "block")]
8135 )
8136
8137 ;; Since we hard code r0 here use the 'o' constraint to prevent
8138 ;; provoking undefined behaviour in the hardware with putting out
8139 ;; auto-increment operations with potentially r0 as the base register.
8140 (define_insn "probe_stack"
8141 [(set (match_operand:SI 0 "memory_operand" "=o")
8142 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
8143 "TARGET_32BIT"
8144 "str%?\\tr0, %0"
8145 [(set_attr "type" "store_4")
8146 (set_attr "predicable" "yes")]
8147 )
8148
8149 (define_insn "probe_stack_range"
8150 [(set (match_operand:SI 0 "register_operand" "=r")
8151 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")
8152 (match_operand:SI 2 "register_operand" "r")]
8153 VUNSPEC_PROBE_STACK_RANGE))]
8154 "TARGET_32BIT"
8155 {
8156 return output_probe_stack_range (operands[0], operands[2]);
8157 }
8158 [(set_attr "type" "multiple")
8159 (set_attr "conds" "clob")]
8160 )
8161
8162 ;; Named patterns for stack smashing protection.
8163 (define_expand "stack_protect_combined_set"
8164 [(parallel
8165 [(set (match_operand:SI 0 "memory_operand")
8166 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8167 UNSPEC_SP_SET))
8168 (clobber (match_scratch:SI 2 ""))
8169 (clobber (match_scratch:SI 3 ""))])]
8170 ""
8171 ""
8172 )
8173
8174 ;; Use a separate insn from the above expand to be able to have the mem outside
8175 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8176 ;; try to reload the guard since we need to control how PIC access is done in
8177 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8178 ;; legitimize_pic_address ()).
8179 (define_insn_and_split "*stack_protect_combined_set_insn"
8180 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8181 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8182 UNSPEC_SP_SET))
8183 (clobber (match_scratch:SI 2 "=&l,&r"))
8184 (clobber (match_scratch:SI 3 "=&l,&r"))]
8185 ""
8186 "#"
8187 "reload_completed"
8188 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))]
8189 UNSPEC_SP_SET))
8190 (clobber (match_dup 2))])]
8191 "
8192 {
8193 if (flag_pic)
8194 {
8195 rtx pic_reg;
8196
8197 if (TARGET_FDPIC)
8198 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8199 else
8200 pic_reg = operands[3];
8201
8202 /* Forces recomputing of GOT base now. */
8203 legitimize_pic_address (operands[1], SImode, operands[2], pic_reg,
8204 true /*compute_now*/);
8205 }
8206 else
8207 {
8208 if (address_operand (operands[1], SImode))
8209 operands[2] = operands[1];
8210 else
8211 {
8212 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8213 emit_move_insn (operands[2], mem);
8214 }
8215 }
8216 }"
8217 [(set_attr "arch" "t1,32")]
8218 )
8219
8220 ;; DO NOT SPLIT THIS INSN. It's important for security reasons that the
8221 ;; canary value does not live beyond the life of this sequence.
8222 (define_insn "*stack_protect_set_insn"
8223 [(set (match_operand:SI 0 "memory_operand" "=m,m")
8224 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))]
8225 UNSPEC_SP_SET))
8226 (clobber (match_dup 1))]
8227 ""
8228 "@
8229 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1, #0
8230 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1, #0"
8231 [(set_attr "length" "8,12")
8232 (set_attr "conds" "clob,nocond")
8233 (set_attr "type" "multiple")
8234 (set_attr "arch" "t1,32")]
8235 )
8236
8237 (define_expand "stack_protect_combined_test"
8238 [(parallel
8239 [(set (pc)
8240 (if_then_else
8241 (eq (match_operand:SI 0 "memory_operand")
8242 (unspec:SI [(match_operand:SI 1 "guard_operand")]
8243 UNSPEC_SP_TEST))
8244 (label_ref (match_operand 2))
8245 (pc)))
8246 (clobber (match_scratch:SI 3 ""))
8247 (clobber (match_scratch:SI 4 ""))
8248 (clobber (reg:CC CC_REGNUM))])]
8249 ""
8250 ""
8251 )
8252
8253 ;; Use a separate insn from the above expand to be able to have the mem outside
8254 ;; the operand #1 when register allocation comes. This is needed to avoid LRA
8255 ;; try to reload the guard since we need to control how PIC access is done in
8256 ;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling
8257 ;; legitimize_pic_address ()).
8258 (define_insn_and_split "*stack_protect_combined_test_insn"
8259 [(set (pc)
8260 (if_then_else
8261 (eq (match_operand:SI 0 "memory_operand" "m,m")
8262 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))]
8263 UNSPEC_SP_TEST))
8264 (label_ref (match_operand 2))
8265 (pc)))
8266 (clobber (match_scratch:SI 3 "=&l,&r"))
8267 (clobber (match_scratch:SI 4 "=&l,&r"))
8268 (clobber (reg:CC CC_REGNUM))]
8269 ""
8270 "#"
8271 "reload_completed"
8272 [(const_int 0)]
8273 {
8274 rtx eq;
8275
8276 if (flag_pic)
8277 {
8278 rtx pic_reg;
8279
8280 if (TARGET_FDPIC)
8281 pic_reg = gen_rtx_REG (Pmode, FDPIC_REGNUM);
8282 else
8283 pic_reg = operands[4];
8284
8285 /* Forces recomputing of GOT base now. */
8286 legitimize_pic_address (operands[1], SImode, operands[3], pic_reg,
8287 true /*compute_now*/);
8288 }
8289 else
8290 {
8291 if (address_operand (operands[1], SImode))
8292 operands[3] = operands[1];
8293 else
8294 {
8295 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0);
8296 emit_move_insn (operands[3], mem);
8297 }
8298 }
8299 if (TARGET_32BIT)
8300 {
8301 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0],
8302 operands[3]));
8303 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM);
8304 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx);
8305 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg));
8306 }
8307 else
8308 {
8309 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0],
8310 operands[3]));
8311 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
8312 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx,
8313 operands[2]));
8314 }
8315 DONE;
8316 }
8317 [(set_attr "arch" "t1,32")]
8318 )
8319
8320 (define_insn "arm_stack_protect_test_insn"
8321 [(set (reg:CC_Z CC_REGNUM)
8322 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m")
8323 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))]
8324 UNSPEC_SP_TEST)
8325 (const_int 0)))
8326 (clobber (match_operand:SI 0 "register_operand" "=&l,&r"))
8327 (clobber (match_dup 2))]
8328 "TARGET_32BIT"
8329 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0"
8330 [(set_attr "length" "8,12")
8331 (set_attr "conds" "set")
8332 (set_attr "type" "multiple")
8333 (set_attr "arch" "t,32")]
8334 )
8335
8336 (define_expand "casesi"
8337 [(match_operand:SI 0 "s_register_operand") ; index to jump on
8338 (match_operand:SI 1 "const_int_operand") ; lower bound
8339 (match_operand:SI 2 "const_int_operand") ; total range
8340 (match_operand:SI 3 "" "") ; table label
8341 (match_operand:SI 4 "" "")] ; Out of range label
8342 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code"
8343 "
8344 {
8345 enum insn_code code;
8346 if (operands[1] != const0_rtx)
8347 {
8348 rtx reg = gen_reg_rtx (SImode);
8349
8350 emit_insn (gen_addsi3 (reg, operands[0],
8351 gen_int_mode (-INTVAL (operands[1]),
8352 SImode)));
8353 operands[0] = reg;
8354 }
8355
8356 if (TARGET_ARM)
8357 code = CODE_FOR_arm_casesi_internal;
8358 else if (TARGET_THUMB1)
8359 code = CODE_FOR_thumb1_casesi_internal_pic;
8360 else if (flag_pic)
8361 code = CODE_FOR_thumb2_casesi_internal_pic;
8362 else
8363 code = CODE_FOR_thumb2_casesi_internal;
8364
8365 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
8366 operands[2] = force_reg (SImode, operands[2]);
8367
8368 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2],
8369 operands[3], operands[4]));
8370 DONE;
8371 }"
8372 )
8373
8374 ;; The USE in this pattern is needed to tell flow analysis that this is
8375 ;; a CASESI insn. It has no other purpose.
8376 (define_expand "arm_casesi_internal"
8377 [(parallel [(set (pc)
8378 (if_then_else
8379 (leu (match_operand:SI 0 "s_register_operand")
8380 (match_operand:SI 1 "arm_rhs_operand"))
8381 (match_dup 4)
8382 (label_ref:SI (match_operand 3 ""))))
8383 (clobber (reg:CC CC_REGNUM))
8384 (use (label_ref:SI (match_operand 2 "")))])]
8385 "TARGET_ARM"
8386 {
8387 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
8388 operands[4] = gen_rtx_PLUS (SImode, operands[4],
8389 gen_rtx_LABEL_REF (SImode, operands[2]));
8390 operands[4] = gen_rtx_MEM (SImode, operands[4]);
8391 MEM_READONLY_P (operands[4]) = 1;
8392 MEM_NOTRAP_P (operands[4]) = 1;
8393 })
8394
8395 (define_insn "*arm_casesi_internal"
8396 [(parallel [(set (pc)
8397 (if_then_else
8398 (leu (match_operand:SI 0 "s_register_operand" "r")
8399 (match_operand:SI 1 "arm_rhs_operand" "rI"))
8400 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
8401 (label_ref:SI (match_operand 2 "" ""))))
8402 (label_ref:SI (match_operand 3 "" ""))))
8403 (clobber (reg:CC CC_REGNUM))
8404 (use (label_ref:SI (match_dup 2)))])]
8405 "TARGET_ARM"
8406 "*
8407 if (flag_pic)
8408 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\";
8409 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
8410 "
8411 [(set_attr "conds" "clob")
8412 (set_attr "length" "12")
8413 (set_attr "type" "multiple")]
8414 )
8415
8416 (define_expand "indirect_jump"
8417 [(set (pc)
8418 (match_operand:SI 0 "s_register_operand"))]
8419 "TARGET_EITHER"
8420 "
8421 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the
8422 address and use bx. */
8423 if (TARGET_THUMB2)
8424 {
8425 rtx tmp;
8426 tmp = gen_reg_rtx (SImode);
8427 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1)));
8428 operands[0] = tmp;
8429 }
8430 "
8431 )
8432
8433 ;; NB Never uses BX.
8434 (define_insn "*arm_indirect_jump"
8435 [(set (pc)
8436 (match_operand:SI 0 "s_register_operand" "r"))]
8437 "TARGET_ARM"
8438 "mov%?\\t%|pc, %0\\t%@ indirect register jump"
8439 [(set_attr "predicable" "yes")
8440 (set_attr "type" "branch")]
8441 )
8442
8443 (define_insn "*load_indirect_jump"
8444 [(set (pc)
8445 (match_operand:SI 0 "memory_operand" "m"))]
8446 "TARGET_ARM"
8447 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump"
8448 [(set_attr "type" "load_4")
8449 (set_attr "pool_range" "4096")
8450 (set_attr "neg_pool_range" "4084")
8451 (set_attr "predicable" "yes")]
8452 )
8453
8454 \f
8455 ;; Misc insns
8456
8457 (define_insn "nop"
8458 [(const_int 0)]
8459 "TARGET_EITHER"
8460 "nop"
8461 [(set (attr "length")
8462 (if_then_else (eq_attr "is_thumb" "yes")
8463 (const_int 2)
8464 (const_int 4)))
8465 (set_attr "type" "mov_reg")]
8466 )
8467
8468 (define_insn "trap"
8469 [(trap_if (const_int 1) (const_int 0))]
8470 ""
8471 "*
8472 if (TARGET_ARM)
8473 return \".inst\\t0xe7f000f0\";
8474 else
8475 return \".inst\\t0xdeff\";
8476 "
8477 [(set (attr "length")
8478 (if_then_else (eq_attr "is_thumb" "yes")
8479 (const_int 2)
8480 (const_int 4)))
8481 (set_attr "type" "trap")
8482 (set_attr "conds" "unconditional")]
8483 )
8484
8485 \f
8486 ;; Patterns to allow combination of arithmetic, cond code and shifts
8487
8488 (define_insn "*<arith_shift_insn>_multsi"
8489 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8490 (SHIFTABLE_OPS:SI
8491 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r")
8492 (match_operand:SI 3 "power_of_two_operand" ""))
8493 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))]
8494 "TARGET_32BIT"
8495 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3"
8496 [(set_attr "predicable" "yes")
8497 (set_attr "shift" "2")
8498 (set_attr "arch" "a,t2")
8499 (set_attr "type" "alu_shift_imm")])
8500
8501 (define_insn "*<arith_shift_insn>_shiftsi"
8502 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8503 (SHIFTABLE_OPS:SI
8504 (match_operator:SI 2 "shift_nomul_operator"
8505 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8506 (match_operand:SI 4 "shift_amount_operand" "M,M,r")])
8507 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))]
8508 "TARGET_32BIT && GET_CODE (operands[2]) != MULT"
8509 "<arith_shift_insn>%?\\t%0, %1, %3%S2"
8510 [(set_attr "predicable" "yes")
8511 (set_attr "shift" "3")
8512 (set_attr "arch" "a,t2,a")
8513 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
8514
8515 (define_split
8516 [(set (match_operand:SI 0 "s_register_operand" "")
8517 (match_operator:SI 1 "shiftable_operator"
8518 [(match_operator:SI 2 "shiftable_operator"
8519 [(match_operator:SI 3 "shift_operator"
8520 [(match_operand:SI 4 "s_register_operand" "")
8521 (match_operand:SI 5 "reg_or_int_operand" "")])
8522 (match_operand:SI 6 "s_register_operand" "")])
8523 (match_operand:SI 7 "arm_rhs_operand" "")]))
8524 (clobber (match_operand:SI 8 "s_register_operand" ""))]
8525 "TARGET_32BIT"
8526 [(set (match_dup 8)
8527 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8528 (match_dup 6)]))
8529 (set (match_dup 0)
8530 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
8531 "")
8532
8533 (define_insn "*arith_shiftsi_compare0"
8534 [(set (reg:CC_NOOV CC_REGNUM)
8535 (compare:CC_NOOV
8536 (match_operator:SI 1 "shiftable_operator"
8537 [(match_operator:SI 3 "shift_operator"
8538 [(match_operand:SI 4 "s_register_operand" "r,r")
8539 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8540 (match_operand:SI 2 "s_register_operand" "r,r")])
8541 (const_int 0)))
8542 (set (match_operand:SI 0 "s_register_operand" "=r,r")
8543 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
8544 (match_dup 2)]))]
8545 "TARGET_32BIT"
8546 "%i1s%?\\t%0, %2, %4%S3"
8547 [(set_attr "conds" "set")
8548 (set_attr "shift" "4")
8549 (set_attr "arch" "32,a")
8550 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8551
8552 (define_insn "*arith_shiftsi_compare0_scratch"
8553 [(set (reg:CC_NOOV CC_REGNUM)
8554 (compare:CC_NOOV
8555 (match_operator:SI 1 "shiftable_operator"
8556 [(match_operator:SI 3 "shift_operator"
8557 [(match_operand:SI 4 "s_register_operand" "r,r")
8558 (match_operand:SI 5 "shift_amount_operand" "M,r")])
8559 (match_operand:SI 2 "s_register_operand" "r,r")])
8560 (const_int 0)))
8561 (clobber (match_scratch:SI 0 "=r,r"))]
8562 "TARGET_32BIT"
8563 "%i1s%?\\t%0, %2, %4%S3"
8564 [(set_attr "conds" "set")
8565 (set_attr "shift" "4")
8566 (set_attr "arch" "32,a")
8567 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8568
8569 (define_insn "*sub_shiftsi"
8570 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8571 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
8572 (match_operator:SI 2 "shift_operator"
8573 [(match_operand:SI 3 "s_register_operand" "r,r")
8574 (match_operand:SI 4 "shift_amount_operand" "M,r")])))]
8575 "TARGET_32BIT"
8576 "sub%?\\t%0, %1, %3%S2"
8577 [(set_attr "predicable" "yes")
8578 (set_attr "predicable_short_it" "no")
8579 (set_attr "shift" "3")
8580 (set_attr "arch" "32,a")
8581 (set_attr "type" "alus_shift_imm,alus_shift_reg")])
8582
8583 (define_insn "*sub_shiftsi_compare0"
8584 [(set (reg:CC_NOOV CC_REGNUM)
8585 (compare:CC_NOOV
8586 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8587 (match_operator:SI 2 "shift_operator"
8588 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8589 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8590 (const_int 0)))
8591 (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8592 (minus:SI (match_dup 1)
8593 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
8594 "TARGET_32BIT"
8595 "subs%?\\t%0, %1, %3%S2"
8596 [(set_attr "conds" "set")
8597 (set_attr "shift" "3")
8598 (set_attr "arch" "32,a,a")
8599 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8600
8601 (define_insn "*sub_shiftsi_compare0_scratch"
8602 [(set (reg:CC_NOOV CC_REGNUM)
8603 (compare:CC_NOOV
8604 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
8605 (match_operator:SI 2 "shift_operator"
8606 [(match_operand:SI 3 "s_register_operand" "r,r,r")
8607 (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
8608 (const_int 0)))
8609 (clobber (match_scratch:SI 0 "=r,r,r"))]
8610 "TARGET_32BIT"
8611 "subs%?\\t%0, %1, %3%S2"
8612 [(set_attr "conds" "set")
8613 (set_attr "shift" "3")
8614 (set_attr "arch" "32,a,a")
8615 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
8616 \f
8617
8618 (define_insn_and_split "*and_scc"
8619 [(set (match_operand:SI 0 "s_register_operand" "=r")
8620 (and:SI (match_operator:SI 1 "arm_comparison_operator"
8621 [(match_operand 2 "cc_register" "") (const_int 0)])
8622 (match_operand:SI 3 "s_register_operand" "r")))]
8623 "TARGET_ARM"
8624 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1"
8625 "&& reload_completed"
8626 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0)))
8627 (cond_exec (match_dup 4) (set (match_dup 0)
8628 (and:SI (match_dup 3) (const_int 1))))]
8629 {
8630 machine_mode mode = GET_MODE (operands[2]);
8631 enum rtx_code rc = GET_CODE (operands[1]);
8632
8633 /* Note that operands[4] is the same as operands[1],
8634 but with VOIDmode as the result. */
8635 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8636 if (mode == CCFPmode || mode == CCFPEmode)
8637 rc = reverse_condition_maybe_unordered (rc);
8638 else
8639 rc = reverse_condition (rc);
8640 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8641 }
8642 [(set_attr "conds" "use")
8643 (set_attr "type" "multiple")
8644 (set_attr "length" "8")]
8645 )
8646
8647 (define_insn_and_split "*ior_scc"
8648 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8649 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
8650 [(match_operand 2 "cc_register" "") (const_int 0)])
8651 (match_operand:SI 3 "s_register_operand" "0,?r")))]
8652 "TARGET_ARM"
8653 "@
8654 orr%d1\\t%0, %3, #1
8655 #"
8656 "&& reload_completed
8657 && REGNO (operands [0]) != REGNO (operands[3])"
8658 ;; && which_alternative == 1
8659 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
8660 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
8661 (cond_exec (match_dup 4) (set (match_dup 0)
8662 (ior:SI (match_dup 3) (const_int 1))))]
8663 {
8664 machine_mode mode = GET_MODE (operands[2]);
8665 enum rtx_code rc = GET_CODE (operands[1]);
8666
8667 /* Note that operands[4] is the same as operands[1],
8668 but with VOIDmode as the result. */
8669 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8670 if (mode == CCFPmode || mode == CCFPEmode)
8671 rc = reverse_condition_maybe_unordered (rc);
8672 else
8673 rc = reverse_condition (rc);
8674 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
8675 }
8676 [(set_attr "conds" "use")
8677 (set_attr "length" "4,8")
8678 (set_attr "type" "logic_imm,multiple")]
8679 )
8680
8681 ; A series of splitters for the compare_scc pattern below. Note that
8682 ; order is important.
8683 (define_split
8684 [(set (match_operand:SI 0 "s_register_operand" "")
8685 (lt:SI (match_operand:SI 1 "s_register_operand" "")
8686 (const_int 0)))
8687 (clobber (reg:CC CC_REGNUM))]
8688 "TARGET_32BIT && reload_completed"
8689 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))])
8690
8691 (define_split
8692 [(set (match_operand:SI 0 "s_register_operand" "")
8693 (ge:SI (match_operand:SI 1 "s_register_operand" "")
8694 (const_int 0)))
8695 (clobber (reg:CC CC_REGNUM))]
8696 "TARGET_32BIT && reload_completed"
8697 [(set (match_dup 0) (not:SI (match_dup 1)))
8698 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))])
8699
8700 (define_split
8701 [(set (match_operand:SI 0 "s_register_operand" "")
8702 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8703 (const_int 0)))
8704 (clobber (reg:CC CC_REGNUM))]
8705 "arm_arch5t && TARGET_32BIT"
8706 [(set (match_dup 0) (clz:SI (match_dup 1)))
8707 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8708 )
8709
8710 (define_split
8711 [(set (match_operand:SI 0 "s_register_operand" "")
8712 (eq:SI (match_operand:SI 1 "s_register_operand" "")
8713 (const_int 0)))
8714 (clobber (reg:CC CC_REGNUM))]
8715 "TARGET_32BIT && reload_completed"
8716 [(parallel
8717 [(set (reg:CC CC_REGNUM)
8718 (compare:CC (const_int 1) (match_dup 1)))
8719 (set (match_dup 0)
8720 (minus:SI (const_int 1) (match_dup 1)))])
8721 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0))
8722 (set (match_dup 0) (const_int 0)))])
8723
8724 (define_split
8725 [(set (match_operand:SI 0 "s_register_operand" "")
8726 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8727 (match_operand:SI 2 "const_int_operand" "")))
8728 (clobber (reg:CC CC_REGNUM))]
8729 "TARGET_32BIT && reload_completed"
8730 [(parallel
8731 [(set (reg:CC CC_REGNUM)
8732 (compare:CC (match_dup 1) (match_dup 2)))
8733 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))])
8734 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0))
8735 (set (match_dup 0) (const_int 1)))]
8736 {
8737 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode);
8738 })
8739
8740 (define_split
8741 [(set (match_operand:SI 0 "s_register_operand" "")
8742 (ne:SI (match_operand:SI 1 "s_register_operand" "")
8743 (match_operand:SI 2 "arm_add_operand" "")))
8744 (clobber (reg:CC CC_REGNUM))]
8745 "TARGET_32BIT && reload_completed"
8746 [(parallel
8747 [(set (reg:CC_NOOV CC_REGNUM)
8748 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2))
8749 (const_int 0)))
8750 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8751 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0))
8752 (set (match_dup 0) (const_int 1)))])
8753
8754 (define_insn_and_split "*compare_scc"
8755 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
8756 (match_operator:SI 1 "arm_comparison_operator"
8757 [(match_operand:SI 2 "s_register_operand" "r,r")
8758 (match_operand:SI 3 "arm_add_operand" "rI,L")]))
8759 (clobber (reg:CC CC_REGNUM))]
8760 "TARGET_32BIT"
8761 "#"
8762 "&& reload_completed"
8763 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3)))
8764 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))
8765 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))]
8766 {
8767 rtx tmp1;
8768 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
8769 operands[2], operands[3]);
8770 enum rtx_code rc = GET_CODE (operands[1]);
8771
8772 tmp1 = gen_rtx_REG (mode, CC_REGNUM);
8773
8774 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8775 if (mode == CCFPmode || mode == CCFPEmode)
8776 rc = reverse_condition_maybe_unordered (rc);
8777 else
8778 rc = reverse_condition (rc);
8779 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
8780 }
8781 [(set_attr "type" "multiple")]
8782 )
8783
8784 ;; Attempt to improve the sequence generated by the compare_scc splitters
8785 ;; not to use conditional execution.
8786
8787 ;; Rd = (eq (reg1) (const_int0)) // ARMv5
8788 ;; clz Rd, reg1
8789 ;; lsr Rd, Rd, #5
8790 (define_peephole2
8791 [(set (reg:CC CC_REGNUM)
8792 (compare:CC (match_operand:SI 1 "register_operand" "")
8793 (const_int 0)))
8794 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8795 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8796 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8797 (set (match_dup 0) (const_int 1)))]
8798 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8799 [(set (match_dup 0) (clz:SI (match_dup 1)))
8800 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8801 )
8802
8803 ;; Rd = (eq (reg1) (const_int0)) // !ARMv5
8804 ;; negs Rd, reg1
8805 ;; adc Rd, Rd, reg1
8806 (define_peephole2
8807 [(set (reg:CC CC_REGNUM)
8808 (compare:CC (match_operand:SI 1 "register_operand" "")
8809 (const_int 0)))
8810 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8811 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8812 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8813 (set (match_dup 0) (const_int 1)))
8814 (match_scratch:SI 2 "r")]
8815 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8816 [(parallel
8817 [(set (reg:CC CC_REGNUM)
8818 (compare:CC (const_int 0) (match_dup 1)))
8819 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))])
8820 (set (match_dup 0)
8821 (plus:SI (plus:SI (match_dup 1) (match_dup 2))
8822 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8823 )
8824
8825 ;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
8826 ;; sub Rd, Reg1, reg2
8827 ;; clz Rd, Rd
8828 ;; lsr Rd, Rd, #5
8829 (define_peephole2
8830 [(set (reg:CC CC_REGNUM)
8831 (compare:CC (match_operand:SI 1 "register_operand" "")
8832 (match_operand:SI 2 "arm_rhs_operand" "")))
8833 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8834 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8835 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8836 (set (match_dup 0) (const_int 1)))]
8837 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
8838 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
8839 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
8840 (set (match_dup 0) (clz:SI (match_dup 0)))
8841 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
8842 )
8843
8844
8845 ;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
8846 ;; sub T1, Reg1, reg2
8847 ;; negs Rd, T1
8848 ;; adc Rd, Rd, T1
8849 (define_peephole2
8850 [(set (reg:CC CC_REGNUM)
8851 (compare:CC (match_operand:SI 1 "register_operand" "")
8852 (match_operand:SI 2 "arm_rhs_operand" "")))
8853 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0))
8854 (set (match_operand:SI 0 "register_operand" "") (const_int 0)))
8855 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
8856 (set (match_dup 0) (const_int 1)))
8857 (match_scratch:SI 3 "r")]
8858 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
8859 [(set (match_dup 3) (match_dup 4))
8860 (parallel
8861 [(set (reg:CC CC_REGNUM)
8862 (compare:CC (const_int 0) (match_dup 3)))
8863 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))])
8864 (set (match_dup 0)
8865 (plus:SI (plus:SI (match_dup 0) (match_dup 3))
8866 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
8867 "
8868 if (CONST_INT_P (operands[2]))
8869 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
8870 else
8871 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
8872 ")
8873
8874 (define_insn "*cond_move"
8875 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
8876 (if_then_else:SI (match_operator 3 "equality_operator"
8877 [(match_operator 4 "arm_comparison_operator"
8878 [(match_operand 5 "cc_register" "") (const_int 0)])
8879 (const_int 0)])
8880 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
8881 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
8882 "TARGET_ARM"
8883 "*
8884 if (GET_CODE (operands[3]) == NE)
8885 {
8886 if (which_alternative != 1)
8887 output_asm_insn (\"mov%D4\\t%0, %2\", operands);
8888 if (which_alternative != 0)
8889 output_asm_insn (\"mov%d4\\t%0, %1\", operands);
8890 return \"\";
8891 }
8892 if (which_alternative != 0)
8893 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8894 if (which_alternative != 1)
8895 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
8896 return \"\";
8897 "
8898 [(set_attr "conds" "use")
8899 (set_attr_alternative "type"
8900 [(if_then_else (match_operand 2 "const_int_operand" "")
8901 (const_string "mov_imm")
8902 (const_string "mov_reg"))
8903 (if_then_else (match_operand 1 "const_int_operand" "")
8904 (const_string "mov_imm")
8905 (const_string "mov_reg"))
8906 (const_string "multiple")])
8907 (set_attr "length" "4,4,8")]
8908 )
8909
8910 (define_insn "*cond_arith"
8911 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8912 (match_operator:SI 5 "shiftable_operator"
8913 [(match_operator:SI 4 "arm_comparison_operator"
8914 [(match_operand:SI 2 "s_register_operand" "r,r")
8915 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
8916 (match_operand:SI 1 "s_register_operand" "0,?r")]))
8917 (clobber (reg:CC CC_REGNUM))]
8918 "TARGET_ARM"
8919 "*
8920 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
8921 return \"%i5\\t%0, %1, %2, lsr #31\";
8922
8923 output_asm_insn (\"cmp\\t%2, %3\", operands);
8924 if (GET_CODE (operands[5]) == AND)
8925 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
8926 else if (GET_CODE (operands[5]) == MINUS)
8927 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
8928 else if (which_alternative != 0)
8929 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8930 return \"%i5%d4\\t%0, %1, #1\";
8931 "
8932 [(set_attr "conds" "clob")
8933 (set_attr "length" "12")
8934 (set_attr "type" "multiple")]
8935 )
8936
8937 (define_insn "*cond_sub"
8938 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
8939 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
8940 (match_operator:SI 4 "arm_comparison_operator"
8941 [(match_operand:SI 2 "s_register_operand" "r,r")
8942 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
8943 (clobber (reg:CC CC_REGNUM))]
8944 "TARGET_ARM"
8945 "*
8946 output_asm_insn (\"cmp\\t%2, %3\", operands);
8947 if (which_alternative != 0)
8948 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
8949 return \"sub%d4\\t%0, %1, #1\";
8950 "
8951 [(set_attr "conds" "clob")
8952 (set_attr "length" "8,12")
8953 (set_attr "type" "multiple")]
8954 )
8955
8956 (define_insn "*cmp_ite0"
8957 [(set (match_operand 6 "dominant_cc_register" "")
8958 (compare
8959 (if_then_else:SI
8960 (match_operator 4 "arm_comparison_operator"
8961 [(match_operand:SI 0 "s_register_operand"
8962 "l,l,l,r,r,r,r,r,r")
8963 (match_operand:SI 1 "arm_add_operand"
8964 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
8965 (match_operator:SI 5 "arm_comparison_operator"
8966 [(match_operand:SI 2 "s_register_operand"
8967 "l,r,r,l,l,r,r,r,r")
8968 (match_operand:SI 3 "arm_add_operand"
8969 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
8970 (const_int 0))
8971 (const_int 0)))]
8972 "TARGET_32BIT"
8973 "*
8974 {
8975 static const char * const cmp1[NUM_OF_COND_CMP][2] =
8976 {
8977 {\"cmp%d5\\t%0, %1\",
8978 \"cmp%d4\\t%2, %3\"},
8979 {\"cmn%d5\\t%0, #%n1\",
8980 \"cmp%d4\\t%2, %3\"},
8981 {\"cmp%d5\\t%0, %1\",
8982 \"cmn%d4\\t%2, #%n3\"},
8983 {\"cmn%d5\\t%0, #%n1\",
8984 \"cmn%d4\\t%2, #%n3\"}
8985 };
8986 static const char * const cmp2[NUM_OF_COND_CMP][2] =
8987 {
8988 {\"cmp\\t%2, %3\",
8989 \"cmp\\t%0, %1\"},
8990 {\"cmp\\t%2, %3\",
8991 \"cmn\\t%0, #%n1\"},
8992 {\"cmn\\t%2, #%n3\",
8993 \"cmp\\t%0, %1\"},
8994 {\"cmn\\t%2, #%n3\",
8995 \"cmn\\t%0, #%n1\"}
8996 };
8997 static const char * const ite[2] =
8998 {
8999 \"it\\t%d5\",
9000 \"it\\t%d4\"
9001 };
9002 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9003 CMP_CMP, CMN_CMP, CMP_CMP,
9004 CMN_CMP, CMP_CMN, CMN_CMN};
9005 int swap =
9006 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9007
9008 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9009 if (TARGET_THUMB2) {
9010 output_asm_insn (ite[swap], operands);
9011 }
9012 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9013 return \"\";
9014 }"
9015 [(set_attr "conds" "set")
9016 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9017 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9018 (set_attr "type" "multiple")
9019 (set_attr_alternative "length"
9020 [(const_int 6)
9021 (const_int 8)
9022 (const_int 8)
9023 (const_int 8)
9024 (const_int 8)
9025 (if_then_else (eq_attr "is_thumb" "no")
9026 (const_int 8)
9027 (const_int 10))
9028 (if_then_else (eq_attr "is_thumb" "no")
9029 (const_int 8)
9030 (const_int 10))
9031 (if_then_else (eq_attr "is_thumb" "no")
9032 (const_int 8)
9033 (const_int 10))
9034 (if_then_else (eq_attr "is_thumb" "no")
9035 (const_int 8)
9036 (const_int 10))])]
9037 )
9038
9039 (define_insn "*cmp_ite1"
9040 [(set (match_operand 6 "dominant_cc_register" "")
9041 (compare
9042 (if_then_else:SI
9043 (match_operator 4 "arm_comparison_operator"
9044 [(match_operand:SI 0 "s_register_operand"
9045 "l,l,l,r,r,r,r,r,r")
9046 (match_operand:SI 1 "arm_add_operand"
9047 "lPy,lPy,lPy,rI,L,rI,L,rI,L")])
9048 (match_operator:SI 5 "arm_comparison_operator"
9049 [(match_operand:SI 2 "s_register_operand"
9050 "l,r,r,l,l,r,r,r,r")
9051 (match_operand:SI 3 "arm_add_operand"
9052 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])
9053 (const_int 1))
9054 (const_int 0)))]
9055 "TARGET_32BIT"
9056 "*
9057 {
9058 static const char * const cmp1[NUM_OF_COND_CMP][2] =
9059 {
9060 {\"cmp\\t%0, %1\",
9061 \"cmp\\t%2, %3\"},
9062 {\"cmn\\t%0, #%n1\",
9063 \"cmp\\t%2, %3\"},
9064 {\"cmp\\t%0, %1\",
9065 \"cmn\\t%2, #%n3\"},
9066 {\"cmn\\t%0, #%n1\",
9067 \"cmn\\t%2, #%n3\"}
9068 };
9069 static const char * const cmp2[NUM_OF_COND_CMP][2] =
9070 {
9071 {\"cmp%d4\\t%2, %3\",
9072 \"cmp%D5\\t%0, %1\"},
9073 {\"cmp%d4\\t%2, %3\",
9074 \"cmn%D5\\t%0, #%n1\"},
9075 {\"cmn%d4\\t%2, #%n3\",
9076 \"cmp%D5\\t%0, %1\"},
9077 {\"cmn%d4\\t%2, #%n3\",
9078 \"cmn%D5\\t%0, #%n1\"}
9079 };
9080 static const char * const ite[2] =
9081 {
9082 \"it\\t%d4\",
9083 \"it\\t%D5\"
9084 };
9085 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN,
9086 CMP_CMP, CMN_CMP, CMP_CMP,
9087 CMN_CMP, CMP_CMN, CMN_CMN};
9088 int swap =
9089 comparison_dominates_p (GET_CODE (operands[5]),
9090 reverse_condition (GET_CODE (operands[4])));
9091
9092 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9093 if (TARGET_THUMB2) {
9094 output_asm_insn (ite[swap], operands);
9095 }
9096 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9097 return \"\";
9098 }"
9099 [(set_attr "conds" "set")
9100 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
9101 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no")
9102 (set_attr_alternative "length"
9103 [(const_int 6)
9104 (const_int 8)
9105 (const_int 8)
9106 (const_int 8)
9107 (const_int 8)
9108 (if_then_else (eq_attr "is_thumb" "no")
9109 (const_int 8)
9110 (const_int 10))
9111 (if_then_else (eq_attr "is_thumb" "no")
9112 (const_int 8)
9113 (const_int 10))
9114 (if_then_else (eq_attr "is_thumb" "no")
9115 (const_int 8)
9116 (const_int 10))
9117 (if_then_else (eq_attr "is_thumb" "no")
9118 (const_int 8)
9119 (const_int 10))])
9120 (set_attr "type" "multiple")]
9121 )
9122
9123 (define_insn "*cmp_and"
9124 [(set (match_operand 6 "dominant_cc_register" "")
9125 (compare
9126 (and:SI
9127 (match_operator 4 "arm_comparison_operator"
9128 [(match_operand:SI 0 "s_register_operand"
9129 "l,l,l,r,r,r,r,r,r,r")
9130 (match_operand:SI 1 "arm_add_operand"
9131 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9132 (match_operator:SI 5 "arm_comparison_operator"
9133 [(match_operand:SI 2 "s_register_operand"
9134 "l,r,r,l,l,r,r,r,r,r")
9135 (match_operand:SI 3 "arm_add_operand"
9136 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9137 (const_int 0)))]
9138 "TARGET_32BIT"
9139 "*
9140 {
9141 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9142 {
9143 {\"cmp%d5\\t%0, %1\",
9144 \"cmp%d4\\t%2, %3\"},
9145 {\"cmn%d5\\t%0, #%n1\",
9146 \"cmp%d4\\t%2, %3\"},
9147 {\"cmp%d5\\t%0, %1\",
9148 \"cmn%d4\\t%2, #%n3\"},
9149 {\"cmn%d5\\t%0, #%n1\",
9150 \"cmn%d4\\t%2, #%n3\"}
9151 };
9152 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9153 {
9154 {\"cmp\\t%2, %3\",
9155 \"cmp\\t%0, %1\"},
9156 {\"cmp\\t%2, %3\",
9157 \"cmn\\t%0, #%n1\"},
9158 {\"cmn\\t%2, #%n3\",
9159 \"cmp\\t%0, %1\"},
9160 {\"cmn\\t%2, #%n3\",
9161 \"cmn\\t%0, #%n1\"}
9162 };
9163 static const char *const ite[2] =
9164 {
9165 \"it\\t%d5\",
9166 \"it\\t%d4\"
9167 };
9168 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9169 CMP_CMP, CMN_CMP, CMP_CMP,
9170 CMP_CMP, CMN_CMP, CMP_CMN,
9171 CMN_CMN};
9172 int swap =
9173 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9174
9175 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9176 if (TARGET_THUMB2) {
9177 output_asm_insn (ite[swap], operands);
9178 }
9179 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9180 return \"\";
9181 }"
9182 [(set_attr "conds" "set")
9183 (set_attr "predicable" "no")
9184 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9185 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9186 (set_attr_alternative "length"
9187 [(const_int 6)
9188 (const_int 8)
9189 (const_int 8)
9190 (const_int 8)
9191 (const_int 8)
9192 (const_int 6)
9193 (if_then_else (eq_attr "is_thumb" "no")
9194 (const_int 8)
9195 (const_int 10))
9196 (if_then_else (eq_attr "is_thumb" "no")
9197 (const_int 8)
9198 (const_int 10))
9199 (if_then_else (eq_attr "is_thumb" "no")
9200 (const_int 8)
9201 (const_int 10))
9202 (if_then_else (eq_attr "is_thumb" "no")
9203 (const_int 8)
9204 (const_int 10))])
9205 (set_attr "type" "multiple")]
9206 )
9207
9208 (define_insn "*cmp_ior"
9209 [(set (match_operand 6 "dominant_cc_register" "")
9210 (compare
9211 (ior:SI
9212 (match_operator 4 "arm_comparison_operator"
9213 [(match_operand:SI 0 "s_register_operand"
9214 "l,l,l,r,r,r,r,r,r,r")
9215 (match_operand:SI 1 "arm_add_operand"
9216 "lPy,lPy,lPy,rI,L,r,rI,L,rI,L")])
9217 (match_operator:SI 5 "arm_comparison_operator"
9218 [(match_operand:SI 2 "s_register_operand"
9219 "l,r,r,l,l,r,r,r,r,r")
9220 (match_operand:SI 3 "arm_add_operand"
9221 "lPy,rI,L,lPy,lPy,r,rI,rI,L,L")]))
9222 (const_int 0)))]
9223 "TARGET_32BIT"
9224 "*
9225 {
9226 static const char *const cmp1[NUM_OF_COND_CMP][2] =
9227 {
9228 {\"cmp\\t%0, %1\",
9229 \"cmp\\t%2, %3\"},
9230 {\"cmn\\t%0, #%n1\",
9231 \"cmp\\t%2, %3\"},
9232 {\"cmp\\t%0, %1\",
9233 \"cmn\\t%2, #%n3\"},
9234 {\"cmn\\t%0, #%n1\",
9235 \"cmn\\t%2, #%n3\"}
9236 };
9237 static const char *const cmp2[NUM_OF_COND_CMP][2] =
9238 {
9239 {\"cmp%D4\\t%2, %3\",
9240 \"cmp%D5\\t%0, %1\"},
9241 {\"cmp%D4\\t%2, %3\",
9242 \"cmn%D5\\t%0, #%n1\"},
9243 {\"cmn%D4\\t%2, #%n3\",
9244 \"cmp%D5\\t%0, %1\"},
9245 {\"cmn%D4\\t%2, #%n3\",
9246 \"cmn%D5\\t%0, #%n1\"}
9247 };
9248 static const char *const ite[2] =
9249 {
9250 \"it\\t%D4\",
9251 \"it\\t%D5\"
9252 };
9253 static const int cmp_idx[] = {CMP_CMP, CMP_CMP, CMP_CMN,
9254 CMP_CMP, CMN_CMP, CMP_CMP,
9255 CMP_CMP, CMN_CMP, CMP_CMN,
9256 CMN_CMN};
9257 int swap =
9258 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4]));
9259
9260 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands);
9261 if (TARGET_THUMB2) {
9262 output_asm_insn (ite[swap], operands);
9263 }
9264 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands);
9265 return \"\";
9266 }
9267 "
9268 [(set_attr "conds" "set")
9269 (set_attr "arch" "t2,t2,t2,t2,t2,t2,any,any,any,any")
9270 (set_attr "enabled_for_short_it" "yes,no,no,no,no,yes,no,no,no,no")
9271 (set_attr_alternative "length"
9272 [(const_int 6)
9273 (const_int 8)
9274 (const_int 8)
9275 (const_int 8)
9276 (const_int 8)
9277 (const_int 6)
9278 (if_then_else (eq_attr "is_thumb" "no")
9279 (const_int 8)
9280 (const_int 10))
9281 (if_then_else (eq_attr "is_thumb" "no")
9282 (const_int 8)
9283 (const_int 10))
9284 (if_then_else (eq_attr "is_thumb" "no")
9285 (const_int 8)
9286 (const_int 10))
9287 (if_then_else (eq_attr "is_thumb" "no")
9288 (const_int 8)
9289 (const_int 10))])
9290 (set_attr "type" "multiple")]
9291 )
9292
9293 (define_insn_and_split "*ior_scc_scc"
9294 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9295 (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9296 [(match_operand:SI 1 "s_register_operand" "l,r")
9297 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9298 (match_operator:SI 6 "arm_comparison_operator"
9299 [(match_operand:SI 4 "s_register_operand" "l,r")
9300 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9301 (clobber (reg:CC CC_REGNUM))]
9302 "TARGET_32BIT
9303 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
9304 != CCmode)"
9305 "#"
9306 "TARGET_32BIT && reload_completed"
9307 [(set (match_dup 7)
9308 (compare
9309 (ior:SI
9310 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9311 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9312 (const_int 0)))
9313 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9314 "operands[7]
9315 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9316 DOM_CC_X_OR_Y),
9317 CC_REGNUM);"
9318 [(set_attr "conds" "clob")
9319 (set_attr "enabled_for_short_it" "yes,no")
9320 (set_attr "length" "16")
9321 (set_attr "type" "multiple")]
9322 )
9323
9324 ; If the above pattern is followed by a CMP insn, then the compare is
9325 ; redundant, since we can rework the conditional instruction that follows.
9326 (define_insn_and_split "*ior_scc_scc_cmp"
9327 [(set (match_operand 0 "dominant_cc_register" "")
9328 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
9329 [(match_operand:SI 1 "s_register_operand" "l,r")
9330 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9331 (match_operator:SI 6 "arm_comparison_operator"
9332 [(match_operand:SI 4 "s_register_operand" "l,r")
9333 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9334 (const_int 0)))
9335 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9336 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9337 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9338 "TARGET_32BIT"
9339 "#"
9340 "TARGET_32BIT && reload_completed"
9341 [(set (match_dup 0)
9342 (compare
9343 (ior:SI
9344 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9345 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9346 (const_int 0)))
9347 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9348 ""
9349 [(set_attr "conds" "set")
9350 (set_attr "enabled_for_short_it" "yes,no")
9351 (set_attr "length" "16")
9352 (set_attr "type" "multiple")]
9353 )
9354
9355 (define_insn_and_split "*and_scc_scc"
9356 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
9357 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9358 [(match_operand:SI 1 "s_register_operand" "l,r")
9359 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9360 (match_operator:SI 6 "arm_comparison_operator"
9361 [(match_operand:SI 4 "s_register_operand" "l,r")
9362 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])))
9363 (clobber (reg:CC CC_REGNUM))]
9364 "TARGET_32BIT
9365 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9366 != CCmode)"
9367 "#"
9368 "TARGET_32BIT && reload_completed
9369 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9370 != CCmode)"
9371 [(set (match_dup 7)
9372 (compare
9373 (and:SI
9374 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9375 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9376 (const_int 0)))
9377 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
9378 "operands[7]
9379 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
9380 DOM_CC_X_AND_Y),
9381 CC_REGNUM);"
9382 [(set_attr "conds" "clob")
9383 (set_attr "enabled_for_short_it" "yes,no")
9384 (set_attr "length" "16")
9385 (set_attr "type" "multiple")]
9386 )
9387
9388 ; If the above pattern is followed by a CMP insn, then the compare is
9389 ; redundant, since we can rework the conditional instruction that follows.
9390 (define_insn_and_split "*and_scc_scc_cmp"
9391 [(set (match_operand 0 "dominant_cc_register" "")
9392 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
9393 [(match_operand:SI 1 "s_register_operand" "l,r")
9394 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")])
9395 (match_operator:SI 6 "arm_comparison_operator"
9396 [(match_operand:SI 4 "s_register_operand" "l,r")
9397 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))
9398 (const_int 0)))
9399 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts")
9400 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9401 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
9402 "TARGET_32BIT"
9403 "#"
9404 "TARGET_32BIT && reload_completed"
9405 [(set (match_dup 0)
9406 (compare
9407 (and:SI
9408 (match_op_dup 3 [(match_dup 1) (match_dup 2)])
9409 (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
9410 (const_int 0)))
9411 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
9412 ""
9413 [(set_attr "conds" "set")
9414 (set_attr "enabled_for_short_it" "yes,no")
9415 (set_attr "length" "16")
9416 (set_attr "type" "multiple")]
9417 )
9418
9419 ;; If there is no dominance in the comparison, then we can still save an
9420 ;; instruction in the AND case, since we can know that the second compare
9421 ;; need only zero the value if false (if true, then the value is already
9422 ;; correct).
9423 (define_insn_and_split "*and_scc_scc_nodom"
9424 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts")
9425 (and:SI (match_operator:SI 3 "arm_comparison_operator"
9426 [(match_operand:SI 1 "s_register_operand" "r,r,0")
9427 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
9428 (match_operator:SI 6 "arm_comparison_operator"
9429 [(match_operand:SI 4 "s_register_operand" "r,r,r")
9430 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
9431 (clobber (reg:CC CC_REGNUM))]
9432 "TARGET_32BIT
9433 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
9434 == CCmode)"
9435 "#"
9436 "TARGET_32BIT && reload_completed"
9437 [(parallel [(set (match_dup 0)
9438 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
9439 (clobber (reg:CC CC_REGNUM))])
9440 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
9441 (set (match_dup 0)
9442 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
9443 (match_dup 0)
9444 (const_int 0)))]
9445 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
9446 operands[4], operands[5]),
9447 CC_REGNUM);
9448 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
9449 operands[5]);"
9450 [(set_attr "conds" "clob")
9451 (set_attr "length" "20")
9452 (set_attr "type" "multiple")]
9453 )
9454
9455 (define_split
9456 [(set (reg:CC_NOOV CC_REGNUM)
9457 (compare:CC_NOOV (ior:SI
9458 (and:SI (match_operand:SI 0 "s_register_operand" "")
9459 (const_int 1))
9460 (match_operator:SI 1 "arm_comparison_operator"
9461 [(match_operand:SI 2 "s_register_operand" "")
9462 (match_operand:SI 3 "arm_add_operand" "")]))
9463 (const_int 0)))
9464 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9465 "TARGET_ARM"
9466 [(set (match_dup 4)
9467 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9468 (match_dup 0)))
9469 (set (reg:CC_NOOV CC_REGNUM)
9470 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9471 (const_int 0)))]
9472 "")
9473
9474 (define_split
9475 [(set (reg:CC_NOOV CC_REGNUM)
9476 (compare:CC_NOOV (ior:SI
9477 (match_operator:SI 1 "arm_comparison_operator"
9478 [(match_operand:SI 2 "s_register_operand" "")
9479 (match_operand:SI 3 "arm_add_operand" "")])
9480 (and:SI (match_operand:SI 0 "s_register_operand" "")
9481 (const_int 1)))
9482 (const_int 0)))
9483 (clobber (match_operand:SI 4 "s_register_operand" ""))]
9484 "TARGET_ARM"
9485 [(set (match_dup 4)
9486 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
9487 (match_dup 0)))
9488 (set (reg:CC_NOOV CC_REGNUM)
9489 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
9490 (const_int 0)))]
9491 "")
9492 ;; ??? The conditional patterns above need checking for Thumb-2 usefulness
9493
9494 (define_insn_and_split "*negscc"
9495 [(set (match_operand:SI 0 "s_register_operand" "=r")
9496 (neg:SI (match_operator 3 "arm_comparison_operator"
9497 [(match_operand:SI 1 "s_register_operand" "r")
9498 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
9499 (clobber (reg:CC CC_REGNUM))]
9500 "TARGET_ARM"
9501 "#"
9502 "&& reload_completed"
9503 [(const_int 0)]
9504 {
9505 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
9506
9507 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
9508 {
9509 /* Emit mov\\t%0, %1, asr #31 */
9510 emit_insn (gen_rtx_SET (operands[0],
9511 gen_rtx_ASHIFTRT (SImode,
9512 operands[1],
9513 GEN_INT (31))));
9514 DONE;
9515 }
9516 else if (GET_CODE (operands[3]) == NE)
9517 {
9518 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */
9519 if (CONST_INT_P (operands[2]))
9520 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
9521 gen_int_mode (-INTVAL (operands[2]),
9522 SImode)));
9523 else
9524 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
9525
9526 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9527 gen_rtx_NE (SImode,
9528 cc_reg,
9529 const0_rtx),
9530 gen_rtx_SET (operands[0],
9531 GEN_INT (~0))));
9532 DONE;
9533 }
9534 else
9535 {
9536 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */
9537 emit_insn (gen_rtx_SET (cc_reg,
9538 gen_rtx_COMPARE (CCmode, operands[1], operands[2])));
9539 enum rtx_code rc = GET_CODE (operands[3]);
9540
9541 rc = reverse_condition (rc);
9542 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9543 gen_rtx_fmt_ee (rc,
9544 VOIDmode,
9545 cc_reg,
9546 const0_rtx),
9547 gen_rtx_SET (operands[0], const0_rtx)));
9548 rc = GET_CODE (operands[3]);
9549 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
9550 gen_rtx_fmt_ee (rc,
9551 VOIDmode,
9552 cc_reg,
9553 const0_rtx),
9554 gen_rtx_SET (operands[0],
9555 GEN_INT (~0))));
9556 DONE;
9557 }
9558 FAIL;
9559 }
9560 [(set_attr "conds" "clob")
9561 (set_attr "length" "12")
9562 (set_attr "type" "multiple")]
9563 )
9564
9565 (define_insn_and_split "movcond_addsi"
9566 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
9567 (if_then_else:SI
9568 (match_operator 5 "comparison_operator"
9569 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r")
9570 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL"))
9571 (const_int 0)])
9572 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r")
9573 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r")))
9574 (clobber (reg:CC CC_REGNUM))]
9575 "TARGET_32BIT"
9576 "#"
9577 "&& reload_completed"
9578 [(set (reg:CC_NOOV CC_REGNUM)
9579 (compare:CC_NOOV
9580 (plus:SI (match_dup 3)
9581 (match_dup 4))
9582 (const_int 0)))
9583 (set (match_dup 0) (match_dup 1))
9584 (cond_exec (match_dup 6)
9585 (set (match_dup 0) (match_dup 2)))]
9586 "
9587 {
9588 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]),
9589 operands[3], operands[4]);
9590 enum rtx_code rc = GET_CODE (operands[5]);
9591 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
9592 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode));
9593 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0]))
9594 rc = reverse_condition (rc);
9595 else
9596 std::swap (operands[1], operands[2]);
9597
9598 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
9599 }
9600 "
9601 [(set_attr "conds" "clob")
9602 (set_attr "enabled_for_short_it" "no,yes,yes")
9603 (set_attr "type" "multiple")]
9604 )
9605
9606 (define_insn "movcond"
9607 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9608 (if_then_else:SI
9609 (match_operator 5 "arm_comparison_operator"
9610 [(match_operand:SI 3 "s_register_operand" "r,r,r")
9611 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
9612 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
9613 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
9614 (clobber (reg:CC CC_REGNUM))]
9615 "TARGET_ARM"
9616 "*
9617 if (GET_CODE (operands[5]) == LT
9618 && (operands[4] == const0_rtx))
9619 {
9620 if (which_alternative != 1 && REG_P (operands[1]))
9621 {
9622 if (operands[2] == const0_rtx)
9623 return \"and\\t%0, %1, %3, asr #31\";
9624 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\";
9625 }
9626 else if (which_alternative != 0 && REG_P (operands[2]))
9627 {
9628 if (operands[1] == const0_rtx)
9629 return \"bic\\t%0, %2, %3, asr #31\";
9630 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
9631 }
9632 /* The only case that falls through to here is when both ops 1 & 2
9633 are constants. */
9634 }
9635
9636 if (GET_CODE (operands[5]) == GE
9637 && (operands[4] == const0_rtx))
9638 {
9639 if (which_alternative != 1 && REG_P (operands[1]))
9640 {
9641 if (operands[2] == const0_rtx)
9642 return \"bic\\t%0, %1, %3, asr #31\";
9643 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\";
9644 }
9645 else if (which_alternative != 0 && REG_P (operands[2]))
9646 {
9647 if (operands[1] == const0_rtx)
9648 return \"and\\t%0, %2, %3, asr #31\";
9649 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
9650 }
9651 /* The only case that falls through to here is when both ops 1 & 2
9652 are constants. */
9653 }
9654 if (CONST_INT_P (operands[4])
9655 && !const_ok_for_arm (INTVAL (operands[4])))
9656 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
9657 else
9658 output_asm_insn (\"cmp\\t%3, %4\", operands);
9659 if (which_alternative != 0)
9660 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
9661 if (which_alternative != 1)
9662 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
9663 return \"\";
9664 "
9665 [(set_attr "conds" "clob")
9666 (set_attr "length" "8,8,12")
9667 (set_attr "type" "multiple")]
9668 )
9669
9670 ;; ??? The patterns below need checking for Thumb-2 usefulness.
9671
9672 (define_insn "*ifcompare_plus_move"
9673 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9674 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9675 [(match_operand:SI 4 "s_register_operand" "r,r")
9676 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9677 (plus:SI
9678 (match_operand:SI 2 "s_register_operand" "r,r")
9679 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))
9680 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9681 (clobber (reg:CC CC_REGNUM))]
9682 "TARGET_ARM"
9683 "#"
9684 [(set_attr "conds" "clob")
9685 (set_attr "length" "8,12")
9686 (set_attr "type" "multiple")]
9687 )
9688
9689 (define_insn "*if_plus_move"
9690 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9691 (if_then_else:SI
9692 (match_operator 4 "arm_comparison_operator"
9693 [(match_operand 5 "cc_register" "") (const_int 0)])
9694 (plus:SI
9695 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9696 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))
9697 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))]
9698 "TARGET_ARM"
9699 "@
9700 add%d4\\t%0, %2, %3
9701 sub%d4\\t%0, %2, #%n3
9702 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1
9703 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1"
9704 [(set_attr "conds" "use")
9705 (set_attr "length" "4,4,8,8")
9706 (set_attr_alternative "type"
9707 [(if_then_else (match_operand 3 "const_int_operand" "")
9708 (const_string "alu_imm" )
9709 (const_string "alu_sreg"))
9710 (const_string "alu_imm")
9711 (const_string "multiple")
9712 (const_string "multiple")])]
9713 )
9714
9715 (define_insn "*ifcompare_move_plus"
9716 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9717 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9718 [(match_operand:SI 4 "s_register_operand" "r,r")
9719 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9720 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9721 (plus:SI
9722 (match_operand:SI 2 "s_register_operand" "r,r")
9723 (match_operand:SI 3 "arm_add_operand" "rIL,rIL"))))
9724 (clobber (reg:CC CC_REGNUM))]
9725 "TARGET_ARM"
9726 "#"
9727 [(set_attr "conds" "clob")
9728 (set_attr "length" "8,12")
9729 (set_attr "type" "multiple")]
9730 )
9731
9732 (define_insn "*if_move_plus"
9733 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r")
9734 (if_then_else:SI
9735 (match_operator 4 "arm_comparison_operator"
9736 [(match_operand 5 "cc_register" "") (const_int 0)])
9737 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")
9738 (plus:SI
9739 (match_operand:SI 2 "s_register_operand" "r,r,r,r")
9740 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))]
9741 "TARGET_ARM"
9742 "@
9743 add%D4\\t%0, %2, %3
9744 sub%D4\\t%0, %2, #%n3
9745 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1
9746 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
9747 [(set_attr "conds" "use")
9748 (set_attr "length" "4,4,8,8")
9749 (set_attr_alternative "type"
9750 [(if_then_else (match_operand 3 "const_int_operand" "")
9751 (const_string "alu_imm" )
9752 (const_string "alu_sreg"))
9753 (const_string "alu_imm")
9754 (const_string "multiple")
9755 (const_string "multiple")])]
9756 )
9757
9758 (define_insn "*ifcompare_arith_arith"
9759 [(set (match_operand:SI 0 "s_register_operand" "=r")
9760 (if_then_else:SI (match_operator 9 "arm_comparison_operator"
9761 [(match_operand:SI 5 "s_register_operand" "r")
9762 (match_operand:SI 6 "arm_add_operand" "rIL")])
9763 (match_operator:SI 8 "shiftable_operator"
9764 [(match_operand:SI 1 "s_register_operand" "r")
9765 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9766 (match_operator:SI 7 "shiftable_operator"
9767 [(match_operand:SI 3 "s_register_operand" "r")
9768 (match_operand:SI 4 "arm_rhs_operand" "rI")])))
9769 (clobber (reg:CC CC_REGNUM))]
9770 "TARGET_ARM"
9771 "#"
9772 [(set_attr "conds" "clob")
9773 (set_attr "length" "12")
9774 (set_attr "type" "multiple")]
9775 )
9776
9777 (define_insn "*if_arith_arith"
9778 [(set (match_operand:SI 0 "s_register_operand" "=r")
9779 (if_then_else:SI (match_operator 5 "arm_comparison_operator"
9780 [(match_operand 8 "cc_register" "") (const_int 0)])
9781 (match_operator:SI 6 "shiftable_operator"
9782 [(match_operand:SI 1 "s_register_operand" "r")
9783 (match_operand:SI 2 "arm_rhs_operand" "rI")])
9784 (match_operator:SI 7 "shiftable_operator"
9785 [(match_operand:SI 3 "s_register_operand" "r")
9786 (match_operand:SI 4 "arm_rhs_operand" "rI")])))]
9787 "TARGET_ARM"
9788 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
9789 [(set_attr "conds" "use")
9790 (set_attr "length" "8")
9791 (set_attr "type" "multiple")]
9792 )
9793
9794 (define_insn "*ifcompare_arith_move"
9795 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9796 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9797 [(match_operand:SI 2 "s_register_operand" "r,r")
9798 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")])
9799 (match_operator:SI 7 "shiftable_operator"
9800 [(match_operand:SI 4 "s_register_operand" "r,r")
9801 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")])
9802 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))
9803 (clobber (reg:CC CC_REGNUM))]
9804 "TARGET_ARM"
9805 "*
9806 /* If we have an operation where (op x 0) is the identity operation and
9807 the conditional operator is LT or GE and we are comparing against zero and
9808 everything is in registers then we can do this in two instructions. */
9809 if (operands[3] == const0_rtx
9810 && GET_CODE (operands[7]) != AND
9811 && REG_P (operands[5])
9812 && REG_P (operands[1])
9813 && REGNO (operands[1]) == REGNO (operands[4])
9814 && REGNO (operands[4]) != REGNO (operands[0]))
9815 {
9816 if (GET_CODE (operands[6]) == LT)
9817 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9818 else if (GET_CODE (operands[6]) == GE)
9819 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\";
9820 }
9821 if (CONST_INT_P (operands[3])
9822 && !const_ok_for_arm (INTVAL (operands[3])))
9823 output_asm_insn (\"cmn\\t%2, #%n3\", operands);
9824 else
9825 output_asm_insn (\"cmp\\t%2, %3\", operands);
9826 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands);
9827 if (which_alternative != 0)
9828 return \"mov%D6\\t%0, %1\";
9829 return \"\";
9830 "
9831 [(set_attr "conds" "clob")
9832 (set_attr "length" "8,12")
9833 (set_attr "type" "multiple")]
9834 )
9835
9836 (define_insn "*if_arith_move"
9837 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9838 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
9839 [(match_operand 6 "cc_register" "") (const_int 0)])
9840 (match_operator:SI 5 "shiftable_operator"
9841 [(match_operand:SI 2 "s_register_operand" "r,r")
9842 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
9843 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))]
9844 "TARGET_ARM"
9845 "@
9846 %I5%d4\\t%0, %2, %3
9847 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
9848 [(set_attr "conds" "use")
9849 (set_attr "length" "4,8")
9850 (set_attr_alternative "type"
9851 [(if_then_else (match_operand 3 "const_int_operand" "")
9852 (const_string "alu_shift_imm" )
9853 (const_string "alu_shift_reg"))
9854 (const_string "multiple")])]
9855 )
9856
9857 (define_insn "*ifcompare_move_arith"
9858 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9859 (if_then_else:SI (match_operator 6 "arm_comparison_operator"
9860 [(match_operand:SI 4 "s_register_operand" "r,r")
9861 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9862 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9863 (match_operator:SI 7 "shiftable_operator"
9864 [(match_operand:SI 2 "s_register_operand" "r,r")
9865 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
9866 (clobber (reg:CC CC_REGNUM))]
9867 "TARGET_ARM"
9868 "*
9869 /* If we have an operation where (op x 0) is the identity operation and
9870 the conditional operator is LT or GE and we are comparing against zero and
9871 everything is in registers then we can do this in two instructions */
9872 if (operands[5] == const0_rtx
9873 && GET_CODE (operands[7]) != AND
9874 && REG_P (operands[3])
9875 && REG_P (operands[1])
9876 && REGNO (operands[1]) == REGNO (operands[2])
9877 && REGNO (operands[2]) != REGNO (operands[0]))
9878 {
9879 if (GET_CODE (operands[6]) == GE)
9880 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9881 else if (GET_CODE (operands[6]) == LT)
9882 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\";
9883 }
9884
9885 if (CONST_INT_P (operands[5])
9886 && !const_ok_for_arm (INTVAL (operands[5])))
9887 output_asm_insn (\"cmn\\t%4, #%n5\", operands);
9888 else
9889 output_asm_insn (\"cmp\\t%4, %5\", operands);
9890
9891 if (which_alternative != 0)
9892 output_asm_insn (\"mov%d6\\t%0, %1\", operands);
9893 return \"%I7%D6\\t%0, %2, %3\";
9894 "
9895 [(set_attr "conds" "clob")
9896 (set_attr "length" "8,12")
9897 (set_attr "type" "multiple")]
9898 )
9899
9900 (define_insn "*if_move_arith"
9901 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9902 (if_then_else:SI
9903 (match_operator 4 "arm_comparison_operator"
9904 [(match_operand 6 "cc_register" "") (const_int 0)])
9905 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
9906 (match_operator:SI 5 "shiftable_operator"
9907 [(match_operand:SI 2 "s_register_operand" "r,r")
9908 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))]
9909 "TARGET_ARM"
9910 "@
9911 %I5%D4\\t%0, %2, %3
9912 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
9913 [(set_attr "conds" "use")
9914 (set_attr "length" "4,8")
9915 (set_attr_alternative "type"
9916 [(if_then_else (match_operand 3 "const_int_operand" "")
9917 (const_string "alu_shift_imm" )
9918 (const_string "alu_shift_reg"))
9919 (const_string "multiple")])]
9920 )
9921
9922 (define_insn "*ifcompare_move_not"
9923 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9924 (if_then_else:SI
9925 (match_operator 5 "arm_comparison_operator"
9926 [(match_operand:SI 3 "s_register_operand" "r,r")
9927 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9928 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
9929 (not:SI
9930 (match_operand:SI 2 "s_register_operand" "r,r"))))
9931 (clobber (reg:CC CC_REGNUM))]
9932 "TARGET_ARM"
9933 "#"
9934 [(set_attr "conds" "clob")
9935 (set_attr "length" "8,12")
9936 (set_attr "type" "multiple")]
9937 )
9938
9939 (define_insn "*if_move_not"
9940 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9941 (if_then_else:SI
9942 (match_operator 4 "arm_comparison_operator"
9943 [(match_operand 3 "cc_register" "") (const_int 0)])
9944 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
9945 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))]
9946 "TARGET_ARM"
9947 "@
9948 mvn%D4\\t%0, %2
9949 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2
9950 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
9951 [(set_attr "conds" "use")
9952 (set_attr "type" "mvn_reg")
9953 (set_attr "length" "4,8,8")
9954 (set_attr "type" "mvn_reg,multiple,multiple")]
9955 )
9956
9957 (define_insn "*ifcompare_not_move"
9958 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9959 (if_then_else:SI
9960 (match_operator 5 "arm_comparison_operator"
9961 [(match_operand:SI 3 "s_register_operand" "r,r")
9962 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
9963 (not:SI
9964 (match_operand:SI 2 "s_register_operand" "r,r"))
9965 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
9966 (clobber (reg:CC CC_REGNUM))]
9967 "TARGET_ARM"
9968 "#"
9969 [(set_attr "conds" "clob")
9970 (set_attr "length" "8,12")
9971 (set_attr "type" "multiple")]
9972 )
9973
9974 (define_insn "*if_not_move"
9975 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
9976 (if_then_else:SI
9977 (match_operator 4 "arm_comparison_operator"
9978 [(match_operand 3 "cc_register" "") (const_int 0)])
9979 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))
9980 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
9981 "TARGET_ARM"
9982 "@
9983 mvn%d4\\t%0, %2
9984 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
9985 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
9986 [(set_attr "conds" "use")
9987 (set_attr "type" "mvn_reg,multiple,multiple")
9988 (set_attr "length" "4,8,8")]
9989 )
9990
9991 (define_insn "*ifcompare_shift_move"
9992 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9993 (if_then_else:SI
9994 (match_operator 6 "arm_comparison_operator"
9995 [(match_operand:SI 4 "s_register_operand" "r,r")
9996 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
9997 (match_operator:SI 7 "shift_operator"
9998 [(match_operand:SI 2 "s_register_operand" "r,r")
9999 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])
10000 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10001 (clobber (reg:CC CC_REGNUM))]
10002 "TARGET_ARM"
10003 "#"
10004 [(set_attr "conds" "clob")
10005 (set_attr "length" "8,12")
10006 (set_attr "type" "multiple")]
10007 )
10008
10009 (define_insn "*if_shift_move"
10010 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10011 (if_then_else:SI
10012 (match_operator 5 "arm_comparison_operator"
10013 [(match_operand 6 "cc_register" "") (const_int 0)])
10014 (match_operator:SI 4 "shift_operator"
10015 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10016 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])
10017 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))]
10018 "TARGET_ARM"
10019 "@
10020 mov%d5\\t%0, %2%S4
10021 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4
10022 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4"
10023 [(set_attr "conds" "use")
10024 (set_attr "shift" "2")
10025 (set_attr "length" "4,8,8")
10026 (set_attr_alternative "type"
10027 [(if_then_else (match_operand 3 "const_int_operand" "")
10028 (const_string "mov_shift" )
10029 (const_string "mov_shift_reg"))
10030 (const_string "multiple")
10031 (const_string "multiple")])]
10032 )
10033
10034 (define_insn "*ifcompare_move_shift"
10035 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10036 (if_then_else:SI
10037 (match_operator 6 "arm_comparison_operator"
10038 [(match_operand:SI 4 "s_register_operand" "r,r")
10039 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")])
10040 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10041 (match_operator:SI 7 "shift_operator"
10042 [(match_operand:SI 2 "s_register_operand" "r,r")
10043 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")])))
10044 (clobber (reg:CC CC_REGNUM))]
10045 "TARGET_ARM"
10046 "#"
10047 [(set_attr "conds" "clob")
10048 (set_attr "length" "8,12")
10049 (set_attr "type" "multiple")]
10050 )
10051
10052 (define_insn "*if_move_shift"
10053 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
10054 (if_then_else:SI
10055 (match_operator 5 "arm_comparison_operator"
10056 [(match_operand 6 "cc_register" "") (const_int 0)])
10057 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")
10058 (match_operator:SI 4 "shift_operator"
10059 [(match_operand:SI 2 "s_register_operand" "r,r,r")
10060 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))]
10061 "TARGET_ARM"
10062 "@
10063 mov%D5\\t%0, %2%S4
10064 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4
10065 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4"
10066 [(set_attr "conds" "use")
10067 (set_attr "shift" "2")
10068 (set_attr "length" "4,8,8")
10069 (set_attr_alternative "type"
10070 [(if_then_else (match_operand 3 "const_int_operand" "")
10071 (const_string "mov_shift" )
10072 (const_string "mov_shift_reg"))
10073 (const_string "multiple")
10074 (const_string "multiple")])]
10075 )
10076
10077 (define_insn "*ifcompare_shift_shift"
10078 [(set (match_operand:SI 0 "s_register_operand" "=r")
10079 (if_then_else:SI
10080 (match_operator 7 "arm_comparison_operator"
10081 [(match_operand:SI 5 "s_register_operand" "r")
10082 (match_operand:SI 6 "arm_add_operand" "rIL")])
10083 (match_operator:SI 8 "shift_operator"
10084 [(match_operand:SI 1 "s_register_operand" "r")
10085 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10086 (match_operator:SI 9 "shift_operator"
10087 [(match_operand:SI 3 "s_register_operand" "r")
10088 (match_operand:SI 4 "arm_rhs_operand" "rM")])))
10089 (clobber (reg:CC CC_REGNUM))]
10090 "TARGET_ARM"
10091 "#"
10092 [(set_attr "conds" "clob")
10093 (set_attr "length" "12")
10094 (set_attr "type" "multiple")]
10095 )
10096
10097 (define_insn "*if_shift_shift"
10098 [(set (match_operand:SI 0 "s_register_operand" "=r")
10099 (if_then_else:SI
10100 (match_operator 5 "arm_comparison_operator"
10101 [(match_operand 8 "cc_register" "") (const_int 0)])
10102 (match_operator:SI 6 "shift_operator"
10103 [(match_operand:SI 1 "s_register_operand" "r")
10104 (match_operand:SI 2 "arm_rhs_operand" "rM")])
10105 (match_operator:SI 7 "shift_operator"
10106 [(match_operand:SI 3 "s_register_operand" "r")
10107 (match_operand:SI 4 "arm_rhs_operand" "rM")])))]
10108 "TARGET_ARM"
10109 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7"
10110 [(set_attr "conds" "use")
10111 (set_attr "shift" "1")
10112 (set_attr "length" "8")
10113 (set (attr "type") (if_then_else
10114 (and (match_operand 2 "const_int_operand" "")
10115 (match_operand 4 "const_int_operand" ""))
10116 (const_string "mov_shift")
10117 (const_string "mov_shift_reg")))]
10118 )
10119
10120 (define_insn "*ifcompare_not_arith"
10121 [(set (match_operand:SI 0 "s_register_operand" "=r")
10122 (if_then_else:SI
10123 (match_operator 6 "arm_comparison_operator"
10124 [(match_operand:SI 4 "s_register_operand" "r")
10125 (match_operand:SI 5 "arm_add_operand" "rIL")])
10126 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10127 (match_operator:SI 7 "shiftable_operator"
10128 [(match_operand:SI 2 "s_register_operand" "r")
10129 (match_operand:SI 3 "arm_rhs_operand" "rI")])))
10130 (clobber (reg:CC CC_REGNUM))]
10131 "TARGET_ARM"
10132 "#"
10133 [(set_attr "conds" "clob")
10134 (set_attr "length" "12")
10135 (set_attr "type" "multiple")]
10136 )
10137
10138 (define_insn "*if_not_arith"
10139 [(set (match_operand:SI 0 "s_register_operand" "=r")
10140 (if_then_else:SI
10141 (match_operator 5 "arm_comparison_operator"
10142 [(match_operand 4 "cc_register" "") (const_int 0)])
10143 (not:SI (match_operand:SI 1 "s_register_operand" "r"))
10144 (match_operator:SI 6 "shiftable_operator"
10145 [(match_operand:SI 2 "s_register_operand" "r")
10146 (match_operand:SI 3 "arm_rhs_operand" "rI")])))]
10147 "TARGET_ARM"
10148 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3"
10149 [(set_attr "conds" "use")
10150 (set_attr "type" "mvn_reg")
10151 (set_attr "length" "8")]
10152 )
10153
10154 (define_insn "*ifcompare_arith_not"
10155 [(set (match_operand:SI 0 "s_register_operand" "=r")
10156 (if_then_else:SI
10157 (match_operator 6 "arm_comparison_operator"
10158 [(match_operand:SI 4 "s_register_operand" "r")
10159 (match_operand:SI 5 "arm_add_operand" "rIL")])
10160 (match_operator:SI 7 "shiftable_operator"
10161 [(match_operand:SI 2 "s_register_operand" "r")
10162 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10163 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))
10164 (clobber (reg:CC CC_REGNUM))]
10165 "TARGET_ARM"
10166 "#"
10167 [(set_attr "conds" "clob")
10168 (set_attr "length" "12")
10169 (set_attr "type" "multiple")]
10170 )
10171
10172 (define_insn "*if_arith_not"
10173 [(set (match_operand:SI 0 "s_register_operand" "=r")
10174 (if_then_else:SI
10175 (match_operator 5 "arm_comparison_operator"
10176 [(match_operand 4 "cc_register" "") (const_int 0)])
10177 (match_operator:SI 6 "shiftable_operator"
10178 [(match_operand:SI 2 "s_register_operand" "r")
10179 (match_operand:SI 3 "arm_rhs_operand" "rI")])
10180 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))]
10181 "TARGET_ARM"
10182 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
10183 [(set_attr "conds" "use")
10184 (set_attr "type" "multiple")
10185 (set_attr "length" "8")]
10186 )
10187
10188 (define_insn "*ifcompare_neg_move"
10189 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10190 (if_then_else:SI
10191 (match_operator 5 "arm_comparison_operator"
10192 [(match_operand:SI 3 "s_register_operand" "r,r")
10193 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10194 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))
10195 (match_operand:SI 1 "arm_not_operand" "0,?rIK")))
10196 (clobber (reg:CC CC_REGNUM))]
10197 "TARGET_ARM"
10198 "#"
10199 [(set_attr "conds" "clob")
10200 (set_attr "length" "8,12")
10201 (set_attr "type" "multiple")]
10202 )
10203
10204 (define_insn_and_split "*if_neg_move"
10205 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10206 (if_then_else:SI
10207 (match_operator 4 "arm_comparison_operator"
10208 [(match_operand 3 "cc_register" "") (const_int 0)])
10209 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))
10210 (match_operand:SI 1 "s_register_operand" "0,0")))]
10211 "TARGET_32BIT"
10212 "#"
10213 "&& reload_completed"
10214 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)])
10215 (set (match_dup 0) (neg:SI (match_dup 2))))]
10216 ""
10217 [(set_attr "conds" "use")
10218 (set_attr "length" "4")
10219 (set_attr "arch" "t2,32")
10220 (set_attr "enabled_for_short_it" "yes,no")
10221 (set_attr "type" "logic_shift_imm")]
10222 )
10223
10224 (define_insn "*ifcompare_move_neg"
10225 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10226 (if_then_else:SI
10227 (match_operator 5 "arm_comparison_operator"
10228 [(match_operand:SI 3 "s_register_operand" "r,r")
10229 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")])
10230 (match_operand:SI 1 "arm_not_operand" "0,?rIK")
10231 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r"))))
10232 (clobber (reg:CC CC_REGNUM))]
10233 "TARGET_ARM"
10234 "#"
10235 [(set_attr "conds" "clob")
10236 (set_attr "length" "8,12")
10237 (set_attr "type" "multiple")]
10238 )
10239
10240 (define_insn_and_split "*if_move_neg"
10241 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
10242 (if_then_else:SI
10243 (match_operator 4 "arm_comparison_operator"
10244 [(match_operand 3 "cc_register" "") (const_int 0)])
10245 (match_operand:SI 1 "s_register_operand" "0,0")
10246 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))]
10247 "TARGET_32BIT"
10248 "#"
10249 "&& reload_completed"
10250 [(cond_exec (match_dup 5)
10251 (set (match_dup 0) (neg:SI (match_dup 2))))]
10252 {
10253 machine_mode mode = GET_MODE (operands[3]);
10254 rtx_code rc = GET_CODE (operands[4]);
10255
10256 if (mode == CCFPmode || mode == CCFPEmode)
10257 rc = reverse_condition_maybe_unordered (rc);
10258 else
10259 rc = reverse_condition (rc);
10260
10261 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
10262 }
10263 [(set_attr "conds" "use")
10264 (set_attr "length" "4")
10265 (set_attr "arch" "t2,32")
10266 (set_attr "enabled_for_short_it" "yes,no")
10267 (set_attr "type" "logic_shift_imm")]
10268 )
10269
10270 (define_insn "*arith_adjacentmem"
10271 [(set (match_operand:SI 0 "s_register_operand" "=r")
10272 (match_operator:SI 1 "shiftable_operator"
10273 [(match_operand:SI 2 "memory_operand" "m")
10274 (match_operand:SI 3 "memory_operand" "m")]))
10275 (clobber (match_scratch:SI 4 "=r"))]
10276 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])"
10277 "*
10278 {
10279 rtx ldm[3];
10280 rtx arith[4];
10281 rtx base_reg;
10282 HOST_WIDE_INT val1 = 0, val2 = 0;
10283
10284 if (REGNO (operands[0]) > REGNO (operands[4]))
10285 {
10286 ldm[1] = operands[4];
10287 ldm[2] = operands[0];
10288 }
10289 else
10290 {
10291 ldm[1] = operands[0];
10292 ldm[2] = operands[4];
10293 }
10294
10295 base_reg = XEXP (operands[2], 0);
10296
10297 if (!REG_P (base_reg))
10298 {
10299 val1 = INTVAL (XEXP (base_reg, 1));
10300 base_reg = XEXP (base_reg, 0);
10301 }
10302
10303 if (!REG_P (XEXP (operands[3], 0)))
10304 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1));
10305
10306 arith[0] = operands[0];
10307 arith[3] = operands[1];
10308
10309 if (val1 < val2)
10310 {
10311 arith[1] = ldm[1];
10312 arith[2] = ldm[2];
10313 }
10314 else
10315 {
10316 arith[1] = ldm[2];
10317 arith[2] = ldm[1];
10318 }
10319
10320 ldm[0] = base_reg;
10321 if (val1 !=0 && val2 != 0)
10322 {
10323 rtx ops[3];
10324
10325 if (val1 == 4 || val2 == 4)
10326 /* Other val must be 8, since we know they are adjacent and neither
10327 is zero. */
10328 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm);
10329 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1))
10330 {
10331 ldm[0] = ops[0] = operands[4];
10332 ops[1] = base_reg;
10333 ops[2] = GEN_INT (val1);
10334 output_add_immediate (ops);
10335 if (val1 < val2)
10336 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10337 else
10338 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10339 }
10340 else
10341 {
10342 /* Offset is out of range for a single add, so use two ldr. */
10343 ops[0] = ldm[1];
10344 ops[1] = base_reg;
10345 ops[2] = GEN_INT (val1);
10346 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10347 ops[0] = ldm[2];
10348 ops[2] = GEN_INT (val2);
10349 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops);
10350 }
10351 }
10352 else if (val1 != 0)
10353 {
10354 if (val1 < val2)
10355 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10356 else
10357 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10358 }
10359 else
10360 {
10361 if (val1 < val2)
10362 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm);
10363 else
10364 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm);
10365 }
10366 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith);
10367 return \"\";
10368 }"
10369 [(set_attr "length" "12")
10370 (set_attr "predicable" "yes")
10371 (set_attr "type" "load_4")]
10372 )
10373
10374 ; This pattern is never tried by combine, so do it as a peephole
10375
10376 (define_peephole2
10377 [(set (match_operand:SI 0 "arm_general_register_operand" "")
10378 (match_operand:SI 1 "arm_general_register_operand" ""))
10379 (set (reg:CC CC_REGNUM)
10380 (compare:CC (match_dup 1) (const_int 0)))]
10381 "TARGET_ARM"
10382 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
10383 (set (match_dup 0) (match_dup 1))])]
10384 ""
10385 )
10386
10387 (define_split
10388 [(set (match_operand:SI 0 "s_register_operand" "")
10389 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "")
10390 (const_int 0))
10391 (neg:SI (match_operator:SI 2 "arm_comparison_operator"
10392 [(match_operand:SI 3 "s_register_operand" "")
10393 (match_operand:SI 4 "arm_rhs_operand" "")]))))
10394 (clobber (match_operand:SI 5 "s_register_operand" ""))]
10395 "TARGET_ARM"
10396 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31))))
10397 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)])
10398 (match_dup 5)))]
10399 ""
10400 )
10401
10402 ;; This split can be used because CC_Z mode implies that the following
10403 ;; branch will be an equality, or an unsigned inequality, so the sign
10404 ;; extension is not needed.
10405
10406 (define_split
10407 [(set (reg:CC_Z CC_REGNUM)
10408 (compare:CC_Z
10409 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0)
10410 (const_int 24))
10411 (match_operand 1 "const_int_operand" "")))
10412 (clobber (match_scratch:SI 2 ""))]
10413 "TARGET_ARM
10414 && ((UINTVAL (operands[1]))
10415 == ((UINTVAL (operands[1])) >> 24) << 24)"
10416 [(set (match_dup 2) (zero_extend:SI (match_dup 0)))
10417 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))]
10418 "
10419 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24);
10420 "
10421 )
10422 ;; ??? Check the patterns above for Thumb-2 usefulness
10423
10424 (define_expand "prologue"
10425 [(clobber (const_int 0))]
10426 "TARGET_EITHER"
10427 "if (TARGET_32BIT)
10428 arm_expand_prologue ();
10429 else
10430 thumb1_expand_prologue ();
10431 DONE;
10432 "
10433 )
10434
10435 (define_expand "epilogue"
10436 [(clobber (const_int 0))]
10437 "TARGET_EITHER"
10438 "
10439 if (crtl->calls_eh_return)
10440 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2)));
10441 if (TARGET_THUMB1)
10442 {
10443 thumb1_expand_epilogue ();
10444 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
10445 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE));
10446 }
10447 else if (HAVE_return)
10448 {
10449 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence,
10450 no need for explicit testing again. */
10451 emit_jump_insn (gen_return ());
10452 }
10453 else if (TARGET_32BIT)
10454 {
10455 arm_expand_epilogue (true);
10456 }
10457 DONE;
10458 "
10459 )
10460
10461 ;; Note - although unspec_volatile's USE all hard registers,
10462 ;; USEs are ignored after relaod has completed. Thus we need
10463 ;; to add an unspec of the link register to ensure that flow
10464 ;; does not think that it is unused by the sibcall branch that
10465 ;; will replace the standard function epilogue.
10466 (define_expand "sibcall_epilogue"
10467 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE)
10468 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
10469 "TARGET_32BIT"
10470 "
10471 arm_expand_epilogue (false);
10472 DONE;
10473 "
10474 )
10475
10476 (define_expand "eh_epilogue"
10477 [(use (match_operand:SI 0 "register_operand"))
10478 (use (match_operand:SI 1 "register_operand"))
10479 (use (match_operand:SI 2 "register_operand"))]
10480 "TARGET_EITHER"
10481 "
10482 {
10483 cfun->machine->eh_epilogue_sp_ofs = operands[1];
10484 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2)
10485 {
10486 rtx ra = gen_rtx_REG (Pmode, 2);
10487
10488 emit_move_insn (ra, operands[2]);
10489 operands[2] = ra;
10490 }
10491 /* This is a hack -- we may have crystalized the function type too
10492 early. */
10493 cfun->machine->func_type = 0;
10494 }"
10495 )
10496
10497 ;; This split is only used during output to reduce the number of patterns
10498 ;; that need assembler instructions adding to them. We allowed the setting
10499 ;; of the conditions to be implicit during rtl generation so that
10500 ;; the conditional compare patterns would work. However this conflicts to
10501 ;; some extent with the conditional data operations, so we have to split them
10502 ;; up again here.
10503
10504 ;; ??? Need to audit these splitters for Thumb-2. Why isn't normal
10505 ;; conditional execution sufficient?
10506
10507 (define_split
10508 [(set (match_operand:SI 0 "s_register_operand" "")
10509 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10510 [(match_operand 2 "" "") (match_operand 3 "" "")])
10511 (match_dup 0)
10512 (match_operand 4 "" "")))
10513 (clobber (reg:CC CC_REGNUM))]
10514 "TARGET_ARM && reload_completed"
10515 [(set (match_dup 5) (match_dup 6))
10516 (cond_exec (match_dup 7)
10517 (set (match_dup 0) (match_dup 4)))]
10518 "
10519 {
10520 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10521 operands[2], operands[3]);
10522 enum rtx_code rc = GET_CODE (operands[1]);
10523
10524 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10525 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10526 if (mode == CCFPmode || mode == CCFPEmode)
10527 rc = reverse_condition_maybe_unordered (rc);
10528 else
10529 rc = reverse_condition (rc);
10530
10531 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx);
10532 }"
10533 )
10534
10535 (define_split
10536 [(set (match_operand:SI 0 "s_register_operand" "")
10537 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10538 [(match_operand 2 "" "") (match_operand 3 "" "")])
10539 (match_operand 4 "" "")
10540 (match_dup 0)))
10541 (clobber (reg:CC CC_REGNUM))]
10542 "TARGET_ARM && reload_completed"
10543 [(set (match_dup 5) (match_dup 6))
10544 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)])
10545 (set (match_dup 0) (match_dup 4)))]
10546 "
10547 {
10548 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10549 operands[2], operands[3]);
10550
10551 operands[5] = gen_rtx_REG (mode, CC_REGNUM);
10552 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10553 }"
10554 )
10555
10556 (define_split
10557 [(set (match_operand:SI 0 "s_register_operand" "")
10558 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10559 [(match_operand 2 "" "") (match_operand 3 "" "")])
10560 (match_operand 4 "" "")
10561 (match_operand 5 "" "")))
10562 (clobber (reg:CC CC_REGNUM))]
10563 "TARGET_ARM && reload_completed"
10564 [(set (match_dup 6) (match_dup 7))
10565 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10566 (set (match_dup 0) (match_dup 4)))
10567 (cond_exec (match_dup 8)
10568 (set (match_dup 0) (match_dup 5)))]
10569 "
10570 {
10571 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10572 operands[2], operands[3]);
10573 enum rtx_code rc = GET_CODE (operands[1]);
10574
10575 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10576 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10577 if (mode == CCFPmode || mode == CCFPEmode)
10578 rc = reverse_condition_maybe_unordered (rc);
10579 else
10580 rc = reverse_condition (rc);
10581
10582 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10583 }"
10584 )
10585
10586 (define_split
10587 [(set (match_operand:SI 0 "s_register_operand" "")
10588 (if_then_else:SI (match_operator 1 "arm_comparison_operator"
10589 [(match_operand:SI 2 "s_register_operand" "")
10590 (match_operand:SI 3 "arm_add_operand" "")])
10591 (match_operand:SI 4 "arm_rhs_operand" "")
10592 (not:SI
10593 (match_operand:SI 5 "s_register_operand" ""))))
10594 (clobber (reg:CC CC_REGNUM))]
10595 "TARGET_ARM && reload_completed"
10596 [(set (match_dup 6) (match_dup 7))
10597 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)])
10598 (set (match_dup 0) (match_dup 4)))
10599 (cond_exec (match_dup 8)
10600 (set (match_dup 0) (not:SI (match_dup 5))))]
10601 "
10602 {
10603 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
10604 operands[2], operands[3]);
10605 enum rtx_code rc = GET_CODE (operands[1]);
10606
10607 operands[6] = gen_rtx_REG (mode, CC_REGNUM);
10608 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]);
10609 if (mode == CCFPmode || mode == CCFPEmode)
10610 rc = reverse_condition_maybe_unordered (rc);
10611 else
10612 rc = reverse_condition (rc);
10613
10614 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx);
10615 }"
10616 )
10617
10618 (define_insn "*cond_move_not"
10619 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
10620 (if_then_else:SI (match_operator 4 "arm_comparison_operator"
10621 [(match_operand 3 "cc_register" "") (const_int 0)])
10622 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")
10623 (not:SI
10624 (match_operand:SI 2 "s_register_operand" "r,r"))))]
10625 "TARGET_ARM"
10626 "@
10627 mvn%D4\\t%0, %2
10628 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
10629 [(set_attr "conds" "use")
10630 (set_attr "type" "mvn_reg,multiple")
10631 (set_attr "length" "4,8")]
10632 )
10633
10634 ;; The next two patterns occur when an AND operation is followed by a
10635 ;; scc insn sequence
10636
10637 (define_insn "*sign_extract_onebit"
10638 [(set (match_operand:SI 0 "s_register_operand" "=r")
10639 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10640 (const_int 1)
10641 (match_operand:SI 2 "const_int_operand" "n")))
10642 (clobber (reg:CC CC_REGNUM))]
10643 "TARGET_ARM"
10644 "*
10645 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10646 output_asm_insn (\"ands\\t%0, %1, %2\", operands);
10647 return \"mvnne\\t%0, #0\";
10648 "
10649 [(set_attr "conds" "clob")
10650 (set_attr "length" "8")
10651 (set_attr "type" "multiple")]
10652 )
10653
10654 (define_insn "*not_signextract_onebit"
10655 [(set (match_operand:SI 0 "s_register_operand" "=r")
10656 (not:SI
10657 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
10658 (const_int 1)
10659 (match_operand:SI 2 "const_int_operand" "n"))))
10660 (clobber (reg:CC CC_REGNUM))]
10661 "TARGET_ARM"
10662 "*
10663 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10664 output_asm_insn (\"tst\\t%1, %2\", operands);
10665 output_asm_insn (\"mvneq\\t%0, #0\", operands);
10666 return \"movne\\t%0, #0\";
10667 "
10668 [(set_attr "conds" "clob")
10669 (set_attr "length" "12")
10670 (set_attr "type" "multiple")]
10671 )
10672 ;; ??? The above patterns need auditing for Thumb-2
10673
10674 ;; Push multiple registers to the stack. Registers are in parallel (use ...)
10675 ;; expressions. For simplicity, the first register is also in the unspec
10676 ;; part.
10677 ;; To avoid the usage of GNU extension, the length attribute is computed
10678 ;; in a C function arm_attr_length_push_multi.
10679 (define_insn "*push_multi"
10680 [(match_parallel 2 "multi_register_push"
10681 [(set (match_operand:BLK 0 "push_mult_memory_operand" "")
10682 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")]
10683 UNSPEC_PUSH_MULT))])]
10684 ""
10685 "*
10686 {
10687 int num_saves = XVECLEN (operands[2], 0);
10688
10689 /* For the StrongARM at least it is faster to
10690 use STR to store only a single register.
10691 In Thumb mode always use push, and the assembler will pick
10692 something appropriate. */
10693 if (num_saves == 1 && TARGET_ARM)
10694 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands);
10695 else
10696 {
10697 int i;
10698 char pattern[100];
10699
10700 if (TARGET_32BIT)
10701 strcpy (pattern, \"push%?\\t{%1\");
10702 else
10703 strcpy (pattern, \"push\\t{%1\");
10704
10705 for (i = 1; i < num_saves; i++)
10706 {
10707 strcat (pattern, \", %|\");
10708 strcat (pattern,
10709 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
10710 }
10711
10712 strcat (pattern, \"}\");
10713 output_asm_insn (pattern, operands);
10714 }
10715
10716 return \"\";
10717 }"
10718 [(set_attr "type" "store_16")
10719 (set (attr "length")
10720 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
10721 )
10722
10723 (define_insn "stack_tie"
10724 [(set (mem:BLK (scratch))
10725 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk")
10726 (match_operand:SI 1 "s_register_operand" "rk")]
10727 UNSPEC_PRLG_STK))]
10728 ""
10729 ""
10730 [(set_attr "length" "0")
10731 (set_attr "type" "block")]
10732 )
10733
10734 ;; Pop (as used in epilogue RTL)
10735 ;;
10736 (define_insn "*load_multiple_with_writeback"
10737 [(match_parallel 0 "load_multiple_operation"
10738 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10739 (plus:SI (match_dup 1)
10740 (match_operand:SI 2 "const_int_I_operand" "I")))
10741 (set (match_operand:SI 3 "s_register_operand" "=rk")
10742 (mem:SI (match_dup 1)))
10743 ])]
10744 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10745 "*
10746 {
10747 arm_output_multireg_pop (operands, /*return_pc=*/false,
10748 /*cond=*/const_true_rtx,
10749 /*reverse=*/false,
10750 /*update=*/true);
10751 return \"\";
10752 }
10753 "
10754 [(set_attr "type" "load_16")
10755 (set_attr "predicable" "yes")
10756 (set (attr "length")
10757 (symbol_ref "arm_attr_length_pop_multi (operands,
10758 /*return_pc=*/false,
10759 /*write_back_p=*/true)"))]
10760 )
10761
10762 ;; Pop with return (as used in epilogue RTL)
10763 ;;
10764 ;; This instruction is generated when the registers are popped at the end of
10765 ;; epilogue. Here, instead of popping the value into LR and then generating
10766 ;; jump to LR, value is popped into PC directly. Hence, the pattern is combined
10767 ;; with (return).
10768 (define_insn "*pop_multiple_with_writeback_and_return"
10769 [(match_parallel 0 "pop_multiple_return"
10770 [(return)
10771 (set (match_operand:SI 1 "s_register_operand" "+rk")
10772 (plus:SI (match_dup 1)
10773 (match_operand:SI 2 "const_int_I_operand" "I")))
10774 (set (match_operand:SI 3 "s_register_operand" "=rk")
10775 (mem:SI (match_dup 1)))
10776 ])]
10777 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10778 "*
10779 {
10780 arm_output_multireg_pop (operands, /*return_pc=*/true,
10781 /*cond=*/const_true_rtx,
10782 /*reverse=*/false,
10783 /*update=*/true);
10784 return \"\";
10785 }
10786 "
10787 [(set_attr "type" "load_16")
10788 (set_attr "predicable" "yes")
10789 (set (attr "length")
10790 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10791 /*write_back_p=*/true)"))]
10792 )
10793
10794 (define_insn "*pop_multiple_with_return"
10795 [(match_parallel 0 "pop_multiple_return"
10796 [(return)
10797 (set (match_operand:SI 2 "s_register_operand" "=rk")
10798 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
10799 ])]
10800 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10801 "*
10802 {
10803 arm_output_multireg_pop (operands, /*return_pc=*/true,
10804 /*cond=*/const_true_rtx,
10805 /*reverse=*/false,
10806 /*update=*/false);
10807 return \"\";
10808 }
10809 "
10810 [(set_attr "type" "load_16")
10811 (set_attr "predicable" "yes")
10812 (set (attr "length")
10813 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
10814 /*write_back_p=*/false)"))]
10815 )
10816
10817 ;; Load into PC and return
10818 (define_insn "*ldr_with_return"
10819 [(return)
10820 (set (reg:SI PC_REGNUM)
10821 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))]
10822 "TARGET_32BIT && (reload_in_progress || reload_completed)"
10823 "ldr%?\t%|pc, [%0], #4"
10824 [(set_attr "type" "load_4")
10825 (set_attr "predicable" "yes")]
10826 )
10827 ;; Pop for floating point registers (as used in epilogue RTL)
10828 (define_insn "*vfp_pop_multiple_with_writeback"
10829 [(match_parallel 0 "pop_multiple_fp"
10830 [(set (match_operand:SI 1 "s_register_operand" "+rk")
10831 (plus:SI (match_dup 1)
10832 (match_operand:SI 2 "const_int_I_operand" "I")))
10833 (set (match_operand:DF 3 "vfp_hard_register_operand" "")
10834 (mem:DF (match_dup 1)))])]
10835 "TARGET_32BIT && TARGET_HARD_FLOAT"
10836 "*
10837 {
10838 int num_regs = XVECLEN (operands[0], 0);
10839 char pattern[100];
10840 rtx op_list[2];
10841 strcpy (pattern, \"vldm\\t\");
10842 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]);
10843 strcat (pattern, \"!, {\");
10844 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0);
10845 strcat (pattern, \"%P0\");
10846 if ((num_regs - 1) > 1)
10847 {
10848 strcat (pattern, \"-%P1\");
10849 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0);
10850 }
10851
10852 strcat (pattern, \"}\");
10853 output_asm_insn (pattern, op_list);
10854 return \"\";
10855 }
10856 "
10857 [(set_attr "type" "load_16")
10858 (set_attr "conds" "unconditional")
10859 (set_attr "predicable" "no")]
10860 )
10861
10862 ;; Special patterns for dealing with the constant pool
10863
10864 (define_insn "align_4"
10865 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
10866 "TARGET_EITHER"
10867 "*
10868 assemble_align (32);
10869 return \"\";
10870 "
10871 [(set_attr "type" "no_insn")]
10872 )
10873
10874 (define_insn "align_8"
10875 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
10876 "TARGET_EITHER"
10877 "*
10878 assemble_align (64);
10879 return \"\";
10880 "
10881 [(set_attr "type" "no_insn")]
10882 )
10883
10884 (define_insn "consttable_end"
10885 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
10886 "TARGET_EITHER"
10887 "*
10888 making_const_table = FALSE;
10889 return \"\";
10890 "
10891 [(set_attr "type" "no_insn")]
10892 )
10893
10894 (define_insn "consttable_1"
10895 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)]
10896 "TARGET_EITHER"
10897 "*
10898 making_const_table = TRUE;
10899 assemble_integer (operands[0], 1, BITS_PER_WORD, 1);
10900 assemble_zeros (3);
10901 return \"\";
10902 "
10903 [(set_attr "length" "4")
10904 (set_attr "type" "no_insn")]
10905 )
10906
10907 (define_insn "consttable_2"
10908 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)]
10909 "TARGET_EITHER"
10910 "*
10911 {
10912 rtx x = operands[0];
10913 making_const_table = TRUE;
10914 switch (GET_MODE_CLASS (GET_MODE (x)))
10915 {
10916 case MODE_FLOAT:
10917 arm_emit_fp16_const (x);
10918 break;
10919 default:
10920 assemble_integer (operands[0], 2, BITS_PER_WORD, 1);
10921 assemble_zeros (2);
10922 break;
10923 }
10924 return \"\";
10925 }"
10926 [(set_attr "length" "4")
10927 (set_attr "type" "no_insn")]
10928 )
10929
10930 (define_insn "consttable_4"
10931 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
10932 "TARGET_EITHER"
10933 "*
10934 {
10935 rtx x = operands[0];
10936 making_const_table = TRUE;
10937 scalar_float_mode float_mode;
10938 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode))
10939 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD);
10940 else
10941 {
10942 /* XXX: Sometimes gcc does something really dumb and ends up with
10943 a HIGH in a constant pool entry, usually because it's trying to
10944 load into a VFP register. We know this will always be used in
10945 combination with a LO_SUM which ignores the high bits, so just
10946 strip off the HIGH. */
10947 if (GET_CODE (x) == HIGH)
10948 x = XEXP (x, 0);
10949 assemble_integer (x, 4, BITS_PER_WORD, 1);
10950 mark_symbol_refs_as_used (x);
10951 }
10952 return \"\";
10953 }"
10954 [(set_attr "length" "4")
10955 (set_attr "type" "no_insn")]
10956 )
10957
10958 (define_insn "consttable_8"
10959 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
10960 "TARGET_EITHER"
10961 "*
10962 {
10963 making_const_table = TRUE;
10964 scalar_float_mode float_mode;
10965 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
10966 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10967 float_mode, BITS_PER_WORD);
10968 else
10969 assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
10970 return \"\";
10971 }"
10972 [(set_attr "length" "8")
10973 (set_attr "type" "no_insn")]
10974 )
10975
10976 (define_insn "consttable_16"
10977 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
10978 "TARGET_EITHER"
10979 "*
10980 {
10981 making_const_table = TRUE;
10982 scalar_float_mode float_mode;
10983 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode))
10984 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
10985 float_mode, BITS_PER_WORD);
10986 else
10987 assemble_integer (operands[0], 16, BITS_PER_WORD, 1);
10988 return \"\";
10989 }"
10990 [(set_attr "length" "16")
10991 (set_attr "type" "no_insn")]
10992 )
10993
10994 ;; V5 Instructions,
10995
10996 (define_insn "clzsi2"
10997 [(set (match_operand:SI 0 "s_register_operand" "=r")
10998 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
10999 "TARGET_32BIT && arm_arch5t"
11000 "clz%?\\t%0, %1"
11001 [(set_attr "predicable" "yes")
11002 (set_attr "type" "clz")])
11003
11004 (define_insn "rbitsi2"
11005 [(set (match_operand:SI 0 "s_register_operand" "=r")
11006 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))]
11007 "TARGET_32BIT && arm_arch_thumb2"
11008 "rbit%?\\t%0, %1"
11009 [(set_attr "predicable" "yes")
11010 (set_attr "type" "clz")])
11011
11012 ;; Keep this as a CTZ expression until after reload and then split
11013 ;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely
11014 ;; to fold with any other expression.
11015
11016 (define_insn_and_split "ctzsi2"
11017 [(set (match_operand:SI 0 "s_register_operand" "=r")
11018 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))]
11019 "TARGET_32BIT && arm_arch_thumb2"
11020 "#"
11021 "&& reload_completed"
11022 [(const_int 0)]
11023 "
11024 emit_insn (gen_rbitsi2 (operands[0], operands[1]));
11025 emit_insn (gen_clzsi2 (operands[0], operands[0]));
11026 DONE;
11027 ")
11028
11029 ;; V5E instructions.
11030
11031 (define_insn "prefetch"
11032 [(prefetch (match_operand:SI 0 "address_operand" "p")
11033 (match_operand:SI 1 "" "")
11034 (match_operand:SI 2 "" ""))]
11035 "TARGET_32BIT && arm_arch5te"
11036 "pld\\t%a0"
11037 [(set_attr "type" "load_4")]
11038 )
11039
11040 ;; General predication pattern
11041
11042 (define_cond_exec
11043 [(match_operator 0 "arm_comparison_operator"
11044 [(match_operand 1 "cc_register" "")
11045 (const_int 0)])]
11046 "TARGET_32BIT
11047 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
11048 ""
11049 [(set_attr "predicated" "yes")]
11050 )
11051
11052 (define_insn "force_register_use"
11053 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
11054 ""
11055 "%@ %0 needed"
11056 [(set_attr "length" "0")
11057 (set_attr "type" "no_insn")]
11058 )
11059
11060
11061 ;; Patterns for exception handling
11062
11063 (define_expand "eh_return"
11064 [(use (match_operand 0 "general_operand"))]
11065 "TARGET_EITHER"
11066 "
11067 {
11068 if (TARGET_32BIT)
11069 emit_insn (gen_arm_eh_return (operands[0]));
11070 else
11071 emit_insn (gen_thumb_eh_return (operands[0]));
11072 DONE;
11073 }"
11074 )
11075
11076 ;; We can't expand this before we know where the link register is stored.
11077 (define_insn_and_split "arm_eh_return"
11078 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
11079 VUNSPEC_EH_RETURN)
11080 (clobber (match_scratch:SI 1 "=&r"))]
11081 "TARGET_ARM"
11082 "#"
11083 "&& reload_completed"
11084 [(const_int 0)]
11085 "
11086 {
11087 arm_set_return_address (operands[0], operands[1]);
11088 DONE;
11089 }"
11090 )
11091
11092 \f
11093 ;; TLS support
11094
11095 (define_insn "load_tp_hard"
11096 [(set (match_operand:SI 0 "register_operand" "=r")
11097 (unspec:SI [(const_int 0)] UNSPEC_TLS))]
11098 "TARGET_HARD_TP"
11099 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
11100 [(set_attr "predicable" "yes")
11101 (set_attr "type" "mrs")]
11102 )
11103
11104 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11105 (define_insn "load_tp_soft_fdpic"
11106 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11107 (clobber (reg:SI FDPIC_REGNUM))
11108 (clobber (reg:SI LR_REGNUM))
11109 (clobber (reg:SI IP_REGNUM))
11110 (clobber (reg:CC CC_REGNUM))]
11111 "TARGET_SOFT_TP && TARGET_FDPIC"
11112 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11113 [(set_attr "conds" "clob")
11114 (set_attr "type" "branch")]
11115 )
11116
11117 ;; Doesn't clobber R1-R3. Must use r0 for the first operand.
11118 (define_insn "load_tp_soft"
11119 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS))
11120 (clobber (reg:SI LR_REGNUM))
11121 (clobber (reg:SI IP_REGNUM))
11122 (clobber (reg:CC CC_REGNUM))]
11123 "TARGET_SOFT_TP && !TARGET_FDPIC"
11124 "bl\\t__aeabi_read_tp\\t@ load_tp_soft"
11125 [(set_attr "conds" "clob")
11126 (set_attr "type" "branch")]
11127 )
11128
11129 ;; tls descriptor call
11130 (define_insn "tlscall"
11131 [(set (reg:SI R0_REGNUM)
11132 (unspec:SI [(reg:SI R0_REGNUM)
11133 (match_operand:SI 0 "" "X")
11134 (match_operand 1 "" "")] UNSPEC_TLS))
11135 (clobber (reg:SI R1_REGNUM))
11136 (clobber (reg:SI LR_REGNUM))
11137 (clobber (reg:SI CC_REGNUM))]
11138 "TARGET_GNU2_TLS"
11139 {
11140 targetm.asm_out.internal_label (asm_out_file, "LPIC",
11141 INTVAL (operands[1]));
11142 return "bl\\t%c0(tlscall)";
11143 }
11144 [(set_attr "conds" "clob")
11145 (set_attr "length" "4")
11146 (set_attr "type" "branch")]
11147 )
11148
11149 ;; For thread pointer builtin
11150 (define_expand "get_thread_pointersi"
11151 [(match_operand:SI 0 "s_register_operand")]
11152 ""
11153 "
11154 {
11155 arm_load_tp (operands[0]);
11156 DONE;
11157 }")
11158
11159 ;;
11160
11161 ;; We only care about the lower 16 bits of the constant
11162 ;; being inserted into the upper 16 bits of the register.
11163 (define_insn "*arm_movtas_ze"
11164 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r")
11165 (const_int 16)
11166 (const_int 16))
11167 (match_operand:SI 1 "const_int_operand" ""))]
11168 "TARGET_HAVE_MOVT"
11169 "@
11170 movt%?\t%0, %L1
11171 movt\t%0, %L1"
11172 [(set_attr "arch" "32,v8mb")
11173 (set_attr "predicable" "yes")
11174 (set_attr "length" "4")
11175 (set_attr "type" "alu_sreg")]
11176 )
11177
11178 (define_insn "*arm_rev"
11179 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11180 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))]
11181 "arm_arch6"
11182 "@
11183 rev\t%0, %1
11184 rev%?\t%0, %1
11185 rev%?\t%0, %1"
11186 [(set_attr "arch" "t1,t2,32")
11187 (set_attr "length" "2,2,4")
11188 (set_attr "predicable" "no,yes,yes")
11189 (set_attr "type" "rev")]
11190 )
11191
11192 (define_expand "arm_legacy_rev"
11193 [(set (match_operand:SI 2 "s_register_operand")
11194 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand")
11195 (const_int 16))
11196 (match_dup 1)))
11197 (set (match_dup 2)
11198 (lshiftrt:SI (match_dup 2)
11199 (const_int 8)))
11200 (set (match_operand:SI 3 "s_register_operand")
11201 (rotatert:SI (match_dup 1)
11202 (const_int 8)))
11203 (set (match_dup 2)
11204 (and:SI (match_dup 2)
11205 (const_int -65281)))
11206 (set (match_operand:SI 0 "s_register_operand")
11207 (xor:SI (match_dup 3)
11208 (match_dup 2)))]
11209 "TARGET_32BIT"
11210 ""
11211 )
11212
11213 ;; Reuse temporaries to keep register pressure down.
11214 (define_expand "thumb_legacy_rev"
11215 [(set (match_operand:SI 2 "s_register_operand")
11216 (ashift:SI (match_operand:SI 1 "s_register_operand")
11217 (const_int 24)))
11218 (set (match_operand:SI 3 "s_register_operand")
11219 (lshiftrt:SI (match_dup 1)
11220 (const_int 24)))
11221 (set (match_dup 3)
11222 (ior:SI (match_dup 3)
11223 (match_dup 2)))
11224 (set (match_operand:SI 4 "s_register_operand")
11225 (const_int 16))
11226 (set (match_operand:SI 5 "s_register_operand")
11227 (rotatert:SI (match_dup 1)
11228 (match_dup 4)))
11229 (set (match_dup 2)
11230 (ashift:SI (match_dup 5)
11231 (const_int 24)))
11232 (set (match_dup 5)
11233 (lshiftrt:SI (match_dup 5)
11234 (const_int 24)))
11235 (set (match_dup 5)
11236 (ior:SI (match_dup 5)
11237 (match_dup 2)))
11238 (set (match_dup 5)
11239 (rotatert:SI (match_dup 5)
11240 (match_dup 4)))
11241 (set (match_operand:SI 0 "s_register_operand")
11242 (ior:SI (match_dup 5)
11243 (match_dup 3)))]
11244 "TARGET_THUMB"
11245 ""
11246 )
11247
11248 ;; ARM-specific expansion of signed mod by power of 2
11249 ;; using conditional negate.
11250 ;; For r0 % n where n is a power of 2 produce:
11251 ;; rsbs r1, r0, #0
11252 ;; and r0, r0, #(n - 1)
11253 ;; and r1, r1, #(n - 1)
11254 ;; rsbpl r0, r1, #0
11255
11256 (define_expand "modsi3"
11257 [(match_operand:SI 0 "register_operand")
11258 (match_operand:SI 1 "register_operand")
11259 (match_operand:SI 2 "const_int_operand")]
11260 "TARGET_32BIT"
11261 {
11262 HOST_WIDE_INT val = INTVAL (operands[2]);
11263
11264 if (val <= 0
11265 || exact_log2 (val) <= 0)
11266 FAIL;
11267
11268 rtx mask = GEN_INT (val - 1);
11269
11270 /* In the special case of x0 % 2 we can do the even shorter:
11271 cmp r0, #0
11272 and r0, r0, #1
11273 rsblt r0, r0, #0. */
11274
11275 if (val == 2)
11276 {
11277 rtx cc_reg = arm_gen_compare_reg (LT,
11278 operands[1], const0_rtx, NULL_RTX);
11279 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx);
11280 rtx masked = gen_reg_rtx (SImode);
11281
11282 emit_insn (gen_andsi3 (masked, operands[1], mask));
11283 emit_move_insn (operands[0],
11284 gen_rtx_IF_THEN_ELSE (SImode, cond,
11285 gen_rtx_NEG (SImode,
11286 masked),
11287 masked));
11288 DONE;
11289 }
11290
11291 rtx neg_op = gen_reg_rtx (SImode);
11292 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx,
11293 operands[1]));
11294
11295 /* Extract the condition register and mode. */
11296 rtx cmp = XVECEXP (PATTERN (insn), 0, 0);
11297 rtx cc_reg = SET_DEST (cmp);
11298 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx);
11299
11300 emit_insn (gen_andsi3 (operands[0], operands[1], mask));
11301
11302 rtx masked_neg = gen_reg_rtx (SImode);
11303 emit_insn (gen_andsi3 (masked_neg, neg_op, mask));
11304
11305 /* We want a conditional negate here, but emitting COND_EXEC rtxes
11306 during expand does not always work. Do an IF_THEN_ELSE instead. */
11307 emit_move_insn (operands[0],
11308 gen_rtx_IF_THEN_ELSE (SImode, cond,
11309 gen_rtx_NEG (SImode, masked_neg),
11310 operands[0]));
11311
11312
11313 DONE;
11314 }
11315 )
11316
11317 (define_expand "bswapsi2"
11318 [(set (match_operand:SI 0 "s_register_operand")
11319 (bswap:SI (match_operand:SI 1 "s_register_operand")))]
11320 "TARGET_EITHER && (arm_arch6 || !optimize_size)"
11321 "
11322 if (!arm_arch6)
11323 {
11324 rtx op2 = gen_reg_rtx (SImode);
11325 rtx op3 = gen_reg_rtx (SImode);
11326
11327 if (TARGET_THUMB)
11328 {
11329 rtx op4 = gen_reg_rtx (SImode);
11330 rtx op5 = gen_reg_rtx (SImode);
11331
11332 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1],
11333 op2, op3, op4, op5));
11334 }
11335 else
11336 {
11337 emit_insn (gen_arm_legacy_rev (operands[0], operands[1],
11338 op2, op3));
11339 }
11340
11341 DONE;
11342 }
11343 "
11344 )
11345
11346 ;; bswap16 patterns: use revsh and rev16 instructions for the signed
11347 ;; and unsigned variants, respectively. For rev16, expose
11348 ;; byte-swapping in the lower 16 bits only.
11349 (define_insn "*arm_revsh"
11350 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r")
11351 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))]
11352 "arm_arch6"
11353 "@
11354 revsh\t%0, %1
11355 revsh%?\t%0, %1
11356 revsh%?\t%0, %1"
11357 [(set_attr "arch" "t1,t2,32")
11358 (set_attr "length" "2,2,4")
11359 (set_attr "type" "rev")]
11360 )
11361
11362 (define_insn "*arm_rev16"
11363 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r")
11364 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))]
11365 "arm_arch6"
11366 "@
11367 rev16\t%0, %1
11368 rev16%?\t%0, %1
11369 rev16%?\t%0, %1"
11370 [(set_attr "arch" "t1,t2,32")
11371 (set_attr "length" "2,2,4")
11372 (set_attr "type" "rev")]
11373 )
11374
11375 ;; There are no canonicalisation rules for the position of the lshiftrt, ashift
11376 ;; operations within an IOR/AND RTX, therefore we have two patterns matching
11377 ;; each valid permutation.
11378
11379 (define_insn "arm_rev16si2"
11380 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11381 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r")
11382 (const_int 8))
11383 (match_operand:SI 3 "const_int_operand" "n,n,n"))
11384 (and:SI (lshiftrt:SI (match_dup 1)
11385 (const_int 8))
11386 (match_operand:SI 2 "const_int_operand" "n,n,n"))))]
11387 "arm_arch6
11388 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11389 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11390 "rev16\\t%0, %1"
11391 [(set_attr "arch" "t1,t2,32")
11392 (set_attr "length" "2,2,4")
11393 (set_attr "type" "rev")]
11394 )
11395
11396 (define_insn "arm_rev16si2_alt"
11397 [(set (match_operand:SI 0 "register_operand" "=l,l,r")
11398 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r")
11399 (const_int 8))
11400 (match_operand:SI 2 "const_int_operand" "n,n,n"))
11401 (and:SI (ashift:SI (match_dup 1)
11402 (const_int 8))
11403 (match_operand:SI 3 "const_int_operand" "n,n,n"))))]
11404 "arm_arch6
11405 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode)
11406 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)"
11407 "rev16\\t%0, %1"
11408 [(set_attr "arch" "t1,t2,32")
11409 (set_attr "length" "2,2,4")
11410 (set_attr "type" "rev")]
11411 )
11412
11413 (define_expand "bswaphi2"
11414 [(set (match_operand:HI 0 "s_register_operand")
11415 (bswap:HI (match_operand:HI 1 "s_register_operand")))]
11416 "arm_arch6"
11417 ""
11418 )
11419
11420 ;; Patterns for LDRD/STRD in Thumb2 mode
11421
11422 (define_insn "*thumb2_ldrd"
11423 [(set (match_operand:SI 0 "s_register_operand" "=r")
11424 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11425 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do"))))
11426 (set (match_operand:SI 3 "s_register_operand" "=r")
11427 (mem:SI (plus:SI (match_dup 1)
11428 (match_operand:SI 4 "const_int_operand" ""))))]
11429 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11430 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4]))
11431 && (operands_ok_ldrd_strd (operands[0], operands[3],
11432 operands[1], INTVAL (operands[2]),
11433 false, true))"
11434 "ldrd%?\t%0, %3, [%1, %2]"
11435 [(set_attr "type" "load_8")
11436 (set_attr "predicable" "yes")])
11437
11438 (define_insn "*thumb2_ldrd_base"
11439 [(set (match_operand:SI 0 "s_register_operand" "=r")
11440 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11441 (set (match_operand:SI 2 "s_register_operand" "=r")
11442 (mem:SI (plus:SI (match_dup 1)
11443 (const_int 4))))]
11444 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11445 && (operands_ok_ldrd_strd (operands[0], operands[2],
11446 operands[1], 0, false, true))"
11447 "ldrd%?\t%0, %2, [%1]"
11448 [(set_attr "type" "load_8")
11449 (set_attr "predicable" "yes")])
11450
11451 (define_insn "*thumb2_ldrd_base_neg"
11452 [(set (match_operand:SI 0 "s_register_operand" "=r")
11453 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk")
11454 (const_int -4))))
11455 (set (match_operand:SI 2 "s_register_operand" "=r")
11456 (mem:SI (match_dup 1)))]
11457 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11458 && (operands_ok_ldrd_strd (operands[0], operands[2],
11459 operands[1], -4, false, true))"
11460 "ldrd%?\t%0, %2, [%1, #-4]"
11461 [(set_attr "type" "load_8")
11462 (set_attr "predicable" "yes")])
11463
11464 (define_insn "*thumb2_strd"
11465 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11466 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do")))
11467 (match_operand:SI 2 "s_register_operand" "r"))
11468 (set (mem:SI (plus:SI (match_dup 0)
11469 (match_operand:SI 3 "const_int_operand" "")))
11470 (match_operand:SI 4 "s_register_operand" "r"))]
11471 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11472 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3]))
11473 && (operands_ok_ldrd_strd (operands[2], operands[4],
11474 operands[0], INTVAL (operands[1]),
11475 false, false))"
11476 "strd%?\t%2, %4, [%0, %1]"
11477 [(set_attr "type" "store_8")
11478 (set_attr "predicable" "yes")])
11479
11480 (define_insn "*thumb2_strd_base"
11481 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk"))
11482 (match_operand:SI 1 "s_register_operand" "r"))
11483 (set (mem:SI (plus:SI (match_dup 0)
11484 (const_int 4)))
11485 (match_operand:SI 2 "s_register_operand" "r"))]
11486 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11487 && (operands_ok_ldrd_strd (operands[1], operands[2],
11488 operands[0], 0, false, false))"
11489 "strd%?\t%1, %2, [%0]"
11490 [(set_attr "type" "store_8")
11491 (set_attr "predicable" "yes")])
11492
11493 (define_insn "*thumb2_strd_base_neg"
11494 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk")
11495 (const_int -4)))
11496 (match_operand:SI 1 "s_register_operand" "r"))
11497 (set (mem:SI (match_dup 0))
11498 (match_operand:SI 2 "s_register_operand" "r"))]
11499 "TARGET_LDRD && TARGET_THUMB2 && reload_completed
11500 && (operands_ok_ldrd_strd (operands[1], operands[2],
11501 operands[0], -4, false, false))"
11502 "strd%?\t%1, %2, [%0, #-4]"
11503 [(set_attr "type" "store_8")
11504 (set_attr "predicable" "yes")])
11505
11506 ;; ARMv8 CRC32 instructions.
11507 (define_insn "arm_<crc_variant>"
11508 [(set (match_operand:SI 0 "s_register_operand" "=r")
11509 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
11510 (match_operand:<crc_mode> 2 "s_register_operand" "r")]
11511 CRC))]
11512 "TARGET_CRC32"
11513 "<crc_variant>\\t%0, %1, %2"
11514 [(set_attr "type" "crc")
11515 (set_attr "conds" "unconditional")]
11516 )
11517
11518 ;; Load the load/store double peephole optimizations.
11519 (include "ldrdstrd.md")
11520
11521 ;; Load the load/store multiple patterns
11522 (include "ldmstm.md")
11523
11524 ;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers
11525 ;; large lists without explicit writeback generated for APCS_FRAME epilogue.
11526 ;; The operands are validated through the load_multiple_operation
11527 ;; match_parallel predicate rather than through constraints so enable it only
11528 ;; after reload.
11529 (define_insn "*load_multiple"
11530 [(match_parallel 0 "load_multiple_operation"
11531 [(set (match_operand:SI 2 "s_register_operand" "=rk")
11532 (mem:SI (match_operand:SI 1 "s_register_operand" "rk")))
11533 ])]
11534 "TARGET_32BIT && reload_completed"
11535 "*
11536 {
11537 arm_output_multireg_pop (operands, /*return_pc=*/false,
11538 /*cond=*/const_true_rtx,
11539 /*reverse=*/false,
11540 /*update=*/false);
11541 return \"\";
11542 }
11543 "
11544 [(set_attr "predicable" "yes")]
11545 )
11546
11547 (define_expand "copysignsf3"
11548 [(match_operand:SF 0 "register_operand")
11549 (match_operand:SF 1 "register_operand")
11550 (match_operand:SF 2 "register_operand")]
11551 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11552 "{
11553 emit_move_insn (operands[0], operands[2]);
11554 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0),
11555 GEN_INT (31), GEN_INT (0),
11556 simplify_gen_subreg (SImode, operands[1], SFmode, 0)));
11557 DONE;
11558 }"
11559 )
11560
11561 (define_expand "copysigndf3"
11562 [(match_operand:DF 0 "register_operand")
11563 (match_operand:DF 1 "register_operand")
11564 (match_operand:DF 2 "register_operand")]
11565 "TARGET_SOFT_FLOAT && arm_arch_thumb2"
11566 "{
11567 rtx op0_low = gen_lowpart (SImode, operands[0]);
11568 rtx op0_high = gen_highpart (SImode, operands[0]);
11569 rtx op1_low = gen_lowpart (SImode, operands[1]);
11570 rtx op1_high = gen_highpart (SImode, operands[1]);
11571 rtx op2_high = gen_highpart (SImode, operands[2]);
11572
11573 rtx scratch1 = gen_reg_rtx (SImode);
11574 rtx scratch2 = gen_reg_rtx (SImode);
11575 emit_move_insn (scratch1, op2_high);
11576 emit_move_insn (scratch2, op1_high);
11577
11578 emit_insn(gen_rtx_SET(scratch1,
11579 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31))));
11580 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1));
11581 emit_move_insn (op0_low, op1_low);
11582 emit_move_insn (op0_high, scratch2);
11583
11584 DONE;
11585 }"
11586 )
11587
11588 ;; movmisalign patterns for HImode and SImode.
11589 (define_expand "movmisalign<mode>"
11590 [(match_operand:HSI 0 "general_operand")
11591 (match_operand:HSI 1 "general_operand")]
11592 "unaligned_access"
11593 {
11594 /* This pattern is not permitted to fail during expansion: if both arguments
11595 are non-registers (e.g. memory := constant), force operand 1 into a
11596 register. */
11597 rtx (* gen_unaligned_load)(rtx, rtx);
11598 rtx tmp_dest = operands[0];
11599 if (!s_register_operand (operands[0], <MODE>mode)
11600 && !s_register_operand (operands[1], <MODE>mode))
11601 operands[1] = force_reg (<MODE>mode, operands[1]);
11602
11603 if (<MODE>mode == HImode)
11604 {
11605 gen_unaligned_load = gen_unaligned_loadhiu;
11606 tmp_dest = gen_reg_rtx (SImode);
11607 }
11608 else
11609 gen_unaligned_load = gen_unaligned_loadsi;
11610
11611 if (MEM_P (operands[1]))
11612 {
11613 emit_insn (gen_unaligned_load (tmp_dest, operands[1]));
11614 if (<MODE>mode == HImode)
11615 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest));
11616 }
11617 else
11618 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1]));
11619
11620 DONE;
11621 })
11622
11623 (define_insn "arm_<cdp>"
11624 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11625 (match_operand:SI 1 "immediate_operand" "n")
11626 (match_operand:SI 2 "immediate_operand" "n")
11627 (match_operand:SI 3 "immediate_operand" "n")
11628 (match_operand:SI 4 "immediate_operand" "n")
11629 (match_operand:SI 5 "immediate_operand" "n")] CDPI)]
11630 "arm_coproc_builtin_available (VUNSPEC_<CDP>)"
11631 {
11632 arm_const_bounds (operands[0], 0, 16);
11633 arm_const_bounds (operands[1], 0, 16);
11634 arm_const_bounds (operands[2], 0, (1 << 5));
11635 arm_const_bounds (operands[3], 0, (1 << 5));
11636 arm_const_bounds (operands[4], 0, (1 << 5));
11637 arm_const_bounds (operands[5], 0, 8);
11638 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5";
11639 }
11640 [(set_attr "length" "4")
11641 (set_attr "type" "coproc")])
11642
11643 (define_insn "*ldc"
11644 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11645 (match_operand:SI 1 "immediate_operand" "n")
11646 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)]
11647 "arm_coproc_builtin_available (VUNSPEC_<LDC>)"
11648 {
11649 arm_const_bounds (operands[0], 0, 16);
11650 arm_const_bounds (operands[1], 0, (1 << 5));
11651 return "<ldc>\\tp%c0, CR%c1, %2";
11652 }
11653 [(set_attr "length" "4")
11654 (set_attr "type" "coproc")])
11655
11656 (define_insn "*stc"
11657 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11658 (match_operand:SI 1 "immediate_operand" "n")
11659 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)]
11660 "arm_coproc_builtin_available (VUNSPEC_<STC>)"
11661 {
11662 arm_const_bounds (operands[0], 0, 16);
11663 arm_const_bounds (operands[1], 0, (1 << 5));
11664 return "<stc>\\tp%c0, CR%c1, %2";
11665 }
11666 [(set_attr "length" "4")
11667 (set_attr "type" "coproc")])
11668
11669 (define_expand "arm_<ldc>"
11670 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11671 (match_operand:SI 1 "immediate_operand")
11672 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
11673 "arm_coproc_builtin_available (VUNSPEC_<LDC>)")
11674
11675 (define_expand "arm_<stc>"
11676 [(unspec_volatile [(match_operand:SI 0 "immediate_operand")
11677 (match_operand:SI 1 "immediate_operand")
11678 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
11679 "arm_coproc_builtin_available (VUNSPEC_<STC>)")
11680
11681 (define_insn "arm_<mcr>"
11682 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11683 (match_operand:SI 1 "immediate_operand" "n")
11684 (match_operand:SI 2 "s_register_operand" "r")
11685 (match_operand:SI 3 "immediate_operand" "n")
11686 (match_operand:SI 4 "immediate_operand" "n")
11687 (match_operand:SI 5 "immediate_operand" "n")] MCRI)
11688 (use (match_dup 2))]
11689 "arm_coproc_builtin_available (VUNSPEC_<MCR>)"
11690 {
11691 arm_const_bounds (operands[0], 0, 16);
11692 arm_const_bounds (operands[1], 0, 8);
11693 arm_const_bounds (operands[3], 0, (1 << 5));
11694 arm_const_bounds (operands[4], 0, (1 << 5));
11695 arm_const_bounds (operands[5], 0, 8);
11696 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5";
11697 }
11698 [(set_attr "length" "4")
11699 (set_attr "type" "coproc")])
11700
11701 (define_insn "arm_<mrc>"
11702 [(set (match_operand:SI 0 "s_register_operand" "=r")
11703 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
11704 (match_operand:SI 2 "immediate_operand" "n")
11705 (match_operand:SI 3 "immediate_operand" "n")
11706 (match_operand:SI 4 "immediate_operand" "n")
11707 (match_operand:SI 5 "immediate_operand" "n")] MRCI))]
11708 "arm_coproc_builtin_available (VUNSPEC_<MRC>)"
11709 {
11710 arm_const_bounds (operands[1], 0, 16);
11711 arm_const_bounds (operands[2], 0, 8);
11712 arm_const_bounds (operands[3], 0, (1 << 5));
11713 arm_const_bounds (operands[4], 0, (1 << 5));
11714 arm_const_bounds (operands[5], 0, 8);
11715 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5";
11716 }
11717 [(set_attr "length" "4")
11718 (set_attr "type" "coproc")])
11719
11720 (define_insn "arm_<mcrr>"
11721 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
11722 (match_operand:SI 1 "immediate_operand" "n")
11723 (match_operand:DI 2 "s_register_operand" "r")
11724 (match_operand:SI 3 "immediate_operand" "n")] MCRRI)
11725 (use (match_dup 2))]
11726 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)"
11727 {
11728 arm_const_bounds (operands[0], 0, 16);
11729 arm_const_bounds (operands[1], 0, 8);
11730 arm_const_bounds (operands[3], 0, (1 << 5));
11731 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3";
11732 }
11733 [(set_attr "length" "4")
11734 (set_attr "type" "coproc")])
11735
11736 (define_insn "arm_<mrrc>"
11737 [(set (match_operand:DI 0 "s_register_operand" "=r")
11738 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
11739 (match_operand:SI 2 "immediate_operand" "n")
11740 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))]
11741 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)"
11742 {
11743 arm_const_bounds (operands[1], 0, 16);
11744 arm_const_bounds (operands[2], 0, 8);
11745 arm_const_bounds (operands[3], 0, (1 << 5));
11746 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3";
11747 }
11748 [(set_attr "length" "4")
11749 (set_attr "type" "coproc")])
11750
11751 (define_expand "speculation_barrier"
11752 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11753 "TARGET_EITHER"
11754 "
11755 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't
11756 have a usable barrier (and probably don't need one in practice).
11757 But to be safe if such code is run on later architectures, call a
11758 helper function in libgcc that will do the thing for the active
11759 system. */
11760 if (!(arm_arch7 || arm_arch8))
11761 {
11762 arm_emit_speculation_barrier_function ();
11763 DONE;
11764 }
11765 "
11766 )
11767
11768 ;; Generate a hard speculation barrier when we have not enabled speculation
11769 ;; tracking.
11770 (define_insn "*speculation_barrier_insn"
11771 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)]
11772 "arm_arch7 || arm_arch8"
11773 "isb\;dsb\\tsy"
11774 [(set_attr "type" "block")
11775 (set_attr "length" "8")]
11776 )
11777
11778 ;; Vector bits common to IWMMXT and Neon
11779 (include "vec-common.md")
11780 ;; Load the Intel Wireless Multimedia Extension patterns
11781 (include "iwmmxt.md")
11782 ;; Load the VFP co-processor patterns
11783 (include "vfp.md")
11784 ;; Thumb-1 patterns
11785 (include "thumb1.md")
11786 ;; Thumb-2 patterns
11787 (include "thumb2.md")
11788 ;; Neon patterns
11789 (include "neon.md")
11790 ;; Crypto patterns
11791 (include "crypto.md")
11792 ;; Synchronization Primitives
11793 (include "sync.md")
11794 ;; Fixed-point patterns
11795 (include "arm-fixed.md")