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