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