annotate gcc/config/aarch64/aarch64-sve-builtins-base.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /* ACLE support for AArch64 SVE (__ARM_FEATURE_SVE intrinsics)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 Copyright (C) 2018-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 This file is part of GCC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 under the terms of the GNU General Public License as published by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 the Free Software Foundation; either version 3, or (at your option)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 WITHOUT ANY WARRANTY; without even the implied warranty of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 General Public License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "config.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 #include "system.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "coretypes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "tm.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #include "tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "rtl.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "tm_p.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 #include "memmodel.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 #include "insn-codes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 #include "optabs.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 #include "recog.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 #include "expr.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 #include "basic-block.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 #include "function.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 #include "fold-const.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 #include "gimple.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 #include "gimple-iterator.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 #include "gimplify.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 #include "explow.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 #include "emit-rtl.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 #include "tree-vector-builder.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 #include "rtx-vector-builder.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 #include "vec-perm-indices.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 #include "aarch64-sve-builtins.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 #include "aarch64-sve-builtins-shapes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 #include "aarch64-sve-builtins-base.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 #include "aarch64-sve-builtins-functions.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 using namespace aarch64_sve;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 namespace {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 /* Return the UNSPEC_CMLA* unspec for rotation amount ROT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 static int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 unspec_cmla (int rot)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 switch (rot)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 case 0: return UNSPEC_CMLA;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 case 90: return UNSPEC_CMLA90;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 case 180: return UNSPEC_CMLA180;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 case 270: return UNSPEC_CMLA270;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 default: gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 /* Return the UNSPEC_FCMLA* unspec for rotation amount ROT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 static int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 unspec_fcmla (int rot)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 switch (rot)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 case 0: return UNSPEC_FCMLA;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 case 90: return UNSPEC_FCMLA90;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 case 180: return UNSPEC_FCMLA180;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 case 270: return UNSPEC_FCMLA270;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 default: gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 /* Return the UNSPEC_COND_FCMLA* unspec for rotation amount ROT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 static int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 unspec_cond_fcmla (int rot)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 switch (rot)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 case 0: return UNSPEC_COND_FCMLA;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 case 90: return UNSPEC_COND_FCMLA90;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 case 180: return UNSPEC_COND_FCMLA180;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 case 270: return UNSPEC_COND_FCMLA270;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 default: gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 /* Expand a call to svmad, or svmla after reordering its operands.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 Make _m forms merge with argument MERGE_ARGNO. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 static rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 expand_mad (function_expander &e,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 unsigned int merge_argno = DEFAULT_MERGE_ARGNO)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 if (e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 icode = code_for_aarch64_pred_fma (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 icode = code_for_aarch64_pred (UNSPEC_COND_FMLA, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 return e.use_pred_x_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 insn_code icode = e.direct_optab_handler (cond_fma_optab);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 return e.use_cond_insn (icode, merge_argno);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 /* Expand a call to svmla_lane or svmls_lane using floating-point unspec
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 UNSPEC. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 static rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 expand_mla_mls_lane (function_expander &e, int unspec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 /* Put the operands in the normal (fma ...) order, with the accumulator
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 last. This fits naturally since that's also the unprinted operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 in the asm output. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 e.rotate_inputs_left (0, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 insn_code icode = code_for_aarch64_lane (unspec, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 /* Expand a call to svmsb, or svmls after reordering its operands.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 Make _m forms merge with argument MERGE_ARGNO. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 static rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130 expand_msb (function_expander &e,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 unsigned int merge_argno = DEFAULT_MERGE_ARGNO)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 if (e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 icode = code_for_aarch64_pred_fnma (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 icode = code_for_aarch64_pred (UNSPEC_COND_FMLS, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 return e.use_pred_x_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 insn_code icode = e.direct_optab_handler (cond_fnma_optab);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 return e.use_cond_insn (icode, merge_argno);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 class svabd_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 /* The integer operations are represented as the subtraction of the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 minimum from the maximum, with the signedness of the instruction
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 keyed off the signedness of the maximum operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 rtx_code max_code = e.type_suffix (0).unsigned_p ? UMAX : SMAX;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 if (e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 icode = code_for_aarch64_pred_abd (max_code, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 icode = code_for_aarch64_pred_abd (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 return e.use_pred_x_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 icode = code_for_aarch64_cond_abd (max_code, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 icode = code_for_aarch64_cond_abd (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 return e.use_cond_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 /* Implements svacge, svacgt, svacle and svaclt. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 class svac_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 CONSTEXPR svac_impl (int unspec) : m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 e.add_ptrue_hint (0, e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 insn_code icode = code_for_aarch64_pred_fac (m_unspec, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 /* The unspec code for the underlying comparison. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 class svadda_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 /* Put the predicate last, as required by mask_fold_left_plus_optab. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 e.rotate_inputs_left (0, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 insn_code icode = direct_optab_handler (mask_fold_left_plus_optab, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 /* Implements svadr[bhwd]. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 class svadr_bhwd_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 CONSTEXPR svadr_bhwd_impl (unsigned int shift) : m_shift (shift) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 machine_mode mode = GET_MODE (e.args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 if (m_shift == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 return e.use_exact_insn (code_for_aarch64_adr (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 /* Turn the access size into an extra shift argument. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 rtx shift = gen_int_mode (m_shift, GET_MODE_INNER (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 e.args.quick_push (expand_vector_broadcast (mode, shift));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 return e.use_exact_insn (code_for_aarch64_adr_shift (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 /* How many bits left to shift the vector displacement. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 unsigned int m_shift;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 class svbic_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 /* Convert svbic of a constant into svand of its inverse. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 if (CONST_INT_P (e.args[2]))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 machine_mode mode = GET_MODE_INNER (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 e.args[2] = simplify_unary_operation (NOT, mode, e.args[2], mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 return e.map_to_rtx_codes (AND, AND, -1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 if (e.type_suffix_ids[0] == TYPE_SUFFIX_b)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 gcc_assert (e.pred == PRED_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 return e.use_exact_insn (CODE_FOR_aarch64_pred_bicvnx16bi_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 if (e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 return e.use_unpred_insn (code_for_aarch64_bic (e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 return e.use_cond_insn (code_for_cond_bic (e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 /* Implements svbrkn, svbrkpa and svbrkpb. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 class svbrk_binary_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 CONSTEXPR svbrk_binary_impl (int unspec) : m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 return e.use_exact_insn (code_for_aarch64_brk (m_unspec));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 /* The unspec code associated with the operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 /* Implements svbrka and svbrkb. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 class svbrk_unary_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 CONSTEXPR svbrk_unary_impl (int unspec) : m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 return e.use_cond_insn (code_for_aarch64_brk (m_unspec));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 /* The unspec code associated with the operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 class svcadd_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 /* Convert the rotation amount into a specific unspec. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 int rot = INTVAL (e.args.pop ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 if (rot == 90)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 return e.map_to_unspecs (UNSPEC_CADD90, UNSPEC_CADD90,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 UNSPEC_COND_FCADD90);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 if (rot == 270)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 return e.map_to_unspecs (UNSPEC_CADD270, UNSPEC_CADD270,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 UNSPEC_COND_FCADD270);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 /* Implements svclasta and svclastb. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 class svclast_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 CONSTEXPR svclast_impl (int unspec) : m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 /* Match the fold_extract_optab order. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 std::swap (e.args[0], e.args[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 if (e.mode_suffix_id == MODE_n)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 icode = code_for_fold_extract (m_unspec, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 icode = code_for_aarch64_fold_extract_vector (m_unspec, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 /* The unspec code associated with the operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 class svcmla_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 /* Convert the rotation amount into a specific unspec. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 int rot = INTVAL (e.args.pop ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 if (e.type_suffix (0).float_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 /* Make the operand order the same as the one used by the fma optabs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 with the accumulator last. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 e.rotate_inputs_left (1, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 return e.map_to_unspecs (-1, -1, unspec_cond_fcmla (rot), 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 int cmla = unspec_cmla (rot);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 return e.map_to_unspecs (cmla, cmla, -1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 class svcmla_lane_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 /* Convert the rotation amount into a specific unspec. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 int rot = INTVAL (e.args.pop ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 if (e.type_suffix (0).float_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 /* Make the operand order the same as the one used by the fma optabs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 with the accumulator last. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 e.rotate_inputs_left (0, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 insn_code icode = code_for_aarch64_lane (unspec_fcmla (rot), mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 insn_code icode = code_for_aarch64_lane (unspec_cmla (rot), mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 /* Implements svcmp<cc> (except svcmpuo, which is handled separately). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 class svcmp_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 CONSTEXPR svcmp_impl (tree_code code, int unspec_for_fp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 : m_code (code), m_unspec_for_fp (unspec_for_fp) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 tree pg = gimple_call_arg (f.call, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 tree rhs1 = gimple_call_arg (f.call, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 tree rhs2 = gimple_call_arg (f.call, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 /* Convert a ptrue-predicated integer comparison into the corresponding
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 gimple-level operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 if (integer_all_onesp (pg)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 && f.type_suffix (0).element_bytes == 1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 && f.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 gimple_seq stmts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 rhs2 = f.force_vector (stmts, TREE_TYPE (rhs1), rhs2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 gsi_insert_seq_before (f.gsi, stmts, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 return gimple_build_assign (f.lhs, m_code, rhs1, rhs2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 /* Comparisons are UNSPEC_PRED_Z operations and so need a hint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 operand. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 e.add_ptrue_hint (0, e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 bool unsigned_p = e.type_suffix (0).unsigned_p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 rtx_code code = get_rtx_code (m_code, unsigned_p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 return e.use_exact_insn (code_for_aarch64_pred_cmp (code, mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 insn_code icode = code_for_aarch64_pred_fcm (m_unspec_for_fp, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 /* The tree code associated with the comparison. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 tree_code m_code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 /* The unspec code to use for floating-point comparisons. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 int m_unspec_for_fp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 /* Implements svcmp<cc>_wide. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 class svcmp_wide_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439 CONSTEXPR svcmp_wide_impl (tree_code code, int unspec_for_sint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 int unspec_for_uint)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441 : m_code (code), m_unspec_for_sint (unspec_for_sint),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 m_unspec_for_uint (unspec_for_uint) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 bool unsigned_p = e.type_suffix (0).unsigned_p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449 rtx_code code = get_rtx_code (m_code, unsigned_p);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451 /* Comparisons are UNSPEC_PRED_Z operations and so need a hint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 operand. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 e.add_ptrue_hint (0, e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 /* If the argument is a constant that the unwidened comparisons
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 can handle directly, use them instead. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457 insn_code icode = code_for_aarch64_pred_cmp (code, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 rtx op2 = unwrap_const_vec_duplicate (e.args[3]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459 if (CONSTANT_P (op2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 && insn_data[icode].operand[4].predicate (op2, DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 e.args[3] = op2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 int unspec = (unsigned_p ? m_unspec_for_uint : m_unspec_for_sint);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 return e.use_exact_insn (code_for_aarch64_pred_cmp_wide (unspec, mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470 /* The tree code associated with the comparison. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 tree_code m_code;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 /* The unspec codes for signed and unsigned wide comparisons
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 respectively. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 int m_unspec_for_sint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 int m_unspec_for_uint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 class svcmpuo_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485 e.add_ptrue_hint (0, e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 return e.use_exact_insn (code_for_aarch64_pred_fcmuo (e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 class svcnot_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 if (e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 /* The pattern for CNOT includes an UNSPEC_PRED_Z, so needs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 a ptrue hint. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 e.add_ptrue_hint (0, e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 return e.use_pred_x_insn (code_for_aarch64_pred_cnot (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 return e.use_cond_insn (code_for_cond_cnot (mode), 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 /* Implements svcnt[bhwd], which count the number of elements
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 in a particular vector mode. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 class svcnt_bhwd_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 CONSTEXPR svcnt_bhwd_impl (machine_mode ref_mode) : m_ref_mode (ref_mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 tree count = build_int_cstu (TREE_TYPE (f.lhs),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 GET_MODE_NUNITS (m_ref_mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 return gimple_build_assign (f.lhs, count);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525 expand (function_expander &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 return gen_int_mode (GET_MODE_NUNITS (m_ref_mode), DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 /* The mode of the vector associated with the [bhwd] suffix. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 machine_mode m_ref_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 /* Implements svcnt[bhwd]_pat. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 class svcnt_bhwd_pat_impl : public svcnt_bhwd_impl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 CONSTEXPR svcnt_bhwd_pat_impl (machine_mode ref_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 : svcnt_bhwd_impl (ref_mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 tree pattern_arg = gimple_call_arg (f.call, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 aarch64_svpattern pattern = (aarch64_svpattern) tree_to_shwi (pattern_arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 if (pattern == AARCH64_SV_ALL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 /* svcvnt[bwhd]_pat (SV_ALL) == svcnt[bwhd] (). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549 return svcnt_bhwd_impl::fold (f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551 /* See whether we can count the number of elements in the pattern
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 at compile time. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 unsigned int elements_per_vq = 128 / GET_MODE_UNIT_BITSIZE (m_ref_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 HOST_WIDE_INT value = aarch64_fold_sve_cnt_pat (pattern, elements_per_vq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 if (value >= 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 tree count = build_int_cstu (TREE_TYPE (f.lhs), value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 return gimple_build_assign (f.lhs, count);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 unsigned int elements_per_vq = 128 / GET_MODE_UNIT_BITSIZE (m_ref_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 e.args.quick_push (gen_int_mode (elements_per_vq, DImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 e.args.quick_push (const1_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 return e.use_exact_insn (CODE_FOR_aarch64_sve_cnt_pat);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 class svcntp_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 e.add_ptrue_hint (0, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 return e.use_exact_insn (code_for_aarch64_pred_cntp (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 /* Implements svcreate2, svcreate3 and svcreate4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 class svcreate_impl : public quiet<multi_vector_function>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 CONSTEXPR svcreate_impl (unsigned int vectors_per_tuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 : quiet<multi_vector_function> (vectors_per_tuple) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 unsigned int nargs = gimple_call_num_args (f.call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 tree lhs_type = TREE_TYPE (f.lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 /* Replace the call with a clobber of the result (to prevent it from
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 becoming upwards exposed) followed by stores into each individual
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 vector of tuple.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 The fold routines expect the replacement statement to have the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 same lhs as the original call, so return the clobber statement
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 rather than the final vector store. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606 gassign *clobber = gimple_build_assign (f.lhs, build_clobber (lhs_type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608 for (unsigned int i = nargs; i-- > 0; )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 tree rhs_vector = gimple_call_arg (f.call, i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 tree field = tuple_type_field (TREE_TYPE (f.lhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 unshare_expr (f.lhs), field, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 lhs_array, size_int (i),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 NULL_TREE, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 gassign *assign = gimple_build_assign (lhs_vector, rhs_vector);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 gsi_insert_after (f.gsi, assign, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 return clobber;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 rtx lhs_tuple = e.get_nonoverlapping_reg_target ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 /* Record that LHS_TUPLE is dead before the first store. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629 emit_clobber (lhs_tuple);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 for (unsigned int i = 0; i < e.args.length (); ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 /* Use an lvalue subreg to refer to vector I in LHS_TUPLE. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 rtx lhs_vector = simplify_gen_subreg (GET_MODE (e.args[i]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 lhs_tuple, GET_MODE (lhs_tuple),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635 i * BYTES_PER_SVE_VECTOR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 emit_move_insn (lhs_vector, e.args[i]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 return lhs_tuple;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 class svcvt_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 machine_mode mode0 = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649 machine_mode mode1 = e.vector_mode (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 /* All this complication comes from the need to select four things
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 simultaneously:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654 (1) the kind of conversion (int<-float, float<-int, float<-float)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 (2) signed vs. unsigned integers, where relevant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 (3) the predication mode, which must be the wider of the predication
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 modes for MODE0 and MODE1
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 (4) the predication type (m, x or z)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 The only supported int<->float conversions for which the integer is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661 narrower than the float are SI<->DF. It's therefore more convenient
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 to handle (3) by defining two patterns for int<->float conversions:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 one in which the integer is at least as wide as the float and so
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 determines the predication mode, and another single SI<->DF pattern
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665 in which the float's mode determines the predication mode (which is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 always VNx2BI in that case).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 The names of the patterns follow the optab convention of giving
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669 the source mode before the destination mode. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 if (e.type_suffix (1).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 int unspec = (e.type_suffix (1).unsigned_p
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 ? UNSPEC_COND_UCVTF
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 : UNSPEC_COND_SCVTF);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 if (e.type_suffix (0).element_bytes <= e.type_suffix (1).element_bytes)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 icode = (e.pred == PRED_x
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 ? code_for_aarch64_sve_nonextend (unspec, mode1, mode0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 : code_for_cond_nonextend (unspec, mode1, mode0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 icode = (e.pred == PRED_x
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681 ? code_for_aarch64_sve_extend (unspec, mode1, mode0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 : code_for_cond_extend (unspec, mode1, mode0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686 int unspec = (!e.type_suffix (0).integer_p ? UNSPEC_COND_FCVT
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 : e.type_suffix (0).unsigned_p ? UNSPEC_COND_FCVTZU
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 : UNSPEC_COND_FCVTZS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 if (e.type_suffix (0).element_bytes >= e.type_suffix (1).element_bytes)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 icode = (e.pred == PRED_x
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 ? code_for_aarch64_sve_nontrunc (unspec, mode1, mode0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692 : code_for_cond_nontrunc (unspec, mode1, mode0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 icode = (e.pred == PRED_x
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 ? code_for_aarch64_sve_trunc (unspec, mode1, mode0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 : code_for_cond_trunc (unspec, mode1, mode0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 if (e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 return e.use_pred_x_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701 return e.use_cond_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 class svdot_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 /* In the optab, the multiplication operands come before the accumulator
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712 operand. The optab is keyed off the multiplication mode. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 e.rotate_inputs_left (0, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 insn_code icode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 = e.direct_optab_handler_for_sign (sdot_prod_optab, udot_prod_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 0, GET_MODE (e.args[0]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 return e.use_unpred_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 class svdotprod_lane_impl : public unspec_based_function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 CONSTEXPR svdotprod_lane_impl (int unspec_for_sint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 int unspec_for_uint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 int unspec_for_float)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 : unspec_based_function_base (unspec_for_sint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 unspec_for_uint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 unspec_for_float) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 /* Use the same ordering as the dot_prod_optab, with the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 accumulator last. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 e.rotate_inputs_left (0, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 int unspec = unspec_for (e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 return e.use_exact_insn (code_for_aarch64_dot_prod_lane (unspec, mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 class svdup_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 tree vec_type = TREE_TYPE (f.lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 tree rhs = gimple_call_arg (f.call, f.pred == PRED_none ? 0 : 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 if (f.pred == PRED_none || f.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 if (CONSTANT_CLASS_P (rhs))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 if (f.type_suffix (0).bool_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 return (tree_to_shwi (rhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758 ? f.fold_to_ptrue ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 : f.fold_to_pfalse ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 tree rhs_vector = build_vector_from_val (vec_type, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 return gimple_build_assign (f.lhs, rhs_vector);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 /* Avoid folding _b to a VEC_DUPLICATE_EXPR, since to do that we
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766 would need to introduce an extra and unwanted conversion to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 the truth vector element type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768 if (!f.type_suffix (0).bool_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 return gimple_build_assign (f.lhs, VEC_DUPLICATE_EXPR, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 /* svdup_z (pg, x) == VEC_COND_EXPR <pg, VEC_DUPLICATE_EXPR <x>, 0>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 if (f.pred == PRED_z)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 gimple_seq stmts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 tree pred = f.convert_pred (stmts, vec_type, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 rhs = f.force_vector (stmts, vec_type, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 gsi_insert_seq_before (f.gsi, stmts, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 return gimple_build_assign (f.lhs, VEC_COND_EXPR, pred, rhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 build_zero_cst (vec_type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 if (e.pred == PRED_none || e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 /* There's no benefit to using predicated instructions for _x here. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 return e.use_unpred_insn (e.direct_optab_handler (vec_duplicate_optab));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 /* Model predicated svdups as a SEL in which the "true" value is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 the duplicate of the function argument and the "false" value
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 is the value of inactive lanes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 if (valid_for_const_vector_p (GET_MODE_INNER (mode), e.args.last ()))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 /* Duplicate the constant to fill a vector. The pattern optimizes
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 various cases involving constant operands, falling back to SEL
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 if necessary. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 icode = code_for_vcond_mask (mode, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804 /* Use the pattern for selecting between a duplicated scalar
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 variable and a vector fallback. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806 icode = code_for_aarch64_sel_dup (mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 return e.use_vcond_mask_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 class svdup_lane_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 /* The native DUP lane has an index range of 64 bytes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 if (CONST_INT_P (e.args[1])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 && IN_RANGE (INTVAL (e.args[1]) * GET_MODE_UNIT_SIZE (mode), 0, 63))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 return e.use_exact_insn (code_for_aarch64_sve_dup_lane (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 /* Treat svdup_lane as if it were svtbl_n. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 return e.use_exact_insn (code_for_aarch64_sve_tbl (e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 class svdupq_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 tree vec_type = TREE_TYPE (f.lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 unsigned int nargs = gimple_call_num_args (f.call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 /* For predicates, pad out each argument so that we have one element
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 per bit. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 unsigned int factor = (f.type_suffix (0).bool_p
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 ? f.type_suffix (0).element_bytes : 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840 tree_vector_builder builder (vec_type, nargs * factor, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 for (unsigned int i = 0; i < nargs; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 tree elt = gimple_call_arg (f.call, i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 if (!CONSTANT_CLASS_P (elt))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 builder.quick_push (elt);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847 for (unsigned int j = 1; j < factor; ++j)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 builder.quick_push (build_zero_cst (TREE_TYPE (vec_type)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 return gimple_build_assign (f.lhs, builder.build ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857 unsigned int elements_per_vq = e.args.length ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 /* Construct a vector of integers so that we can compare them against
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 zero below. Zero vs. nonzero is the only distinction that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 matters. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 mode = aarch64_sve_int_mode (mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 for (unsigned int i = 0; i < elements_per_vq; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 e.args[i] = simplify_gen_unary (ZERO_EXTEND, GET_MODE_INNER (mode),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866 e.args[i], QImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 /* Get the 128-bit Advanced SIMD vector for this data size. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 scalar_mode element_mode = GET_MODE_INNER (mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 machine_mode vq_mode = aarch64_vq_mode (element_mode).require ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 gcc_assert (known_eq (elements_per_vq, GET_MODE_NUNITS (vq_mode)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 /* Put the arguments into a 128-bit Advanced SIMD vector. We want
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 argument N to go into architectural lane N, whereas Advanced SIMD
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 vectors are loaded memory lsb to register lsb. We therefore need
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877 to reverse the elements for big-endian targets. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 rtx vq_reg = gen_reg_rtx (vq_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 rtvec vec = rtvec_alloc (elements_per_vq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 for (unsigned int i = 0; i < elements_per_vq; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 unsigned int argno = BYTES_BIG_ENDIAN ? elements_per_vq - i - 1 : i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 RTVEC_ELT (vec, i) = e.args[argno];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 aarch64_expand_vector_init (vq_reg, gen_rtx_PARALLEL (vq_mode, vec));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 /* If the result is a boolean, compare the data vector against zero. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888 if (mode != e.vector_mode (0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 rtx data_dupq = aarch64_expand_sve_dupq (NULL, mode, vq_reg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891 return aarch64_convert_sve_data_to_pred (e.possible_target,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 e.vector_mode (0), data_dupq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 return aarch64_expand_sve_dupq (e.possible_target, mode, vq_reg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 class svdupq_lane_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 rtx index = e.args[1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 if (CONST_INT_P (index) && IN_RANGE (INTVAL (index), 0, 3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 /* Use the .Q form of DUP, which is the native instruction for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 this function. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911 insn_code icode = code_for_aarch64_sve_dupq_lane (mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 unsigned int num_indices = e.elements_per_vq (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 rtx indices = aarch64_gen_stepped_int_parallel
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914 (num_indices, INTVAL (index) * num_indices, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 e.add_output_operand (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 e.add_input_operand (icode, e.args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 e.add_fixed_operand (indices);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919 return e.generate_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 /* Build a .D TBL index for the pairs of doublewords that we want to
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923 duplicate. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 if (CONST_INT_P (index))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 /* The index vector is a constant. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927 rtx_vector_builder builder (VNx2DImode, 2, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 builder.quick_push (gen_int_mode (INTVAL (index) * 2, DImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 builder.quick_push (gen_int_mode (INTVAL (index) * 2 + 1, DImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930 index = builder.build ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934 /* Duplicate INDEX * 2 to fill a DImode vector. The ACLE spec
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 explicitly allows the top of the index to be dropped. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 index = force_reg (DImode, simplify_gen_binary (ASHIFT, DImode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 index, const1_rtx));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 index = expand_vector_broadcast (VNx2DImode, index);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940 /* Get an alternating 0, 1 predicate. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 rtx_vector_builder builder (VNx2BImode, 2, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 builder.quick_push (const0_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943 builder.quick_push (constm1_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944 rtx pg = force_reg (VNx2BImode, builder.build ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 /* Add one to the odd elements of the index. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 rtx one = force_reg (VNx2DImode, CONST1_RTX (VNx2DImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 rtx target = gen_reg_rtx (VNx2DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949 emit_insn (gen_cond_addvnx2di (target, pg, index, one, index));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 index = target;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953 e.args[0] = gen_lowpart (VNx2DImode, e.args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 e.args[1] = index;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 return e.use_exact_insn (CODE_FOR_aarch64_sve_tblvnx2di);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959 /* Implements svextb, svexth and svextw. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960 class svext_bhw_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 CONSTEXPR svext_bhw_impl (scalar_int_mode from_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 : m_from_mode (from_mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 if (e.type_suffix (0).unsigned_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 /* Convert to an AND. The widest we go is 0xffffffff, which fits
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972 in a CONST_INT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 e.args.quick_push (GEN_INT (GET_MODE_MASK (m_from_mode)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 if (e.pred == PRED_m)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 /* We now have arguments "(inactive, pg, op, mask)". Convert this
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 to "(pg, op, mask, inactive)" so that the order matches svand_m
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 with an extra argument on the end. Take the inactive elements
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978 from this extra argument. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 e.rotate_inputs_left (0, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980 return e.map_to_rtx_codes (AND, AND, -1, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 machine_mode wide_mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984 poly_uint64 nunits = GET_MODE_NUNITS (wide_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 machine_mode narrow_mode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 = aarch64_sve_data_mode (m_from_mode, nunits).require ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987 if (e.pred == PRED_x)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989 insn_code icode = code_for_aarch64_pred_sxt (wide_mode, narrow_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 return e.use_pred_x_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 insn_code icode = code_for_aarch64_cond_sxt (wide_mode, narrow_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994 return e.use_cond_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 /* The element mode that we're extending from. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 scalar_int_mode m_from_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 /* Implements svget2, svget3 and svget4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 class svget_impl : public quiet<multi_vector_function>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 CONSTEXPR svget_impl (unsigned int vectors_per_tuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 : quiet<multi_vector_function> (vectors_per_tuple) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 /* Fold into a normal gimple component access. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012 tree rhs_tuple = gimple_call_arg (f.call, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013 tree index = gimple_call_arg (f.call, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 tree field = tuple_type_field (TREE_TYPE (rhs_tuple));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 tree rhs_array = build3 (COMPONENT_REF, TREE_TYPE (field),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016 rhs_tuple, field, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 tree rhs_vector = build4 (ARRAY_REF, TREE_TYPE (f.lhs),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 rhs_array, index, NULL_TREE, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019 return gimple_build_assign (f.lhs, rhs_vector);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 /* Fold the access into a subreg rvalue. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026 return simplify_gen_subreg (e.vector_mode (0), e.args[0],
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 GET_MODE (e.args[0]),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 INTVAL (e.args[1]) * BYTES_PER_SVE_VECTOR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032 class svindex_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038 return e.use_exact_insn (e.direct_optab_handler (vec_series_optab));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 class svinsr_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048 gcall *new_call = gimple_build_call_internal (IFN_VEC_SHL_INSERT, 2,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049 gimple_call_arg (f.call, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050 gimple_call_arg (f.call, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051 gimple_call_set_lhs (new_call, f.lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052 return new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 insn_code icode = direct_optab_handler (vec_shl_insert_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059 e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064 /* Implements svlasta and svlastb. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065 class svlast_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068 CONSTEXPR svlast_impl (int unspec) : m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 return e.use_exact_insn (code_for_extract (m_unspec, e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076 /* The unspec code associated with the operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 class svld1_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086 return CP_READ_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 tree vectype = f.vector_type (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094 /* Get the predicate and base pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095 gimple_seq stmts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096 tree pred = f.convert_pred (stmts, vectype, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 tree base = f.fold_contiguous_base (stmts, vectype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098 gsi_insert_seq_before (f.gsi, stmts, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100 tree cookie = f.load_store_cookie (TREE_TYPE (vectype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101 gcall *new_call = gimple_build_call_internal (IFN_MASK_LOAD, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 base, cookie, pred);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 gimple_call_set_lhs (new_call, f.lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 return new_call;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 insn_code icode = convert_optab_handler (maskload_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111 e.vector_mode (0), e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112 return e.use_contiguous_load_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116 /* Implements extending contiguous forms of svld1. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 class svld1_extend_impl : public extending_load
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1118 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1119 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1120 CONSTEXPR svld1_extend_impl (type_suffix_index memory_type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1121 : extending_load (memory_type) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1123 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1124 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1125 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1126 insn_code icode = code_for_aarch64_load (extend_rtx_code (),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1127 e.vector_mode (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1128 e.memory_vector_mode ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1129 return e.use_contiguous_load_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1130 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1131 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1132
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1133 class svld1_gather_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1134 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1135 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1136 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1137 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1138 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1139 return CP_READ_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1140 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1141
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1142 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1143 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1144 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1145 e.prepare_gather_address_operands (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1146 /* Put the predicate last, as required by mask_gather_load_optab. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1147 e.rotate_inputs_left (0, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1148 machine_mode mem_mode = e.memory_vector_mode ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1149 machine_mode int_mode = aarch64_sve_int_mode (mem_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1150 insn_code icode = convert_optab_handler (mask_gather_load_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1151 mem_mode, int_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1152 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1153 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1154 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1155
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1156 /* Implements extending forms of svld1_gather. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1157 class svld1_gather_extend_impl : public extending_load
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1158 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1159 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1160 CONSTEXPR svld1_gather_extend_impl (type_suffix_index memory_type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1161 : extending_load (memory_type) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1162
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1163 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1164 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1165 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1166 e.prepare_gather_address_operands (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1167 /* Put the predicate last, since the extending gathers use the same
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1168 operand order as mask_gather_load_optab. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1169 e.rotate_inputs_left (0, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1170 /* Add a constant predicate for the extension rtx. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1171 e.args.quick_push (CONSTM1_RTX (VNx16BImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1172 insn_code icode = code_for_aarch64_gather_load (extend_rtx_code (),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1173 e.vector_mode (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1174 e.memory_vector_mode ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1175 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1176 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1177 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1178
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1179 class load_replicate : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1180 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1181 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1182 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1183 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1184 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1185 return CP_READ_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1186 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1187
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1188 tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1189 memory_scalar_type (const function_instance &fi) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1190 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1191 return fi.scalar_type (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1192 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1193 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1194
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1195 class svld1rq_impl : public load_replicate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1196 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1197 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1198 machine_mode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1199 memory_vector_mode (const function_instance &fi) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1200 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1201 return aarch64_vq_mode (GET_MODE_INNER (fi.vector_mode (0))).require ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1202 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1203
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1204 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1205 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1206 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1207 insn_code icode = code_for_aarch64_sve_ld1rq (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1208 return e.use_contiguous_load_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1209 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1210 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1211
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1212 class svld1ro_impl : public load_replicate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1213 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1214 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1215 machine_mode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1216 memory_vector_mode (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1217 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1218 return OImode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1219 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1220
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1221 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1222 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1223 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1224 insn_code icode = code_for_aarch64_sve_ld1ro (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1225 return e.use_contiguous_load_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1226 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1227 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1229 /* Implements svld2, svld3 and svld4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1230 class svld234_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1231 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1232 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1233 CONSTEXPR svld234_impl (unsigned int vectors_per_tuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1234 : full_width_access (vectors_per_tuple) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1235
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1236 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1237 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1238 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1239 return CP_READ_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1240 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1241
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1242 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1243 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1244 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1245 tree tuple_type = TREE_TYPE (f.lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1246 tree vectype = f.vector_type (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1247
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1248 /* Get the predicate and base pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1249 gimple_seq stmts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1250 tree pred = f.convert_pred (stmts, vectype, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1251 tree base = f.fold_contiguous_base (stmts, vectype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1252 gsi_insert_seq_before (f.gsi, stmts, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1253
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1254 /* Emit two statements: a clobber of the lhs, so that it isn't
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1255 upwards exposed, and then the load itself.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1256
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1257 The fold routines expect the replacement statement to have the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1258 same lhs as the original call, so return the clobber statement
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1259 rather than the load. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1260 gimple *clobber = gimple_build_assign (f.lhs, build_clobber (tuple_type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1262 /* View the loaded data as an array of vectors. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1263 tree field = tuple_type_field (tuple_type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1264 tree lhs_array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (field),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1265 unshare_expr (f.lhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1266
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1267 /* Emit the load itself. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1268 tree cookie = f.load_store_cookie (TREE_TYPE (vectype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1269 gcall *new_call = gimple_build_call_internal (IFN_MASK_LOAD_LANES, 3,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1270 base, cookie, pred);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1271 gimple_call_set_lhs (new_call, lhs_array);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1272 gsi_insert_after (f.gsi, new_call, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1273
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1274 return clobber;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1275 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1277 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1278 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1279 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1280 machine_mode tuple_mode = TYPE_MODE (TREE_TYPE (e.call_expr));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1281 insn_code icode = convert_optab_handler (vec_mask_load_lanes_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1282 tuple_mode, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1283 return e.use_contiguous_load_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1284 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1285 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1286
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1287 class svldff1_gather_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1288 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1289 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1290 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1291 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1292 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1293 return CP_READ_MEMORY | CP_READ_FFR | CP_WRITE_FFR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1294 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1295
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1296 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1297 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1298 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1299 /* See the block comment in aarch64-sve.md for details about the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1300 FFR handling. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1301 emit_insn (gen_aarch64_update_ffr_for_load ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1302
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1303 e.prepare_gather_address_operands (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1304 /* Put the predicate last, since ldff1_gather uses the same operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1305 order as mask_gather_load_optab. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1306 e.rotate_inputs_left (0, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1307 machine_mode mem_mode = e.memory_vector_mode ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1308 return e.use_exact_insn (code_for_aarch64_ldff1_gather (mem_mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1309 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1310 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1311
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1312 /* Implements extending forms of svldff1_gather. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1313 class svldff1_gather_extend : public extending_load
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1314 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1315 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1316 CONSTEXPR svldff1_gather_extend (type_suffix_index memory_type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1317 : extending_load (memory_type) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1318
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1319 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1320 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1321 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1322 /* See the block comment in aarch64-sve.md for details about the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1323 FFR handling. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1324 emit_insn (gen_aarch64_update_ffr_for_load ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1325
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1326 e.prepare_gather_address_operands (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1327 /* Put the predicate last, since ldff1_gather uses the same operand
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1328 order as mask_gather_load_optab. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1329 e.rotate_inputs_left (0, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1330 /* Add a constant predicate for the extension rtx. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1331 e.args.quick_push (CONSTM1_RTX (VNx16BImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1332 insn_code icode = code_for_aarch64_ldff1_gather (extend_rtx_code (),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1333 e.vector_mode (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1334 e.memory_vector_mode ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1335 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1336 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1337 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1338
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1339 class svldnt1_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1340 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1341 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1342 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1343 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1344 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1345 return CP_READ_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1346 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1347
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1348 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1349 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1350 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1351 insn_code icode = code_for_aarch64_ldnt1 (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1352 return e.use_contiguous_load_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1353 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1354 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1356 /* Implements svldff1 and svldnf1. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1357 class svldxf1_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1358 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1359 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1360 CONSTEXPR svldxf1_impl (int unspec) : m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1361
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1362 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1363 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1364 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1365 return CP_READ_MEMORY | CP_READ_FFR | CP_WRITE_FFR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1366 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1367
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1368 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1369 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1370 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1371 /* See the block comment in aarch64-sve.md for details about the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1372 FFR handling. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1373 emit_insn (gen_aarch64_update_ffr_for_load ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1374
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1375 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1376 return e.use_contiguous_load_insn (code_for_aarch64_ldf1 (m_unspec, mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1377 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1378
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1379 /* The unspec associated with the load. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1380 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1381 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1382
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1383 /* Implements extending contiguous forms of svldff1 and svldnf1. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1384 class svldxf1_extend_impl : public extending_load
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1385 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1386 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1387 CONSTEXPR svldxf1_extend_impl (type_suffix_index memory_type, int unspec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1388 : extending_load (memory_type), m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1389
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1390 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1391 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1392 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1393 return CP_READ_MEMORY | CP_READ_FFR | CP_WRITE_FFR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1394 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1395
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1396 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1397 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1398 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1399 /* See the block comment in aarch64-sve.md for details about the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1400 FFR handling. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1401 emit_insn (gen_aarch64_update_ffr_for_load ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1402
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1403 insn_code icode = code_for_aarch64_ldf1 (m_unspec, extend_rtx_code (),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1404 e.vector_mode (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1405 e.memory_vector_mode ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1406 return e.use_contiguous_load_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1407 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1408
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1409 /* The unspec associated with the load. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1410 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1411 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1412
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1413 class svlen_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1414 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1415 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1416 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1417 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1418 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1419 /* The argument only exists for its type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1420 tree rhs_type = TREE_TYPE (gimple_call_arg (f.call, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1421 tree count = build_int_cstu (TREE_TYPE (f.lhs),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1422 TYPE_VECTOR_SUBPARTS (rhs_type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1423 return gimple_build_assign (f.lhs, count);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1424 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1425
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1426 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1427 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1428 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1429 /* The argument only exists for its type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1430 return gen_int_mode (GET_MODE_NUNITS (e.vector_mode (0)), DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1431 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1432 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1434 class svmad_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1435 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1436 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1437 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1438 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1439 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1440 return expand_mad (e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1441 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1442 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1444 class svmla_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1445 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1446 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1447 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1448 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1449 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1450 /* Put the accumulator at the end (argument 3), but keep it as the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1451 merge input for _m functions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1452 e.rotate_inputs_left (1, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1453 return expand_mad (e, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1454 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1455 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1456
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1457 class svmla_lane_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1458 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1459 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1460 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1461 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1462 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1463 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1464 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1465 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1466 return e.use_exact_insn (code_for_aarch64_sve_add_mul_lane (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1467 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1468 return expand_mla_mls_lane (e, UNSPEC_FMLA);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1469 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1470 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1471
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1472 class svmls_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1473 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1474 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1475 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1476 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1477 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1478 /* Put the accumulator at the end (argument 3), but keep it as the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1479 merge input for _m functions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1480 e.rotate_inputs_left (1, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1481 return expand_msb (e, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1482 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1483 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1484
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1485 class svmov_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1486 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1487 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1488 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1489 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1490 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1491 return gimple_build_assign (f.lhs, BIT_AND_EXPR,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1492 gimple_call_arg (f.call, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1493 gimple_call_arg (f.call, 1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1494 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1495
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1496 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1497 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1498 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1499 /* The canonical form for the assembler alias "MOV Pa.B, Pb/Z, Pc.B"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1500 is "AND Pa.B, Pb/Z, Pc.B, Pc.B". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1501 gcc_assert (e.pred == PRED_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1502 e.args.quick_push (e.args[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1503 return e.use_exact_insn (CODE_FOR_aarch64_pred_andvnx16bi_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1504 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1505 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1507 class svmls_lane_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1508 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1509 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1510 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1511 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1512 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1513 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1514 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1515 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1516 return e.use_exact_insn (code_for_aarch64_sve_sub_mul_lane (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1517 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1518 return expand_mla_mls_lane (e, UNSPEC_FMLS);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1519 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1520 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1521
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1522 class svmmla_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1523 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1524 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1525 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1526 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1527 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1528 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1529 if (e.type_suffix (0).integer_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1530 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1531 if (e.type_suffix (0).unsigned_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1532 icode = code_for_aarch64_sve_add (UNSPEC_UMATMUL, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1533 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1534 icode = code_for_aarch64_sve_add (UNSPEC_SMATMUL, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1535 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1536 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1537 icode = code_for_aarch64_sve (UNSPEC_FMMLA, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1538 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1539 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1540 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1541
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1542 class svmsb_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1543 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1544 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1545 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1546 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1547 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1548 return expand_msb (e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1549 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1550 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1551
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1552 class svnand_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1553 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1554 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1555 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1556 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1557 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1558 gcc_assert (e.pred == PRED_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1559 return e.use_exact_insn (CODE_FOR_aarch64_pred_nandvnx16bi_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1560 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1561 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1562
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1563 class svnor_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1564 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1565 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1566 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1567 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1568 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1569 gcc_assert (e.pred == PRED_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1570 return e.use_exact_insn (CODE_FOR_aarch64_pred_norvnx16bi_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1571 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1572 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1573
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1574 class svnot_impl : public rtx_code_function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1575 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1576 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1577 CONSTEXPR svnot_impl () : rtx_code_function (NOT, NOT, -1) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1578
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1579 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1580 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1581 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1582 if (e.type_suffix_ids[0] == TYPE_SUFFIX_b)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1583 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1584 /* The canonical form for the assembler alias "NOT Pa.B, Pb/Z, Pc.B"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1585 is "EOR Pa.B, Pb/Z, Pb.B, Pc.B". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1586 gcc_assert (e.pred == PRED_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1587 e.args.quick_insert (1, e.args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1588 return e.use_exact_insn (CODE_FOR_aarch64_pred_xorvnx16bi_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1589 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1590 return rtx_code_function::expand (e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1591 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1592 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1593
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1594 class svorn_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1595 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1596 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1597 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1598 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1599 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1600 gcc_assert (e.pred == PRED_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1601 return e.use_exact_insn (CODE_FOR_aarch64_pred_ornvnx16bi_z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1602 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1603 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1604
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1605 class svpfalse_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1606 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1607 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1608 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1609 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1610 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1611 return f.fold_to_pfalse ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1612 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1613
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1614 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1615 expand (function_expander &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1616 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1617 return CONST0_RTX (VNx16BImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1618 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1619 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1620
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1621 /* Implements svpfirst and svpnext, which share the same .md patterns. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1622 class svpfirst_svpnext_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1623 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1624 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1625 CONSTEXPR svpfirst_svpnext_impl (int unspec) : m_unspec (unspec) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1626
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1627 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1628 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1629 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1630 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1631 e.add_ptrue_hint (0, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1632 return e.use_exact_insn (code_for_aarch64_sve (m_unspec, mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1633 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1634
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1635 /* The unspec associated with the operation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1636 int m_unspec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1637 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1638
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1639 /* Implements contiguous forms of svprf[bhwd]. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1640 class svprf_bhwd_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1641 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1642 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1643 CONSTEXPR svprf_bhwd_impl (machine_mode mode) : m_mode (mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1644
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1645 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1646 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1647 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1648 return CP_PREFETCH_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1649 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1650
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1651 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1652 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1653 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1654 e.prepare_prefetch_operands ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1655 insn_code icode = code_for_aarch64_sve_prefetch (m_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1656 return e.use_contiguous_prefetch_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1657 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1658
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1659 /* The mode that we'd use to hold one vector of prefetched data. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1660 machine_mode m_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1661 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1662
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1663 /* Implements svprf[bhwd]_gather. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1664 class svprf_bhwd_gather_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1665 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1666 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1667 CONSTEXPR svprf_bhwd_gather_impl (machine_mode mode) : m_mode (mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1668
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1669 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1670 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1671 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1672 return CP_PREFETCH_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1673 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1674
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1675 machine_mode
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1676 memory_vector_mode (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1677 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1678 return m_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1679 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1680
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1681 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1682 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1683 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1684 e.prepare_prefetch_operands ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1685 e.prepare_gather_address_operands (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1686
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1687 /* Insert a zero operand to identify the mode of the memory being
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1688 accessed. This goes between the gather operands and prefetch
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1689 operands created above. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1690 e.args.quick_insert (5, CONST0_RTX (m_mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1691
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1692 machine_mode reg_mode = GET_MODE (e.args[2]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1693 insn_code icode = code_for_aarch64_sve_gather_prefetch (m_mode, reg_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1694 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1695 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1696
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1697 /* The mode that we'd use to hold one vector of prefetched data. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1698 machine_mode m_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1699 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1700
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1701 /* Implements svptest_any, svptest_first and svptest_last. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1702 class svptest_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1703 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1704 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1705 CONSTEXPR svptest_impl (rtx_code compare) : m_compare (compare) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1706
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1707 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1708 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1709 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1710 /* See whether GP is an exact ptrue for some predicate mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1711 i.e. whether converting the GP to that mode will not drop
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1712 set bits and will leave all significant bits set. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1713 machine_mode wide_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1714 int hint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1715 if (aarch64_ptrue_all_mode (e.args[0]).exists (&wide_mode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1716 hint = SVE_KNOWN_PTRUE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1717 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1718 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1719 hint = SVE_MAYBE_NOT_PTRUE;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1720 wide_mode = VNx16BImode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1721 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1722
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1723 /* Generate the PTEST itself. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1724 rtx pg = force_reg (VNx16BImode, e.args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1725 rtx wide_pg = gen_lowpart (wide_mode, pg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1726 rtx hint_rtx = gen_int_mode (hint, DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1727 rtx op = force_reg (wide_mode, gen_lowpart (wide_mode, e.args[1]));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1728 emit_insn (gen_aarch64_ptestvnx16bi (pg, wide_pg, hint_rtx, op));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1729
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1730 /* Get the location of the boolean result. We can provide SImode and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1731 DImode values directly; rely on generic code to convert others. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1732 rtx target = e.possible_target;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1733 if (!target
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1734 || !REG_P (target)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1735 || (GET_MODE (target) != SImode && GET_MODE (target) != DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1736 target = gen_reg_rtx (DImode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1737
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1738 /* Generate a CSET to convert the CC result of the PTEST to a boolean. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1739 rtx cc_reg = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1740 rtx compare = gen_rtx_fmt_ee (m_compare, GET_MODE (target),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1741 cc_reg, const0_rtx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1742 emit_insn (gen_rtx_SET (target, compare));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1743 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1744 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1745
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1746 /* The comparison code associated with ptest condition. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1747 rtx_code m_compare;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1748 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1749
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1750 class svptrue_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1751 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1752 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1753 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1754 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1755 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1756 return f.fold_to_ptrue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1757 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1758
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1759 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1760 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1761 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1762 return aarch64_ptrue_all (e.type_suffix (0).element_bytes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1763 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1764 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1765
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1766 class svptrue_pat_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1767 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1768 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1769 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1770 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1771 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1772 tree pattern_arg = gimple_call_arg (f.call, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1773 aarch64_svpattern pattern = (aarch64_svpattern) tree_to_shwi (pattern_arg);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1774
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1775 if (pattern == AARCH64_SV_ALL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1776 /* svptrue_pat_bN (SV_ALL) == svptrue_bN (). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1777 return f.fold_to_ptrue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1778
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1779 /* See whether we can count the number of elements in the pattern
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1780 at compile time. If so, construct a predicate with that number
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1781 of 1s followed by all 0s. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1782 int nelts_per_vq = f.elements_per_vq (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1783 HOST_WIDE_INT value = aarch64_fold_sve_cnt_pat (pattern, nelts_per_vq);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1784 if (value >= 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1785 return f.fold_to_vl_pred (value);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1786
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1787 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1788 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1789
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1790 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1791 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1792 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1793 /* In rtl, the predicate is represented as the constant:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1794
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1795 (const:V16BI (unspec:V16BI [(const_int PATTERN)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1796 (const_vector:VnnBI [zeros])]
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1797 UNSPEC_PTRUE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1798
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1799 where nn determines the element size. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1800 rtvec vec = gen_rtvec (2, e.args[0], CONST0_RTX (e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1801 return gen_rtx_CONST (VNx16BImode,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1802 gen_rtx_UNSPEC (VNx16BImode, vec, UNSPEC_PTRUE));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1803 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1804 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1805
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1806 /* Implements svqdec[bhwd]{,_pat} and svqinc[bhwd]{,_pat}. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1807 class svqdec_svqinc_bhwd_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1808 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1809 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1810 CONSTEXPR svqdec_svqinc_bhwd_impl (rtx_code code_for_sint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1811 rtx_code code_for_uint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1812 scalar_int_mode elem_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1813 : m_code_for_sint (code_for_sint),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1814 m_code_for_uint (code_for_uint),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1815 m_elem_mode (elem_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1816 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1817
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1818 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1819 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1820 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1821 /* Treat non-_pat functions in the same way as _pat functions with
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1822 an SV_ALL argument. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1823 if (e.args.length () == 2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1824 e.args.quick_insert (1, gen_int_mode (AARCH64_SV_ALL, DImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1825
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1826 /* Insert the number of elements per 128-bit block as a fake argument,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1827 between the pattern and the multiplier. Arguments 1, 2 and 3 then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1828 correspond exactly with the 3 UNSPEC_SVE_CNT_PAT operands; see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1829 aarch64_sve_cnt_pat for details. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1830 unsigned int elements_per_vq = 128 / GET_MODE_BITSIZE (m_elem_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1831 e.args.quick_insert (2, gen_int_mode (elements_per_vq, DImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1832
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1833 rtx_code code = (e.type_suffix (0).unsigned_p
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1834 ? m_code_for_uint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1835 : m_code_for_sint);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1836
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1837 /* Choose between operating on integer scalars or integer vectors. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1838 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1839 if (e.mode_suffix_id == MODE_n)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1840 mode = GET_MODE_INNER (mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1841 return e.use_exact_insn (code_for_aarch64_sve_pat (code, mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1842 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1843
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1844 /* The saturating addition or subtraction codes to use for signed and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1845 unsigned values respectively. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1846 rtx_code m_code_for_sint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1847 rtx_code m_code_for_uint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1848
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1849 /* The integer mode associated with the [bhwd] suffix. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1850 scalar_int_mode m_elem_mode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1851 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1852
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1853 /* Implements svqdec[bhwd]{,_pat}. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1854 class svqdec_bhwd_impl : public svqdec_svqinc_bhwd_impl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1855 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1856 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1857 CONSTEXPR svqdec_bhwd_impl (scalar_int_mode elem_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1858 : svqdec_svqinc_bhwd_impl (SS_MINUS, US_MINUS, elem_mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1859 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1860
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1861 /* Implements svqinc[bhwd]{,_pat}. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1862 class svqinc_bhwd_impl : public svqdec_svqinc_bhwd_impl
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1863 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1864 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1865 CONSTEXPR svqinc_bhwd_impl (scalar_int_mode elem_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1866 : svqdec_svqinc_bhwd_impl (SS_PLUS, US_PLUS, elem_mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1867 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1868
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1869 /* Implements svqdecp and svqincp. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1870 class svqdecp_svqincp_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1871 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1872 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1873 CONSTEXPR svqdecp_svqincp_impl (rtx_code code_for_sint,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1874 rtx_code code_for_uint)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1875 : m_code_for_sint (code_for_sint),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1876 m_code_for_uint (code_for_uint)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1877 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1878
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1879 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1880 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1881 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1882 rtx_code code = (e.type_suffix (0).unsigned_p
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1883 ? m_code_for_uint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1884 : m_code_for_sint);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1885 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1886 if (e.mode_suffix_id == MODE_n)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1887 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1888 /* Increment or decrement a scalar (whose mode is given by the first
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1889 type suffix) by the number of active elements in a predicate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1890 (whose mode is given by the second type suffix). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1891 machine_mode mode = GET_MODE_INNER (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1892 icode = code_for_aarch64_sve_cntp (code, mode, e.vector_mode (1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1893 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1894 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1895 /* Increment a vector by the number of active elements in a predicate,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1896 with the vector mode determining the predicate mode. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1897 icode = code_for_aarch64_sve_cntp (code, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1898 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1899 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1900
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1901 /* The saturating addition or subtraction codes to use for signed and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1902 unsigned values respectively. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1903 rtx_code m_code_for_sint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1904 rtx_code m_code_for_uint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1905 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1906
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1907 class svrdffr_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1908 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1909 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1910 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1911 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1912 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1913 return CP_READ_FFR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1914 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1915
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1916 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1917 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1918 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1919 /* See the block comment in aarch64-sve.md for details about the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1920 FFR handling. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1921 emit_insn (gen_aarch64_copy_ffr_to_ffrt ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1922 rtx result = e.use_exact_insn (e.pred == PRED_z
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1923 ? CODE_FOR_aarch64_rdffr_z
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1924 : CODE_FOR_aarch64_rdffr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1925 emit_insn (gen_aarch64_update_ffrt ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1926 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1927 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1928 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1929
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1930 class svreinterpret_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1931 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1932 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1933 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1934 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1935 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1936 /* Punt to rtl if the effect of the reinterpret on registers does not
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1937 conform to GCC's endianness model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1938 if (!targetm.can_change_mode_class (f.vector_mode (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1939 f.vector_mode (1), FP_REGS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1940 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1941
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1942 /* Otherwise svreinterpret corresponds directly to a VIEW_CONVERT_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1943 reinterpretation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1944 tree rhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (f.lhs),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1945 gimple_call_arg (f.call, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1946 return gimple_build_assign (f.lhs, VIEW_CONVERT_EXPR, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1947 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1948
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1949 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1950 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1951 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1952 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1953 return e.use_exact_insn (code_for_aarch64_sve_reinterpret (mode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1954 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1955 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1956
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1957 class svrev_impl : public permute
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1958 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1959 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1960 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1961 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1962 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1963 /* Punt for now on _b16 and wider; we'd need more complex evpc logic
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1964 to rerecognize the result. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1965 if (f.type_suffix (0).bool_p && f.type_suffix (0).element_bits > 8)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1966 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1967
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1968 /* Permute as { nelts - 1, nelts - 2, nelts - 3, ... }. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1969 poly_int64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (f.lhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1970 vec_perm_builder builder (nelts, 1, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1971 for (int i = 0; i < 3; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1972 builder.quick_push (nelts - i - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1973 return fold_permute (f, builder);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1974 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1975
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1976 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1977 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1978 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1979 return e.use_exact_insn (code_for_aarch64_sve_rev (e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1980 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1981 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1982
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1983 class svsel_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1984 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1985 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1986 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1987 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1988 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1989 /* svsel corresponds exactly to VEC_COND_EXPR. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1990 gimple_seq stmts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1991 tree pred = f.convert_pred (stmts, f.vector_type (0), 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1992 gsi_insert_seq_before (f.gsi, stmts, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1993 return gimple_build_assign (f.lhs, VEC_COND_EXPR, pred,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1994 gimple_call_arg (f.call, 1),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1995 gimple_call_arg (f.call, 2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1996 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1997
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1998 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1999 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2000 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2001 /* svsel (cond, truev, falsev) is vcond_mask (truev, falsev, cond). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2002 e.rotate_inputs_left (0, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2003 insn_code icode = convert_optab_handler (vcond_mask_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2004 e.vector_mode (0),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2005 e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2006 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2007 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2008 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2009
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2010 /* Implements svset2, svset3 and svset4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2011 class svset_impl : public quiet<multi_vector_function>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2012 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2013 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2014 CONSTEXPR svset_impl (unsigned int vectors_per_tuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2015 : quiet<multi_vector_function> (vectors_per_tuple) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2016
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2017 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2018 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2019 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2020 tree rhs_tuple = gimple_call_arg (f.call, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2021 tree index = gimple_call_arg (f.call, 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2022 tree rhs_vector = gimple_call_arg (f.call, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2023
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2024 /* Replace the call with two statements: a copy of the full tuple
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2025 to the call result, followed by an update of the individual vector.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2026
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2027 The fold routines expect the replacement statement to have the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2028 same lhs as the original call, so return the copy statement
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2029 rather than the field update. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2030 gassign *copy = gimple_build_assign (unshare_expr (f.lhs), rhs_tuple);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2031
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2032 /* Get a reference to the individual vector. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2033 tree field = tuple_type_field (TREE_TYPE (f.lhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2034 tree lhs_array = build3 (COMPONENT_REF, TREE_TYPE (field),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2035 f.lhs, field, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2036 tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2037 lhs_array, index, NULL_TREE, NULL_TREE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2038 gassign *update = gimple_build_assign (lhs_vector, rhs_vector);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2039 gsi_insert_after (f.gsi, update, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2040
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2041 return copy;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2042 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2043
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2044 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2045 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2046 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2047 rtx rhs_tuple = e.args[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2048 unsigned int index = INTVAL (e.args[1]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2049 rtx rhs_vector = e.args[2];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2050
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2051 /* First copy the full tuple to the target register. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2052 rtx lhs_tuple = e.get_nonoverlapping_reg_target ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2053 emit_move_insn (lhs_tuple, rhs_tuple);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2054
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2055 /* ...then update the individual vector. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2056 rtx lhs_vector = simplify_gen_subreg (GET_MODE (rhs_vector),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2057 lhs_tuple, GET_MODE (lhs_tuple),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2058 index * BYTES_PER_SVE_VECTOR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2059 emit_move_insn (lhs_vector, rhs_vector);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2060 return lhs_vector;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2061 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2062 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2063
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2064 class svsetffr_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2065 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2066 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2067 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2068 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2069 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2070 return CP_WRITE_FFR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2071 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2072
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2073 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2074 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2075 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2076 e.args.quick_push (CONSTM1_RTX (VNx16BImode));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2077 return e.use_exact_insn (CODE_FOR_aarch64_wrffr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2078 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2079 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2080
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2081 class svst1_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2082 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2083 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2084 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2085 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2086 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2087 return CP_WRITE_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2088 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2089
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2090 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2091 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2092 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2093 tree vectype = f.vector_type (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2094
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2095 /* Get the predicate and base pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2096 gimple_seq stmts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2097 tree pred = f.convert_pred (stmts, vectype, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2098 tree base = f.fold_contiguous_base (stmts, vectype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2099 gsi_insert_seq_before (f.gsi, stmts, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2100
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2101 tree cookie = f.load_store_cookie (TREE_TYPE (vectype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2102 tree rhs = gimple_call_arg (f.call, gimple_call_num_args (f.call) - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2103 return gimple_build_call_internal (IFN_MASK_STORE, 4,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2104 base, cookie, pred, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2105 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2106
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2107 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2108 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2109 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2110 insn_code icode = convert_optab_handler (maskstore_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2111 e.vector_mode (0), e.gp_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2112 return e.use_contiguous_store_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2113 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2114 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2115
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2116 class svst1_scatter_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2117 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2118 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2119 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2120 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2121 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2122 return CP_WRITE_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2123 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2124
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2125 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2126 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2127 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2128 e.prepare_gather_address_operands (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2129 /* Put the predicate last, as required by mask_scatter_store_optab. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2130 e.rotate_inputs_left (0, 6);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2131 machine_mode mem_mode = e.memory_vector_mode ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2132 machine_mode int_mode = aarch64_sve_int_mode (mem_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2133 insn_code icode = convert_optab_handler (mask_scatter_store_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2134 mem_mode, int_mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2135 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2136 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2137 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2139 /* Implements truncating forms of svst1_scatter. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2140 class svst1_scatter_truncate_impl : public truncating_store
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2141 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2142 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2143 CONSTEXPR svst1_scatter_truncate_impl (scalar_int_mode to_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2144 : truncating_store (to_mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2146 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2147 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2148 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2149 e.prepare_gather_address_operands (1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2150 /* Put the predicate last, since the truncating scatters use the same
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2151 operand order as mask_scatter_store_optab. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2152 e.rotate_inputs_left (0, 6);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2153 insn_code icode = code_for_aarch64_scatter_store_trunc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2154 (e.memory_vector_mode (), e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2155 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2156 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2157 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2158
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2159 /* Implements truncating contiguous forms of svst1. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2160 class svst1_truncate_impl : public truncating_store
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2161 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2162 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2163 CONSTEXPR svst1_truncate_impl (scalar_int_mode to_mode)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2164 : truncating_store (to_mode) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2165
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2166 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2167 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2168 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2169 insn_code icode = code_for_aarch64_store_trunc (e.memory_vector_mode (),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2170 e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2171 return e.use_contiguous_store_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2172 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2173 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2174
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2175 /* Implements svst2, svst3 and svst4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2176 class svst234_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2177 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2178 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2179 CONSTEXPR svst234_impl (unsigned int vectors_per_tuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2180 : full_width_access (vectors_per_tuple) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2181
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2182 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2183 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2184 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2185 return CP_WRITE_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2186 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2187
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2188 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2189 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2190 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2191 tree vectype = f.vector_type (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2192
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2193 /* Get the predicate and base pointer. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2194 gimple_seq stmts = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2195 tree pred = f.convert_pred (stmts, vectype, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2196 tree base = f.fold_contiguous_base (stmts, vectype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2197 gsi_insert_seq_before (f.gsi, stmts, GSI_SAME_STMT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2198
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2199 /* View the stored data as an array of vectors. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2200 unsigned int num_args = gimple_call_num_args (f.call);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2201 tree rhs_tuple = gimple_call_arg (f.call, num_args - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2202 tree field = tuple_type_field (TREE_TYPE (rhs_tuple));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2203 tree rhs_array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (field), rhs_tuple);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2204
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2205 tree cookie = f.load_store_cookie (TREE_TYPE (vectype));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2206 return gimple_build_call_internal (IFN_MASK_STORE_LANES, 4,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2207 base, cookie, pred, rhs_array);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2208 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2210 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2211 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2212 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2213 machine_mode tuple_mode = GET_MODE (e.args.last ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2214 insn_code icode = convert_optab_handler (vec_mask_store_lanes_optab,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2215 tuple_mode, e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2216 return e.use_contiguous_store_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2217 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2218 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2220 class svstnt1_impl : public full_width_access
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2221 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2222 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2223 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2224 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2225 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2226 return CP_WRITE_MEMORY;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2227 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2229 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2230 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2231 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2232 insn_code icode = code_for_aarch64_stnt1 (e.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2233 return e.use_contiguous_store_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2234 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2235 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2236
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2237 class svsub_impl : public rtx_code_function
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2238 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2239 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2240 CONSTEXPR svsub_impl ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2241 : rtx_code_function (MINUS, MINUS, UNSPEC_COND_FSUB) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2242
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2243 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2244 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2245 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2246 /* Canonicalize subtractions of constants to additions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2247 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2248 if (e.try_negating_argument (2, mode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2249 return e.map_to_rtx_codes (PLUS, PLUS, UNSPEC_COND_FADD);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2250
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2251 return rtx_code_function::expand (e);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2252 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2253 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2254
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2255 class svtbl_impl : public permute
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2256 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2257 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2258 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2259 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2260 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2261 return e.use_exact_insn (code_for_aarch64_sve_tbl (e.vector_mode (0)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2262 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2263 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2264
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2265 /* Implements svtrn1 and svtrn2. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2266 class svtrn_impl : public binary_permute
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2267 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2268 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2269 CONSTEXPR svtrn_impl (int base)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2270 : binary_permute (base ? UNSPEC_TRN2 : UNSPEC_TRN1), m_base (base) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2271
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2272 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2273 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2274 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2275 /* svtrn1: { 0, nelts, 2, nelts + 2, 4, nelts + 4, ... }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2276 svtrn2: as for svtrn1, but with 1 added to each index. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2277 poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (f.lhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2278 vec_perm_builder builder (nelts, 2, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2279 for (unsigned int i = 0; i < 3; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2280 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2281 builder.quick_push (m_base + i * 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2282 builder.quick_push (m_base + i * 2 + nelts);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2283 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2284 return fold_permute (f, builder);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2285 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2286
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2287 /* 0 for svtrn1, 1 for svtrn2. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2288 unsigned int m_base;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2289 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2290
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2291 /* Base class for svundef{,2,3,4}. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2292 class svundef_impl : public quiet<multi_vector_function>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2293 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2294 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2295 CONSTEXPR svundef_impl (unsigned int vectors_per_tuple)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2296 : quiet<multi_vector_function> (vectors_per_tuple) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2297
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2298 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2299 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2300 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2301 /* Don't fold svundef at the gimple level. There's no exact
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2302 correspondence for SSA_NAMEs, and we explicitly don't want
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2303 to generate a specific value (like an all-zeros vector). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2304 if (vectors_per_tuple () == 1)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2305 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2306 return gimple_build_assign (f.lhs, build_clobber (TREE_TYPE (f.lhs)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2307 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2308
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2309 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2310 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2311 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2312 rtx target = e.get_reg_target ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2313 emit_clobber (copy_rtx (target));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2314 return target;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2315 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2316 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2317
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2318 /* Implements svunpklo and svunpkhi. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2319 class svunpk_impl : public quiet<function_base>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2320 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2321 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2322 CONSTEXPR svunpk_impl (bool high_p) : m_high_p (high_p) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2323
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2324 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2325 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2326 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2327 /* Don't fold the predicate ops, since every bit of the svbool_t
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2328 result is significant. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2329 if (f.type_suffix_ids[0] == TYPE_SUFFIX_b)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2330 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2331
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2332 /* The first half in memory is VEC_UNPACK_LO_EXPR for little-endian
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2333 and VEC_UNPACK_HI_EXPR for big-endian. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2334 bool high_p = BYTES_BIG_ENDIAN ? !m_high_p : m_high_p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2335 tree_code code = high_p ? VEC_UNPACK_HI_EXPR : VEC_UNPACK_LO_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2336 return gimple_build_assign (f.lhs, code, gimple_call_arg (f.call, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2337 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2338
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2339 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2340 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2341 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2342 machine_mode mode = GET_MODE (e.args[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2343 unsigned int unpacku = m_high_p ? UNSPEC_UNPACKUHI : UNSPEC_UNPACKULO;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2344 unsigned int unpacks = m_high_p ? UNSPEC_UNPACKSHI : UNSPEC_UNPACKSLO;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2345 insn_code icode;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2346 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2347 icode = code_for_aarch64_sve_punpk (unpacku, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2348 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2349 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2350 int unspec = e.type_suffix (0).unsigned_p ? unpacku : unpacks;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2351 icode = code_for_aarch64_sve_unpk (unspec, unspec, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2352 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2353 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2354 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2356 /* True for svunpkhi, false for svunpklo. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2357 bool m_high_p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2358 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2359
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2360 /* Also implements svsudot. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2361 class svusdot_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2362 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2363 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2364 CONSTEXPR svusdot_impl (bool su) : m_su (su) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2365
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2366 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2367 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2368 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2369 /* The implementation of the ACLE function svsudot (for the non-lane
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2370 version) is through the USDOT instruction but with the second and third
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2371 inputs swapped. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2372 if (m_su)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2373 e.rotate_inputs_left (1, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2374 /* The ACLE function has the same order requirements as for svdot.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2375 While there's no requirement for the RTL pattern to have the same sort
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2376 of order as that for <sur>dot_prod, it's easier to read.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2377 Hence we do the same rotation on arguments as svdot_impl does. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2378 e.rotate_inputs_left (0, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2379 machine_mode mode = e.vector_mode (0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2380 insn_code icode = code_for_aarch64_dot_prod (UNSPEC_USDOT, mode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2381 return e.use_exact_insn (icode);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2382 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2383
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2384 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2385 bool m_su;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2386 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2387
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2388 /* Implements svuzp1 and svuzp2. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2389 class svuzp_impl : public binary_permute
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2390 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2391 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2392 CONSTEXPR svuzp_impl (unsigned int base)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2393 : binary_permute (base ? UNSPEC_UZP2 : UNSPEC_UZP1), m_base (base) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2394
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2395 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2396 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2397 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2398 /* svuzp1: { 0, 2, 4, 6, ... }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2399 svuzp2: { 1, 3, 5, 7, ... }. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2400 poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (f.lhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2401 vec_perm_builder builder (nelts, 1, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2402 for (unsigned int i = 0; i < 3; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2403 builder.quick_push (m_base + i * 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2404 return fold_permute (f, builder);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2405 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2406
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2407 /* 0 for svuzp1, 1 for svuzp2. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2408 unsigned int m_base;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2409 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2410
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2411 /* A function_base for svwhilele and svwhilelt functions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2412 class svwhilelx_impl : public while_comparison
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2413 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2414 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2415 CONSTEXPR svwhilelx_impl (int unspec_for_sint, int unspec_for_uint, bool eq_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2416 : while_comparison (unspec_for_sint, unspec_for_uint), m_eq_p (eq_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2417 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2418
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2419 /* Try to fold a call by treating its arguments as constants of type T. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2420 template<typename T>
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2421 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2422 fold_type (gimple_folder &f) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2423 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2424 /* Only handle cases in which both operands are constant. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2425 T arg0, arg1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2426 if (!poly_int_tree_p (gimple_call_arg (f.call, 0), &arg0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2427 || !poly_int_tree_p (gimple_call_arg (f.call, 1), &arg1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2428 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2429
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2430 /* Check whether the result is known to be all-false. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2431 if (m_eq_p ? known_gt (arg0, arg1) : known_ge (arg0, arg1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2432 return f.fold_to_pfalse ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2433
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2434 /* Punt if we can't tell at compile time whether the result
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2435 is all-false. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2436 if (m_eq_p ? maybe_gt (arg0, arg1) : maybe_ge (arg0, arg1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2437 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2438
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2439 /* At this point we know the result has at least one set element. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2440 poly_uint64 diff = arg1 - arg0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2441 poly_uint64 nelts = GET_MODE_NUNITS (f.vector_mode (0));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2442
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2443 /* Canonicalize the svwhilele form to the svwhilelt form. Subtract
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2444 from NELTS rather than adding to DIFF, to prevent overflow. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2445 if (m_eq_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2446 nelts -= 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2447
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2448 /* Check whether the result is known to be all-true. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2449 if (known_ge (diff, nelts))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2450 return f.fold_to_ptrue ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2451
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2452 /* Punt if DIFF might not be the actual number of set elements
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2453 in the result. Conditional equality is fine. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2454 if (maybe_gt (diff, nelts))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2455 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2456
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2457 /* At this point we know that the predicate will have DIFF set elements
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2458 for svwhilelt and DIFF + 1 set elements for svwhilele (which stops
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2459 after rather than before ARG1 is reached). See if we can create
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2460 the predicate at compile time. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2461 unsigned HOST_WIDE_INT vl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2462 if (diff.is_constant (&vl))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2463 /* Overflow is no longer possible after the checks above. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2464 return f.fold_to_vl_pred (m_eq_p ? vl + 1 : vl);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2465
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2466 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2467 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2468
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2469 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2470 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2471 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2472 if (f.type_suffix (1).unsigned_p)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2473 return fold_type<poly_uint64> (f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2474 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2475 return fold_type<poly_int64> (f);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2476 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2477
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2478 /* True svwhilele, false for svwhilelt. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2479 bool m_eq_p;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2480 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2481
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2482 class svwrffr_impl : public function_base
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2483 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2484 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2485 unsigned int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2486 call_properties (const function_instance &) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2487 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2488 return CP_WRITE_FFR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2489 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2490
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2491 rtx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2492 expand (function_expander &e) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2493 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2494 return e.use_exact_insn (CODE_FOR_aarch64_wrffr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2495 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2496 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2497
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2498 /* Implements svzip1 and svzip2. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2499 class svzip_impl : public binary_permute
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2500 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2501 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2502 CONSTEXPR svzip_impl (unsigned int base)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2503 : binary_permute (base ? UNSPEC_ZIP2 : UNSPEC_ZIP1), m_base (base) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2504
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2505 gimple *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2506 fold (gimple_folder &f) const OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2507 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2508 /* svzip1: { 0, nelts, 1, nelts + 1, 2, nelts + 2, ... }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2509 svzip2: as for svzip1, but with nelts / 2 added to each index. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2510 poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (f.lhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2511 poly_uint64 base = m_base * exact_div (nelts, 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2512 vec_perm_builder builder (nelts, 2, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2513 for (unsigned int i = 0; i < 3; ++i)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2514 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2515 builder.quick_push (base + i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2516 builder.quick_push (base + i + nelts);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2517 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2518 return fold_permute (f, builder);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2519 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2520
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2521 /* 0 for svzip1, 1 for svzip2. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2522 unsigned int m_base;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2523 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2524
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2525 } /* end anonymous namespace */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2526
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2527 namespace aarch64_sve {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2528
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2529 FUNCTION (svabd, svabd_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2530 FUNCTION (svabs, quiet<rtx_code_function>, (ABS, ABS, UNSPEC_COND_FABS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2531 FUNCTION (svacge, svac_impl, (UNSPEC_COND_FCMGE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2532 FUNCTION (svacgt, svac_impl, (UNSPEC_COND_FCMGT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2533 FUNCTION (svacle, svac_impl, (UNSPEC_COND_FCMLE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2534 FUNCTION (svaclt, svac_impl, (UNSPEC_COND_FCMLT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2535 FUNCTION (svadd, rtx_code_function, (PLUS, PLUS, UNSPEC_COND_FADD))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2536 FUNCTION (svadda, svadda_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2537 FUNCTION (svaddv, reduction, (UNSPEC_SADDV, UNSPEC_UADDV, UNSPEC_FADDV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2538 FUNCTION (svadrb, svadr_bhwd_impl, (0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2539 FUNCTION (svadrd, svadr_bhwd_impl, (3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2540 FUNCTION (svadrh, svadr_bhwd_impl, (1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2541 FUNCTION (svadrw, svadr_bhwd_impl, (2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2542 FUNCTION (svand, rtx_code_function, (AND, AND))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2543 FUNCTION (svandv, reduction, (UNSPEC_ANDV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2544 FUNCTION (svasr, rtx_code_function, (ASHIFTRT, ASHIFTRT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2545 FUNCTION (svasr_wide, shift_wide, (ASHIFTRT, UNSPEC_ASHIFTRT_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2546 FUNCTION (svasrd, unspec_based_function, (UNSPEC_ASRD, -1, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2547 FUNCTION (svbfdot, fixed_insn_function, (CODE_FOR_aarch64_sve_bfdotvnx4sf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2548 FUNCTION (svbfdot_lane, fixed_insn_function,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2549 (CODE_FOR_aarch64_sve_bfdot_lanevnx4sf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2550 FUNCTION (svbfmlalb, fixed_insn_function, (CODE_FOR_aarch64_sve_bfmlalbvnx4sf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2551 FUNCTION (svbfmlalb_lane, fixed_insn_function,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2552 (CODE_FOR_aarch64_sve_bfmlalb_lanevnx4sf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2553 FUNCTION (svbfmlalt, fixed_insn_function, (CODE_FOR_aarch64_sve_bfmlaltvnx4sf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2554 FUNCTION (svbfmlalt_lane, fixed_insn_function,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2555 (CODE_FOR_aarch64_sve_bfmlalt_lanevnx4sf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2556 FUNCTION (svbfmmla, fixed_insn_function, (CODE_FOR_aarch64_sve_bfmmlavnx4sf))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2557 FUNCTION (svbic, svbic_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2558 FUNCTION (svbrka, svbrk_unary_impl, (UNSPEC_BRKA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2559 FUNCTION (svbrkb, svbrk_unary_impl, (UNSPEC_BRKB))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2560 FUNCTION (svbrkn, svbrk_binary_impl, (UNSPEC_BRKN))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2561 FUNCTION (svbrkpa, svbrk_binary_impl, (UNSPEC_BRKPA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2562 FUNCTION (svbrkpb, svbrk_binary_impl, (UNSPEC_BRKPB))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2563 FUNCTION (svcadd, svcadd_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2564 FUNCTION (svclasta, svclast_impl, (UNSPEC_CLASTA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2565 FUNCTION (svclastb, svclast_impl, (UNSPEC_CLASTB))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2566 FUNCTION (svcls, unary_count, (CLRSB))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2567 FUNCTION (svclz, unary_count, (CLZ))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2568 FUNCTION (svcmla, svcmla_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2569 FUNCTION (svcmla_lane, svcmla_lane_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2570 FUNCTION (svcmpeq, svcmp_impl, (EQ_EXPR, UNSPEC_COND_FCMEQ))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2571 FUNCTION (svcmpeq_wide, svcmp_wide_impl, (EQ_EXPR, UNSPEC_COND_CMPEQ_WIDE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2572 UNSPEC_COND_CMPEQ_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2573 FUNCTION (svcmpge, svcmp_impl, (GE_EXPR, UNSPEC_COND_FCMGE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2574 FUNCTION (svcmpge_wide, svcmp_wide_impl, (GE_EXPR, UNSPEC_COND_CMPGE_WIDE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2575 UNSPEC_COND_CMPHS_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2576 FUNCTION (svcmpgt, svcmp_impl, (GT_EXPR, UNSPEC_COND_FCMGT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2577 FUNCTION (svcmpgt_wide, svcmp_wide_impl, (GT_EXPR, UNSPEC_COND_CMPGT_WIDE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2578 UNSPEC_COND_CMPHI_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2579 FUNCTION (svcmple, svcmp_impl, (LE_EXPR, UNSPEC_COND_FCMLE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2580 FUNCTION (svcmple_wide, svcmp_wide_impl, (LE_EXPR, UNSPEC_COND_CMPLE_WIDE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2581 UNSPEC_COND_CMPLS_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2582 FUNCTION (svcmplt, svcmp_impl, (LT_EXPR, UNSPEC_COND_FCMLT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2583 FUNCTION (svcmplt_wide, svcmp_wide_impl, (LT_EXPR, UNSPEC_COND_CMPLT_WIDE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2584 UNSPEC_COND_CMPLO_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2585 FUNCTION (svcmpne, svcmp_impl, (NE_EXPR, UNSPEC_COND_FCMNE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2586 FUNCTION (svcmpne_wide, svcmp_wide_impl, (NE_EXPR, UNSPEC_COND_CMPNE_WIDE,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2587 UNSPEC_COND_CMPNE_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2588 FUNCTION (svcmpuo, svcmpuo_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2589 FUNCTION (svcnot, svcnot_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2590 FUNCTION (svcnt, unary_count, (POPCOUNT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2591 FUNCTION (svcntb, svcnt_bhwd_impl, (VNx16QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2592 FUNCTION (svcntb_pat, svcnt_bhwd_pat_impl, (VNx16QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2593 FUNCTION (svcntd, svcnt_bhwd_impl, (VNx2DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2594 FUNCTION (svcntd_pat, svcnt_bhwd_pat_impl, (VNx2DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2595 FUNCTION (svcnth, svcnt_bhwd_impl, (VNx8HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2596 FUNCTION (svcnth_pat, svcnt_bhwd_pat_impl, (VNx8HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2597 FUNCTION (svcntp, svcntp_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2598 FUNCTION (svcntw, svcnt_bhwd_impl, (VNx4SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2599 FUNCTION (svcntw_pat, svcnt_bhwd_pat_impl, (VNx4SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2600 FUNCTION (svcompact, QUIET_CODE_FOR_MODE0 (aarch64_sve_compact),)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2601 FUNCTION (svcreate2, svcreate_impl, (2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2602 FUNCTION (svcreate3, svcreate_impl, (3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2603 FUNCTION (svcreate4, svcreate_impl, (4))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2604 FUNCTION (svcvt, svcvt_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2605 FUNCTION (svcvtnt, CODE_FOR_MODE0 (aarch64_sve_cvtnt),)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2606 FUNCTION (svdiv, rtx_code_function, (DIV, UDIV, UNSPEC_COND_FDIV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2607 FUNCTION (svdivr, rtx_code_function_rotated, (DIV, UDIV, UNSPEC_COND_FDIV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2608 FUNCTION (svdot, svdot_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2609 FUNCTION (svdot_lane, svdotprod_lane_impl, (UNSPEC_SDOT, UNSPEC_UDOT, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2610 FUNCTION (svdup, svdup_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2611 FUNCTION (svdup_lane, svdup_lane_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2612 FUNCTION (svdupq, svdupq_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2613 FUNCTION (svdupq_lane, svdupq_lane_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2614 FUNCTION (sveor, rtx_code_function, (XOR, XOR, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2615 FUNCTION (sveorv, reduction, (UNSPEC_XORV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2616 FUNCTION (svexpa, unspec_based_function, (-1, -1, UNSPEC_FEXPA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2617 FUNCTION (svext, QUIET_CODE_FOR_MODE0 (aarch64_sve_ext),)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2618 FUNCTION (svextb, svext_bhw_impl, (QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2619 FUNCTION (svexth, svext_bhw_impl, (HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2620 FUNCTION (svextw, svext_bhw_impl, (SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2621 FUNCTION (svget2, svget_impl, (2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2622 FUNCTION (svget3, svget_impl, (3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2623 FUNCTION (svget4, svget_impl, (4))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2624 FUNCTION (svindex, svindex_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2625 FUNCTION (svinsr, svinsr_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2626 FUNCTION (svlasta, svlast_impl, (UNSPEC_LASTA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2627 FUNCTION (svlastb, svlast_impl, (UNSPEC_LASTB))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2628 FUNCTION (svld1, svld1_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2629 FUNCTION (svld1_gather, svld1_gather_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2630 FUNCTION (svld1ro, svld1ro_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2631 FUNCTION (svld1rq, svld1rq_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2632 FUNCTION (svld1sb, svld1_extend_impl, (TYPE_SUFFIX_s8))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2633 FUNCTION (svld1sb_gather, svld1_gather_extend_impl, (TYPE_SUFFIX_s8))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2634 FUNCTION (svld1sh, svld1_extend_impl, (TYPE_SUFFIX_s16))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2635 FUNCTION (svld1sh_gather, svld1_gather_extend_impl, (TYPE_SUFFIX_s16))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2636 FUNCTION (svld1sw, svld1_extend_impl, (TYPE_SUFFIX_s32))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2637 FUNCTION (svld1sw_gather, svld1_gather_extend_impl, (TYPE_SUFFIX_s32))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2638 FUNCTION (svld1ub, svld1_extend_impl, (TYPE_SUFFIX_u8))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2639 FUNCTION (svld1ub_gather, svld1_gather_extend_impl, (TYPE_SUFFIX_u8))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2640 FUNCTION (svld1uh, svld1_extend_impl, (TYPE_SUFFIX_u16))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2641 FUNCTION (svld1uh_gather, svld1_gather_extend_impl, (TYPE_SUFFIX_u16))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2642 FUNCTION (svld1uw, svld1_extend_impl, (TYPE_SUFFIX_u32))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2643 FUNCTION (svld1uw_gather, svld1_gather_extend_impl, (TYPE_SUFFIX_u32))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2644 FUNCTION (svld2, svld234_impl, (2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2645 FUNCTION (svld3, svld234_impl, (3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2646 FUNCTION (svld4, svld234_impl, (4))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2647 FUNCTION (svldff1, svldxf1_impl, (UNSPEC_LDFF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2648 FUNCTION (svldff1_gather, svldff1_gather_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2649 FUNCTION (svldff1sb, svldxf1_extend_impl, (TYPE_SUFFIX_s8, UNSPEC_LDFF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2650 FUNCTION (svldff1sb_gather, svldff1_gather_extend, (TYPE_SUFFIX_s8))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2651 FUNCTION (svldff1sh, svldxf1_extend_impl, (TYPE_SUFFIX_s16, UNSPEC_LDFF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2652 FUNCTION (svldff1sh_gather, svldff1_gather_extend, (TYPE_SUFFIX_s16))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2653 FUNCTION (svldff1sw, svldxf1_extend_impl, (TYPE_SUFFIX_s32, UNSPEC_LDFF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2654 FUNCTION (svldff1sw_gather, svldff1_gather_extend, (TYPE_SUFFIX_s32))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2655 FUNCTION (svldff1ub, svldxf1_extend_impl, (TYPE_SUFFIX_u8, UNSPEC_LDFF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2656 FUNCTION (svldff1ub_gather, svldff1_gather_extend, (TYPE_SUFFIX_u8))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2657 FUNCTION (svldff1uh, svldxf1_extend_impl, (TYPE_SUFFIX_u16, UNSPEC_LDFF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2658 FUNCTION (svldff1uh_gather, svldff1_gather_extend, (TYPE_SUFFIX_u16))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2659 FUNCTION (svldff1uw, svldxf1_extend_impl, (TYPE_SUFFIX_u32, UNSPEC_LDFF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2660 FUNCTION (svldff1uw_gather, svldff1_gather_extend, (TYPE_SUFFIX_u32))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2661 FUNCTION (svldnf1, svldxf1_impl, (UNSPEC_LDNF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2662 FUNCTION (svldnf1sb, svldxf1_extend_impl, (TYPE_SUFFIX_s8, UNSPEC_LDNF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2663 FUNCTION (svldnf1sh, svldxf1_extend_impl, (TYPE_SUFFIX_s16, UNSPEC_LDNF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2664 FUNCTION (svldnf1sw, svldxf1_extend_impl, (TYPE_SUFFIX_s32, UNSPEC_LDNF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2665 FUNCTION (svldnf1ub, svldxf1_extend_impl, (TYPE_SUFFIX_u8, UNSPEC_LDNF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2666 FUNCTION (svldnf1uh, svldxf1_extend_impl, (TYPE_SUFFIX_u16, UNSPEC_LDNF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2667 FUNCTION (svldnf1uw, svldxf1_extend_impl, (TYPE_SUFFIX_u32, UNSPEC_LDNF1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2668 FUNCTION (svldnt1, svldnt1_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2669 FUNCTION (svlen, svlen_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2670 FUNCTION (svlsl, rtx_code_function, (ASHIFT, ASHIFT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2671 FUNCTION (svlsl_wide, shift_wide, (ASHIFT, UNSPEC_ASHIFT_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2672 FUNCTION (svlsr, rtx_code_function, (LSHIFTRT, LSHIFTRT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2673 FUNCTION (svlsr_wide, shift_wide, (LSHIFTRT, UNSPEC_LSHIFTRT_WIDE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2674 FUNCTION (svmad, svmad_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2675 FUNCTION (svmax, rtx_code_function, (SMAX, UMAX, UNSPEC_COND_FMAX))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2676 FUNCTION (svmaxnm, unspec_based_function, (-1, -1, UNSPEC_COND_FMAXNM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2677 FUNCTION (svmaxnmv, reduction, (UNSPEC_FMAXNMV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2678 FUNCTION (svmaxv, reduction, (UNSPEC_SMAXV, UNSPEC_UMAXV, UNSPEC_FMAXV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2679 FUNCTION (svmin, rtx_code_function, (SMIN, UMIN, UNSPEC_COND_FMIN))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2680 FUNCTION (svminnm, unspec_based_function, (-1, -1, UNSPEC_COND_FMINNM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2681 FUNCTION (svminnmv, reduction, (UNSPEC_FMINNMV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2682 FUNCTION (svminv, reduction, (UNSPEC_SMINV, UNSPEC_UMINV, UNSPEC_FMINV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2683 FUNCTION (svmla, svmla_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2684 FUNCTION (svmla_lane, svmla_lane_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2685 FUNCTION (svmls, svmls_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2686 FUNCTION (svmls_lane, svmls_lane_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2687 FUNCTION (svmmla, svmmla_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2688 FUNCTION (svmov, svmov_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2689 FUNCTION (svmsb, svmsb_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2690 FUNCTION (svmul, rtx_code_function, (MULT, MULT, UNSPEC_COND_FMUL))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2691 FUNCTION (svmul_lane, CODE_FOR_MODE0 (aarch64_mul_lane),)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2692 FUNCTION (svmulh, unspec_based_function, (UNSPEC_SMUL_HIGHPART,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2693 UNSPEC_UMUL_HIGHPART, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2694 FUNCTION (svmulx, unspec_based_function, (-1, -1, UNSPEC_COND_FMULX))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2695 FUNCTION (svnand, svnand_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2696 FUNCTION (svneg, quiet<rtx_code_function>, (NEG, NEG, UNSPEC_COND_FNEG))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2697 FUNCTION (svnmad, unspec_based_function, (-1, -1, UNSPEC_COND_FNMLA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2698 FUNCTION (svnmla, unspec_based_function_rotated, (-1, -1, UNSPEC_COND_FNMLA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2699 FUNCTION (svnmls, unspec_based_function_rotated, (-1, -1, UNSPEC_COND_FNMLS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2700 FUNCTION (svnmsb, unspec_based_function, (-1, -1, UNSPEC_COND_FNMLS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2701 FUNCTION (svnor, svnor_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2702 FUNCTION (svnot, svnot_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2703 FUNCTION (svorn, svorn_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2704 FUNCTION (svorr, rtx_code_function, (IOR, IOR))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2705 FUNCTION (svorv, reduction, (UNSPEC_IORV))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2706 FUNCTION (svpfalse, svpfalse_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2707 FUNCTION (svpfirst, svpfirst_svpnext_impl, (UNSPEC_PFIRST))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2708 FUNCTION (svpnext, svpfirst_svpnext_impl, (UNSPEC_PNEXT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2709 FUNCTION (svprfb, svprf_bhwd_impl, (VNx16QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2710 FUNCTION (svprfb_gather, svprf_bhwd_gather_impl, (VNx16QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2711 FUNCTION (svprfd, svprf_bhwd_impl, (VNx2DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2712 FUNCTION (svprfd_gather, svprf_bhwd_gather_impl, (VNx2DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2713 FUNCTION (svprfh, svprf_bhwd_impl, (VNx8HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2714 FUNCTION (svprfh_gather, svprf_bhwd_gather_impl, (VNx8HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2715 FUNCTION (svprfw, svprf_bhwd_impl, (VNx4SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2716 FUNCTION (svprfw_gather, svprf_bhwd_gather_impl, (VNx4SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2717 FUNCTION (svptest_any, svptest_impl, (NE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2718 FUNCTION (svptest_first, svptest_impl, (LT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2719 FUNCTION (svptest_last, svptest_impl, (LTU))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2720 FUNCTION (svptrue, svptrue_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2721 FUNCTION (svptrue_pat, svptrue_pat_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2722 FUNCTION (svqadd, rtx_code_function, (SS_PLUS, US_PLUS, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2723 FUNCTION (svqdecb, svqdec_bhwd_impl, (QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2724 FUNCTION (svqdecb_pat, svqdec_bhwd_impl, (QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2725 FUNCTION (svqdecd, svqdec_bhwd_impl, (DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2726 FUNCTION (svqdecd_pat, svqdec_bhwd_impl, (DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2727 FUNCTION (svqdech, svqdec_bhwd_impl, (HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2728 FUNCTION (svqdech_pat, svqdec_bhwd_impl, (HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2729 FUNCTION (svqdecp, svqdecp_svqincp_impl, (SS_MINUS, US_MINUS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2730 FUNCTION (svqdecw, svqdec_bhwd_impl, (SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2731 FUNCTION (svqdecw_pat, svqdec_bhwd_impl, (SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2732 FUNCTION (svqincb, svqinc_bhwd_impl, (QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2733 FUNCTION (svqincb_pat, svqinc_bhwd_impl, (QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2734 FUNCTION (svqincd, svqinc_bhwd_impl, (DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2735 FUNCTION (svqincd_pat, svqinc_bhwd_impl, (DImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2736 FUNCTION (svqinch, svqinc_bhwd_impl, (HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2737 FUNCTION (svqinch_pat, svqinc_bhwd_impl, (HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2738 FUNCTION (svqincp, svqdecp_svqincp_impl, (SS_PLUS, US_PLUS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2739 FUNCTION (svqincw, svqinc_bhwd_impl, (SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2740 FUNCTION (svqincw_pat, svqinc_bhwd_impl, (SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2741 FUNCTION (svqsub, rtx_code_function, (SS_MINUS, US_MINUS, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2742 FUNCTION (svrbit, unspec_based_function, (UNSPEC_RBIT, UNSPEC_RBIT, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2743 FUNCTION (svrdffr, svrdffr_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2744 FUNCTION (svrecpe, unspec_based_function, (-1, UNSPEC_URECPE, UNSPEC_FRECPE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2745 FUNCTION (svrecps, unspec_based_function, (-1, -1, UNSPEC_FRECPS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2746 FUNCTION (svrecpx, unspec_based_function, (-1, -1, UNSPEC_COND_FRECPX))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2747 FUNCTION (svreinterpret, svreinterpret_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2748 FUNCTION (svrev, svrev_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2749 FUNCTION (svrevb, unspec_based_function, (UNSPEC_REVB, UNSPEC_REVB, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2750 FUNCTION (svrevh, unspec_based_function, (UNSPEC_REVH, UNSPEC_REVH, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2751 FUNCTION (svrevw, unspec_based_function, (UNSPEC_REVW, UNSPEC_REVW, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2752 FUNCTION (svrinta, unspec_based_function, (-1, -1, UNSPEC_COND_FRINTA))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2753 FUNCTION (svrinti, unspec_based_function, (-1, -1, UNSPEC_COND_FRINTI))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2754 FUNCTION (svrintm, unspec_based_function, (-1, -1, UNSPEC_COND_FRINTM))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2755 FUNCTION (svrintn, unspec_based_function, (-1, -1, UNSPEC_COND_FRINTN))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2756 FUNCTION (svrintp, unspec_based_function, (-1, -1, UNSPEC_COND_FRINTP))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2757 FUNCTION (svrintx, unspec_based_function, (-1, -1, UNSPEC_COND_FRINTX))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2758 FUNCTION (svrintz, unspec_based_function, (-1, -1, UNSPEC_COND_FRINTZ))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2759 FUNCTION (svrsqrte, unspec_based_function, (-1, UNSPEC_RSQRTE, UNSPEC_RSQRTE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2760 FUNCTION (svrsqrts, unspec_based_function, (-1, -1, UNSPEC_RSQRTS))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2761 FUNCTION (svscale, unspec_based_function, (-1, -1, UNSPEC_COND_FSCALE))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2762 FUNCTION (svsel, svsel_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2763 FUNCTION (svset2, svset_impl, (2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2764 FUNCTION (svset3, svset_impl, (3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2765 FUNCTION (svset4, svset_impl, (4))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2766 FUNCTION (svsetffr, svsetffr_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2767 FUNCTION (svsplice, QUIET_CODE_FOR_MODE0 (aarch64_sve_splice),)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2768 FUNCTION (svsqrt, rtx_code_function, (SQRT, SQRT, UNSPEC_COND_FSQRT))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2769 FUNCTION (svst1, svst1_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2770 FUNCTION (svst1_scatter, svst1_scatter_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2771 FUNCTION (svst1b, svst1_truncate_impl, (QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2772 FUNCTION (svst1b_scatter, svst1_scatter_truncate_impl, (QImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2773 FUNCTION (svst1h, svst1_truncate_impl, (HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2774 FUNCTION (svst1h_scatter, svst1_scatter_truncate_impl, (HImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2775 FUNCTION (svst1w, svst1_truncate_impl, (SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2776 FUNCTION (svst1w_scatter, svst1_scatter_truncate_impl, (SImode))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2777 FUNCTION (svst2, svst234_impl, (2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2778 FUNCTION (svst3, svst234_impl, (3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2779 FUNCTION (svst4, svst234_impl, (4))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2780 FUNCTION (svstnt1, svstnt1_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2781 FUNCTION (svsub, svsub_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2782 FUNCTION (svsubr, rtx_code_function_rotated, (MINUS, MINUS, UNSPEC_COND_FSUB))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2783 FUNCTION (svsudot, svusdot_impl, (true))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2784 FUNCTION (svsudot_lane, svdotprod_lane_impl, (UNSPEC_SUDOT, -1, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2785 FUNCTION (svtbl, svtbl_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2786 FUNCTION (svtmad, CODE_FOR_MODE0 (aarch64_sve_tmad),)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2787 FUNCTION (svtrn1, svtrn_impl, (0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2788 FUNCTION (svtrn1q, unspec_based_function, (UNSPEC_TRN1Q, UNSPEC_TRN1Q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2789 UNSPEC_TRN1Q))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2790 FUNCTION (svtrn2, svtrn_impl, (1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2791 FUNCTION (svtrn2q, unspec_based_function, (UNSPEC_TRN2Q, UNSPEC_TRN2Q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2792 UNSPEC_TRN2Q))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2793 FUNCTION (svtsmul, unspec_based_function, (-1, -1, UNSPEC_FTSMUL))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2794 FUNCTION (svtssel, unspec_based_function, (-1, -1, UNSPEC_FTSSEL))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2795 FUNCTION (svundef, svundef_impl, (1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2796 FUNCTION (svundef2, svundef_impl, (2))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2797 FUNCTION (svundef3, svundef_impl, (3))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2798 FUNCTION (svundef4, svundef_impl, (4))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2799 FUNCTION (svunpkhi, svunpk_impl, (true))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2800 FUNCTION (svunpklo, svunpk_impl, (false))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2801 FUNCTION (svusdot, svusdot_impl, (false))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2802 FUNCTION (svusdot_lane, svdotprod_lane_impl, (UNSPEC_USDOT, -1, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2803 FUNCTION (svusmmla, unspec_based_add_function, (UNSPEC_USMATMUL, -1, -1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2804 FUNCTION (svuzp1, svuzp_impl, (0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2805 FUNCTION (svuzp1q, unspec_based_function, (UNSPEC_UZP1Q, UNSPEC_UZP1Q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2806 UNSPEC_UZP1Q))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2807 FUNCTION (svuzp2, svuzp_impl, (1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2808 FUNCTION (svuzp2q, unspec_based_function, (UNSPEC_UZP2Q, UNSPEC_UZP2Q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2809 UNSPEC_UZP2Q))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2810 FUNCTION (svwhilele, svwhilelx_impl, (UNSPEC_WHILELE, UNSPEC_WHILELS, true))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2811 FUNCTION (svwhilelt, svwhilelx_impl, (UNSPEC_WHILELT, UNSPEC_WHILELO, false))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2812 FUNCTION (svwrffr, svwrffr_impl,)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2813 FUNCTION (svzip1, svzip_impl, (0))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2814 FUNCTION (svzip1q, unspec_based_function, (UNSPEC_ZIP1Q, UNSPEC_ZIP1Q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2815 UNSPEC_ZIP1Q))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2816 FUNCTION (svzip2, svzip_impl, (1))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2817 FUNCTION (svzip2q, unspec_based_function, (UNSPEC_ZIP2Q, UNSPEC_ZIP2Q,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2818 UNSPEC_ZIP2Q))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2819
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2820 } /* end namespace aarch64_sve */