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