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 
13 namespace v8 {
14 namespace 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.
67 class DecoderVisitor {
68  public:
~DecoderVisitor()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.
78 class DispatchingDecoderVisitor : public DecoderVisitor {
79  public:
DispatchingDecoderVisitor()80   DispatchingDecoderVisitor() {}
~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 
122 template<typename V>
123 class Decoder : public V {
124  public:
Decoder()125   Decoder() {}
~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