1*f5c631daSSadaf Ebrahimi // Copyright 2019, 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 #ifndef VIXL_AARCH64_DECODER_AARCH64_H_ 28*f5c631daSSadaf Ebrahimi #define VIXL_AARCH64_DECODER_AARCH64_H_ 29*f5c631daSSadaf Ebrahimi 30*f5c631daSSadaf Ebrahimi #include <list> 31*f5c631daSSadaf Ebrahimi #include <map> 32*f5c631daSSadaf Ebrahimi #include <string> 33*f5c631daSSadaf Ebrahimi 34*f5c631daSSadaf Ebrahimi #include "../globals-vixl.h" 35*f5c631daSSadaf Ebrahimi 36*f5c631daSSadaf Ebrahimi #include "instructions-aarch64.h" 37*f5c631daSSadaf Ebrahimi 38*f5c631daSSadaf Ebrahimi // List macro containing all visitors needed by the decoder class. 39*f5c631daSSadaf Ebrahimi #define VISITOR_LIST_THAT_RETURN(V) \ 40*f5c631daSSadaf Ebrahimi V(AddSubExtended) \ 41*f5c631daSSadaf Ebrahimi V(AddSubImmediate) \ 42*f5c631daSSadaf Ebrahimi V(AddSubShifted) \ 43*f5c631daSSadaf Ebrahimi V(AddSubWithCarry) \ 44*f5c631daSSadaf Ebrahimi V(AtomicMemory) \ 45*f5c631daSSadaf Ebrahimi V(Bitfield) \ 46*f5c631daSSadaf Ebrahimi V(CompareBranch) \ 47*f5c631daSSadaf Ebrahimi V(ConditionalBranch) \ 48*f5c631daSSadaf Ebrahimi V(ConditionalCompareImmediate) \ 49*f5c631daSSadaf Ebrahimi V(ConditionalCompareRegister) \ 50*f5c631daSSadaf Ebrahimi V(ConditionalSelect) \ 51*f5c631daSSadaf Ebrahimi V(Crypto2RegSHA) \ 52*f5c631daSSadaf Ebrahimi V(Crypto3RegSHA) \ 53*f5c631daSSadaf Ebrahimi V(CryptoAES) \ 54*f5c631daSSadaf Ebrahimi V(DataProcessing1Source) \ 55*f5c631daSSadaf Ebrahimi V(DataProcessing2Source) \ 56*f5c631daSSadaf Ebrahimi V(DataProcessing3Source) \ 57*f5c631daSSadaf Ebrahimi V(EvaluateIntoFlags) \ 58*f5c631daSSadaf Ebrahimi V(Exception) \ 59*f5c631daSSadaf Ebrahimi V(Extract) \ 60*f5c631daSSadaf Ebrahimi V(FPCompare) \ 61*f5c631daSSadaf Ebrahimi V(FPConditionalCompare) \ 62*f5c631daSSadaf Ebrahimi V(FPConditionalSelect) \ 63*f5c631daSSadaf Ebrahimi V(FPDataProcessing1Source) \ 64*f5c631daSSadaf Ebrahimi V(FPDataProcessing2Source) \ 65*f5c631daSSadaf Ebrahimi V(FPDataProcessing3Source) \ 66*f5c631daSSadaf Ebrahimi V(FPFixedPointConvert) \ 67*f5c631daSSadaf Ebrahimi V(FPImmediate) \ 68*f5c631daSSadaf Ebrahimi V(FPIntegerConvert) \ 69*f5c631daSSadaf Ebrahimi V(LoadLiteral) \ 70*f5c631daSSadaf Ebrahimi V(LoadStoreExclusive) \ 71*f5c631daSSadaf Ebrahimi V(LoadStorePAC) \ 72*f5c631daSSadaf Ebrahimi V(LoadStorePairNonTemporal) \ 73*f5c631daSSadaf Ebrahimi V(LoadStorePairOffset) \ 74*f5c631daSSadaf Ebrahimi V(LoadStorePairPostIndex) \ 75*f5c631daSSadaf Ebrahimi V(LoadStorePairPreIndex) \ 76*f5c631daSSadaf Ebrahimi V(LoadStorePostIndex) \ 77*f5c631daSSadaf Ebrahimi V(LoadStorePreIndex) \ 78*f5c631daSSadaf Ebrahimi V(LoadStoreRCpcUnscaledOffset) \ 79*f5c631daSSadaf Ebrahimi V(LoadStoreRegisterOffset) \ 80*f5c631daSSadaf Ebrahimi V(LoadStoreUnscaledOffset) \ 81*f5c631daSSadaf Ebrahimi V(LoadStoreUnsignedOffset) \ 82*f5c631daSSadaf Ebrahimi V(LogicalImmediate) \ 83*f5c631daSSadaf Ebrahimi V(LogicalShifted) \ 84*f5c631daSSadaf Ebrahimi V(MoveWideImmediate) \ 85*f5c631daSSadaf Ebrahimi V(NEON2RegMisc) \ 86*f5c631daSSadaf Ebrahimi V(NEON2RegMiscFP16) \ 87*f5c631daSSadaf Ebrahimi V(NEON3Different) \ 88*f5c631daSSadaf Ebrahimi V(NEON3Same) \ 89*f5c631daSSadaf Ebrahimi V(NEON3SameExtra) \ 90*f5c631daSSadaf Ebrahimi V(NEON3SameFP16) \ 91*f5c631daSSadaf Ebrahimi V(NEONAcrossLanes) \ 92*f5c631daSSadaf Ebrahimi V(NEONByIndexedElement) \ 93*f5c631daSSadaf Ebrahimi V(NEONCopy) \ 94*f5c631daSSadaf Ebrahimi V(NEONExtract) \ 95*f5c631daSSadaf Ebrahimi V(NEONLoadStoreMultiStruct) \ 96*f5c631daSSadaf Ebrahimi V(NEONLoadStoreMultiStructPostIndex) \ 97*f5c631daSSadaf Ebrahimi V(NEONLoadStoreSingleStruct) \ 98*f5c631daSSadaf Ebrahimi V(NEONLoadStoreSingleStructPostIndex) \ 99*f5c631daSSadaf Ebrahimi V(NEONModifiedImmediate) \ 100*f5c631daSSadaf Ebrahimi V(NEONPerm) \ 101*f5c631daSSadaf Ebrahimi V(NEONScalar2RegMisc) \ 102*f5c631daSSadaf Ebrahimi V(NEONScalar2RegMiscFP16) \ 103*f5c631daSSadaf Ebrahimi V(NEONScalar3Diff) \ 104*f5c631daSSadaf Ebrahimi V(NEONScalar3Same) \ 105*f5c631daSSadaf Ebrahimi V(NEONScalar3SameExtra) \ 106*f5c631daSSadaf Ebrahimi V(NEONScalar3SameFP16) \ 107*f5c631daSSadaf Ebrahimi V(NEONScalarByIndexedElement) \ 108*f5c631daSSadaf Ebrahimi V(NEONScalarCopy) \ 109*f5c631daSSadaf Ebrahimi V(NEONScalarPairwise) \ 110*f5c631daSSadaf Ebrahimi V(NEONScalarShiftImmediate) \ 111*f5c631daSSadaf Ebrahimi V(NEONShiftImmediate) \ 112*f5c631daSSadaf Ebrahimi V(NEONTable) \ 113*f5c631daSSadaf Ebrahimi V(PCRelAddressing) \ 114*f5c631daSSadaf Ebrahimi V(RotateRightIntoFlags) \ 115*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoad_ScalarPlus32BitUnscaledOffsets) \ 116*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoad_VectorPlusImm) \ 117*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoadHalfwords_ScalarPlus32BitScaledOffsets) \ 118*f5c631daSSadaf Ebrahimi V(SVE32BitGatherLoadWords_ScalarPlus32BitScaledOffsets) \ 119*f5c631daSSadaf Ebrahimi V(SVE32BitGatherPrefetch_ScalarPlus32BitScaledOffsets) \ 120*f5c631daSSadaf Ebrahimi V(SVE32BitGatherPrefetch_VectorPlusImm) \ 121*f5c631daSSadaf Ebrahimi V(SVE32BitScatterStore_ScalarPlus32BitScaledOffsets) \ 122*f5c631daSSadaf Ebrahimi V(SVE32BitScatterStore_ScalarPlus32BitUnscaledOffsets) \ 123*f5c631daSSadaf Ebrahimi V(SVE32BitScatterStore_VectorPlusImm) \ 124*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlus32BitUnpackedScaledOffsets) \ 125*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlus64BitScaledOffsets) \ 126*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlus64BitUnscaledOffsets) \ 127*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_ScalarPlusUnpacked32BitUnscaledOffsets) \ 128*f5c631daSSadaf Ebrahimi V(SVE64BitGatherLoad_VectorPlusImm) \ 129*f5c631daSSadaf Ebrahimi V(SVE64BitGatherPrefetch_ScalarPlus64BitScaledOffsets) \ 130*f5c631daSSadaf Ebrahimi V(SVE64BitGatherPrefetch_ScalarPlusUnpacked32BitScaledOffsets) \ 131*f5c631daSSadaf Ebrahimi V(SVE64BitGatherPrefetch_VectorPlusImm) \ 132*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlus64BitScaledOffsets) \ 133*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlus64BitUnscaledOffsets) \ 134*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlusUnpacked32BitScaledOffsets) \ 135*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_ScalarPlusUnpacked32BitUnscaledOffsets) \ 136*f5c631daSSadaf Ebrahimi V(SVE64BitScatterStore_VectorPlusImm) \ 137*f5c631daSSadaf Ebrahimi V(SVEAddressGeneration) \ 138*f5c631daSSadaf Ebrahimi V(SVEBitwiseLogicalUnpredicated) \ 139*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftUnpredicated) \ 140*f5c631daSSadaf Ebrahimi V(SVEFFRInitialise) \ 141*f5c631daSSadaf Ebrahimi V(SVEFFRWriteFromPredicate) \ 142*f5c631daSSadaf Ebrahimi V(SVEFPAccumulatingReduction) \ 143*f5c631daSSadaf Ebrahimi V(SVEFPArithmeticUnpredicated) \ 144*f5c631daSSadaf Ebrahimi V(SVEFPCompareVectors) \ 145*f5c631daSSadaf Ebrahimi V(SVEFPCompareWithZero) \ 146*f5c631daSSadaf Ebrahimi V(SVEFPComplexAddition) \ 147*f5c631daSSadaf Ebrahimi V(SVEFPComplexMulAdd) \ 148*f5c631daSSadaf Ebrahimi V(SVEFPComplexMulAddIndex) \ 149*f5c631daSSadaf Ebrahimi V(SVEFPFastReduction) \ 150*f5c631daSSadaf Ebrahimi V(SVEFPMulIndex) \ 151*f5c631daSSadaf Ebrahimi V(SVEFPMulAdd) \ 152*f5c631daSSadaf Ebrahimi V(SVEFPMulAddIndex) \ 153*f5c631daSSadaf Ebrahimi V(SVEFPUnaryOpUnpredicated) \ 154*f5c631daSSadaf Ebrahimi V(SVEIncDecByPredicateCount) \ 155*f5c631daSSadaf Ebrahimi V(SVEIndexGeneration) \ 156*f5c631daSSadaf Ebrahimi V(SVEIntArithmeticUnpredicated) \ 157*f5c631daSSadaf Ebrahimi V(SVEIntCompareSignedImm) \ 158*f5c631daSSadaf Ebrahimi V(SVEIntCompareUnsignedImm) \ 159*f5c631daSSadaf Ebrahimi V(SVEIntCompareVectors) \ 160*f5c631daSSadaf Ebrahimi V(SVEIntMulAddPredicated) \ 161*f5c631daSSadaf Ebrahimi V(SVEIntMulAddUnpredicated) \ 162*f5c631daSSadaf Ebrahimi V(SVEIntReduction) \ 163*f5c631daSSadaf Ebrahimi V(SVEIntUnaryArithmeticPredicated) \ 164*f5c631daSSadaf Ebrahimi V(SVEMovprfx) \ 165*f5c631daSSadaf Ebrahimi V(SVEMulIndex) \ 166*f5c631daSSadaf Ebrahimi V(SVEPermuteVectorExtract) \ 167*f5c631daSSadaf Ebrahimi V(SVEPermuteVectorInterleaving) \ 168*f5c631daSSadaf Ebrahimi V(SVEPredicateCount) \ 169*f5c631daSSadaf Ebrahimi V(SVEPredicateLogical) \ 170*f5c631daSSadaf Ebrahimi V(SVEPropagateBreak) \ 171*f5c631daSSadaf Ebrahimi V(SVEStackFrameAdjustment) \ 172*f5c631daSSadaf Ebrahimi V(SVEStackFrameSize) \ 173*f5c631daSSadaf Ebrahimi V(SVEVectorSelect) \ 174*f5c631daSSadaf Ebrahimi V(SVEBitwiseLogical_Predicated) \ 175*f5c631daSSadaf Ebrahimi V(SVEBitwiseLogicalWithImm_Unpredicated) \ 176*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftByImm_Predicated) \ 177*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftByVector_Predicated) \ 178*f5c631daSSadaf Ebrahimi V(SVEBitwiseShiftByWideElements_Predicated) \ 179*f5c631daSSadaf Ebrahimi V(SVEBroadcastBitmaskImm) \ 180*f5c631daSSadaf Ebrahimi V(SVEBroadcastFPImm_Unpredicated) \ 181*f5c631daSSadaf Ebrahimi V(SVEBroadcastGeneralRegister) \ 182*f5c631daSSadaf Ebrahimi V(SVEBroadcastIndexElement) \ 183*f5c631daSSadaf Ebrahimi V(SVEBroadcastIntImm_Unpredicated) \ 184*f5c631daSSadaf Ebrahimi V(SVECompressActiveElements) \ 185*f5c631daSSadaf Ebrahimi V(SVEConditionallyBroadcastElementToVector) \ 186*f5c631daSSadaf Ebrahimi V(SVEConditionallyExtractElementToSIMDFPScalar) \ 187*f5c631daSSadaf Ebrahimi V(SVEConditionallyExtractElementToGeneralRegister) \ 188*f5c631daSSadaf Ebrahimi V(SVEConditionallyTerminateScalars) \ 189*f5c631daSSadaf Ebrahimi V(SVEConstructivePrefix_Unpredicated) \ 190*f5c631daSSadaf Ebrahimi V(SVEContiguousFirstFaultLoad_ScalarPlusScalar) \ 191*f5c631daSSadaf Ebrahimi V(SVEContiguousLoad_ScalarPlusImm) \ 192*f5c631daSSadaf Ebrahimi V(SVEContiguousLoad_ScalarPlusScalar) \ 193*f5c631daSSadaf Ebrahimi V(SVEContiguousNonFaultLoad_ScalarPlusImm) \ 194*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalLoad_ScalarPlusImm) \ 195*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalLoad_ScalarPlusScalar) \ 196*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalStore_ScalarPlusImm) \ 197*f5c631daSSadaf Ebrahimi V(SVEContiguousNonTemporalStore_ScalarPlusScalar) \ 198*f5c631daSSadaf Ebrahimi V(SVEContiguousPrefetch_ScalarPlusImm) \ 199*f5c631daSSadaf Ebrahimi V(SVEContiguousPrefetch_ScalarPlusScalar) \ 200*f5c631daSSadaf Ebrahimi V(SVEContiguousStore_ScalarPlusImm) \ 201*f5c631daSSadaf Ebrahimi V(SVEContiguousStore_ScalarPlusScalar) \ 202*f5c631daSSadaf Ebrahimi V(SVECopySIMDFPScalarRegisterToVector_Predicated) \ 203*f5c631daSSadaf Ebrahimi V(SVECopyFPImm_Predicated) \ 204*f5c631daSSadaf Ebrahimi V(SVECopyGeneralRegisterToVector_Predicated) \ 205*f5c631daSSadaf Ebrahimi V(SVECopyIntImm_Predicated) \ 206*f5c631daSSadaf Ebrahimi V(SVEElementCount) \ 207*f5c631daSSadaf Ebrahimi V(SVEExtractElementToSIMDFPScalarRegister) \ 208*f5c631daSSadaf Ebrahimi V(SVEExtractElementToGeneralRegister) \ 209*f5c631daSSadaf Ebrahimi V(SVEFPArithmetic_Predicated) \ 210*f5c631daSSadaf Ebrahimi V(SVEFPArithmeticWithImm_Predicated) \ 211*f5c631daSSadaf Ebrahimi V(SVEFPConvertPrecision) \ 212*f5c631daSSadaf Ebrahimi V(SVEFPConvertToInt) \ 213*f5c631daSSadaf Ebrahimi V(SVEFPExponentialAccelerator) \ 214*f5c631daSSadaf Ebrahimi V(SVEFPRoundToIntegralValue) \ 215*f5c631daSSadaf Ebrahimi V(SVEFPTrigMulAddCoefficient) \ 216*f5c631daSSadaf Ebrahimi V(SVEFPTrigSelectCoefficient) \ 217*f5c631daSSadaf Ebrahimi V(SVEFPUnaryOp) \ 218*f5c631daSSadaf Ebrahimi V(SVEIncDecRegisterByElementCount) \ 219*f5c631daSSadaf Ebrahimi V(SVEIncDecVectorByElementCount) \ 220*f5c631daSSadaf Ebrahimi V(SVEInsertSIMDFPScalarRegister) \ 221*f5c631daSSadaf Ebrahimi V(SVEInsertGeneralRegister) \ 222*f5c631daSSadaf Ebrahimi V(SVEIntAddSubtractImm_Unpredicated) \ 223*f5c631daSSadaf Ebrahimi V(SVEIntAddSubtractVectors_Predicated) \ 224*f5c631daSSadaf Ebrahimi V(SVEIntCompareScalarCountAndLimit) \ 225*f5c631daSSadaf Ebrahimi V(SVEIntConvertToFP) \ 226*f5c631daSSadaf Ebrahimi V(SVEIntDivideVectors_Predicated) \ 227*f5c631daSSadaf Ebrahimi V(SVEIntMinMaxImm_Unpredicated) \ 228*f5c631daSSadaf Ebrahimi V(SVEIntMinMaxDifference_Predicated) \ 229*f5c631daSSadaf Ebrahimi V(SVEIntMulImm_Unpredicated) \ 230*f5c631daSSadaf Ebrahimi V(SVEIntMulVectors_Predicated) \ 231*f5c631daSSadaf Ebrahimi V(SVELoadAndBroadcastElement) \ 232*f5c631daSSadaf Ebrahimi V(SVELoadAndBroadcastQOWord_ScalarPlusImm) \ 233*f5c631daSSadaf Ebrahimi V(SVELoadAndBroadcastQOWord_ScalarPlusScalar) \ 234*f5c631daSSadaf Ebrahimi V(SVELoadMultipleStructures_ScalarPlusImm) \ 235*f5c631daSSadaf Ebrahimi V(SVELoadMultipleStructures_ScalarPlusScalar) \ 236*f5c631daSSadaf Ebrahimi V(SVELoadPredicateRegister) \ 237*f5c631daSSadaf Ebrahimi V(SVELoadVectorRegister) \ 238*f5c631daSSadaf Ebrahimi V(SVEPartitionBreakCondition) \ 239*f5c631daSSadaf Ebrahimi V(SVEPermutePredicateElements) \ 240*f5c631daSSadaf Ebrahimi V(SVEPredicateFirstActive) \ 241*f5c631daSSadaf Ebrahimi V(SVEPredicateInitialize) \ 242*f5c631daSSadaf Ebrahimi V(SVEPredicateNextActive) \ 243*f5c631daSSadaf Ebrahimi V(SVEPredicateReadFromFFR_Predicated) \ 244*f5c631daSSadaf Ebrahimi V(SVEPredicateReadFromFFR_Unpredicated) \ 245*f5c631daSSadaf Ebrahimi V(SVEPredicateTest) \ 246*f5c631daSSadaf Ebrahimi V(SVEPredicateZero) \ 247*f5c631daSSadaf Ebrahimi V(SVEPropagateBreakToNextPartition) \ 248*f5c631daSSadaf Ebrahimi V(SVEReversePredicateElements) \ 249*f5c631daSSadaf Ebrahimi V(SVEReverseVectorElements) \ 250*f5c631daSSadaf Ebrahimi V(SVEReverseWithinElements) \ 251*f5c631daSSadaf Ebrahimi V(SVESaturatingIncDecRegisterByElementCount) \ 252*f5c631daSSadaf Ebrahimi V(SVESaturatingIncDecVectorByElementCount) \ 253*f5c631daSSadaf Ebrahimi V(SVEStoreMultipleStructures_ScalarPlusImm) \ 254*f5c631daSSadaf Ebrahimi V(SVEStoreMultipleStructures_ScalarPlusScalar) \ 255*f5c631daSSadaf Ebrahimi V(SVEStorePredicateRegister) \ 256*f5c631daSSadaf Ebrahimi V(SVEStoreVectorRegister) \ 257*f5c631daSSadaf Ebrahimi V(SVETableLookup) \ 258*f5c631daSSadaf Ebrahimi V(SVEUnpackPredicateElements) \ 259*f5c631daSSadaf Ebrahimi V(SVEUnpackVectorElements) \ 260*f5c631daSSadaf Ebrahimi V(SVEVectorSplice) \ 261*f5c631daSSadaf Ebrahimi V(System) \ 262*f5c631daSSadaf Ebrahimi V(TestBranch) \ 263*f5c631daSSadaf Ebrahimi V(Unallocated) \ 264*f5c631daSSadaf Ebrahimi V(UnconditionalBranch) \ 265*f5c631daSSadaf Ebrahimi V(UnconditionalBranchToRegister) \ 266*f5c631daSSadaf Ebrahimi V(Unimplemented) 267*f5c631daSSadaf Ebrahimi 268*f5c631daSSadaf Ebrahimi #define VISITOR_LIST_THAT_DONT_RETURN(V) V(Reserved) 269*f5c631daSSadaf Ebrahimi 270*f5c631daSSadaf Ebrahimi #define VISITOR_LIST(V) \ 271*f5c631daSSadaf Ebrahimi VISITOR_LIST_THAT_RETURN(V) \ 272*f5c631daSSadaf Ebrahimi VISITOR_LIST_THAT_DONT_RETURN(V) 273*f5c631daSSadaf Ebrahimi 274*f5c631daSSadaf Ebrahimi namespace vixl { 275*f5c631daSSadaf Ebrahimi namespace aarch64 { 276*f5c631daSSadaf Ebrahimi 277*f5c631daSSadaf Ebrahimi using Metadata = std::map<std::string, std::string>; 278*f5c631daSSadaf Ebrahimi 279*f5c631daSSadaf Ebrahimi // The Visitor interface consists only of the Visit() method. User classes 280*f5c631daSSadaf Ebrahimi // that inherit from this one must provide an implementation of the method. 281*f5c631daSSadaf Ebrahimi // Information about the instruction encountered by the Decoder is available 282*f5c631daSSadaf Ebrahimi // via the metadata pointer. 283*f5c631daSSadaf Ebrahimi class DecoderVisitor { 284*f5c631daSSadaf Ebrahimi public: 285*f5c631daSSadaf Ebrahimi enum VisitorConstness { kConstVisitor, kNonConstVisitor }; 286*f5c631daSSadaf Ebrahimi explicit DecoderVisitor(VisitorConstness constness = kConstVisitor) constness_(constness)287*f5c631daSSadaf Ebrahimi : constness_(constness) {} 288*f5c631daSSadaf Ebrahimi ~DecoderVisitor()289*f5c631daSSadaf Ebrahimi virtual ~DecoderVisitor() {} 290*f5c631daSSadaf Ebrahimi 291*f5c631daSSadaf Ebrahimi virtual void Visit(Metadata* metadata, const Instruction* instr) = 0; 292*f5c631daSSadaf Ebrahimi IsConstVisitor()293*f5c631daSSadaf Ebrahimi bool IsConstVisitor() const { return constness_ == kConstVisitor; } MutableInstruction(const Instruction * instr)294*f5c631daSSadaf Ebrahimi Instruction* MutableInstruction(const Instruction* instr) { 295*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!IsConstVisitor()); 296*f5c631daSSadaf Ebrahimi return const_cast<Instruction*>(instr); 297*f5c631daSSadaf Ebrahimi } 298*f5c631daSSadaf Ebrahimi 299*f5c631daSSadaf Ebrahimi private: 300*f5c631daSSadaf Ebrahimi const VisitorConstness constness_; 301*f5c631daSSadaf Ebrahimi }; 302*f5c631daSSadaf Ebrahimi 303*f5c631daSSadaf Ebrahimi class DecodeNode; 304*f5c631daSSadaf Ebrahimi class CompiledDecodeNode; 305*f5c631daSSadaf Ebrahimi 306*f5c631daSSadaf Ebrahimi // The instruction decoder is constructed from a graph of decode nodes. At each 307*f5c631daSSadaf Ebrahimi // node, a number of bits are sampled from the instruction being decoded. The 308*f5c631daSSadaf Ebrahimi // resulting value is used to look up the next node in the graph, which then 309*f5c631daSSadaf Ebrahimi // samples other bits, and moves to other decode nodes. Eventually, a visitor 310*f5c631daSSadaf Ebrahimi // node is reached, and the corresponding visitor function is called, which 311*f5c631daSSadaf Ebrahimi // handles the instruction. 312*f5c631daSSadaf Ebrahimi class Decoder { 313*f5c631daSSadaf Ebrahimi public: Decoder()314*f5c631daSSadaf Ebrahimi Decoder() { ConstructDecodeGraph(); } 315*f5c631daSSadaf Ebrahimi 316*f5c631daSSadaf Ebrahimi // Top-level wrappers around the actual decoding function. 317*f5c631daSSadaf Ebrahimi void Decode(const Instruction* instr); 318*f5c631daSSadaf Ebrahimi void Decode(Instruction* instr); 319*f5c631daSSadaf Ebrahimi 320*f5c631daSSadaf Ebrahimi // Decode all instructions from start (inclusive) to end (exclusive). 321*f5c631daSSadaf Ebrahimi template <typename T> Decode(T start,T end)322*f5c631daSSadaf Ebrahimi void Decode(T start, T end) { 323*f5c631daSSadaf Ebrahimi for (T instr = start; instr < end; instr = instr->GetNextInstruction()) { 324*f5c631daSSadaf Ebrahimi Decode(instr); 325*f5c631daSSadaf Ebrahimi } 326*f5c631daSSadaf Ebrahimi } 327*f5c631daSSadaf Ebrahimi 328*f5c631daSSadaf Ebrahimi // Register a new visitor class with the decoder. 329*f5c631daSSadaf Ebrahimi // Decode() will call the corresponding visitor method from all registered 330*f5c631daSSadaf Ebrahimi // visitor classes when decoding reaches the leaf node of the instruction 331*f5c631daSSadaf Ebrahimi // decode tree. 332*f5c631daSSadaf Ebrahimi // Visitors are called in order. 333*f5c631daSSadaf Ebrahimi // A visitor can be registered multiple times. 334*f5c631daSSadaf Ebrahimi // 335*f5c631daSSadaf Ebrahimi // d.AppendVisitor(V1); 336*f5c631daSSadaf Ebrahimi // d.AppendVisitor(V2); 337*f5c631daSSadaf Ebrahimi // d.PrependVisitor(V2); 338*f5c631daSSadaf Ebrahimi // d.AppendVisitor(V3); 339*f5c631daSSadaf Ebrahimi // 340*f5c631daSSadaf Ebrahimi // d.Decode(i); 341*f5c631daSSadaf Ebrahimi // 342*f5c631daSSadaf Ebrahimi // will call in order visitor methods in V2, V1, V2, V3. 343*f5c631daSSadaf Ebrahimi void AppendVisitor(DecoderVisitor* visitor); 344*f5c631daSSadaf Ebrahimi void PrependVisitor(DecoderVisitor* visitor); 345*f5c631daSSadaf Ebrahimi // These helpers register `new_visitor` before or after the first instance of 346*f5c631daSSadaf Ebrahimi // `registered_visiter` in the list. 347*f5c631daSSadaf Ebrahimi // So if 348*f5c631daSSadaf Ebrahimi // V1, V2, V1, V2 349*f5c631daSSadaf Ebrahimi // are registered in this order in the decoder, calls to 350*f5c631daSSadaf Ebrahimi // d.InsertVisitorAfter(V3, V1); 351*f5c631daSSadaf Ebrahimi // d.InsertVisitorBefore(V4, V2); 352*f5c631daSSadaf Ebrahimi // will yield the order 353*f5c631daSSadaf Ebrahimi // V1, V3, V4, V2, V1, V2 354*f5c631daSSadaf Ebrahimi // 355*f5c631daSSadaf Ebrahimi // For more complex modifications of the order of registered visitors, one can 356*f5c631daSSadaf Ebrahimi // directly access and modify the list of visitors via the `visitors()' 357*f5c631daSSadaf Ebrahimi // accessor. 358*f5c631daSSadaf Ebrahimi void InsertVisitorBefore(DecoderVisitor* new_visitor, 359*f5c631daSSadaf Ebrahimi DecoderVisitor* registered_visitor); 360*f5c631daSSadaf Ebrahimi void InsertVisitorAfter(DecoderVisitor* new_visitor, 361*f5c631daSSadaf Ebrahimi DecoderVisitor* registered_visitor); 362*f5c631daSSadaf Ebrahimi 363*f5c631daSSadaf Ebrahimi // Remove all instances of a previously registered visitor class from the list 364*f5c631daSSadaf Ebrahimi // of visitors stored by the decoder. 365*f5c631daSSadaf Ebrahimi void RemoveVisitor(DecoderVisitor* visitor); 366*f5c631daSSadaf Ebrahimi 367*f5c631daSSadaf Ebrahimi void VisitNamedInstruction(const Instruction* instr, const std::string& name); 368*f5c631daSSadaf Ebrahimi visitors()369*f5c631daSSadaf Ebrahimi std::list<DecoderVisitor*>* visitors() { return &visitors_; } 370*f5c631daSSadaf Ebrahimi 371*f5c631daSSadaf Ebrahimi // Get a DecodeNode by name from the Decoder's map. 372*f5c631daSSadaf Ebrahimi DecodeNode* GetDecodeNode(std::string name); 373*f5c631daSSadaf Ebrahimi 374*f5c631daSSadaf Ebrahimi private: 375*f5c631daSSadaf Ebrahimi // Decodes an instruction and calls the visitor functions registered with the 376*f5c631daSSadaf Ebrahimi // Decoder class. 377*f5c631daSSadaf Ebrahimi void DecodeInstruction(const Instruction* instr); 378*f5c631daSSadaf Ebrahimi 379*f5c631daSSadaf Ebrahimi // Add an initialised DecodeNode to the decode_node_ map. 380*f5c631daSSadaf Ebrahimi void AddDecodeNode(const DecodeNode& node); 381*f5c631daSSadaf Ebrahimi 382*f5c631daSSadaf Ebrahimi // Visitors are registered in a list. 383*f5c631daSSadaf Ebrahimi std::list<DecoderVisitor*> visitors_; 384*f5c631daSSadaf Ebrahimi 385*f5c631daSSadaf Ebrahimi // Compile the dynamically generated decode graph based on the static 386*f5c631daSSadaf Ebrahimi // information in kDecodeMapping and kVisitorNodes. 387*f5c631daSSadaf Ebrahimi void ConstructDecodeGraph(); 388*f5c631daSSadaf Ebrahimi 389*f5c631daSSadaf Ebrahimi // Root node for the compiled decoder graph, stored here to avoid a map lookup 390*f5c631daSSadaf Ebrahimi // for every instruction decoded. 391*f5c631daSSadaf Ebrahimi CompiledDecodeNode* compiled_decoder_root_; 392*f5c631daSSadaf Ebrahimi 393*f5c631daSSadaf Ebrahimi // Map of node names to DecodeNodes. 394*f5c631daSSadaf Ebrahimi std::map<std::string, DecodeNode> decode_nodes_; 395*f5c631daSSadaf Ebrahimi }; 396*f5c631daSSadaf Ebrahimi 397*f5c631daSSadaf Ebrahimi typedef void (Decoder::*DecodeFnPtr)(const Instruction*); 398*f5c631daSSadaf Ebrahimi typedef uint32_t (Instruction::*BitExtractFn)(void) const; 399*f5c631daSSadaf Ebrahimi 400*f5c631daSSadaf Ebrahimi // A Visitor node maps the name of a visitor to the function that handles it. 401*f5c631daSSadaf Ebrahimi struct VisitorNode { 402*f5c631daSSadaf Ebrahimi const char* name; 403*f5c631daSSadaf Ebrahimi const DecodeFnPtr visitor_fn; 404*f5c631daSSadaf Ebrahimi }; 405*f5c631daSSadaf Ebrahimi 406*f5c631daSSadaf Ebrahimi // DecodePattern and DecodeMapping represent the input data to the decoder 407*f5c631daSSadaf Ebrahimi // compilation stage. After compilation, the decoder is embodied in the graph 408*f5c631daSSadaf Ebrahimi // of CompiledDecodeNodes pointer to by compiled_decoder_root_. 409*f5c631daSSadaf Ebrahimi 410*f5c631daSSadaf Ebrahimi // A DecodePattern maps a pattern of set/unset/don't care (1, 0, x) bits encoded 411*f5c631daSSadaf Ebrahimi // as uint32_t to its handler. 412*f5c631daSSadaf Ebrahimi // The encoding uses two bits per symbol: 0 => 0b00, 1 => 0b01, x => 0b10. 413*f5c631daSSadaf Ebrahimi // 0b11 marks the edge of the most-significant bits of the pattern, which is 414*f5c631daSSadaf Ebrahimi // required to determine the length. For example, the pattern "1x01"_b is 415*f5c631daSSadaf Ebrahimi // encoded in a uint32_t as 0b11_01_10_00_01. 416*f5c631daSSadaf Ebrahimi struct DecodePattern { 417*f5c631daSSadaf Ebrahimi uint32_t pattern; 418*f5c631daSSadaf Ebrahimi const char* handler; 419*f5c631daSSadaf Ebrahimi }; 420*f5c631daSSadaf Ebrahimi 421*f5c631daSSadaf Ebrahimi // A DecodeMapping consists of the name of a handler, the bits sampled in the 422*f5c631daSSadaf Ebrahimi // instruction by that handler, and a mapping from the pattern that those 423*f5c631daSSadaf Ebrahimi // sampled bits match to the corresponding name of a node. 424*f5c631daSSadaf Ebrahimi struct DecodeMapping { 425*f5c631daSSadaf Ebrahimi const char* name; 426*f5c631daSSadaf Ebrahimi const std::vector<uint8_t> sampled_bits; 427*f5c631daSSadaf Ebrahimi const std::vector<DecodePattern> mapping; 428*f5c631daSSadaf Ebrahimi }; 429*f5c631daSSadaf Ebrahimi 430*f5c631daSSadaf Ebrahimi // For speed, before nodes can be used for decoding instructions, they must 431*f5c631daSSadaf Ebrahimi // be compiled. This converts the mapping "bit pattern strings to decoder name 432*f5c631daSSadaf Ebrahimi // string" stored in DecodeNodes to an array look up for the pointer to the next 433*f5c631daSSadaf Ebrahimi // node, stored in CompiledDecodeNodes. Compilation may also apply other 434*f5c631daSSadaf Ebrahimi // optimisations for simple decode patterns. 435*f5c631daSSadaf Ebrahimi class CompiledDecodeNode { 436*f5c631daSSadaf Ebrahimi public: 437*f5c631daSSadaf Ebrahimi // Constructor for decode node, containing a decode table and pointer to a 438*f5c631daSSadaf Ebrahimi // function that extracts the bits to be sampled. CompiledDecodeNode(BitExtractFn bit_extract_fn,size_t decode_table_size)439*f5c631daSSadaf Ebrahimi CompiledDecodeNode(BitExtractFn bit_extract_fn, size_t decode_table_size) 440*f5c631daSSadaf Ebrahimi : bit_extract_fn_(bit_extract_fn), 441*f5c631daSSadaf Ebrahimi instruction_name_("node"), 442*f5c631daSSadaf Ebrahimi decode_table_size_(decode_table_size), 443*f5c631daSSadaf Ebrahimi decoder_(NULL) { 444*f5c631daSSadaf Ebrahimi decode_table_ = new CompiledDecodeNode*[decode_table_size_]; 445*f5c631daSSadaf Ebrahimi memset(decode_table_, 0, decode_table_size_ * sizeof(decode_table_[0])); 446*f5c631daSSadaf Ebrahimi } 447*f5c631daSSadaf Ebrahimi 448*f5c631daSSadaf Ebrahimi // Constructor for wrappers around visitor functions. These require no 449*f5c631daSSadaf Ebrahimi // decoding, so no bit extraction function or decode table is assigned. CompiledDecodeNode(std::string iname,Decoder * decoder)450*f5c631daSSadaf Ebrahimi explicit CompiledDecodeNode(std::string iname, Decoder* decoder) 451*f5c631daSSadaf Ebrahimi : bit_extract_fn_(NULL), 452*f5c631daSSadaf Ebrahimi instruction_name_(iname), 453*f5c631daSSadaf Ebrahimi decode_table_(NULL), 454*f5c631daSSadaf Ebrahimi decode_table_size_(0), 455*f5c631daSSadaf Ebrahimi decoder_(decoder) {} 456*f5c631daSSadaf Ebrahimi ~CompiledDecodeNode()457*f5c631daSSadaf Ebrahimi ~CompiledDecodeNode() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION { 458*f5c631daSSadaf Ebrahimi // Free the decode table, if this is a compiled, non-leaf node. 459*f5c631daSSadaf Ebrahimi if (decode_table_ != NULL) { 460*f5c631daSSadaf Ebrahimi VIXL_ASSERT(!IsLeafNode()); 461*f5c631daSSadaf Ebrahimi delete[] decode_table_; 462*f5c631daSSadaf Ebrahimi } 463*f5c631daSSadaf Ebrahimi } 464*f5c631daSSadaf Ebrahimi 465*f5c631daSSadaf Ebrahimi // Decode the instruction by either sampling the bits using the bit extract 466*f5c631daSSadaf Ebrahimi // function to find the next node, or, if we're at a leaf, calling the visitor 467*f5c631daSSadaf Ebrahimi // function. 468*f5c631daSSadaf Ebrahimi void Decode(const Instruction* instr) const; 469*f5c631daSSadaf Ebrahimi 470*f5c631daSSadaf Ebrahimi // A leaf node is a wrapper for a visitor function. IsLeafNode()471*f5c631daSSadaf Ebrahimi bool IsLeafNode() const { 472*f5c631daSSadaf Ebrahimi VIXL_ASSERT(((instruction_name_ == "node") && (bit_extract_fn_ != NULL)) || 473*f5c631daSSadaf Ebrahimi ((instruction_name_ != "node") && (bit_extract_fn_ == NULL))); 474*f5c631daSSadaf Ebrahimi return instruction_name_ != "node"; 475*f5c631daSSadaf Ebrahimi } 476*f5c631daSSadaf Ebrahimi 477*f5c631daSSadaf Ebrahimi // Get a pointer to the next node required in the decode process, based on the 478*f5c631daSSadaf Ebrahimi // bits sampled by the current node. GetNodeForBits(uint32_t bits)479*f5c631daSSadaf Ebrahimi CompiledDecodeNode* GetNodeForBits(uint32_t bits) const { 480*f5c631daSSadaf Ebrahimi VIXL_ASSERT(bits < decode_table_size_); 481*f5c631daSSadaf Ebrahimi return decode_table_[bits]; 482*f5c631daSSadaf Ebrahimi } 483*f5c631daSSadaf Ebrahimi 484*f5c631daSSadaf Ebrahimi // Set the next node in the decode process for the pattern of sampled bits in 485*f5c631daSSadaf Ebrahimi // the current node. SetNodeForBits(uint32_t bits,CompiledDecodeNode * n)486*f5c631daSSadaf Ebrahimi void SetNodeForBits(uint32_t bits, CompiledDecodeNode* n) { 487*f5c631daSSadaf Ebrahimi VIXL_ASSERT(bits < decode_table_size_); 488*f5c631daSSadaf Ebrahimi VIXL_ASSERT(n != NULL); 489*f5c631daSSadaf Ebrahimi decode_table_[bits] = n; 490*f5c631daSSadaf Ebrahimi } 491*f5c631daSSadaf Ebrahimi 492*f5c631daSSadaf Ebrahimi private: 493*f5c631daSSadaf Ebrahimi // Pointer to an instantiated template function for extracting the bits 494*f5c631daSSadaf Ebrahimi // sampled by this node. Set to NULL for leaf nodes. 495*f5c631daSSadaf Ebrahimi const BitExtractFn bit_extract_fn_; 496*f5c631daSSadaf Ebrahimi 497*f5c631daSSadaf Ebrahimi // Visitor function that handles the instruction identified. Set only for 498*f5c631daSSadaf Ebrahimi // leaf nodes, where no extra decoding is required, otherwise NULL. 499*f5c631daSSadaf Ebrahimi std::string instruction_name_; 500*f5c631daSSadaf Ebrahimi 501*f5c631daSSadaf Ebrahimi // Mapping table from instruction bits to next decode stage. 502*f5c631daSSadaf Ebrahimi CompiledDecodeNode** decode_table_; 503*f5c631daSSadaf Ebrahimi const size_t decode_table_size_; 504*f5c631daSSadaf Ebrahimi 505*f5c631daSSadaf Ebrahimi // Pointer to the decoder containing this node, used to call its visitor 506*f5c631daSSadaf Ebrahimi // function for leaf nodes. Set to NULL for non-leaf nodes. 507*f5c631daSSadaf Ebrahimi Decoder* decoder_; 508*f5c631daSSadaf Ebrahimi }; 509*f5c631daSSadaf Ebrahimi 510*f5c631daSSadaf Ebrahimi class DecodeNode { 511*f5c631daSSadaf Ebrahimi public: 512*f5c631daSSadaf Ebrahimi // Default constructor needed for map initialisation. DecodeNode()513*f5c631daSSadaf Ebrahimi DecodeNode() 514*f5c631daSSadaf Ebrahimi : sampled_bits_(DecodeNode::kEmptySampledBits), 515*f5c631daSSadaf Ebrahimi pattern_table_(DecodeNode::kEmptyPatternTable), 516*f5c631daSSadaf Ebrahimi compiled_node_(NULL) {} 517*f5c631daSSadaf Ebrahimi 518*f5c631daSSadaf Ebrahimi // Constructor for DecodeNode wrappers around visitor functions. These are 519*f5c631daSSadaf Ebrahimi // marked as "compiled", as there is no decoding left to do. DecodeNode(const std::string & iname,Decoder * decoder)520*f5c631daSSadaf Ebrahimi explicit DecodeNode(const std::string& iname, Decoder* decoder) 521*f5c631daSSadaf Ebrahimi : name_(iname), 522*f5c631daSSadaf Ebrahimi sampled_bits_(DecodeNode::kEmptySampledBits), 523*f5c631daSSadaf Ebrahimi instruction_name_(iname), 524*f5c631daSSadaf Ebrahimi pattern_table_(DecodeNode::kEmptyPatternTable), 525*f5c631daSSadaf Ebrahimi decoder_(decoder), 526*f5c631daSSadaf Ebrahimi compiled_node_(NULL) {} 527*f5c631daSSadaf Ebrahimi 528*f5c631daSSadaf Ebrahimi // Constructor for DecodeNodes that map bit patterns to other DecodeNodes. 529*f5c631daSSadaf Ebrahimi explicit DecodeNode(const DecodeMapping& map, Decoder* decoder = NULL) 530*f5c631daSSadaf Ebrahimi : name_(map.name), 531*f5c631daSSadaf Ebrahimi sampled_bits_(map.sampled_bits), 532*f5c631daSSadaf Ebrahimi instruction_name_("node"), 533*f5c631daSSadaf Ebrahimi pattern_table_(map.mapping), 534*f5c631daSSadaf Ebrahimi decoder_(decoder), 535*f5c631daSSadaf Ebrahimi compiled_node_(NULL) { 536*f5c631daSSadaf Ebrahimi // With the current two bits per symbol encoding scheme, the maximum pattern 537*f5c631daSSadaf Ebrahimi // length is (32 - 2) / 2 = 15 bits. 538*f5c631daSSadaf Ebrahimi VIXL_CHECK(GetPatternLength(map.mapping[0].pattern) <= 15); 539*f5c631daSSadaf Ebrahimi for (const DecodePattern& p : map.mapping) { 540*f5c631daSSadaf Ebrahimi VIXL_CHECK(GetPatternLength(p.pattern) == map.sampled_bits.size()); 541*f5c631daSSadaf Ebrahimi } 542*f5c631daSSadaf Ebrahimi } 543*f5c631daSSadaf Ebrahimi ~DecodeNode()544*f5c631daSSadaf Ebrahimi ~DecodeNode() { 545*f5c631daSSadaf Ebrahimi // Delete the compiled version of this node, if one was created. 546*f5c631daSSadaf Ebrahimi if (compiled_node_ != NULL) { 547*f5c631daSSadaf Ebrahimi delete compiled_node_; 548*f5c631daSSadaf Ebrahimi } 549*f5c631daSSadaf Ebrahimi } 550*f5c631daSSadaf Ebrahimi 551*f5c631daSSadaf Ebrahimi // Get the bits sampled from the instruction by this node. GetSampledBits()552*f5c631daSSadaf Ebrahimi const std::vector<uint8_t>& GetSampledBits() const { return sampled_bits_; } 553*f5c631daSSadaf Ebrahimi 554*f5c631daSSadaf Ebrahimi // Get the number of bits sampled from the instruction by this node. GetSampledBitsCount()555*f5c631daSSadaf Ebrahimi size_t GetSampledBitsCount() const { return sampled_bits_.size(); } 556*f5c631daSSadaf Ebrahimi 557*f5c631daSSadaf Ebrahimi // A leaf node is a DecodeNode that wraps the visitor function for the 558*f5c631daSSadaf Ebrahimi // identified instruction class. IsLeafNode()559*f5c631daSSadaf Ebrahimi bool IsLeafNode() const { return instruction_name_ != "node"; } 560*f5c631daSSadaf Ebrahimi GetName()561*f5c631daSSadaf Ebrahimi std::string GetName() const { return name_; } 562*f5c631daSSadaf Ebrahimi 563*f5c631daSSadaf Ebrahimi // Create a CompiledDecodeNode of specified table size that uses 564*f5c631daSSadaf Ebrahimi // bit_extract_fn to sample bits from the instruction. CreateCompiledNode(BitExtractFn bit_extract_fn,size_t table_size)565*f5c631daSSadaf Ebrahimi void CreateCompiledNode(BitExtractFn bit_extract_fn, size_t table_size) { 566*f5c631daSSadaf Ebrahimi VIXL_ASSERT(bit_extract_fn != NULL); 567*f5c631daSSadaf Ebrahimi VIXL_ASSERT(table_size > 0); 568*f5c631daSSadaf Ebrahimi compiled_node_ = new CompiledDecodeNode(bit_extract_fn, table_size); 569*f5c631daSSadaf Ebrahimi } 570*f5c631daSSadaf Ebrahimi 571*f5c631daSSadaf Ebrahimi // Create a CompiledDecodeNode wrapping a visitor function. No decoding is 572*f5c631daSSadaf Ebrahimi // required for this node; the visitor function is called instead. CreateVisitorNode()573*f5c631daSSadaf Ebrahimi void CreateVisitorNode() { 574*f5c631daSSadaf Ebrahimi compiled_node_ = new CompiledDecodeNode(instruction_name_, decoder_); 575*f5c631daSSadaf Ebrahimi } 576*f5c631daSSadaf Ebrahimi 577*f5c631daSSadaf Ebrahimi // Find and compile the DecodeNode named "name", and set it as the node for 578*f5c631daSSadaf Ebrahimi // the pattern "bits". 579*f5c631daSSadaf Ebrahimi void CompileNodeForBits(Decoder* decoder, std::string name, uint32_t bits); 580*f5c631daSSadaf Ebrahimi 581*f5c631daSSadaf Ebrahimi // Get a pointer to an instruction method that extracts the instruction bits 582*f5c631daSSadaf Ebrahimi // specified by the mask argument, and returns those sampled bits as a 583*f5c631daSSadaf Ebrahimi // contiguous sequence, suitable for indexing an array. 584*f5c631daSSadaf Ebrahimi // For example, a mask of 0b1010 returns a function that, given an instruction 585*f5c631daSSadaf Ebrahimi // 0bXYZW, will return 0bXZ. GetBitExtractFunction(uint32_t mask)586*f5c631daSSadaf Ebrahimi BitExtractFn GetBitExtractFunction(uint32_t mask) { 587*f5c631daSSadaf Ebrahimi return GetBitExtractFunctionHelper(mask, 0); 588*f5c631daSSadaf Ebrahimi } 589*f5c631daSSadaf Ebrahimi 590*f5c631daSSadaf Ebrahimi // Get a pointer to an Instruction method that applies a mask to the 591*f5c631daSSadaf Ebrahimi // instruction bits, and tests if the result is equal to value. The returned 592*f5c631daSSadaf Ebrahimi // function gives a 1 result if (inst & mask == value), 0 otherwise. GetBitExtractFunction(uint32_t mask,uint32_t value)593*f5c631daSSadaf Ebrahimi BitExtractFn GetBitExtractFunction(uint32_t mask, uint32_t value) { 594*f5c631daSSadaf Ebrahimi return GetBitExtractFunctionHelper(value, mask); 595*f5c631daSSadaf Ebrahimi } 596*f5c631daSSadaf Ebrahimi 597*f5c631daSSadaf Ebrahimi // Compile this DecodeNode into a new CompiledDecodeNode and returns a pointer 598*f5c631daSSadaf Ebrahimi // to it. This pointer is also stored inside the DecodeNode itself. Destroying 599*f5c631daSSadaf Ebrahimi // a DecodeNode frees its associated CompiledDecodeNode. 600*f5c631daSSadaf Ebrahimi CompiledDecodeNode* Compile(Decoder* decoder); 601*f5c631daSSadaf Ebrahimi 602*f5c631daSSadaf Ebrahimi // Get a pointer to the CompiledDecodeNode associated with this DecodeNode. 603*f5c631daSSadaf Ebrahimi // Returns NULL if the node has not been compiled yet. GetCompiledNode()604*f5c631daSSadaf Ebrahimi CompiledDecodeNode* GetCompiledNode() const { return compiled_node_; } IsCompiled()605*f5c631daSSadaf Ebrahimi bool IsCompiled() const { return GetCompiledNode() != NULL; } 606*f5c631daSSadaf Ebrahimi 607*f5c631daSSadaf Ebrahimi enum class PatternSymbol { kSymbol0 = 0, kSymbol1 = 1, kSymbolX = 2 }; 608*f5c631daSSadaf Ebrahimi static const uint32_t kEndOfPattern = 3; 609*f5c631daSSadaf Ebrahimi static const uint32_t kPatternSymbolMask = 3; 610*f5c631daSSadaf Ebrahimi GetPatternLength(uint32_t pattern)611*f5c631daSSadaf Ebrahimi size_t GetPatternLength(uint32_t pattern) const { 612*f5c631daSSadaf Ebrahimi uint32_t hsb = HighestSetBitPosition(pattern); 613*f5c631daSSadaf Ebrahimi // The pattern length is signified by two set bits in a two bit-aligned 614*f5c631daSSadaf Ebrahimi // position. Ensure that the pattern has a highest set bit, it's at an odd 615*f5c631daSSadaf Ebrahimi // bit position, and that the bit to the right of the hsb is also set. 616*f5c631daSSadaf Ebrahimi VIXL_ASSERT(((hsb % 2) == 1) && (pattern >> (hsb - 1)) == kEndOfPattern); 617*f5c631daSSadaf Ebrahimi return hsb / 2; 618*f5c631daSSadaf Ebrahimi } 619*f5c631daSSadaf Ebrahimi PatternContainsSymbol(uint32_t pattern,PatternSymbol symbol)620*f5c631daSSadaf Ebrahimi bool PatternContainsSymbol(uint32_t pattern, PatternSymbol symbol) const { 621*f5c631daSSadaf Ebrahimi while ((pattern & kPatternSymbolMask) != kEndOfPattern) { 622*f5c631daSSadaf Ebrahimi if (static_cast<PatternSymbol>(pattern & kPatternSymbolMask) == symbol) 623*f5c631daSSadaf Ebrahimi return true; 624*f5c631daSSadaf Ebrahimi pattern >>= 2; 625*f5c631daSSadaf Ebrahimi } 626*f5c631daSSadaf Ebrahimi return false; 627*f5c631daSSadaf Ebrahimi } 628*f5c631daSSadaf Ebrahimi GetSymbolAt(uint32_t pattern,size_t pos)629*f5c631daSSadaf Ebrahimi PatternSymbol GetSymbolAt(uint32_t pattern, size_t pos) const { 630*f5c631daSSadaf Ebrahimi size_t len = GetPatternLength(pattern); 631*f5c631daSSadaf Ebrahimi VIXL_ASSERT((pos < 15) && (pos < len)); 632*f5c631daSSadaf Ebrahimi uint32_t shift = static_cast<uint32_t>(2 * (len - pos - 1)); 633*f5c631daSSadaf Ebrahimi uint32_t sym = (pattern >> shift) & kPatternSymbolMask; 634*f5c631daSSadaf Ebrahimi return static_cast<PatternSymbol>(sym); 635*f5c631daSSadaf Ebrahimi } 636*f5c631daSSadaf Ebrahimi 637*f5c631daSSadaf Ebrahimi private: 638*f5c631daSSadaf Ebrahimi // Generate a mask and value pair from a pattern constructed from 0, 1 and x 639*f5c631daSSadaf Ebrahimi // (don't care) 2-bit symbols. 640*f5c631daSSadaf Ebrahimi // For example "10x1"_b should return mask = 0b1101, value = 0b1001. 641*f5c631daSSadaf Ebrahimi typedef std::pair<Instr, Instr> MaskValuePair; 642*f5c631daSSadaf Ebrahimi MaskValuePair GenerateMaskValuePair(uint32_t pattern) const; 643*f5c631daSSadaf Ebrahimi 644*f5c631daSSadaf Ebrahimi // Generate a pattern ordered by the bit positions sampled by this node. 645*f5c631daSSadaf Ebrahimi // The symbol corresponding to the lowest sample position is placed in the 646*f5c631daSSadaf Ebrahimi // least-significant bits of the result pattern. 647*f5c631daSSadaf Ebrahimi // For example, a pattern of "1x0"_b expected when sampling bits 31, 1 and 30 648*f5c631daSSadaf Ebrahimi // returns the pattern "x01"_b; bit 1 should be 'x', bit 30 '0' and bit 31 649*f5c631daSSadaf Ebrahimi // '1'. 650*f5c631daSSadaf Ebrahimi // This output makes comparisons easier between the pattern and bits sampled 651*f5c631daSSadaf Ebrahimi // from an instruction using the fast "compress" algorithm. See 652*f5c631daSSadaf Ebrahimi // Instruction::Compress(). 653*f5c631daSSadaf Ebrahimi uint32_t GenerateOrderedPattern(uint32_t pattern) const; 654*f5c631daSSadaf Ebrahimi 655*f5c631daSSadaf Ebrahimi // Generate a mask with a bit set at each sample position. 656*f5c631daSSadaf Ebrahimi uint32_t GenerateSampledBitsMask() const; 657*f5c631daSSadaf Ebrahimi 658*f5c631daSSadaf Ebrahimi // Try to compile a more optimised decode operation for this node, returning 659*f5c631daSSadaf Ebrahimi // true if successful. 660*f5c631daSSadaf Ebrahimi bool TryCompileOptimisedDecodeTable(Decoder* decoder); 661*f5c631daSSadaf Ebrahimi 662*f5c631daSSadaf Ebrahimi // Helper function that returns a bit extracting function. If y is zero, 663*f5c631daSSadaf Ebrahimi // x is a bit extraction mask. Otherwise, y is the mask, and x is the value 664*f5c631daSSadaf Ebrahimi // to match after masking. 665*f5c631daSSadaf Ebrahimi BitExtractFn GetBitExtractFunctionHelper(uint32_t x, uint32_t y); 666*f5c631daSSadaf Ebrahimi 667*f5c631daSSadaf Ebrahimi // Name of this decoder node, used to construct edges in the decode graph. 668*f5c631daSSadaf Ebrahimi std::string name_; 669*f5c631daSSadaf Ebrahimi 670*f5c631daSSadaf Ebrahimi // Vector of bits sampled from an instruction to determine which node to look 671*f5c631daSSadaf Ebrahimi // up next in the decode process. 672*f5c631daSSadaf Ebrahimi const std::vector<uint8_t>& sampled_bits_; 673*f5c631daSSadaf Ebrahimi static const std::vector<uint8_t> kEmptySampledBits; 674*f5c631daSSadaf Ebrahimi 675*f5c631daSSadaf Ebrahimi // For leaf nodes, this is the name of the instruction form that the node 676*f5c631daSSadaf Ebrahimi // represents. For other nodes, this is always set to "node". 677*f5c631daSSadaf Ebrahimi std::string instruction_name_; 678*f5c631daSSadaf Ebrahimi 679*f5c631daSSadaf Ebrahimi // Source mapping from bit pattern to name of next decode stage. 680*f5c631daSSadaf Ebrahimi const std::vector<DecodePattern>& pattern_table_; 681*f5c631daSSadaf Ebrahimi static const std::vector<DecodePattern> kEmptyPatternTable; 682*f5c631daSSadaf Ebrahimi 683*f5c631daSSadaf Ebrahimi // Pointer to the decoder containing this node, used to call its visitor 684*f5c631daSSadaf Ebrahimi // function for leaf nodes. 685*f5c631daSSadaf Ebrahimi Decoder* decoder_; 686*f5c631daSSadaf Ebrahimi 687*f5c631daSSadaf Ebrahimi // Pointer to the compiled version of this node. Is this node hasn't been 688*f5c631daSSadaf Ebrahimi // compiled yet, this pointer is NULL. 689*f5c631daSSadaf Ebrahimi CompiledDecodeNode* compiled_node_; 690*f5c631daSSadaf Ebrahimi }; 691*f5c631daSSadaf Ebrahimi 692*f5c631daSSadaf Ebrahimi } // namespace aarch64 693*f5c631daSSadaf Ebrahimi } // namespace vixl 694*f5c631daSSadaf Ebrahimi 695*f5c631daSSadaf Ebrahimi #endif // VIXL_AARCH64_DECODER_AARCH64_H_ 696