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