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