1 ;; Machine description for AArch64 SVE2.
2 ;; Copyright (C) 2019 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
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)
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.
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/>.
21 ;; Integer average (floor).
22 (define_expand "<u>avg<mode>3_floor"
23 [(set (match_operand:SVE_I 0 "register_operand")
26 (unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
27 (match_operand:SVE_I 2 "register_operand")]
32 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
36 ;; Integer average (rounding).
37 (define_expand "<u>avg<mode>3_ceil"
38 [(set (match_operand:SVE_I 0 "register_operand")
41 (unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
42 (match_operand:SVE_I 2 "register_operand")]
47 operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
51 ;; Predicated halving addsub.
52 (define_insn "*<sur>h<addsub><mode>"
53 [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
55 [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
56 (unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0, w")
57 (match_operand:SVE_I 3 "register_operand" "w, w")]
62 <sur>h<addsub>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
63 movprfx\t%0, %2\;<sur>h<addsub>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
64 [(set_attr "movprfx" "*,yes")]
67 ;; Multiply long top / bottom.
68 (define_insn "<su>mull<bt><Vwide>"
69 [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
70 (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand" "w")
71 (match_operand:SVE_BHSI 2 "register_operand" "w")]
74 "<su>mull<bt>\t%0.<Vewtype>, %1.<Vetype>, %2.<Vetype>"
77 ;; (Rounding) Right shift narrow bottom.
78 (define_insn "<r>shrnb<mode>"
79 [(set (match_operand:SVE_BHSI 0 "register_operand" "=w")
81 [(match_operand:<VWIDE> 1 "register_operand" "w")
82 (match_operand 2 "aarch64_simd_shift_imm_offset_<Vel>" "")]
85 "<r>shrnb\t%0.<Vetype>, %1.<Vewtype>, #%2"
88 ;; (Rounding) Right shift narrow top.
89 (define_insn "<r>shrnt<mode>"
90 [(set (match_operand:SVE_BHSI 0 "register_operand" "=w")
92 [(match_operand:SVE_BHSI 1 "register_operand" "0")
93 (match_operand:<VWIDE> 2 "register_operand" "w")
94 (match_operand 3 "aarch64_simd_shift_imm_offset_<Vel>" "i")]
97 "<r>shrnt\t%0.<Vetype>, %2.<Vewtype>, #%3"
100 ;; Unpredicated integer multiply-high-with-(round-and-)scale.
101 (define_expand "<su>mulh<r>s<mode>3"
102 [(set (match_operand:SVE_BHSI 0 "register_operand")
105 (unspec:SVE_BHSI [(match_operand:SVE_BHSI 1 "register_operand")
106 (match_operand:SVE_BHSI 2 "register_operand")]
111 operands[3] = aarch64_ptrue_reg (<VPRED>mode);
113 rtx prod_b = gen_reg_rtx (<VWIDE>mode);
114 rtx prod_t = gen_reg_rtx (<VWIDE>mode);
115 emit_insn (gen_<su>mullb<Vwide> (prod_b, operands[1], operands[2]));
116 emit_insn (gen_<su>mullt<Vwide> (prod_t, operands[1], operands[2]));
118 rtx shift = GEN_INT (GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1);
119 emit_insn (gen_<r>shrnb<mode> (operands[0], prod_b, shift));
120 emit_insn (gen_<r>shrnt<mode> (operands[0], operands[0], prod_t, shift));