• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019, VIXL authors
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #ifndef VIXL_AARCH64_DECODER_AARCH64_H_
28 #define VIXL_AARCH64_DECODER_AARCH64_H_
29 
30 #include <list>
31 #include <map>
32 #include <string>
33 
34 #include "../globals-vixl.h"
35 
36 #include "instructions-aarch64.h"
37 
38 
39 // List macro containing all visitors needed by the decoder class.
40 
41 #define VISITOR_LIST_THAT_RETURN(V)                              \
42   V(AddSubExtended)                                              \
43   V(AddSubImmediate)                                             \
44   V(AddSubShifted)                                               \
45   V(AddSubWithCarry)                                             \
46   V(AtomicMemory)                                                \
47   V(Bitfield)                                                    \
48   V(CompareBranch)                                               \
49   V(ConditionalBranch)                                           \
50   V(ConditionalCompareImmediate)                                 \
51   V(ConditionalCompareRegister)                                  \
52   V(ConditionalSelect)                                           \
53   V(Crypto2RegSHA)                                               \
54   V(Crypto3RegSHA)                                               \
55   V(CryptoAES)                                                   \
56   V(DataProcessing1Source)                                       \
57   V(DataProcessing2Source)                                       \
58   V(DataProcessing3Source)                                       \
59   V(EvaluateIntoFlags)                                           \
60   V(Exception)                                                   \
61   V(Extract)                                                     \
62   V(FPCompare)                                                   \
63   V(FPConditionalCompare)                                        \
64   V(FPConditionalSelect)                                         \
65   V(FPDataProcessing1Source)                                     \
66   V(FPDataProcessing2Source)                                     \
67   V(FPDataProcessing3Source)                                     \
68   V(FPFixedPointConvert)                                         \
69   V(FPImmediate)                                                 \
70   V(FPIntegerConvert)                                            \
71   V(LoadLiteral)                                                 \
72   V(LoadStoreExclusive)                                          \
73   V(LoadStorePAC)                                                \
74   V(LoadStorePairNonTemporal)                                    \
75   V(LoadStorePairOffset)                                         \
76   V(LoadStorePairPostIndex)                                      \
77   V(LoadStorePairPreIndex)                                       \
78   V(LoadStorePostIndex)                                          \
79   V(LoadStorePreIndex)                                           \
80   V(LoadStoreRCpcUnscaledOffset)                                 \
81   V(LoadStoreRegisterOffset)                                     \
82   V(LoadStoreUnscaledOffset)                                     \
83   V(LoadStoreUnsignedOffset)                                     \
84   V(LogicalImmediate)                                            \
85   V(LogicalShifted)                                              \
86   V(MoveWideImmediate)                                           \
87   V(NEON2RegMisc)                                                \
88   V(NEON2RegMiscFP16)                                            \
89   V(NEON3Different)                                              \
90   V(NEON3Same)                                                   \
91   V(NEON3SameExtra)                                              \
92   V(NEON3SameFP16)                                               \
93   V(NEONAcrossLanes)                                             \
94   V(NEONByIndexedElement)                                        \
95   V(NEONCopy)                                                    \
96   V(NEONExtract)                                                 \
97   V(NEONLoadStoreMultiStruct)                                    \
98   V(NEONLoadStoreMultiStructPostIndex)                           \
99   V(NEONLoadStoreSingleStruct)                                   \
100   V(NEONLoadStoreSingleStructPostIndex)                          \
101   V(NEONModifiedImmediate)                                       \
102   V(NEONPerm)                                                    \
103   V(NEONScalar2RegMisc)                                          \
104   V(NEONScalar2RegMiscFP16)                                      \
105   V(NEONScalar3Diff)                                             \
106   V(NEONScalar3Same)                                             \
107   V(NEONScalar3SameExtra)                                        \
108   V(NEONScalar3SameFP16)                                         \
109   V(NEONScalarByIndexedElement)                                  \
110   V(NEONScalarCopy)                                              \
111   V(NEONScalarPairwise)                                          \
112   V(NEONScalarShiftImmediate)                                    \
113   V(NEONShiftImmediate)                                          \
114   V(NEONTable)                                                   \
115   V(PCRelAddressing)                                             \
116   V(RotateRightIntoFlags)                                        \
117   V(SVE32BitGatherLoad_ScalarPlus32BitUnscaledOffsets)           \
118   V(SVE32BitGatherLoad_VectorPlusImm)                            \
119   V(SVE32BitGatherLoadHalfwords_ScalarPlus32BitScaledOffsets)    \
120   V(SVE32BitGatherLoadWords_ScalarPlus32BitScaledOffsets)        \
121   V(SVE32BitGatherPrefetch_ScalarPlus32BitScaledOffsets)         \
122   V(SVE32BitGatherPrefetch_VectorPlusImm)                        \
123   V(SVE32BitScatterStore_ScalarPlus32BitScaledOffsets)           \
124   V(SVE32BitScatterStore_ScalarPlus32BitUnscaledOffsets)         \
125   V(SVE32BitScatterStore_VectorPlusImm)                          \
126   V(SVE64BitGatherLoad_ScalarPlus32BitUnpackedScaledOffsets)     \
127   V(SVE64BitGatherLoad_ScalarPlus64BitScaledOffsets)             \
128   V(SVE64BitGatherLoad_ScalarPlus64BitUnscaledOffsets)           \
129   V(SVE64BitGatherLoad_ScalarPlusUnpacked32BitUnscaledOffsets)   \
130   V(SVE64BitGatherLoad_VectorPlusImm)                            \
131   V(SVE64BitGatherPrefetch_ScalarPlus64BitScaledOffsets)         \
132   V(SVE64BitGatherPrefetch_ScalarPlusUnpacked32BitScaledOffsets) \
133   V(SVE64BitGatherPrefetch_VectorPlusImm)                        \
134   V(SVE64BitScatterStore_ScalarPlus64BitScaledOffsets)           \
135   V(SVE64BitScatterStore_ScalarPlus64BitUnscaledOffsets)         \
136   V(SVE64BitScatterStore_ScalarPlusUnpacked32BitScaledOffsets)   \
137   V(SVE64BitScatterStore_ScalarPlusUnpacked32BitUnscaledOffsets) \
138   V(SVE64BitScatterStore_VectorPlusImm)                          \
139   V(SVEAddressGeneration)                                        \
140   V(SVEBitwiseLogicalUnpredicated)                               \
141   V(SVEBitwiseShiftUnpredicated)                                 \
142   V(SVEFFRInitialise)                                            \
143   V(SVEFFRWriteFromPredicate)                                    \
144   V(SVEFPAccumulatingReduction)                                  \
145   V(SVEFPArithmeticUnpredicated)                                 \
146   V(SVEFPCompareVectors)                                         \
147   V(SVEFPCompareWithZero)                                        \
148   V(SVEFPComplexAddition)                                        \
149   V(SVEFPComplexMulAdd)                                          \
150   V(SVEFPComplexMulAddIndex)                                     \
151   V(SVEFPFastReduction)                                          \
152   V(SVEFPMulIndex)                                               \
153   V(SVEFPMulAdd)                                                 \
154   V(SVEFPMulAddIndex)                                            \
155   V(SVEFPUnaryOpUnpredicated)                                    \
156   V(SVEIncDecByPredicateCount)                                   \
157   V(SVEIndexGeneration)                                          \
158   V(SVEIntArithmeticUnpredicated)                                \
159   V(SVEIntCompareSignedImm)                                      \
160   V(SVEIntCompareUnsignedImm)                                    \
161   V(SVEIntCompareVectors)                                        \
162   V(SVEIntMulAddPredicated)                                      \
163   V(SVEIntMulAddUnpredicated)                                    \
164   V(SVEIntReduction)                                             \
165   V(SVEIntUnaryArithmeticPredicated)                             \
166   V(SVEMovprfx)                                                  \
167   V(SVEMulIndex)                                                 \
168   V(SVEPermuteVectorExtract)                                     \
169   V(SVEPermuteVectorInterleaving)                                \
170   V(SVEPredicateCount)                                           \
171   V(SVEPredicateLogical)                                         \
172   V(SVEPropagateBreak)                                           \
173   V(SVEStackFrameAdjustment)                                     \
174   V(SVEStackFrameSize)                                           \
175   V(SVEVectorSelect)                                             \
176   V(SVEBitwiseLogical_Predicated)                                \
177   V(SVEBitwiseLogicalWithImm_Unpredicated)                       \
178   V(SVEBitwiseShiftByImm_Predicated)                             \
179   V(SVEBitwiseShiftByVector_Predicated)                          \
180   V(SVEBitwiseShiftByWideElements_Predicated)                    \
181   V(SVEBroadcastBitmaskImm)                                      \
182   V(SVEBroadcastFPImm_Unpredicated)                              \
183   V(SVEBroadcastGeneralRegister)                                 \
184   V(SVEBroadcastIndexElement)                                    \
185   V(SVEBroadcastIntImm_Unpredicated)                             \
186   V(SVECompressActiveElements)                                   \
187   V(SVEConditionallyBroadcastElementToVector)                    \
188   V(SVEConditionallyExtractElementToSIMDFPScalar)                \
189   V(SVEConditionallyExtractElementToGeneralRegister)             \
190   V(SVEConditionallyTerminateScalars)                            \
191   V(SVEConstructivePrefix_Unpredicated)                          \
192   V(SVEContiguousFirstFaultLoad_ScalarPlusScalar)                \
193   V(SVEContiguousLoad_ScalarPlusImm)                             \
194   V(SVEContiguousLoad_ScalarPlusScalar)                          \
195   V(SVEContiguousNonFaultLoad_ScalarPlusImm)                     \
196   V(SVEContiguousNonTemporalLoad_ScalarPlusImm)                  \
197   V(SVEContiguousNonTemporalLoad_ScalarPlusScalar)               \
198   V(SVEContiguousNonTemporalStore_ScalarPlusImm)                 \
199   V(SVEContiguousNonTemporalStore_ScalarPlusScalar)              \
200   V(SVEContiguousPrefetch_ScalarPlusImm)                         \
201   V(SVEContiguousPrefetch_ScalarPlusScalar)                      \
202   V(SVEContiguousStore_ScalarPlusImm)                            \
203   V(SVEContiguousStore_ScalarPlusScalar)                         \
204   V(SVECopySIMDFPScalarRegisterToVector_Predicated)              \
205   V(SVECopyFPImm_Predicated)                                     \
206   V(SVECopyGeneralRegisterToVector_Predicated)                   \
207   V(SVECopyIntImm_Predicated)                                    \
208   V(SVEElementCount)                                             \
209   V(SVEExtractElementToSIMDFPScalarRegister)                     \
210   V(SVEExtractElementToGeneralRegister)                          \
211   V(SVEFPArithmetic_Predicated)                                  \
212   V(SVEFPArithmeticWithImm_Predicated)                           \
213   V(SVEFPConvertPrecision)                                       \
214   V(SVEFPConvertToInt)                                           \
215   V(SVEFPExponentialAccelerator)                                 \
216   V(SVEFPRoundToIntegralValue)                                   \
217   V(SVEFPTrigMulAddCoefficient)                                  \
218   V(SVEFPTrigSelectCoefficient)                                  \
219   V(SVEFPUnaryOp)                                                \
220   V(SVEIncDecRegisterByElementCount)                             \
221   V(SVEIncDecVectorByElementCount)                               \
222   V(SVEInsertSIMDFPScalarRegister)                               \
223   V(SVEInsertGeneralRegister)                                    \
224   V(SVEIntAddSubtractImm_Unpredicated)                           \
225   V(SVEIntAddSubtractVectors_Predicated)                         \
226   V(SVEIntCompareScalarCountAndLimit)                            \
227   V(SVEIntConvertToFP)                                           \
228   V(SVEIntDivideVectors_Predicated)                              \
229   V(SVEIntMinMaxImm_Unpredicated)                                \
230   V(SVEIntMinMaxDifference_Predicated)                           \
231   V(SVEIntMulImm_Unpredicated)                                   \
232   V(SVEIntMulVectors_Predicated)                                 \
233   V(SVELoadAndBroadcastElement)                                  \
234   V(SVELoadAndBroadcastQuadword_ScalarPlusImm)                   \
235   V(SVELoadAndBroadcastQuadword_ScalarPlusScalar)                \
236   V(SVELoadMultipleStructures_ScalarPlusImm)                     \
237   V(SVELoadMultipleStructures_ScalarPlusScalar)                  \
238   V(SVELoadPredicateRegister)                                    \
239   V(SVELoadVectorRegister)                                       \
240   V(SVEPartitionBreakCondition)                                  \
241   V(SVEPermutePredicateElements)                                 \
242   V(SVEPredicateFirstActive)                                     \
243   V(SVEPredicateInitialize)                                      \
244   V(SVEPredicateNextActive)                                      \
245   V(SVEPredicateReadFromFFR_Predicated)                          \
246   V(SVEPredicateReadFromFFR_Unpredicated)                        \
247   V(SVEPredicateTest)                                            \
248   V(SVEPredicateZero)                                            \
249   V(SVEPropagateBreakToNextPartition)                            \
250   V(SVEReversePredicateElements)                                 \
251   V(SVEReverseVectorElements)                                    \
252   V(SVEReverseWithinElements)                                    \
253   V(SVESaturatingIncDecRegisterByElementCount)                   \
254   V(SVESaturatingIncDecVectorByElementCount)                     \
255   V(SVEStoreMultipleStructures_ScalarPlusImm)                    \
256   V(SVEStoreMultipleStructures_ScalarPlusScalar)                 \
257   V(SVEStorePredicateRegister)                                   \
258   V(SVEStoreVectorRegister)                                      \
259   V(SVETableLookup)                                              \
260   V(SVEUnpackPredicateElements)                                  \
261   V(SVEUnpackVectorElements)                                     \
262   V(SVEVectorSplice_Destructive)                                 \
263   V(System)                                                      \
264   V(TestBranch)                                                  \
265   V(Unallocated)                                                 \
266   V(UnconditionalBranch)                                         \
267   V(UnconditionalBranchToRegister)                               \
268   V(Unimplemented)
269 
270 #define VISITOR_LIST_THAT_DONT_RETURN(V) V(Reserved)
271 
272 #define VISITOR_LIST(V)       \
273   VISITOR_LIST_THAT_RETURN(V) \
274   VISITOR_LIST_THAT_DONT_RETURN(V)
275 
276 namespace vixl {
277 namespace aarch64 {
278 
279 // The Visitor interface. Disassembler and simulator (and other tools)
280 // must provide implementations for all of these functions.
281 //
282 // Note that this class must change in breaking ways with even minor additions
283 // to VIXL, and so its API should be considered unstable. User classes that
284 // inherit from this one should be expected to break even on minor version
285 // updates. If this is a problem, consider using DecoderVisitorWithDefaults
286 // instead.
287 class DecoderVisitor {
288  public:
289   enum VisitorConstness { kConstVisitor, kNonConstVisitor };
290   explicit DecoderVisitor(VisitorConstness constness = kConstVisitor)
constness_(constness)291       : constness_(constness) {}
292 
~DecoderVisitor()293   virtual ~DecoderVisitor() {}
294 
295 #define DECLARE(A) virtual void Visit##A(const Instruction* instr) = 0;
VISITOR_LIST(DECLARE)296   VISITOR_LIST(DECLARE)
297 #undef DECLARE
298 
299   bool IsConstVisitor() const { return constness_ == kConstVisitor; }
MutableInstruction(const Instruction * instr)300   Instruction* MutableInstruction(const Instruction* instr) {
301     VIXL_ASSERT(!IsConstVisitor());
302     return const_cast<Instruction*>(instr);
303   }
304 
305  private:
306   const VisitorConstness constness_;
307 };
308 
309 // As above, but a default (no-op) implementation for each visitor is provided.
310 // This is useful for derived class that only care about specific visitors.
311 //
312 // A minor version update may add a visitor, but will never remove one, so it is
313 // safe (and recommended) to use `override` in derived classes.
314 class DecoderVisitorWithDefaults : public DecoderVisitor {
315  public:
316   explicit DecoderVisitorWithDefaults(
317       VisitorConstness constness = kConstVisitor)
DecoderVisitor(constness)318       : DecoderVisitor(constness) {}
319 
~DecoderVisitorWithDefaults()320   virtual ~DecoderVisitorWithDefaults() {}
321 
322 #define DECLARE(A) \
323   virtual void Visit##A(const Instruction* instr) VIXL_OVERRIDE { USE(instr); }
324   VISITOR_LIST(DECLARE)
325 #undef DECLARE
326 };
327 
328 class DecodeNode;
329 class CompiledDecodeNode;
330 
331 // The instruction decoder is constructed from a graph of decode nodes. At each
332 // node, a number of bits are sampled from the instruction being decoded. The
333 // resulting value is used to look up the next node in the graph, which then
334 // samples other bits, and moves to other decode nodes. Eventually, a visitor
335 // node is reached, and the corresponding visitor function is called, which
336 // handles the instruction.
337 class Decoder {
338  public:
Decoder()339   Decoder() { ConstructDecodeGraph(); }
340 
341   // Top-level wrappers around the actual decoding function.
342   void Decode(const Instruction* instr);
343   void Decode(Instruction* instr);
344 
345   // Decode all instructions from start (inclusive) to end (exclusive).
346   template <typename T>
Decode(T start,T end)347   void Decode(T start, T end) {
348     for (T instr = start; instr < end; instr = instr->GetNextInstruction()) {
349       Decode(instr);
350     }
351   }
352 
353   // Register a new visitor class with the decoder.
354   // Decode() will call the corresponding visitor method from all registered
355   // visitor classes when decoding reaches the leaf node of the instruction
356   // decode tree.
357   // Visitors are called in order.
358   // A visitor can be registered multiple times.
359   //
360   //   d.AppendVisitor(V1);
361   //   d.AppendVisitor(V2);
362   //   d.PrependVisitor(V2);
363   //   d.AppendVisitor(V3);
364   //
365   //   d.Decode(i);
366   //
367   // will call in order visitor methods in V2, V1, V2, V3.
368   void AppendVisitor(DecoderVisitor* visitor);
369   void PrependVisitor(DecoderVisitor* visitor);
370   // These helpers register `new_visitor` before or after the first instance of
371   // `registered_visiter` in the list.
372   // So if
373   //   V1, V2, V1, V2
374   // are registered in this order in the decoder, calls to
375   //   d.InsertVisitorAfter(V3, V1);
376   //   d.InsertVisitorBefore(V4, V2);
377   // will yield the order
378   //   V1, V3, V4, V2, V1, V2
379   //
380   // For more complex modifications of the order of registered visitors, one can
381   // directly access and modify the list of visitors via the `visitors()'
382   // accessor.
383   void InsertVisitorBefore(DecoderVisitor* new_visitor,
384                            DecoderVisitor* registered_visitor);
385   void InsertVisitorAfter(DecoderVisitor* new_visitor,
386                           DecoderVisitor* registered_visitor);
387 
388   // Remove all instances of a previously registered visitor class from the list
389   // of visitors stored by the decoder.
390   void RemoveVisitor(DecoderVisitor* visitor);
391 
392 #define DECLARE(A) void Visit##A(const Instruction* instr);
VISITOR_LIST(DECLARE)393   VISITOR_LIST(DECLARE)
394 #undef DECLARE
395 
396   std::list<DecoderVisitor*>* visitors() { return &visitors_; }
397 
398   // Get a DecodeNode by name from the Decoder's map.
399   DecodeNode* GetDecodeNode(std::string name);
400 
401  private:
402   // Decodes an instruction and calls the visitor functions registered with the
403   // Decoder class.
404   void DecodeInstruction(const Instruction* instr);
405 
406   // Add an initialised DecodeNode to the decode_node_ map.
407   void AddDecodeNode(const DecodeNode& node);
408 
409   // Visitors are registered in a list.
410   std::list<DecoderVisitor*> visitors_;
411 
412   // Compile the dynamically generated decode graph based on the static
413   // information in kDecodeMapping and kVisitorNodes.
414   void ConstructDecodeGraph();
415 
416   // Root node for the compiled decoder graph, stored here to avoid a map lookup
417   // for every instruction decoded.
418   CompiledDecodeNode* compiled_decoder_root_;
419 
420   // Map of node names to DecodeNodes.
421   std::map<std::string, DecodeNode> decode_nodes_;
422 };
423 
424 const int kMaxDecodeSampledBits = 16;
425 const int kMaxDecodeMappings = 100;
426 typedef void (Decoder::*DecodeFnPtr)(const Instruction*);
427 typedef uint32_t (Instruction::*BitExtractFn)(void) const;
428 
429 // A Visitor node maps the name of a visitor to the function that handles it.
430 struct VisitorNode {
431   const char* name;
432   const DecodeFnPtr visitor_fn;
433 };
434 
435 // DecodePattern and DecodeMapping represent the input data to the decoder
436 // compilation stage. After compilation, the decoder is embodied in the graph
437 // of CompiledDecodeNodes pointer to by compiled_decoder_root_.
438 
439 // A DecodePattern maps a pattern of set/unset/don't care (1, 0, x) bits as a
440 // string to the name of its handler.
441 struct DecodePattern {
442   const char* pattern;
443   const char* handler;
444 };
445 
446 // A DecodeMapping consists of the name of a handler, the bits sampled in the
447 // instruction by that handler, and a mapping from the pattern that those
448 // sampled bits match to the corresponding name of a node.
449 struct DecodeMapping {
450   const char* name;
451   const uint8_t sampled_bits[kMaxDecodeSampledBits];
452   const DecodePattern mapping[kMaxDecodeMappings];
453 };
454 
455 // For speed, before nodes can be used for decoding instructions, they must
456 // be compiled. This converts the mapping "bit pattern strings to decoder name
457 // string" stored in DecodeNodes to an array look up for the pointer to the next
458 // node, stored in CompiledDecodeNodes. Compilation may also apply other
459 // optimisations for simple decode patterns.
460 class CompiledDecodeNode {
461  public:
462   // Constructor for decode node, containing a decode table and pointer to a
463   // function that extracts the bits to be sampled.
CompiledDecodeNode(BitExtractFn bit_extract_fn,size_t decode_table_size)464   CompiledDecodeNode(BitExtractFn bit_extract_fn, size_t decode_table_size)
465       : bit_extract_fn_(bit_extract_fn),
466         visitor_fn_(NULL),
467         decode_table_size_(decode_table_size),
468         decoder_(NULL) {
469     decode_table_ = new CompiledDecodeNode*[decode_table_size_];
470     memset(decode_table_, 0, decode_table_size_ * sizeof(decode_table_[0]));
471   }
472 
473   // Constructor for wrappers around visitor functions. These require no
474   // decoding, so no bit extraction function or decode table is assigned.
CompiledDecodeNode(DecodeFnPtr visitor_fn,Decoder * decoder)475   explicit CompiledDecodeNode(DecodeFnPtr visitor_fn, Decoder* decoder)
476       : bit_extract_fn_(NULL),
477         visitor_fn_(visitor_fn),
478         decode_table_(NULL),
479         decode_table_size_(0),
480         decoder_(decoder) {}
481 
~CompiledDecodeNode()482   ~CompiledDecodeNode() VIXL_NEGATIVE_TESTING_ALLOW_EXCEPTION {
483     // Free the decode table, if this is a compiled, non-leaf node.
484     if (decode_table_ != NULL) {
485       VIXL_ASSERT(!IsLeafNode());
486       delete[] decode_table_;
487     }
488   }
489 
490   // Decode the instruction by either sampling the bits using the bit extract
491   // function to find the next node, or, if we're at a leaf, calling the visitor
492   // function.
493   void Decode(const Instruction* instr) const;
494 
495   // A leaf node is a wrapper for a visitor function.
IsLeafNode()496   bool IsLeafNode() const {
497     VIXL_ASSERT(((visitor_fn_ == NULL) && (bit_extract_fn_ != NULL)) ||
498                 ((visitor_fn_ != NULL) && (bit_extract_fn_ == NULL)));
499     return visitor_fn_ != NULL;
500   }
501 
502   // Get a pointer to the next node required in the decode process, based on the
503   // bits sampled by the current node.
GetNodeForBits(uint32_t bits)504   CompiledDecodeNode* GetNodeForBits(uint32_t bits) const {
505     VIXL_ASSERT(bits < decode_table_size_);
506     return decode_table_[bits];
507   }
508 
509   // Set the next node in the decode process for the pattern of sampled bits in
510   // the current node.
SetNodeForBits(uint32_t bits,CompiledDecodeNode * n)511   void SetNodeForBits(uint32_t bits, CompiledDecodeNode* n) {
512     VIXL_ASSERT(bits < decode_table_size_);
513     VIXL_ASSERT(n != NULL);
514     decode_table_[bits] = n;
515   }
516 
517  private:
518   // Pointer to an instantiated template function for extracting the bits
519   // sampled by this node. Set to NULL for leaf nodes.
520   const BitExtractFn bit_extract_fn_;
521 
522   // Visitor function that handles the instruction identified. Set only for
523   // leaf nodes, where no extra decoding is required, otherwise NULL.
524   const DecodeFnPtr visitor_fn_;
525 
526   // Mapping table from instruction bits to next decode stage.
527   CompiledDecodeNode** decode_table_;
528   const size_t decode_table_size_;
529 
530   // Pointer to the decoder containing this node, used to call its visitor
531   // function for leaf nodes. Set to NULL for non-leaf nodes.
532   Decoder* decoder_;
533 };
534 
535 class DecodeNode {
536  public:
537   // Default constructor needed for map initialisation.
DecodeNode()538   DecodeNode() : compiled_node_(NULL) {}
539 
540   // Constructor for DecodeNode wrappers around visitor functions. These are
541   // marked as "compiled", as there is no decoding left to do.
DecodeNode(const VisitorNode & visitor,Decoder * decoder)542   explicit DecodeNode(const VisitorNode& visitor, Decoder* decoder)
543       : name_(visitor.name),
544         visitor_fn_(visitor.visitor_fn),
545         decoder_(decoder),
546         compiled_node_(NULL) {}
547 
548   // Constructor for DecodeNodes that map bit patterns to other DecodeNodes.
549   explicit DecodeNode(const DecodeMapping& map, Decoder* decoder = NULL)
550       : name_(map.name),
551         visitor_fn_(NULL),
552         decoder_(decoder),
553         compiled_node_(NULL) {
554     // The length of the bit string in the first mapping determines the number
555     // of sampled bits. When adding patterns later, we assert that all mappings
556     // sample the same number of bits.
557     VIXL_CHECK(strcmp(map.mapping[0].pattern, "otherwise") != 0);
558     int bit_count = static_cast<int>(strlen(map.mapping[0].pattern));
559     VIXL_CHECK((bit_count > 0) && (bit_count <= 32));
560     SetSampledBits(map.sampled_bits, bit_count);
561     AddPatterns(map.mapping);
562   }
563 
~DecodeNode()564   ~DecodeNode() {
565     // Delete the compiled version of this node, if one was created.
566     if (compiled_node_ != NULL) {
567       delete compiled_node_;
568     }
569   }
570 
571   // Set the bits sampled from the instruction by this node.
572   void SetSampledBits(const uint8_t* bits, int bit_count);
573 
574   // Get the bits sampled from the instruction by this node.
575   std::vector<uint8_t> GetSampledBits() const;
576 
577   // Get the number of bits sampled from the instruction by this node.
578   size_t GetSampledBitsCount() const;
579 
580   // Add patterns to this node's internal pattern table.
581   void AddPatterns(const DecodePattern* patterns);
582 
583   // A leaf node is a DecodeNode that wraps the visitor function for the
584   // identified instruction class.
IsLeafNode()585   bool IsLeafNode() const { return visitor_fn_ != NULL; }
586 
GetName()587   std::string GetName() const { return name_; }
588 
589   // Create a CompiledDecodeNode of specified table size that uses
590   // bit_extract_fn to sample bits from the instruction.
CreateCompiledNode(BitExtractFn bit_extract_fn,size_t table_size)591   void CreateCompiledNode(BitExtractFn bit_extract_fn, size_t table_size) {
592     VIXL_ASSERT(bit_extract_fn != NULL);
593     VIXL_ASSERT(table_size > 0);
594     compiled_node_ = new CompiledDecodeNode(bit_extract_fn, table_size);
595   }
596 
597   // Create a CompiledDecodeNode wrapping a visitor function. No decoding is
598   // required for this node; the visitor function is called instead.
CreateVisitorNode()599   void CreateVisitorNode() {
600     compiled_node_ = new CompiledDecodeNode(visitor_fn_, decoder_);
601   }
602 
603   // Find and compile the DecodeNode named "name", and set it as the node for
604   // the pattern "bits".
605   void CompileNodeForBits(Decoder* decoder, std::string name, uint32_t bits);
606 
607   // Get a pointer to an instruction method that extracts the instruction bits
608   // specified by the mask argument, and returns those sampled bits as a
609   // contiguous sequence, suitable for indexing an array.
610   // For example, a mask of 0b1010 returns a function that, given an instruction
611   // 0bXYZW, will return 0bXZ.
612   BitExtractFn GetBitExtractFunction(uint32_t mask);
613 
614   // Get a pointer to an Instruction method that applies a mask to the
615   // instruction bits, and tests if the result is equal to value. The returned
616   // function gives a 1 result if (inst & mask == value), 0 otherwise.
617   BitExtractFn GetBitExtractFunction(uint32_t mask, uint32_t value);
618 
619   // Compile this DecodeNode into a new CompiledDecodeNode and returns a pointer
620   // to it. This pointer is also stored inside the DecodeNode itself. Destroying
621   // a DecodeNode frees its associated CompiledDecodeNode.
622   CompiledDecodeNode* Compile(Decoder* decoder);
623 
624   // Get a pointer to the CompiledDecodeNode associated with this DecodeNode.
625   // Returns NULL if the node has not been compiled yet.
GetCompiledNode()626   CompiledDecodeNode* GetCompiledNode() const { return compiled_node_; }
IsCompiled()627   bool IsCompiled() const { return GetCompiledNode() != NULL; }
628 
629  private:
630   // Generate a mask and value pair from a string constructed from 0, 1 and x
631   // (don't care) characters.
632   // For example "10x1" should return mask = 0b1101, value = 0b1001.
633   typedef std::pair<Instr, Instr> MaskValuePair;
634   MaskValuePair GenerateMaskValuePair(std::string pattern) const;
635 
636   // Generate a pattern string ordered by the bit positions sampled by this
637   // node. The first character in the string corresponds to the lowest sampled
638   // bit.
639   // For example, a pattern of "1x0" expected when sampling bits 31, 1 and 30
640   // returns the pattern "x01"; bit 1 should be 'x', bit 30 '0' and bit 31 '1'.
641   // This output makes comparisons easier between the pattern and bits sampled
642   // from an instruction using the fast "compress" algorithm. See
643   // Instruction::Compress().
644   std::string GenerateOrderedPattern(std::string pattern) const;
645 
646   // Generate a mask with a bit set at each sample position.
647   uint32_t GenerateSampledBitsMask() const;
648 
649   // Try to compile a more optimised decode operation for this node, returning
650   // true if successful.
651   bool TryCompileOptimisedDecodeTable(Decoder* decoder);
652 
653   // Name of this decoder node, used to construct edges in the decode graph.
654   std::string name_;
655 
656   // Vector of bits sampled from an instruction to determine which node to look
657   // up next in the decode process.
658   std::vector<uint8_t> sampled_bits_;
659 
660   // Visitor function that handles the instruction identified. Set only for leaf
661   // nodes, where no extra decoding is required. For non-leaf decoding nodes,
662   // this pointer is NULL.
663   DecodeFnPtr visitor_fn_;
664 
665   // Source mapping from bit pattern to name of next decode stage.
666   std::vector<DecodePattern> pattern_table_;
667 
668   // Pointer to the decoder containing this node, used to call its visitor
669   // function for leaf nodes.
670   Decoder* decoder_;
671 
672   // Pointer to the compiled version of this node. Is this node hasn't been
673   // compiled yet, this pointer is NULL.
674   CompiledDecodeNode* compiled_node_;
675 };
676 
677 }  // namespace aarch64
678 }  // namespace vixl
679 
680 #endif  // VIXL_AARCH64_DECODER_AARCH64_H_
681