1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_ARM64_DECODER_ARM64_H_ 6 #define V8_ARM64_DECODER_ARM64_H_ 7 8 #include <list> 9 10 #include "src/arm64/instructions-arm64.h" 11 #include "src/globals.h" 12 13 namespace v8 { 14 namespace internal { 15 16 17 // List macro containing all visitors needed by the decoder class. 18 19 #define VISITOR_LIST(V) \ 20 V(PCRelAddressing) \ 21 V(AddSubImmediate) \ 22 V(LogicalImmediate) \ 23 V(MoveWideImmediate) \ 24 V(Bitfield) \ 25 V(Extract) \ 26 V(UnconditionalBranch) \ 27 V(UnconditionalBranchToRegister) \ 28 V(CompareBranch) \ 29 V(TestBranch) \ 30 V(ConditionalBranch) \ 31 V(System) \ 32 V(Exception) \ 33 V(LoadStorePairPostIndex) \ 34 V(LoadStorePairOffset) \ 35 V(LoadStorePairPreIndex) \ 36 V(LoadLiteral) \ 37 V(LoadStoreUnscaledOffset) \ 38 V(LoadStorePostIndex) \ 39 V(LoadStorePreIndex) \ 40 V(LoadStoreRegisterOffset) \ 41 V(LoadStoreUnsignedOffset) \ 42 V(LogicalShifted) \ 43 V(AddSubShifted) \ 44 V(AddSubExtended) \ 45 V(AddSubWithCarry) \ 46 V(ConditionalCompareRegister) \ 47 V(ConditionalCompareImmediate) \ 48 V(ConditionalSelect) \ 49 V(DataProcessing1Source) \ 50 V(DataProcessing2Source) \ 51 V(DataProcessing3Source) \ 52 V(FPCompare) \ 53 V(FPConditionalCompare) \ 54 V(FPConditionalSelect) \ 55 V(FPImmediate) \ 56 V(FPDataProcessing1Source) \ 57 V(FPDataProcessing2Source) \ 58 V(FPDataProcessing3Source) \ 59 V(FPIntegerConvert) \ 60 V(FPFixedPointConvert) \ 61 V(Unallocated) \ 62 V(Unimplemented) 63 64 // The Visitor interface. Disassembler and simulator (and other tools) 65 // must provide implementations for all of these functions. 66 class DecoderVisitor { 67 public: ~DecoderVisitor()68 virtual ~DecoderVisitor() {} 69 70 #define DECLARE(A) virtual void Visit##A(Instruction* instr) = 0; 71 VISITOR_LIST(DECLARE) 72 #undef DECLARE 73 }; 74 75 76 // A visitor that dispatches to a list of visitors. 77 class DispatchingDecoderVisitor : public DecoderVisitor { 78 public: DispatchingDecoderVisitor()79 DispatchingDecoderVisitor() {} ~DispatchingDecoderVisitor()80 virtual ~DispatchingDecoderVisitor() {} 81 82 // Register a new visitor class with the decoder. 83 // Decode() will call the corresponding visitor method from all registered 84 // visitor classes when decoding reaches the leaf node of the instruction 85 // decode tree. 86 // Visitors are called in the order. 87 // A visitor can only be registered once. 88 // Registering an already registered visitor will update its position. 89 // 90 // d.AppendVisitor(V1); 91 // d.AppendVisitor(V2); 92 // d.PrependVisitor(V2); // Move V2 at the start of the list. 93 // d.InsertVisitorBefore(V3, V2); 94 // d.AppendVisitor(V4); 95 // d.AppendVisitor(V4); // No effect. 96 // 97 // d.Decode(i); 98 // 99 // will call in order visitor methods in V3, V2, V1, V4. 100 void AppendVisitor(DecoderVisitor* visitor); 101 void PrependVisitor(DecoderVisitor* visitor); 102 void InsertVisitorBefore(DecoderVisitor* new_visitor, 103 DecoderVisitor* registered_visitor); 104 void InsertVisitorAfter(DecoderVisitor* new_visitor, 105 DecoderVisitor* registered_visitor); 106 107 // Remove a previously registered visitor class from the list of visitors 108 // stored by the decoder. 109 void RemoveVisitor(DecoderVisitor* visitor); 110 111 #define DECLARE(A) void Visit##A(Instruction* instr); 112 VISITOR_LIST(DECLARE) 113 #undef DECLARE 114 115 private: 116 // Visitors are registered in a list. 117 std::list<DecoderVisitor*> visitors_; 118 }; 119 120 121 template<typename V> 122 class Decoder : public V { 123 public: Decoder()124 Decoder() {} ~Decoder()125 virtual ~Decoder() {} 126 127 // Top-level instruction decoder function. Decodes an instruction and calls 128 // the visitor functions registered with the Decoder class. 129 virtual void Decode(Instruction *instr); 130 131 private: 132 // Decode the PC relative addressing instruction, and call the corresponding 133 // visitors. 134 // On entry, instruction bits 27:24 = 0x0. 135 void DecodePCRelAddressing(Instruction* instr); 136 137 // Decode the add/subtract immediate instruction, and call the corresponding 138 // visitors. 139 // On entry, instruction bits 27:24 = 0x1. 140 void DecodeAddSubImmediate(Instruction* instr); 141 142 // Decode the branch, system command, and exception generation parts of 143 // the instruction tree, and call the corresponding visitors. 144 // On entry, instruction bits 27:24 = {0x4, 0x5, 0x6, 0x7}. 145 void DecodeBranchSystemException(Instruction* instr); 146 147 // Decode the load and store parts of the instruction tree, and call 148 // the corresponding visitors. 149 // On entry, instruction bits 27:24 = {0x8, 0x9, 0xC, 0xD}. 150 void DecodeLoadStore(Instruction* instr); 151 152 // Decode the logical immediate and move wide immediate parts of the 153 // instruction tree, and call the corresponding visitors. 154 // On entry, instruction bits 27:24 = 0x2. 155 void DecodeLogical(Instruction* instr); 156 157 // Decode the bitfield and extraction parts of the instruction tree, 158 // and call the corresponding visitors. 159 // On entry, instruction bits 27:24 = 0x3. 160 void DecodeBitfieldExtract(Instruction* instr); 161 162 // Decode the data processing parts of the instruction tree, and call the 163 // corresponding visitors. 164 // On entry, instruction bits 27:24 = {0x1, 0xA, 0xB}. 165 void DecodeDataProcessing(Instruction* instr); 166 167 // Decode the floating point parts of the instruction tree, and call the 168 // corresponding visitors. 169 // On entry, instruction bits 27:24 = {0xE, 0xF}. 170 void DecodeFP(Instruction* instr); 171 172 // Decode the Advanced SIMD (NEON) load/store part of the instruction tree, 173 // and call the corresponding visitors. 174 // On entry, instruction bits 29:25 = 0x6. 175 void DecodeAdvSIMDLoadStore(Instruction* instr); 176 177 // Decode the Advanced SIMD (NEON) data processing part of the instruction 178 // tree, and call the corresponding visitors. 179 // On entry, instruction bits 27:25 = 0x7. 180 void DecodeAdvSIMDDataProcessing(Instruction* instr); 181 }; 182 183 184 } // namespace internal 185 } // namespace v8 186 187 #endif // V8_ARM64_DECODER_ARM64_H_ 188