1*f5c631daSSadaf Ebrahimi // Copyright 2018, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi // * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi // this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi // * Redistributions in binary form must reproduce the above copyright notice,
10*f5c631daSSadaf Ebrahimi // this list of conditions and the following disclaimer in the documentation
11*f5c631daSSadaf Ebrahimi // and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi // * Neither the name of Arm Limited nor the names of its contributors may be
13*f5c631daSSadaf Ebrahimi // used to endorse or promote products derived from this software without
14*f5c631daSSadaf Ebrahimi // specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*f5c631daSSadaf Ebrahimi
27*f5c631daSSadaf Ebrahimi #include "cpu-features.h"
28*f5c631daSSadaf Ebrahimi #include "globals-vixl.h"
29*f5c631daSSadaf Ebrahimi #include "utils-vixl.h"
30*f5c631daSSadaf Ebrahimi #include "decoder-aarch64.h"
31*f5c631daSSadaf Ebrahimi
32*f5c631daSSadaf Ebrahimi #include "cpu-features-auditor-aarch64.h"
33*f5c631daSSadaf Ebrahimi
34*f5c631daSSadaf Ebrahimi namespace vixl {
35*f5c631daSSadaf Ebrahimi namespace aarch64 {
36*f5c631daSSadaf Ebrahimi
37*f5c631daSSadaf Ebrahimi
38*f5c631daSSadaf Ebrahimi const CPUFeaturesAuditor::FormToVisitorFnMap*
GetFormToVisitorFnMap()39*f5c631daSSadaf Ebrahimi CPUFeaturesAuditor::GetFormToVisitorFnMap() {
40*f5c631daSSadaf Ebrahimi static const FormToVisitorFnMap form_to_visitor = {
41*f5c631daSSadaf Ebrahimi DEFAULT_FORM_TO_VISITOR_MAP(CPUFeaturesAuditor),
42*f5c631daSSadaf Ebrahimi SIM_AUD_VISITOR_MAP(CPUFeaturesAuditor),
43*f5c631daSSadaf Ebrahimi {"fcmla_asimdelem_c_h"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
44*f5c631daSSadaf Ebrahimi {"fcmla_asimdelem_c_s"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
45*f5c631daSSadaf Ebrahimi {"fmlal2_asimdelem_lh"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
46*f5c631daSSadaf Ebrahimi {"fmlal_asimdelem_lh"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
47*f5c631daSSadaf Ebrahimi {"fmla_asimdelem_rh_h"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
48*f5c631daSSadaf Ebrahimi {"fmla_asimdelem_r_sd"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
49*f5c631daSSadaf Ebrahimi {"fmlsl2_asimdelem_lh"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
50*f5c631daSSadaf Ebrahimi {"fmlsl_asimdelem_lh"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
51*f5c631daSSadaf Ebrahimi {"fmls_asimdelem_rh_h"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
52*f5c631daSSadaf Ebrahimi {"fmls_asimdelem_r_sd"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
53*f5c631daSSadaf Ebrahimi {"fmulx_asimdelem_rh_h"_h,
54*f5c631daSSadaf Ebrahimi &CPUFeaturesAuditor::VisitNEONByIndexedElement},
55*f5c631daSSadaf Ebrahimi {"fmulx_asimdelem_r_sd"_h,
56*f5c631daSSadaf Ebrahimi &CPUFeaturesAuditor::VisitNEONByIndexedElement},
57*f5c631daSSadaf Ebrahimi {"fmul_asimdelem_rh_h"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
58*f5c631daSSadaf Ebrahimi {"fmul_asimdelem_r_sd"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
59*f5c631daSSadaf Ebrahimi {"sdot_asimdelem_d"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
60*f5c631daSSadaf Ebrahimi {"smlal_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
61*f5c631daSSadaf Ebrahimi {"smlsl_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
62*f5c631daSSadaf Ebrahimi {"smull_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
63*f5c631daSSadaf Ebrahimi {"sqdmlal_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
64*f5c631daSSadaf Ebrahimi {"sqdmlsl_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
65*f5c631daSSadaf Ebrahimi {"sqdmull_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
66*f5c631daSSadaf Ebrahimi {"udot_asimdelem_d"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
67*f5c631daSSadaf Ebrahimi {"umlal_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
68*f5c631daSSadaf Ebrahimi {"umlsl_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
69*f5c631daSSadaf Ebrahimi {"umull_asimdelem_l"_h, &CPUFeaturesAuditor::VisitNEONByIndexedElement},
70*f5c631daSSadaf Ebrahimi };
71*f5c631daSSadaf Ebrahimi return &form_to_visitor;
72*f5c631daSSadaf Ebrahimi }
73*f5c631daSSadaf Ebrahimi
74*f5c631daSSadaf Ebrahimi // Every instruction must update last_instruction_, even if only to clear it,
75*f5c631daSSadaf Ebrahimi // and every instruction must also update seen_ once it has been fully handled.
76*f5c631daSSadaf Ebrahimi // This scope makes that simple, and allows early returns in the decode logic.
77*f5c631daSSadaf Ebrahimi class CPUFeaturesAuditor::RecordInstructionFeaturesScope {
78*f5c631daSSadaf Ebrahimi public:
RecordInstructionFeaturesScope(CPUFeaturesAuditor * auditor)79*f5c631daSSadaf Ebrahimi explicit RecordInstructionFeaturesScope(CPUFeaturesAuditor* auditor)
80*f5c631daSSadaf Ebrahimi : auditor_(auditor) {
81*f5c631daSSadaf Ebrahimi auditor_->last_instruction_ = CPUFeatures::None();
82*f5c631daSSadaf Ebrahimi }
~RecordInstructionFeaturesScope()83*f5c631daSSadaf Ebrahimi ~RecordInstructionFeaturesScope() {
84*f5c631daSSadaf Ebrahimi auditor_->seen_.Combine(auditor_->last_instruction_);
85*f5c631daSSadaf Ebrahimi }
86*f5c631daSSadaf Ebrahimi
Record(const CPUFeatures & features)87*f5c631daSSadaf Ebrahimi void Record(const CPUFeatures& features) {
88*f5c631daSSadaf Ebrahimi auditor_->last_instruction_.Combine(features);
89*f5c631daSSadaf Ebrahimi }
90*f5c631daSSadaf Ebrahimi
Record(CPUFeatures::Feature feature0,CPUFeatures::Feature feature1=CPUFeatures::kNone,CPUFeatures::Feature feature2=CPUFeatures::kNone,CPUFeatures::Feature feature3=CPUFeatures::kNone)91*f5c631daSSadaf Ebrahimi void Record(CPUFeatures::Feature feature0,
92*f5c631daSSadaf Ebrahimi CPUFeatures::Feature feature1 = CPUFeatures::kNone,
93*f5c631daSSadaf Ebrahimi CPUFeatures::Feature feature2 = CPUFeatures::kNone,
94*f5c631daSSadaf Ebrahimi CPUFeatures::Feature feature3 = CPUFeatures::kNone) {
95*f5c631daSSadaf Ebrahimi auditor_->last_instruction_.Combine(feature0, feature1, feature2, feature3);
96*f5c631daSSadaf Ebrahimi }
97*f5c631daSSadaf Ebrahimi
98*f5c631daSSadaf Ebrahimi // If exactly one of a or b is known to be available, record it. Otherwise,
99*f5c631daSSadaf Ebrahimi // record both. This is intended for encodings that can be provided by two
100*f5c631daSSadaf Ebrahimi // different features.
RecordOneOrBothOf(CPUFeatures::Feature a,CPUFeatures::Feature b)101*f5c631daSSadaf Ebrahimi void RecordOneOrBothOf(CPUFeatures::Feature a, CPUFeatures::Feature b) {
102*f5c631daSSadaf Ebrahimi bool hint_a = auditor_->available_.Has(a);
103*f5c631daSSadaf Ebrahimi bool hint_b = auditor_->available_.Has(b);
104*f5c631daSSadaf Ebrahimi if (hint_a && !hint_b) {
105*f5c631daSSadaf Ebrahimi Record(a);
106*f5c631daSSadaf Ebrahimi } else if (hint_b && !hint_a) {
107*f5c631daSSadaf Ebrahimi Record(b);
108*f5c631daSSadaf Ebrahimi } else {
109*f5c631daSSadaf Ebrahimi Record(a, b);
110*f5c631daSSadaf Ebrahimi }
111*f5c631daSSadaf Ebrahimi }
112*f5c631daSSadaf Ebrahimi
113*f5c631daSSadaf Ebrahimi private:
114*f5c631daSSadaf Ebrahimi CPUFeaturesAuditor* auditor_;
115*f5c631daSSadaf Ebrahimi };
116*f5c631daSSadaf Ebrahimi
LoadStoreHelper(const Instruction * instr)117*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::LoadStoreHelper(const Instruction* instr) {
118*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
119*f5c631daSSadaf Ebrahimi switch (instr->Mask(LoadStoreMask)) {
120*f5c631daSSadaf Ebrahimi case LDR_b:
121*f5c631daSSadaf Ebrahimi case LDR_q:
122*f5c631daSSadaf Ebrahimi case STR_b:
123*f5c631daSSadaf Ebrahimi case STR_q:
124*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
125*f5c631daSSadaf Ebrahimi return;
126*f5c631daSSadaf Ebrahimi case LDR_h:
127*f5c631daSSadaf Ebrahimi case LDR_s:
128*f5c631daSSadaf Ebrahimi case LDR_d:
129*f5c631daSSadaf Ebrahimi case STR_h:
130*f5c631daSSadaf Ebrahimi case STR_s:
131*f5c631daSSadaf Ebrahimi case STR_d:
132*f5c631daSSadaf Ebrahimi scope.RecordOneOrBothOf(CPUFeatures::kFP, CPUFeatures::kNEON);
133*f5c631daSSadaf Ebrahimi return;
134*f5c631daSSadaf Ebrahimi default:
135*f5c631daSSadaf Ebrahimi // No special CPU features.
136*f5c631daSSadaf Ebrahimi return;
137*f5c631daSSadaf Ebrahimi }
138*f5c631daSSadaf Ebrahimi }
139*f5c631daSSadaf Ebrahimi
LoadStorePairHelper(const Instruction * instr)140*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::LoadStorePairHelper(const Instruction* instr) {
141*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
142*f5c631daSSadaf Ebrahimi switch (instr->Mask(LoadStorePairMask)) {
143*f5c631daSSadaf Ebrahimi case LDP_q:
144*f5c631daSSadaf Ebrahimi case STP_q:
145*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
146*f5c631daSSadaf Ebrahimi return;
147*f5c631daSSadaf Ebrahimi case LDP_s:
148*f5c631daSSadaf Ebrahimi case LDP_d:
149*f5c631daSSadaf Ebrahimi case STP_s:
150*f5c631daSSadaf Ebrahimi case STP_d: {
151*f5c631daSSadaf Ebrahimi scope.RecordOneOrBothOf(CPUFeatures::kFP, CPUFeatures::kNEON);
152*f5c631daSSadaf Ebrahimi return;
153*f5c631daSSadaf Ebrahimi }
154*f5c631daSSadaf Ebrahimi default:
155*f5c631daSSadaf Ebrahimi // No special CPU features.
156*f5c631daSSadaf Ebrahimi return;
157*f5c631daSSadaf Ebrahimi }
158*f5c631daSSadaf Ebrahimi }
159*f5c631daSSadaf Ebrahimi
VisitAddSubExtended(const Instruction * instr)160*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitAddSubExtended(const Instruction* instr) {
161*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
162*f5c631daSSadaf Ebrahimi USE(instr);
163*f5c631daSSadaf Ebrahimi }
164*f5c631daSSadaf Ebrahimi
VisitAddSubImmediate(const Instruction * instr)165*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitAddSubImmediate(const Instruction* instr) {
166*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
167*f5c631daSSadaf Ebrahimi USE(instr);
168*f5c631daSSadaf Ebrahimi }
169*f5c631daSSadaf Ebrahimi
VisitAddSubShifted(const Instruction * instr)170*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitAddSubShifted(const Instruction* instr) {
171*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
172*f5c631daSSadaf Ebrahimi USE(instr);
173*f5c631daSSadaf Ebrahimi }
174*f5c631daSSadaf Ebrahimi
VisitAddSubWithCarry(const Instruction * instr)175*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitAddSubWithCarry(const Instruction* instr) {
176*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
177*f5c631daSSadaf Ebrahimi USE(instr);
178*f5c631daSSadaf Ebrahimi }
179*f5c631daSSadaf Ebrahimi
VisitRotateRightIntoFlags(const Instruction * instr)180*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitRotateRightIntoFlags(const Instruction* instr) {
181*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
182*f5c631daSSadaf Ebrahimi switch (instr->Mask(RotateRightIntoFlagsMask)) {
183*f5c631daSSadaf Ebrahimi case RMIF:
184*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFlagM);
185*f5c631daSSadaf Ebrahimi return;
186*f5c631daSSadaf Ebrahimi }
187*f5c631daSSadaf Ebrahimi }
188*f5c631daSSadaf Ebrahimi
VisitEvaluateIntoFlags(const Instruction * instr)189*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitEvaluateIntoFlags(const Instruction* instr) {
190*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
191*f5c631daSSadaf Ebrahimi switch (instr->Mask(EvaluateIntoFlagsMask)) {
192*f5c631daSSadaf Ebrahimi case SETF8:
193*f5c631daSSadaf Ebrahimi case SETF16:
194*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFlagM);
195*f5c631daSSadaf Ebrahimi return;
196*f5c631daSSadaf Ebrahimi }
197*f5c631daSSadaf Ebrahimi }
198*f5c631daSSadaf Ebrahimi
VisitAtomicMemory(const Instruction * instr)199*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitAtomicMemory(const Instruction* instr) {
200*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
201*f5c631daSSadaf Ebrahimi switch (instr->Mask(AtomicMemoryMask)) {
202*f5c631daSSadaf Ebrahimi case LDAPRB:
203*f5c631daSSadaf Ebrahimi case LDAPRH:
204*f5c631daSSadaf Ebrahimi case LDAPR_w:
205*f5c631daSSadaf Ebrahimi case LDAPR_x:
206*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kRCpc);
207*f5c631daSSadaf Ebrahimi return;
208*f5c631daSSadaf Ebrahimi default:
209*f5c631daSSadaf Ebrahimi // Everything else belongs to the Atomics extension.
210*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kAtomics);
211*f5c631daSSadaf Ebrahimi return;
212*f5c631daSSadaf Ebrahimi }
213*f5c631daSSadaf Ebrahimi }
214*f5c631daSSadaf Ebrahimi
VisitBitfield(const Instruction * instr)215*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitBitfield(const Instruction* instr) {
216*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
217*f5c631daSSadaf Ebrahimi USE(instr);
218*f5c631daSSadaf Ebrahimi }
219*f5c631daSSadaf Ebrahimi
VisitCompareBranch(const Instruction * instr)220*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitCompareBranch(const Instruction* instr) {
221*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
222*f5c631daSSadaf Ebrahimi USE(instr);
223*f5c631daSSadaf Ebrahimi }
224*f5c631daSSadaf Ebrahimi
VisitConditionalBranch(const Instruction * instr)225*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitConditionalBranch(const Instruction* instr) {
226*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
227*f5c631daSSadaf Ebrahimi USE(instr);
228*f5c631daSSadaf Ebrahimi }
229*f5c631daSSadaf Ebrahimi
VisitConditionalCompareImmediate(const Instruction * instr)230*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitConditionalCompareImmediate(
231*f5c631daSSadaf Ebrahimi const Instruction* instr) {
232*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
233*f5c631daSSadaf Ebrahimi USE(instr);
234*f5c631daSSadaf Ebrahimi }
235*f5c631daSSadaf Ebrahimi
VisitConditionalCompareRegister(const Instruction * instr)236*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitConditionalCompareRegister(
237*f5c631daSSadaf Ebrahimi const Instruction* instr) {
238*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
239*f5c631daSSadaf Ebrahimi USE(instr);
240*f5c631daSSadaf Ebrahimi }
241*f5c631daSSadaf Ebrahimi
VisitConditionalSelect(const Instruction * instr)242*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitConditionalSelect(const Instruction* instr) {
243*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
244*f5c631daSSadaf Ebrahimi USE(instr);
245*f5c631daSSadaf Ebrahimi }
246*f5c631daSSadaf Ebrahimi
VisitCrypto2RegSHA(const Instruction * instr)247*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitCrypto2RegSHA(const Instruction* instr) {
248*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
249*f5c631daSSadaf Ebrahimi USE(instr);
250*f5c631daSSadaf Ebrahimi }
251*f5c631daSSadaf Ebrahimi
VisitCrypto3RegSHA(const Instruction * instr)252*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitCrypto3RegSHA(const Instruction* instr) {
253*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
254*f5c631daSSadaf Ebrahimi USE(instr);
255*f5c631daSSadaf Ebrahimi }
256*f5c631daSSadaf Ebrahimi
VisitCryptoAES(const Instruction * instr)257*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitCryptoAES(const Instruction* instr) {
258*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
259*f5c631daSSadaf Ebrahimi USE(instr);
260*f5c631daSSadaf Ebrahimi }
261*f5c631daSSadaf Ebrahimi
VisitDataProcessing1Source(const Instruction * instr)262*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitDataProcessing1Source(const Instruction* instr) {
263*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
264*f5c631daSSadaf Ebrahimi switch (instr->Mask(DataProcessing1SourceMask)) {
265*f5c631daSSadaf Ebrahimi case PACIA:
266*f5c631daSSadaf Ebrahimi case PACIB:
267*f5c631daSSadaf Ebrahimi case PACDA:
268*f5c631daSSadaf Ebrahimi case PACDB:
269*f5c631daSSadaf Ebrahimi case AUTIA:
270*f5c631daSSadaf Ebrahimi case AUTIB:
271*f5c631daSSadaf Ebrahimi case AUTDA:
272*f5c631daSSadaf Ebrahimi case AUTDB:
273*f5c631daSSadaf Ebrahimi case PACIZA:
274*f5c631daSSadaf Ebrahimi case PACIZB:
275*f5c631daSSadaf Ebrahimi case PACDZA:
276*f5c631daSSadaf Ebrahimi case PACDZB:
277*f5c631daSSadaf Ebrahimi case AUTIZA:
278*f5c631daSSadaf Ebrahimi case AUTIZB:
279*f5c631daSSadaf Ebrahimi case AUTDZA:
280*f5c631daSSadaf Ebrahimi case AUTDZB:
281*f5c631daSSadaf Ebrahimi case XPACI:
282*f5c631daSSadaf Ebrahimi case XPACD:
283*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kPAuth);
284*f5c631daSSadaf Ebrahimi return;
285*f5c631daSSadaf Ebrahimi default:
286*f5c631daSSadaf Ebrahimi // No special CPU features.
287*f5c631daSSadaf Ebrahimi return;
288*f5c631daSSadaf Ebrahimi }
289*f5c631daSSadaf Ebrahimi }
290*f5c631daSSadaf Ebrahimi
VisitDataProcessing2Source(const Instruction * instr)291*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitDataProcessing2Source(const Instruction* instr) {
292*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
293*f5c631daSSadaf Ebrahimi switch (instr->Mask(DataProcessing2SourceMask)) {
294*f5c631daSSadaf Ebrahimi case CRC32B:
295*f5c631daSSadaf Ebrahimi case CRC32H:
296*f5c631daSSadaf Ebrahimi case CRC32W:
297*f5c631daSSadaf Ebrahimi case CRC32X:
298*f5c631daSSadaf Ebrahimi case CRC32CB:
299*f5c631daSSadaf Ebrahimi case CRC32CH:
300*f5c631daSSadaf Ebrahimi case CRC32CW:
301*f5c631daSSadaf Ebrahimi case CRC32CX:
302*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kCRC32);
303*f5c631daSSadaf Ebrahimi return;
304*f5c631daSSadaf Ebrahimi case PACGA:
305*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kPAuth, CPUFeatures::kPAuthGeneric);
306*f5c631daSSadaf Ebrahimi return;
307*f5c631daSSadaf Ebrahimi default:
308*f5c631daSSadaf Ebrahimi // No special CPU features.
309*f5c631daSSadaf Ebrahimi return;
310*f5c631daSSadaf Ebrahimi }
311*f5c631daSSadaf Ebrahimi }
312*f5c631daSSadaf Ebrahimi
VisitLoadStoreRCpcUnscaledOffset(const Instruction * instr)313*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStoreRCpcUnscaledOffset(
314*f5c631daSSadaf Ebrahimi const Instruction* instr) {
315*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
316*f5c631daSSadaf Ebrahimi switch (instr->Mask(LoadStoreRCpcUnscaledOffsetMask)) {
317*f5c631daSSadaf Ebrahimi case LDAPURB:
318*f5c631daSSadaf Ebrahimi case LDAPURSB_w:
319*f5c631daSSadaf Ebrahimi case LDAPURSB_x:
320*f5c631daSSadaf Ebrahimi case LDAPURH:
321*f5c631daSSadaf Ebrahimi case LDAPURSH_w:
322*f5c631daSSadaf Ebrahimi case LDAPURSH_x:
323*f5c631daSSadaf Ebrahimi case LDAPUR_w:
324*f5c631daSSadaf Ebrahimi case LDAPURSW:
325*f5c631daSSadaf Ebrahimi case LDAPUR_x:
326*f5c631daSSadaf Ebrahimi
327*f5c631daSSadaf Ebrahimi // These stores don't actually have RCpc semantics but they're included with
328*f5c631daSSadaf Ebrahimi // the RCpc extensions.
329*f5c631daSSadaf Ebrahimi case STLURB:
330*f5c631daSSadaf Ebrahimi case STLURH:
331*f5c631daSSadaf Ebrahimi case STLUR_w:
332*f5c631daSSadaf Ebrahimi case STLUR_x:
333*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kRCpc, CPUFeatures::kRCpcImm);
334*f5c631daSSadaf Ebrahimi return;
335*f5c631daSSadaf Ebrahimi }
336*f5c631daSSadaf Ebrahimi }
337*f5c631daSSadaf Ebrahimi
VisitLoadStorePAC(const Instruction * instr)338*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStorePAC(const Instruction* instr) {
339*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
340*f5c631daSSadaf Ebrahimi USE(instr);
341*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kPAuth);
342*f5c631daSSadaf Ebrahimi }
343*f5c631daSSadaf Ebrahimi
VisitDataProcessing3Source(const Instruction * instr)344*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitDataProcessing3Source(const Instruction* instr) {
345*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
346*f5c631daSSadaf Ebrahimi USE(instr);
347*f5c631daSSadaf Ebrahimi }
348*f5c631daSSadaf Ebrahimi
VisitException(const Instruction * instr)349*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitException(const Instruction* instr) {
350*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
351*f5c631daSSadaf Ebrahimi USE(instr);
352*f5c631daSSadaf Ebrahimi }
353*f5c631daSSadaf Ebrahimi
VisitExtract(const Instruction * instr)354*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitExtract(const Instruction* instr) {
355*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
356*f5c631daSSadaf Ebrahimi USE(instr);
357*f5c631daSSadaf Ebrahimi }
358*f5c631daSSadaf Ebrahimi
VisitFPCompare(const Instruction * instr)359*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPCompare(const Instruction* instr) {
360*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
361*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
362*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
363*f5c631daSSadaf Ebrahimi switch (instr->Mask(FPCompareMask)) {
364*f5c631daSSadaf Ebrahimi case FCMP_h:
365*f5c631daSSadaf Ebrahimi case FCMP_h_zero:
366*f5c631daSSadaf Ebrahimi case FCMPE_h:
367*f5c631daSSadaf Ebrahimi case FCMPE_h_zero:
368*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
369*f5c631daSSadaf Ebrahimi return;
370*f5c631daSSadaf Ebrahimi default:
371*f5c631daSSadaf Ebrahimi // No special CPU features.
372*f5c631daSSadaf Ebrahimi return;
373*f5c631daSSadaf Ebrahimi }
374*f5c631daSSadaf Ebrahimi }
375*f5c631daSSadaf Ebrahimi
VisitFPConditionalCompare(const Instruction * instr)376*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPConditionalCompare(const Instruction* instr) {
377*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
378*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
379*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
380*f5c631daSSadaf Ebrahimi switch (instr->Mask(FPConditionalCompareMask)) {
381*f5c631daSSadaf Ebrahimi case FCCMP_h:
382*f5c631daSSadaf Ebrahimi case FCCMPE_h:
383*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
384*f5c631daSSadaf Ebrahimi return;
385*f5c631daSSadaf Ebrahimi default:
386*f5c631daSSadaf Ebrahimi // No special CPU features.
387*f5c631daSSadaf Ebrahimi return;
388*f5c631daSSadaf Ebrahimi }
389*f5c631daSSadaf Ebrahimi }
390*f5c631daSSadaf Ebrahimi
VisitFPConditionalSelect(const Instruction * instr)391*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPConditionalSelect(const Instruction* instr) {
392*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
393*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
394*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
395*f5c631daSSadaf Ebrahimi if (instr->Mask(FPConditionalSelectMask) == FCSEL_h) {
396*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
397*f5c631daSSadaf Ebrahimi }
398*f5c631daSSadaf Ebrahimi }
399*f5c631daSSadaf Ebrahimi
VisitFPDataProcessing1Source(const Instruction * instr)400*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPDataProcessing1Source(
401*f5c631daSSadaf Ebrahimi const Instruction* instr) {
402*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
403*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
404*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
405*f5c631daSSadaf Ebrahimi switch (instr->Mask(FPDataProcessing1SourceMask)) {
406*f5c631daSSadaf Ebrahimi case FMOV_h:
407*f5c631daSSadaf Ebrahimi case FABS_h:
408*f5c631daSSadaf Ebrahimi case FNEG_h:
409*f5c631daSSadaf Ebrahimi case FSQRT_h:
410*f5c631daSSadaf Ebrahimi case FRINTN_h:
411*f5c631daSSadaf Ebrahimi case FRINTP_h:
412*f5c631daSSadaf Ebrahimi case FRINTM_h:
413*f5c631daSSadaf Ebrahimi case FRINTZ_h:
414*f5c631daSSadaf Ebrahimi case FRINTA_h:
415*f5c631daSSadaf Ebrahimi case FRINTX_h:
416*f5c631daSSadaf Ebrahimi case FRINTI_h:
417*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
418*f5c631daSSadaf Ebrahimi return;
419*f5c631daSSadaf Ebrahimi case FRINT32X_s:
420*f5c631daSSadaf Ebrahimi case FRINT32X_d:
421*f5c631daSSadaf Ebrahimi case FRINT32Z_s:
422*f5c631daSSadaf Ebrahimi case FRINT32Z_d:
423*f5c631daSSadaf Ebrahimi case FRINT64X_s:
424*f5c631daSSadaf Ebrahimi case FRINT64X_d:
425*f5c631daSSadaf Ebrahimi case FRINT64Z_s:
426*f5c631daSSadaf Ebrahimi case FRINT64Z_d:
427*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFrintToFixedSizedInt);
428*f5c631daSSadaf Ebrahimi return;
429*f5c631daSSadaf Ebrahimi default:
430*f5c631daSSadaf Ebrahimi // No special CPU features.
431*f5c631daSSadaf Ebrahimi // This category includes some half-precision FCVT instructions that do
432*f5c631daSSadaf Ebrahimi // not require FPHalf.
433*f5c631daSSadaf Ebrahimi return;
434*f5c631daSSadaf Ebrahimi }
435*f5c631daSSadaf Ebrahimi }
436*f5c631daSSadaf Ebrahimi
VisitFPDataProcessing2Source(const Instruction * instr)437*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPDataProcessing2Source(
438*f5c631daSSadaf Ebrahimi const Instruction* instr) {
439*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
440*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
441*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
442*f5c631daSSadaf Ebrahimi switch (instr->Mask(FPDataProcessing2SourceMask)) {
443*f5c631daSSadaf Ebrahimi case FMUL_h:
444*f5c631daSSadaf Ebrahimi case FDIV_h:
445*f5c631daSSadaf Ebrahimi case FADD_h:
446*f5c631daSSadaf Ebrahimi case FSUB_h:
447*f5c631daSSadaf Ebrahimi case FMAX_h:
448*f5c631daSSadaf Ebrahimi case FMIN_h:
449*f5c631daSSadaf Ebrahimi case FMAXNM_h:
450*f5c631daSSadaf Ebrahimi case FMINNM_h:
451*f5c631daSSadaf Ebrahimi case FNMUL_h:
452*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
453*f5c631daSSadaf Ebrahimi return;
454*f5c631daSSadaf Ebrahimi default:
455*f5c631daSSadaf Ebrahimi // No special CPU features.
456*f5c631daSSadaf Ebrahimi return;
457*f5c631daSSadaf Ebrahimi }
458*f5c631daSSadaf Ebrahimi }
459*f5c631daSSadaf Ebrahimi
VisitFPDataProcessing3Source(const Instruction * instr)460*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPDataProcessing3Source(
461*f5c631daSSadaf Ebrahimi const Instruction* instr) {
462*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
463*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
464*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
465*f5c631daSSadaf Ebrahimi switch (instr->Mask(FPDataProcessing3SourceMask)) {
466*f5c631daSSadaf Ebrahimi case FMADD_h:
467*f5c631daSSadaf Ebrahimi case FMSUB_h:
468*f5c631daSSadaf Ebrahimi case FNMADD_h:
469*f5c631daSSadaf Ebrahimi case FNMSUB_h:
470*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
471*f5c631daSSadaf Ebrahimi return;
472*f5c631daSSadaf Ebrahimi default:
473*f5c631daSSadaf Ebrahimi // No special CPU features.
474*f5c631daSSadaf Ebrahimi return;
475*f5c631daSSadaf Ebrahimi }
476*f5c631daSSadaf Ebrahimi }
477*f5c631daSSadaf Ebrahimi
VisitFPFixedPointConvert(const Instruction * instr)478*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPFixedPointConvert(const Instruction* instr) {
479*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
480*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
481*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
482*f5c631daSSadaf Ebrahimi switch (instr->Mask(FPFixedPointConvertMask)) {
483*f5c631daSSadaf Ebrahimi case FCVTZS_wh_fixed:
484*f5c631daSSadaf Ebrahimi case FCVTZS_xh_fixed:
485*f5c631daSSadaf Ebrahimi case FCVTZU_wh_fixed:
486*f5c631daSSadaf Ebrahimi case FCVTZU_xh_fixed:
487*f5c631daSSadaf Ebrahimi case SCVTF_hw_fixed:
488*f5c631daSSadaf Ebrahimi case SCVTF_hx_fixed:
489*f5c631daSSadaf Ebrahimi case UCVTF_hw_fixed:
490*f5c631daSSadaf Ebrahimi case UCVTF_hx_fixed:
491*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
492*f5c631daSSadaf Ebrahimi return;
493*f5c631daSSadaf Ebrahimi default:
494*f5c631daSSadaf Ebrahimi // No special CPU features.
495*f5c631daSSadaf Ebrahimi return;
496*f5c631daSSadaf Ebrahimi }
497*f5c631daSSadaf Ebrahimi }
498*f5c631daSSadaf Ebrahimi
VisitFPImmediate(const Instruction * instr)499*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPImmediate(const Instruction* instr) {
500*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
501*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
502*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
503*f5c631daSSadaf Ebrahimi if (instr->Mask(FPImmediateMask) == FMOV_h_imm) {
504*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
505*f5c631daSSadaf Ebrahimi }
506*f5c631daSSadaf Ebrahimi }
507*f5c631daSSadaf Ebrahimi
VisitFPIntegerConvert(const Instruction * instr)508*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitFPIntegerConvert(const Instruction* instr) {
509*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
510*f5c631daSSadaf Ebrahimi // All of these instructions require FP.
511*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
512*f5c631daSSadaf Ebrahimi switch (instr->Mask(FPIntegerConvertMask)) {
513*f5c631daSSadaf Ebrahimi case FCVTAS_wh:
514*f5c631daSSadaf Ebrahimi case FCVTAS_xh:
515*f5c631daSSadaf Ebrahimi case FCVTAU_wh:
516*f5c631daSSadaf Ebrahimi case FCVTAU_xh:
517*f5c631daSSadaf Ebrahimi case FCVTMS_wh:
518*f5c631daSSadaf Ebrahimi case FCVTMS_xh:
519*f5c631daSSadaf Ebrahimi case FCVTMU_wh:
520*f5c631daSSadaf Ebrahimi case FCVTMU_xh:
521*f5c631daSSadaf Ebrahimi case FCVTNS_wh:
522*f5c631daSSadaf Ebrahimi case FCVTNS_xh:
523*f5c631daSSadaf Ebrahimi case FCVTNU_wh:
524*f5c631daSSadaf Ebrahimi case FCVTNU_xh:
525*f5c631daSSadaf Ebrahimi case FCVTPS_wh:
526*f5c631daSSadaf Ebrahimi case FCVTPS_xh:
527*f5c631daSSadaf Ebrahimi case FCVTPU_wh:
528*f5c631daSSadaf Ebrahimi case FCVTPU_xh:
529*f5c631daSSadaf Ebrahimi case FCVTZS_wh:
530*f5c631daSSadaf Ebrahimi case FCVTZS_xh:
531*f5c631daSSadaf Ebrahimi case FCVTZU_wh:
532*f5c631daSSadaf Ebrahimi case FCVTZU_xh:
533*f5c631daSSadaf Ebrahimi case FMOV_hw:
534*f5c631daSSadaf Ebrahimi case FMOV_hx:
535*f5c631daSSadaf Ebrahimi case FMOV_wh:
536*f5c631daSSadaf Ebrahimi case FMOV_xh:
537*f5c631daSSadaf Ebrahimi case SCVTF_hw:
538*f5c631daSSadaf Ebrahimi case SCVTF_hx:
539*f5c631daSSadaf Ebrahimi case UCVTF_hw:
540*f5c631daSSadaf Ebrahimi case UCVTF_hx:
541*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFPHalf);
542*f5c631daSSadaf Ebrahimi return;
543*f5c631daSSadaf Ebrahimi case FMOV_d1_x:
544*f5c631daSSadaf Ebrahimi case FMOV_x_d1:
545*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
546*f5c631daSSadaf Ebrahimi return;
547*f5c631daSSadaf Ebrahimi case FJCVTZS:
548*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kJSCVT);
549*f5c631daSSadaf Ebrahimi return;
550*f5c631daSSadaf Ebrahimi default:
551*f5c631daSSadaf Ebrahimi // No special CPU features.
552*f5c631daSSadaf Ebrahimi return;
553*f5c631daSSadaf Ebrahimi }
554*f5c631daSSadaf Ebrahimi }
555*f5c631daSSadaf Ebrahimi
VisitLoadLiteral(const Instruction * instr)556*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadLiteral(const Instruction* instr) {
557*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
558*f5c631daSSadaf Ebrahimi switch (instr->Mask(LoadLiteralMask)) {
559*f5c631daSSadaf Ebrahimi case LDR_s_lit:
560*f5c631daSSadaf Ebrahimi case LDR_d_lit:
561*f5c631daSSadaf Ebrahimi scope.RecordOneOrBothOf(CPUFeatures::kFP, CPUFeatures::kNEON);
562*f5c631daSSadaf Ebrahimi return;
563*f5c631daSSadaf Ebrahimi case LDR_q_lit:
564*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
565*f5c631daSSadaf Ebrahimi return;
566*f5c631daSSadaf Ebrahimi default:
567*f5c631daSSadaf Ebrahimi // No special CPU features.
568*f5c631daSSadaf Ebrahimi return;
569*f5c631daSSadaf Ebrahimi }
570*f5c631daSSadaf Ebrahimi }
571*f5c631daSSadaf Ebrahimi
VisitLoadStoreExclusive(const Instruction * instr)572*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStoreExclusive(const Instruction* instr) {
573*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
574*f5c631daSSadaf Ebrahimi switch (instr->Mask(LoadStoreExclusiveMask)) {
575*f5c631daSSadaf Ebrahimi case CAS_w:
576*f5c631daSSadaf Ebrahimi case CASA_w:
577*f5c631daSSadaf Ebrahimi case CASL_w:
578*f5c631daSSadaf Ebrahimi case CASAL_w:
579*f5c631daSSadaf Ebrahimi case CAS_x:
580*f5c631daSSadaf Ebrahimi case CASA_x:
581*f5c631daSSadaf Ebrahimi case CASL_x:
582*f5c631daSSadaf Ebrahimi case CASAL_x:
583*f5c631daSSadaf Ebrahimi case CASB:
584*f5c631daSSadaf Ebrahimi case CASAB:
585*f5c631daSSadaf Ebrahimi case CASLB:
586*f5c631daSSadaf Ebrahimi case CASALB:
587*f5c631daSSadaf Ebrahimi case CASH:
588*f5c631daSSadaf Ebrahimi case CASAH:
589*f5c631daSSadaf Ebrahimi case CASLH:
590*f5c631daSSadaf Ebrahimi case CASALH:
591*f5c631daSSadaf Ebrahimi case CASP_w:
592*f5c631daSSadaf Ebrahimi case CASPA_w:
593*f5c631daSSadaf Ebrahimi case CASPL_w:
594*f5c631daSSadaf Ebrahimi case CASPAL_w:
595*f5c631daSSadaf Ebrahimi case CASP_x:
596*f5c631daSSadaf Ebrahimi case CASPA_x:
597*f5c631daSSadaf Ebrahimi case CASPL_x:
598*f5c631daSSadaf Ebrahimi case CASPAL_x:
599*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kAtomics);
600*f5c631daSSadaf Ebrahimi return;
601*f5c631daSSadaf Ebrahimi case STLLRB:
602*f5c631daSSadaf Ebrahimi case LDLARB:
603*f5c631daSSadaf Ebrahimi case STLLRH:
604*f5c631daSSadaf Ebrahimi case LDLARH:
605*f5c631daSSadaf Ebrahimi case STLLR_w:
606*f5c631daSSadaf Ebrahimi case LDLAR_w:
607*f5c631daSSadaf Ebrahimi case STLLR_x:
608*f5c631daSSadaf Ebrahimi case LDLAR_x:
609*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kLORegions);
610*f5c631daSSadaf Ebrahimi return;
611*f5c631daSSadaf Ebrahimi default:
612*f5c631daSSadaf Ebrahimi // No special CPU features.
613*f5c631daSSadaf Ebrahimi return;
614*f5c631daSSadaf Ebrahimi }
615*f5c631daSSadaf Ebrahimi }
616*f5c631daSSadaf Ebrahimi
VisitLoadStorePairNonTemporal(const Instruction * instr)617*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStorePairNonTemporal(
618*f5c631daSSadaf Ebrahimi const Instruction* instr) {
619*f5c631daSSadaf Ebrahimi LoadStorePairHelper(instr);
620*f5c631daSSadaf Ebrahimi }
621*f5c631daSSadaf Ebrahimi
VisitLoadStorePairOffset(const Instruction * instr)622*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStorePairOffset(const Instruction* instr) {
623*f5c631daSSadaf Ebrahimi LoadStorePairHelper(instr);
624*f5c631daSSadaf Ebrahimi }
625*f5c631daSSadaf Ebrahimi
VisitLoadStorePairPostIndex(const Instruction * instr)626*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStorePairPostIndex(const Instruction* instr) {
627*f5c631daSSadaf Ebrahimi LoadStorePairHelper(instr);
628*f5c631daSSadaf Ebrahimi }
629*f5c631daSSadaf Ebrahimi
VisitLoadStorePairPreIndex(const Instruction * instr)630*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStorePairPreIndex(const Instruction* instr) {
631*f5c631daSSadaf Ebrahimi LoadStorePairHelper(instr);
632*f5c631daSSadaf Ebrahimi }
633*f5c631daSSadaf Ebrahimi
VisitLoadStorePostIndex(const Instruction * instr)634*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStorePostIndex(const Instruction* instr) {
635*f5c631daSSadaf Ebrahimi LoadStoreHelper(instr);
636*f5c631daSSadaf Ebrahimi }
637*f5c631daSSadaf Ebrahimi
VisitLoadStorePreIndex(const Instruction * instr)638*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStorePreIndex(const Instruction* instr) {
639*f5c631daSSadaf Ebrahimi LoadStoreHelper(instr);
640*f5c631daSSadaf Ebrahimi }
641*f5c631daSSadaf Ebrahimi
VisitLoadStoreRegisterOffset(const Instruction * instr)642*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStoreRegisterOffset(
643*f5c631daSSadaf Ebrahimi const Instruction* instr) {
644*f5c631daSSadaf Ebrahimi LoadStoreHelper(instr);
645*f5c631daSSadaf Ebrahimi }
646*f5c631daSSadaf Ebrahimi
VisitLoadStoreUnscaledOffset(const Instruction * instr)647*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStoreUnscaledOffset(
648*f5c631daSSadaf Ebrahimi const Instruction* instr) {
649*f5c631daSSadaf Ebrahimi LoadStoreHelper(instr);
650*f5c631daSSadaf Ebrahimi }
651*f5c631daSSadaf Ebrahimi
VisitLoadStoreUnsignedOffset(const Instruction * instr)652*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLoadStoreUnsignedOffset(
653*f5c631daSSadaf Ebrahimi const Instruction* instr) {
654*f5c631daSSadaf Ebrahimi LoadStoreHelper(instr);
655*f5c631daSSadaf Ebrahimi }
656*f5c631daSSadaf Ebrahimi
VisitLogicalImmediate(const Instruction * instr)657*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLogicalImmediate(const Instruction* instr) {
658*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
659*f5c631daSSadaf Ebrahimi USE(instr);
660*f5c631daSSadaf Ebrahimi }
661*f5c631daSSadaf Ebrahimi
VisitLogicalShifted(const Instruction * instr)662*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitLogicalShifted(const Instruction* instr) {
663*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
664*f5c631daSSadaf Ebrahimi USE(instr);
665*f5c631daSSadaf Ebrahimi }
666*f5c631daSSadaf Ebrahimi
VisitMoveWideImmediate(const Instruction * instr)667*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitMoveWideImmediate(const Instruction* instr) {
668*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
669*f5c631daSSadaf Ebrahimi USE(instr);
670*f5c631daSSadaf Ebrahimi }
671*f5c631daSSadaf Ebrahimi
VisitNEON2RegMisc(const Instruction * instr)672*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEON2RegMisc(const Instruction* instr) {
673*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
674*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
675*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
676*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEON2RegMiscFPMask)) {
677*f5c631daSSadaf Ebrahimi case NEON_FABS:
678*f5c631daSSadaf Ebrahimi case NEON_FNEG:
679*f5c631daSSadaf Ebrahimi case NEON_FSQRT:
680*f5c631daSSadaf Ebrahimi case NEON_FCVTL:
681*f5c631daSSadaf Ebrahimi case NEON_FCVTN:
682*f5c631daSSadaf Ebrahimi case NEON_FCVTXN:
683*f5c631daSSadaf Ebrahimi case NEON_FRINTI:
684*f5c631daSSadaf Ebrahimi case NEON_FRINTX:
685*f5c631daSSadaf Ebrahimi case NEON_FRINTA:
686*f5c631daSSadaf Ebrahimi case NEON_FRINTM:
687*f5c631daSSadaf Ebrahimi case NEON_FRINTN:
688*f5c631daSSadaf Ebrahimi case NEON_FRINTP:
689*f5c631daSSadaf Ebrahimi case NEON_FRINTZ:
690*f5c631daSSadaf Ebrahimi case NEON_FCVTNS:
691*f5c631daSSadaf Ebrahimi case NEON_FCVTNU:
692*f5c631daSSadaf Ebrahimi case NEON_FCVTPS:
693*f5c631daSSadaf Ebrahimi case NEON_FCVTPU:
694*f5c631daSSadaf Ebrahimi case NEON_FCVTMS:
695*f5c631daSSadaf Ebrahimi case NEON_FCVTMU:
696*f5c631daSSadaf Ebrahimi case NEON_FCVTZS:
697*f5c631daSSadaf Ebrahimi case NEON_FCVTZU:
698*f5c631daSSadaf Ebrahimi case NEON_FCVTAS:
699*f5c631daSSadaf Ebrahimi case NEON_FCVTAU:
700*f5c631daSSadaf Ebrahimi case NEON_SCVTF:
701*f5c631daSSadaf Ebrahimi case NEON_UCVTF:
702*f5c631daSSadaf Ebrahimi case NEON_FRSQRTE:
703*f5c631daSSadaf Ebrahimi case NEON_FRECPE:
704*f5c631daSSadaf Ebrahimi case NEON_FCMGT_zero:
705*f5c631daSSadaf Ebrahimi case NEON_FCMGE_zero:
706*f5c631daSSadaf Ebrahimi case NEON_FCMEQ_zero:
707*f5c631daSSadaf Ebrahimi case NEON_FCMLE_zero:
708*f5c631daSSadaf Ebrahimi case NEON_FCMLT_zero:
709*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
710*f5c631daSSadaf Ebrahimi return;
711*f5c631daSSadaf Ebrahimi case NEON_FRINT32X:
712*f5c631daSSadaf Ebrahimi case NEON_FRINT32Z:
713*f5c631daSSadaf Ebrahimi case NEON_FRINT64X:
714*f5c631daSSadaf Ebrahimi case NEON_FRINT64Z:
715*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kFrintToFixedSizedInt);
716*f5c631daSSadaf Ebrahimi return;
717*f5c631daSSadaf Ebrahimi default:
718*f5c631daSSadaf Ebrahimi // No additional features.
719*f5c631daSSadaf Ebrahimi return;
720*f5c631daSSadaf Ebrahimi }
721*f5c631daSSadaf Ebrahimi }
722*f5c631daSSadaf Ebrahimi
VisitNEON2RegMiscFP16(const Instruction * instr)723*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEON2RegMiscFP16(const Instruction* instr) {
724*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
725*f5c631daSSadaf Ebrahimi // All of these instructions require NEONHalf.
726*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kNEON, CPUFeatures::kNEONHalf);
727*f5c631daSSadaf Ebrahimi USE(instr);
728*f5c631daSSadaf Ebrahimi }
729*f5c631daSSadaf Ebrahimi
VisitNEON3Different(const Instruction * instr)730*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEON3Different(const Instruction* instr) {
731*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
732*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
733*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
734*f5c631daSSadaf Ebrahimi USE(instr);
735*f5c631daSSadaf Ebrahimi }
736*f5c631daSSadaf Ebrahimi
VisitNEON3Same(const Instruction * instr)737*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEON3Same(const Instruction* instr) {
738*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
739*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
740*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
741*f5c631daSSadaf Ebrahimi if (instr->Mask(NEON3SameFPFMask) == NEON3SameFPFixed) {
742*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
743*f5c631daSSadaf Ebrahimi }
744*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEON3SameFHMMask)) {
745*f5c631daSSadaf Ebrahimi case NEON_FMLAL:
746*f5c631daSSadaf Ebrahimi case NEON_FMLAL2:
747*f5c631daSSadaf Ebrahimi case NEON_FMLSL:
748*f5c631daSSadaf Ebrahimi case NEON_FMLSL2:
749*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kNEONHalf, CPUFeatures::kFHM);
750*f5c631daSSadaf Ebrahimi return;
751*f5c631daSSadaf Ebrahimi default:
752*f5c631daSSadaf Ebrahimi // No additional features.
753*f5c631daSSadaf Ebrahimi return;
754*f5c631daSSadaf Ebrahimi }
755*f5c631daSSadaf Ebrahimi }
756*f5c631daSSadaf Ebrahimi
VisitNEON3SameExtra(const Instruction * instr)757*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEON3SameExtra(const Instruction* instr) {
758*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
759*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
760*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
761*f5c631daSSadaf Ebrahimi if ((instr->Mask(NEON3SameExtraFCMLAMask) == NEON_FCMLA) ||
762*f5c631daSSadaf Ebrahimi (instr->Mask(NEON3SameExtraFCADDMask) == NEON_FCADD)) {
763*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kFcma);
764*f5c631daSSadaf Ebrahimi if (instr->GetNEONSize() == 1) scope.Record(CPUFeatures::kNEONHalf);
765*f5c631daSSadaf Ebrahimi } else {
766*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEON3SameExtraMask)) {
767*f5c631daSSadaf Ebrahimi case NEON_SDOT:
768*f5c631daSSadaf Ebrahimi case NEON_UDOT:
769*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kDotProduct);
770*f5c631daSSadaf Ebrahimi return;
771*f5c631daSSadaf Ebrahimi case NEON_SQRDMLAH:
772*f5c631daSSadaf Ebrahimi case NEON_SQRDMLSH:
773*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kRDM);
774*f5c631daSSadaf Ebrahimi return;
775*f5c631daSSadaf Ebrahimi default:
776*f5c631daSSadaf Ebrahimi // No additional features.
777*f5c631daSSadaf Ebrahimi return;
778*f5c631daSSadaf Ebrahimi }
779*f5c631daSSadaf Ebrahimi }
780*f5c631daSSadaf Ebrahimi }
781*f5c631daSSadaf Ebrahimi
VisitNEON3SameFP16(const Instruction * instr)782*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEON3SameFP16(const Instruction* instr) {
783*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
784*f5c631daSSadaf Ebrahimi // All of these instructions require NEON FP16 support.
785*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kNEON, CPUFeatures::kNEONHalf);
786*f5c631daSSadaf Ebrahimi USE(instr);
787*f5c631daSSadaf Ebrahimi }
788*f5c631daSSadaf Ebrahimi
VisitNEONAcrossLanes(const Instruction * instr)789*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONAcrossLanes(const Instruction* instr) {
790*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
791*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
792*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
793*f5c631daSSadaf Ebrahimi if (instr->Mask(NEONAcrossLanesFP16FMask) == NEONAcrossLanesFP16Fixed) {
794*f5c631daSSadaf Ebrahimi // FMAXV_H, FMINV_H, FMAXNMV_H, FMINNMV_H
795*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kNEONHalf);
796*f5c631daSSadaf Ebrahimi } else if (instr->Mask(NEONAcrossLanesFPFMask) == NEONAcrossLanesFPFixed) {
797*f5c631daSSadaf Ebrahimi // FMAXV, FMINV, FMAXNMV, FMINNMV
798*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
799*f5c631daSSadaf Ebrahimi }
800*f5c631daSSadaf Ebrahimi }
801*f5c631daSSadaf Ebrahimi
VisitNEONByIndexedElement(const Instruction * instr)802*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONByIndexedElement(const Instruction* instr) {
803*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
804*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
805*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
806*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONByIndexedElementMask)) {
807*f5c631daSSadaf Ebrahimi case NEON_SDOT_byelement:
808*f5c631daSSadaf Ebrahimi case NEON_UDOT_byelement:
809*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kDotProduct);
810*f5c631daSSadaf Ebrahimi return;
811*f5c631daSSadaf Ebrahimi case NEON_SQRDMLAH_byelement:
812*f5c631daSSadaf Ebrahimi case NEON_SQRDMLSH_byelement:
813*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kRDM);
814*f5c631daSSadaf Ebrahimi return;
815*f5c631daSSadaf Ebrahimi default:
816*f5c631daSSadaf Ebrahimi // Fall through to check other instructions.
817*f5c631daSSadaf Ebrahimi break;
818*f5c631daSSadaf Ebrahimi }
819*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONByIndexedElementFPLongMask)) {
820*f5c631daSSadaf Ebrahimi case NEON_FMLAL_H_byelement:
821*f5c631daSSadaf Ebrahimi case NEON_FMLAL2_H_byelement:
822*f5c631daSSadaf Ebrahimi case NEON_FMLSL_H_byelement:
823*f5c631daSSadaf Ebrahimi case NEON_FMLSL2_H_byelement:
824*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kNEONHalf, CPUFeatures::kFHM);
825*f5c631daSSadaf Ebrahimi return;
826*f5c631daSSadaf Ebrahimi default:
827*f5c631daSSadaf Ebrahimi // Fall through to check other instructions.
828*f5c631daSSadaf Ebrahimi break;
829*f5c631daSSadaf Ebrahimi }
830*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONByIndexedElementFPMask)) {
831*f5c631daSSadaf Ebrahimi case NEON_FMLA_H_byelement:
832*f5c631daSSadaf Ebrahimi case NEON_FMLS_H_byelement:
833*f5c631daSSadaf Ebrahimi case NEON_FMUL_H_byelement:
834*f5c631daSSadaf Ebrahimi case NEON_FMULX_H_byelement:
835*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEONHalf);
836*f5c631daSSadaf Ebrahimi VIXL_FALLTHROUGH();
837*f5c631daSSadaf Ebrahimi case NEON_FMLA_byelement:
838*f5c631daSSadaf Ebrahimi case NEON_FMLS_byelement:
839*f5c631daSSadaf Ebrahimi case NEON_FMUL_byelement:
840*f5c631daSSadaf Ebrahimi case NEON_FMULX_byelement:
841*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
842*f5c631daSSadaf Ebrahimi return;
843*f5c631daSSadaf Ebrahimi default:
844*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONByIndexedElementFPComplexMask)) {
845*f5c631daSSadaf Ebrahimi case NEON_FCMLA_byelement:
846*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kFcma);
847*f5c631daSSadaf Ebrahimi if (instr->GetNEONSize() == 1) scope.Record(CPUFeatures::kNEONHalf);
848*f5c631daSSadaf Ebrahimi return;
849*f5c631daSSadaf Ebrahimi }
850*f5c631daSSadaf Ebrahimi // No additional features.
851*f5c631daSSadaf Ebrahimi return;
852*f5c631daSSadaf Ebrahimi }
853*f5c631daSSadaf Ebrahimi }
854*f5c631daSSadaf Ebrahimi
VisitNEONCopy(const Instruction * instr)855*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONCopy(const Instruction* instr) {
856*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
857*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
858*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
859*f5c631daSSadaf Ebrahimi USE(instr);
860*f5c631daSSadaf Ebrahimi }
861*f5c631daSSadaf Ebrahimi
VisitNEONExtract(const Instruction * instr)862*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONExtract(const Instruction* instr) {
863*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
864*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
865*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
866*f5c631daSSadaf Ebrahimi USE(instr);
867*f5c631daSSadaf Ebrahimi }
868*f5c631daSSadaf Ebrahimi
VisitNEONLoadStoreMultiStruct(const Instruction * instr)869*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONLoadStoreMultiStruct(
870*f5c631daSSadaf Ebrahimi const Instruction* instr) {
871*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
872*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
873*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
874*f5c631daSSadaf Ebrahimi USE(instr);
875*f5c631daSSadaf Ebrahimi }
876*f5c631daSSadaf Ebrahimi
VisitNEONLoadStoreMultiStructPostIndex(const Instruction * instr)877*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONLoadStoreMultiStructPostIndex(
878*f5c631daSSadaf Ebrahimi const Instruction* instr) {
879*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
880*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
881*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
882*f5c631daSSadaf Ebrahimi USE(instr);
883*f5c631daSSadaf Ebrahimi }
884*f5c631daSSadaf Ebrahimi
VisitNEONLoadStoreSingleStruct(const Instruction * instr)885*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONLoadStoreSingleStruct(
886*f5c631daSSadaf Ebrahimi const Instruction* instr) {
887*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
888*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
889*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
890*f5c631daSSadaf Ebrahimi USE(instr);
891*f5c631daSSadaf Ebrahimi }
892*f5c631daSSadaf Ebrahimi
VisitNEONLoadStoreSingleStructPostIndex(const Instruction * instr)893*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONLoadStoreSingleStructPostIndex(
894*f5c631daSSadaf Ebrahimi const Instruction* instr) {
895*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
896*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
897*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
898*f5c631daSSadaf Ebrahimi USE(instr);
899*f5c631daSSadaf Ebrahimi }
900*f5c631daSSadaf Ebrahimi
VisitNEONModifiedImmediate(const Instruction * instr)901*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONModifiedImmediate(const Instruction* instr) {
902*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
903*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
904*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
905*f5c631daSSadaf Ebrahimi if (instr->GetNEONCmode() == 0xf) {
906*f5c631daSSadaf Ebrahimi // FMOV (vector, immediate), double-, single- or half-precision.
907*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
908*f5c631daSSadaf Ebrahimi if (instr->ExtractBit(11)) scope.Record(CPUFeatures::kNEONHalf);
909*f5c631daSSadaf Ebrahimi }
910*f5c631daSSadaf Ebrahimi }
911*f5c631daSSadaf Ebrahimi
VisitNEONPerm(const Instruction * instr)912*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONPerm(const Instruction* instr) {
913*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
914*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
915*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
916*f5c631daSSadaf Ebrahimi USE(instr);
917*f5c631daSSadaf Ebrahimi }
918*f5c631daSSadaf Ebrahimi
VisitNEONScalar2RegMisc(const Instruction * instr)919*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalar2RegMisc(const Instruction* instr) {
920*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
921*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
922*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
923*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONScalar2RegMiscFPMask)) {
924*f5c631daSSadaf Ebrahimi case NEON_FRECPE_scalar:
925*f5c631daSSadaf Ebrahimi case NEON_FRECPX_scalar:
926*f5c631daSSadaf Ebrahimi case NEON_FRSQRTE_scalar:
927*f5c631daSSadaf Ebrahimi case NEON_FCMGT_zero_scalar:
928*f5c631daSSadaf Ebrahimi case NEON_FCMGE_zero_scalar:
929*f5c631daSSadaf Ebrahimi case NEON_FCMEQ_zero_scalar:
930*f5c631daSSadaf Ebrahimi case NEON_FCMLE_zero_scalar:
931*f5c631daSSadaf Ebrahimi case NEON_FCMLT_zero_scalar:
932*f5c631daSSadaf Ebrahimi case NEON_SCVTF_scalar:
933*f5c631daSSadaf Ebrahimi case NEON_UCVTF_scalar:
934*f5c631daSSadaf Ebrahimi case NEON_FCVTNS_scalar:
935*f5c631daSSadaf Ebrahimi case NEON_FCVTNU_scalar:
936*f5c631daSSadaf Ebrahimi case NEON_FCVTPS_scalar:
937*f5c631daSSadaf Ebrahimi case NEON_FCVTPU_scalar:
938*f5c631daSSadaf Ebrahimi case NEON_FCVTMS_scalar:
939*f5c631daSSadaf Ebrahimi case NEON_FCVTMU_scalar:
940*f5c631daSSadaf Ebrahimi case NEON_FCVTZS_scalar:
941*f5c631daSSadaf Ebrahimi case NEON_FCVTZU_scalar:
942*f5c631daSSadaf Ebrahimi case NEON_FCVTAS_scalar:
943*f5c631daSSadaf Ebrahimi case NEON_FCVTAU_scalar:
944*f5c631daSSadaf Ebrahimi case NEON_FCVTXN_scalar:
945*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
946*f5c631daSSadaf Ebrahimi return;
947*f5c631daSSadaf Ebrahimi default:
948*f5c631daSSadaf Ebrahimi // No additional features.
949*f5c631daSSadaf Ebrahimi return;
950*f5c631daSSadaf Ebrahimi }
951*f5c631daSSadaf Ebrahimi }
952*f5c631daSSadaf Ebrahimi
VisitNEONScalar2RegMiscFP16(const Instruction * instr)953*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalar2RegMiscFP16(const Instruction* instr) {
954*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
955*f5c631daSSadaf Ebrahimi // All of these instructions require NEONHalf.
956*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kNEON, CPUFeatures::kNEONHalf);
957*f5c631daSSadaf Ebrahimi USE(instr);
958*f5c631daSSadaf Ebrahimi }
959*f5c631daSSadaf Ebrahimi
VisitNEONScalar3Diff(const Instruction * instr)960*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalar3Diff(const Instruction* instr) {
961*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
962*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
963*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
964*f5c631daSSadaf Ebrahimi USE(instr);
965*f5c631daSSadaf Ebrahimi }
966*f5c631daSSadaf Ebrahimi
VisitNEONScalar3Same(const Instruction * instr)967*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalar3Same(const Instruction* instr) {
968*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
969*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
970*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
971*f5c631daSSadaf Ebrahimi if (instr->Mask(NEONScalar3SameFPFMask) == NEONScalar3SameFPFixed) {
972*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
973*f5c631daSSadaf Ebrahimi }
974*f5c631daSSadaf Ebrahimi }
975*f5c631daSSadaf Ebrahimi
VisitNEONScalar3SameExtra(const Instruction * instr)976*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalar3SameExtra(const Instruction* instr) {
977*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
978*f5c631daSSadaf Ebrahimi // All of these instructions require NEON and RDM.
979*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON, CPUFeatures::kRDM);
980*f5c631daSSadaf Ebrahimi USE(instr);
981*f5c631daSSadaf Ebrahimi }
982*f5c631daSSadaf Ebrahimi
VisitNEONScalar3SameFP16(const Instruction * instr)983*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalar3SameFP16(const Instruction* instr) {
984*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
985*f5c631daSSadaf Ebrahimi // All of these instructions require NEONHalf.
986*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP, CPUFeatures::kNEON, CPUFeatures::kNEONHalf);
987*f5c631daSSadaf Ebrahimi USE(instr);
988*f5c631daSSadaf Ebrahimi }
989*f5c631daSSadaf Ebrahimi
VisitNEONScalarByIndexedElement(const Instruction * instr)990*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalarByIndexedElement(
991*f5c631daSSadaf Ebrahimi const Instruction* instr) {
992*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
993*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
994*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
995*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONScalarByIndexedElementMask)) {
996*f5c631daSSadaf Ebrahimi case NEON_SQRDMLAH_byelement_scalar:
997*f5c631daSSadaf Ebrahimi case NEON_SQRDMLSH_byelement_scalar:
998*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kRDM);
999*f5c631daSSadaf Ebrahimi return;
1000*f5c631daSSadaf Ebrahimi default:
1001*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONScalarByIndexedElementFPMask)) {
1002*f5c631daSSadaf Ebrahimi case NEON_FMLA_H_byelement_scalar:
1003*f5c631daSSadaf Ebrahimi case NEON_FMLS_H_byelement_scalar:
1004*f5c631daSSadaf Ebrahimi case NEON_FMUL_H_byelement_scalar:
1005*f5c631daSSadaf Ebrahimi case NEON_FMULX_H_byelement_scalar:
1006*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEONHalf);
1007*f5c631daSSadaf Ebrahimi VIXL_FALLTHROUGH();
1008*f5c631daSSadaf Ebrahimi case NEON_FMLA_byelement_scalar:
1009*f5c631daSSadaf Ebrahimi case NEON_FMLS_byelement_scalar:
1010*f5c631daSSadaf Ebrahimi case NEON_FMUL_byelement_scalar:
1011*f5c631daSSadaf Ebrahimi case NEON_FMULX_byelement_scalar:
1012*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
1013*f5c631daSSadaf Ebrahimi return;
1014*f5c631daSSadaf Ebrahimi }
1015*f5c631daSSadaf Ebrahimi // No additional features.
1016*f5c631daSSadaf Ebrahimi return;
1017*f5c631daSSadaf Ebrahimi }
1018*f5c631daSSadaf Ebrahimi }
1019*f5c631daSSadaf Ebrahimi
VisitNEONScalarCopy(const Instruction * instr)1020*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalarCopy(const Instruction* instr) {
1021*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1022*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
1023*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
1024*f5c631daSSadaf Ebrahimi USE(instr);
1025*f5c631daSSadaf Ebrahimi }
1026*f5c631daSSadaf Ebrahimi
VisitNEONScalarPairwise(const Instruction * instr)1027*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalarPairwise(const Instruction* instr) {
1028*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1029*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
1030*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
1031*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONScalarPairwiseMask)) {
1032*f5c631daSSadaf Ebrahimi case NEON_FMAXNMP_h_scalar:
1033*f5c631daSSadaf Ebrahimi case NEON_FADDP_h_scalar:
1034*f5c631daSSadaf Ebrahimi case NEON_FMAXP_h_scalar:
1035*f5c631daSSadaf Ebrahimi case NEON_FMINNMP_h_scalar:
1036*f5c631daSSadaf Ebrahimi case NEON_FMINP_h_scalar:
1037*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEONHalf);
1038*f5c631daSSadaf Ebrahimi VIXL_FALLTHROUGH();
1039*f5c631daSSadaf Ebrahimi case NEON_FADDP_scalar:
1040*f5c631daSSadaf Ebrahimi case NEON_FMAXP_scalar:
1041*f5c631daSSadaf Ebrahimi case NEON_FMAXNMP_scalar:
1042*f5c631daSSadaf Ebrahimi case NEON_FMINP_scalar:
1043*f5c631daSSadaf Ebrahimi case NEON_FMINNMP_scalar:
1044*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
1045*f5c631daSSadaf Ebrahimi return;
1046*f5c631daSSadaf Ebrahimi default:
1047*f5c631daSSadaf Ebrahimi // No additional features.
1048*f5c631daSSadaf Ebrahimi return;
1049*f5c631daSSadaf Ebrahimi }
1050*f5c631daSSadaf Ebrahimi }
1051*f5c631daSSadaf Ebrahimi
VisitNEONScalarShiftImmediate(const Instruction * instr)1052*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONScalarShiftImmediate(
1053*f5c631daSSadaf Ebrahimi const Instruction* instr) {
1054*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1055*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
1056*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
1057*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONScalarShiftImmediateMask)) {
1058*f5c631daSSadaf Ebrahimi case NEON_FCVTZS_imm_scalar:
1059*f5c631daSSadaf Ebrahimi case NEON_FCVTZU_imm_scalar:
1060*f5c631daSSadaf Ebrahimi case NEON_SCVTF_imm_scalar:
1061*f5c631daSSadaf Ebrahimi case NEON_UCVTF_imm_scalar:
1062*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
1063*f5c631daSSadaf Ebrahimi // If immh is 0b001x then the data type is FP16, and requires kNEONHalf.
1064*f5c631daSSadaf Ebrahimi if ((instr->GetImmNEONImmh() & 0xe) == 0x2) {
1065*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEONHalf);
1066*f5c631daSSadaf Ebrahimi }
1067*f5c631daSSadaf Ebrahimi return;
1068*f5c631daSSadaf Ebrahimi default:
1069*f5c631daSSadaf Ebrahimi // No additional features.
1070*f5c631daSSadaf Ebrahimi return;
1071*f5c631daSSadaf Ebrahimi }
1072*f5c631daSSadaf Ebrahimi }
1073*f5c631daSSadaf Ebrahimi
VisitNEONShiftImmediate(const Instruction * instr)1074*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONShiftImmediate(const Instruction* instr) {
1075*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1076*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
1077*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
1078*f5c631daSSadaf Ebrahimi switch (instr->Mask(NEONShiftImmediateMask)) {
1079*f5c631daSSadaf Ebrahimi case NEON_SCVTF_imm:
1080*f5c631daSSadaf Ebrahimi case NEON_UCVTF_imm:
1081*f5c631daSSadaf Ebrahimi case NEON_FCVTZS_imm:
1082*f5c631daSSadaf Ebrahimi case NEON_FCVTZU_imm:
1083*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFP);
1084*f5c631daSSadaf Ebrahimi // If immh is 0b001x then the data type is FP16, and requires kNEONHalf.
1085*f5c631daSSadaf Ebrahimi if ((instr->GetImmNEONImmh() & 0xe) == 0x2) {
1086*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEONHalf);
1087*f5c631daSSadaf Ebrahimi }
1088*f5c631daSSadaf Ebrahimi return;
1089*f5c631daSSadaf Ebrahimi default:
1090*f5c631daSSadaf Ebrahimi // No additional features.
1091*f5c631daSSadaf Ebrahimi return;
1092*f5c631daSSadaf Ebrahimi }
1093*f5c631daSSadaf Ebrahimi }
1094*f5c631daSSadaf Ebrahimi
VisitNEONTable(const Instruction * instr)1095*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitNEONTable(const Instruction* instr) {
1096*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1097*f5c631daSSadaf Ebrahimi // All of these instructions require NEON.
1098*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kNEON);
1099*f5c631daSSadaf Ebrahimi USE(instr);
1100*f5c631daSSadaf Ebrahimi }
1101*f5c631daSSadaf Ebrahimi
VisitPCRelAddressing(const Instruction * instr)1102*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitPCRelAddressing(const Instruction* instr) {
1103*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1104*f5c631daSSadaf Ebrahimi USE(instr);
1105*f5c631daSSadaf Ebrahimi }
1106*f5c631daSSadaf Ebrahimi
1107*f5c631daSSadaf Ebrahimi // Most SVE visitors require only SVE.
1108*f5c631daSSadaf Ebrahimi #define VIXL_SIMPLE_SVE_VISITOR_LIST(V) \
1109*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoad_ScalarPlus32BitUnscaledOffsets) \
1110*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoad_VectorPlusImm) \
1111*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoadHalfwords_ScalarPlus32BitScaledOffsets) \
1112*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoadWords_ScalarPlus32BitScaledOffsets) \
1113*f5c631daSSadaf Ebrahimi V(SVE32BitGatherPrefetch_ScalarPlus32BitScaledOffsets) \
1114*f5c631daSSadaf Ebrahimi V(SVE32BitGatherPrefetch_VectorPlusImm) \
1115*f5c631daSSadaf Ebrahimi V(SVE32BitScatterStore_ScalarPlus32BitScaledOffsets) \
1116*f5c631daSSadaf Ebrahimi V(SVE32BitScatterStore_ScalarPlus32BitUnscaledOffsets) \
1117*f5c631daSSadaf Ebrahimi V(SVE32BitScatterStore_VectorPlusImm) \
1118*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlus32BitUnpackedScaledOffsets) \
1119*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlus64BitScaledOffsets) \
1120*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlus64BitUnscaledOffsets) \
1121*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlusUnpacked32BitUnscaledOffsets) \
1122*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_VectorPlusImm) \
1123*f5c631daSSadaf Ebrahimi V(SVE64BitGatherPrefetch_ScalarPlus64BitScaledOffsets) \
1124*f5c631daSSadaf Ebrahimi V(SVE64BitGatherPrefetch_ScalarPlusUnpacked32BitScaledOffsets) \
1125*f5c631daSSadaf Ebrahimi V(SVE64BitGatherPrefetch_VectorPlusImm) \
1126*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlus64BitScaledOffsets) \
1127*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlus64BitUnscaledOffsets) \
1128*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlusUnpacked32BitScaledOffsets) \
1129*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlusUnpacked32BitUnscaledOffsets) \
1130*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_VectorPlusImm) \
1131*f5c631daSSadaf Ebrahimi V(SVEAddressGeneration) \
1132*f5c631daSSadaf Ebrahimi V(SVEBitwiseLogicalUnpredicated) \
1133*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftUnpredicated) \
1134*f5c631daSSadaf Ebrahimi V(SVEFFRInitialise) \
1135*f5c631daSSadaf Ebrahimi V(SVEFFRWriteFromPredicate) \
1136*f5c631daSSadaf Ebrahimi V(SVEFPAccumulatingReduction) \
1137*f5c631daSSadaf Ebrahimi V(SVEFPArithmeticUnpredicated) \
1138*f5c631daSSadaf Ebrahimi V(SVEFPCompareVectors) \
1139*f5c631daSSadaf Ebrahimi V(SVEFPCompareWithZero) \
1140*f5c631daSSadaf Ebrahimi V(SVEFPComplexAddition) \
1141*f5c631daSSadaf Ebrahimi V(SVEFPComplexMulAdd) \
1142*f5c631daSSadaf Ebrahimi V(SVEFPComplexMulAddIndex) \
1143*f5c631daSSadaf Ebrahimi V(SVEFPFastReduction) \
1144*f5c631daSSadaf Ebrahimi V(SVEFPMulIndex) \
1145*f5c631daSSadaf Ebrahimi V(SVEFPMulAdd) \
1146*f5c631daSSadaf Ebrahimi V(SVEFPMulAddIndex) \
1147*f5c631daSSadaf Ebrahimi V(SVEFPUnaryOpUnpredicated) \
1148*f5c631daSSadaf Ebrahimi V(SVEIncDecByPredicateCount) \
1149*f5c631daSSadaf Ebrahimi V(SVEIndexGeneration) \
1150*f5c631daSSadaf Ebrahimi V(SVEIntArithmeticUnpredicated) \
1151*f5c631daSSadaf Ebrahimi V(SVEIntCompareSignedImm) \
1152*f5c631daSSadaf Ebrahimi V(SVEIntCompareUnsignedImm) \
1153*f5c631daSSadaf Ebrahimi V(SVEIntCompareVectors) \
1154*f5c631daSSadaf Ebrahimi V(SVEIntMulAddPredicated) \
1155*f5c631daSSadaf Ebrahimi V(SVEIntMulAddUnpredicated) \
1156*f5c631daSSadaf Ebrahimi V(SVEIntReduction) \
1157*f5c631daSSadaf Ebrahimi V(SVEIntUnaryArithmeticPredicated) \
1158*f5c631daSSadaf Ebrahimi V(SVEMovprfx) \
1159*f5c631daSSadaf Ebrahimi V(SVEMulIndex) \
1160*f5c631daSSadaf Ebrahimi V(SVEPermuteVectorExtract) \
1161*f5c631daSSadaf Ebrahimi V(SVEPermuteVectorInterleaving) \
1162*f5c631daSSadaf Ebrahimi V(SVEPredicateCount) \
1163*f5c631daSSadaf Ebrahimi V(SVEPredicateLogical) \
1164*f5c631daSSadaf Ebrahimi V(SVEPropagateBreak) \
1165*f5c631daSSadaf Ebrahimi V(SVEStackFrameAdjustment) \
1166*f5c631daSSadaf Ebrahimi V(SVEStackFrameSize) \
1167*f5c631daSSadaf Ebrahimi V(SVEVectorSelect) \
1168*f5c631daSSadaf Ebrahimi V(SVEBitwiseLogical_Predicated) \
1169*f5c631daSSadaf Ebrahimi V(SVEBitwiseLogicalWithImm_Unpredicated) \
1170*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftByImm_Predicated) \
1171*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftByVector_Predicated) \
1172*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftByWideElements_Predicated) \
1173*f5c631daSSadaf Ebrahimi V(SVEBroadcastBitmaskImm) \
1174*f5c631daSSadaf Ebrahimi V(SVEBroadcastFPImm_Unpredicated) \
1175*f5c631daSSadaf Ebrahimi V(SVEBroadcastGeneralRegister) \
1176*f5c631daSSadaf Ebrahimi V(SVEBroadcastIndexElement) \
1177*f5c631daSSadaf Ebrahimi V(SVEBroadcastIntImm_Unpredicated) \
1178*f5c631daSSadaf Ebrahimi V(SVECompressActiveElements) \
1179*f5c631daSSadaf Ebrahimi V(SVEConditionallyBroadcastElementToVector) \
1180*f5c631daSSadaf Ebrahimi V(SVEConditionallyExtractElementToSIMDFPScalar) \
1181*f5c631daSSadaf Ebrahimi V(SVEConditionallyExtractElementToGeneralRegister) \
1182*f5c631daSSadaf Ebrahimi V(SVEConditionallyTerminateScalars) \
1183*f5c631daSSadaf Ebrahimi V(SVEConstructivePrefix_Unpredicated) \
1184*f5c631daSSadaf Ebrahimi V(SVEContiguousFirstFaultLoad_ScalarPlusScalar) \
1185*f5c631daSSadaf Ebrahimi V(SVEContiguousLoad_ScalarPlusImm) \
1186*f5c631daSSadaf Ebrahimi V(SVEContiguousLoad_ScalarPlusScalar) \
1187*f5c631daSSadaf Ebrahimi V(SVEContiguousNonFaultLoad_ScalarPlusImm) \
1188*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalLoad_ScalarPlusImm) \
1189*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalLoad_ScalarPlusScalar) \
1190*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalStore_ScalarPlusImm) \
1191*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalStore_ScalarPlusScalar) \
1192*f5c631daSSadaf Ebrahimi V(SVEContiguousPrefetch_ScalarPlusImm) \
1193*f5c631daSSadaf Ebrahimi V(SVEContiguousPrefetch_ScalarPlusScalar) \
1194*f5c631daSSadaf Ebrahimi V(SVEContiguousStore_ScalarPlusImm) \
1195*f5c631daSSadaf Ebrahimi V(SVEContiguousStore_ScalarPlusScalar) \
1196*f5c631daSSadaf Ebrahimi V(SVECopySIMDFPScalarRegisterToVector_Predicated) \
1197*f5c631daSSadaf Ebrahimi V(SVECopyFPImm_Predicated) \
1198*f5c631daSSadaf Ebrahimi V(SVECopyGeneralRegisterToVector_Predicated) \
1199*f5c631daSSadaf Ebrahimi V(SVECopyIntImm_Predicated) \
1200*f5c631daSSadaf Ebrahimi V(SVEElementCount) \
1201*f5c631daSSadaf Ebrahimi V(SVEExtractElementToSIMDFPScalarRegister) \
1202*f5c631daSSadaf Ebrahimi V(SVEExtractElementToGeneralRegister) \
1203*f5c631daSSadaf Ebrahimi V(SVEFPArithmetic_Predicated) \
1204*f5c631daSSadaf Ebrahimi V(SVEFPArithmeticWithImm_Predicated) \
1205*f5c631daSSadaf Ebrahimi V(SVEFPConvertPrecision) \
1206*f5c631daSSadaf Ebrahimi V(SVEFPConvertToInt) \
1207*f5c631daSSadaf Ebrahimi V(SVEFPExponentialAccelerator) \
1208*f5c631daSSadaf Ebrahimi V(SVEFPRoundToIntegralValue) \
1209*f5c631daSSadaf Ebrahimi V(SVEFPTrigMulAddCoefficient) \
1210*f5c631daSSadaf Ebrahimi V(SVEFPTrigSelectCoefficient) \
1211*f5c631daSSadaf Ebrahimi V(SVEFPUnaryOp) \
1212*f5c631daSSadaf Ebrahimi V(SVEIncDecRegisterByElementCount) \
1213*f5c631daSSadaf Ebrahimi V(SVEIncDecVectorByElementCount) \
1214*f5c631daSSadaf Ebrahimi V(SVEInsertSIMDFPScalarRegister) \
1215*f5c631daSSadaf Ebrahimi V(SVEInsertGeneralRegister) \
1216*f5c631daSSadaf Ebrahimi V(SVEIntAddSubtractImm_Unpredicated) \
1217*f5c631daSSadaf Ebrahimi V(SVEIntAddSubtractVectors_Predicated) \
1218*f5c631daSSadaf Ebrahimi V(SVEIntCompareScalarCountAndLimit) \
1219*f5c631daSSadaf Ebrahimi V(SVEIntConvertToFP) \
1220*f5c631daSSadaf Ebrahimi V(SVEIntDivideVectors_Predicated) \
1221*f5c631daSSadaf Ebrahimi V(SVEIntMinMaxImm_Unpredicated) \
1222*f5c631daSSadaf Ebrahimi V(SVEIntMinMaxDifference_Predicated) \
1223*f5c631daSSadaf Ebrahimi V(SVEIntMulImm_Unpredicated) \
1224*f5c631daSSadaf Ebrahimi V(SVEIntMulVectors_Predicated) \
1225*f5c631daSSadaf Ebrahimi V(SVELoadAndBroadcastElement) \
1226*f5c631daSSadaf Ebrahimi V(SVELoadAndBroadcastQOWord_ScalarPlusImm) \
1227*f5c631daSSadaf Ebrahimi V(SVELoadAndBroadcastQOWord_ScalarPlusScalar) \
1228*f5c631daSSadaf Ebrahimi V(SVELoadMultipleStructures_ScalarPlusImm) \
1229*f5c631daSSadaf Ebrahimi V(SVELoadMultipleStructures_ScalarPlusScalar) \
1230*f5c631daSSadaf Ebrahimi V(SVELoadPredicateRegister) \
1231*f5c631daSSadaf Ebrahimi V(SVELoadVectorRegister) \
1232*f5c631daSSadaf Ebrahimi V(SVEPartitionBreakCondition) \
1233*f5c631daSSadaf Ebrahimi V(SVEPermutePredicateElements) \
1234*f5c631daSSadaf Ebrahimi V(SVEPredicateFirstActive) \
1235*f5c631daSSadaf Ebrahimi V(SVEPredicateInitialize) \
1236*f5c631daSSadaf Ebrahimi V(SVEPredicateNextActive) \
1237*f5c631daSSadaf Ebrahimi V(SVEPredicateReadFromFFR_Predicated) \
1238*f5c631daSSadaf Ebrahimi V(SVEPredicateReadFromFFR_Unpredicated) \
1239*f5c631daSSadaf Ebrahimi V(SVEPredicateTest) \
1240*f5c631daSSadaf Ebrahimi V(SVEPredicateZero) \
1241*f5c631daSSadaf Ebrahimi V(SVEPropagateBreakToNextPartition) \
1242*f5c631daSSadaf Ebrahimi V(SVEReversePredicateElements) \
1243*f5c631daSSadaf Ebrahimi V(SVEReverseVectorElements) \
1244*f5c631daSSadaf Ebrahimi V(SVEReverseWithinElements) \
1245*f5c631daSSadaf Ebrahimi V(SVESaturatingIncDecRegisterByElementCount) \
1246*f5c631daSSadaf Ebrahimi V(SVESaturatingIncDecVectorByElementCount) \
1247*f5c631daSSadaf Ebrahimi V(SVEStoreMultipleStructures_ScalarPlusImm) \
1248*f5c631daSSadaf Ebrahimi V(SVEStoreMultipleStructures_ScalarPlusScalar) \
1249*f5c631daSSadaf Ebrahimi V(SVEStorePredicateRegister) \
1250*f5c631daSSadaf Ebrahimi V(SVEStoreVectorRegister) \
1251*f5c631daSSadaf Ebrahimi V(SVETableLookup) \
1252*f5c631daSSadaf Ebrahimi V(SVEUnpackPredicateElements) \
1253*f5c631daSSadaf Ebrahimi V(SVEUnpackVectorElements) \
1254*f5c631daSSadaf Ebrahimi V(SVEVectorSplice)
1255*f5c631daSSadaf Ebrahimi
1256*f5c631daSSadaf Ebrahimi #define VIXL_DEFINE_SIMPLE_SVE_VISITOR(NAME) \
1257*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::Visit##NAME(const Instruction* instr) { \
1258*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this); \
1259*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kSVE); \
1260*f5c631daSSadaf Ebrahimi USE(instr); \
1261*f5c631daSSadaf Ebrahimi }
VIXL_SIMPLE_SVE_VISITOR_LIST(VIXL_DEFINE_SIMPLE_SVE_VISITOR)1262*f5c631daSSadaf Ebrahimi VIXL_SIMPLE_SVE_VISITOR_LIST(VIXL_DEFINE_SIMPLE_SVE_VISITOR)
1263*f5c631daSSadaf Ebrahimi #undef VIXL_DEFINE_SIMPLE_SVE_VISITOR
1264*f5c631daSSadaf Ebrahimi #undef VIXL_SIMPLE_SVE_VISITOR_LIST
1265*f5c631daSSadaf Ebrahimi
1266*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitSystem(const Instruction* instr) {
1267*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1268*f5c631daSSadaf Ebrahimi if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
1269*f5c631daSSadaf Ebrahimi CPUFeatures required;
1270*f5c631daSSadaf Ebrahimi switch (instr->GetInstructionBits()) {
1271*f5c631daSSadaf Ebrahimi case PACIA1716:
1272*f5c631daSSadaf Ebrahimi case PACIB1716:
1273*f5c631daSSadaf Ebrahimi case AUTIA1716:
1274*f5c631daSSadaf Ebrahimi case AUTIB1716:
1275*f5c631daSSadaf Ebrahimi case PACIAZ:
1276*f5c631daSSadaf Ebrahimi case PACIASP:
1277*f5c631daSSadaf Ebrahimi case PACIBZ:
1278*f5c631daSSadaf Ebrahimi case PACIBSP:
1279*f5c631daSSadaf Ebrahimi case AUTIAZ:
1280*f5c631daSSadaf Ebrahimi case AUTIASP:
1281*f5c631daSSadaf Ebrahimi case AUTIBZ:
1282*f5c631daSSadaf Ebrahimi case AUTIBSP:
1283*f5c631daSSadaf Ebrahimi case XPACLRI:
1284*f5c631daSSadaf Ebrahimi required.Combine(CPUFeatures::kPAuth);
1285*f5c631daSSadaf Ebrahimi break;
1286*f5c631daSSadaf Ebrahimi default:
1287*f5c631daSSadaf Ebrahimi switch (instr->GetImmHint()) {
1288*f5c631daSSadaf Ebrahimi case ESB:
1289*f5c631daSSadaf Ebrahimi required.Combine(CPUFeatures::kRAS);
1290*f5c631daSSadaf Ebrahimi break;
1291*f5c631daSSadaf Ebrahimi case BTI:
1292*f5c631daSSadaf Ebrahimi case BTI_j:
1293*f5c631daSSadaf Ebrahimi case BTI_c:
1294*f5c631daSSadaf Ebrahimi case BTI_jc:
1295*f5c631daSSadaf Ebrahimi required.Combine(CPUFeatures::kBTI);
1296*f5c631daSSadaf Ebrahimi break;
1297*f5c631daSSadaf Ebrahimi default:
1298*f5c631daSSadaf Ebrahimi break;
1299*f5c631daSSadaf Ebrahimi }
1300*f5c631daSSadaf Ebrahimi break;
1301*f5c631daSSadaf Ebrahimi }
1302*f5c631daSSadaf Ebrahimi
1303*f5c631daSSadaf Ebrahimi // These are all HINT instructions, and behave as NOPs if the corresponding
1304*f5c631daSSadaf Ebrahimi // features are not implemented, so we record the corresponding features
1305*f5c631daSSadaf Ebrahimi // only if they are available.
1306*f5c631daSSadaf Ebrahimi if (available_.Has(required)) scope.Record(required);
1307*f5c631daSSadaf Ebrahimi } else if (instr->Mask(SystemSysMask) == SYS) {
1308*f5c631daSSadaf Ebrahimi switch (instr->GetSysOp()) {
1309*f5c631daSSadaf Ebrahimi // DC instruction variants.
1310*f5c631daSSadaf Ebrahimi case CVAP:
1311*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kDCPoP);
1312*f5c631daSSadaf Ebrahimi break;
1313*f5c631daSSadaf Ebrahimi case CVADP:
1314*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kDCCVADP);
1315*f5c631daSSadaf Ebrahimi break;
1316*f5c631daSSadaf Ebrahimi case IVAU:
1317*f5c631daSSadaf Ebrahimi case CVAC:
1318*f5c631daSSadaf Ebrahimi case CVAU:
1319*f5c631daSSadaf Ebrahimi case CIVAC:
1320*f5c631daSSadaf Ebrahimi // No special CPU features.
1321*f5c631daSSadaf Ebrahimi break;
1322*f5c631daSSadaf Ebrahimi }
1323*f5c631daSSadaf Ebrahimi } else if (instr->Mask(SystemPStateFMask) == SystemPStateFixed) {
1324*f5c631daSSadaf Ebrahimi switch (instr->Mask(SystemPStateMask)) {
1325*f5c631daSSadaf Ebrahimi case CFINV:
1326*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kFlagM);
1327*f5c631daSSadaf Ebrahimi break;
1328*f5c631daSSadaf Ebrahimi case AXFLAG:
1329*f5c631daSSadaf Ebrahimi case XAFLAG:
1330*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kAXFlag);
1331*f5c631daSSadaf Ebrahimi break;
1332*f5c631daSSadaf Ebrahimi }
1333*f5c631daSSadaf Ebrahimi } else if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) {
1334*f5c631daSSadaf Ebrahimi if (instr->Mask(SystemSysRegMask) == MRS) {
1335*f5c631daSSadaf Ebrahimi switch (instr->GetImmSystemRegister()) {
1336*f5c631daSSadaf Ebrahimi case RNDR:
1337*f5c631daSSadaf Ebrahimi case RNDRRS:
1338*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kRNG);
1339*f5c631daSSadaf Ebrahimi break;
1340*f5c631daSSadaf Ebrahimi }
1341*f5c631daSSadaf Ebrahimi }
1342*f5c631daSSadaf Ebrahimi }
1343*f5c631daSSadaf Ebrahimi }
1344*f5c631daSSadaf Ebrahimi
VisitTestBranch(const Instruction * instr)1345*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitTestBranch(const Instruction* instr) {
1346*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1347*f5c631daSSadaf Ebrahimi USE(instr);
1348*f5c631daSSadaf Ebrahimi }
1349*f5c631daSSadaf Ebrahimi
VisitUnallocated(const Instruction * instr)1350*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitUnallocated(const Instruction* instr) {
1351*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1352*f5c631daSSadaf Ebrahimi USE(instr);
1353*f5c631daSSadaf Ebrahimi }
1354*f5c631daSSadaf Ebrahimi
VisitUnconditionalBranch(const Instruction * instr)1355*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitUnconditionalBranch(const Instruction* instr) {
1356*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1357*f5c631daSSadaf Ebrahimi USE(instr);
1358*f5c631daSSadaf Ebrahimi }
1359*f5c631daSSadaf Ebrahimi
VisitUnconditionalBranchToRegister(const Instruction * instr)1360*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitUnconditionalBranchToRegister(
1361*f5c631daSSadaf Ebrahimi const Instruction* instr) {
1362*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1363*f5c631daSSadaf Ebrahimi switch (instr->Mask(UnconditionalBranchToRegisterMask)) {
1364*f5c631daSSadaf Ebrahimi case BRAAZ:
1365*f5c631daSSadaf Ebrahimi case BRABZ:
1366*f5c631daSSadaf Ebrahimi case BLRAAZ:
1367*f5c631daSSadaf Ebrahimi case BLRABZ:
1368*f5c631daSSadaf Ebrahimi case RETAA:
1369*f5c631daSSadaf Ebrahimi case RETAB:
1370*f5c631daSSadaf Ebrahimi case BRAA:
1371*f5c631daSSadaf Ebrahimi case BRAB:
1372*f5c631daSSadaf Ebrahimi case BLRAA:
1373*f5c631daSSadaf Ebrahimi case BLRAB:
1374*f5c631daSSadaf Ebrahimi scope.Record(CPUFeatures::kPAuth);
1375*f5c631daSSadaf Ebrahimi return;
1376*f5c631daSSadaf Ebrahimi default:
1377*f5c631daSSadaf Ebrahimi // No additional features.
1378*f5c631daSSadaf Ebrahimi return;
1379*f5c631daSSadaf Ebrahimi }
1380*f5c631daSSadaf Ebrahimi }
1381*f5c631daSSadaf Ebrahimi
VisitReserved(const Instruction * instr)1382*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitReserved(const Instruction* instr) {
1383*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1384*f5c631daSSadaf Ebrahimi USE(instr);
1385*f5c631daSSadaf Ebrahimi }
1386*f5c631daSSadaf Ebrahimi
VisitUnimplemented(const Instruction * instr)1387*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::VisitUnimplemented(const Instruction* instr) {
1388*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1389*f5c631daSSadaf Ebrahimi USE(instr);
1390*f5c631daSSadaf Ebrahimi }
1391*f5c631daSSadaf Ebrahimi
Visit(Metadata * metadata,const Instruction * instr)1392*f5c631daSSadaf Ebrahimi void CPUFeaturesAuditor::Visit(Metadata* metadata, const Instruction* instr) {
1393*f5c631daSSadaf Ebrahimi VIXL_ASSERT(metadata->count("form") > 0);
1394*f5c631daSSadaf Ebrahimi const std::string& form = (*metadata)["form"];
1395*f5c631daSSadaf Ebrahimi uint32_t form_hash = Hash(form.c_str());
1396*f5c631daSSadaf Ebrahimi const FormToVisitorFnMap* fv = CPUFeaturesAuditor::GetFormToVisitorFnMap();
1397*f5c631daSSadaf Ebrahimi FormToVisitorFnMap::const_iterator it = fv->find(form_hash);
1398*f5c631daSSadaf Ebrahimi if (it == fv->end()) {
1399*f5c631daSSadaf Ebrahimi RecordInstructionFeaturesScope scope(this);
1400*f5c631daSSadaf Ebrahimi std::map<uint32_t, const CPUFeatures> features = {
1401*f5c631daSSadaf Ebrahimi {"adclb_z_zzz"_h, CPUFeatures::kSVE2},
1402*f5c631daSSadaf Ebrahimi {"adclt_z_zzz"_h, CPUFeatures::kSVE2},
1403*f5c631daSSadaf Ebrahimi {"addhnb_z_zz"_h, CPUFeatures::kSVE2},
1404*f5c631daSSadaf Ebrahimi {"addhnt_z_zz"_h, CPUFeatures::kSVE2},
1405*f5c631daSSadaf Ebrahimi {"addp_z_p_zz"_h, CPUFeatures::kSVE2},
1406*f5c631daSSadaf Ebrahimi {"bcax_z_zzz"_h, CPUFeatures::kSVE2},
1407*f5c631daSSadaf Ebrahimi {"bdep_z_zz"_h,
1408*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE2, CPUFeatures::kSVEBitPerm)},
1409*f5c631daSSadaf Ebrahimi {"bext_z_zz"_h,
1410*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE2, CPUFeatures::kSVEBitPerm)},
1411*f5c631daSSadaf Ebrahimi {"bgrp_z_zz"_h,
1412*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE2, CPUFeatures::kSVEBitPerm)},
1413*f5c631daSSadaf Ebrahimi {"bsl1n_z_zzz"_h, CPUFeatures::kSVE2},
1414*f5c631daSSadaf Ebrahimi {"bsl2n_z_zzz"_h, CPUFeatures::kSVE2},
1415*f5c631daSSadaf Ebrahimi {"bsl_z_zzz"_h, CPUFeatures::kSVE2},
1416*f5c631daSSadaf Ebrahimi {"cadd_z_zz"_h, CPUFeatures::kSVE2},
1417*f5c631daSSadaf Ebrahimi {"cdot_z_zzz"_h, CPUFeatures::kSVE2},
1418*f5c631daSSadaf Ebrahimi {"cdot_z_zzzi_d"_h, CPUFeatures::kSVE2},
1419*f5c631daSSadaf Ebrahimi {"cdot_z_zzzi_s"_h, CPUFeatures::kSVE2},
1420*f5c631daSSadaf Ebrahimi {"cmla_z_zzz"_h, CPUFeatures::kSVE2},
1421*f5c631daSSadaf Ebrahimi {"cmla_z_zzzi_h"_h, CPUFeatures::kSVE2},
1422*f5c631daSSadaf Ebrahimi {"cmla_z_zzzi_s"_h, CPUFeatures::kSVE2},
1423*f5c631daSSadaf Ebrahimi {"eor3_z_zzz"_h, CPUFeatures::kSVE2},
1424*f5c631daSSadaf Ebrahimi {"eorbt_z_zz"_h, CPUFeatures::kSVE2},
1425*f5c631daSSadaf Ebrahimi {"eortb_z_zz"_h, CPUFeatures::kSVE2},
1426*f5c631daSSadaf Ebrahimi {"ext_z_zi_con"_h, CPUFeatures::kSVE2},
1427*f5c631daSSadaf Ebrahimi {"faddp_z_p_zz"_h, CPUFeatures::kSVE2},
1428*f5c631daSSadaf Ebrahimi {"fcvtlt_z_p_z_h2s"_h, CPUFeatures::kSVE2},
1429*f5c631daSSadaf Ebrahimi {"fcvtlt_z_p_z_s2d"_h, CPUFeatures::kSVE2},
1430*f5c631daSSadaf Ebrahimi {"fcvtnt_z_p_z_d2s"_h, CPUFeatures::kSVE2},
1431*f5c631daSSadaf Ebrahimi {"fcvtnt_z_p_z_s2h"_h, CPUFeatures::kSVE2},
1432*f5c631daSSadaf Ebrahimi {"fcvtx_z_p_z_d2s"_h, CPUFeatures::kSVE2},
1433*f5c631daSSadaf Ebrahimi {"fcvtxnt_z_p_z_d2s"_h, CPUFeatures::kSVE2},
1434*f5c631daSSadaf Ebrahimi {"flogb_z_p_z"_h, CPUFeatures::kSVE2},
1435*f5c631daSSadaf Ebrahimi {"fmaxnmp_z_p_zz"_h, CPUFeatures::kSVE2},
1436*f5c631daSSadaf Ebrahimi {"fmaxp_z_p_zz"_h, CPUFeatures::kSVE2},
1437*f5c631daSSadaf Ebrahimi {"fminnmp_z_p_zz"_h, CPUFeatures::kSVE2},
1438*f5c631daSSadaf Ebrahimi {"fminp_z_p_zz"_h, CPUFeatures::kSVE2},
1439*f5c631daSSadaf Ebrahimi {"fmlalb_z_zzz"_h, CPUFeatures::kSVE2},
1440*f5c631daSSadaf Ebrahimi {"fmlalb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1441*f5c631daSSadaf Ebrahimi {"fmlalt_z_zzz"_h, CPUFeatures::kSVE2},
1442*f5c631daSSadaf Ebrahimi {"fmlalt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1443*f5c631daSSadaf Ebrahimi {"fmlslb_z_zzz"_h, CPUFeatures::kSVE2},
1444*f5c631daSSadaf Ebrahimi {"fmlslb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1445*f5c631daSSadaf Ebrahimi {"fmlslt_z_zzz"_h, CPUFeatures::kSVE2},
1446*f5c631daSSadaf Ebrahimi {"fmlslt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1447*f5c631daSSadaf Ebrahimi {"histcnt_z_p_zz"_h, CPUFeatures::kSVE2},
1448*f5c631daSSadaf Ebrahimi {"histseg_z_zz"_h, CPUFeatures::kSVE2},
1449*f5c631daSSadaf Ebrahimi {"ldnt1b_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1450*f5c631daSSadaf Ebrahimi {"ldnt1b_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1451*f5c631daSSadaf Ebrahimi {"ldnt1d_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1452*f5c631daSSadaf Ebrahimi {"ldnt1h_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1453*f5c631daSSadaf Ebrahimi {"ldnt1h_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1454*f5c631daSSadaf Ebrahimi {"ldnt1sb_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1455*f5c631daSSadaf Ebrahimi {"ldnt1sb_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1456*f5c631daSSadaf Ebrahimi {"ldnt1sh_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1457*f5c631daSSadaf Ebrahimi {"ldnt1sh_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1458*f5c631daSSadaf Ebrahimi {"ldnt1sw_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1459*f5c631daSSadaf Ebrahimi {"ldnt1w_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1460*f5c631daSSadaf Ebrahimi {"ldnt1w_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1461*f5c631daSSadaf Ebrahimi {"match_p_p_zz"_h, CPUFeatures::kSVE2},
1462*f5c631daSSadaf Ebrahimi {"mla_z_zzzi_d"_h, CPUFeatures::kSVE2},
1463*f5c631daSSadaf Ebrahimi {"mla_z_zzzi_h"_h, CPUFeatures::kSVE2},
1464*f5c631daSSadaf Ebrahimi {"mla_z_zzzi_s"_h, CPUFeatures::kSVE2},
1465*f5c631daSSadaf Ebrahimi {"mls_z_zzzi_d"_h, CPUFeatures::kSVE2},
1466*f5c631daSSadaf Ebrahimi {"mls_z_zzzi_h"_h, CPUFeatures::kSVE2},
1467*f5c631daSSadaf Ebrahimi {"mls_z_zzzi_s"_h, CPUFeatures::kSVE2},
1468*f5c631daSSadaf Ebrahimi {"mul_z_zz"_h, CPUFeatures::kSVE2},
1469*f5c631daSSadaf Ebrahimi {"mul_z_zzi_d"_h, CPUFeatures::kSVE2},
1470*f5c631daSSadaf Ebrahimi {"mul_z_zzi_h"_h, CPUFeatures::kSVE2},
1471*f5c631daSSadaf Ebrahimi {"mul_z_zzi_s"_h, CPUFeatures::kSVE2},
1472*f5c631daSSadaf Ebrahimi {"nbsl_z_zzz"_h, CPUFeatures::kSVE2},
1473*f5c631daSSadaf Ebrahimi {"nmatch_p_p_zz"_h, CPUFeatures::kSVE2},
1474*f5c631daSSadaf Ebrahimi {"pmul_z_zz"_h, CPUFeatures::kSVE2},
1475*f5c631daSSadaf Ebrahimi {"pmullb_z_zz"_h, CPUFeatures::kSVE2},
1476*f5c631daSSadaf Ebrahimi {"pmullt_z_zz"_h, CPUFeatures::kSVE2},
1477*f5c631daSSadaf Ebrahimi {"raddhnb_z_zz"_h, CPUFeatures::kSVE2},
1478*f5c631daSSadaf Ebrahimi {"raddhnt_z_zz"_h, CPUFeatures::kSVE2},
1479*f5c631daSSadaf Ebrahimi {"rshrnb_z_zi"_h, CPUFeatures::kSVE2},
1480*f5c631daSSadaf Ebrahimi {"rshrnt_z_zi"_h, CPUFeatures::kSVE2},
1481*f5c631daSSadaf Ebrahimi {"rsubhnb_z_zz"_h, CPUFeatures::kSVE2},
1482*f5c631daSSadaf Ebrahimi {"rsubhnt_z_zz"_h, CPUFeatures::kSVE2},
1483*f5c631daSSadaf Ebrahimi {"saba_z_zzz"_h, CPUFeatures::kSVE2},
1484*f5c631daSSadaf Ebrahimi {"sabalb_z_zzz"_h, CPUFeatures::kSVE2},
1485*f5c631daSSadaf Ebrahimi {"sabalt_z_zzz"_h, CPUFeatures::kSVE2},
1486*f5c631daSSadaf Ebrahimi {"sabdlb_z_zz"_h, CPUFeatures::kSVE2},
1487*f5c631daSSadaf Ebrahimi {"sabdlt_z_zz"_h, CPUFeatures::kSVE2},
1488*f5c631daSSadaf Ebrahimi {"sadalp_z_p_z"_h, CPUFeatures::kSVE2},
1489*f5c631daSSadaf Ebrahimi {"saddlb_z_zz"_h, CPUFeatures::kSVE2},
1490*f5c631daSSadaf Ebrahimi {"saddlbt_z_zz"_h, CPUFeatures::kSVE2},
1491*f5c631daSSadaf Ebrahimi {"saddlt_z_zz"_h, CPUFeatures::kSVE2},
1492*f5c631daSSadaf Ebrahimi {"saddwb_z_zz"_h, CPUFeatures::kSVE2},
1493*f5c631daSSadaf Ebrahimi {"saddwt_z_zz"_h, CPUFeatures::kSVE2},
1494*f5c631daSSadaf Ebrahimi {"sbclb_z_zzz"_h, CPUFeatures::kSVE2},
1495*f5c631daSSadaf Ebrahimi {"sbclt_z_zzz"_h, CPUFeatures::kSVE2},
1496*f5c631daSSadaf Ebrahimi {"shadd_z_p_zz"_h, CPUFeatures::kSVE2},
1497*f5c631daSSadaf Ebrahimi {"shrnb_z_zi"_h, CPUFeatures::kSVE2},
1498*f5c631daSSadaf Ebrahimi {"shrnt_z_zi"_h, CPUFeatures::kSVE2},
1499*f5c631daSSadaf Ebrahimi {"shsub_z_p_zz"_h, CPUFeatures::kSVE2},
1500*f5c631daSSadaf Ebrahimi {"shsubr_z_p_zz"_h, CPUFeatures::kSVE2},
1501*f5c631daSSadaf Ebrahimi {"sli_z_zzi"_h, CPUFeatures::kSVE2},
1502*f5c631daSSadaf Ebrahimi {"smaxp_z_p_zz"_h, CPUFeatures::kSVE2},
1503*f5c631daSSadaf Ebrahimi {"sminp_z_p_zz"_h, CPUFeatures::kSVE2},
1504*f5c631daSSadaf Ebrahimi {"smlalb_z_zzz"_h, CPUFeatures::kSVE2},
1505*f5c631daSSadaf Ebrahimi {"smlalb_z_zzzi_d"_h, CPUFeatures::kSVE2},
1506*f5c631daSSadaf Ebrahimi {"smlalb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1507*f5c631daSSadaf Ebrahimi {"smlalt_z_zzz"_h, CPUFeatures::kSVE2},
1508*f5c631daSSadaf Ebrahimi {"smlalt_z_zzzi_d"_h, CPUFeatures::kSVE2},
1509*f5c631daSSadaf Ebrahimi {"smlalt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1510*f5c631daSSadaf Ebrahimi {"smlslb_z_zzz"_h, CPUFeatures::kSVE2},
1511*f5c631daSSadaf Ebrahimi {"smlslb_z_zzzi_d"_h, CPUFeatures::kSVE2},
1512*f5c631daSSadaf Ebrahimi {"smlslb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1513*f5c631daSSadaf Ebrahimi {"smlslt_z_zzz"_h, CPUFeatures::kSVE2},
1514*f5c631daSSadaf Ebrahimi {"smlslt_z_zzzi_d"_h, CPUFeatures::kSVE2},
1515*f5c631daSSadaf Ebrahimi {"smlslt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1516*f5c631daSSadaf Ebrahimi {"smulh_z_zz"_h, CPUFeatures::kSVE2},
1517*f5c631daSSadaf Ebrahimi {"smullb_z_zz"_h, CPUFeatures::kSVE2},
1518*f5c631daSSadaf Ebrahimi {"smullb_z_zzi_d"_h, CPUFeatures::kSVE2},
1519*f5c631daSSadaf Ebrahimi {"smullb_z_zzi_s"_h, CPUFeatures::kSVE2},
1520*f5c631daSSadaf Ebrahimi {"smullt_z_zz"_h, CPUFeatures::kSVE2},
1521*f5c631daSSadaf Ebrahimi {"smullt_z_zzi_d"_h, CPUFeatures::kSVE2},
1522*f5c631daSSadaf Ebrahimi {"smullt_z_zzi_s"_h, CPUFeatures::kSVE2},
1523*f5c631daSSadaf Ebrahimi {"splice_z_p_zz_con"_h, CPUFeatures::kSVE2},
1524*f5c631daSSadaf Ebrahimi {"sqabs_z_p_z"_h, CPUFeatures::kSVE2},
1525*f5c631daSSadaf Ebrahimi {"sqadd_z_p_zz"_h, CPUFeatures::kSVE2},
1526*f5c631daSSadaf Ebrahimi {"sqcadd_z_zz"_h, CPUFeatures::kSVE2},
1527*f5c631daSSadaf Ebrahimi {"sqdmlalb_z_zzz"_h, CPUFeatures::kSVE2},
1528*f5c631daSSadaf Ebrahimi {"sqdmlalb_z_zzzi_d"_h, CPUFeatures::kSVE2},
1529*f5c631daSSadaf Ebrahimi {"sqdmlalb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1530*f5c631daSSadaf Ebrahimi {"sqdmlalbt_z_zzz"_h, CPUFeatures::kSVE2},
1531*f5c631daSSadaf Ebrahimi {"sqdmlalt_z_zzz"_h, CPUFeatures::kSVE2},
1532*f5c631daSSadaf Ebrahimi {"sqdmlalt_z_zzzi_d"_h, CPUFeatures::kSVE2},
1533*f5c631daSSadaf Ebrahimi {"sqdmlalt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1534*f5c631daSSadaf Ebrahimi {"sqdmlslb_z_zzz"_h, CPUFeatures::kSVE2},
1535*f5c631daSSadaf Ebrahimi {"sqdmlslb_z_zzzi_d"_h, CPUFeatures::kSVE2},
1536*f5c631daSSadaf Ebrahimi {"sqdmlslb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1537*f5c631daSSadaf Ebrahimi {"sqdmlslbt_z_zzz"_h, CPUFeatures::kSVE2},
1538*f5c631daSSadaf Ebrahimi {"sqdmlslt_z_zzz"_h, CPUFeatures::kSVE2},
1539*f5c631daSSadaf Ebrahimi {"sqdmlslt_z_zzzi_d"_h, CPUFeatures::kSVE2},
1540*f5c631daSSadaf Ebrahimi {"sqdmlslt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1541*f5c631daSSadaf Ebrahimi {"sqdmulh_z_zz"_h, CPUFeatures::kSVE2},
1542*f5c631daSSadaf Ebrahimi {"sqdmulh_z_zzi_d"_h, CPUFeatures::kSVE2},
1543*f5c631daSSadaf Ebrahimi {"sqdmulh_z_zzi_h"_h, CPUFeatures::kSVE2},
1544*f5c631daSSadaf Ebrahimi {"sqdmulh_z_zzi_s"_h, CPUFeatures::kSVE2},
1545*f5c631daSSadaf Ebrahimi {"sqdmullb_z_zz"_h, CPUFeatures::kSVE2},
1546*f5c631daSSadaf Ebrahimi {"sqdmullb_z_zzi_d"_h, CPUFeatures::kSVE2},
1547*f5c631daSSadaf Ebrahimi {"sqdmullb_z_zzi_s"_h, CPUFeatures::kSVE2},
1548*f5c631daSSadaf Ebrahimi {"sqdmullt_z_zz"_h, CPUFeatures::kSVE2},
1549*f5c631daSSadaf Ebrahimi {"sqdmullt_z_zzi_d"_h, CPUFeatures::kSVE2},
1550*f5c631daSSadaf Ebrahimi {"sqdmullt_z_zzi_s"_h, CPUFeatures::kSVE2},
1551*f5c631daSSadaf Ebrahimi {"sqneg_z_p_z"_h, CPUFeatures::kSVE2},
1552*f5c631daSSadaf Ebrahimi {"sqrdcmlah_z_zzz"_h, CPUFeatures::kSVE2},
1553*f5c631daSSadaf Ebrahimi {"sqrdcmlah_z_zzzi_h"_h, CPUFeatures::kSVE2},
1554*f5c631daSSadaf Ebrahimi {"sqrdcmlah_z_zzzi_s"_h, CPUFeatures::kSVE2},
1555*f5c631daSSadaf Ebrahimi {"sqrdmlah_z_zzz"_h, CPUFeatures::kSVE2},
1556*f5c631daSSadaf Ebrahimi {"sqrdmlah_z_zzzi_d"_h, CPUFeatures::kSVE2},
1557*f5c631daSSadaf Ebrahimi {"sqrdmlah_z_zzzi_h"_h, CPUFeatures::kSVE2},
1558*f5c631daSSadaf Ebrahimi {"sqrdmlah_z_zzzi_s"_h, CPUFeatures::kSVE2},
1559*f5c631daSSadaf Ebrahimi {"sqrdmlsh_z_zzz"_h, CPUFeatures::kSVE2},
1560*f5c631daSSadaf Ebrahimi {"sqrdmlsh_z_zzzi_d"_h, CPUFeatures::kSVE2},
1561*f5c631daSSadaf Ebrahimi {"sqrdmlsh_z_zzzi_h"_h, CPUFeatures::kSVE2},
1562*f5c631daSSadaf Ebrahimi {"sqrdmlsh_z_zzzi_s"_h, CPUFeatures::kSVE2},
1563*f5c631daSSadaf Ebrahimi {"sqrdmulh_z_zz"_h, CPUFeatures::kSVE2},
1564*f5c631daSSadaf Ebrahimi {"sqrdmulh_z_zzi_d"_h, CPUFeatures::kSVE2},
1565*f5c631daSSadaf Ebrahimi {"sqrdmulh_z_zzi_h"_h, CPUFeatures::kSVE2},
1566*f5c631daSSadaf Ebrahimi {"sqrdmulh_z_zzi_s"_h, CPUFeatures::kSVE2},
1567*f5c631daSSadaf Ebrahimi {"sqrshl_z_p_zz"_h, CPUFeatures::kSVE2},
1568*f5c631daSSadaf Ebrahimi {"sqrshlr_z_p_zz"_h, CPUFeatures::kSVE2},
1569*f5c631daSSadaf Ebrahimi {"sqrshrnb_z_zi"_h, CPUFeatures::kSVE2},
1570*f5c631daSSadaf Ebrahimi {"sqrshrnt_z_zi"_h, CPUFeatures::kSVE2},
1571*f5c631daSSadaf Ebrahimi {"sqrshrunb_z_zi"_h, CPUFeatures::kSVE2},
1572*f5c631daSSadaf Ebrahimi {"sqrshrunt_z_zi"_h, CPUFeatures::kSVE2},
1573*f5c631daSSadaf Ebrahimi {"sqshl_z_p_zi"_h, CPUFeatures::kSVE2},
1574*f5c631daSSadaf Ebrahimi {"sqshl_z_p_zz"_h, CPUFeatures::kSVE2},
1575*f5c631daSSadaf Ebrahimi {"sqshlr_z_p_zz"_h, CPUFeatures::kSVE2},
1576*f5c631daSSadaf Ebrahimi {"sqshlu_z_p_zi"_h, CPUFeatures::kSVE2},
1577*f5c631daSSadaf Ebrahimi {"sqshrnb_z_zi"_h, CPUFeatures::kSVE2},
1578*f5c631daSSadaf Ebrahimi {"sqshrnt_z_zi"_h, CPUFeatures::kSVE2},
1579*f5c631daSSadaf Ebrahimi {"sqshrunb_z_zi"_h, CPUFeatures::kSVE2},
1580*f5c631daSSadaf Ebrahimi {"sqshrunt_z_zi"_h, CPUFeatures::kSVE2},
1581*f5c631daSSadaf Ebrahimi {"sqsub_z_p_zz"_h, CPUFeatures::kSVE2},
1582*f5c631daSSadaf Ebrahimi {"sqsubr_z_p_zz"_h, CPUFeatures::kSVE2},
1583*f5c631daSSadaf Ebrahimi {"sqxtnb_z_zz"_h, CPUFeatures::kSVE2},
1584*f5c631daSSadaf Ebrahimi {"sqxtnt_z_zz"_h, CPUFeatures::kSVE2},
1585*f5c631daSSadaf Ebrahimi {"sqxtunb_z_zz"_h, CPUFeatures::kSVE2},
1586*f5c631daSSadaf Ebrahimi {"sqxtunt_z_zz"_h, CPUFeatures::kSVE2},
1587*f5c631daSSadaf Ebrahimi {"srhadd_z_p_zz"_h, CPUFeatures::kSVE2},
1588*f5c631daSSadaf Ebrahimi {"sri_z_zzi"_h, CPUFeatures::kSVE2},
1589*f5c631daSSadaf Ebrahimi {"srshl_z_p_zz"_h, CPUFeatures::kSVE2},
1590*f5c631daSSadaf Ebrahimi {"srshlr_z_p_zz"_h, CPUFeatures::kSVE2},
1591*f5c631daSSadaf Ebrahimi {"srshr_z_p_zi"_h, CPUFeatures::kSVE2},
1592*f5c631daSSadaf Ebrahimi {"srsra_z_zi"_h, CPUFeatures::kSVE2},
1593*f5c631daSSadaf Ebrahimi {"sshllb_z_zi"_h, CPUFeatures::kSVE2},
1594*f5c631daSSadaf Ebrahimi {"sshllt_z_zi"_h, CPUFeatures::kSVE2},
1595*f5c631daSSadaf Ebrahimi {"ssra_z_zi"_h, CPUFeatures::kSVE2},
1596*f5c631daSSadaf Ebrahimi {"ssublb_z_zz"_h, CPUFeatures::kSVE2},
1597*f5c631daSSadaf Ebrahimi {"ssublbt_z_zz"_h, CPUFeatures::kSVE2},
1598*f5c631daSSadaf Ebrahimi {"ssublt_z_zz"_h, CPUFeatures::kSVE2},
1599*f5c631daSSadaf Ebrahimi {"ssubltb_z_zz"_h, CPUFeatures::kSVE2},
1600*f5c631daSSadaf Ebrahimi {"ssubwb_z_zz"_h, CPUFeatures::kSVE2},
1601*f5c631daSSadaf Ebrahimi {"ssubwt_z_zz"_h, CPUFeatures::kSVE2},
1602*f5c631daSSadaf Ebrahimi {"stnt1b_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1603*f5c631daSSadaf Ebrahimi {"stnt1b_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1604*f5c631daSSadaf Ebrahimi {"stnt1d_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1605*f5c631daSSadaf Ebrahimi {"stnt1h_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1606*f5c631daSSadaf Ebrahimi {"stnt1h_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1607*f5c631daSSadaf Ebrahimi {"stnt1w_z_p_ar_d_64_unscaled"_h, CPUFeatures::kSVE2},
1608*f5c631daSSadaf Ebrahimi {"stnt1w_z_p_ar_s_x32_unscaled"_h, CPUFeatures::kSVE2},
1609*f5c631daSSadaf Ebrahimi {"subhnb_z_zz"_h, CPUFeatures::kSVE2},
1610*f5c631daSSadaf Ebrahimi {"subhnt_z_zz"_h, CPUFeatures::kSVE2},
1611*f5c631daSSadaf Ebrahimi {"suqadd_z_p_zz"_h, CPUFeatures::kSVE2},
1612*f5c631daSSadaf Ebrahimi {"tbl_z_zz_2"_h, CPUFeatures::kSVE2},
1613*f5c631daSSadaf Ebrahimi {"tbx_z_zz"_h, CPUFeatures::kSVE2},
1614*f5c631daSSadaf Ebrahimi {"uaba_z_zzz"_h, CPUFeatures::kSVE2},
1615*f5c631daSSadaf Ebrahimi {"uabalb_z_zzz"_h, CPUFeatures::kSVE2},
1616*f5c631daSSadaf Ebrahimi {"uabalt_z_zzz"_h, CPUFeatures::kSVE2},
1617*f5c631daSSadaf Ebrahimi {"uabdlb_z_zz"_h, CPUFeatures::kSVE2},
1618*f5c631daSSadaf Ebrahimi {"uabdlt_z_zz"_h, CPUFeatures::kSVE2},
1619*f5c631daSSadaf Ebrahimi {"uadalp_z_p_z"_h, CPUFeatures::kSVE2},
1620*f5c631daSSadaf Ebrahimi {"uaddlb_z_zz"_h, CPUFeatures::kSVE2},
1621*f5c631daSSadaf Ebrahimi {"uaddlt_z_zz"_h, CPUFeatures::kSVE2},
1622*f5c631daSSadaf Ebrahimi {"uaddwb_z_zz"_h, CPUFeatures::kSVE2},
1623*f5c631daSSadaf Ebrahimi {"uaddwt_z_zz"_h, CPUFeatures::kSVE2},
1624*f5c631daSSadaf Ebrahimi {"uhadd_z_p_zz"_h, CPUFeatures::kSVE2},
1625*f5c631daSSadaf Ebrahimi {"uhsub_z_p_zz"_h, CPUFeatures::kSVE2},
1626*f5c631daSSadaf Ebrahimi {"uhsubr_z_p_zz"_h, CPUFeatures::kSVE2},
1627*f5c631daSSadaf Ebrahimi {"umaxp_z_p_zz"_h, CPUFeatures::kSVE2},
1628*f5c631daSSadaf Ebrahimi {"uminp_z_p_zz"_h, CPUFeatures::kSVE2},
1629*f5c631daSSadaf Ebrahimi {"umlalb_z_zzz"_h, CPUFeatures::kSVE2},
1630*f5c631daSSadaf Ebrahimi {"umlalb_z_zzzi_d"_h, CPUFeatures::kSVE2},
1631*f5c631daSSadaf Ebrahimi {"umlalb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1632*f5c631daSSadaf Ebrahimi {"umlalt_z_zzz"_h, CPUFeatures::kSVE2},
1633*f5c631daSSadaf Ebrahimi {"umlalt_z_zzzi_d"_h, CPUFeatures::kSVE2},
1634*f5c631daSSadaf Ebrahimi {"umlalt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1635*f5c631daSSadaf Ebrahimi {"umlslb_z_zzz"_h, CPUFeatures::kSVE2},
1636*f5c631daSSadaf Ebrahimi {"umlslb_z_zzzi_d"_h, CPUFeatures::kSVE2},
1637*f5c631daSSadaf Ebrahimi {"umlslb_z_zzzi_s"_h, CPUFeatures::kSVE2},
1638*f5c631daSSadaf Ebrahimi {"umlslt_z_zzz"_h, CPUFeatures::kSVE2},
1639*f5c631daSSadaf Ebrahimi {"umlslt_z_zzzi_d"_h, CPUFeatures::kSVE2},
1640*f5c631daSSadaf Ebrahimi {"umlslt_z_zzzi_s"_h, CPUFeatures::kSVE2},
1641*f5c631daSSadaf Ebrahimi {"umulh_z_zz"_h, CPUFeatures::kSVE2},
1642*f5c631daSSadaf Ebrahimi {"umullb_z_zz"_h, CPUFeatures::kSVE2},
1643*f5c631daSSadaf Ebrahimi {"umullb_z_zzi_d"_h, CPUFeatures::kSVE2},
1644*f5c631daSSadaf Ebrahimi {"umullb_z_zzi_s"_h, CPUFeatures::kSVE2},
1645*f5c631daSSadaf Ebrahimi {"umullt_z_zz"_h, CPUFeatures::kSVE2},
1646*f5c631daSSadaf Ebrahimi {"umullt_z_zzi_d"_h, CPUFeatures::kSVE2},
1647*f5c631daSSadaf Ebrahimi {"umullt_z_zzi_s"_h, CPUFeatures::kSVE2},
1648*f5c631daSSadaf Ebrahimi {"uqadd_z_p_zz"_h, CPUFeatures::kSVE2},
1649*f5c631daSSadaf Ebrahimi {"uqrshl_z_p_zz"_h, CPUFeatures::kSVE2},
1650*f5c631daSSadaf Ebrahimi {"uqrshlr_z_p_zz"_h, CPUFeatures::kSVE2},
1651*f5c631daSSadaf Ebrahimi {"uqrshrnb_z_zi"_h, CPUFeatures::kSVE2},
1652*f5c631daSSadaf Ebrahimi {"uqrshrnt_z_zi"_h, CPUFeatures::kSVE2},
1653*f5c631daSSadaf Ebrahimi {"uqshl_z_p_zi"_h, CPUFeatures::kSVE2},
1654*f5c631daSSadaf Ebrahimi {"uqshl_z_p_zz"_h, CPUFeatures::kSVE2},
1655*f5c631daSSadaf Ebrahimi {"uqshlr_z_p_zz"_h, CPUFeatures::kSVE2},
1656*f5c631daSSadaf Ebrahimi {"uqshrnb_z_zi"_h, CPUFeatures::kSVE2},
1657*f5c631daSSadaf Ebrahimi {"uqshrnt_z_zi"_h, CPUFeatures::kSVE2},
1658*f5c631daSSadaf Ebrahimi {"uqsub_z_p_zz"_h, CPUFeatures::kSVE2},
1659*f5c631daSSadaf Ebrahimi {"uqsubr_z_p_zz"_h, CPUFeatures::kSVE2},
1660*f5c631daSSadaf Ebrahimi {"uqxtnb_z_zz"_h, CPUFeatures::kSVE2},
1661*f5c631daSSadaf Ebrahimi {"uqxtnt_z_zz"_h, CPUFeatures::kSVE2},
1662*f5c631daSSadaf Ebrahimi {"urecpe_z_p_z"_h, CPUFeatures::kSVE2},
1663*f5c631daSSadaf Ebrahimi {"urhadd_z_p_zz"_h, CPUFeatures::kSVE2},
1664*f5c631daSSadaf Ebrahimi {"urshl_z_p_zz"_h, CPUFeatures::kSVE2},
1665*f5c631daSSadaf Ebrahimi {"urshlr_z_p_zz"_h, CPUFeatures::kSVE2},
1666*f5c631daSSadaf Ebrahimi {"urshr_z_p_zi"_h, CPUFeatures::kSVE2},
1667*f5c631daSSadaf Ebrahimi {"ursqrte_z_p_z"_h, CPUFeatures::kSVE2},
1668*f5c631daSSadaf Ebrahimi {"ursra_z_zi"_h, CPUFeatures::kSVE2},
1669*f5c631daSSadaf Ebrahimi {"ushllb_z_zi"_h, CPUFeatures::kSVE2},
1670*f5c631daSSadaf Ebrahimi {"ushllt_z_zi"_h, CPUFeatures::kSVE2},
1671*f5c631daSSadaf Ebrahimi {"usqadd_z_p_zz"_h, CPUFeatures::kSVE2},
1672*f5c631daSSadaf Ebrahimi {"usra_z_zi"_h, CPUFeatures::kSVE2},
1673*f5c631daSSadaf Ebrahimi {"usublb_z_zz"_h, CPUFeatures::kSVE2},
1674*f5c631daSSadaf Ebrahimi {"usublt_z_zz"_h, CPUFeatures::kSVE2},
1675*f5c631daSSadaf Ebrahimi {"usubwb_z_zz"_h, CPUFeatures::kSVE2},
1676*f5c631daSSadaf Ebrahimi {"usubwt_z_zz"_h, CPUFeatures::kSVE2},
1677*f5c631daSSadaf Ebrahimi {"whilege_p_p_rr"_h, CPUFeatures::kSVE2},
1678*f5c631daSSadaf Ebrahimi {"whilegt_p_p_rr"_h, CPUFeatures::kSVE2},
1679*f5c631daSSadaf Ebrahimi {"whilehi_p_p_rr"_h, CPUFeatures::kSVE2},
1680*f5c631daSSadaf Ebrahimi {"whilehs_p_p_rr"_h, CPUFeatures::kSVE2},
1681*f5c631daSSadaf Ebrahimi {"whilerw_p_rr"_h, CPUFeatures::kSVE2},
1682*f5c631daSSadaf Ebrahimi {"whilewr_p_rr"_h, CPUFeatures::kSVE2},
1683*f5c631daSSadaf Ebrahimi {"xar_z_zzi"_h, CPUFeatures::kSVE2},
1684*f5c631daSSadaf Ebrahimi {"smmla_z_zzz"_h,
1685*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEI8MM)},
1686*f5c631daSSadaf Ebrahimi {"ummla_z_zzz"_h,
1687*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEI8MM)},
1688*f5c631daSSadaf Ebrahimi {"usmmla_z_zzz"_h,
1689*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEI8MM)},
1690*f5c631daSSadaf Ebrahimi {"fmmla_z_zzz_s"_h,
1691*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF32MM)},
1692*f5c631daSSadaf Ebrahimi {"fmmla_z_zzz_d"_h,
1693*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1694*f5c631daSSadaf Ebrahimi {"smmla_asimdsame2_g"_h,
1695*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kI8MM)},
1696*f5c631daSSadaf Ebrahimi {"ummla_asimdsame2_g"_h,
1697*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kI8MM)},
1698*f5c631daSSadaf Ebrahimi {"usmmla_asimdsame2_g"_h,
1699*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kI8MM)},
1700*f5c631daSSadaf Ebrahimi {"ld1row_z_p_bi_u32"_h,
1701*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1702*f5c631daSSadaf Ebrahimi {"ld1row_z_p_br_contiguous"_h,
1703*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1704*f5c631daSSadaf Ebrahimi {"ld1rod_z_p_bi_u64"_h,
1705*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1706*f5c631daSSadaf Ebrahimi {"ld1rod_z_p_br_contiguous"_h,
1707*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1708*f5c631daSSadaf Ebrahimi {"ld1rob_z_p_bi_u8"_h,
1709*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1710*f5c631daSSadaf Ebrahimi {"ld1rob_z_p_br_contiguous"_h,
1711*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1712*f5c631daSSadaf Ebrahimi {"ld1roh_z_p_bi_u16"_h,
1713*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1714*f5c631daSSadaf Ebrahimi {"ld1roh_z_p_br_contiguous"_h,
1715*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEF64MM)},
1716*f5c631daSSadaf Ebrahimi {"usdot_asimdsame2_d"_h,
1717*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kI8MM)},
1718*f5c631daSSadaf Ebrahimi {"sudot_asimdelem_d"_h,
1719*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kI8MM)},
1720*f5c631daSSadaf Ebrahimi {"usdot_asimdelem_d"_h,
1721*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kNEON, CPUFeatures::kI8MM)},
1722*f5c631daSSadaf Ebrahimi {"usdot_z_zzz_s"_h,
1723*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEI8MM)},
1724*f5c631daSSadaf Ebrahimi {"usdot_z_zzzi_s"_h,
1725*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEI8MM)},
1726*f5c631daSSadaf Ebrahimi {"sudot_z_zzzi_s"_h,
1727*f5c631daSSadaf Ebrahimi CPUFeatures(CPUFeatures::kSVE, CPUFeatures::kSVEI8MM)},
1728*f5c631daSSadaf Ebrahimi };
1729*f5c631daSSadaf Ebrahimi
1730*f5c631daSSadaf Ebrahimi if (features.count(form_hash) > 0) {
1731*f5c631daSSadaf Ebrahimi scope.Record(features[form_hash]);
1732*f5c631daSSadaf Ebrahimi }
1733*f5c631daSSadaf Ebrahimi } else {
1734*f5c631daSSadaf Ebrahimi (it->second)(this, instr);
1735*f5c631daSSadaf Ebrahimi }
1736*f5c631daSSadaf Ebrahimi }
1737*f5c631daSSadaf Ebrahimi
1738*f5c631daSSadaf Ebrahimi } // namespace aarch64
1739*f5c631daSSadaf Ebrahimi } // namespace vixl
1740