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#include "decoder-aarch64.h"
28
29#include <string>
30
31#include "../globals-vixl.h"
32#include "../utils-vixl.h"
33
34#include "decoder-constants-aarch64.h"
35
36namespace vixl {
37namespace aarch64 {
38
39void Decoder::Decode(const Instruction* instr) {
40#ifndef PANDA_BUILD
41    std::list<DecoderVisitor*>::iterator it;
42#else
43    List<DecoderVisitor*>::iterator it;
44#endif
45
46  for (it = visitors_.begin(); it != visitors_.end(); it++) {
47    VIXL_ASSERT((*it)->IsConstVisitor());
48  }
49  VIXL_ASSERT(compiled_decoder_root_ != NULL);
50  compiled_decoder_root_->Decode(instr);
51}
52
53void Decoder::Decode(Instruction* instr) {
54  compiled_decoder_root_->Decode(const_cast<const Instruction*>(instr));
55}
56
57void Decoder::AddDecodeNode(const DecodeNode& node) {
58  if (decode_nodes_.count(node.GetName()) == 0) {
59    decode_nodes_.insert(std::make_pair(node.GetName(), node));
60  }
61}
62
63DecodeNode* Decoder::GetDecodeNode(const String& name) {
64  auto elem{decode_nodes_.find(name)};
65  if (elem == decode_nodes_.end()) {
66    auto msg = String("Can't find decode node ", GetAllocator().Adapter()) + name.data() + ".\n";
67    VIXL_ABORT_WITH_MSG(msg.c_str());
68  }
69  return &elem->second;
70}
71
72void Decoder::ConstructDecodeGraph() {
73  // Add all of the decoding nodes to the Decoder.
74  for (unsigned i = 0; i < ArrayLength(kDecodeMapping); i++) {
75    AddDecodeNode(DecodeNode(kDecodeMapping[i], this));
76
77    // Add a node for each instruction form named, identified by having no '_'
78    // prefix on the node name.
79    const DecodeMapping& map = kDecodeMapping[i];
80    for (unsigned j = 0; j < map.mapping.size(); j++) {
81      if ((map.mapping[j].handler != NULL) &&
82          (map.mapping[j].handler[0] != '_')) {
83        AddDecodeNode(DecodeNode(map.mapping[j].handler, this));
84      }
85    }
86  }
87
88  // Add an "unallocated" node, used when an instruction encoding is not
89  // recognised by the decoding graph.
90  AddDecodeNode(DecodeNode("unallocated", this));
91
92  // Compile the graph from the root.
93  auto root_node{String("Root", GetAllocator().Adapter())};
94  compiled_decoder_root_ = GetDecodeNode(root_node)->Compile(this);
95}
96
97void Decoder::AppendVisitor(DecoderVisitor* new_visitor) {
98  visitors_.push_back(new_visitor);
99}
100
101
102void Decoder::PrependVisitor(DecoderVisitor* new_visitor) {
103  visitors_.push_front(new_visitor);
104}
105
106
107void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,
108                                  DecoderVisitor* registered_visitor) {
109#ifndef PANDA_BUILD
110  std::list<DecoderVisitor*>::iterator it;
111#else
112  List<DecoderVisitor*>::iterator it;
113#endif
114  for (it = visitors_.begin(); it != visitors_.end(); it++) {
115    if (*it == registered_visitor) {
116      visitors_.insert(it, new_visitor);
117      return;
118    }
119  }
120  // We reached the end of the list. The last element must be
121  // registered_visitor.
122  VIXL_ASSERT(*it == registered_visitor);
123  visitors_.insert(it, new_visitor);
124}
125
126
127void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,
128                                 DecoderVisitor* registered_visitor) {
129#ifndef PANDA_BUILD
130  std::list<DecoderVisitor*>::iterator it;
131#else
132  List<DecoderVisitor*>::iterator it;
133#endif
134  for (it = visitors_.begin(); it != visitors_.end(); it++) {
135    if (*it == registered_visitor) {
136      it++;
137      visitors_.insert(it, new_visitor);
138      return;
139    }
140  }
141  // We reached the end of the list. The last element must be
142  // registered_visitor.
143  VIXL_ASSERT(*it == registered_visitor);
144  visitors_.push_back(new_visitor);
145}
146
147
148void Decoder::RemoveVisitor(DecoderVisitor* visitor) {
149  visitors_.remove(visitor);
150}
151
152void Decoder::VisitNamedInstruction(const Instruction* instr,
153                                    const std::string_view name) {
154  std::list<DecoderVisitor*>::iterator it;
155  Metadata m = {{"form", std::string(name)}};
156  for (it = visitors_.begin(); it != visitors_.end(); it++) {
157    (*it)->Visit(&m, instr);
158  }
159}
160
161// Initialise empty vectors for sampled bits and pattern table.
162const std::vector<uint8_t> DecodeNode::kEmptySampledBits;
163const std::vector<DecodePattern> DecodeNode::kEmptyPatternTable;
164
165void DecodeNode::CompileNodeForBits(Decoder* decoder,
166                                    const String& name,
167                                    uint32_t bits) {
168  DecodeNode* n = decoder->GetDecodeNode(name);
169  VIXL_ASSERT(n != NULL);
170  if (!n->IsCompiled()) {
171    n->Compile(decoder);
172  }
173  VIXL_ASSERT(n->IsCompiled());
174  compiled_node_->SetNodeForBits(bits, n->GetCompiledNode());
175}
176
177
178#define INSTANTIATE_TEMPLATE_M(M)                      \
179  case 0x##M:                                          \
180    bit_extract_fn = &Instruction::ExtractBits<0x##M>; \
181    break;
182#define INSTANTIATE_TEMPLATE_MV(M, V)                           \
183  case 0x##M##V:                                                \
184    bit_extract_fn = &Instruction::IsMaskedValue<0x##M, 0x##V>; \
185    break;
186
187BitExtractFn DecodeNode::GetBitExtractFunctionHelper(uint32_t x, uint32_t y) {
188  // Instantiate a templated bit extraction function for every pattern we
189  // might encounter. If the assertion in the default clause is reached, add a
190  // new instantiation below using the information in the failure message.
191  BitExtractFn bit_extract_fn = NULL;
192
193  // The arguments x and y represent the mask and value. If y is 0, x is the
194  // mask. Otherwise, y is the mask, and x is the value to compare against a
195  // masked result.
196  uint64_t signature = (static_cast<uint64_t>(y) << 32) | x;
197  switch (signature) {
198    INSTANTIATE_TEMPLATE_M(00000002);
199    INSTANTIATE_TEMPLATE_M(00000010);
200    INSTANTIATE_TEMPLATE_M(00000060);
201    INSTANTIATE_TEMPLATE_M(000000df);
202    INSTANTIATE_TEMPLATE_M(00000100);
203    INSTANTIATE_TEMPLATE_M(00000200);
204    INSTANTIATE_TEMPLATE_M(00000400);
205    INSTANTIATE_TEMPLATE_M(00000800);
206    INSTANTIATE_TEMPLATE_M(00000c00);
207    INSTANTIATE_TEMPLATE_M(00000c10);
208    INSTANTIATE_TEMPLATE_M(00000fc0);
209    INSTANTIATE_TEMPLATE_M(00001000);
210    INSTANTIATE_TEMPLATE_M(00001400);
211    INSTANTIATE_TEMPLATE_M(00001800);
212    INSTANTIATE_TEMPLATE_M(00001c00);
213    INSTANTIATE_TEMPLATE_M(00002000);
214    INSTANTIATE_TEMPLATE_M(00002010);
215    INSTANTIATE_TEMPLATE_M(00002400);
216    INSTANTIATE_TEMPLATE_M(00003000);
217    INSTANTIATE_TEMPLATE_M(00003020);
218    INSTANTIATE_TEMPLATE_M(00003400);
219    INSTANTIATE_TEMPLATE_M(00003800);
220    INSTANTIATE_TEMPLATE_M(00003c00);
221    INSTANTIATE_TEMPLATE_M(00013000);
222    INSTANTIATE_TEMPLATE_M(000203e0);
223    INSTANTIATE_TEMPLATE_M(000303e0);
224    INSTANTIATE_TEMPLATE_M(00040000);
225    INSTANTIATE_TEMPLATE_M(00040010);
226    INSTANTIATE_TEMPLATE_M(00060000);
227    INSTANTIATE_TEMPLATE_M(00061000);
228    INSTANTIATE_TEMPLATE_M(00070000);
229    INSTANTIATE_TEMPLATE_M(000703c0);
230    INSTANTIATE_TEMPLATE_M(00080000);
231    INSTANTIATE_TEMPLATE_M(00090000);
232    INSTANTIATE_TEMPLATE_M(000f0000);
233    INSTANTIATE_TEMPLATE_M(000f0010);
234    INSTANTIATE_TEMPLATE_M(00100000);
235    INSTANTIATE_TEMPLATE_M(00180000);
236    INSTANTIATE_TEMPLATE_M(001b1c00);
237    INSTANTIATE_TEMPLATE_M(001f0000);
238    INSTANTIATE_TEMPLATE_M(001f0018);
239    INSTANTIATE_TEMPLATE_M(001f2000);
240    INSTANTIATE_TEMPLATE_M(001f3000);
241    INSTANTIATE_TEMPLATE_M(00400000);
242    INSTANTIATE_TEMPLATE_M(00400018);
243    INSTANTIATE_TEMPLATE_M(00400800);
244    INSTANTIATE_TEMPLATE_M(00403000);
245    INSTANTIATE_TEMPLATE_M(00500000);
246    INSTANTIATE_TEMPLATE_M(00500800);
247    INSTANTIATE_TEMPLATE_M(00583000);
248    INSTANTIATE_TEMPLATE_M(005f0000);
249    INSTANTIATE_TEMPLATE_M(00800000);
250    INSTANTIATE_TEMPLATE_M(00800400);
251    INSTANTIATE_TEMPLATE_M(00800c1d);
252    INSTANTIATE_TEMPLATE_M(0080101f);
253    INSTANTIATE_TEMPLATE_M(00801c00);
254    INSTANTIATE_TEMPLATE_M(00803000);
255    INSTANTIATE_TEMPLATE_M(00803c00);
256    INSTANTIATE_TEMPLATE_M(009f0000);
257    INSTANTIATE_TEMPLATE_M(009f2000);
258    INSTANTIATE_TEMPLATE_M(00c00000);
259    INSTANTIATE_TEMPLATE_M(00c00010);
260    INSTANTIATE_TEMPLATE_M(00c0001f);
261    INSTANTIATE_TEMPLATE_M(00c00200);
262    INSTANTIATE_TEMPLATE_M(00c00400);
263    INSTANTIATE_TEMPLATE_M(00c00c00);
264    INSTANTIATE_TEMPLATE_M(00c00c19);
265    INSTANTIATE_TEMPLATE_M(00c01000);
266    INSTANTIATE_TEMPLATE_M(00c01400);
267    INSTANTIATE_TEMPLATE_M(00c01c00);
268    INSTANTIATE_TEMPLATE_M(00c02000);
269    INSTANTIATE_TEMPLATE_M(00c03000);
270    INSTANTIATE_TEMPLATE_M(00c03c00);
271    INSTANTIATE_TEMPLATE_M(00c70000);
272    INSTANTIATE_TEMPLATE_M(00c83000);
273    INSTANTIATE_TEMPLATE_M(00d00200);
274    INSTANTIATE_TEMPLATE_M(00d80800);
275    INSTANTIATE_TEMPLATE_M(00d81800);
276    INSTANTIATE_TEMPLATE_M(00d81c00);
277    INSTANTIATE_TEMPLATE_M(00d82800);
278    INSTANTIATE_TEMPLATE_M(00d82c00);
279    INSTANTIATE_TEMPLATE_M(00d92400);
280    INSTANTIATE_TEMPLATE_M(00d93000);
281    INSTANTIATE_TEMPLATE_M(00db0000);
282    INSTANTIATE_TEMPLATE_M(00db2000);
283    INSTANTIATE_TEMPLATE_M(00dc0000);
284    INSTANTIATE_TEMPLATE_M(00dc2000);
285    INSTANTIATE_TEMPLATE_M(00df0000);
286    INSTANTIATE_TEMPLATE_M(40000000);
287    INSTANTIATE_TEMPLATE_M(40000010);
288    INSTANTIATE_TEMPLATE_M(40000c00);
289    INSTANTIATE_TEMPLATE_M(40002000);
290    INSTANTIATE_TEMPLATE_M(40002010);
291    INSTANTIATE_TEMPLATE_M(40003000);
292    INSTANTIATE_TEMPLATE_M(40003c00);
293    INSTANTIATE_TEMPLATE_M(401f2000);
294    INSTANTIATE_TEMPLATE_M(40400800);
295    INSTANTIATE_TEMPLATE_M(40400c00);
296    INSTANTIATE_TEMPLATE_M(40403c00);
297    INSTANTIATE_TEMPLATE_M(405f0000);
298    INSTANTIATE_TEMPLATE_M(40800000);
299    INSTANTIATE_TEMPLATE_M(40800c00);
300    INSTANTIATE_TEMPLATE_M(40802000);
301    INSTANTIATE_TEMPLATE_M(40802010);
302    INSTANTIATE_TEMPLATE_M(40803400);
303    INSTANTIATE_TEMPLATE_M(40803c00);
304    INSTANTIATE_TEMPLATE_M(40c00000);
305    INSTANTIATE_TEMPLATE_M(40c00400);
306    INSTANTIATE_TEMPLATE_M(40c00800);
307    INSTANTIATE_TEMPLATE_M(40c00c00);
308    INSTANTIATE_TEMPLATE_M(40c00c10);
309    INSTANTIATE_TEMPLATE_M(40c02000);
310    INSTANTIATE_TEMPLATE_M(40c02010);
311    INSTANTIATE_TEMPLATE_M(40c02c00);
312    INSTANTIATE_TEMPLATE_M(40c03c00);
313    INSTANTIATE_TEMPLATE_M(40c80000);
314    INSTANTIATE_TEMPLATE_M(40c90000);
315    INSTANTIATE_TEMPLATE_M(40cf0000);
316    INSTANTIATE_TEMPLATE_M(40d02000);
317    INSTANTIATE_TEMPLATE_M(40d02010);
318    INSTANTIATE_TEMPLATE_M(40d80000);
319    INSTANTIATE_TEMPLATE_M(40d81800);
320    INSTANTIATE_TEMPLATE_M(40dc0000);
321    INSTANTIATE_TEMPLATE_M(bf20c000);
322    INSTANTIATE_TEMPLATE_MV(00000006, 00000000);
323    INSTANTIATE_TEMPLATE_MV(00000006, 00000006);
324    INSTANTIATE_TEMPLATE_MV(00000007, 00000000);
325    INSTANTIATE_TEMPLATE_MV(0000001f, 0000001f);
326    INSTANTIATE_TEMPLATE_MV(00000210, 00000000);
327    INSTANTIATE_TEMPLATE_MV(000003e0, 00000000);
328    INSTANTIATE_TEMPLATE_MV(000003e0, 000003e0);
329    INSTANTIATE_TEMPLATE_MV(000003e2, 000003e0);
330    INSTANTIATE_TEMPLATE_MV(000003e6, 000003e0);
331    INSTANTIATE_TEMPLATE_MV(000003e6, 000003e6);
332    INSTANTIATE_TEMPLATE_MV(00000c00, 00000000);
333    INSTANTIATE_TEMPLATE_MV(00000fc0, 00000000);
334    INSTANTIATE_TEMPLATE_MV(000013e0, 00001000);
335    INSTANTIATE_TEMPLATE_MV(00001c00, 00000000);
336    INSTANTIATE_TEMPLATE_MV(00002400, 00000000);
337    INSTANTIATE_TEMPLATE_MV(00003000, 00000000);
338    INSTANTIATE_TEMPLATE_MV(00003000, 00001000);
339    INSTANTIATE_TEMPLATE_MV(00003000, 00002000);
340    INSTANTIATE_TEMPLATE_MV(00003000, 00003000);
341    INSTANTIATE_TEMPLATE_MV(00003010, 00000000);
342    INSTANTIATE_TEMPLATE_MV(00003c00, 00003c00);
343    INSTANTIATE_TEMPLATE_MV(00040010, 00000000);
344    INSTANTIATE_TEMPLATE_MV(00060000, 00000000);
345    INSTANTIATE_TEMPLATE_MV(00061000, 00000000);
346    INSTANTIATE_TEMPLATE_MV(00070000, 00030000);
347    INSTANTIATE_TEMPLATE_MV(00073ee0, 00033060);
348    INSTANTIATE_TEMPLATE_MV(00073f9f, 0000001f);
349    INSTANTIATE_TEMPLATE_MV(000f0000, 00000000);
350    INSTANTIATE_TEMPLATE_MV(000f0010, 00000000);
351    INSTANTIATE_TEMPLATE_MV(00100200, 00000000);
352    INSTANTIATE_TEMPLATE_MV(00100210, 00000000);
353    INSTANTIATE_TEMPLATE_MV(00160000, 00000000);
354    INSTANTIATE_TEMPLATE_MV(00170000, 00000000);
355    INSTANTIATE_TEMPLATE_MV(001c0000, 00000000);
356    INSTANTIATE_TEMPLATE_MV(001d0000, 00000000);
357    INSTANTIATE_TEMPLATE_MV(001e0000, 00000000);
358    INSTANTIATE_TEMPLATE_MV(001f0000, 00000000);
359    INSTANTIATE_TEMPLATE_MV(001f0000, 00010000);
360    INSTANTIATE_TEMPLATE_MV(001f0000, 00100000);
361    INSTANTIATE_TEMPLATE_MV(001f0000, 001f0000);
362    INSTANTIATE_TEMPLATE_MV(001f3000, 00000000);
363    INSTANTIATE_TEMPLATE_MV(001f3000, 00001000);
364    INSTANTIATE_TEMPLATE_MV(001f3000, 001f0000);
365    INSTANTIATE_TEMPLATE_MV(001f300f, 0000000d);
366    INSTANTIATE_TEMPLATE_MV(001f301f, 0000000d);
367    INSTANTIATE_TEMPLATE_MV(001f33e0, 000103e0);
368    INSTANTIATE_TEMPLATE_MV(001f3800, 00000000);
369    INSTANTIATE_TEMPLATE_MV(00401000, 00400000);
370    INSTANTIATE_TEMPLATE_MV(005f3000, 001f0000);
371    INSTANTIATE_TEMPLATE_MV(005f3000, 001f1000);
372    INSTANTIATE_TEMPLATE_MV(00800010, 00000000);
373    INSTANTIATE_TEMPLATE_MV(00800400, 00000000);
374    INSTANTIATE_TEMPLATE_MV(00800410, 00000000);
375    INSTANTIATE_TEMPLATE_MV(00803000, 00002000);
376    INSTANTIATE_TEMPLATE_MV(00870000, 00000000);
377    INSTANTIATE_TEMPLATE_MV(009f0000, 00010000);
378    INSTANTIATE_TEMPLATE_MV(00c00000, 00000000);
379    INSTANTIATE_TEMPLATE_MV(00c00000, 00400000);
380    INSTANTIATE_TEMPLATE_MV(00c0001f, 00000000);
381    INSTANTIATE_TEMPLATE_MV(00c001ff, 00000000);
382    INSTANTIATE_TEMPLATE_MV(00c00200, 00400000);
383    INSTANTIATE_TEMPLATE_MV(00c0020f, 00400000);
384    INSTANTIATE_TEMPLATE_MV(00c003e0, 00000000);
385    INSTANTIATE_TEMPLATE_MV(00c00800, 00000000);
386    INSTANTIATE_TEMPLATE_MV(00d80800, 00000000);
387    INSTANTIATE_TEMPLATE_MV(00df0000, 00000000);
388    INSTANTIATE_TEMPLATE_MV(00df3800, 001f0800);
389    INSTANTIATE_TEMPLATE_MV(40002000, 40000000);
390    INSTANTIATE_TEMPLATE_MV(40003c00, 00000000);
391    INSTANTIATE_TEMPLATE_MV(40040000, 00000000);
392    INSTANTIATE_TEMPLATE_MV(401f2000, 401f0000);
393    INSTANTIATE_TEMPLATE_MV(40800c00, 40000400);
394    INSTANTIATE_TEMPLATE_MV(40c00000, 00000000);
395    INSTANTIATE_TEMPLATE_MV(40c00000, 00400000);
396    INSTANTIATE_TEMPLATE_MV(40c00000, 40000000);
397    INSTANTIATE_TEMPLATE_MV(40c00000, 40800000);
398    INSTANTIATE_TEMPLATE_MV(40df0000, 00000000);
399    default: {
400      static bool printed_preamble = false;
401      if (!printed_preamble) {
402        printf("One or more missing template instantiations.\n");
403        printf(
404            "Add the following to either GetBitExtractFunction() "
405            "implementations\n");
406        printf("in %s near line %d:\n", __FILE__, __LINE__);
407        printed_preamble = true;
408      }
409
410      if (y == 0) {
411        printf("  INSTANTIATE_TEMPLATE_M(%08x);\n", x);
412        bit_extract_fn = &Instruction::ExtractBitsAbsent;
413      } else {
414        printf("  INSTANTIATE_TEMPLATE_MV(%08x, %08x);\n", y, x);
415        bit_extract_fn = &Instruction::IsMaskedValueAbsent;
416      }
417    }
418  }
419  return bit_extract_fn;
420}
421
422#undef INSTANTIATE_TEMPLATE_M
423#undef INSTANTIATE_TEMPLATE_MV
424
425bool DecodeNode::TryCompileOptimisedDecodeTable(Decoder* decoder) {
426  // EitherOr optimisation: if there are only one or two patterns in the table,
427  // try to optimise the node to exploit that.
428  size_t table_size = pattern_table_.size();
429  if ((table_size <= 2) && (GetSampledBitsCount() > 1)) {
430    // TODO: support 'x' in this optimisation by dropping the sampled bit
431    // positions before making the mask/value.
432    if (!PatternContainsSymbol(pattern_table_[0].pattern,
433                               PatternSymbol::kSymbolX) &&
434        (table_size == 1)) {
435      // A pattern table consisting of a fixed pattern with no x's, and an
436      // "otherwise" or absent case. Optimise this into an instruction mask and
437      // value test.
438      uint32_t single_decode_mask = 0;
439      uint32_t single_decode_value = 0;
440      const auto& bits = GetSampledBits();
441
442      // Construct the instruction mask and value from the pattern.
443      VIXL_ASSERT(bits.size() == GetPatternLength(pattern_table_[0].pattern));
444      for (size_t i = 0; i < bits.size(); i++) {
445        single_decode_mask |= 1U << bits[i];
446        if (GetSymbolAt(pattern_table_[0].pattern, i) ==
447            PatternSymbol::kSymbol1) {
448          single_decode_value |= 1U << bits[i];
449        }
450      }
451      BitExtractFn bit_extract_fn =
452          GetBitExtractFunction(single_decode_mask, single_decode_value);
453
454      // Create a compiled node that contains a two entry table for the
455      // either/or cases.
456      CreateCompiledNode(bit_extract_fn, 2);
457
458      // Set DecodeNode for when the instruction after masking doesn't match the
459      // value.
460      CompileNodeForBits(decoder, String("unallocated", GetAllocator().Adapter()), 0);
461
462      // Set DecodeNode for when it does match.
463      CompileNodeForBits(decoder, String(pattern_table_[0].handler, GetAllocator().Adapter()), 1);
464
465      return true;
466    }
467  }
468  return false;
469}
470
471CompiledDecodeNode* DecodeNode::Compile(Decoder* decoder) {
472  if (IsLeafNode()) {
473    // A leaf node is a simple wrapper around a visitor function, with no
474    // instruction decoding to do.
475    CreateVisitorNode();
476  } else if (!TryCompileOptimisedDecodeTable(decoder)) {
477    // The "otherwise" node is the default next node if no pattern matches.
478    String otherwise("unallocated", GetAllocator().Adapter());
479
480    // For each pattern in pattern_table_, create an entry in matches that
481    // has a corresponding mask and value for the pattern.
482    Vector<MaskValuePair> matches(GetAllocator().Adapter());
483    for (size_t i = 0; i < pattern_table_.size(); i++) {
484      matches.push_back(GenerateMaskValuePair(
485          GenerateOrderedPattern(pattern_table_[i].pattern)));
486    }
487
488    BitExtractFn bit_extract_fn =
489        GetBitExtractFunction(GenerateSampledBitsMask());
490
491    // Create a compiled node that contains a table with an entry for every bit
492    // pattern.
493    CreateCompiledNode(bit_extract_fn,
494                       static_cast<size_t>(1) << GetSampledBitsCount());
495    VIXL_ASSERT(compiled_node_ != NULL);
496
497    // When we find a pattern matches the representation, set the node's decode
498    // function for that representation to the corresponding function.
499    for (uint32_t bits = 0; bits < (1U << GetSampledBitsCount()); bits++) {
500      for (size_t i = 0; i < matches.size(); i++) {
501        if ((bits & matches[i].first) == matches[i].second) {
502          // Only one instruction class should match for each value of bits, so
503          // if we get here, the node pointed to should still be unallocated.
504          VIXL_ASSERT(compiled_node_->GetNodeForBits(bits) == NULL);
505          CompileNodeForBits(decoder, String(pattern_table_[i].handler, GetAllocator().Adapter()), bits);
506          break;
507        }
508      }
509
510      // If the decode_table_ entry for these bits is still NULL, the
511      // instruction must be handled by the "otherwise" case, which by default
512      // is the Unallocated visitor.
513      if (compiled_node_->GetNodeForBits(bits) == NULL) {
514        CompileNodeForBits(decoder, String(otherwise, GetAllocator().Adapter()), bits);
515      }
516    }
517  }
518
519  VIXL_ASSERT(compiled_node_ != NULL);
520  return compiled_node_;
521}
522
523void CompiledDecodeNode::Decode(const Instruction* instr) const {
524  if (IsLeafNode()) {
525    // If this node is a leaf, call the registered visitor function.
526    VIXL_ASSERT(decoder_ != NULL);
527    decoder_->VisitNamedInstruction(instr, instruction_name_);
528  } else {
529    // Otherwise, using the sampled bit extractor for this node, look up the
530    // next node in the decode tree, and call its Decode method.
531    VIXL_ASSERT(bit_extract_fn_ != NULL);
532    VIXL_ASSERT((instr->*bit_extract_fn_)() < decode_table_size_);
533    VIXL_ASSERT(decode_table_[(instr->*bit_extract_fn_)()] != NULL);
534    decode_table_[(instr->*bit_extract_fn_)()]->Decode(instr);
535  }
536}
537
538DecodeNode::MaskValuePair DecodeNode::GenerateMaskValuePair(
539    uint32_t pattern) const {
540  uint32_t mask = 0, value = 0;
541  for (size_t i = 0; i < GetPatternLength(pattern); i++) {
542    PatternSymbol sym = GetSymbolAt(pattern, i);
543    mask = (mask << 1) | ((sym == PatternSymbol::kSymbolX) ? 0 : 1);
544    value = (value << 1) | (static_cast<uint32_t>(sym) & 1);
545  }
546  return std::make_pair(mask, value);
547}
548
549uint32_t DecodeNode::GenerateOrderedPattern(uint32_t pattern) const {
550  const auto& sampled_bits = GetSampledBits();
551  uint64_t temp = 0xffffffffffffffff;
552
553  // Place symbols into the field of set bits. Symbols are two bits wide and
554  // take values 0, 1 or 2, so 3 will represent "no symbol".
555  for (size_t i = 0; i < sampled_bits.size(); i++) {
556    int shift = sampled_bits[i] * 2;
557    temp ^= static_cast<uint64_t>(kEndOfPattern) << shift;
558    temp |= static_cast<uint64_t>(GetSymbolAt(pattern, i)) << shift;
559  }
560
561  // Iterate over temp and extract new pattern ordered by sample position.
562  uint32_t result = kEndOfPattern;  // End of pattern marker.
563
564  // Iterate over the pattern one symbol (two bits) at a time.
565  for (int i = 62; i >= 0; i -= 2) {
566    uint32_t sym = (temp >> i) & kPatternSymbolMask;
567
568    // If this is a valid symbol, shift into the result.
569    if (sym != kEndOfPattern) {
570      result = (result << 2) | sym;
571    }
572  }
573
574  // The length of the ordered pattern must be the same as the input pattern,
575  // and the number of sampled bits.
576  VIXL_ASSERT(GetPatternLength(result) == GetPatternLength(pattern));
577  VIXL_ASSERT(GetPatternLength(result) == sampled_bits.size());
578
579  return result;
580}
581
582uint32_t DecodeNode::GenerateSampledBitsMask() const {
583  uint32_t mask = 0;
584  for (int bit : GetSampledBits()) {
585    mask |= 1 << bit;
586  }
587  return mask;
588}
589
590}  // namespace aarch64
591}  // namespace vixl
592