Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 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 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame] | 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(LoadStoreAcquireRelease) \ |
| 43 | V(LogicalShifted) \ |
| 44 | V(AddSubShifted) \ |
| 45 | V(AddSubExtended) \ |
| 46 | V(AddSubWithCarry) \ |
| 47 | V(ConditionalCompareRegister) \ |
| 48 | V(ConditionalCompareImmediate) \ |
| 49 | V(ConditionalSelect) \ |
| 50 | V(DataProcessing1Source) \ |
| 51 | V(DataProcessing2Source) \ |
| 52 | V(DataProcessing3Source) \ |
| 53 | V(FPCompare) \ |
| 54 | V(FPConditionalCompare) \ |
| 55 | V(FPConditionalSelect) \ |
| 56 | V(FPImmediate) \ |
| 57 | V(FPDataProcessing1Source) \ |
| 58 | V(FPDataProcessing2Source) \ |
| 59 | V(FPDataProcessing3Source) \ |
| 60 | V(FPIntegerConvert) \ |
| 61 | V(FPFixedPointConvert) \ |
| 62 | V(Unallocated) \ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 63 | V(Unimplemented) |
| 64 | |
| 65 | // The Visitor interface. Disassembler and simulator (and other tools) |
| 66 | // must provide implementations for all of these functions. |
| 67 | class DecoderVisitor { |
| 68 | public: |
| 69 | virtual ~DecoderVisitor() {} |
| 70 | |
| 71 | #define DECLARE(A) virtual void Visit##A(Instruction* instr) = 0; |
| 72 | VISITOR_LIST(DECLARE) |
| 73 | #undef DECLARE |
| 74 | }; |
| 75 | |
| 76 | |
| 77 | // A visitor that dispatches to a list of visitors. |
| 78 | class DispatchingDecoderVisitor : public DecoderVisitor { |
| 79 | public: |
| 80 | DispatchingDecoderVisitor() {} |
| 81 | virtual ~DispatchingDecoderVisitor() {} |
| 82 | |
| 83 | // Register a new visitor class with the decoder. |
| 84 | // Decode() will call the corresponding visitor method from all registered |
| 85 | // visitor classes when decoding reaches the leaf node of the instruction |
| 86 | // decode tree. |
| 87 | // Visitors are called in the order. |
| 88 | // A visitor can only be registered once. |
| 89 | // Registering an already registered visitor will update its position. |
| 90 | // |
| 91 | // d.AppendVisitor(V1); |
| 92 | // d.AppendVisitor(V2); |
| 93 | // d.PrependVisitor(V2); // Move V2 at the start of the list. |
| 94 | // d.InsertVisitorBefore(V3, V2); |
| 95 | // d.AppendVisitor(V4); |
| 96 | // d.AppendVisitor(V4); // No effect. |
| 97 | // |
| 98 | // d.Decode(i); |
| 99 | // |
| 100 | // will call in order visitor methods in V3, V2, V1, V4. |
| 101 | void AppendVisitor(DecoderVisitor* visitor); |
| 102 | void PrependVisitor(DecoderVisitor* visitor); |
| 103 | void InsertVisitorBefore(DecoderVisitor* new_visitor, |
| 104 | DecoderVisitor* registered_visitor); |
| 105 | void InsertVisitorAfter(DecoderVisitor* new_visitor, |
| 106 | DecoderVisitor* registered_visitor); |
| 107 | |
| 108 | // Remove a previously registered visitor class from the list of visitors |
| 109 | // stored by the decoder. |
| 110 | void RemoveVisitor(DecoderVisitor* visitor); |
| 111 | |
| 112 | #define DECLARE(A) void Visit##A(Instruction* instr); |
| 113 | VISITOR_LIST(DECLARE) |
| 114 | #undef DECLARE |
| 115 | |
| 116 | private: |
| 117 | // Visitors are registered in a list. |
| 118 | std::list<DecoderVisitor*> visitors_; |
| 119 | }; |
| 120 | |
| 121 | |
| 122 | template<typename V> |
| 123 | class Decoder : public V { |
| 124 | public: |
| 125 | Decoder() {} |
| 126 | virtual ~Decoder() {} |
| 127 | |
| 128 | // Top-level instruction decoder function. Decodes an instruction and calls |
| 129 | // the visitor functions registered with the Decoder class. |
| 130 | virtual void Decode(Instruction *instr); |
| 131 | |
| 132 | private: |
| 133 | // Decode the PC relative addressing instruction, and call the corresponding |
| 134 | // visitors. |
| 135 | // On entry, instruction bits 27:24 = 0x0. |
| 136 | void DecodePCRelAddressing(Instruction* instr); |
| 137 | |
| 138 | // Decode the add/subtract immediate instruction, and call the corresponding |
| 139 | // visitors. |
| 140 | // On entry, instruction bits 27:24 = 0x1. |
| 141 | void DecodeAddSubImmediate(Instruction* instr); |
| 142 | |
| 143 | // Decode the branch, system command, and exception generation parts of |
| 144 | // the instruction tree, and call the corresponding visitors. |
| 145 | // On entry, instruction bits 27:24 = {0x4, 0x5, 0x6, 0x7}. |
| 146 | void DecodeBranchSystemException(Instruction* instr); |
| 147 | |
| 148 | // Decode the load and store parts of the instruction tree, and call |
| 149 | // the corresponding visitors. |
| 150 | // On entry, instruction bits 27:24 = {0x8, 0x9, 0xC, 0xD}. |
| 151 | void DecodeLoadStore(Instruction* instr); |
| 152 | |
| 153 | // Decode the logical immediate and move wide immediate parts of the |
| 154 | // instruction tree, and call the corresponding visitors. |
| 155 | // On entry, instruction bits 27:24 = 0x2. |
| 156 | void DecodeLogical(Instruction* instr); |
| 157 | |
| 158 | // Decode the bitfield and extraction parts of the instruction tree, |
| 159 | // and call the corresponding visitors. |
| 160 | // On entry, instruction bits 27:24 = 0x3. |
| 161 | void DecodeBitfieldExtract(Instruction* instr); |
| 162 | |
| 163 | // Decode the data processing parts of the instruction tree, and call the |
| 164 | // corresponding visitors. |
| 165 | // On entry, instruction bits 27:24 = {0x1, 0xA, 0xB}. |
| 166 | void DecodeDataProcessing(Instruction* instr); |
| 167 | |
| 168 | // Decode the floating point parts of the instruction tree, and call the |
| 169 | // corresponding visitors. |
| 170 | // On entry, instruction bits 27:24 = {0xE, 0xF}. |
| 171 | void DecodeFP(Instruction* instr); |
| 172 | |
| 173 | // Decode the Advanced SIMD (NEON) load/store part of the instruction tree, |
| 174 | // and call the corresponding visitors. |
| 175 | // On entry, instruction bits 29:25 = 0x6. |
| 176 | void DecodeAdvSIMDLoadStore(Instruction* instr); |
| 177 | |
| 178 | // Decode the Advanced SIMD (NEON) data processing part of the instruction |
| 179 | // tree, and call the corresponding visitors. |
| 180 | // On entry, instruction bits 27:25 = 0x7. |
| 181 | void DecodeAdvSIMDDataProcessing(Instruction* instr); |
| 182 | }; |
| 183 | |
| 184 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 185 | } // namespace internal |
| 186 | } // namespace v8 |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 187 | |
| 188 | #endif // V8_ARM64_DECODER_ARM64_H_ |