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