]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/aarch64/aarch64.md
[ARM,AARCH64] Insn type reclassification. Split f_cvt type.
[thirdparty/gcc.git] / gcc / config / aarch64 / aarch64.md
1 ;; Machine description for AArch64 architecture.
2 ;; Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;; Register numbers
22 (define_constants
23 [
24 (R0_REGNUM 0)
25 (R1_REGNUM 1)
26 (R2_REGNUM 2)
27 (R3_REGNUM 3)
28 (R4_REGNUM 4)
29 (R5_REGNUM 5)
30 (R6_REGNUM 6)
31 (R7_REGNUM 7)
32 (R8_REGNUM 8)
33 (R9_REGNUM 9)
34 (R10_REGNUM 10)
35 (R11_REGNUM 11)
36 (R12_REGNUM 12)
37 (R13_REGNUM 13)
38 (R14_REGNUM 14)
39 (R15_REGNUM 15)
40 (R16_REGNUM 16)
41 (IP0_REGNUM 16)
42 (R17_REGNUM 17)
43 (IP1_REGNUM 17)
44 (R18_REGNUM 18)
45 (R19_REGNUM 19)
46 (R20_REGNUM 20)
47 (R21_REGNUM 21)
48 (R22_REGNUM 22)
49 (R23_REGNUM 23)
50 (R24_REGNUM 24)
51 (R25_REGNUM 25)
52 (R26_REGNUM 26)
53 (R27_REGNUM 27)
54 (R28_REGNUM 28)
55 (R29_REGNUM 29)
56 (R30_REGNUM 30)
57 (LR_REGNUM 30)
58 (SP_REGNUM 31)
59 (V0_REGNUM 32)
60 (V15_REGNUM 47)
61 (V31_REGNUM 63)
62 (SFP_REGNUM 64)
63 (AP_REGNUM 65)
64 (CC_REGNUM 66)
65 ]
66 )
67
68 (define_c_enum "unspec" [
69 UNSPEC_CASESI
70 UNSPEC_CLS
71 UNSPEC_FRECPE
72 UNSPEC_FRECPS
73 UNSPEC_FRECPX
74 UNSPEC_FRINTA
75 UNSPEC_FRINTI
76 UNSPEC_FRINTM
77 UNSPEC_FRINTN
78 UNSPEC_FRINTP
79 UNSPEC_FRINTX
80 UNSPEC_FRINTZ
81 UNSPEC_GOTSMALLPIC
82 UNSPEC_GOTSMALLTLS
83 UNSPEC_GOTTINYPIC
84 UNSPEC_LD2
85 UNSPEC_LD3
86 UNSPEC_LD4
87 UNSPEC_MB
88 UNSPEC_NOP
89 UNSPEC_PRLG_STK
90 UNSPEC_RBIT
91 UNSPEC_SISD_NEG
92 UNSPEC_SISD_SSHL
93 UNSPEC_SISD_USHL
94 UNSPEC_SSHL_2S
95 UNSPEC_ST2
96 UNSPEC_ST3
97 UNSPEC_ST4
98 UNSPEC_TLS
99 UNSPEC_TLSDESC
100 UNSPEC_USHL_2S
101 UNSPEC_VSTRUCTDUMMY
102 ])
103
104 (define_c_enum "unspecv" [
105 UNSPECV_EH_RETURN ; Represent EH_RETURN
106 ]
107 )
108
109 ;; If further include files are added the defintion of MD_INCLUDES
110 ;; must be updated.
111
112 (include "constraints.md")
113 (include "predicates.md")
114 (include "iterators.md")
115
116 ;; -------------------------------------------------------------------
117 ;; Instruction types and attributes
118 ;; -------------------------------------------------------------------
119
120 ;; Main data types used by the insntructions
121
122 (define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
123 (const_string "unknown"))
124
125 (define_attr "mode2" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF"
126 (const_string "unknown"))
127
128 ; The "v8type" attribute is used to for fine grained classification of
129 ; AArch64 instructions. This table briefly explains the meaning of each type.
130
131 ; adc add/subtract with carry.
132 ; adcs add/subtract with carry (setting condition flags).
133 ; adr calculate address.
134 ; alu simple alu instruction (no memory or fp regs access).
135 ; alu_ext simple alu instruction (sign/zero-extended register).
136 ; alu_shift simple alu instruction, with a source operand shifted by a constant.
137 ; alus simple alu instruction (setting condition flags).
138 ; alus_ext simple alu instruction (sign/zero-extended register, setting condition flags).
139 ; alus_shift simple alu instruction, with a source operand shifted by a constant (setting condition flags).
140 ; bfm bitfield move operation.
141 ; branch branch.
142 ; call subroutine call.
143 ; ccmp conditional compare.
144 ; clz count leading zeros/sign bits.
145 ; csel conditional select.
146 ; dmb data memory barrier.
147 ; extend sign/zero-extend (specialised bitfield move).
148 ; extr extract register-sized bitfield encoding.
149 ; fpsimd_load load single floating point / simd scalar register from memory.
150 ; fpsimd_load2 load pair of floating point / simd scalar registers from memory.
151 ; fpsimd_store store single floating point / simd scalar register to memory.
152 ; fpsimd_store2 store pair floating point / simd scalar registers to memory.
153 ; fadd floating point add/sub.
154 ; fccmp floating point conditional compare.
155 ; fcmp floating point comparison.
156 ; fconst floating point load immediate.
157 ; fcsel floating point conditional select.
158 ; fcvt floating point convert (float to float).
159 ; fcvtf2i floating point convert (float to integer).
160 ; fcvti2f floating point convert (integer to float).
161 ; fdiv floating point division operation.
162 ; ffarith floating point abs, neg or cpy.
163 ; fmadd floating point multiply-add/sub.
164 ; fminmax floating point min/max.
165 ; fmov floating point move (float to float).
166 ; fmovf2i floating point move (float to integer).
167 ; fmovi2f floating point move (integer to float).
168 ; fmul floating point multiply.
169 ; frint floating point round to integral.
170 ; fsqrt floating point square root.
171 ; load_acq load-acquire.
172 ; load load single general register from memory
173 ; load2 load pair of general registers from memory
174 ; logic logical operation (register).
175 ; logic_imm and/or/xor operation (immediate).
176 ; logic_shift logical operation with shift.
177 ; logics logical operation (register, setting condition flags).
178 ; logics_imm and/or/xor operation (immediate, setting condition flags).
179 ; logics_shift logical operation with shift (setting condition flags).
180 ; madd integer multiply-add/sub.
181 ; maddl widening integer multiply-add/sub.
182 ; misc miscellaneous - any type that doesn't fit into the rest.
183 ; move integer move operation.
184 ; move2 double integer move operation.
185 ; movk move 16-bit immediate with keep.
186 ; movz move 16-bit immmediate with zero/one.
187 ; mrs system/special register move.
188 ; mulh 64x64 to 128-bit multiply (high part).
189 ; mull widening multiply.
190 ; mult integer multiply instruction.
191 ; prefetch memory prefetch.
192 ; rbit reverse bits.
193 ; rev reverse bytes.
194 ; sdiv integer division operation (signed).
195 ; shift variable shift operation.
196 ; shift_imm immediate shift operation (specialised bitfield move).
197 ; store_rel store-release.
198 ; store store single general register to memory.
199 ; store2 store pair of general registers to memory.
200 ; udiv integer division operation (unsigned).
201
202 (define_attr "v8type"
203 "adc,\
204 adcs,\
205 adr,\
206 alu,\
207 alu_ext,\
208 alu_shift,\
209 alus,\
210 alus_ext,\
211 alus_shift,\
212 bfm,\
213 branch,\
214 call,\
215 ccmp,\
216 clz,\
217 csel,\
218 dmb,\
219 div,\
220 div64,\
221 extend,\
222 extr,\
223 fpsimd_load,\
224 fpsimd_load2,\
225 fpsimd_store2,\
226 fpsimd_store,\
227 fadd,\
228 fccmp,\
229 fcvt,\
230 fcvtf2i,\
231 fcvti2f,\
232 fcmp,\
233 fconst,\
234 fcsel,\
235 fdiv,\
236 ffarith,\
237 fmadd,\
238 fminmax,\
239 fmov,\
240 fmovf2i,\
241 fmovi2f,\
242 fmul,\
243 frint,\
244 fsqrt,\
245 load_acq,\
246 load1,\
247 load2,\
248 logic,\
249 logic_imm,\
250 logic_shift,\
251 logics,\
252 logics_imm,\
253 logics_shift,\
254 madd,\
255 maddl,\
256 misc,\
257 move,\
258 move2,\
259 movk,\
260 movz,\
261 mrs,\
262 mulh,\
263 mull,\
264 mult,\
265 prefetch,\
266 rbit,\
267 rev,\
268 sdiv,\
269 shift,\
270 shift_imm,\
271 store_rel,\
272 store1,\
273 store2,\
274 udiv"
275 (const_string "alu"))
276
277 ; The "type" attribute is is included here from AArch32 backend to be able
278 ; to share pipeline descriptions.
279 (include "../arm/types.md")
280
281 ;; Attribute that specifies whether or not the instruction touches fp
282 ;; registers.
283 (define_attr "fp" "no,yes" (const_string "no"))
284
285 ;; Attribute that specifies whether or not the instruction touches simd
286 ;; registers.
287 (define_attr "simd" "no,yes" (const_string "no"))
288
289 (define_attr "length" ""
290 (const_int 4))
291
292 ;; Attribute that controls whether an alternative is enabled or not.
293 ;; Currently it is only used to disable alternatives which touch fp or simd
294 ;; registers when -mgeneral-regs-only is specified.
295 (define_attr "enabled" "no,yes"
296 (cond [(ior
297 (and (eq_attr "fp" "yes")
298 (eq (symbol_ref "TARGET_FLOAT") (const_int 0)))
299 (and (eq_attr "simd" "yes")
300 (eq (symbol_ref "TARGET_SIMD") (const_int 0))))
301 (const_string "no")
302 ] (const_string "yes")))
303
304 ;; -------------------------------------------------------------------
305 ;; Pipeline descriptions and scheduling
306 ;; -------------------------------------------------------------------
307
308 ;; Processor types.
309 (include "aarch64-tune.md")
310
311 ;; Scheduling
312 (include "aarch64-generic.md")
313 (include "large.md")
314 (include "small.md")
315 (include "../arm/cortex-a53.md")
316
317 ;; -------------------------------------------------------------------
318 ;; Jumps and other miscellaneous insns
319 ;; -------------------------------------------------------------------
320
321 (define_insn "indirect_jump"
322 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
323 ""
324 "br\\t%0"
325 [(set_attr "v8type" "branch")
326 (set_attr "type" "branch")]
327 )
328
329 (define_insn "jump"
330 [(set (pc) (label_ref (match_operand 0 "" "")))]
331 ""
332 "b\\t%l0"
333 [(set_attr "v8type" "branch")
334 (set_attr "type" "branch")]
335 )
336
337 (define_expand "cbranch<mode>4"
338 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
339 [(match_operand:GPI 1 "register_operand" "")
340 (match_operand:GPI 2 "aarch64_plus_operand" "")])
341 (label_ref (match_operand 3 "" ""))
342 (pc)))]
343 ""
344 "
345 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
346 operands[2]);
347 operands[2] = const0_rtx;
348 "
349 )
350
351 (define_expand "cbranch<mode>4"
352 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
353 [(match_operand:GPF 1 "register_operand" "")
354 (match_operand:GPF 2 "aarch64_reg_or_zero" "")])
355 (label_ref (match_operand 3 "" ""))
356 (pc)))]
357 ""
358 "
359 operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), operands[1],
360 operands[2]);
361 operands[2] = const0_rtx;
362 "
363 )
364
365 (define_insn "*condjump"
366 [(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
367 [(match_operand 1 "cc_register" "") (const_int 0)])
368 (label_ref (match_operand 2 "" ""))
369 (pc)))]
370 ""
371 "b%m0\\t%l2"
372 [(set_attr "v8type" "branch")
373 (set_attr "type" "branch")]
374 )
375
376 (define_expand "casesi"
377 [(match_operand:SI 0 "register_operand" "") ; Index
378 (match_operand:SI 1 "const_int_operand" "") ; Lower bound
379 (match_operand:SI 2 "const_int_operand" "") ; Total range
380 (match_operand:DI 3 "" "") ; Table label
381 (match_operand:DI 4 "" "")] ; Out of range label
382 ""
383 {
384 if (operands[1] != const0_rtx)
385 {
386 rtx reg = gen_reg_rtx (SImode);
387
388 /* Canonical RTL says that if you have:
389
390 (minus (X) (CONST))
391
392 then this should be emitted as:
393
394 (plus (X) (-CONST))
395
396 The use of trunc_int_for_mode ensures that the resulting
397 constant can be represented in SImode, this is important
398 for the corner case where operand[1] is INT_MIN. */
399
400 operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
401
402 if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
403 (operands[1], SImode))
404 operands[1] = force_reg (SImode, operands[1]);
405 emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
406 operands[0] = reg;
407 }
408
409 if (!aarch64_plus_operand (operands[2], SImode))
410 operands[2] = force_reg (SImode, operands[2]);
411 emit_jump_insn (gen_cbranchsi4 (gen_rtx_GTU (SImode, const0_rtx,
412 const0_rtx),
413 operands[0], operands[2], operands[4]));
414
415 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
416 emit_jump_insn (gen_casesi_dispatch (operands[2], operands[0],
417 operands[3]));
418 DONE;
419 }
420 )
421
422 (define_insn "casesi_dispatch"
423 [(parallel
424 [(set (pc)
425 (mem:DI (unspec [(match_operand:DI 0 "register_operand" "r")
426 (match_operand:SI 1 "register_operand" "r")]
427 UNSPEC_CASESI)))
428 (clobber (reg:CC CC_REGNUM))
429 (clobber (match_scratch:DI 3 "=r"))
430 (clobber (match_scratch:DI 4 "=r"))
431 (use (label_ref (match_operand 2 "" "")))])]
432 ""
433 "*
434 return aarch64_output_casesi (operands);
435 "
436 [(set_attr "length" "16")
437 (set_attr "v8type" "branch")
438 (set_attr "type" "branch")]
439 )
440
441 (define_insn "nop"
442 [(unspec[(const_int 0)] UNSPEC_NOP)]
443 ""
444 "nop"
445 [(set_attr "v8type" "misc")]
446 )
447
448 (define_expand "prologue"
449 [(clobber (const_int 0))]
450 ""
451 "
452 aarch64_expand_prologue ();
453 DONE;
454 "
455 )
456
457 (define_expand "epilogue"
458 [(clobber (const_int 0))]
459 ""
460 "
461 aarch64_expand_epilogue (false);
462 DONE;
463 "
464 )
465
466 (define_expand "sibcall_epilogue"
467 [(clobber (const_int 0))]
468 ""
469 "
470 aarch64_expand_epilogue (true);
471 DONE;
472 "
473 )
474
475 (define_insn "*do_return"
476 [(return)]
477 ""
478 "ret"
479 [(set_attr "v8type" "branch")
480 (set_attr "type" "branch")]
481 )
482
483 (define_insn "eh_return"
484 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
485 UNSPECV_EH_RETURN)]
486 ""
487 "#"
488 [(set_attr "v8type" "branch")
489 (set_attr "type" "branch")]
490
491 )
492
493 (define_split
494 [(unspec_volatile [(match_operand:DI 0 "register_operand" "")]
495 UNSPECV_EH_RETURN)]
496 "reload_completed"
497 [(set (match_dup 1) (match_dup 0))]
498 {
499 operands[1] = aarch64_final_eh_return_addr ();
500 }
501 )
502
503 (define_insn "*cb<optab><mode>1"
504 [(set (pc) (if_then_else (EQL (match_operand:GPI 0 "register_operand" "r")
505 (const_int 0))
506 (label_ref (match_operand 1 "" ""))
507 (pc)))]
508 ""
509 "<cbz>\\t%<w>0, %l1"
510 [(set_attr "v8type" "branch")
511 (set_attr "type" "branch")]
512
513 )
514
515 (define_insn "*tb<optab><mode>1"
516 [(set (pc) (if_then_else
517 (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r")
518 (const_int 1)
519 (match_operand 1 "const_int_operand" "n"))
520 (const_int 0))
521 (label_ref (match_operand 2 "" ""))
522 (pc)))
523 (clobber (match_scratch:DI 3 "=r"))]
524 ""
525 "*
526 if (get_attr_length (insn) == 8)
527 return \"ubfx\\t%<w>3, %<w>0, %1, #1\;<cbz>\\t%<w>3, %l2\";
528 return \"<tbz>\\t%<w>0, %1, %l2\";
529 "
530 [(set_attr "v8type" "branch")
531 (set_attr "type" "branch")
532 (set_attr "mode" "<MODE>")
533 (set (attr "length")
534 (if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
535 (lt (minus (match_dup 2) (pc)) (const_int 32764)))
536 (const_int 4)
537 (const_int 8)))]
538 )
539
540 (define_insn "*cb<optab><mode>1"
541 [(set (pc) (if_then_else (LTGE (match_operand:ALLI 0 "register_operand" "r")
542 (const_int 0))
543 (label_ref (match_operand 1 "" ""))
544 (pc)))
545 (clobber (match_scratch:DI 2 "=r"))]
546 ""
547 "*
548 if (get_attr_length (insn) == 8)
549 return \"ubfx\\t%<w>2, %<w>0, <sizem1>, #1\;<cbz>\\t%<w>2, %l1\";
550 return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
551 "
552 [(set_attr "v8type" "branch")
553 (set_attr "type" "branch")
554 (set_attr "mode" "<MODE>")
555 (set (attr "length")
556 (if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
557 (lt (minus (match_dup 1) (pc)) (const_int 32764)))
558 (const_int 4)
559 (const_int 8)))]
560 )
561
562 ;; -------------------------------------------------------------------
563 ;; Subroutine calls and sibcalls
564 ;; -------------------------------------------------------------------
565
566 (define_expand "call"
567 [(parallel [(call (match_operand 0 "memory_operand" "")
568 (match_operand 1 "general_operand" ""))
569 (use (match_operand 2 "" ""))
570 (clobber (reg:DI LR_REGNUM))])]
571 ""
572 "
573 {
574 rtx callee;
575
576 /* In an untyped call, we can get NULL for operand 2. */
577 if (operands[2] == NULL)
578 operands[2] = const0_rtx;
579
580 /* Decide if we should generate indirect calls by loading the
581 64-bit address of the callee into a register before performing
582 the branch-and-link. */
583 callee = XEXP (operands[0], 0);
584 if (GET_CODE (callee) == SYMBOL_REF
585 ? aarch64_is_long_call_p (callee)
586 : !REG_P (callee))
587 XEXP (operands[0], 0) = force_reg (Pmode, callee);
588 }"
589 )
590
591 (define_insn "*call_reg"
592 [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
593 (match_operand 1 "" ""))
594 (use (match_operand 2 "" ""))
595 (clobber (reg:DI LR_REGNUM))]
596 ""
597 "blr\\t%0"
598 [(set_attr "v8type" "call")
599 (set_attr "type" "call")]
600 )
601
602 (define_insn "*call_symbol"
603 [(call (mem:DI (match_operand:DI 0 "" ""))
604 (match_operand 1 "" ""))
605 (use (match_operand 2 "" ""))
606 (clobber (reg:DI LR_REGNUM))]
607 "GET_CODE (operands[0]) == SYMBOL_REF
608 && !aarch64_is_long_call_p (operands[0])"
609 "bl\\t%a0"
610 [(set_attr "v8type" "call")
611 (set_attr "type" "call")]
612 )
613
614 (define_expand "call_value"
615 [(parallel [(set (match_operand 0 "" "")
616 (call (match_operand 1 "memory_operand" "")
617 (match_operand 2 "general_operand" "")))
618 (use (match_operand 3 "" ""))
619 (clobber (reg:DI LR_REGNUM))])]
620 ""
621 "
622 {
623 rtx callee;
624
625 /* In an untyped call, we can get NULL for operand 3. */
626 if (operands[3] == NULL)
627 operands[3] = const0_rtx;
628
629 /* Decide if we should generate indirect calls by loading the
630 64-bit address of the callee into a register before performing
631 the branch-and-link. */
632 callee = XEXP (operands[1], 0);
633 if (GET_CODE (callee) == SYMBOL_REF
634 ? aarch64_is_long_call_p (callee)
635 : !REG_P (callee))
636 XEXP (operands[1], 0) = force_reg (Pmode, callee);
637 }"
638 )
639
640 (define_insn "*call_value_reg"
641 [(set (match_operand 0 "" "")
642 (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
643 (match_operand 2 "" "")))
644 (use (match_operand 3 "" ""))
645 (clobber (reg:DI LR_REGNUM))]
646 ""
647 "blr\\t%1"
648 [(set_attr "v8type" "call")
649 (set_attr "type" "call")]
650
651 )
652
653 (define_insn "*call_value_symbol"
654 [(set (match_operand 0 "" "")
655 (call (mem:DI (match_operand:DI 1 "" ""))
656 (match_operand 2 "" "")))
657 (use (match_operand 3 "" ""))
658 (clobber (reg:DI LR_REGNUM))]
659 "GET_CODE (operands[1]) == SYMBOL_REF
660 && !aarch64_is_long_call_p (operands[1])"
661 "bl\\t%a1"
662 [(set_attr "v8type" "call")
663 (set_attr "type" "call")]
664 )
665
666 (define_expand "sibcall"
667 [(parallel [(call (match_operand 0 "memory_operand" "")
668 (match_operand 1 "general_operand" ""))
669 (return)
670 (use (match_operand 2 "" ""))])]
671 ""
672 {
673 if (operands[2] == NULL_RTX)
674 operands[2] = const0_rtx;
675 }
676 )
677
678 (define_expand "sibcall_value"
679 [(parallel [(set (match_operand 0 "" "")
680 (call (match_operand 1 "memory_operand" "")
681 (match_operand 2 "general_operand" "")))
682 (return)
683 (use (match_operand 3 "" ""))])]
684 ""
685 {
686 if (operands[3] == NULL_RTX)
687 operands[3] = const0_rtx;
688 }
689 )
690
691 (define_insn "*sibcall_insn"
692 [(call (mem:DI (match_operand:DI 0 "" "X"))
693 (match_operand 1 "" ""))
694 (return)
695 (use (match_operand 2 "" ""))]
696 "GET_CODE (operands[0]) == SYMBOL_REF"
697 "b\\t%a0"
698 [(set_attr "v8type" "branch")
699 (set_attr "type" "branch")]
700
701 )
702
703 (define_insn "*sibcall_value_insn"
704 [(set (match_operand 0 "" "")
705 (call (mem:DI (match_operand 1 "" "X"))
706 (match_operand 2 "" "")))
707 (return)
708 (use (match_operand 3 "" ""))]
709 "GET_CODE (operands[1]) == SYMBOL_REF"
710 "b\\t%a1"
711 [(set_attr "v8type" "branch")
712 (set_attr "type" "branch")]
713 )
714
715 ;; Call subroutine returning any type.
716
717 (define_expand "untyped_call"
718 [(parallel [(call (match_operand 0 "")
719 (const_int 0))
720 (match_operand 1 "")
721 (match_operand 2 "")])]
722 ""
723 {
724 int i;
725
726 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
727
728 for (i = 0; i < XVECLEN (operands[2], 0); i++)
729 {
730 rtx set = XVECEXP (operands[2], 0, i);
731 emit_move_insn (SET_DEST (set), SET_SRC (set));
732 }
733
734 /* The optimizer does not know that the call sets the function value
735 registers we stored in the result block. We avoid problems by
736 claiming that all hard registers are used and clobbered at this
737 point. */
738 emit_insn (gen_blockage ());
739 DONE;
740 })
741
742 ;; -------------------------------------------------------------------
743 ;; Moves
744 ;; -------------------------------------------------------------------
745
746 (define_expand "mov<mode>"
747 [(set (match_operand:SHORT 0 "nonimmediate_operand" "")
748 (match_operand:SHORT 1 "general_operand" ""))]
749 ""
750 "
751 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
752 operands[1] = force_reg (<MODE>mode, operands[1]);
753 "
754 )
755
756 (define_insn "*mov<mode>_aarch64"
757 [(set (match_operand:SHORT 0 "nonimmediate_operand" "=r,r, *w,r,*w, m, m, r,*w,*w")
758 (match_operand:SHORT 1 "general_operand" " r,M,D<hq>,m, m,rZ,*w,*w, r,*w"))]
759 "(register_operand (operands[0], <MODE>mode)
760 || aarch64_reg_or_zero (operands[1], <MODE>mode))"
761 {
762 switch (which_alternative)
763 {
764 case 0:
765 return "mov\t%w0, %w1";
766 case 1:
767 return "mov\t%w0, %1";
768 case 2:
769 return aarch64_output_scalar_simd_mov_immediate (operands[1],
770 <MODE>mode);
771 case 3:
772 return "ldr<size>\t%w0, %1";
773 case 4:
774 return "ldr\t%<size>0, %1";
775 case 5:
776 return "str<size>\t%w1, %0";
777 case 6:
778 return "str\t%<size>1, %0";
779 case 7:
780 return "umov\t%w0, %1.<v>[0]";
781 case 8:
782 return "dup\t%0.<Vallxd>, %w1";
783 case 9:
784 return "dup\t%0, %1.<v>[0]";
785 default:
786 gcc_unreachable ();
787 }
788 }
789 [(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
790 (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,*,*,*")
791 (set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
792 (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
793 (set_attr "mode" "<MODE>")
794 (set_attr "simd_mode" "<MODE>")]
795 )
796
797 (define_expand "mov<mode>"
798 [(set (match_operand:GPI 0 "nonimmediate_operand" "")
799 (match_operand:GPI 1 "general_operand" ""))]
800 ""
801 "
802 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
803 operands[1] = force_reg (<MODE>mode, operands[1]);
804
805 if (CONSTANT_P (operands[1]))
806 {
807 aarch64_expand_mov_immediate (operands[0], operands[1]);
808 DONE;
809 }
810 "
811 )
812
813 (define_insn "*movsi_aarch64"
814 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r ,*w, r,*w")
815 (match_operand:SI 1 "aarch64_mov_operand" " r,r,k,M,m, m,rZ,*w,S,Ush,rZ,*w,*w"))]
816 "(register_operand (operands[0], SImode)
817 || aarch64_reg_or_zero (operands[1], SImode))"
818 "@
819 mov\\t%w0, %w1
820 mov\\t%w0, %w1
821 mov\\t%w0, %w1
822 mov\\t%w0, %1
823 ldr\\t%w0, %1
824 ldr\\t%s0, %1
825 str\\t%w1, %0
826 str\\t%s1, %0
827 adr\\t%x0, %a1
828 adrp\\t%x0, %A1
829 fmov\\t%s0, %w1
830 fmov\\t%w0, %s1
831 fmov\\t%s0, %s1"
832 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov")
833 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
834 adr,adr,mov_reg,mov_reg,mov_reg")
835 (set_attr "mode" "SI")
836 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
837 )
838
839 (define_insn "*movdi_aarch64"
840 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,k,r,r,r,*w,m, m,r,r, *w, r,*w,w")
841 (match_operand:DI 1 "aarch64_mov_operand" " r,r,k,N,m, m,rZ,*w,S,Ush,rZ,*w,*w,Dd"))]
842 "(register_operand (operands[0], DImode)
843 || aarch64_reg_or_zero (operands[1], DImode))"
844 "@
845 mov\\t%x0, %x1
846 mov\\t%0, %x1
847 mov\\t%x0, %1
848 mov\\t%x0, %1
849 ldr\\t%x0, %1
850 ldr\\t%d0, %1
851 str\\t%x1, %0
852 str\\t%d1, %0
853 adr\\t%x0, %a1
854 adrp\\t%x0, %A1
855 fmov\\t%d0, %x1
856 fmov\\t%x0, %d1
857 fmov\\t%d0, %d1
858 movi\\t%d0, %1"
859 [(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
860 (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
861 adr,adr,mov_reg,mov_reg,mov_reg,mov_reg")
862 (set_attr "mode" "DI")
863 (set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
864 (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
865 )
866
867 (define_insn "insv_imm<mode>"
868 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
869 (const_int 16)
870 (match_operand:GPI 1 "const_int_operand" "n"))
871 (match_operand:GPI 2 "const_int_operand" "n"))]
872 "UINTVAL (operands[1]) < GET_MODE_BITSIZE (<MODE>mode)
873 && UINTVAL (operands[1]) % 16 == 0"
874 "movk\\t%<w>0, %X2, lsl %1"
875 [(set_attr "v8type" "movk")
876 (set_attr "type" "mov_imm")
877 (set_attr "mode" "<MODE>")]
878 )
879
880 (define_expand "movti"
881 [(set (match_operand:TI 0 "nonimmediate_operand" "")
882 (match_operand:TI 1 "general_operand" ""))]
883 ""
884 "
885 if (GET_CODE (operands[0]) == MEM && operands[1] != const0_rtx)
886 operands[1] = force_reg (TImode, operands[1]);
887 "
888 )
889
890 (define_insn "*movti_aarch64"
891 [(set (match_operand:TI 0
892 "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
893 (match_operand:TI 1
894 "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
895 "(register_operand (operands[0], TImode)
896 || aarch64_reg_or_zero (operands[1], TImode))"
897 "@
898 #
899 #
900 #
901 orr\\t%0.16b, %1.16b, %1.16b
902 ldp\\t%0, %H0, %1
903 stp\\t%1, %H1, %0
904 stp\\txzr, xzr, %0
905 ldr\\t%q0, %1
906 str\\t%q1, %0"
907 [(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
908 load2,store2,store2,fpsimd_load,fpsimd_store")
909 (set_attr "type" "mov_reg,f_mcr,f_mrc,*, \
910 load2,store2,store2,f_loadd,f_stored")
911 (set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
912 (set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
913 (set_attr "length" "8,8,8,4,4,4,4,4,4")
914 (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
915 (set_attr "simd" "*,*,*,yes,*,*,*,*,*")])
916
917 ;; Split a TImode register-register or register-immediate move into
918 ;; its component DImode pieces, taking care to handle overlapping
919 ;; source and dest registers.
920 (define_split
921 [(set (match_operand:TI 0 "register_operand" "")
922 (match_operand:TI 1 "aarch64_reg_or_imm" ""))]
923 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
924 [(const_int 0)]
925 {
926 aarch64_split_128bit_move (operands[0], operands[1]);
927 DONE;
928 })
929
930 (define_expand "mov<mode>"
931 [(set (match_operand:GPF 0 "nonimmediate_operand" "")
932 (match_operand:GPF 1 "general_operand" ""))]
933 ""
934 "
935 if (!TARGET_FLOAT)
936 {
937 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
938 FAIL;
939 }
940
941 if (GET_CODE (operands[0]) == MEM)
942 operands[1] = force_reg (<MODE>mode, operands[1]);
943 "
944 )
945
946 (define_insn "*movsf_aarch64"
947 [(set (match_operand:SF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
948 (match_operand:SF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
949 "TARGET_FLOAT && (register_operand (operands[0], SFmode)
950 || register_operand (operands[1], SFmode))"
951 "@
952 fmov\\t%s0, %w1
953 fmov\\t%w0, %s1
954 fmov\\t%s0, %s1
955 fmov\\t%s0, %1
956 ldr\\t%s0, %1
957 str\\t%s1, %0
958 ldr\\t%w0, %1
959 str\\t%w1, %0
960 mov\\t%w0, %w1"
961 [(set_attr "v8type" "fmovi2f,fmovf2i,\
962 fmov,fconst,fpsimd_load,\
963 fpsimd_store,fpsimd_load,fpsimd_store,fmov")
964 (set_attr "type" "f_mcr,f_mrc,mov_reg,fconsts,\
965 f_loads,f_stores,f_loads,f_stores,mov_reg")
966 (set_attr "mode" "SF")]
967 )
968
969 (define_insn "*movdf_aarch64"
970 [(set (match_operand:DF 0 "nonimmediate_operand" "=w, ?r,w,w ,w,m,r,m ,r")
971 (match_operand:DF 1 "general_operand" "?rY, w,w,Ufc,m,w,m,rY,r"))]
972 "TARGET_FLOAT && (register_operand (operands[0], DFmode)
973 || register_operand (operands[1], DFmode))"
974 "@
975 fmov\\t%d0, %x1
976 fmov\\t%x0, %d1
977 fmov\\t%d0, %d1
978 fmov\\t%d0, %1
979 ldr\\t%d0, %1
980 str\\t%d1, %0
981 ldr\\t%x0, %1
982 str\\t%x1, %0
983 mov\\t%x0, %x1"
984 [(set_attr "v8type" "fmovi2f,fmovf2i,\
985 fmov,fconst,fpsimd_load,\
986 fpsimd_store,fpsimd_load,fpsimd_store,move")
987 (set_attr "type" "f_mcr,f_mrc,mov_reg,fconstd,\
988 f_loadd,f_stored,f_loadd,f_stored,mov_reg")
989 (set_attr "mode" "DF")]
990 )
991
992 (define_expand "movtf"
993 [(set (match_operand:TF 0 "nonimmediate_operand" "")
994 (match_operand:TF 1 "general_operand" ""))]
995 ""
996 "
997 if (!TARGET_FLOAT)
998 {
999 sorry (\"%qs and floating point code\", \"-mgeneral-regs-only\");
1000 FAIL;
1001 }
1002
1003 if (GET_CODE (operands[0]) == MEM)
1004 operands[1] = force_reg (TFmode, operands[1]);
1005 "
1006 )
1007
1008 (define_insn "*movtf_aarch64"
1009 [(set (match_operand:TF 0
1010 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
1011 (match_operand:TF 1
1012 "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
1013 "TARGET_FLOAT && (register_operand (operands[0], TFmode)
1014 || register_operand (operands[1], TFmode))"
1015 "@
1016 orr\\t%0.16b, %1.16b, %1.16b
1017 #
1018 #
1019 #
1020 movi\\t%0.2d, #0
1021 fmov\\t%s0, wzr
1022 ldr\\t%q0, %1
1023 str\\t%q1, %0
1024 ldp\\t%0, %H0, %1
1025 stp\\t%1, %H1, %0"
1026 [(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
1027 (set_attr "type" "logic_reg,mov_reg,f_mcr,f_mrc,fconstd,fconstd,\
1028 f_loadd,f_stored,f_loadd,f_stored")
1029 (set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
1030 (set_attr "length" "4,8,8,8,4,4,4,4,4,4")
1031 (set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
1032 (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
1033 )
1034
1035 (define_split
1036 [(set (match_operand:TF 0 "register_operand" "")
1037 (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
1038 "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
1039 [(const_int 0)]
1040 {
1041 aarch64_split_128bit_move (operands[0], operands[1]);
1042 DONE;
1043 }
1044 )
1045
1046 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1047 ;; fairly lax checking on the second memory operation.
1048 (define_insn "load_pair<mode>"
1049 [(set (match_operand:GPI 0 "register_operand" "=r")
1050 (match_operand:GPI 1 "aarch64_mem_pair_operand" "Ump"))
1051 (set (match_operand:GPI 2 "register_operand" "=r")
1052 (match_operand:GPI 3 "memory_operand" "m"))]
1053 "rtx_equal_p (XEXP (operands[3], 0),
1054 plus_constant (Pmode,
1055 XEXP (operands[1], 0),
1056 GET_MODE_SIZE (<MODE>mode)))"
1057 "ldp\\t%<w>0, %<w>2, %1"
1058 [(set_attr "v8type" "load2")
1059 (set_attr "type" "load2")
1060 (set_attr "mode" "<MODE>")]
1061 )
1062
1063 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1064 ;; fairly lax checking on the second memory operation.
1065 (define_insn "store_pair<mode>"
1066 [(set (match_operand:GPI 0 "aarch64_mem_pair_operand" "=Ump")
1067 (match_operand:GPI 1 "register_operand" "r"))
1068 (set (match_operand:GPI 2 "memory_operand" "=m")
1069 (match_operand:GPI 3 "register_operand" "r"))]
1070 "rtx_equal_p (XEXP (operands[2], 0),
1071 plus_constant (Pmode,
1072 XEXP (operands[0], 0),
1073 GET_MODE_SIZE (<MODE>mode)))"
1074 "stp\\t%<w>1, %<w>3, %0"
1075 [(set_attr "v8type" "store2")
1076 (set_attr "type" "store2")
1077 (set_attr "mode" "<MODE>")]
1078 )
1079
1080 ;; Operands 1 and 3 are tied together by the final condition; so we allow
1081 ;; fairly lax checking on the second memory operation.
1082 (define_insn "load_pair<mode>"
1083 [(set (match_operand:GPF 0 "register_operand" "=w")
1084 (match_operand:GPF 1 "aarch64_mem_pair_operand" "Ump"))
1085 (set (match_operand:GPF 2 "register_operand" "=w")
1086 (match_operand:GPF 3 "memory_operand" "m"))]
1087 "rtx_equal_p (XEXP (operands[3], 0),
1088 plus_constant (Pmode,
1089 XEXP (operands[1], 0),
1090 GET_MODE_SIZE (<MODE>mode)))"
1091 "ldp\\t%<w>0, %<w>2, %1"
1092 [(set_attr "v8type" "fpsimd_load2")
1093 (set_attr "type" "f_load<s>")
1094 (set_attr "mode" "<MODE>")]
1095 )
1096
1097 ;; Operands 0 and 2 are tied together by the final condition; so we allow
1098 ;; fairly lax checking on the second memory operation.
1099 (define_insn "store_pair<mode>"
1100 [(set (match_operand:GPF 0 "aarch64_mem_pair_operand" "=Ump")
1101 (match_operand:GPF 1 "register_operand" "w"))
1102 (set (match_operand:GPF 2 "memory_operand" "=m")
1103 (match_operand:GPF 3 "register_operand" "w"))]
1104 "rtx_equal_p (XEXP (operands[2], 0),
1105 plus_constant (Pmode,
1106 XEXP (operands[0], 0),
1107 GET_MODE_SIZE (<MODE>mode)))"
1108 "stp\\t%<w>1, %<w>3, %0"
1109 [(set_attr "v8type" "fpsimd_load2")
1110 (set_attr "type" "f_load<s>")
1111 (set_attr "mode" "<MODE>")]
1112 )
1113
1114 ;; Load pair with writeback. This is primarily used in function epilogues
1115 ;; when restoring [fp,lr]
1116 (define_insn "loadwb_pair<GPI:mode>_<P:mode>"
1117 [(parallel
1118 [(set (match_operand:P 0 "register_operand" "=k")
1119 (plus:P (match_operand:P 1 "register_operand" "0")
1120 (match_operand:P 4 "const_int_operand" "n")))
1121 (set (match_operand:GPI 2 "register_operand" "=r")
1122 (mem:GPI (plus:P (match_dup 1)
1123 (match_dup 4))))
1124 (set (match_operand:GPI 3 "register_operand" "=r")
1125 (mem:GPI (plus:P (match_dup 1)
1126 (match_operand:P 5 "const_int_operand" "n"))))])]
1127 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1128 "ldp\\t%<w>2, %<w>3, [%1], %4"
1129 [(set_attr "v8type" "load2")
1130 (set_attr "type" "load2")
1131 (set_attr "mode" "<GPI:MODE>")]
1132 )
1133
1134 ;; Store pair with writeback. This is primarily used in function prologues
1135 ;; when saving [fp,lr]
1136 (define_insn "storewb_pair<GPI:mode>_<P:mode>"
1137 [(parallel
1138 [(set (match_operand:P 0 "register_operand" "=&k")
1139 (plus:P (match_operand:P 1 "register_operand" "0")
1140 (match_operand:P 4 "const_int_operand" "n")))
1141 (set (mem:GPI (plus:P (match_dup 0)
1142 (match_dup 4)))
1143 (match_operand:GPI 2 "register_operand" "r"))
1144 (set (mem:GPI (plus:P (match_dup 0)
1145 (match_operand:P 5 "const_int_operand" "n")))
1146 (match_operand:GPI 3 "register_operand" "r"))])]
1147 "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
1148 "stp\\t%<w>2, %<w>3, [%0, %4]!"
1149 [(set_attr "v8type" "store2")
1150 (set_attr "type" "store2")
1151 (set_attr "mode" "<GPI:MODE>")]
1152 )
1153
1154 ;; -------------------------------------------------------------------
1155 ;; Sign/Zero extension
1156 ;; -------------------------------------------------------------------
1157
1158 (define_expand "<optab>sidi2"
1159 [(set (match_operand:DI 0 "register_operand")
1160 (ANY_EXTEND:DI (match_operand:SI 1 "nonimmediate_operand")))]
1161 ""
1162 )
1163
1164 (define_insn "*extendsidi2_aarch64"
1165 [(set (match_operand:DI 0 "register_operand" "=r,r")
1166 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1167 ""
1168 "@
1169 sxtw\t%0, %w1
1170 ldrsw\t%0, %1"
1171 [(set_attr "v8type" "extend,load1")
1172 (set_attr "type" "extend,load1")
1173 (set_attr "mode" "DI")]
1174 )
1175
1176 (define_insn "*zero_extendsidi2_aarch64"
1177 [(set (match_operand:DI 0 "register_operand" "=r,r")
1178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
1179 ""
1180 "@
1181 uxtw\t%0, %w1
1182 ldr\t%w0, %1"
1183 [(set_attr "v8type" "extend,load1")
1184 (set_attr "type" "extend,load1")
1185 (set_attr "mode" "DI")]
1186 )
1187
1188 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
1189 [(set (match_operand:GPI 0 "register_operand")
1190 (ANY_EXTEND:GPI (match_operand:SHORT 1 "nonimmediate_operand")))]
1191 ""
1192 )
1193
1194 (define_insn "*extend<SHORT:mode><GPI:mode>2_aarch64"
1195 [(set (match_operand:GPI 0 "register_operand" "=r,r")
1196 (sign_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))]
1197 ""
1198 "@
1199 sxt<SHORT:size>\t%<GPI:w>0, %w1
1200 ldrs<SHORT:size>\t%<GPI:w>0, %1"
1201 [(set_attr "v8type" "extend,load1")
1202 (set_attr "type" "extend,load1")
1203 (set_attr "mode" "<GPI:MODE>")]
1204 )
1205
1206 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
1207 [(set (match_operand:GPI 0 "register_operand" "=r,r,*w")
1208 (zero_extend:GPI (match_operand:SHORT 1 "nonimmediate_operand" "r,m,m")))]
1209 ""
1210 "@
1211 uxt<SHORT:size>\t%<GPI:w>0, %w1
1212 ldr<SHORT:size>\t%w0, %1
1213 ldr\t%<SHORT:size>0, %1"
1214 [(set_attr "v8type" "extend,load1,load1")
1215 (set_attr "type" "extend,load1,load1")
1216 (set_attr "mode" "<GPI:MODE>")]
1217 )
1218
1219 (define_expand "<optab>qihi2"
1220 [(set (match_operand:HI 0 "register_operand")
1221 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand")))]
1222 ""
1223 )
1224
1225 (define_insn "*<optab>qihi2_aarch64"
1226 [(set (match_operand:HI 0 "register_operand" "=r,r")
1227 (ANY_EXTEND:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1228 ""
1229 "@
1230 <su>xtb\t%w0, %w1
1231 <ldrxt>b\t%w0, %1"
1232 [(set_attr "v8type" "extend,load1")
1233 (set_attr "type" "extend,load1")
1234 (set_attr "mode" "HI")]
1235 )
1236
1237 ;; -------------------------------------------------------------------
1238 ;; Simple arithmetic
1239 ;; -------------------------------------------------------------------
1240
1241 (define_expand "add<mode>3"
1242 [(set
1243 (match_operand:GPI 0 "register_operand" "")
1244 (plus:GPI (match_operand:GPI 1 "register_operand" "")
1245 (match_operand:GPI 2 "aarch64_pluslong_operand" "")))]
1246 ""
1247 "
1248 if (! aarch64_plus_operand (operands[2], VOIDmode))
1249 {
1250 rtx subtarget = ((optimize && can_create_pseudo_p ())
1251 ? gen_reg_rtx (<MODE>mode) : operands[0]);
1252 HOST_WIDE_INT imm = INTVAL (operands[2]);
1253
1254 if (imm < 0)
1255 imm = -(-imm & ~0xfff);
1256 else
1257 imm &= ~0xfff;
1258
1259 emit_insn (gen_add<mode>3 (subtarget, operands[1], GEN_INT (imm)));
1260 operands[1] = subtarget;
1261 operands[2] = GEN_INT (INTVAL (operands[2]) - imm);
1262 }
1263 "
1264 )
1265
1266 (define_insn "*addsi3_aarch64"
1267 [(set
1268 (match_operand:SI 0 "register_operand" "=rk,rk,rk")
1269 (plus:SI
1270 (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1271 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J")))]
1272 ""
1273 "@
1274 add\\t%w0, %w1, %2
1275 add\\t%w0, %w1, %w2
1276 sub\\t%w0, %w1, #%n2"
1277 [(set_attr "v8type" "alu")
1278 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1279 (set_attr "mode" "SI")]
1280 )
1281
1282 ;; zero_extend version of above
1283 (define_insn "*addsi3_aarch64_uxtw"
1284 [(set
1285 (match_operand:DI 0 "register_operand" "=rk,rk,rk")
1286 (zero_extend:DI
1287 (plus:SI (match_operand:SI 1 "register_operand" "%rk,rk,rk")
1288 (match_operand:SI 2 "aarch64_plus_operand" "I,r,J"))))]
1289 ""
1290 "@
1291 add\\t%w0, %w1, %2
1292 add\\t%w0, %w1, %w2
1293 sub\\t%w0, %w1, #%n2"
1294 [(set_attr "v8type" "alu")
1295 (set_attr "type" "alu_imm,alu_reg,alu_imm")
1296 (set_attr "mode" "SI")]
1297 )
1298
1299 (define_insn "*adddi3_aarch64"
1300 [(set
1301 (match_operand:DI 0 "register_operand" "=rk,rk,rk,!w")
1302 (plus:DI
1303 (match_operand:DI 1 "register_operand" "%rk,rk,rk,!w")
1304 (match_operand:DI 2 "aarch64_plus_operand" "I,r,J,!w")))]
1305 ""
1306 "@
1307 add\\t%x0, %x1, %2
1308 add\\t%x0, %x1, %x2
1309 sub\\t%x0, %x1, #%n2
1310 add\\t%d0, %d1, %d2"
1311 [(set_attr "v8type" "alu")
1312 (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
1313 (set_attr "mode" "DI")
1314 (set_attr "simd" "*,*,*,yes")]
1315 )
1316
1317 (define_insn "*add<mode>3_compare0"
1318 [(set (reg:CC_NZ CC_REGNUM)
1319 (compare:CC_NZ
1320 (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
1321 (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
1322 (const_int 0)))
1323 (set (match_operand:GPI 0 "register_operand" "=r,r,r")
1324 (plus:GPI (match_dup 1) (match_dup 2)))]
1325 ""
1326 "@
1327 adds\\t%<w>0, %<w>1, %<w>2
1328 adds\\t%<w>0, %<w>1, %<w>2
1329 subs\\t%<w>0, %<w>1, #%n2"
1330 [(set_attr "v8type" "alus")
1331 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1332 (set_attr "mode" "<MODE>")]
1333 )
1334
1335 ;; zero_extend version of above
1336 (define_insn "*addsi3_compare0_uxtw"
1337 [(set (reg:CC_NZ CC_REGNUM)
1338 (compare:CC_NZ
1339 (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
1340 (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
1341 (const_int 0)))
1342 (set (match_operand:DI 0 "register_operand" "=r,r,r")
1343 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
1344 ""
1345 "@
1346 adds\\t%w0, %w1, %w2
1347 adds\\t%w0, %w1, %w2
1348 subs\\t%w0, %w1, #%n2"
1349 [(set_attr "v8type" "alus")
1350 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1351 (set_attr "mode" "SI")]
1352 )
1353
1354 (define_insn "*adds_mul_imm_<mode>"
1355 [(set (reg:CC_NZ CC_REGNUM)
1356 (compare:CC_NZ
1357 (plus:GPI (mult:GPI
1358 (match_operand:GPI 1 "register_operand" "r")
1359 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1360 (match_operand:GPI 3 "register_operand" "rk"))
1361 (const_int 0)))
1362 (set (match_operand:GPI 0 "register_operand" "=r")
1363 (plus:GPI (mult:GPI (match_dup 1) (match_dup 2))
1364 (match_dup 3)))]
1365 ""
1366 "adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1367 [(set_attr "v8type" "alus_shift")
1368 (set_attr "type" "alus_shift_imm")
1369 (set_attr "mode" "<MODE>")]
1370 )
1371
1372 (define_insn "*subs_mul_imm_<mode>"
1373 [(set (reg:CC_NZ CC_REGNUM)
1374 (compare:CC_NZ
1375 (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
1376 (mult:GPI
1377 (match_operand:GPI 2 "register_operand" "r")
1378 (match_operand:QI 3 "aarch64_pwr_2_<mode>" "n")))
1379 (const_int 0)))
1380 (set (match_operand:GPI 0 "register_operand" "=r")
1381 (minus:GPI (match_dup 1)
1382 (mult:GPI (match_dup 2) (match_dup 3))))]
1383 ""
1384 "subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
1385 [(set_attr "v8type" "alus_shift")
1386 (set_attr "type" "alus_shift_imm")
1387 (set_attr "mode" "<MODE>")]
1388 )
1389
1390 (define_insn "*adds_<optab><ALLX:mode>_<GPI:mode>"
1391 [(set (reg:CC_NZ CC_REGNUM)
1392 (compare:CC_NZ
1393 (plus:GPI
1394 (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1395 (match_operand:GPI 2 "register_operand" "r"))
1396 (const_int 0)))
1397 (set (match_operand:GPI 0 "register_operand" "=r")
1398 (plus:GPI (ANY_EXTEND:GPI (match_dup 1)) (match_dup 2)))]
1399 ""
1400 "adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1401 [(set_attr "v8type" "alus_ext")
1402 (set_attr "type" "alus_ext")
1403 (set_attr "mode" "<GPI:MODE>")]
1404 )
1405
1406 (define_insn "*subs_<optab><ALLX:mode>_<GPI:mode>"
1407 [(set (reg:CC_NZ CC_REGNUM)
1408 (compare:CC_NZ
1409 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1410 (ANY_EXTEND:GPI
1411 (match_operand:ALLX 2 "register_operand" "r")))
1412 (const_int 0)))
1413 (set (match_operand:GPI 0 "register_operand" "=r")
1414 (minus:GPI (match_dup 1) (ANY_EXTEND:GPI (match_dup 2))))]
1415 ""
1416 "subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1417 [(set_attr "v8type" "alus_ext")
1418 (set_attr "type" "alus_ext")
1419 (set_attr "mode" "<GPI:MODE>")]
1420 )
1421
1422 (define_insn "*adds_<optab><mode>_multp2"
1423 [(set (reg:CC_NZ CC_REGNUM)
1424 (compare:CC_NZ
1425 (plus:GPI (ANY_EXTRACT:GPI
1426 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1427 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1428 (match_operand 3 "const_int_operand" "n")
1429 (const_int 0))
1430 (match_operand:GPI 4 "register_operand" "r"))
1431 (const_int 0)))
1432 (set (match_operand:GPI 0 "register_operand" "=r")
1433 (plus:GPI (ANY_EXTRACT:GPI (mult:GPI (match_dup 1) (match_dup 2))
1434 (match_dup 3)
1435 (const_int 0))
1436 (match_dup 4)))]
1437 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1438 "adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1439 [(set_attr "v8type" "alus_ext")
1440 (set_attr "type" "alus_ext")
1441 (set_attr "mode" "<MODE>")]
1442 )
1443
1444 (define_insn "*subs_<optab><mode>_multp2"
1445 [(set (reg:CC_NZ CC_REGNUM)
1446 (compare:CC_NZ
1447 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1448 (ANY_EXTRACT:GPI
1449 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1450 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1451 (match_operand 3 "const_int_operand" "n")
1452 (const_int 0)))
1453 (const_int 0)))
1454 (set (match_operand:GPI 0 "register_operand" "=r")
1455 (minus:GPI (match_dup 4) (ANY_EXTRACT:GPI
1456 (mult:GPI (match_dup 1) (match_dup 2))
1457 (match_dup 3)
1458 (const_int 0))))]
1459 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1460 "subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1461 [(set_attr "v8type" "alus_ext")
1462 (set_attr "type" "alus_ext")
1463 (set_attr "mode" "<MODE>")]
1464 )
1465
1466 (define_insn "*add<mode>3nr_compare0"
1467 [(set (reg:CC_NZ CC_REGNUM)
1468 (compare:CC_NZ
1469 (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
1470 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
1471 (const_int 0)))]
1472 ""
1473 "@
1474 cmn\\t%<w>0, %<w>1
1475 cmn\\t%<w>0, %<w>1
1476 cmp\\t%<w>0, #%n1"
1477 [(set_attr "v8type" "alus")
1478 (set_attr "type" "alus_reg,alus_imm,alus_imm")
1479 (set_attr "mode" "<MODE>")]
1480 )
1481
1482 (define_insn "*compare_neg<mode>"
1483 [(set (reg:CC CC_REGNUM)
1484 (compare:CC
1485 (match_operand:GPI 0 "register_operand" "r")
1486 (neg:GPI (match_operand:GPI 1 "register_operand" "r"))))]
1487 ""
1488 "cmn\\t%<w>0, %<w>1"
1489 [(set_attr "v8type" "alus")
1490 (set_attr "type" "alus_reg")
1491 (set_attr "mode" "<MODE>")]
1492 )
1493
1494 (define_insn "*add_<shift>_<mode>"
1495 [(set (match_operand:GPI 0 "register_operand" "=rk")
1496 (plus:GPI (ASHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
1497 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
1498 (match_operand:GPI 3 "register_operand" "r")))]
1499 ""
1500 "add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1501 [(set_attr "v8type" "alu_shift")
1502 (set_attr "type" "alu_shift_imm")
1503 (set_attr "mode" "<MODE>")]
1504 )
1505
1506 ;; zero_extend version of above
1507 (define_insn "*add_<shift>_si_uxtw"
1508 [(set (match_operand:DI 0 "register_operand" "=rk")
1509 (zero_extend:DI
1510 (plus:SI (ASHIFT:SI (match_operand:SI 1 "register_operand" "r")
1511 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
1512 (match_operand:SI 3 "register_operand" "r"))))]
1513 ""
1514 "add\\t%w0, %w3, %w1, <shift> %2"
1515 [(set_attr "v8type" "alu_shift")
1516 (set_attr "type" "alu_shift_imm")
1517 (set_attr "mode" "SI")]
1518 )
1519
1520 (define_insn "*add_mul_imm_<mode>"
1521 [(set (match_operand:GPI 0 "register_operand" "=rk")
1522 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1523 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))
1524 (match_operand:GPI 3 "register_operand" "r")))]
1525 ""
1526 "add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1527 [(set_attr "v8type" "alu_shift")
1528 (set_attr "type" "alu_shift_imm")
1529 (set_attr "mode" "<MODE>")]
1530 )
1531
1532 (define_insn "*add_<optab><ALLX:mode>_<GPI:mode>"
1533 [(set (match_operand:GPI 0 "register_operand" "=rk")
1534 (plus:GPI (ANY_EXTEND:GPI (match_operand:ALLX 1 "register_operand" "r"))
1535 (match_operand:GPI 2 "register_operand" "r")))]
1536 ""
1537 "add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
1538 [(set_attr "v8type" "alu_ext")
1539 (set_attr "type" "alu_ext")
1540 (set_attr "mode" "<GPI:MODE>")]
1541 )
1542
1543 ;; zero_extend version of above
1544 (define_insn "*add_<optab><SHORT:mode>_si_uxtw"
1545 [(set (match_operand:DI 0 "register_operand" "=rk")
1546 (zero_extend:DI
1547 (plus:SI (ANY_EXTEND:SI (match_operand:SHORT 1 "register_operand" "r"))
1548 (match_operand:GPI 2 "register_operand" "r"))))]
1549 ""
1550 "add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
1551 [(set_attr "v8type" "alu_ext")
1552 (set_attr "type" "alu_ext")
1553 (set_attr "mode" "SI")]
1554 )
1555
1556 (define_insn "*add_<optab><ALLX:mode>_shft_<GPI:mode>"
1557 [(set (match_operand:GPI 0 "register_operand" "=rk")
1558 (plus:GPI (ashift:GPI (ANY_EXTEND:GPI
1559 (match_operand:ALLX 1 "register_operand" "r"))
1560 (match_operand 2 "aarch64_imm3" "Ui3"))
1561 (match_operand:GPI 3 "register_operand" "r")))]
1562 ""
1563 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
1564 [(set_attr "v8type" "alu_ext")
1565 (set_attr "type" "alu_ext")
1566 (set_attr "mode" "<GPI:MODE>")]
1567 )
1568
1569 ;; zero_extend version of above
1570 (define_insn "*add_<optab><SHORT:mode>_shft_si_uxtw"
1571 [(set (match_operand:DI 0 "register_operand" "=rk")
1572 (zero_extend:DI
1573 (plus:SI (ashift:SI (ANY_EXTEND:SI
1574 (match_operand:SHORT 1 "register_operand" "r"))
1575 (match_operand 2 "aarch64_imm3" "Ui3"))
1576 (match_operand:SI 3 "register_operand" "r"))))]
1577 ""
1578 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
1579 [(set_attr "v8type" "alu_ext")
1580 (set_attr "type" "alu_ext")
1581 (set_attr "mode" "SI")]
1582 )
1583
1584 (define_insn "*add_<optab><ALLX:mode>_mult_<GPI:mode>"
1585 [(set (match_operand:GPI 0 "register_operand" "=rk")
1586 (plus:GPI (mult:GPI (ANY_EXTEND:GPI
1587 (match_operand:ALLX 1 "register_operand" "r"))
1588 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1589 (match_operand:GPI 3 "register_operand" "r")))]
1590 ""
1591 "add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
1592 [(set_attr "v8type" "alu_ext")
1593 (set_attr "type" "alu_ext")
1594 (set_attr "mode" "<GPI:MODE>")]
1595 )
1596
1597 ;; zero_extend version of above
1598 (define_insn "*add_<optab><SHORT:mode>_mult_si_uxtw"
1599 [(set (match_operand:DI 0 "register_operand" "=rk")
1600 (zero_extend:DI (plus:SI (mult:SI (ANY_EXTEND:SI
1601 (match_operand:SHORT 1 "register_operand" "r"))
1602 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1603 (match_operand:SI 3 "register_operand" "r"))))]
1604 ""
1605 "add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
1606 [(set_attr "v8type" "alu_ext")
1607 (set_attr "type" "alu_ext")
1608 (set_attr "mode" "SI")]
1609 )
1610
1611 (define_insn "*add_<optab><mode>_multp2"
1612 [(set (match_operand:GPI 0 "register_operand" "=rk")
1613 (plus:GPI (ANY_EXTRACT:GPI
1614 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1615 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1616 (match_operand 3 "const_int_operand" "n")
1617 (const_int 0))
1618 (match_operand:GPI 4 "register_operand" "r")))]
1619 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1620 "add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1621 [(set_attr "v8type" "alu_ext")
1622 (set_attr "type" "alu_ext")
1623 (set_attr "mode" "<MODE>")]
1624 )
1625
1626 ;; zero_extend version of above
1627 (define_insn "*add_<optab>si_multp2_uxtw"
1628 [(set (match_operand:DI 0 "register_operand" "=rk")
1629 (zero_extend:DI
1630 (plus:SI (ANY_EXTRACT:SI
1631 (mult:SI (match_operand:SI 1 "register_operand" "r")
1632 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1633 (match_operand 3 "const_int_operand" "n")
1634 (const_int 0))
1635 (match_operand:SI 4 "register_operand" "r"))))]
1636 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
1637 "add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
1638 [(set_attr "v8type" "alu_ext")
1639 (set_attr "type" "alu_ext")
1640 (set_attr "mode" "SI")]
1641 )
1642
1643 (define_insn "*add<mode>3_carryin"
1644 [(set
1645 (match_operand:GPI 0 "register_operand" "=r")
1646 (plus:GPI (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1647 (plus:GPI
1648 (match_operand:GPI 1 "register_operand" "r")
1649 (match_operand:GPI 2 "register_operand" "r"))))]
1650 ""
1651 "adc\\t%<w>0, %<w>1, %<w>2"
1652 [(set_attr "v8type" "adc")
1653 (set_attr "type" "adc_reg")
1654 (set_attr "mode" "<MODE>")]
1655 )
1656
1657 ;; zero_extend version of above
1658 (define_insn "*addsi3_carryin_uxtw"
1659 [(set
1660 (match_operand:DI 0 "register_operand" "=r")
1661 (zero_extend:DI
1662 (plus:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1663 (plus:SI
1664 (match_operand:SI 1 "register_operand" "r")
1665 (match_operand:SI 2 "register_operand" "r")))))]
1666 ""
1667 "adc\\t%w0, %w1, %w2"
1668 [(set_attr "v8type" "adc")
1669 (set_attr "type" "adc_reg")
1670 (set_attr "mode" "SI")]
1671 )
1672
1673 (define_insn "*add<mode>3_carryin_alt1"
1674 [(set
1675 (match_operand:GPI 0 "register_operand" "=r")
1676 (plus:GPI (plus:GPI
1677 (match_operand:GPI 1 "register_operand" "r")
1678 (match_operand:GPI 2 "register_operand" "r"))
1679 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))))]
1680 ""
1681 "adc\\t%<w>0, %<w>1, %<w>2"
1682 [(set_attr "v8type" "adc")
1683 (set_attr "type" "adc_reg")
1684 (set_attr "mode" "<MODE>")]
1685 )
1686
1687 ;; zero_extend version of above
1688 (define_insn "*addsi3_carryin_alt1_uxtw"
1689 [(set
1690 (match_operand:DI 0 "register_operand" "=r")
1691 (zero_extend:DI
1692 (plus:SI (plus:SI
1693 (match_operand:SI 1 "register_operand" "r")
1694 (match_operand:SI 2 "register_operand" "r"))
1695 (geu:SI (reg:CC CC_REGNUM) (const_int 0)))))]
1696 ""
1697 "adc\\t%w0, %w1, %w2"
1698 [(set_attr "v8type" "adc")
1699 (set_attr "type" "adc_reg")
1700 (set_attr "mode" "SI")]
1701 )
1702
1703 (define_insn "*add<mode>3_carryin_alt2"
1704 [(set
1705 (match_operand:GPI 0 "register_operand" "=r")
1706 (plus:GPI (plus:GPI
1707 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1708 (match_operand:GPI 1 "register_operand" "r"))
1709 (match_operand:GPI 2 "register_operand" "r")))]
1710 ""
1711 "adc\\t%<w>0, %<w>1, %<w>2"
1712 [(set_attr "v8type" "adc")
1713 (set_attr "type" "adc_reg")
1714 (set_attr "mode" "<MODE>")]
1715 )
1716
1717 ;; zero_extend version of above
1718 (define_insn "*addsi3_carryin_alt2_uxtw"
1719 [(set
1720 (match_operand:DI 0 "register_operand" "=r")
1721 (zero_extend:DI
1722 (plus:SI (plus:SI
1723 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1724 (match_operand:SI 1 "register_operand" "r"))
1725 (match_operand:SI 2 "register_operand" "r"))))]
1726 ""
1727 "adc\\t%w0, %w1, %w2"
1728 [(set_attr "v8type" "adc")
1729 (set_attr "type" "adc_reg")
1730 (set_attr "mode" "SI")]
1731 )
1732
1733 (define_insn "*add<mode>3_carryin_alt3"
1734 [(set
1735 (match_operand:GPI 0 "register_operand" "=r")
1736 (plus:GPI (plus:GPI
1737 (geu:GPI (reg:CC CC_REGNUM) (const_int 0))
1738 (match_operand:GPI 2 "register_operand" "r"))
1739 (match_operand:GPI 1 "register_operand" "r")))]
1740 ""
1741 "adc\\t%<w>0, %<w>1, %<w>2"
1742 [(set_attr "v8type" "adc")
1743 (set_attr "type" "adc_reg")
1744 (set_attr "mode" "<MODE>")]
1745 )
1746
1747 ;; zero_extend version of above
1748 (define_insn "*addsi3_carryin_alt3_uxtw"
1749 [(set
1750 (match_operand:DI 0 "register_operand" "=r")
1751 (zero_extend:DI
1752 (plus:SI (plus:SI
1753 (geu:SI (reg:CC CC_REGNUM) (const_int 0))
1754 (match_operand:SI 2 "register_operand" "r"))
1755 (match_operand:SI 1 "register_operand" "r"))))]
1756 ""
1757 "adc\\t%w0, %w1, %w2"
1758 [(set_attr "v8type" "adc")
1759 (set_attr "type" "adc_reg")
1760 (set_attr "mode" "SI")]
1761 )
1762
1763 (define_insn "*add_uxt<mode>_multp2"
1764 [(set (match_operand:GPI 0 "register_operand" "=rk")
1765 (plus:GPI (and:GPI
1766 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1767 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1768 (match_operand 3 "const_int_operand" "n"))
1769 (match_operand:GPI 4 "register_operand" "r")))]
1770 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1771 "*
1772 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1773 INTVAL (operands[3])));
1774 return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
1775 [(set_attr "v8type" "alu_ext")
1776 (set_attr "type" "alu_ext")
1777 (set_attr "mode" "<MODE>")]
1778 )
1779
1780 ;; zero_extend version of above
1781 (define_insn "*add_uxtsi_multp2_uxtw"
1782 [(set (match_operand:DI 0 "register_operand" "=rk")
1783 (zero_extend:DI
1784 (plus:SI (and:SI
1785 (mult:SI (match_operand:SI 1 "register_operand" "r")
1786 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1787 (match_operand 3 "const_int_operand" "n"))
1788 (match_operand:SI 4 "register_operand" "r"))))]
1789 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])), INTVAL (operands[3])) != 0"
1790 "*
1791 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
1792 INTVAL (operands[3])));
1793 return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
1794 [(set_attr "v8type" "alu_ext")
1795 (set_attr "type" "alu_ext")
1796 (set_attr "mode" "SI")]
1797 )
1798
1799 (define_insn "subsi3"
1800 [(set (match_operand:SI 0 "register_operand" "=rk")
1801 (minus:SI (match_operand:SI 1 "register_operand" "r")
1802 (match_operand:SI 2 "register_operand" "r")))]
1803 ""
1804 "sub\\t%w0, %w1, %w2"
1805 [(set_attr "v8type" "alu")
1806 (set_attr "type" "alu_reg")
1807 (set_attr "mode" "SI")]
1808 )
1809
1810 ;; zero_extend version of above
1811 (define_insn "*subsi3_uxtw"
1812 [(set (match_operand:DI 0 "register_operand" "=rk")
1813 (zero_extend:DI
1814 (minus:SI (match_operand:SI 1 "register_operand" "r")
1815 (match_operand:SI 2 "register_operand" "r"))))]
1816 ""
1817 "sub\\t%w0, %w1, %w2"
1818 [(set_attr "v8type" "alu")
1819 (set_attr "type" "alu_reg")
1820 (set_attr "mode" "SI")]
1821 )
1822
1823 (define_insn "subdi3"
1824 [(set (match_operand:DI 0 "register_operand" "=rk,!w")
1825 (minus:DI (match_operand:DI 1 "register_operand" "r,!w")
1826 (match_operand:DI 2 "register_operand" "r,!w")))]
1827 ""
1828 "@
1829 sub\\t%x0, %x1, %x2
1830 sub\\t%d0, %d1, %d2"
1831 [(set_attr "v8type" "alu")
1832 (set_attr "type" "alu_reg")
1833 (set_attr "mode" "DI")
1834 (set_attr "simd" "*,yes")]
1835 )
1836
1837
1838 (define_insn "*sub<mode>3_compare0"
1839 [(set (reg:CC_NZ CC_REGNUM)
1840 (compare:CC_NZ (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1841 (match_operand:GPI 2 "register_operand" "r"))
1842 (const_int 0)))
1843 (set (match_operand:GPI 0 "register_operand" "=r")
1844 (minus:GPI (match_dup 1) (match_dup 2)))]
1845 ""
1846 "subs\\t%<w>0, %<w>1, %<w>2"
1847 [(set_attr "v8type" "alus")
1848 (set_attr "type" "alus_reg")
1849 (set_attr "mode" "<MODE>")]
1850 )
1851
1852 ;; zero_extend version of above
1853 (define_insn "*subsi3_compare0_uxtw"
1854 [(set (reg:CC_NZ CC_REGNUM)
1855 (compare:CC_NZ (minus:SI (match_operand:SI 1 "register_operand" "r")
1856 (match_operand:SI 2 "register_operand" "r"))
1857 (const_int 0)))
1858 (set (match_operand:DI 0 "register_operand" "=r")
1859 (zero_extend:DI (minus:SI (match_dup 1) (match_dup 2))))]
1860 ""
1861 "subs\\t%w0, %w1, %w2"
1862 [(set_attr "v8type" "alus")
1863 (set_attr "type" "alus_reg")
1864 (set_attr "mode" "SI")]
1865 )
1866
1867 (define_insn "*sub_<shift>_<mode>"
1868 [(set (match_operand:GPI 0 "register_operand" "=rk")
1869 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1870 (ASHIFT:GPI
1871 (match_operand:GPI 1 "register_operand" "r")
1872 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
1873 ""
1874 "sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
1875 [(set_attr "v8type" "alu_shift")
1876 (set_attr "type" "alu_shift_imm")
1877 (set_attr "mode" "<MODE>")]
1878 )
1879
1880 ;; zero_extend version of above
1881 (define_insn "*sub_<shift>_si_uxtw"
1882 [(set (match_operand:DI 0 "register_operand" "=rk")
1883 (zero_extend:DI
1884 (minus:SI (match_operand:SI 3 "register_operand" "r")
1885 (ASHIFT:SI
1886 (match_operand:SI 1 "register_operand" "r")
1887 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
1888 ""
1889 "sub\\t%w0, %w3, %w1, <shift> %2"
1890 [(set_attr "v8type" "alu_shift")
1891 (set_attr "type" "alu_shift_imm")
1892 (set_attr "mode" "SI")]
1893 )
1894
1895 (define_insn "*sub_mul_imm_<mode>"
1896 [(set (match_operand:GPI 0 "register_operand" "=rk")
1897 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
1898 (mult:GPI
1899 (match_operand:GPI 1 "register_operand" "r")
1900 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
1901 ""
1902 "sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
1903 [(set_attr "v8type" "alu_shift")
1904 (set_attr "type" "alu_shift_imm")
1905 (set_attr "mode" "<MODE>")]
1906 )
1907
1908 ;; zero_extend version of above
1909 (define_insn "*sub_mul_imm_si_uxtw"
1910 [(set (match_operand:DI 0 "register_operand" "=rk")
1911 (zero_extend:DI
1912 (minus:SI (match_operand:SI 3 "register_operand" "r")
1913 (mult:SI
1914 (match_operand:SI 1 "register_operand" "r")
1915 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
1916 ""
1917 "sub\\t%w0, %w3, %w1, lsl %p2"
1918 [(set_attr "v8type" "alu_shift")
1919 (set_attr "type" "alu_shift_imm")
1920 (set_attr "mode" "SI")]
1921 )
1922
1923 (define_insn "*sub_<optab><ALLX:mode>_<GPI:mode>"
1924 [(set (match_operand:GPI 0 "register_operand" "=rk")
1925 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1926 (ANY_EXTEND:GPI
1927 (match_operand:ALLX 2 "register_operand" "r"))))]
1928 ""
1929 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
1930 [(set_attr "v8type" "alu_ext")
1931 (set_attr "type" "alu_ext")
1932 (set_attr "mode" "<GPI:MODE>")]
1933 )
1934
1935 ;; zero_extend version of above
1936 (define_insn "*sub_<optab><SHORT:mode>_si_uxtw"
1937 [(set (match_operand:DI 0 "register_operand" "=rk")
1938 (zero_extend:DI
1939 (minus:SI (match_operand:SI 1 "register_operand" "r")
1940 (ANY_EXTEND:SI
1941 (match_operand:SHORT 2 "register_operand" "r")))))]
1942 ""
1943 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
1944 [(set_attr "v8type" "alu_ext")
1945 (set_attr "type" "alu_ext")
1946 (set_attr "mode" "SI")]
1947 )
1948
1949 (define_insn "*sub_<optab><ALLX:mode>_shft_<GPI:mode>"
1950 [(set (match_operand:GPI 0 "register_operand" "=rk")
1951 (minus:GPI (match_operand:GPI 1 "register_operand" "r")
1952 (ashift:GPI (ANY_EXTEND:GPI
1953 (match_operand:ALLX 2 "register_operand" "r"))
1954 (match_operand 3 "aarch64_imm3" "Ui3"))))]
1955 ""
1956 "sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
1957 [(set_attr "v8type" "alu_ext")
1958 (set_attr "type" "alu_ext")
1959 (set_attr "mode" "<GPI:MODE>")]
1960 )
1961
1962 ;; zero_extend version of above
1963 (define_insn "*sub_<optab><SHORT:mode>_shft_si_uxtw"
1964 [(set (match_operand:DI 0 "register_operand" "=rk")
1965 (zero_extend:DI
1966 (minus:SI (match_operand:SI 1 "register_operand" "r")
1967 (ashift:SI (ANY_EXTEND:SI
1968 (match_operand:SHORT 2 "register_operand" "r"))
1969 (match_operand 3 "aarch64_imm3" "Ui3")))))]
1970 ""
1971 "sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
1972 [(set_attr "v8type" "alu_ext")
1973 (set_attr "type" "alu_ext")
1974 (set_attr "mode" "SI")]
1975 )
1976
1977 (define_insn "*sub_<optab><mode>_multp2"
1978 [(set (match_operand:GPI 0 "register_operand" "=rk")
1979 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
1980 (ANY_EXTRACT:GPI
1981 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
1982 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
1983 (match_operand 3 "const_int_operand" "n")
1984 (const_int 0))))]
1985 "aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
1986 "sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
1987 [(set_attr "v8type" "alu_ext")
1988 (set_attr "type" "alu_ext")
1989 (set_attr "mode" "<MODE>")]
1990 )
1991
1992 ;; zero_extend version of above
1993 (define_insn "*sub_<optab>si_multp2_uxtw"
1994 [(set (match_operand:DI 0 "register_operand" "=rk")
1995 (zero_extend:DI
1996 (minus:SI (match_operand:SI 4 "register_operand" "r")
1997 (ANY_EXTRACT:SI
1998 (mult:SI (match_operand:SI 1 "register_operand" "r")
1999 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2000 (match_operand 3 "const_int_operand" "n")
2001 (const_int 0)))))]
2002 "aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
2003 "sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
2004 [(set_attr "v8type" "alu_ext")
2005 (set_attr "type" "alu_ext")
2006 (set_attr "mode" "SI")]
2007 )
2008
2009 (define_insn "*sub<mode>3_carryin"
2010 [(set
2011 (match_operand:GPI 0 "register_operand" "=r")
2012 (minus:GPI (minus:GPI
2013 (match_operand:GPI 1 "register_operand" "r")
2014 (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2015 (match_operand:GPI 2 "register_operand" "r")))]
2016 ""
2017 "sbc\\t%<w>0, %<w>1, %<w>2"
2018 [(set_attr "v8type" "adc")
2019 (set_attr "type" "adc_reg")
2020 (set_attr "mode" "<MODE>")]
2021 )
2022
2023 ;; zero_extend version of the above
2024 (define_insn "*subsi3_carryin_uxtw"
2025 [(set
2026 (match_operand:DI 0 "register_operand" "=r")
2027 (zero_extend:DI
2028 (minus:SI (minus:SI
2029 (match_operand:SI 1 "register_operand" "r")
2030 (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2031 (match_operand:SI 2 "register_operand" "r"))))]
2032 ""
2033 "sbc\\t%w0, %w1, %w2"
2034 [(set_attr "v8type" "adc")
2035 (set_attr "type" "adc_reg")
2036 (set_attr "mode" "SI")]
2037 )
2038
2039 (define_insn "*sub_uxt<mode>_multp2"
2040 [(set (match_operand:GPI 0 "register_operand" "=rk")
2041 (minus:GPI (match_operand:GPI 4 "register_operand" "r")
2042 (and:GPI
2043 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2044 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2045 (match_operand 3 "const_int_operand" "n"))))]
2046 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2047 "*
2048 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2049 INTVAL (operands[3])));
2050 return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
2051 [(set_attr "v8type" "alu_ext")
2052 (set_attr "type" "alu_ext")
2053 (set_attr "mode" "<MODE>")]
2054 )
2055
2056 ;; zero_extend version of above
2057 (define_insn "*sub_uxtsi_multp2_uxtw"
2058 [(set (match_operand:DI 0 "register_operand" "=rk")
2059 (zero_extend:DI
2060 (minus:SI (match_operand:SI 4 "register_operand" "r")
2061 (and:SI
2062 (mult:SI (match_operand:SI 1 "register_operand" "r")
2063 (match_operand 2 "aarch64_pwr_imm3" "Up3"))
2064 (match_operand 3 "const_int_operand" "n")))))]
2065 "aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),INTVAL (operands[3])) != 0"
2066 "*
2067 operands[3] = GEN_INT (aarch64_uxt_size (exact_log2 (INTVAL (operands[2])),
2068 INTVAL (operands[3])));
2069 return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
2070 [(set_attr "v8type" "alu_ext")
2071 (set_attr "type" "alu_ext")
2072 (set_attr "mode" "SI")]
2073 )
2074
2075 (define_insn_and_split "absdi2"
2076 [(set (match_operand:DI 0 "register_operand" "=r,w")
2077 (abs:DI (match_operand:DI 1 "register_operand" "r,w")))
2078 (clobber (match_scratch:DI 2 "=&r,X"))]
2079 ""
2080 "@
2081 #
2082 abs\\t%d0, %d1"
2083 "reload_completed
2084 && GP_REGNUM_P (REGNO (operands[0]))
2085 && GP_REGNUM_P (REGNO (operands[1]))"
2086 [(const_int 0)]
2087 {
2088 emit_insn (gen_rtx_SET (VOIDmode, operands[2],
2089 gen_rtx_XOR (DImode,
2090 gen_rtx_ASHIFTRT (DImode,
2091 operands[1],
2092 GEN_INT (63)),
2093 operands[1])));
2094 emit_insn (gen_rtx_SET (VOIDmode,
2095 operands[0],
2096 gen_rtx_MINUS (DImode,
2097 operands[2],
2098 gen_rtx_ASHIFTRT (DImode,
2099 operands[1],
2100 GEN_INT (63)))));
2101 DONE;
2102 }
2103 [(set_attr "v8type" "alu")
2104 (set_attr "type" "alu_reg")
2105 (set_attr "mode" "DI")]
2106 )
2107
2108 (define_insn "neg<mode>2"
2109 [(set (match_operand:GPI 0 "register_operand" "=r,w")
2110 (neg:GPI (match_operand:GPI 1 "register_operand" "r,w")))]
2111 ""
2112 "@
2113 neg\\t%<w>0, %<w>1
2114 neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
2115 [(set_attr "v8type" "alu")
2116 (set_attr "type" "alu_reg")
2117 (set_attr "simd_type" "*,simd_negabs")
2118 (set_attr "simd" "*,yes")
2119 (set_attr "mode" "<MODE>")
2120 (set_attr "simd_mode" "<MODE>")]
2121 )
2122
2123 ;; zero_extend version of above
2124 (define_insn "*negsi2_uxtw"
2125 [(set (match_operand:DI 0 "register_operand" "=r")
2126 (zero_extend:DI (neg:SI (match_operand:SI 1 "register_operand" "r"))))]
2127 ""
2128 "neg\\t%w0, %w1"
2129 [(set_attr "v8type" "alu")
2130 (set_attr "type" "alu_reg")
2131 (set_attr "mode" "SI")]
2132 )
2133
2134 (define_insn "*ngc<mode>"
2135 [(set (match_operand:GPI 0 "register_operand" "=r")
2136 (minus:GPI (neg:GPI (ltu:GPI (reg:CC CC_REGNUM) (const_int 0)))
2137 (match_operand:GPI 1 "register_operand" "r")))]
2138 ""
2139 "ngc\\t%<w>0, %<w>1"
2140 [(set_attr "v8type" "adc")
2141 (set_attr "type" "adc_reg")
2142 (set_attr "mode" "<MODE>")]
2143 )
2144
2145 (define_insn "*ngcsi_uxtw"
2146 [(set (match_operand:DI 0 "register_operand" "=r")
2147 (zero_extend:DI
2148 (minus:SI (neg:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)))
2149 (match_operand:SI 1 "register_operand" "r"))))]
2150 ""
2151 "ngc\\t%w0, %w1"
2152 [(set_attr "v8type" "adc")
2153 (set_attr "type" "adc_reg")
2154 (set_attr "mode" "SI")]
2155 )
2156
2157 (define_insn "*neg<mode>2_compare0"
2158 [(set (reg:CC_NZ CC_REGNUM)
2159 (compare:CC_NZ (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2160 (const_int 0)))
2161 (set (match_operand:GPI 0 "register_operand" "=r")
2162 (neg:GPI (match_dup 1)))]
2163 ""
2164 "negs\\t%<w>0, %<w>1"
2165 [(set_attr "v8type" "alus")
2166 (set_attr "type" "alus_reg")
2167 (set_attr "mode" "<MODE>")]
2168 )
2169
2170 ;; zero_extend version of above
2171 (define_insn "*negsi2_compare0_uxtw"
2172 [(set (reg:CC_NZ CC_REGNUM)
2173 (compare:CC_NZ (neg:SI (match_operand:SI 1 "register_operand" "r"))
2174 (const_int 0)))
2175 (set (match_operand:DI 0 "register_operand" "=r")
2176 (zero_extend:DI (neg:SI (match_dup 1))))]
2177 ""
2178 "negs\\t%w0, %w1"
2179 [(set_attr "v8type" "alus")
2180 (set_attr "type" "alus_reg")
2181 (set_attr "mode" "SI")]
2182 )
2183
2184 (define_insn "*neg_<shift><mode>3_compare0"
2185 [(set (reg:CC_NZ CC_REGNUM)
2186 (compare:CC_NZ
2187 (neg:GPI (ASHIFT:GPI
2188 (match_operand:GPI 1 "register_operand" "r")
2189 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2190 (const_int 0)))
2191 (set (match_operand:GPI 0 "register_operand" "=r")
2192 (neg:GPI (ASHIFT:GPI (match_dup 1) (match_dup 2))))]
2193 ""
2194 "negs\\t%<w>0, %<w>1, <shift> %2"
2195 [(set_attr "v8type" "alus_shift")
2196 (set_attr "type" "alus_shift_imm")
2197 (set_attr "mode" "<MODE>")]
2198 )
2199
2200 (define_insn "*neg_<shift>_<mode>2"
2201 [(set (match_operand:GPI 0 "register_operand" "=r")
2202 (neg:GPI (ASHIFT:GPI
2203 (match_operand:GPI 1 "register_operand" "r")
2204 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2205 ""
2206 "neg\\t%<w>0, %<w>1, <shift> %2"
2207 [(set_attr "v8type" "alu_shift")
2208 (set_attr "type" "alu_shift_imm")
2209 (set_attr "mode" "<MODE>")]
2210 )
2211
2212 ;; zero_extend version of above
2213 (define_insn "*neg_<shift>_si2_uxtw"
2214 [(set (match_operand:DI 0 "register_operand" "=r")
2215 (zero_extend:DI
2216 (neg:SI (ASHIFT:SI
2217 (match_operand:SI 1 "register_operand" "r")
2218 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))))]
2219 ""
2220 "neg\\t%w0, %w1, <shift> %2"
2221 [(set_attr "v8type" "alu_shift")
2222 (set_attr "type" "alu_shift_imm")
2223 (set_attr "mode" "SI")]
2224 )
2225
2226 (define_insn "*neg_mul_imm_<mode>2"
2227 [(set (match_operand:GPI 0 "register_operand" "=r")
2228 (neg:GPI (mult:GPI
2229 (match_operand:GPI 1 "register_operand" "r")
2230 (match_operand:QI 2 "aarch64_pwr_2_<mode>" "n"))))]
2231 ""
2232 "neg\\t%<w>0, %<w>1, lsl %p2"
2233 [(set_attr "v8type" "alu_shift")
2234 (set_attr "type" "alu_shift_imm")
2235 (set_attr "mode" "<MODE>")]
2236 )
2237
2238 ;; zero_extend version of above
2239 (define_insn "*neg_mul_imm_si2_uxtw"
2240 [(set (match_operand:DI 0 "register_operand" "=r")
2241 (zero_extend:DI
2242 (neg:SI (mult:SI
2243 (match_operand:SI 1 "register_operand" "r")
2244 (match_operand:QI 2 "aarch64_pwr_2_si" "n")))))]
2245 ""
2246 "neg\\t%w0, %w1, lsl %p2"
2247 [(set_attr "v8type" "alu_shift")
2248 (set_attr "type" "alu_shift_imm")
2249 (set_attr "mode" "SI")]
2250 )
2251
2252 (define_insn "mul<mode>3"
2253 [(set (match_operand:GPI 0 "register_operand" "=r")
2254 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2255 (match_operand:GPI 2 "register_operand" "r")))]
2256 ""
2257 "mul\\t%<w>0, %<w>1, %<w>2"
2258 [(set_attr "v8type" "mult")
2259 (set_attr "type" "mul")
2260 (set_attr "mode" "<MODE>")]
2261 )
2262
2263 ;; zero_extend version of above
2264 (define_insn "*mulsi3_uxtw"
2265 [(set (match_operand:DI 0 "register_operand" "=r")
2266 (zero_extend:DI
2267 (mult:SI (match_operand:SI 1 "register_operand" "r")
2268 (match_operand:SI 2 "register_operand" "r"))))]
2269 ""
2270 "mul\\t%w0, %w1, %w2"
2271 [(set_attr "v8type" "mult")
2272 (set_attr "type" "mul")
2273 (set_attr "mode" "SI")]
2274 )
2275
2276 (define_insn "*madd<mode>"
2277 [(set (match_operand:GPI 0 "register_operand" "=r")
2278 (plus:GPI (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2279 (match_operand:GPI 2 "register_operand" "r"))
2280 (match_operand:GPI 3 "register_operand" "r")))]
2281 ""
2282 "madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
2283 [(set_attr "v8type" "madd")
2284 (set_attr "type" "mul")
2285 (set_attr "mode" "<MODE>")]
2286 )
2287
2288 ;; zero_extend version of above
2289 (define_insn "*maddsi_uxtw"
2290 [(set (match_operand:DI 0 "register_operand" "=r")
2291 (zero_extend:DI
2292 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
2293 (match_operand:SI 2 "register_operand" "r"))
2294 (match_operand:SI 3 "register_operand" "r"))))]
2295 ""
2296 "madd\\t%w0, %w1, %w2, %w3"
2297 [(set_attr "v8type" "madd")
2298 (set_attr "type" "mul")
2299 (set_attr "mode" "SI")]
2300 )
2301
2302 (define_insn "*msub<mode>"
2303 [(set (match_operand:GPI 0 "register_operand" "=r")
2304 (minus:GPI (match_operand:GPI 3 "register_operand" "r")
2305 (mult:GPI (match_operand:GPI 1 "register_operand" "r")
2306 (match_operand:GPI 2 "register_operand" "r"))))]
2307
2308 ""
2309 "msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
2310 [(set_attr "v8type" "madd")
2311 (set_attr "type" "mul")
2312 (set_attr "mode" "<MODE>")]
2313 )
2314
2315 ;; zero_extend version of above
2316 (define_insn "*msubsi_uxtw"
2317 [(set (match_operand:DI 0 "register_operand" "=r")
2318 (zero_extend:DI
2319 (minus:SI (match_operand:SI 3 "register_operand" "r")
2320 (mult:SI (match_operand:SI 1 "register_operand" "r")
2321 (match_operand:SI 2 "register_operand" "r")))))]
2322
2323 ""
2324 "msub\\t%w0, %w1, %w2, %w3"
2325 [(set_attr "v8type" "madd")
2326 (set_attr "type" "mul")
2327 (set_attr "mode" "SI")]
2328 )
2329
2330 (define_insn "*mul<mode>_neg"
2331 [(set (match_operand:GPI 0 "register_operand" "=r")
2332 (mult:GPI (neg:GPI (match_operand:GPI 1 "register_operand" "r"))
2333 (match_operand:GPI 2 "register_operand" "r")))]
2334
2335 ""
2336 "mneg\\t%<w>0, %<w>1, %<w>2"
2337 [(set_attr "v8type" "mult")
2338 (set_attr "type" "mul")
2339 (set_attr "mode" "<MODE>")]
2340 )
2341
2342 ;; zero_extend version of above
2343 (define_insn "*mulsi_neg_uxtw"
2344 [(set (match_operand:DI 0 "register_operand" "=r")
2345 (zero_extend:DI
2346 (mult:SI (neg:SI (match_operand:SI 1 "register_operand" "r"))
2347 (match_operand:SI 2 "register_operand" "r"))))]
2348
2349 ""
2350 "mneg\\t%w0, %w1, %w2"
2351 [(set_attr "v8type" "mult")
2352 (set_attr "type" "mul")
2353 (set_attr "mode" "SI")]
2354 )
2355
2356 (define_insn "<su_optab>mulsidi3"
2357 [(set (match_operand:DI 0 "register_operand" "=r")
2358 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2359 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2360 ""
2361 "<su>mull\\t%0, %w1, %w2"
2362 [(set_attr "v8type" "mull")
2363 (set_attr "type" "<su>mull")
2364 (set_attr "mode" "DI")]
2365 )
2366
2367 (define_insn "<su_optab>maddsidi4"
2368 [(set (match_operand:DI 0 "register_operand" "=r")
2369 (plus:DI (mult:DI
2370 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2371 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
2372 (match_operand:DI 3 "register_operand" "r")))]
2373 ""
2374 "<su>maddl\\t%0, %w1, %w2, %3"
2375 [(set_attr "v8type" "maddl")
2376 (set_attr "type" "mul")
2377 (set_attr "mode" "DI")]
2378 )
2379
2380 (define_insn "<su_optab>msubsidi4"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (minus:DI
2383 (match_operand:DI 3 "register_operand" "r")
2384 (mult:DI (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
2385 (ANY_EXTEND:DI
2386 (match_operand:SI 2 "register_operand" "r")))))]
2387 ""
2388 "<su>msubl\\t%0, %w1, %w2, %3"
2389 [(set_attr "v8type" "maddl")
2390 (set_attr "type" "mul")
2391 (set_attr "mode" "DI")]
2392 )
2393
2394 (define_insn "*<su_optab>mulsidi_neg"
2395 [(set (match_operand:DI 0 "register_operand" "=r")
2396 (mult:DI (neg:DI
2397 (ANY_EXTEND:DI (match_operand:SI 1 "register_operand" "r")))
2398 (ANY_EXTEND:DI (match_operand:SI 2 "register_operand" "r"))))]
2399 ""
2400 "<su>mnegl\\t%0, %w1, %w2"
2401 [(set_attr "v8type" "mull")
2402 (set_attr "type" "<su>mull")
2403 (set_attr "mode" "DI")]
2404 )
2405
2406 (define_insn "<su>muldi3_highpart"
2407 [(set (match_operand:DI 0 "register_operand" "=r")
2408 (truncate:DI
2409 (lshiftrt:TI
2410 (mult:TI
2411 (ANY_EXTEND:TI (match_operand:DI 1 "register_operand" "r"))
2412 (ANY_EXTEND:TI (match_operand:DI 2 "register_operand" "r")))
2413 (const_int 64))))]
2414 ""
2415 "<su>mulh\\t%0, %1, %2"
2416 [(set_attr "v8type" "mulh")
2417 (set_attr "type" "<su>mull")
2418 (set_attr "mode" "DI")]
2419 )
2420
2421 (define_insn "<su_optab>div<mode>3"
2422 [(set (match_operand:GPI 0 "register_operand" "=r")
2423 (ANY_DIV:GPI (match_operand:GPI 1 "register_operand" "r")
2424 (match_operand:GPI 2 "register_operand" "r")))]
2425 ""
2426 "<su>div\\t%<w>0, %<w>1, %<w>2"
2427 [(set_attr "v8type" "<su>div")
2428 (set_attr "type" "<su>div")
2429 (set_attr "mode" "<MODE>")]
2430 )
2431
2432 ;; zero_extend version of above
2433 (define_insn "*<su_optab>divsi3_uxtw"
2434 [(set (match_operand:DI 0 "register_operand" "=r")
2435 (zero_extend:DI
2436 (ANY_DIV:SI (match_operand:SI 1 "register_operand" "r")
2437 (match_operand:SI 2 "register_operand" "r"))))]
2438 ""
2439 "<su>div\\t%w0, %w1, %w2"
2440 [(set_attr "v8type" "<su>div")
2441 (set_attr "type" "<su>div")
2442 (set_attr "mode" "SI")]
2443 )
2444
2445 ;; -------------------------------------------------------------------
2446 ;; Comparison insns
2447 ;; -------------------------------------------------------------------
2448
2449 (define_insn "*cmp<mode>"
2450 [(set (reg:CC CC_REGNUM)
2451 (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
2452 (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
2453 ""
2454 "@
2455 cmp\\t%<w>0, %<w>1
2456 cmp\\t%<w>0, %<w>1
2457 cmn\\t%<w>0, #%n1"
2458 [(set_attr "v8type" "alus")
2459 (set_attr "type" "alus_reg,alus_imm,alus_imm")
2460 (set_attr "mode" "<MODE>")]
2461 )
2462
2463 (define_insn "*cmp<mode>"
2464 [(set (reg:CCFP CC_REGNUM)
2465 (compare:CCFP (match_operand:GPF 0 "register_operand" "w,w")
2466 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2467 "TARGET_FLOAT"
2468 "@
2469 fcmp\\t%<s>0, #0.0
2470 fcmp\\t%<s>0, %<s>1"
2471 [(set_attr "v8type" "fcmp")
2472 (set_attr "type" "fcmp<s>")
2473 (set_attr "mode" "<MODE>")]
2474 )
2475
2476 (define_insn "*cmpe<mode>"
2477 [(set (reg:CCFPE CC_REGNUM)
2478 (compare:CCFPE (match_operand:GPF 0 "register_operand" "w,w")
2479 (match_operand:GPF 1 "aarch64_fp_compare_operand" "Y,w")))]
2480 "TARGET_FLOAT"
2481 "@
2482 fcmpe\\t%<s>0, #0.0
2483 fcmpe\\t%<s>0, %<s>1"
2484 [(set_attr "v8type" "fcmp")
2485 (set_attr "type" "fcmp<s>")
2486 (set_attr "mode" "<MODE>")]
2487 )
2488
2489 (define_insn "*cmp_swp_<shift>_reg<mode>"
2490 [(set (reg:CC_SWP CC_REGNUM)
2491 (compare:CC_SWP (ASHIFT:GPI
2492 (match_operand:GPI 0 "register_operand" "r")
2493 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
2494 (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")))]
2495 ""
2496 "cmp\\t%<w>2, %<w>0, <shift> %1"
2497 [(set_attr "v8type" "alus_shift")
2498 (set_attr "type" "alus_shift_imm")
2499 (set_attr "mode" "<MODE>")]
2500 )
2501
2502 (define_insn "*cmp_swp_<optab><ALLX:mode>_reg<GPI:mode>"
2503 [(set (reg:CC_SWP CC_REGNUM)
2504 (compare:CC_SWP (ANY_EXTEND:GPI
2505 (match_operand:ALLX 0 "register_operand" "r"))
2506 (match_operand:GPI 1 "register_operand" "r")))]
2507 ""
2508 "cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
2509 [(set_attr "v8type" "alus_ext")
2510 (set_attr "type" "alus_ext")
2511 (set_attr "mode" "<GPI:MODE>")]
2512 )
2513
2514 (define_insn "*cmp_swp_<optab><ALLX:mode>_shft_<GPI:mode>"
2515 [(set (reg:CC_SWP CC_REGNUM)
2516 (compare:CC_SWP (ashift:GPI
2517 (ANY_EXTEND:GPI
2518 (match_operand:ALLX 0 "register_operand" "r"))
2519 (match_operand 1 "aarch64_imm3" "Ui3"))
2520 (match_operand:GPI 2 "register_operand" "r")))]
2521 ""
2522 "cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
2523 [(set_attr "v8type" "alus_ext")
2524 (set_attr "type" "alus_ext")
2525 (set_attr "mode" "<GPI:MODE>")]
2526 )
2527
2528 ;; -------------------------------------------------------------------
2529 ;; Store-flag and conditional select insns
2530 ;; -------------------------------------------------------------------
2531
2532 (define_expand "cstore<mode>4"
2533 [(set (match_operand:SI 0 "register_operand" "")
2534 (match_operator:SI 1 "aarch64_comparison_operator"
2535 [(match_operand:GPI 2 "register_operand" "")
2536 (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
2537 ""
2538 "
2539 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2540 operands[3]);
2541 operands[3] = const0_rtx;
2542 "
2543 )
2544
2545 (define_expand "cstore<mode>4"
2546 [(set (match_operand:SI 0 "register_operand" "")
2547 (match_operator:SI 1 "aarch64_comparison_operator"
2548 [(match_operand:GPF 2 "register_operand" "")
2549 (match_operand:GPF 3 "register_operand" "")]))]
2550 ""
2551 "
2552 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2553 operands[3]);
2554 operands[3] = const0_rtx;
2555 "
2556 )
2557
2558 (define_insn "*cstore<mode>_insn"
2559 [(set (match_operand:ALLI 0 "register_operand" "=r")
2560 (match_operator:ALLI 1 "aarch64_comparison_operator"
2561 [(match_operand 2 "cc_register" "") (const_int 0)]))]
2562 ""
2563 "cset\\t%<w>0, %m1"
2564 [(set_attr "v8type" "csel")
2565 (set_attr "type" "csel")
2566 (set_attr "mode" "<MODE>")]
2567 )
2568
2569 ;; zero_extend version of the above
2570 (define_insn "*cstoresi_insn_uxtw"
2571 [(set (match_operand:DI 0 "register_operand" "=r")
2572 (zero_extend:DI
2573 (match_operator:SI 1 "aarch64_comparison_operator"
2574 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2575 ""
2576 "cset\\t%w0, %m1"
2577 [(set_attr "v8type" "csel")
2578 (set_attr "type" "csel")
2579 (set_attr "mode" "SI")]
2580 )
2581
2582 (define_insn "cstore<mode>_neg"
2583 [(set (match_operand:ALLI 0 "register_operand" "=r")
2584 (neg:ALLI (match_operator:ALLI 1 "aarch64_comparison_operator"
2585 [(match_operand 2 "cc_register" "") (const_int 0)])))]
2586 ""
2587 "csetm\\t%<w>0, %m1"
2588 [(set_attr "v8type" "csel")
2589 (set_attr "type" "csel")
2590 (set_attr "mode" "<MODE>")]
2591 )
2592
2593 ;; zero_extend version of the above
2594 (define_insn "*cstoresi_neg_uxtw"
2595 [(set (match_operand:DI 0 "register_operand" "=r")
2596 (zero_extend:DI
2597 (neg:SI (match_operator:SI 1 "aarch64_comparison_operator"
2598 [(match_operand 2 "cc_register" "") (const_int 0)]))))]
2599 ""
2600 "csetm\\t%w0, %m1"
2601 [(set_attr "v8type" "csel")
2602 (set_attr "type" "csel")
2603 (set_attr "mode" "SI")]
2604 )
2605
2606 (define_expand "cmov<mode>6"
2607 [(set (match_operand:GPI 0 "register_operand" "")
2608 (if_then_else:GPI
2609 (match_operator 1 "aarch64_comparison_operator"
2610 [(match_operand:GPI 2 "register_operand" "")
2611 (match_operand:GPI 3 "aarch64_plus_operand" "")])
2612 (match_operand:GPI 4 "register_operand" "")
2613 (match_operand:GPI 5 "register_operand" "")))]
2614 ""
2615 "
2616 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2617 operands[3]);
2618 operands[3] = const0_rtx;
2619 "
2620 )
2621
2622 (define_expand "cmov<mode>6"
2623 [(set (match_operand:GPF 0 "register_operand" "")
2624 (if_then_else:GPF
2625 (match_operator 1 "aarch64_comparison_operator"
2626 [(match_operand:GPF 2 "register_operand" "")
2627 (match_operand:GPF 3 "register_operand" "")])
2628 (match_operand:GPF 4 "register_operand" "")
2629 (match_operand:GPF 5 "register_operand" "")))]
2630 ""
2631 "
2632 operands[2] = aarch64_gen_compare_reg (GET_CODE (operands[1]), operands[2],
2633 operands[3]);
2634 operands[3] = const0_rtx;
2635 "
2636 )
2637
2638 (define_insn "*cmov<mode>_insn"
2639 [(set (match_operand:ALLI 0 "register_operand" "=r,r,r,r,r,r,r")
2640 (if_then_else:ALLI
2641 (match_operator 1 "aarch64_comparison_operator"
2642 [(match_operand 2 "cc_register" "") (const_int 0)])
2643 (match_operand:ALLI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2644 (match_operand:ALLI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1")))]
2645 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2646 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2647 ;; Final two alternatives should be unreachable, but included for completeness
2648 "@
2649 csel\\t%<w>0, %<w>3, %<w>4, %m1
2650 csinv\\t%<w>0, %<w>3, <w>zr, %m1
2651 csinv\\t%<w>0, %<w>4, <w>zr, %M1
2652 csinc\\t%<w>0, %<w>3, <w>zr, %m1
2653 csinc\\t%<w>0, %<w>4, <w>zr, %M1
2654 mov\\t%<w>0, -1
2655 mov\\t%<w>0, 1"
2656 [(set_attr "v8type" "csel")
2657 (set_attr "type" "csel")
2658 (set_attr "mode" "<MODE>")]
2659 )
2660
2661 ;; zero_extend version of above
2662 (define_insn "*cmovsi_insn_uxtw"
2663 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r,r")
2664 (zero_extend:DI
2665 (if_then_else:SI
2666 (match_operator 1 "aarch64_comparison_operator"
2667 [(match_operand 2 "cc_register" "") (const_int 0)])
2668 (match_operand:SI 3 "aarch64_reg_zero_or_m1_or_1" "rZ,rZ,UsM,rZ,Ui1,UsM,Ui1")
2669 (match_operand:SI 4 "aarch64_reg_zero_or_m1_or_1" "rZ,UsM,rZ,Ui1,rZ,UsM,Ui1"))))]
2670 "!((operands[3] == const1_rtx && operands[4] == constm1_rtx)
2671 || (operands[3] == constm1_rtx && operands[4] == const1_rtx))"
2672 ;; Final two alternatives should be unreachable, but included for completeness
2673 "@
2674 csel\\t%w0, %w3, %w4, %m1
2675 csinv\\t%w0, %w3, wzr, %m1
2676 csinv\\t%w0, %w4, wzr, %M1
2677 csinc\\t%w0, %w3, wzr, %m1
2678 csinc\\t%w0, %w4, wzr, %M1
2679 mov\\t%w0, -1
2680 mov\\t%w0, 1"
2681 [(set_attr "v8type" "csel")
2682 (set_attr "type" "csel")
2683 (set_attr "mode" "SI")]
2684 )
2685
2686 (define_insn "*cmov<mode>_insn"
2687 [(set (match_operand:GPF 0 "register_operand" "=w")
2688 (if_then_else:GPF
2689 (match_operator 1 "aarch64_comparison_operator"
2690 [(match_operand 2 "cc_register" "") (const_int 0)])
2691 (match_operand:GPF 3 "register_operand" "w")
2692 (match_operand:GPF 4 "register_operand" "w")))]
2693 "TARGET_FLOAT"
2694 "fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
2695 [(set_attr "v8type" "fcsel")
2696 (set_attr "type" "fcsel")
2697 (set_attr "mode" "<MODE>")]
2698 )
2699
2700 (define_expand "mov<mode>cc"
2701 [(set (match_operand:ALLI 0 "register_operand" "")
2702 (if_then_else:ALLI (match_operand 1 "aarch64_comparison_operator" "")
2703 (match_operand:ALLI 2 "register_operand" "")
2704 (match_operand:ALLI 3 "register_operand" "")))]
2705 ""
2706 {
2707 rtx ccreg;
2708 enum rtx_code code = GET_CODE (operands[1]);
2709
2710 if (code == UNEQ || code == LTGT)
2711 FAIL;
2712
2713 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2714 XEXP (operands[1], 1));
2715 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2716 }
2717 )
2718
2719 (define_expand "mov<GPF:mode><GPI:mode>cc"
2720 [(set (match_operand:GPI 0 "register_operand" "")
2721 (if_then_else:GPI (match_operand 1 "aarch64_comparison_operator" "")
2722 (match_operand:GPF 2 "register_operand" "")
2723 (match_operand:GPF 3 "register_operand" "")))]
2724 ""
2725 {
2726 rtx ccreg;
2727 enum rtx_code code = GET_CODE (operands[1]);
2728
2729 if (code == UNEQ || code == LTGT)
2730 FAIL;
2731
2732 ccreg = aarch64_gen_compare_reg (code, XEXP (operands[1], 0),
2733 XEXP (operands[1], 1));
2734 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
2735 }
2736 )
2737
2738 (define_insn "*csinc2<mode>_insn"
2739 [(set (match_operand:GPI 0 "register_operand" "=r")
2740 (plus:GPI (match_operator:GPI 2 "aarch64_comparison_operator"
2741 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
2742 (match_operand:GPI 1 "register_operand" "r")))]
2743 ""
2744 "csinc\\t%<w>0, %<w>1, %<w>1, %M2"
2745 [(set_attr "v8type" "csel")
2746 (set_attr "type" "csel")
2747 (set_attr "mode" "<MODE>")])
2748
2749 (define_insn "csinc3<mode>_insn"
2750 [(set (match_operand:GPI 0 "register_operand" "=r")
2751 (if_then_else:GPI
2752 (match_operator:GPI 1 "aarch64_comparison_operator"
2753 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2754 (plus:GPI (match_operand:GPI 3 "register_operand" "r")
2755 (const_int 1))
2756 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2757 ""
2758 "csinc\\t%<w>0, %<w>4, %<w>3, %M1"
2759 [(set_attr "v8type" "csel")
2760 (set_attr "type" "csel")
2761 (set_attr "mode" "<MODE>")]
2762 )
2763
2764 (define_insn "*csinv3<mode>_insn"
2765 [(set (match_operand:GPI 0 "register_operand" "=r")
2766 (if_then_else:GPI
2767 (match_operator:GPI 1 "aarch64_comparison_operator"
2768 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2769 (not:GPI (match_operand:GPI 3 "register_operand" "r"))
2770 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2771 ""
2772 "csinv\\t%<w>0, %<w>4, %<w>3, %M1"
2773 [(set_attr "v8type" "csel")
2774 (set_attr "type" "csel")
2775 (set_attr "mode" "<MODE>")])
2776
2777 (define_insn "*csneg3<mode>_insn"
2778 [(set (match_operand:GPI 0 "register_operand" "=r")
2779 (if_then_else:GPI
2780 (match_operator:GPI 1 "aarch64_comparison_operator"
2781 [(match_operand:CC 2 "cc_register" "") (const_int 0)])
2782 (neg:GPI (match_operand:GPI 3 "register_operand" "r"))
2783 (match_operand:GPI 4 "aarch64_reg_or_zero" "rZ")))]
2784 ""
2785 "csneg\\t%<w>0, %<w>4, %<w>3, %M1"
2786 [(set_attr "v8type" "csel")
2787 (set_attr "type" "csel")
2788 (set_attr "mode" "<MODE>")])
2789
2790 ;; -------------------------------------------------------------------
2791 ;; Logical operations
2792 ;; -------------------------------------------------------------------
2793
2794 (define_insn "<optab><mode>3"
2795 [(set (match_operand:GPI 0 "register_operand" "=r,rk")
2796 (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2797 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>")))]
2798 ""
2799 "<logical>\\t%<w>0, %<w>1, %<w>2"
2800 [(set_attr "v8type" "logic,logic_imm")
2801 (set_attr "type" "logic_reg,logic_imm")
2802 (set_attr "mode" "<MODE>")])
2803
2804 ;; zero_extend version of above
2805 (define_insn "*<optab>si3_uxtw"
2806 [(set (match_operand:DI 0 "register_operand" "=r,rk")
2807 (zero_extend:DI
2808 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
2809 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
2810 ""
2811 "<logical>\\t%w0, %w1, %w2"
2812 [(set_attr "v8type" "logic,logic_imm")
2813 (set_attr "type" "logic_reg,logic_imm")
2814 (set_attr "mode" "SI")])
2815
2816 (define_insn "*and<mode>3_compare0"
2817 [(set (reg:CC_NZ CC_REGNUM)
2818 (compare:CC_NZ
2819 (and:GPI (match_operand:GPI 1 "register_operand" "%r,r")
2820 (match_operand:GPI 2 "aarch64_logical_operand" "r,<lconst>"))
2821 (const_int 0)))
2822 (set (match_operand:GPI 0 "register_operand" "=r,r")
2823 (and:GPI (match_dup 1) (match_dup 2)))]
2824 ""
2825 "ands\\t%<w>0, %<w>1, %<w>2"
2826 [(set_attr "v8type" "logics,logics_imm")
2827 (set_attr "type" "logics_reg,logics_imm")
2828 (set_attr "mode" "<MODE>")]
2829 )
2830
2831 ;; zero_extend version of above
2832 (define_insn "*andsi3_compare0_uxtw"
2833 [(set (reg:CC_NZ CC_REGNUM)
2834 (compare:CC_NZ
2835 (and:SI (match_operand:SI 1 "register_operand" "%r,r")
2836 (match_operand:SI 2 "aarch64_logical_operand" "r,K"))
2837 (const_int 0)))
2838 (set (match_operand:DI 0 "register_operand" "=r,r")
2839 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
2840 ""
2841 "ands\\t%w0, %w1, %w2"
2842 [(set_attr "v8type" "logics,logics_imm")
2843 (set_attr "type" "logics_reg,logics_imm")
2844 (set_attr "mode" "SI")]
2845 )
2846
2847 (define_insn "*and_<SHIFT:optab><mode>3_compare0"
2848 [(set (reg:CC_NZ CC_REGNUM)
2849 (compare:CC_NZ
2850 (and:GPI (SHIFT:GPI
2851 (match_operand:GPI 1 "register_operand" "r")
2852 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2853 (match_operand:GPI 3 "register_operand" "r"))
2854 (const_int 0)))
2855 (set (match_operand:GPI 0 "register_operand" "=r")
2856 (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))]
2857 ""
2858 "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2859 [(set_attr "v8type" "logics_shift")
2860 (set_attr "type" "logics_shift_imm")
2861 (set_attr "mode" "<MODE>")]
2862 )
2863
2864 ;; zero_extend version of above
2865 (define_insn "*and_<SHIFT:optab>si3_compare0_uxtw"
2866 [(set (reg:CC_NZ CC_REGNUM)
2867 (compare:CC_NZ
2868 (and:SI (SHIFT:SI
2869 (match_operand:SI 1 "register_operand" "r")
2870 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2871 (match_operand:SI 3 "register_operand" "r"))
2872 (const_int 0)))
2873 (set (match_operand:DI 0 "register_operand" "=r")
2874 (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2))
2875 (match_dup 3))))]
2876 ""
2877 "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2878 [(set_attr "v8type" "logics_shift")
2879 (set_attr "type" "logics_shift_imm")
2880 (set_attr "mode" "SI")]
2881 )
2882
2883 (define_insn "*<LOGICAL:optab>_<SHIFT:optab><mode>3"
2884 [(set (match_operand:GPI 0 "register_operand" "=r")
2885 (LOGICAL:GPI (SHIFT:GPI
2886 (match_operand:GPI 1 "register_operand" "r")
2887 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))
2888 (match_operand:GPI 3 "register_operand" "r")))]
2889 ""
2890 "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2891 [(set_attr "v8type" "logic_shift")
2892 (set_attr "type" "logic_shift_imm")
2893 (set_attr "mode" "<MODE>")])
2894
2895 ;; zero_extend version of above
2896 (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw"
2897 [(set (match_operand:DI 0 "register_operand" "=r")
2898 (zero_extend:DI
2899 (LOGICAL:SI (SHIFT:SI
2900 (match_operand:SI 1 "register_operand" "r")
2901 (match_operand:QI 2 "aarch64_shift_imm_si" "n"))
2902 (match_operand:SI 3 "register_operand" "r"))))]
2903 ""
2904 "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
2905 [(set_attr "v8type" "logic_shift")
2906 (set_attr "type" "logic_shift_imm")
2907 (set_attr "mode" "SI")])
2908
2909 (define_insn "one_cmpl<mode>2"
2910 [(set (match_operand:GPI 0 "register_operand" "=r")
2911 (not:GPI (match_operand:GPI 1 "register_operand" "r")))]
2912 ""
2913 "mvn\\t%<w>0, %<w>1"
2914 [(set_attr "v8type" "logic")
2915 (set_attr "type" "logic_reg")
2916 (set_attr "mode" "<MODE>")])
2917
2918 (define_insn "*one_cmpl_<optab><mode>2"
2919 [(set (match_operand:GPI 0 "register_operand" "=r")
2920 (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r")
2921 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))]
2922 ""
2923 "mvn\\t%<w>0, %<w>1, <shift> %2"
2924 [(set_attr "v8type" "logic_shift")
2925 (set_attr "type" "logic_shift_imm")
2926 (set_attr "mode" "<MODE>")])
2927
2928 (define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
2929 [(set (match_operand:GPI 0 "register_operand" "=r")
2930 (LOGICAL:GPI (not:GPI
2931 (match_operand:GPI 1 "register_operand" "r"))
2932 (match_operand:GPI 2 "register_operand" "r")))]
2933 ""
2934 "<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
2935 [(set_attr "v8type" "logic")
2936 (set_attr "type" "logic_reg")
2937 (set_attr "mode" "<MODE>")])
2938
2939 (define_insn "*and_one_cmpl<mode>3_compare0"
2940 [(set (reg:CC_NZ CC_REGNUM)
2941 (compare:CC_NZ
2942 (and:GPI (not:GPI
2943 (match_operand:GPI 1 "register_operand" "r"))
2944 (match_operand:GPI 2 "register_operand" "r"))
2945 (const_int 0)))
2946 (set (match_operand:GPI 0 "register_operand" "=r")
2947 (and:GPI (not:GPI (match_dup 1)) (match_dup 2)))]
2948 ""
2949 "bics\\t%<w>0, %<w>2, %<w>1"
2950 [(set_attr "v8type" "logics")
2951 (set_attr "type" "logics_reg")
2952 (set_attr "mode" "<MODE>")])
2953
2954 ;; zero_extend version of above
2955 (define_insn "*and_one_cmplsi3_compare0_uxtw"
2956 [(set (reg:CC_NZ CC_REGNUM)
2957 (compare:CC_NZ
2958 (and:SI (not:SI
2959 (match_operand:SI 1 "register_operand" "r"))
2960 (match_operand:SI 2 "register_operand" "r"))
2961 (const_int 0)))
2962 (set (match_operand:DI 0 "register_operand" "=r")
2963 (zero_extend:DI (and:SI (not:SI (match_dup 1)) (match_dup 2))))]
2964 ""
2965 "bics\\t%w0, %w2, %w1"
2966 [(set_attr "v8type" "logics")
2967 (set_attr "type" "logics_reg")
2968 (set_attr "mode" "SI")])
2969
2970 (define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
2971 [(set (match_operand:GPI 0 "register_operand" "=r")
2972 (LOGICAL:GPI (not:GPI
2973 (SHIFT:GPI
2974 (match_operand:GPI 1 "register_operand" "r")
2975 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2976 (match_operand:GPI 3 "register_operand" "r")))]
2977 ""
2978 "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2979 [(set_attr "v8type" "logic_shift")
2980 (set_attr "type" "logics_shift_imm")
2981 (set_attr "mode" "<MODE>")])
2982
2983 (define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
2984 [(set (reg:CC_NZ CC_REGNUM)
2985 (compare:CC_NZ
2986 (and:GPI (not:GPI
2987 (SHIFT:GPI
2988 (match_operand:GPI 1 "register_operand" "r")
2989 (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")))
2990 (match_operand:GPI 3 "register_operand" "r"))
2991 (const_int 0)))
2992 (set (match_operand:GPI 0 "register_operand" "=r")
2993 (and:GPI (not:GPI
2994 (SHIFT:GPI
2995 (match_dup 1) (match_dup 2))) (match_dup 3)))]
2996 ""
2997 "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
2998 [(set_attr "v8type" "logics_shift")
2999 (set_attr "type" "logics_shift_imm")
3000 (set_attr "mode" "<MODE>")])
3001
3002 ;; zero_extend version of above
3003 (define_insn "*and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw"
3004 [(set (reg:CC_NZ CC_REGNUM)
3005 (compare:CC_NZ
3006 (and:SI (not:SI
3007 (SHIFT:SI
3008 (match_operand:SI 1 "register_operand" "r")
3009 (match_operand:QI 2 "aarch64_shift_imm_si" "n")))
3010 (match_operand:SI 3 "register_operand" "r"))
3011 (const_int 0)))
3012 (set (match_operand:DI 0 "register_operand" "=r")
3013 (zero_extend:DI (and:SI
3014 (not:SI
3015 (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))]
3016 ""
3017 "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
3018 [(set_attr "v8type" "logics_shift")
3019 (set_attr "type" "logics_shift_imm")
3020 (set_attr "mode" "SI")])
3021
3022 (define_insn "clz<mode>2"
3023 [(set (match_operand:GPI 0 "register_operand" "=r")
3024 (clz:GPI (match_operand:GPI 1 "register_operand" "r")))]
3025 ""
3026 "clz\\t%<w>0, %<w>1"
3027 [(set_attr "v8type" "clz")
3028 (set_attr "type" "clz")
3029 (set_attr "mode" "<MODE>")])
3030
3031 (define_expand "ffs<mode>2"
3032 [(match_operand:GPI 0 "register_operand")
3033 (match_operand:GPI 1 "register_operand")]
3034 ""
3035 {
3036 rtx ccreg = aarch64_gen_compare_reg (EQ, operands[1], const0_rtx);
3037 rtx x = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
3038
3039 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3040 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3041 emit_insn (gen_csinc3<mode>_insn (operands[0], x, ccreg, operands[0], const0_rtx));
3042 DONE;
3043 }
3044 )
3045
3046 (define_insn "clrsb<mode>2"
3047 [(set (match_operand:GPI 0 "register_operand" "=r")
3048 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_CLS))]
3049 ""
3050 "cls\\t%<w>0, %<w>1"
3051 [(set_attr "v8type" "clz")
3052 (set_attr "type" "clz")
3053 (set_attr "mode" "<MODE>")])
3054
3055 (define_insn "rbit<mode>2"
3056 [(set (match_operand:GPI 0 "register_operand" "=r")
3057 (unspec:GPI [(match_operand:GPI 1 "register_operand" "r")] UNSPEC_RBIT))]
3058 ""
3059 "rbit\\t%<w>0, %<w>1"
3060 [(set_attr "v8type" "rbit")
3061 (set_attr "type" "rbit")
3062 (set_attr "mode" "<MODE>")])
3063
3064 (define_expand "ctz<mode>2"
3065 [(match_operand:GPI 0 "register_operand")
3066 (match_operand:GPI 1 "register_operand")]
3067 ""
3068 {
3069 emit_insn (gen_rbit<mode>2 (operands[0], operands[1]));
3070 emit_insn (gen_clz<mode>2 (operands[0], operands[0]));
3071 DONE;
3072 }
3073 )
3074
3075 (define_insn "*and<mode>3nr_compare0"
3076 [(set (reg:CC_NZ CC_REGNUM)
3077 (compare:CC_NZ
3078 (and:GPI (match_operand:GPI 0 "register_operand" "%r,r")
3079 (match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
3080 (const_int 0)))]
3081 ""
3082 "tst\\t%<w>0, %<w>1"
3083 [(set_attr "v8type" "logics")
3084 (set_attr "type" "logics_reg")
3085 (set_attr "mode" "<MODE>")])
3086
3087 (define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
3088 [(set (reg:CC_NZ CC_REGNUM)
3089 (compare:CC_NZ
3090 (and:GPI (SHIFT:GPI
3091 (match_operand:GPI 0 "register_operand" "r")
3092 (match_operand:QI 1 "aarch64_shift_imm_<mode>" "n"))
3093 (match_operand:GPI 2 "register_operand" "r"))
3094 (const_int 0)))]
3095 ""
3096 "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
3097 [(set_attr "v8type" "logics_shift")
3098 (set_attr "type" "logics_shift_imm")
3099 (set_attr "mode" "<MODE>")])
3100
3101 ;; -------------------------------------------------------------------
3102 ;; Shifts
3103 ;; -------------------------------------------------------------------
3104
3105 (define_expand "<optab><mode>3"
3106 [(set (match_operand:GPI 0 "register_operand")
3107 (ASHIFT:GPI (match_operand:GPI 1 "register_operand")
3108 (match_operand:QI 2 "nonmemory_operand")))]
3109 ""
3110 {
3111 if (CONST_INT_P (operands[2]))
3112 {
3113 operands[2] = GEN_INT (INTVAL (operands[2])
3114 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3115
3116 if (operands[2] == const0_rtx)
3117 {
3118 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3119 DONE;
3120 }
3121 }
3122 }
3123 )
3124
3125 (define_expand "ashl<mode>3"
3126 [(set (match_operand:SHORT 0 "register_operand")
3127 (ashift:SHORT (match_operand:SHORT 1 "register_operand")
3128 (match_operand:QI 2 "nonmemory_operand")))]
3129 ""
3130 {
3131 if (CONST_INT_P (operands[2]))
3132 {
3133 operands[2] = GEN_INT (INTVAL (operands[2])
3134 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3135
3136 if (operands[2] == const0_rtx)
3137 {
3138 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3139 DONE;
3140 }
3141 }
3142 }
3143 )
3144
3145 (define_expand "rotr<mode>3"
3146 [(set (match_operand:GPI 0 "register_operand")
3147 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3148 (match_operand:QI 2 "nonmemory_operand")))]
3149 ""
3150 {
3151 if (CONST_INT_P (operands[2]))
3152 {
3153 operands[2] = GEN_INT (INTVAL (operands[2])
3154 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3155
3156 if (operands[2] == const0_rtx)
3157 {
3158 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3159 DONE;
3160 }
3161 }
3162 }
3163 )
3164
3165 (define_expand "rotl<mode>3"
3166 [(set (match_operand:GPI 0 "register_operand")
3167 (rotatert:GPI (match_operand:GPI 1 "register_operand")
3168 (match_operand:QI 2 "nonmemory_operand")))]
3169 ""
3170 {
3171 /* (SZ - cnt) % SZ == -cnt % SZ */
3172 if (CONST_INT_P (operands[2]))
3173 {
3174 operands[2] = GEN_INT ((-INTVAL (operands[2]))
3175 & (GET_MODE_BITSIZE (<MODE>mode) - 1));
3176 if (operands[2] == const0_rtx)
3177 {
3178 emit_insn (gen_mov<mode> (operands[0], operands[1]));
3179 DONE;
3180 }
3181 }
3182 else
3183 operands[2] = expand_simple_unop (QImode, NEG, operands[2],
3184 NULL_RTX, 1);
3185 }
3186 )
3187
3188 ;; Logical left shift using SISD or Integer instruction
3189 (define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
3190 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3191 (ashift:GPI
3192 (match_operand:GPI 1 "register_operand" "w,w,r")
3193 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3194 ""
3195 "@
3196 shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3197 ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
3198 lsl\t%<w>0, %<w>1, %<w>2"
3199 [(set_attr "simd" "yes,yes,no")
3200 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3201 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3202 (set_attr "v8type" "*,*,shift")
3203 (set_attr "type" "*,*,shift_reg")
3204 (set_attr "mode" "*,*,<MODE>")]
3205 )
3206
3207 ;; Logical right shift using SISD or Integer instruction
3208 (define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
3209 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3210 (lshiftrt:GPI
3211 (match_operand:GPI 1 "register_operand" "w,w,r")
3212 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
3213 ""
3214 "@
3215 ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3216 #
3217 lsr\t%<w>0, %<w>1, %<w>2"
3218 [(set_attr "simd" "yes,yes,no")
3219 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3220 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3221 (set_attr "v8type" "*,*,shift")
3222 (set_attr "type" "*,*,shift_reg")
3223 (set_attr "mode" "*,*,<MODE>")]
3224 )
3225
3226 (define_split
3227 [(set (match_operand:DI 0 "aarch64_simd_register")
3228 (lshiftrt:DI
3229 (match_operand:DI 1 "aarch64_simd_register")
3230 (match_operand:QI 2 "aarch64_simd_register")))]
3231 "TARGET_SIMD && reload_completed"
3232 [(set (match_dup 2)
3233 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3234 (set (match_dup 0)
3235 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
3236 ""
3237 )
3238
3239 (define_split
3240 [(set (match_operand:SI 0 "aarch64_simd_register")
3241 (lshiftrt:SI
3242 (match_operand:SI 1 "aarch64_simd_register")
3243 (match_operand:QI 2 "aarch64_simd_register")))]
3244 "TARGET_SIMD && reload_completed"
3245 [(set (match_dup 2)
3246 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3247 (set (match_dup 0)
3248 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
3249 ""
3250 )
3251
3252 ;; Arithmetic right shift using SISD or Integer instruction
3253 (define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
3254 [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
3255 (ashiftrt:GPI
3256 (match_operand:GPI 1 "register_operand" "w,w,r")
3257 (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
3258 ""
3259 "@
3260 sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
3261 #
3262 asr\t%<w>0, %<w>1, %<w>2"
3263 [(set_attr "simd" "yes,yes,no")
3264 (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
3265 (set_attr "simd_mode" "<MODE>,<MODE>,*")
3266 (set_attr "v8type" "*,*,shift")
3267 (set_attr "type" "*,*,shift_reg")
3268 (set_attr "mode" "*,*,<MODE>")]
3269 )
3270
3271 (define_split
3272 [(set (match_operand:DI 0 "aarch64_simd_register")
3273 (ashiftrt:DI
3274 (match_operand:DI 1 "aarch64_simd_register")
3275 (match_operand:QI 2 "aarch64_simd_register")))]
3276 "TARGET_SIMD && reload_completed"
3277 [(set (match_dup 2)
3278 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3279 (set (match_dup 0)
3280 (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
3281 ""
3282 )
3283
3284 (define_split
3285 [(set (match_operand:SI 0 "aarch64_simd_register")
3286 (ashiftrt:SI
3287 (match_operand:SI 1 "aarch64_simd_register")
3288 (match_operand:QI 2 "aarch64_simd_register")))]
3289 "TARGET_SIMD && reload_completed"
3290 [(set (match_dup 2)
3291 (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
3292 (set (match_dup 0)
3293 (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
3294 ""
3295 )
3296
3297 (define_insn "*aarch64_sisd_ushl"
3298 [(set (match_operand:DI 0 "register_operand" "=w")
3299 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3300 (match_operand:QI 2 "register_operand" "w")]
3301 UNSPEC_SISD_USHL))]
3302 "TARGET_SIMD"
3303 "ushl\t%d0, %d1, %d2"
3304 [(set_attr "simd" "yes")
3305 (set_attr "simd_type" "simd_shift")
3306 (set_attr "simd_mode" "DI")]
3307 )
3308
3309 (define_insn "*aarch64_ushl_2s"
3310 [(set (match_operand:SI 0 "register_operand" "=w")
3311 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3312 (match_operand:QI 2 "register_operand" "w")]
3313 UNSPEC_USHL_2S))]
3314 "TARGET_SIMD"
3315 "ushl\t%0.2s, %1.2s, %2.2s"
3316 [(set_attr "simd" "yes")
3317 (set_attr "simd_type" "simd_shift")
3318 (set_attr "simd_mode" "DI")]
3319 )
3320
3321 (define_insn "*aarch64_sisd_sshl"
3322 [(set (match_operand:DI 0 "register_operand" "=w")
3323 (unspec:DI [(match_operand:DI 1 "register_operand" "w")
3324 (match_operand:QI 2 "register_operand" "w")]
3325 UNSPEC_SISD_SSHL))]
3326 "TARGET_SIMD"
3327 "sshl\t%d0, %d1, %d2"
3328 [(set_attr "simd" "yes")
3329 (set_attr "simd_type" "simd_shift")
3330 (set_attr "simd_mode" "DI")]
3331 )
3332
3333 (define_insn "*aarch64_sshl_2s"
3334 [(set (match_operand:SI 0 "register_operand" "=w")
3335 (unspec:SI [(match_operand:SI 1 "register_operand" "w")
3336 (match_operand:QI 2 "register_operand" "w")]
3337 UNSPEC_SSHL_2S))]
3338 "TARGET_SIMD"
3339 "sshl\t%0.2s, %1.2s, %2.2s"
3340 [(set_attr "simd" "yes")
3341 (set_attr "simd_type" "simd_shift")
3342 (set_attr "simd_mode" "DI")]
3343 )
3344
3345 (define_insn "*aarch64_sisd_neg_qi"
3346 [(set (match_operand:QI 0 "register_operand" "=w")
3347 (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
3348 UNSPEC_SISD_NEG))]
3349 "TARGET_SIMD"
3350 "neg\t%d0, %d1"
3351 [(set_attr "simd" "yes")
3352 (set_attr "simd_type" "simd_negabs")
3353 (set_attr "simd_mode" "QI")]
3354 )
3355
3356 ;; Rotate right
3357 (define_insn "*ror<mode>3_insn"
3358 [(set (match_operand:GPI 0 "register_operand" "=r")
3359 (rotatert:GPI
3360 (match_operand:GPI 1 "register_operand" "r")
3361 (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
3362 ""
3363 "ror\\t%<w>0, %<w>1, %<w>2"
3364 [(set_attr "v8type" "shift")
3365 (set_attr "type" "shift_reg")
3366 (set_attr "mode" "<MODE>")]
3367 )
3368
3369 ;; zero_extend version of above
3370 (define_insn "*<optab>si3_insn_uxtw"
3371 [(set (match_operand:DI 0 "register_operand" "=r")
3372 (zero_extend:DI (SHIFT:SI
3373 (match_operand:SI 1 "register_operand" "r")
3374 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
3375 ""
3376 "<shift>\\t%w0, %w1, %w2"
3377 [(set_attr "v8type" "shift")
3378 (set_attr "type" "shift_reg")
3379 (set_attr "mode" "SI")]
3380 )
3381
3382 (define_insn "*ashl<mode>3_insn"
3383 [(set (match_operand:SHORT 0 "register_operand" "=r")
3384 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3385 (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
3386 ""
3387 "lsl\\t%<w>0, %<w>1, %<w>2"
3388 [(set_attr "v8type" "shift")
3389 (set_attr "type" "shift_reg")
3390 (set_attr "mode" "<MODE>")]
3391 )
3392
3393 (define_insn "*<optab><mode>3_insn"
3394 [(set (match_operand:SHORT 0 "register_operand" "=r")
3395 (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
3396 (match_operand 2 "const_int_operand" "n")))]
3397 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3398 {
3399 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3400 return "<bfshift>\t%w0, %w1, %2, %3";
3401 }
3402 [(set_attr "v8type" "bfm")
3403 (set_attr "type" "bfm")
3404 (set_attr "mode" "<MODE>")]
3405 )
3406
3407 (define_insn "*extr<mode>5_insn"
3408 [(set (match_operand:GPI 0 "register_operand" "=r")
3409 (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3410 (match_operand 3 "const_int_operand" "n"))
3411 (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r")
3412 (match_operand 4 "const_int_operand" "n"))))]
3413 "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
3414 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
3415 "extr\\t%<w>0, %<w>1, %<w>2, %4"
3416 [(set_attr "v8type" "shift")
3417 (set_attr "type" "shift_imm")
3418 (set_attr "mode" "<MODE>")]
3419 )
3420
3421 ;; zero_extend version of the above
3422 (define_insn "*extrsi5_insn_uxtw"
3423 [(set (match_operand:DI 0 "register_operand" "=r")
3424 (zero_extend:DI
3425 (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
3426 (match_operand 3 "const_int_operand" "n"))
3427 (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
3428 (match_operand 4 "const_int_operand" "n")))))]
3429 "UINTVAL (operands[3]) < 32 &&
3430 (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
3431 "extr\\t%w0, %w1, %w2, %4"
3432 [(set_attr "v8type" "shift")
3433 (set_attr "type" "shift_imm")
3434 (set_attr "mode" "SI")]
3435 )
3436
3437 (define_insn "*ror<mode>3_insn"
3438 [(set (match_operand:GPI 0 "register_operand" "=r")
3439 (rotate:GPI (match_operand:GPI 1 "register_operand" "r")
3440 (match_operand 2 "const_int_operand" "n")))]
3441 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
3442 {
3443 operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2]));
3444 return "ror\\t%<w>0, %<w>1, %3";
3445 }
3446 [(set_attr "v8type" "shift")
3447 (set_attr "type" "shift_imm")
3448 (set_attr "mode" "<MODE>")]
3449 )
3450
3451 ;; zero_extend version of the above
3452 (define_insn "*rorsi3_insn_uxtw"
3453 [(set (match_operand:DI 0 "register_operand" "=r")
3454 (zero_extend:DI
3455 (rotate:SI (match_operand:SI 1 "register_operand" "r")
3456 (match_operand 2 "const_int_operand" "n"))))]
3457 "UINTVAL (operands[2]) < 32"
3458 {
3459 operands[3] = GEN_INT (32 - UINTVAL (operands[2]));
3460 return "ror\\t%w0, %w1, %3";
3461 }
3462 [(set_attr "v8type" "shift")
3463 (set_attr "type" "shift_imm")
3464 (set_attr "mode" "SI")]
3465 )
3466
3467 (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>"
3468 [(set (match_operand:GPI 0 "register_operand" "=r")
3469 (ANY_EXTEND:GPI
3470 (ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
3471 (match_operand 2 "const_int_operand" "n"))))]
3472 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3473 {
3474 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3475 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3476 }
3477 [(set_attr "v8type" "bfm")
3478 (set_attr "type" "bfm")
3479 (set_attr "mode" "<GPI:MODE>")]
3480 )
3481
3482 (define_insn "*zero_extend<GPI:mode>_lshr<SHORT:mode>"
3483 [(set (match_operand:GPI 0 "register_operand" "=r")
3484 (zero_extend:GPI
3485 (lshiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3486 (match_operand 2 "const_int_operand" "n"))))]
3487 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3488 {
3489 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3490 return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3491 }
3492 [(set_attr "v8type" "bfm")
3493 (set_attr "type" "bfm")
3494 (set_attr "mode" "<GPI:MODE>")]
3495 )
3496
3497 (define_insn "*extend<GPI:mode>_ashr<SHORT:mode>"
3498 [(set (match_operand:GPI 0 "register_operand" "=r")
3499 (sign_extend:GPI
3500 (ashiftrt:SHORT (match_operand:SHORT 1 "register_operand" "r")
3501 (match_operand 2 "const_int_operand" "n"))))]
3502 "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<SHORT:MODE>mode)"
3503 {
3504 operands[3] = GEN_INT (<SHORT:sizen> - UINTVAL (operands[2]));
3505 return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3506 }
3507 [(set_attr "v8type" "bfm")
3508 (set_attr "type" "bfm")
3509 (set_attr "mode" "<GPI:MODE>")]
3510 )
3511
3512 ;; -------------------------------------------------------------------
3513 ;; Bitfields
3514 ;; -------------------------------------------------------------------
3515
3516 (define_expand "<optab>"
3517 [(set (match_operand:DI 0 "register_operand" "=r")
3518 (ANY_EXTRACT:DI (match_operand:DI 1 "register_operand" "r")
3519 (match_operand 2 "const_int_operand" "n")
3520 (match_operand 3 "const_int_operand" "n")))]
3521 ""
3522 ""
3523 )
3524
3525 (define_insn "*<optab><mode>"
3526 [(set (match_operand:GPI 0 "register_operand" "=r")
3527 (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r")
3528 (match_operand 2 "const_int_operand" "n")
3529 (match_operand 3 "const_int_operand" "n")))]
3530 ""
3531 "<su>bfx\\t%<w>0, %<w>1, %3, %2"
3532 [(set_attr "v8type" "bfm")
3533 (set_attr "type" "bfm")
3534 (set_attr "mode" "<MODE>")]
3535 )
3536
3537 ;; Bitfield Insert (insv)
3538 (define_expand "insv<mode>"
3539 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand")
3540 (match_operand 1 "const_int_operand")
3541 (match_operand 2 "const_int_operand"))
3542 (match_operand:GPI 3 "general_operand"))]
3543 ""
3544 {
3545 unsigned HOST_WIDE_INT width = UINTVAL (operands[1]);
3546 unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
3547 rtx value = operands[3];
3548
3549 if (width == 0 || (pos + width) > GET_MODE_BITSIZE (<MODE>mode))
3550 FAIL;
3551
3552 if (CONST_INT_P (value))
3553 {
3554 unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
3555
3556 /* Prefer AND/OR for inserting all zeros or all ones. */
3557 if ((UINTVAL (value) & mask) == 0
3558 || (UINTVAL (value) & mask) == mask)
3559 FAIL;
3560
3561 /* 16-bit aligned 16-bit wide insert is handled by insv_imm. */
3562 if (width == 16 && (pos % 16) == 0)
3563 DONE;
3564 }
3565 operands[3] = force_reg (<MODE>mode, value);
3566 })
3567
3568 (define_insn "*insv_reg<mode>"
3569 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3570 (match_operand 1 "const_int_operand" "n")
3571 (match_operand 2 "const_int_operand" "n"))
3572 (match_operand:GPI 3 "register_operand" "r"))]
3573 "!(UINTVAL (operands[1]) == 0
3574 || (UINTVAL (operands[2]) + UINTVAL (operands[1])
3575 > GET_MODE_BITSIZE (<MODE>mode)))"
3576 "bfi\\t%<w>0, %<w>3, %2, %1"
3577 [(set_attr "v8type" "bfm")
3578 (set_attr "type" "bfm")
3579 (set_attr "mode" "<MODE>")]
3580 )
3581
3582 (define_insn "*extr_insv_lower_reg<mode>"
3583 [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand" "+r")
3584 (match_operand 1 "const_int_operand" "n")
3585 (const_int 0))
3586 (zero_extract:GPI (match_operand:GPI 2 "register_operand" "+r")
3587 (match_dup 1)
3588 (match_operand 3 "const_int_operand" "n")))]
3589 "!(UINTVAL (operands[1]) == 0
3590 || (UINTVAL (operands[3]) + UINTVAL (operands[1])
3591 > GET_MODE_BITSIZE (<MODE>mode)))"
3592 "bfxil\\t%<w>0, %<w>2, %3, %1"
3593 [(set_attr "v8type" "bfm")
3594 (set_attr "type" "bfm")
3595 (set_attr "mode" "<MODE>")]
3596 )
3597
3598 (define_insn "*<optab><ALLX:mode>_shft_<GPI:mode>"
3599 [(set (match_operand:GPI 0 "register_operand" "=r")
3600 (ashift:GPI (ANY_EXTEND:GPI
3601 (match_operand:ALLX 1 "register_operand" "r"))
3602 (match_operand 2 "const_int_operand" "n")))]
3603 "UINTVAL (operands[2]) < <GPI:sizen>"
3604 {
3605 operands[3] = (<ALLX:sizen> <= (<GPI:sizen> - UINTVAL (operands[2])))
3606 ? GEN_INT (<ALLX:sizen>)
3607 : GEN_INT (<GPI:sizen> - UINTVAL (operands[2]));
3608 return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
3609 }
3610 [(set_attr "v8type" "bfm")
3611 (set_attr "type" "bfm")
3612 (set_attr "mode" "<GPI:MODE>")]
3613 )
3614
3615 ;; XXX We should match (any_extend (ashift)) here, like (and (ashift)) below
3616
3617 (define_insn "*andim_ashift<mode>_bfiz"
3618 [(set (match_operand:GPI 0 "register_operand" "=r")
3619 (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r")
3620 (match_operand 2 "const_int_operand" "n"))
3621 (match_operand 3 "const_int_operand" "n")))]
3622 "exact_log2 ((INTVAL (operands[3]) >> INTVAL (operands[2])) + 1) >= 0
3623 && (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
3624 "ubfiz\\t%<w>0, %<w>1, %2, %P3"
3625 [(set_attr "v8type" "bfm")
3626 (set_attr "type" "bfm")
3627 (set_attr "mode" "<MODE>")]
3628 )
3629
3630 (define_insn "bswap<mode>2"
3631 [(set (match_operand:GPI 0 "register_operand" "=r")
3632 (bswap:GPI (match_operand:GPI 1 "register_operand" "r")))]
3633 ""
3634 "rev\\t%<w>0, %<w>1"
3635 [(set_attr "v8type" "rev")
3636 (set_attr "type" "rev")
3637 (set_attr "mode" "<MODE>")]
3638 )
3639
3640 (define_insn "bswaphi2"
3641 [(set (match_operand:HI 0 "register_operand" "=r")
3642 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
3643 ""
3644 "rev16\\t%w0, %w1"
3645 [(set_attr "v8type" "rev")
3646 (set_attr "type" "rev")
3647 (set_attr "mode" "HI")]
3648 )
3649
3650 ;; zero_extend version of above
3651 (define_insn "*bswapsi2_uxtw"
3652 [(set (match_operand:DI 0 "register_operand" "=r")
3653 (zero_extend:DI (bswap:SI (match_operand:SI 1 "register_operand" "r"))))]
3654 ""
3655 "rev\\t%w0, %w1"
3656 [(set_attr "v8type" "rev")
3657 (set_attr "type" "rev")
3658 (set_attr "mode" "SI")]
3659 )
3660
3661 ;; -------------------------------------------------------------------
3662 ;; Floating-point intrinsics
3663 ;; -------------------------------------------------------------------
3664
3665 ;; frint floating-point round to integral standard patterns.
3666 ;; Expands to btrunc, ceil, floor, nearbyint, rint, round.
3667
3668 (define_insn "<frint_pattern><mode>2"
3669 [(set (match_operand:GPF 0 "register_operand" "=w")
3670 (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3671 FRINT))]
3672 "TARGET_FLOAT"
3673 "frint<frint_suffix>\\t%<s>0, %<s>1"
3674 [(set_attr "v8type" "frint")
3675 (set_attr "type" "f_rint<s>")
3676 (set_attr "mode" "<MODE>")]
3677 )
3678
3679 ;; frcvt floating-point round to integer and convert standard patterns.
3680 ;; Expands to lbtrunc, lceil, lfloor, lround.
3681 (define_insn "l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2"
3682 [(set (match_operand:GPI 0 "register_operand" "=r")
3683 (FIXUORS:GPI (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
3684 FCVT)))]
3685 "TARGET_FLOAT"
3686 "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
3687 [(set_attr "v8type" "fcvtf2i")
3688 (set_attr "type" "f_cvtf2i")
3689 (set_attr "mode" "<GPF:MODE>")
3690 (set_attr "mode2" "<GPI:MODE>")]
3691 )
3692
3693 ;; fma - no throw
3694
3695 (define_insn "fma<mode>4"
3696 [(set (match_operand:GPF 0 "register_operand" "=w")
3697 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3698 (match_operand:GPF 2 "register_operand" "w")
3699 (match_operand:GPF 3 "register_operand" "w")))]
3700 "TARGET_FLOAT"
3701 "fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3702 [(set_attr "v8type" "fmadd")
3703 (set_attr "type" "fmac<s>")
3704 (set_attr "mode" "<MODE>")]
3705 )
3706
3707 (define_insn "fnma<mode>4"
3708 [(set (match_operand:GPF 0 "register_operand" "=w")
3709 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3710 (match_operand:GPF 2 "register_operand" "w")
3711 (match_operand:GPF 3 "register_operand" "w")))]
3712 "TARGET_FLOAT"
3713 "fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3714 [(set_attr "v8type" "fmadd")
3715 (set_attr "type" "fmac<s>")
3716 (set_attr "mode" "<MODE>")]
3717 )
3718
3719 (define_insn "fms<mode>4"
3720 [(set (match_operand:GPF 0 "register_operand" "=w")
3721 (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3722 (match_operand:GPF 2 "register_operand" "w")
3723 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3724 "TARGET_FLOAT"
3725 "fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
3726 [(set_attr "v8type" "fmadd")
3727 (set_attr "type" "fmac<s>")
3728 (set_attr "mode" "<MODE>")]
3729 )
3730
3731 (define_insn "fnms<mode>4"
3732 [(set (match_operand:GPF 0 "register_operand" "=w")
3733 (fma:GPF (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3734 (match_operand:GPF 2 "register_operand" "w")
3735 (neg:GPF (match_operand:GPF 3 "register_operand" "w"))))]
3736 "TARGET_FLOAT"
3737 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3738 [(set_attr "v8type" "fmadd")
3739 (set_attr "type" "fmac<s>")
3740 (set_attr "mode" "<MODE>")]
3741 )
3742
3743 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
3744 (define_insn "*fnmadd<mode>4"
3745 [(set (match_operand:GPF 0 "register_operand" "=w")
3746 (neg:GPF (fma:GPF (match_operand:GPF 1 "register_operand" "w")
3747 (match_operand:GPF 2 "register_operand" "w")
3748 (match_operand:GPF 3 "register_operand" "w"))))]
3749 "!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
3750 "fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
3751 [(set_attr "v8type" "fmadd")
3752 (set_attr "type" "fmac<s>")
3753 (set_attr "mode" "<MODE>")]
3754 )
3755
3756 ;; -------------------------------------------------------------------
3757 ;; Floating-point conversions
3758 ;; -------------------------------------------------------------------
3759
3760 (define_insn "extendsfdf2"
3761 [(set (match_operand:DF 0 "register_operand" "=w")
3762 (float_extend:DF (match_operand:SF 1 "register_operand" "w")))]
3763 "TARGET_FLOAT"
3764 "fcvt\\t%d0, %s1"
3765 [(set_attr "v8type" "fcvt")
3766 (set_attr "type" "f_cvt")
3767 (set_attr "mode" "DF")
3768 (set_attr "mode2" "SF")]
3769 )
3770
3771 (define_insn "truncdfsf2"
3772 [(set (match_operand:SF 0 "register_operand" "=w")
3773 (float_truncate:SF (match_operand:DF 1 "register_operand" "w")))]
3774 "TARGET_FLOAT"
3775 "fcvt\\t%s0, %d1"
3776 [(set_attr "v8type" "fcvt")
3777 (set_attr "type" "f_cvt")
3778 (set_attr "mode" "SF")
3779 (set_attr "mode2" "DF")]
3780 )
3781
3782 (define_insn "fix_trunc<GPF:mode><GPI:mode>2"
3783 [(set (match_operand:GPI 0 "register_operand" "=r")
3784 (fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3785 "TARGET_FLOAT"
3786 "fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
3787 [(set_attr "v8type" "fcvtf2i")
3788 (set_attr "type" "f_cvtf2i")
3789 (set_attr "mode" "<GPF:MODE>")
3790 (set_attr "mode2" "<GPI:MODE>")]
3791 )
3792
3793 (define_insn "fixuns_trunc<GPF:mode><GPI:mode>2"
3794 [(set (match_operand:GPI 0 "register_operand" "=r")
3795 (unsigned_fix:GPI (match_operand:GPF 1 "register_operand" "w")))]
3796 "TARGET_FLOAT"
3797 "fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
3798 [(set_attr "v8type" "fcvtf2i")
3799 (set_attr "type" "f_cvtf2i")
3800 (set_attr "mode" "<GPF:MODE>")
3801 (set_attr "mode2" "<GPI:MODE>")]
3802 )
3803
3804 (define_insn "float<GPI:mode><GPF:mode>2"
3805 [(set (match_operand:GPF 0 "register_operand" "=w")
3806 (float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3807 "TARGET_FLOAT"
3808 "scvtf\\t%<GPF:s>0, %<GPI:w>1"
3809 [(set_attr "v8type" "fcvti2f")
3810 (set_attr "type" "f_cvti2f")
3811 (set_attr "mode" "<GPF:MODE>")
3812 (set_attr "mode2" "<GPI:MODE>")]
3813 )
3814
3815 (define_insn "floatuns<GPI:mode><GPF:mode>2"
3816 [(set (match_operand:GPF 0 "register_operand" "=w")
3817 (unsigned_float:GPF (match_operand:GPI 1 "register_operand" "r")))]
3818 "TARGET_FLOAT"
3819 "ucvtf\\t%<GPF:s>0, %<GPI:w>1"
3820 [(set_attr "v8type" "fcvt")
3821 (set_attr "type" "f_cvt")
3822 (set_attr "mode" "<GPF:MODE>")
3823 (set_attr "mode2" "<GPI:MODE>")]
3824 )
3825
3826 ;; -------------------------------------------------------------------
3827 ;; Floating-point arithmetic
3828 ;; -------------------------------------------------------------------
3829
3830 (define_insn "add<mode>3"
3831 [(set (match_operand:GPF 0 "register_operand" "=w")
3832 (plus:GPF
3833 (match_operand:GPF 1 "register_operand" "w")
3834 (match_operand:GPF 2 "register_operand" "w")))]
3835 "TARGET_FLOAT"
3836 "fadd\\t%<s>0, %<s>1, %<s>2"
3837 [(set_attr "v8type" "fadd")
3838 (set_attr "type" "fadd<s>")
3839 (set_attr "mode" "<MODE>")]
3840 )
3841
3842 (define_insn "sub<mode>3"
3843 [(set (match_operand:GPF 0 "register_operand" "=w")
3844 (minus:GPF
3845 (match_operand:GPF 1 "register_operand" "w")
3846 (match_operand:GPF 2 "register_operand" "w")))]
3847 "TARGET_FLOAT"
3848 "fsub\\t%<s>0, %<s>1, %<s>2"
3849 [(set_attr "v8type" "fadd")
3850 (set_attr "type" "fadd<s>")
3851 (set_attr "mode" "<MODE>")]
3852 )
3853
3854 (define_insn "mul<mode>3"
3855 [(set (match_operand:GPF 0 "register_operand" "=w")
3856 (mult:GPF
3857 (match_operand:GPF 1 "register_operand" "w")
3858 (match_operand:GPF 2 "register_operand" "w")))]
3859 "TARGET_FLOAT"
3860 "fmul\\t%<s>0, %<s>1, %<s>2"
3861 [(set_attr "v8type" "fmul")
3862 (set_attr "type" "fmul<s>")
3863 (set_attr "mode" "<MODE>")]
3864 )
3865
3866 (define_insn "*fnmul<mode>3"
3867 [(set (match_operand:GPF 0 "register_operand" "=w")
3868 (mult:GPF
3869 (neg:GPF (match_operand:GPF 1 "register_operand" "w"))
3870 (match_operand:GPF 2 "register_operand" "w")))]
3871 "TARGET_FLOAT"
3872 "fnmul\\t%<s>0, %<s>1, %<s>2"
3873 [(set_attr "v8type" "fmul")
3874 (set_attr "type" "fmul<s>")
3875 (set_attr "mode" "<MODE>")]
3876 )
3877
3878 (define_insn "div<mode>3"
3879 [(set (match_operand:GPF 0 "register_operand" "=w")
3880 (div:GPF
3881 (match_operand:GPF 1 "register_operand" "w")
3882 (match_operand:GPF 2 "register_operand" "w")))]
3883 "TARGET_FLOAT"
3884 "fdiv\\t%<s>0, %<s>1, %<s>2"
3885 [(set_attr "v8type" "fdiv")
3886 (set_attr "type" "fdiv<s>")
3887 (set_attr "mode" "<MODE>")]
3888 )
3889
3890 (define_insn "neg<mode>2"
3891 [(set (match_operand:GPF 0 "register_operand" "=w")
3892 (neg:GPF (match_operand:GPF 1 "register_operand" "w")))]
3893 "TARGET_FLOAT"
3894 "fneg\\t%<s>0, %<s>1"
3895 [(set_attr "v8type" "ffarith")
3896 (set_attr "type" "ffarith<s>")
3897 (set_attr "mode" "<MODE>")]
3898 )
3899
3900 (define_insn "sqrt<mode>2"
3901 [(set (match_operand:GPF 0 "register_operand" "=w")
3902 (sqrt:GPF (match_operand:GPF 1 "register_operand" "w")))]
3903 "TARGET_FLOAT"
3904 "fsqrt\\t%<s>0, %<s>1"
3905 [(set_attr "v8type" "fsqrt")
3906 (set_attr "type" "fdiv<s>")
3907 (set_attr "mode" "<MODE>")]
3908 )
3909
3910 (define_insn "abs<mode>2"
3911 [(set (match_operand:GPF 0 "register_operand" "=w")
3912 (abs:GPF (match_operand:GPF 1 "register_operand" "w")))]
3913 "TARGET_FLOAT"
3914 "fabs\\t%<s>0, %<s>1"
3915 [(set_attr "v8type" "ffarith")
3916 (set_attr "type" "ffarith<s>")
3917 (set_attr "mode" "<MODE>")]
3918 )
3919
3920 ;; Given that smax/smin do not specify the result when either input is NaN,
3921 ;; we could use either FMAXNM or FMAX for smax, and either FMINNM or FMIN
3922 ;; for smin.
3923
3924 (define_insn "smax<mode>3"
3925 [(set (match_operand:GPF 0 "register_operand" "=w")
3926 (smax:GPF (match_operand:GPF 1 "register_operand" "w")
3927 (match_operand:GPF 2 "register_operand" "w")))]
3928 "TARGET_FLOAT"
3929 "fmaxnm\\t%<s>0, %<s>1, %<s>2"
3930 [(set_attr "v8type" "fminmax")
3931 (set_attr "type" "f_minmax<s>")
3932 (set_attr "mode" "<MODE>")]
3933 )
3934
3935 (define_insn "smin<mode>3"
3936 [(set (match_operand:GPF 0 "register_operand" "=w")
3937 (smin:GPF (match_operand:GPF 1 "register_operand" "w")
3938 (match_operand:GPF 2 "register_operand" "w")))]
3939 "TARGET_FLOAT"
3940 "fminnm\\t%<s>0, %<s>1, %<s>2"
3941 [(set_attr "v8type" "fminmax")
3942 (set_attr "type" "f_minmax<s>")
3943 (set_attr "mode" "<MODE>")]
3944 )
3945
3946 ;; -------------------------------------------------------------------
3947 ;; Reload support
3948 ;; -------------------------------------------------------------------
3949
3950 ;; Reload SP+imm where imm cannot be handled by a single ADD instruction.
3951 ;; Must load imm into a scratch register and copy SP to the dest reg before
3952 ;; adding, since SP cannot be used as a source register in an ADD
3953 ;; instruction.
3954 (define_expand "reload_sp_immediate"
3955 [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
3956 (match_operand:DI 1 "" ""))
3957 (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
3958 ""
3959 {
3960 rtx sp = XEXP (operands[1], 0);
3961 rtx val = XEXP (operands[1], 1);
3962 unsigned regno = REGNO (operands[2]);
3963 rtx scratch = operands[1];
3964 gcc_assert (GET_CODE (operands[1]) == PLUS);
3965 gcc_assert (sp == stack_pointer_rtx);
3966 gcc_assert (CONST_INT_P (val));
3967
3968 /* It is possible that one of the registers we got for operands[2]
3969 might coincide with that of operands[0] (which is why we made
3970 it TImode). Pick the other one to use as our scratch. */
3971 if (regno == REGNO (operands[0]))
3972 regno++;
3973 scratch = gen_rtx_REG (DImode, regno);
3974
3975 emit_move_insn (scratch, val);
3976 emit_move_insn (operands[0], sp);
3977 emit_insn (gen_adddi3 (operands[0], operands[0], scratch));
3978 DONE;
3979 }
3980 )
3981
3982 (define_expand "aarch64_reload_mov<mode>"
3983 [(set (match_operand:TX 0 "register_operand" "=w")
3984 (match_operand:TX 1 "register_operand" "w"))
3985 (clobber (match_operand:DI 2 "register_operand" "=&r"))
3986 ]
3987 ""
3988 {
3989 rtx op0 = simplify_gen_subreg (TImode, operands[0], <MODE>mode, 0);
3990 rtx op1 = simplify_gen_subreg (TImode, operands[1], <MODE>mode, 0);
3991 gen_aarch64_movtilow_tilow (op0, op1);
3992 gen_aarch64_movdi_tihigh (operands[2], op1);
3993 gen_aarch64_movtihigh_di (op0, operands[2]);
3994 DONE;
3995 }
3996 )
3997
3998 ;; The following secondary reload helpers patterns are invoked
3999 ;; after or during reload as we don't want these patterns to start
4000 ;; kicking in during the combiner.
4001
4002 (define_insn "aarch64_movdi_<mode>low"
4003 [(set (match_operand:DI 0 "register_operand" "=r")
4004 (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
4005 "reload_completed || reload_in_progress"
4006 "fmov\\t%x0, %d1"
4007 [(set_attr "v8type" "fmovf2i")
4008 (set_attr "type" "f_mrc")
4009 (set_attr "mode" "DI")
4010 (set_attr "length" "4")
4011 ])
4012
4013 (define_insn "aarch64_movdi_<mode>high"
4014 [(set (match_operand:DI 0 "register_operand" "=r")
4015 (truncate:DI
4016 (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
4017 (const_int 64))))]
4018 "reload_completed || reload_in_progress"
4019 "fmov\\t%x0, %1.d[1]"
4020 [(set_attr "v8type" "fmovf2i")
4021 (set_attr "type" "f_mrc")
4022 (set_attr "mode" "DI")
4023 (set_attr "length" "4")
4024 ])
4025
4026 (define_insn "aarch64_mov<mode>high_di"
4027 [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
4028 (const_int 64) (const_int 64))
4029 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4030 "reload_completed || reload_in_progress"
4031 "fmov\\t%0.d[1], %x1"
4032 [(set_attr "v8type" "fmovi2f")
4033 (set_attr "type" "f_mcr")
4034 (set_attr "mode" "DI")
4035 (set_attr "length" "4")
4036 ])
4037
4038 (define_insn "aarch64_mov<mode>low_di"
4039 [(set (match_operand:TX 0 "register_operand" "=w")
4040 (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
4041 "reload_completed || reload_in_progress"
4042 "fmov\\t%d0, %x1"
4043 [(set_attr "v8type" "fmovi2f")
4044 (set_attr "type" "f_mcr")
4045 (set_attr "mode" "DI")
4046 (set_attr "length" "4")
4047 ])
4048
4049 (define_insn "aarch64_movtilow_tilow"
4050 [(set (match_operand:TI 0 "register_operand" "=w")
4051 (zero_extend:TI
4052 (truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
4053 "reload_completed || reload_in_progress"
4054 "fmov\\t%d0, %d1"
4055 [(set_attr "v8type" "fmovi2f")
4056 (set_attr "type" "f_mcr")
4057 (set_attr "mode" "DI")
4058 (set_attr "length" "4")
4059 ])
4060
4061 ;; There is a deliberate reason why the parameters of high and lo_sum's
4062 ;; don't have modes for ADRP and ADD instructions. This is to allow high
4063 ;; and lo_sum's to be used with the labels defining the jump tables in
4064 ;; rodata section.
4065
4066 (define_expand "add_losym"
4067 [(set (match_operand 0 "register_operand" "=r")
4068 (lo_sum (match_operand 1 "register_operand" "r")
4069 (match_operand 2 "aarch64_valid_symref" "S")))]
4070 ""
4071 {
4072 enum machine_mode mode = GET_MODE (operands[0]);
4073
4074 emit_insn ((mode == DImode
4075 ? gen_add_losym_di
4076 : gen_add_losym_si) (operands[0],
4077 operands[1],
4078 operands[2]));
4079 DONE;
4080 })
4081
4082 (define_insn "add_losym_<mode>"
4083 [(set (match_operand:P 0 "register_operand" "=r")
4084 (lo_sum:P (match_operand:P 1 "register_operand" "r")
4085 (match_operand 2 "aarch64_valid_symref" "S")))]
4086 ""
4087 "add\\t%<w>0, %<w>1, :lo12:%a2"
4088 [(set_attr "v8type" "alu")
4089 (set_attr "type" "alu_reg")
4090 (set_attr "mode" "<MODE>")]
4091 )
4092
4093 (define_insn "ldr_got_small_<mode>"
4094 [(set (match_operand:PTR 0 "register_operand" "=r")
4095 (unspec:PTR [(mem:PTR (lo_sum:PTR
4096 (match_operand:PTR 1 "register_operand" "r")
4097 (match_operand:PTR 2 "aarch64_valid_symref" "S")))]
4098 UNSPEC_GOTSMALLPIC))]
4099 ""
4100 "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
4101 [(set_attr "v8type" "load1")
4102 (set_attr "type" "load1")
4103 (set_attr "mode" "<MODE>")]
4104 )
4105
4106 (define_insn "ldr_got_small_sidi"
4107 [(set (match_operand:DI 0 "register_operand" "=r")
4108 (zero_extend:DI
4109 (unspec:SI [(mem:SI (lo_sum:DI
4110 (match_operand:DI 1 "register_operand" "r")
4111 (match_operand:DI 2 "aarch64_valid_symref" "S")))]
4112 UNSPEC_GOTSMALLPIC)))]
4113 "TARGET_ILP32"
4114 "ldr\\t%w0, [%1, #:got_lo12:%a2]"
4115 [(set_attr "v8type" "load1")
4116 (set_attr "type" "load1")
4117 (set_attr "mode" "DI")]
4118 )
4119
4120 (define_insn "ldr_got_tiny"
4121 [(set (match_operand:DI 0 "register_operand" "=r")
4122 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
4123 UNSPEC_GOTTINYPIC))]
4124 ""
4125 "ldr\\t%0, %L1"
4126 [(set_attr "v8type" "load1")
4127 (set_attr "type" "load1")
4128 (set_attr "mode" "DI")]
4129 )
4130
4131 (define_insn "aarch64_load_tp_hard"
4132 [(set (match_operand:DI 0 "register_operand" "=r")
4133 (unspec:DI [(const_int 0)] UNSPEC_TLS))]
4134 ""
4135 "mrs\\t%0, tpidr_el0"
4136 [(set_attr "v8type" "mrs")
4137 (set_attr "type" "mov_reg")
4138 (set_attr "mode" "DI")]
4139 )
4140
4141 ;; The TLS ABI specifically requires that the compiler does not schedule
4142 ;; instructions in the TLS stubs, in order to enable linker relaxation.
4143 ;; Therefore we treat the stubs as an atomic sequence.
4144 (define_expand "tlsgd_small"
4145 [(parallel [(set (match_operand 0 "register_operand" "")
4146 (call (mem:DI (match_dup 2)) (const_int 1)))
4147 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "")] UNSPEC_GOTSMALLTLS)
4148 (clobber (reg:DI LR_REGNUM))])]
4149 ""
4150 {
4151 operands[2] = aarch64_tls_get_addr ();
4152 })
4153
4154 (define_insn "*tlsgd_small"
4155 [(set (match_operand 0 "register_operand" "")
4156 (call (mem:DI (match_operand:DI 2 "" "")) (const_int 1)))
4157 (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")] UNSPEC_GOTSMALLTLS)
4158 (clobber (reg:DI LR_REGNUM))
4159 ]
4160 ""
4161 "adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
4162 [(set_attr "v8type" "call")
4163 (set_attr "type" "call")
4164 (set_attr "length" "16")])
4165
4166 (define_insn "tlsie_small"
4167 [(set (match_operand:DI 0 "register_operand" "=r")
4168 (unspec:DI [(match_operand:DI 1 "aarch64_tls_ie_symref" "S")]
4169 UNSPEC_GOTSMALLTLS))]
4170 ""
4171 "adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
4172 [(set_attr "v8type" "load1")
4173 (set_attr "type" "load1")
4174 (set_attr "mode" "DI")
4175 (set_attr "length" "8")]
4176 )
4177
4178 (define_insn "tlsle_small"
4179 [(set (match_operand:DI 0 "register_operand" "=r")
4180 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4181 (match_operand:DI 2 "aarch64_tls_le_symref" "S")]
4182 UNSPEC_GOTSMALLTLS))]
4183 ""
4184 "add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
4185 [(set_attr "v8type" "alu")
4186 (set_attr "type" "alu_reg")
4187 (set_attr "mode" "DI")
4188 (set_attr "length" "8")]
4189 )
4190
4191 (define_insn "tlsdesc_small"
4192 [(set (reg:DI R0_REGNUM)
4193 (unspec:DI [(match_operand:DI 0 "aarch64_valid_symref" "S")]
4194 UNSPEC_TLSDESC))
4195 (clobber (reg:DI LR_REGNUM))
4196 (clobber (match_scratch:DI 1 "=r"))]
4197 "TARGET_TLS_DESC"
4198 "adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
4199 [(set_attr "v8type" "call")
4200 (set_attr "type" "call")
4201 (set_attr "length" "16")])
4202
4203 (define_insn "stack_tie"
4204 [(set (mem:BLK (scratch))
4205 (unspec:BLK [(match_operand:DI 0 "register_operand" "rk")
4206 (match_operand:DI 1 "register_operand" "rk")]
4207 UNSPEC_PRLG_STK))]
4208 ""
4209 ""
4210 [(set_attr "length" "0")]
4211 )
4212
4213 ;; Named pattern for expanding thread pointer reference.
4214 (define_expand "get_thread_pointerdi"
4215 [(match_operand:DI 0 "register_operand" "=r")]
4216 ""
4217 {
4218 rtx tmp = aarch64_load_tp (operands[0]);
4219 if (tmp != operands[0])
4220 emit_move_insn (operands[0], tmp);
4221 DONE;
4222 })
4223
4224 ;; AdvSIMD Stuff
4225 (include "aarch64-simd.md")
4226
4227 ;; Atomic Operations
4228 (include "atomics.md")