1 // Copyright 2014, 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 32 #include "../globals-vixl.h" 33 34 #include "instructions-aarch64.h" 35 36 37 // List macro containing all visitors needed by the decoder class. 38 39 #define VISITOR_LIST_THAT_RETURN(V) \ 40 V(AddSubExtended) \ 41 V(AddSubImmediate) \ 42 V(AddSubShifted) \ 43 V(AddSubWithCarry) \ 44 V(AtomicMemory) \ 45 V(Bitfield) \ 46 V(CompareBranch) \ 47 V(ConditionalBranch) \ 48 V(ConditionalCompareImmediate) \ 49 V(ConditionalCompareRegister) \ 50 V(ConditionalSelect) \ 51 V(Crypto2RegSHA) \ 52 V(Crypto3RegSHA) \ 53 V(CryptoAES) \ 54 V(DataProcessing1Source) \ 55 V(DataProcessing2Source) \ 56 V(DataProcessing3Source) \ 57 V(Exception) \ 58 V(Extract) \ 59 V(FPCompare) \ 60 V(FPConditionalCompare) \ 61 V(FPConditionalSelect) \ 62 V(FPDataProcessing1Source) \ 63 V(FPDataProcessing2Source) \ 64 V(FPDataProcessing3Source) \ 65 V(FPFixedPointConvert) \ 66 V(FPImmediate) \ 67 V(FPIntegerConvert) \ 68 V(LoadLiteral) \ 69 V(LoadStoreExclusive) \ 70 V(LoadStorePairNonTemporal) \ 71 V(LoadStorePairOffset) \ 72 V(LoadStorePairPostIndex) \ 73 V(LoadStorePairPreIndex) \ 74 V(LoadStorePostIndex) \ 75 V(LoadStorePreIndex) \ 76 V(LoadStoreRegisterOffset) \ 77 V(LoadStoreUnscaledOffset) \ 78 V(LoadStoreUnsignedOffset) \ 79 V(LogicalImmediate) \ 80 V(LogicalShifted) \ 81 V(MoveWideImmediate) \ 82 V(NEON2RegMisc) \ 83 V(NEON2RegMiscFP16) \ 84 V(NEON3Different) \ 85 V(NEON3Same) \ 86 V(NEON3SameExtra) \ 87 V(NEON3SameFP16) \ 88 V(NEONAcrossLanes) \ 89 V(NEONByIndexedElement) \ 90 V(NEONCopy) \ 91 V(NEONExtract) \ 92 V(NEONLoadStoreMultiStruct) \ 93 V(NEONLoadStoreMultiStructPostIndex) \ 94 V(NEONLoadStoreSingleStruct) \ 95 V(NEONLoadStoreSingleStructPostIndex) \ 96 V(NEONModifiedImmediate) \ 97 V(NEONPerm) \ 98 V(NEONScalar2RegMisc) \ 99 V(NEONScalar2RegMiscFP16) \ 100 V(NEONScalar3Diff) \ 101 V(NEONScalar3Same) \ 102 V(NEONScalar3SameExtra) \ 103 V(NEONScalar3SameFP16) \ 104 V(NEONScalarByIndexedElement) \ 105 V(NEONScalarCopy) \ 106 V(NEONScalarPairwise) \ 107 V(NEONScalarShiftImmediate) \ 108 V(NEONShiftImmediate) \ 109 V(NEONTable) \ 110 V(PCRelAddressing) \ 111 V(System) \ 112 V(TestBranch) \ 113 V(UnconditionalBranch) \ 114 V(UnconditionalBranchToRegister) 115 116 #define VISITOR_LIST_THAT_DONT_RETURN(V) \ 117 V(Unallocated) \ 118 V(Unimplemented) 119 120 #define VISITOR_LIST(V) \ 121 VISITOR_LIST_THAT_RETURN(V) \ 122 VISITOR_LIST_THAT_DONT_RETURN(V) 123 124 namespace vixl { 125 namespace aarch64 { 126 127 // The Visitor interface. Disassembler and simulator (and other tools) 128 // must provide implementations for all of these functions. 129 class DecoderVisitor { 130 public: 131 enum VisitorConstness { kConstVisitor, kNonConstVisitor }; 132 explicit DecoderVisitor(VisitorConstness constness = kConstVisitor) constness_(constness)133 : constness_(constness) {} 134 ~DecoderVisitor()135 virtual ~DecoderVisitor() {} 136 137 #define DECLARE(A) virtual void Visit##A(const Instruction* instr) = 0; VISITOR_LIST(DECLARE)138 VISITOR_LIST(DECLARE) 139 #undef DECLARE 140 141 bool IsConstVisitor() const { return constness_ == kConstVisitor; } MutableInstruction(const Instruction * instr)142 Instruction* MutableInstruction(const Instruction* instr) { 143 VIXL_ASSERT(!IsConstVisitor()); 144 return const_cast<Instruction*>(instr); 145 } 146 147 private: 148 const VisitorConstness constness_; 149 }; 150 151 152 class Decoder { 153 public: Decoder()154 Decoder() {} 155 156 // Top-level wrappers around the actual decoding function. Decode(const Instruction * instr)157 void Decode(const Instruction* instr) { 158 std::list<DecoderVisitor*>::iterator it; 159 for (it = visitors_.begin(); it != visitors_.end(); it++) { 160 VIXL_ASSERT((*it)->IsConstVisitor()); 161 } 162 DecodeInstruction(instr); 163 } Decode(Instruction * instr)164 void Decode(Instruction* instr) { 165 DecodeInstruction(const_cast<const Instruction*>(instr)); 166 } 167 168 // Decode all instructions from start (inclusive) to end (exclusive). 169 template <typename T> Decode(T start,T end)170 void Decode(T start, T end) { 171 for (T instr = start; instr < end; instr = instr->GetNextInstruction()) { 172 Decode(instr); 173 } 174 } 175 176 // Register a new visitor class with the decoder. 177 // Decode() will call the corresponding visitor method from all registered 178 // visitor classes when decoding reaches the leaf node of the instruction 179 // decode tree. 180 // Visitors are called in order. 181 // A visitor can be registered multiple times. 182 // 183 // d.AppendVisitor(V1); 184 // d.AppendVisitor(V2); 185 // d.PrependVisitor(V2); 186 // d.AppendVisitor(V3); 187 // 188 // d.Decode(i); 189 // 190 // will call in order visitor methods in V2, V1, V2, V3. 191 void AppendVisitor(DecoderVisitor* visitor); 192 void PrependVisitor(DecoderVisitor* visitor); 193 // These helpers register `new_visitor` before or after the first instance of 194 // `registered_visiter` in the list. 195 // So if 196 // V1, V2, V1, V2 197 // are registered in this order in the decoder, calls to 198 // d.InsertVisitorAfter(V3, V1); 199 // d.InsertVisitorBefore(V4, V2); 200 // will yield the order 201 // V1, V3, V4, V2, V1, V2 202 // 203 // For more complex modifications of the order of registered visitors, one can 204 // directly access and modify the list of visitors via the `visitors()' 205 // accessor. 206 void InsertVisitorBefore(DecoderVisitor* new_visitor, 207 DecoderVisitor* registered_visitor); 208 void InsertVisitorAfter(DecoderVisitor* new_visitor, 209 DecoderVisitor* registered_visitor); 210 211 // Remove all instances of a previously registered visitor class from the list 212 // of visitors stored by the decoder. 213 void RemoveVisitor(DecoderVisitor* visitor); 214 215 #define DECLARE(A) void Visit##A(const Instruction* instr); VISITOR_LIST(DECLARE)216 VISITOR_LIST(DECLARE) 217 #undef DECLARE 218 219 220 std::list<DecoderVisitor*>* visitors() { return &visitors_; } 221 222 private: 223 // Decodes an instruction and calls the visitor functions registered with the 224 // Decoder class. 225 void DecodeInstruction(const Instruction* instr); 226 227 // Decode the PC relative addressing instruction, and call the corresponding 228 // visitors. 229 // On entry, instruction bits 27:24 = 0x0. 230 void DecodePCRelAddressing(const Instruction* instr); 231 232 // Decode the add/subtract immediate instruction, and call the correspoding 233 // visitors. 234 // On entry, instruction bits 27:24 = 0x1. 235 void DecodeAddSubImmediate(const Instruction* instr); 236 237 // Decode the branch, system command, and exception generation parts of 238 // the instruction tree, and call the corresponding visitors. 239 // On entry, instruction bits 27:24 = {0x4, 0x5, 0x6, 0x7}. 240 void DecodeBranchSystemException(const Instruction* instr); 241 242 // Decode the load and store parts of the instruction tree, and call 243 // the corresponding visitors. 244 // On entry, instruction bits 27:24 = {0x8, 0x9, 0xC, 0xD}. 245 void DecodeLoadStore(const Instruction* instr); 246 247 // Decode the logical immediate and move wide immediate parts of the 248 // instruction tree, and call the corresponding visitors. 249 // On entry, instruction bits 27:24 = 0x2. 250 void DecodeLogical(const Instruction* instr); 251 252 // Decode the bitfield and extraction parts of the instruction tree, 253 // and call the corresponding visitors. 254 // On entry, instruction bits 27:24 = 0x3. 255 void DecodeBitfieldExtract(const Instruction* instr); 256 257 // Decode the data processing parts of the instruction tree, and call the 258 // corresponding visitors. 259 // On entry, instruction bits 27:24 = {0x1, 0xA, 0xB}. 260 void DecodeDataProcessing(const Instruction* instr); 261 262 // Decode the floating point parts of the instruction tree, and call the 263 // corresponding visitors. 264 // On entry, instruction bits 27:24 = {0xE, 0xF}. 265 void DecodeFP(const Instruction* instr); 266 267 // Decode the Advanced SIMD (NEON) load/store part of the instruction tree, 268 // and call the corresponding visitors. 269 // On entry, instruction bits 29:25 = 0x6. 270 void DecodeNEONLoadStore(const Instruction* instr); 271 272 // Decode the Advanced SIMD (NEON) vector data processing part of the 273 // instruction tree, and call the corresponding visitors. 274 // On entry, instruction bits 28:25 = 0x7. 275 void DecodeNEONVectorDataProcessing(const Instruction* instr); 276 277 // Decode the Advanced SIMD (NEON) scalar data processing part of the 278 // instruction tree, and call the corresponding visitors. 279 // On entry, instruction bits 28:25 = 0xF. 280 void DecodeNEONScalarDataProcessing(const Instruction* instr); 281 282 private: 283 // Visitors are registered in a list. 284 std::list<DecoderVisitor*> visitors_; 285 }; 286 287 } // namespace aarch64 288 } // namespace vixl 289 290 #endif // VIXL_AARCH64_DECODER_AARCH64_H_ 291