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 <string>
28
29 #include "../globals-vixl.h"
30 #include "../utils-vixl.h"
31
32 #include "decoder-aarch64.h"
33 #include "decoder-constants-aarch64.h"
34
35 namespace vixl {
36 namespace aarch64 {
37
Decode(const Instruction * instr)38 void Decoder::Decode(const Instruction* instr) {
39 std::list<DecoderVisitor*>::iterator it;
40 for (it = visitors_.begin(); it != visitors_.end(); it++) {
41 VIXL_ASSERT((*it)->IsConstVisitor());
42 }
43 VIXL_ASSERT(compiled_decoder_root_ != NULL);
44 compiled_decoder_root_->Decode(instr);
45 }
46
Decode(Instruction * instr)47 void Decoder::Decode(Instruction* instr) {
48 compiled_decoder_root_->Decode(const_cast<const Instruction*>(instr));
49 }
50
AddDecodeNode(const DecodeNode & node)51 void Decoder::AddDecodeNode(const DecodeNode& node) {
52 decode_nodes_.insert(std::make_pair(node.GetName(), node));
53 }
54
GetDecodeNode(std::string name)55 DecodeNode* Decoder::GetDecodeNode(std::string name) {
56 if (decode_nodes_.count(name) != 1) {
57 std::string msg = "Can't find decode node " + name + ".\n";
58 VIXL_ABORT_WITH_MSG(msg.c_str());
59 }
60 return &decode_nodes_[name];
61 }
62
ConstructDecodeGraph()63 void Decoder::ConstructDecodeGraph() {
64 // Add all of the decoding nodes to the Decoder.
65 for (unsigned i = 0; i < ArrayLength(kDecodeMapping); i++) {
66 AddDecodeNode(DecodeNode(kDecodeMapping[i], this));
67 }
68
69 // Add the visitor function wrapping nodes to the Decoder.
70 for (unsigned i = 0; i < ArrayLength(kVisitorNodes); i++) {
71 AddDecodeNode(DecodeNode(kVisitorNodes[i], this));
72 }
73
74 // Compile the graph from the root.
75 compiled_decoder_root_ = GetDecodeNode("Root")->Compile(this);
76 }
77
AppendVisitor(DecoderVisitor * new_visitor)78 void Decoder::AppendVisitor(DecoderVisitor* new_visitor) {
79 visitors_.push_back(new_visitor);
80 }
81
82
PrependVisitor(DecoderVisitor * new_visitor)83 void Decoder::PrependVisitor(DecoderVisitor* new_visitor) {
84 visitors_.push_front(new_visitor);
85 }
86
87
InsertVisitorBefore(DecoderVisitor * new_visitor,DecoderVisitor * registered_visitor)88 void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,
89 DecoderVisitor* registered_visitor) {
90 std::list<DecoderVisitor*>::iterator it;
91 for (it = visitors_.begin(); it != visitors_.end(); it++) {
92 if (*it == registered_visitor) {
93 visitors_.insert(it, new_visitor);
94 return;
95 }
96 }
97 // We reached the end of the list. The last element must be
98 // registered_visitor.
99 VIXL_ASSERT(*it == registered_visitor);
100 visitors_.insert(it, new_visitor);
101 }
102
103
InsertVisitorAfter(DecoderVisitor * new_visitor,DecoderVisitor * registered_visitor)104 void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,
105 DecoderVisitor* registered_visitor) {
106 std::list<DecoderVisitor*>::iterator it;
107 for (it = visitors_.begin(); it != visitors_.end(); it++) {
108 if (*it == registered_visitor) {
109 it++;
110 visitors_.insert(it, new_visitor);
111 return;
112 }
113 }
114 // We reached the end of the list. The last element must be
115 // registered_visitor.
116 VIXL_ASSERT(*it == registered_visitor);
117 visitors_.push_back(new_visitor);
118 }
119
120
RemoveVisitor(DecoderVisitor * visitor)121 void Decoder::RemoveVisitor(DecoderVisitor* visitor) {
122 visitors_.remove(visitor);
123 }
124
125 #define DEFINE_VISITOR_CALLERS(A) \
126 void Decoder::Visit##A(const Instruction* instr) { \
127 VIXL_ASSERT(((A##FMask == 0) && (A##Fixed == 0)) || \
128 (instr->Mask(A##FMask) == A##Fixed)); \
129 std::list<DecoderVisitor*>::iterator it; \
130 for (it = visitors_.begin(); it != visitors_.end(); it++) { \
131 (*it)->Visit##A(instr); \
132 } \
133 }
VISITOR_LIST(DEFINE_VISITOR_CALLERS)134 VISITOR_LIST(DEFINE_VISITOR_CALLERS)
135 #undef DEFINE_VISITOR_CALLERS
136
137 void DecodeNode::SetSampledBits(const uint8_t* bits, int bit_count) {
138 VIXL_ASSERT(!IsCompiled());
139
140 sampled_bits_.resize(bit_count);
141 for (int i = 0; i < bit_count; i++) {
142 sampled_bits_[i] = bits[i];
143 }
144 }
145
GetSampledBits() const146 std::vector<uint8_t> DecodeNode::GetSampledBits() const {
147 return sampled_bits_;
148 }
149
GetSampledBitsCount() const150 size_t DecodeNode::GetSampledBitsCount() const { return sampled_bits_.size(); }
151
AddPatterns(const DecodePattern * patterns)152 void DecodeNode::AddPatterns(const DecodePattern* patterns) {
153 VIXL_ASSERT(!IsCompiled());
154 for (unsigned i = 0; i < kMaxDecodeMappings; i++) {
155 // Empty string indicates end of patterns.
156 if (patterns[i].pattern == NULL) break;
157 VIXL_ASSERT((strlen(patterns[i].pattern) == GetSampledBitsCount()) ||
158 (strcmp(patterns[i].pattern, "otherwise") == 0));
159 pattern_table_.push_back(patterns[i]);
160 }
161 }
162
CompileNodeForBits(Decoder * decoder,std::string name,uint32_t bits)163 void DecodeNode::CompileNodeForBits(Decoder* decoder,
164 std::string name,
165 uint32_t bits) {
166 DecodeNode* n = decoder->GetDecodeNode(name);
167 VIXL_ASSERT(n != NULL);
168 if (!n->IsCompiled()) {
169 n->Compile(decoder);
170 }
171 VIXL_ASSERT(n->IsCompiled());
172 compiled_node_->SetNodeForBits(bits, n->GetCompiledNode());
173 }
174
GetBitExtractFunction(uint32_t mask)175 BitExtractFn DecodeNode::GetBitExtractFunction(uint32_t mask) {
176 // Instantiate a templated bit extraction function for every pattern we
177 // might encounter. If the assertion in the default clause is reached, add a
178 // new instantiation below using the information in the failure message.
179 BitExtractFn bit_extract_fn = NULL;
180 switch (mask) {
181 #define INSTANTIATE_TEMPLATE(M) \
182 case M: \
183 bit_extract_fn = &Instruction::ExtractBits<M>; \
184 break;
185 INSTANTIATE_TEMPLATE(0x000001e0);
186 INSTANTIATE_TEMPLATE(0x00000400);
187 INSTANTIATE_TEMPLATE(0x00000800);
188 INSTANTIATE_TEMPLATE(0x00000c00);
189 INSTANTIATE_TEMPLATE(0x00001000);
190 INSTANTIATE_TEMPLATE(0x00001800);
191 INSTANTIATE_TEMPLATE(0x00001c00);
192 INSTANTIATE_TEMPLATE(0x00004000);
193 INSTANTIATE_TEMPLATE(0x00008000);
194 INSTANTIATE_TEMPLATE(0x0000f000);
195 INSTANTIATE_TEMPLATE(0x0000fc00);
196 INSTANTIATE_TEMPLATE(0x00060010);
197 INSTANTIATE_TEMPLATE(0x00093e00);
198 INSTANTIATE_TEMPLATE(0x000c1000);
199 INSTANTIATE_TEMPLATE(0x00100000);
200 INSTANTIATE_TEMPLATE(0x00101800);
201 INSTANTIATE_TEMPLATE(0x00140000);
202 INSTANTIATE_TEMPLATE(0x00180000);
203 INSTANTIATE_TEMPLATE(0x00181000);
204 INSTANTIATE_TEMPLATE(0x00190000);
205 INSTANTIATE_TEMPLATE(0x00191400);
206 INSTANTIATE_TEMPLATE(0x001c0000);
207 INSTANTIATE_TEMPLATE(0x001c1800);
208 INSTANTIATE_TEMPLATE(0x001f0000);
209 INSTANTIATE_TEMPLATE(0x0020fc00);
210 INSTANTIATE_TEMPLATE(0x0038f000);
211 INSTANTIATE_TEMPLATE(0x00400000);
212 INSTANTIATE_TEMPLATE(0x00400010);
213 INSTANTIATE_TEMPLATE(0x0040f000);
214 INSTANTIATE_TEMPLATE(0x00500000);
215 INSTANTIATE_TEMPLATE(0x00800000);
216 INSTANTIATE_TEMPLATE(0x00800010);
217 INSTANTIATE_TEMPLATE(0x00801800);
218 INSTANTIATE_TEMPLATE(0x009f0000);
219 INSTANTIATE_TEMPLATE(0x00c00000);
220 INSTANTIATE_TEMPLATE(0x00c00010);
221 INSTANTIATE_TEMPLATE(0x00cf8000);
222 INSTANTIATE_TEMPLATE(0x00db0000);
223 INSTANTIATE_TEMPLATE(0x00dc0000);
224 INSTANTIATE_TEMPLATE(0x00e00003);
225 INSTANTIATE_TEMPLATE(0x00f80400);
226 INSTANTIATE_TEMPLATE(0x01e00000);
227 INSTANTIATE_TEMPLATE(0x03800000);
228 INSTANTIATE_TEMPLATE(0x04c0f000);
229 INSTANTIATE_TEMPLATE(0x10800400);
230 INSTANTIATE_TEMPLATE(0x1e000000);
231 INSTANTIATE_TEMPLATE(0x20000000);
232 INSTANTIATE_TEMPLATE(0x20000410);
233 INSTANTIATE_TEMPLATE(0x20007000);
234 INSTANTIATE_TEMPLATE(0x20007800);
235 INSTANTIATE_TEMPLATE(0x2000f000);
236 INSTANTIATE_TEMPLATE(0x2000f800);
237 INSTANTIATE_TEMPLATE(0x201e0c00);
238 INSTANTIATE_TEMPLATE(0x20803800);
239 INSTANTIATE_TEMPLATE(0x20c0cc00);
240 INSTANTIATE_TEMPLATE(0x20c0f000);
241 INSTANTIATE_TEMPLATE(0x20c0f800);
242 INSTANTIATE_TEMPLATE(0x20c1f000);
243 INSTANTIATE_TEMPLATE(0x51e00000);
244 INSTANTIATE_TEMPLATE(0x60007800);
245 INSTANTIATE_TEMPLATE(0x6000f800);
246 INSTANTIATE_TEMPLATE(0x601e0000);
247 INSTANTIATE_TEMPLATE(0x80007c00);
248 INSTANTIATE_TEMPLATE(0x80017c00);
249 INSTANTIATE_TEMPLATE(0x80408000);
250 INSTANTIATE_TEMPLATE(0x80a07c00);
251 INSTANTIATE_TEMPLATE(0x80df0000);
252 INSTANTIATE_TEMPLATE(0x80e08000);
253 INSTANTIATE_TEMPLATE(0xa0c00000);
254 INSTANTIATE_TEMPLATE(0xb5a00000);
255 INSTANTIATE_TEMPLATE(0xc0c00c00);
256 INSTANTIATE_TEMPLATE(0xc4400000);
257 INSTANTIATE_TEMPLATE(0xc4c00000);
258 INSTANTIATE_TEMPLATE(0xe0400000);
259 INSTANTIATE_TEMPLATE(0xe120e000);
260 INSTANTIATE_TEMPLATE(0xe3c00000);
261 INSTANTIATE_TEMPLATE(0xf1200000);
262 #undef INSTANTIATE_TEMPLATE
263 default:
264 printf("Node %s: No template instantiated for extracting 0x%08x.\n",
265 GetName().c_str(),
266 GenerateSampledBitsMask());
267 printf("Add one in %s above line %d:\n", __FILE__, __LINE__);
268 printf(" INSTANTIATE_TEMPLATE(0x%08x);\n", GenerateSampledBitsMask());
269 VIXL_UNREACHABLE();
270 }
271 return bit_extract_fn;
272 }
273
GetBitExtractFunction(uint32_t mask,uint32_t value)274 BitExtractFn DecodeNode::GetBitExtractFunction(uint32_t mask, uint32_t value) {
275 // Instantiate a templated bit extraction function for every pattern we
276 // might encounter. If the assertion in the following check fails, add a
277 // new instantiation below using the information in the failure message.
278 bool instantiated = false;
279 BitExtractFn bit_extract_fn = NULL;
280 #define INSTANTIATE_TEMPLATE(M, V) \
281 if ((mask == M) && (value == V)) { \
282 bit_extract_fn = &Instruction::IsMaskedValue<M, V>; \
283 instantiated = true; \
284 }
285 INSTANTIATE_TEMPLATE(0x0000001c, 0x00000000);
286 INSTANTIATE_TEMPLATE(0x00000210, 0x00000000);
287 INSTANTIATE_TEMPLATE(0x000003c0, 0x00000000);
288 INSTANTIATE_TEMPLATE(0x00001c00, 0x00000000);
289 INSTANTIATE_TEMPLATE(0x00001c0f, 0x00000000);
290 INSTANTIATE_TEMPLATE(0x00003000, 0x00000000);
291 INSTANTIATE_TEMPLATE(0x00007800, 0x00000000);
292 INSTANTIATE_TEMPLATE(0x0000e000, 0x0000a000);
293 INSTANTIATE_TEMPLATE(0x0000f000, 0x00000000);
294 INSTANTIATE_TEMPLATE(0x00030400, 0x00000000);
295 INSTANTIATE_TEMPLATE(0x0003801f, 0x0000000d);
296 INSTANTIATE_TEMPLATE(0x00060210, 0x00000000);
297 INSTANTIATE_TEMPLATE(0x00060810, 0x00000000);
298 INSTANTIATE_TEMPLATE(0x00060a10, 0x00000000);
299 INSTANTIATE_TEMPLATE(0x00060bf0, 0x00000000);
300 INSTANTIATE_TEMPLATE(0x00061e10, 0x00000000);
301 INSTANTIATE_TEMPLATE(0x00061e10, 0x00000400);
302 INSTANTIATE_TEMPLATE(0x00070200, 0x00000000);
303 INSTANTIATE_TEMPLATE(0x000b1e10, 0x00000000);
304 INSTANTIATE_TEMPLATE(0x000f0000, 0x00000000);
305 INSTANTIATE_TEMPLATE(0x00130e1f, 0x00000000);
306 INSTANTIATE_TEMPLATE(0x00130fff, 0x00000000);
307 INSTANTIATE_TEMPLATE(0x00180000, 0x00000000);
308 INSTANTIATE_TEMPLATE(0x00180000, 0x00100000);
309 INSTANTIATE_TEMPLATE(0x001e0000, 0x00000000);
310 INSTANTIATE_TEMPLATE(0x001f0000, 0x00000000);
311 INSTANTIATE_TEMPLATE(0x001f0000, 0x001f0000);
312 INSTANTIATE_TEMPLATE(0x0038e000, 0x00000000);
313 INSTANTIATE_TEMPLATE(0x0039e000, 0x00002000);
314 INSTANTIATE_TEMPLATE(0x003ae000, 0x00002000);
315 INSTANTIATE_TEMPLATE(0x003ce000, 0x00042000);
316 INSTANTIATE_TEMPLATE(0x005f0000, 0x001f0000);
317 INSTANTIATE_TEMPLATE(0x00780000, 0x00000000);
318 INSTANTIATE_TEMPLATE(0x00870210, 0x00000000);
319 INSTANTIATE_TEMPLATE(0x00c00000, 0x00000000);
320 INSTANTIATE_TEMPLATE(0x00c00000, 0x00800000);
321 INSTANTIATE_TEMPLATE(0x00c00000, 0x00c00000);
322 INSTANTIATE_TEMPLATE(0x00c00010, 0x00800000);
323 INSTANTIATE_TEMPLATE(0x00ca1e10, 0x00000000);
324 INSTANTIATE_TEMPLATE(0x01000010, 0x00000000);
325 INSTANTIATE_TEMPLATE(0x20000800, 0x00000000);
326 INSTANTIATE_TEMPLATE(0x20008000, 0x00000000);
327 INSTANTIATE_TEMPLATE(0x20040000, 0x00000000);
328 INSTANTIATE_TEMPLATE(0x201e8000, 0x00000000);
329 INSTANTIATE_TEMPLATE(0x60000000, 0x00000000);
330 INSTANTIATE_TEMPLATE(0x60000000, 0x20000000);
331 INSTANTIATE_TEMPLATE(0x60000000, 0x60000000);
332 INSTANTIATE_TEMPLATE(0x60200000, 0x00000000);
333 INSTANTIATE_TEMPLATE(0x80008000, 0x00000000);
334 INSTANTIATE_TEMPLATE(0x80008000, 0x00008000);
335 INSTANTIATE_TEMPLATE(0x80400000, 0x00400000);
336 INSTANTIATE_TEMPLATE(0xa00003e0, 0x00000000);
337 INSTANTIATE_TEMPLATE(0xa000c007, 0x00000000);
338 INSTANTIATE_TEMPLATE(0xa0100000, 0x00000000);
339 INSTANTIATE_TEMPLATE(0xc4000000, 0xc0000000);
340 INSTANTIATE_TEMPLATE(0xc4000000, 0xc4000000);
341 INSTANTIATE_TEMPLATE(0xe0000010, 0xa0000000);
342 INSTANTIATE_TEMPLATE(0xe01c0000, 0x20000000);
343 INSTANTIATE_TEMPLATE(0xe1ff0000, 0x00000000);
344 #undef INSTANTIATE_TEMPLATE
345
346 if (!instantiated) {
347 printf(
348 "Node %s: no template instantiated for mask 0x%08x, value = "
349 "0x%08x.\n",
350 GetName().c_str(),
351 mask,
352 value);
353 printf("Add one in %s above line %d:\n", __FILE__, __LINE__);
354 printf(" INSTANTIATE_TEMPLATE(0x%08x, 0x%08x);\n", mask, value);
355 VIXL_UNREACHABLE();
356 }
357 return bit_extract_fn;
358 }
359
TryCompileOptimisedDecodeTable(Decoder * decoder)360 bool DecodeNode::TryCompileOptimisedDecodeTable(Decoder* decoder) {
361 // EitherOr optimisation: if there are only one or two patterns in the table,
362 // try to optimise the node to exploit that.
363 size_t table_size = pattern_table_.size();
364 if ((table_size <= 2) && (GetSampledBitsCount() > 1)) {
365 // TODO: support 'x' in this optimisation by dropping the sampled bit
366 // positions before making the mask/value.
367 if ((strchr(pattern_table_[0].pattern, 'x') == NULL) &&
368 ((table_size == 1) ||
369 (strcmp(pattern_table_[1].pattern, "otherwise") == 0))) {
370 // A pattern table consisting of a fixed pattern with no x's, and an
371 // "otherwise" or absent case. Optimise this into an instruction mask and
372 // value test.
373 uint32_t single_decode_mask = 0;
374 uint32_t single_decode_value = 0;
375 std::vector<uint8_t> bits = GetSampledBits();
376
377 // Construct the instruction mask and value from the pattern.
378 VIXL_ASSERT(bits.size() == strlen(pattern_table_[0].pattern));
379 for (size_t i = 0; i < bits.size(); i++) {
380 single_decode_mask |= 1U << bits[i];
381 if (pattern_table_[0].pattern[i] == '1') {
382 single_decode_value |= 1U << bits[i];
383 }
384 }
385 BitExtractFn bit_extract_fn =
386 GetBitExtractFunction(single_decode_mask, single_decode_value);
387
388 // Create a compiled node that contains a two entry table for the
389 // either/or cases.
390 CreateCompiledNode(bit_extract_fn, 2);
391
392 // Set DecodeNode for when the instruction after masking doesn't match the
393 // value.
394 const char* doesnt_match_handler =
395 (table_size == 1) ? "VisitUnallocated" : pattern_table_[1].handler;
396 CompileNodeForBits(decoder, doesnt_match_handler, 0);
397
398 // Set DecodeNode for when it does match.
399 CompileNodeForBits(decoder, pattern_table_[0].handler, 1);
400
401 return true;
402 }
403 }
404 return false;
405 }
406
Compile(Decoder * decoder)407 CompiledDecodeNode* DecodeNode::Compile(Decoder* decoder) {
408 if (IsLeafNode()) {
409 // A leaf node is a simple wrapper around a visitor function, with no
410 // instruction decoding to do.
411 CreateVisitorNode();
412 } else if (!TryCompileOptimisedDecodeTable(decoder)) {
413 // The "otherwise" node is the default next node if no pattern matches.
414 std::string otherwise = "VisitUnallocated";
415
416 // For each pattern in pattern_table_, create an entry in matches that
417 // has a corresponding mask and value for the pattern.
418 std::vector<MaskValuePair> matches;
419 for (size_t i = 0; i < pattern_table_.size(); i++) {
420 if (strcmp(pattern_table_[i].pattern, "otherwise") == 0) {
421 // "otherwise" must be the last pattern in the list, otherwise the
422 // indices won't match for pattern_table_ and matches.
423 VIXL_ASSERT(i == pattern_table_.size() - 1);
424 otherwise = pattern_table_[i].handler;
425 } else {
426 matches.push_back(GenerateMaskValuePair(
427 GenerateOrderedPattern(pattern_table_[i].pattern)));
428 }
429 }
430
431 BitExtractFn bit_extract_fn =
432 GetBitExtractFunction(GenerateSampledBitsMask());
433
434 // Create a compiled node that contains a table with an entry for every bit
435 // pattern.
436 CreateCompiledNode(bit_extract_fn, 1U << GetSampledBitsCount());
437 VIXL_ASSERT(compiled_node_ != NULL);
438
439 // When we find a pattern matches the representation, set the node's decode
440 // function for that representation to the corresponding function.
441 for (uint32_t bits = 0; bits < (1U << GetSampledBitsCount()); bits++) {
442 for (size_t i = 0; i < matches.size(); i++) {
443 if ((bits & matches[i].first) == matches[i].second) {
444 // Only one instruction class should match for each value of bits, so
445 // if we get here, the node pointed to should still be unallocated.
446 VIXL_ASSERT(compiled_node_->GetNodeForBits(bits) == NULL);
447 CompileNodeForBits(decoder, pattern_table_[i].handler, bits);
448 break;
449 }
450 }
451
452 // If the decode_table_ entry for these bits is still NULL, the
453 // instruction must be handled by the "otherwise" case, which by default
454 // is the Unallocated visitor.
455 if (compiled_node_->GetNodeForBits(bits) == NULL) {
456 CompileNodeForBits(decoder, otherwise, bits);
457 }
458 }
459 }
460
461 VIXL_ASSERT(compiled_node_ != NULL);
462 return compiled_node_;
463 }
464
Decode(const Instruction * instr) const465 void CompiledDecodeNode::Decode(const Instruction* instr) const {
466 if (IsLeafNode()) {
467 // If this node is a leaf, call the registered visitor function.
468 VIXL_ASSERT(decoder_ != NULL);
469 (decoder_->*visitor_fn_)(instr);
470 } else {
471 // Otherwise, using the sampled bit extractor for this node, look up the
472 // next node in the decode tree, and call its Decode method.
473 VIXL_ASSERT(bit_extract_fn_ != NULL);
474 VIXL_ASSERT((instr->*bit_extract_fn_)() < decode_table_size_);
475 VIXL_ASSERT(decode_table_[(instr->*bit_extract_fn_)()] != NULL);
476 decode_table_[(instr->*bit_extract_fn_)()]->Decode(instr);
477 }
478 }
479
GenerateMaskValuePair(std::string pattern) const480 DecodeNode::MaskValuePair DecodeNode::GenerateMaskValuePair(
481 std::string pattern) const {
482 uint32_t mask = 0, value = 0;
483 for (size_t i = 0; i < pattern.size(); i++) {
484 mask |= ((pattern[i] == 'x') ? 0 : 1) << i;
485 value |= ((pattern[i] == '1') ? 1 : 0) << i;
486 }
487 return std::make_pair(mask, value);
488 }
489
GenerateOrderedPattern(std::string pattern) const490 std::string DecodeNode::GenerateOrderedPattern(std::string pattern) const {
491 std::vector<uint8_t> sampled_bits = GetSampledBits();
492 // Construct a temporary 32-character string containing '_', then at each
493 // sampled bit position, set the corresponding pattern character.
494 std::string temp(32, '_');
495 for (size_t i = 0; i < sampled_bits.size(); i++) {
496 temp[sampled_bits[i]] = pattern[i];
497 }
498
499 // Iterate through the temporary string, filtering out the non-'_' characters
500 // into a new ordered pattern result string.
501 std::string result;
502 for (size_t i = 0; i < temp.size(); i++) {
503 if (temp[i] != '_') {
504 result.push_back(temp[i]);
505 }
506 }
507 VIXL_ASSERT(result.size() == sampled_bits.size());
508 return result;
509 }
510
GenerateSampledBitsMask() const511 uint32_t DecodeNode::GenerateSampledBitsMask() const {
512 std::vector<uint8_t> sampled_bits = GetSampledBits();
513 uint32_t mask = 0;
514 for (size_t i = 0; i < sampled_bits.size(); i++) {
515 mask |= 1 << sampled_bits[i];
516 }
517 return mask;
518 }
519
520 } // namespace aarch64
521 } // namespace vixl
522