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