xref: /aosp_15_r20/external/vixl/src/aarch64/cpu-features-auditor-aarch64.cc (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
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