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