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(Exception) \ 60 V(Extract) \ 61 V(EvaluateIntoFlags) \ 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(System) \ 118 V(TestBranch) \ 119 V(UnconditionalBranch) \ 120 V(UnconditionalBranchToRegister) 121 122 // TODO: We shouldn't expose debug-only behaviour like this. Instead, we should 123 // use release-mode aborts where appropriate, and merge thse into a single 124 // no-return list. 125 #define VISITOR_LIST_THAT_DONT_RETURN_IN_DEBUG_MODE(V) \ 126 V(Unallocated) \ 127 V(Unimplemented) 128 129 #define VISITOR_LIST_THAT_DONT_RETURN(V) V(Reserved) 130 131 #define VISITOR_LIST(V) \ 132 VISITOR_LIST_THAT_RETURN(V) \ 133 VISITOR_LIST_THAT_DONT_RETURN_IN_DEBUG_MODE(V) \ 134 VISITOR_LIST_THAT_DONT_RETURN(V) 135 136 namespace vixl { 137 namespace aarch64 { 138 139 // The Visitor interface. Disassembler and simulator (and other tools) 140 // must provide implementations for all of these functions. 141 class DecoderVisitor { 142 public: 143 enum VisitorConstness { kConstVisitor, kNonConstVisitor }; 144 explicit DecoderVisitor(VisitorConstness constness = kConstVisitor) constness_(constness)145 : constness_(constness) {} 146 ~DecoderVisitor()147 virtual ~DecoderVisitor() {} 148 149 #define DECLARE(A) virtual void Visit##A(const Instruction* instr) = 0; VISITOR_LIST(DECLARE)150 VISITOR_LIST(DECLARE) 151 #undef DECLARE 152 153 bool IsConstVisitor() const { return constness_ == kConstVisitor; } MutableInstruction(const Instruction * instr)154 Instruction* MutableInstruction(const Instruction* instr) { 155 VIXL_ASSERT(!IsConstVisitor()); 156 return const_cast<Instruction*>(instr); 157 } 158 159 private: 160 const VisitorConstness constness_; 161 }; 162 163 class DecodeNode; 164 class CompiledDecodeNode; 165 166 // The instruction decoder is constructed from a graph of decode nodes. At each 167 // node, a number of bits are sampled from the instruction being decoded. The 168 // resulting value is used to look up the next node in the graph, which then 169 // samples other bits, and moves to other decode nodes. Eventually, a visitor 170 // node is reached, and the corresponding visitor function is called, which 171 // handles the instruction. 172 class Decoder { 173 public: Decoder()174 Decoder() { ConstructDecodeGraph(); } 175 176 // Top-level wrappers around the actual decoding function. 177 void Decode(const Instruction* instr); 178 void Decode(Instruction* instr); 179 180 // Decode all instructions from start (inclusive) to end (exclusive). 181 template <typename T> Decode(T start,T end)182 void Decode(T start, T end) { 183 for (T instr = start; instr < end; instr = instr->GetNextInstruction()) { 184 Decode(instr); 185 } 186 } 187 188 // Register a new visitor class with the decoder. 189 // Decode() will call the corresponding visitor method from all registered 190 // visitor classes when decoding reaches the leaf node of the instruction 191 // decode tree. 192 // Visitors are called in order. 193 // A visitor can be registered multiple times. 194 // 195 // d.AppendVisitor(V1); 196 // d.AppendVisitor(V2); 197 // d.PrependVisitor(V2); 198 // d.AppendVisitor(V3); 199 // 200 // d.Decode(i); 201 // 202 // will call in order visitor methods in V2, V1, V2, V3. 203 void AppendVisitor(DecoderVisitor* visitor); 204 void PrependVisitor(DecoderVisitor* visitor); 205 // These helpers register `new_visitor` before or after the first instance of 206 // `registered_visiter` in the list. 207 // So if 208 // V1, V2, V1, V2 209 // are registered in this order in the decoder, calls to 210 // d.InsertVisitorAfter(V3, V1); 211 // d.InsertVisitorBefore(V4, V2); 212 // will yield the order 213 // V1, V3, V4, V2, V1, V2 214 // 215 // For more complex modifications of the order of registered visitors, one can 216 // directly access and modify the list of visitors via the `visitors()' 217 // accessor. 218 void InsertVisitorBefore(DecoderVisitor* new_visitor, 219 DecoderVisitor* registered_visitor); 220 void InsertVisitorAfter(DecoderVisitor* new_visitor, 221 DecoderVisitor* registered_visitor); 222 223 // Remove all instances of a previously registered visitor class from the list 224 // of visitors stored by the decoder. 225 void RemoveVisitor(DecoderVisitor* visitor); 226 227 #define DECLARE(A) void Visit##A(const Instruction* instr); VISITOR_LIST(DECLARE)228 VISITOR_LIST(DECLARE) 229 #undef DECLARE 230 231 std::list<DecoderVisitor*>* visitors() { return &visitors_; } 232 233 // Get a DecodeNode by name from the Decoder's map. 234 DecodeNode* GetDecodeNode(std::string name); 235 236 private: 237 // Decodes an instruction and calls the visitor functions registered with the 238 // Decoder class. 239 void DecodeInstruction(const Instruction* instr); 240 241 // Add an initialised DecodeNode to the decode_node_ map. 242 void AddDecodeNode(const DecodeNode& node); 243 244 // Visitors are registered in a list. 245 std::list<DecoderVisitor*> visitors_; 246 247 // Compile the dynamically generated decode graph based on the static 248 // information in kDecodeMapping and kVisitorNodes. 249 void ConstructDecodeGraph(); 250 251 // Root node for the compiled decoder graph, stored here to avoid a map lookup 252 // for every instruction decoded. 253 CompiledDecodeNode* compiled_decoder_root_; 254 255 // Map of node names to DecodeNodes. 256 std::map<std::string, DecodeNode> decode_nodes_; 257 }; 258 259 const int kMaxDecodeSampledBits = 16; 260 const int kMaxDecodeMappings = 22; 261 typedef void (Decoder::*DecodeFnPtr)(const Instruction*); 262 typedef uint32_t (Instruction::*BitExtractFn)(void) const; 263 264 // A Visitor node maps the name of a visitor to the function that handles it. 265 struct VisitorNode { 266 const char* name; 267 const DecodeFnPtr visitor_fn; 268 }; 269 270 // DecodePattern and DecodeMapping represent the input data to the decoder 271 // compilation stage. After compilation, the decoder is embodied in the graph 272 // of CompiledDecodeNodes pointer to by compiled_decoder_root_. 273 274 // A DecodePattern maps a pattern of set/unset/don't care (1, 0, x) bits as a 275 // string to the name of its handler. 276 struct DecodePattern { 277 const char* pattern; 278 const char* handler; 279 }; 280 281 // A DecodeMapping consists of the name of a handler, the bits sampled in the 282 // instruction by that handler, and a mapping from the pattern that those 283 // sampled bits match to the corresponding name of a node. 284 struct DecodeMapping { 285 const char* name; 286 const uint8_t sampled_bits[kMaxDecodeSampledBits]; 287 const DecodePattern mapping[kMaxDecodeMappings]; 288 }; 289 290 // For speed, before nodes can be used for decoding instructions, they must 291 // be compiled. This converts the mapping "bit pattern strings to decoder name 292 // string" stored in DecodeNodes to an array look up for the pointer to the next 293 // node, stored in CompiledDecodeNodes. Compilation may also apply other 294 // optimisations for simple decode patterns. 295 class CompiledDecodeNode { 296 public: 297 // Constructor for decode node, containing a decode table and pointer to a 298 // function that extracts the bits to be sampled. CompiledDecodeNode(BitExtractFn bit_extract_fn,size_t decode_table_size)299 CompiledDecodeNode(BitExtractFn bit_extract_fn, size_t decode_table_size) 300 : bit_extract_fn_(bit_extract_fn), 301 visitor_fn_(NULL), 302 decode_table_size_(decode_table_size), 303 decoder_(NULL) { 304 decode_table_ = new CompiledDecodeNode*[decode_table_size_]; 305 memset(decode_table_, 0, decode_table_size_ * sizeof(decode_table_[0])); 306 } 307 308 // Constructor for wrappers around visitor functions. These require no 309 // decoding, so no bit extraction function or decode table is assigned. CompiledDecodeNode(DecodeFnPtr visitor_fn,Decoder * decoder)310 explicit CompiledDecodeNode(DecodeFnPtr visitor_fn, Decoder* decoder) 311 : bit_extract_fn_(NULL), 312 visitor_fn_(visitor_fn), 313 decode_table_(NULL), 314 decode_table_size_(0), 315 decoder_(decoder) {} 316 ~CompiledDecodeNode()317 ~CompiledDecodeNode() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION { 318 // Free the decode table, if this is a compiled, non-leaf node. 319 if (decode_table_ != NULL) { 320 VIXL_ASSERT(!IsLeafNode()); 321 delete[] decode_table_; 322 } 323 } 324 325 // Decode the instruction by either sampling the bits using the bit extract 326 // function to find the next node, or, if we're at a leaf, calling the visitor 327 // function. 328 void Decode(const Instruction* instr) const; 329 330 // A leaf node is a wrapper for a visitor function. IsLeafNode()331 bool IsLeafNode() const { 332 VIXL_ASSERT(((visitor_fn_ == NULL) && (bit_extract_fn_ != NULL)) || 333 ((visitor_fn_ != NULL) && (bit_extract_fn_ == NULL))); 334 return visitor_fn_ != NULL; 335 } 336 337 // Get a pointer to the next node required in the decode process, based on the 338 // bits sampled by the current node. GetNodeForBits(uint32_t bits)339 CompiledDecodeNode* GetNodeForBits(uint32_t bits) const { 340 VIXL_ASSERT(bits < decode_table_size_); 341 return decode_table_[bits]; 342 } 343 344 // Set the next node in the decode process for the pattern of sampled bits in 345 // the current node. SetNodeForBits(uint32_t bits,CompiledDecodeNode * n)346 void SetNodeForBits(uint32_t bits, CompiledDecodeNode* n) { 347 VIXL_ASSERT(bits < decode_table_size_); 348 VIXL_ASSERT(n != NULL); 349 decode_table_[bits] = n; 350 } 351 352 private: 353 // Pointer to an instantiated template function for extracting the bits 354 // sampled by this node. Set to NULL for leaf nodes. 355 const BitExtractFn bit_extract_fn_; 356 357 // Visitor function that handles the instruction identified. Set only for 358 // leaf nodes, where no extra decoding is required, otherwise NULL. 359 const DecodeFnPtr visitor_fn_; 360 361 // Mapping table from instruction bits to next decode stage. 362 CompiledDecodeNode** decode_table_; 363 const size_t decode_table_size_; 364 365 // Pointer to the decoder containing this node, used to call its visitor 366 // function for leaf nodes. Set to NULL for non-leaf nodes. 367 Decoder* decoder_; 368 }; 369 370 class DecodeNode { 371 public: 372 // Default constructor needed for map initialisation. DecodeNode()373 DecodeNode() : compiled_node_(NULL) {} 374 375 // Constructor for DecodeNode wrappers around visitor functions. These are 376 // marked as "compiled", as there is no decoding left to do. DecodeNode(const VisitorNode & visitor,Decoder * decoder)377 explicit DecodeNode(const VisitorNode& visitor, Decoder* decoder) 378 : name_(visitor.name), 379 visitor_fn_(visitor.visitor_fn), 380 decoder_(decoder), 381 compiled_node_(NULL) {} 382 383 // Constructor for DecodeNodes that map bit patterns to other DecodeNodes. 384 explicit DecodeNode(const DecodeMapping& map, Decoder* decoder = NULL) 385 : name_(map.name), 386 visitor_fn_(NULL), 387 decoder_(decoder), 388 compiled_node_(NULL) { 389 // The length of the bit string in the first mapping determines the number 390 // of sampled bits. When adding patterns later, we assert that all mappings 391 // sample the same number of bits. 392 VIXL_CHECK(strcmp(map.mapping[0].pattern, "otherwise") != 0); 393 int bit_count = static_cast<int>(strlen(map.mapping[0].pattern)); 394 VIXL_CHECK((bit_count > 0) && (bit_count <= 32)); 395 SetSampledBits(map.sampled_bits, bit_count); 396 AddPatterns(map.mapping); 397 } 398 ~DecodeNode()399 ~DecodeNode() { 400 // Delete the compiled version of this node, if one was created. 401 if (compiled_node_ != NULL) { 402 delete compiled_node_; 403 } 404 } 405 406 // Set the bits sampled from the instruction by this node. 407 void SetSampledBits(const uint8_t* bits, int bit_count); 408 409 // Get the bits sampled from the instruction by this node. 410 std::vector<uint8_t> GetSampledBits() const; 411 412 // Get the number of bits sampled from the instruction by this node. 413 size_t GetSampledBitsCount() const; 414 415 // Add patterns to this node's internal pattern table. 416 void AddPatterns(const DecodePattern* patterns); 417 418 // A leaf node is a DecodeNode that wraps the visitor function for the 419 // identified instruction class. IsLeafNode()420 bool IsLeafNode() const { return visitor_fn_ != NULL; } 421 GetName()422 std::string GetName() const { return name_; } 423 424 // Create a CompiledDecodeNode of specified table size that uses 425 // bit_extract_fn to sample bits from the instruction. CreateCompiledNode(BitExtractFn bit_extract_fn,size_t table_size)426 void CreateCompiledNode(BitExtractFn bit_extract_fn, size_t table_size) { 427 VIXL_ASSERT(bit_extract_fn != NULL); 428 VIXL_ASSERT(table_size > 0); 429 compiled_node_ = new CompiledDecodeNode(bit_extract_fn, table_size); 430 } 431 432 // Create a CompiledDecodeNode wrapping a visitor function. No decoding is 433 // required for this node; the visitor function is called instead. CreateVisitorNode()434 void CreateVisitorNode() { 435 compiled_node_ = new CompiledDecodeNode(visitor_fn_, decoder_); 436 } 437 438 // Find and compile the DecodeNode named "name", and set it as the node for 439 // the pattern "bits". 440 void CompileNodeForBits(Decoder* decoder, std::string name, uint32_t bits); 441 442 // Get a pointer to an instruction method that extracts the instruction bits 443 // specified by the mask argument, and returns those sampled bits as a 444 // contiguous sequence, suitable for indexing an array. 445 // For example, a mask of 0b1010 returns a function that, given an instruction 446 // 0bXYZW, will return 0bXZ. 447 BitExtractFn GetBitExtractFunction(uint32_t mask); 448 449 // Get a pointer to an Instruction method that applies a mask to the 450 // instruction bits, and tests if the result is equal to value. The returned 451 // function gives a 1 result if (inst & mask == value), 0 otherwise. 452 BitExtractFn GetBitExtractFunction(uint32_t mask, uint32_t value); 453 454 // Compile this DecodeNode into a new CompiledDecodeNode and returns a pointer 455 // to it. This pointer is also stored inside the DecodeNode itself. Destroying 456 // a DecodeNode frees its associated CompiledDecodeNode. 457 CompiledDecodeNode* Compile(Decoder* decoder); 458 459 // Get a pointer to the CompiledDecodeNode associated with this DecodeNode. 460 // Returns NULL if the node has not been compiled yet. GetCompiledNode()461 CompiledDecodeNode* GetCompiledNode() const { return compiled_node_; } IsCompiled()462 bool IsCompiled() const { return GetCompiledNode() != NULL; } 463 464 private: 465 // Generate a mask and value pair from a string constructed from 0, 1 and x 466 // (don't care) characters. 467 // For example "10x1" should return mask = 0b1101, value = 0b1001. 468 typedef std::pair<Instr, Instr> MaskValuePair; 469 MaskValuePair GenerateMaskValuePair(std::string pattern) const; 470 471 // Generate a pattern string ordered by the bit positions sampled by this 472 // node. The first character in the string corresponds to the lowest sampled 473 // bit. 474 // For example, a pattern of "1x0" expected when sampling bits 31, 1 and 30 475 // returns the pattern "x01"; bit 1 should be 'x', bit 30 '0' and bit 31 '1'. 476 // This output makes comparisons easier between the pattern and bits sampled 477 // from an instruction using the fast "compress" algorithm. See 478 // Instruction::Compress(). 479 std::string GenerateOrderedPattern(std::string pattern) const; 480 481 // Generate a mask with a bit set at each sample position. 482 uint32_t GenerateSampledBitsMask() const; 483 484 // Try to compile a more optimised decode operation for this node, returning 485 // true if successful. 486 bool TryCompileOptimisedDecodeTable(Decoder* decoder); 487 488 // Name of this decoder node, used to construct edges in the decode graph. 489 std::string name_; 490 491 // Vector of bits sampled from an instruction to determine which node to look 492 // up next in the decode process. 493 std::vector<uint8_t> sampled_bits_; 494 495 // Visitor function that handles the instruction identified. Set only for leaf 496 // nodes, where no extra decoding is required. For non-leaf decoding nodes, 497 // this pointer is NULL. 498 DecodeFnPtr visitor_fn_; 499 500 // Source mapping from bit pattern to name of next decode stage. 501 std::vector<DecodePattern> pattern_table_; 502 503 // Pointer to the decoder containing this node, used to call its visitor 504 // function for leaf nodes. 505 Decoder* decoder_; 506 507 // Pointer to the compiled version of this node. Is this node hasn't been 508 // compiled yet, this pointer is NULL. 509 CompiledDecodeNode* compiled_node_; 510 }; 511 512 } // namespace aarch64 513 } // namespace vixl 514 515 #endif // VIXL_AARCH64_DECODER_AARCH64_H_ 516