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