Path: blob/master/dep/vixl/src/aarch64/decoder-aarch64.cc
4261 views
// Copyright 2019, VIXL authors1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are met:5//6// * Redistributions of source code must retain the above copyright notice,7// this list of conditions and the following disclaimer.8// * Redistributions in binary form must reproduce the above copyright notice,9// this list of conditions and the following disclaimer in the documentation10// and/or other materials provided with the distribution.11// * Neither the name of ARM Limited nor the names of its contributors may be12// used to endorse or promote products derived from this software without13// specific prior written permission.14//15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE19// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR21// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER22// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,23// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE24// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2526#include "decoder-aarch64.h"2728#include <string>2930#include "../globals-vixl.h"31#include "../utils-vixl.h"3233#include "decoder-constants-aarch64.h"3435namespace vixl {36namespace aarch64 {3738void Decoder::Decode(const Instruction* instr) {39std::list<DecoderVisitor*>::iterator it;40for (it = visitors_.begin(); it != visitors_.end(); it++) {41VIXL_ASSERT((*it)->IsConstVisitor());42}43VIXL_ASSERT(compiled_decoder_root_ != NULL);44compiled_decoder_root_->Decode(instr);45}4647void Decoder::Decode(Instruction* instr) {48compiled_decoder_root_->Decode(const_cast<const Instruction*>(instr));49}5051void Decoder::AddDecodeNode(const DecodeNode& node) {52if (decode_nodes_.count(node.GetName()) == 0) {53decode_nodes_.insert(std::make_pair(node.GetName(), node));54}55}5657DecodeNode* Decoder::GetDecodeNode(std::string name) {58if (decode_nodes_.count(name) != 1) {59std::string msg = "Can't find decode node " + name + ".\n";60VIXL_ABORT_WITH_MSG(msg.c_str());61}62return &decode_nodes_[name];63}6465void Decoder::ConstructDecodeGraph() {66// Add all of the decoding nodes to the Decoder.67for (unsigned i = 0; i < ArrayLength(kDecodeMapping); i++) {68AddDecodeNode(DecodeNode(kDecodeMapping[i], this));6970// Add a node for each instruction form named, identified by having no '_'71// prefix on the node name.72const DecodeMapping& map = kDecodeMapping[i];73for (unsigned j = 0; j < map.mapping.size(); j++) {74if ((map.mapping[j].handler != NULL) &&75(map.mapping[j].handler[0] != '_')) {76AddDecodeNode(DecodeNode(map.mapping[j].handler, this));77}78}79}8081// Add an "unallocated" node, used when an instruction encoding is not82// recognised by the decoding graph.83AddDecodeNode(DecodeNode("unallocated", this));8485// Compile the graph from the root.86compiled_decoder_root_ = GetDecodeNode("Root")->Compile(this);87}8889void Decoder::AppendVisitor(DecoderVisitor* new_visitor) {90visitors_.push_back(new_visitor);91}929394void Decoder::PrependVisitor(DecoderVisitor* new_visitor) {95visitors_.push_front(new_visitor);96}979899void Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,100DecoderVisitor* registered_visitor) {101std::list<DecoderVisitor*>::iterator it;102for (it = visitors_.begin(); it != visitors_.end(); it++) {103if (*it == registered_visitor) {104visitors_.insert(it, new_visitor);105return;106}107}108// We reached the end of the list. The last element must be109// registered_visitor.110VIXL_ASSERT(*it == registered_visitor);111visitors_.insert(it, new_visitor);112}113114115void Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,116DecoderVisitor* registered_visitor) {117std::list<DecoderVisitor*>::iterator it;118for (it = visitors_.begin(); it != visitors_.end(); it++) {119if (*it == registered_visitor) {120it++;121visitors_.insert(it, new_visitor);122return;123}124}125// We reached the end of the list. The last element must be126// registered_visitor.127VIXL_ASSERT(*it == registered_visitor);128visitors_.push_back(new_visitor);129}130131132void Decoder::RemoveVisitor(DecoderVisitor* visitor) {133visitors_.remove(visitor);134}135136void Decoder::VisitNamedInstruction(const Instruction* instr,137const std::string& name) {138std::list<DecoderVisitor*>::iterator it;139Metadata m = {{"form", name}};140for (it = visitors_.begin(); it != visitors_.end(); it++) {141(*it)->Visit(&m, instr);142}143}144145// Initialise empty vectors for sampled bits and pattern table.146const std::vector<uint8_t> DecodeNode::kEmptySampledBits;147const std::vector<DecodePattern> DecodeNode::kEmptyPatternTable;148149void DecodeNode::CompileNodeForBits(Decoder* decoder,150std::string name,151uint32_t bits) {152DecodeNode* n = decoder->GetDecodeNode(name);153VIXL_ASSERT(n != NULL);154if (!n->IsCompiled()) {155n->Compile(decoder);156}157VIXL_ASSERT(n->IsCompiled());158compiled_node_->SetNodeForBits(bits, n->GetCompiledNode());159}160161162#define INSTANTIATE_TEMPLATE_M(M) \163case 0x##M: \164bit_extract_fn = &Instruction::ExtractBits<0x##M>; \165break;166#define INSTANTIATE_TEMPLATE_MV(M, V) \167case 0x##M##V: \168bit_extract_fn = &Instruction::IsMaskedValue<0x##M, 0x##V>; \169break;170171BitExtractFn DecodeNode::GetBitExtractFunctionHelper(uint32_t x, uint32_t y) {172// Instantiate a templated bit extraction function for every pattern we173// might encounter. If the assertion in the default clause is reached, add a174// new instantiation below using the information in the failure message.175BitExtractFn bit_extract_fn = NULL;176177// The arguments x and y represent the mask and value. If y is 0, x is the178// mask. Otherwise, y is the mask, and x is the value to compare against a179// masked result.180uint64_t signature = (static_cast<uint64_t>(y) << 32) | x;181switch (signature) {182INSTANTIATE_TEMPLATE_M(00000002);183INSTANTIATE_TEMPLATE_M(00000010);184INSTANTIATE_TEMPLATE_M(00000060);185INSTANTIATE_TEMPLATE_M(000000df);186INSTANTIATE_TEMPLATE_M(00000100);187INSTANTIATE_TEMPLATE_M(00000200);188INSTANTIATE_TEMPLATE_M(00000400);189INSTANTIATE_TEMPLATE_M(00000800);190INSTANTIATE_TEMPLATE_M(00000c00);191INSTANTIATE_TEMPLATE_M(00000c10);192INSTANTIATE_TEMPLATE_M(00000fc0);193INSTANTIATE_TEMPLATE_M(00001000);194INSTANTIATE_TEMPLATE_M(00001400);195INSTANTIATE_TEMPLATE_M(00001800);196INSTANTIATE_TEMPLATE_M(00001c00);197INSTANTIATE_TEMPLATE_M(00002000);198INSTANTIATE_TEMPLATE_M(00002010);199INSTANTIATE_TEMPLATE_M(00002400);200INSTANTIATE_TEMPLATE_M(00003000);201INSTANTIATE_TEMPLATE_M(00003020);202INSTANTIATE_TEMPLATE_M(00003400);203INSTANTIATE_TEMPLATE_M(00003800);204INSTANTIATE_TEMPLATE_M(00003c00);205INSTANTIATE_TEMPLATE_M(00013000);206INSTANTIATE_TEMPLATE_M(000203e0);207INSTANTIATE_TEMPLATE_M(000303e0);208INSTANTIATE_TEMPLATE_M(00040000);209INSTANTIATE_TEMPLATE_M(00040010);210INSTANTIATE_TEMPLATE_M(00060000);211INSTANTIATE_TEMPLATE_M(00061000);212INSTANTIATE_TEMPLATE_M(00070000);213INSTANTIATE_TEMPLATE_M(000703c0);214INSTANTIATE_TEMPLATE_M(00080000);215INSTANTIATE_TEMPLATE_M(00090000);216INSTANTIATE_TEMPLATE_M(000f0000);217INSTANTIATE_TEMPLATE_M(000f0010);218INSTANTIATE_TEMPLATE_M(00100000);219INSTANTIATE_TEMPLATE_M(00180000);220INSTANTIATE_TEMPLATE_M(001b1c00);221INSTANTIATE_TEMPLATE_M(001f0000);222INSTANTIATE_TEMPLATE_M(001f0018);223INSTANTIATE_TEMPLATE_M(001f2000);224INSTANTIATE_TEMPLATE_M(001f3000);225INSTANTIATE_TEMPLATE_M(00400000);226INSTANTIATE_TEMPLATE_M(00400018);227INSTANTIATE_TEMPLATE_M(00400800);228INSTANTIATE_TEMPLATE_M(00403000);229INSTANTIATE_TEMPLATE_M(00500000);230INSTANTIATE_TEMPLATE_M(00500800);231INSTANTIATE_TEMPLATE_M(00583000);232INSTANTIATE_TEMPLATE_M(005f0000);233INSTANTIATE_TEMPLATE_M(00800000);234INSTANTIATE_TEMPLATE_M(00800400);235INSTANTIATE_TEMPLATE_M(00800c1d);236INSTANTIATE_TEMPLATE_M(0080101f);237INSTANTIATE_TEMPLATE_M(00801c00);238INSTANTIATE_TEMPLATE_M(00803000);239INSTANTIATE_TEMPLATE_M(00803c00);240INSTANTIATE_TEMPLATE_M(009f0000);241INSTANTIATE_TEMPLATE_M(009f2000);242INSTANTIATE_TEMPLATE_M(00c00000);243INSTANTIATE_TEMPLATE_M(00c00010);244INSTANTIATE_TEMPLATE_M(00c0001f);245INSTANTIATE_TEMPLATE_M(00c00200);246INSTANTIATE_TEMPLATE_M(00c00400);247INSTANTIATE_TEMPLATE_M(00c00c00);248INSTANTIATE_TEMPLATE_M(00c00c19);249INSTANTIATE_TEMPLATE_M(00c01000);250INSTANTIATE_TEMPLATE_M(00c01400);251INSTANTIATE_TEMPLATE_M(00c01c00);252INSTANTIATE_TEMPLATE_M(00c02000);253INSTANTIATE_TEMPLATE_M(00c03000);254INSTANTIATE_TEMPLATE_M(00c03c00);255INSTANTIATE_TEMPLATE_M(00c70000);256INSTANTIATE_TEMPLATE_M(00c83000);257INSTANTIATE_TEMPLATE_M(00d00200);258INSTANTIATE_TEMPLATE_M(00d80800);259INSTANTIATE_TEMPLATE_M(00d81800);260INSTANTIATE_TEMPLATE_M(00d81c00);261INSTANTIATE_TEMPLATE_M(00d82800);262INSTANTIATE_TEMPLATE_M(00d82c00);263INSTANTIATE_TEMPLATE_M(00d92400);264INSTANTIATE_TEMPLATE_M(00d93000);265INSTANTIATE_TEMPLATE_M(00db0000);266INSTANTIATE_TEMPLATE_M(00db2000);267INSTANTIATE_TEMPLATE_M(00dc0000);268INSTANTIATE_TEMPLATE_M(00dc2000);269INSTANTIATE_TEMPLATE_M(00df0000);270INSTANTIATE_TEMPLATE_M(40000000);271INSTANTIATE_TEMPLATE_M(40000010);272INSTANTIATE_TEMPLATE_M(40000c00);273INSTANTIATE_TEMPLATE_M(40002000);274INSTANTIATE_TEMPLATE_M(40002010);275INSTANTIATE_TEMPLATE_M(40003000);276INSTANTIATE_TEMPLATE_M(40003c00);277INSTANTIATE_TEMPLATE_M(401f2000);278INSTANTIATE_TEMPLATE_M(40400800);279INSTANTIATE_TEMPLATE_M(40400c00);280INSTANTIATE_TEMPLATE_M(40403c00);281INSTANTIATE_TEMPLATE_M(405f0000);282INSTANTIATE_TEMPLATE_M(40800000);283INSTANTIATE_TEMPLATE_M(40800c00);284INSTANTIATE_TEMPLATE_M(40802000);285INSTANTIATE_TEMPLATE_M(40802010);286INSTANTIATE_TEMPLATE_M(40803400);287INSTANTIATE_TEMPLATE_M(40803c00);288INSTANTIATE_TEMPLATE_M(40c00000);289INSTANTIATE_TEMPLATE_M(40c00400);290INSTANTIATE_TEMPLATE_M(40c00800);291INSTANTIATE_TEMPLATE_M(40c00c00);292INSTANTIATE_TEMPLATE_M(40c00c10);293INSTANTIATE_TEMPLATE_M(40c02000);294INSTANTIATE_TEMPLATE_M(40c02010);295INSTANTIATE_TEMPLATE_M(40c02c00);296INSTANTIATE_TEMPLATE_M(40c03c00);297INSTANTIATE_TEMPLATE_M(40c80000);298INSTANTIATE_TEMPLATE_M(40c90000);299INSTANTIATE_TEMPLATE_M(40cf0000);300INSTANTIATE_TEMPLATE_M(40d02000);301INSTANTIATE_TEMPLATE_M(40d02010);302INSTANTIATE_TEMPLATE_M(40d80000);303INSTANTIATE_TEMPLATE_M(40d81800);304INSTANTIATE_TEMPLATE_M(40dc0000);305INSTANTIATE_TEMPLATE_M(bf20c000);306INSTANTIATE_TEMPLATE_MV(00000006, 00000000);307INSTANTIATE_TEMPLATE_MV(00000006, 00000006);308INSTANTIATE_TEMPLATE_MV(00000007, 00000000);309INSTANTIATE_TEMPLATE_MV(0000001f, 0000001f);310INSTANTIATE_TEMPLATE_MV(00000210, 00000000);311INSTANTIATE_TEMPLATE_MV(000003e0, 00000000);312INSTANTIATE_TEMPLATE_MV(000003e0, 000003e0);313INSTANTIATE_TEMPLATE_MV(000003e2, 000003e0);314INSTANTIATE_TEMPLATE_MV(000003e6, 000003e0);315INSTANTIATE_TEMPLATE_MV(000003e6, 000003e6);316INSTANTIATE_TEMPLATE_MV(00000c00, 00000000);317INSTANTIATE_TEMPLATE_MV(00000fc0, 00000000);318INSTANTIATE_TEMPLATE_MV(000013e0, 00001000);319INSTANTIATE_TEMPLATE_MV(00001c00, 00000000);320INSTANTIATE_TEMPLATE_MV(00002400, 00000000);321INSTANTIATE_TEMPLATE_MV(00003000, 00000000);322INSTANTIATE_TEMPLATE_MV(00003000, 00001000);323INSTANTIATE_TEMPLATE_MV(00003000, 00002000);324INSTANTIATE_TEMPLATE_MV(00003000, 00003000);325INSTANTIATE_TEMPLATE_MV(00003010, 00000000);326INSTANTIATE_TEMPLATE_MV(00003c00, 00003c00);327INSTANTIATE_TEMPLATE_MV(00040010, 00000000);328INSTANTIATE_TEMPLATE_MV(00060000, 00000000);329INSTANTIATE_TEMPLATE_MV(00061000, 00000000);330INSTANTIATE_TEMPLATE_MV(00070000, 00030000);331INSTANTIATE_TEMPLATE_MV(00073ee0, 00033060);332INSTANTIATE_TEMPLATE_MV(00073f9f, 0000001f);333INSTANTIATE_TEMPLATE_MV(000f0000, 00000000);334INSTANTIATE_TEMPLATE_MV(000f0010, 00000000);335INSTANTIATE_TEMPLATE_MV(00100200, 00000000);336INSTANTIATE_TEMPLATE_MV(00100210, 00000000);337INSTANTIATE_TEMPLATE_MV(00160000, 00000000);338INSTANTIATE_TEMPLATE_MV(00170000, 00000000);339INSTANTIATE_TEMPLATE_MV(001c0000, 00000000);340INSTANTIATE_TEMPLATE_MV(001d0000, 00000000);341INSTANTIATE_TEMPLATE_MV(001e0000, 00000000);342INSTANTIATE_TEMPLATE_MV(001f0000, 00000000);343INSTANTIATE_TEMPLATE_MV(001f0000, 00010000);344INSTANTIATE_TEMPLATE_MV(001f0000, 00100000);345INSTANTIATE_TEMPLATE_MV(001f0000, 001f0000);346INSTANTIATE_TEMPLATE_MV(001f3000, 00000000);347INSTANTIATE_TEMPLATE_MV(001f3000, 00001000);348INSTANTIATE_TEMPLATE_MV(001f3000, 001f0000);349INSTANTIATE_TEMPLATE_MV(001f300f, 0000000d);350INSTANTIATE_TEMPLATE_MV(001f301f, 0000000d);351INSTANTIATE_TEMPLATE_MV(001f33e0, 000103e0);352INSTANTIATE_TEMPLATE_MV(001f3800, 00000000);353INSTANTIATE_TEMPLATE_MV(00401000, 00400000);354INSTANTIATE_TEMPLATE_MV(005f3000, 001f0000);355INSTANTIATE_TEMPLATE_MV(005f3000, 001f1000);356INSTANTIATE_TEMPLATE_MV(00800010, 00000000);357INSTANTIATE_TEMPLATE_MV(00800400, 00000000);358INSTANTIATE_TEMPLATE_MV(00800410, 00000000);359INSTANTIATE_TEMPLATE_MV(00803000, 00002000);360INSTANTIATE_TEMPLATE_MV(00870000, 00000000);361INSTANTIATE_TEMPLATE_MV(009f0000, 00010000);362INSTANTIATE_TEMPLATE_MV(00c00000, 00000000);363INSTANTIATE_TEMPLATE_MV(00c00000, 00400000);364INSTANTIATE_TEMPLATE_MV(00c0001f, 00000000);365INSTANTIATE_TEMPLATE_MV(00c001ff, 00000000);366INSTANTIATE_TEMPLATE_MV(00c00200, 00400000);367INSTANTIATE_TEMPLATE_MV(00c0020f, 00400000);368INSTANTIATE_TEMPLATE_MV(00c003e0, 00000000);369INSTANTIATE_TEMPLATE_MV(00c00800, 00000000);370INSTANTIATE_TEMPLATE_MV(00d80800, 00000000);371INSTANTIATE_TEMPLATE_MV(00df0000, 00000000);372INSTANTIATE_TEMPLATE_MV(00df3800, 001f0800);373INSTANTIATE_TEMPLATE_MV(40002000, 40000000);374INSTANTIATE_TEMPLATE_MV(40003c00, 00000000);375INSTANTIATE_TEMPLATE_MV(40040000, 00000000);376INSTANTIATE_TEMPLATE_MV(401f2000, 401f0000);377INSTANTIATE_TEMPLATE_MV(40800c00, 40000400);378INSTANTIATE_TEMPLATE_MV(40c00000, 00000000);379INSTANTIATE_TEMPLATE_MV(40c00000, 00400000);380INSTANTIATE_TEMPLATE_MV(40c00000, 40000000);381INSTANTIATE_TEMPLATE_MV(40c00000, 40800000);382INSTANTIATE_TEMPLATE_MV(40df0000, 00000000);383default: {384static bool printed_preamble = false;385if (!printed_preamble) {386printf("One or more missing template instantiations.\n");387printf(388"Add the following to either GetBitExtractFunction() "389"implementations\n");390printf("in %s near line %d:\n", __FILE__, __LINE__);391printed_preamble = true;392}393394if (y == 0) {395printf(" INSTANTIATE_TEMPLATE_M(%08x);\n", x);396bit_extract_fn = &Instruction::ExtractBitsAbsent;397} else {398printf(" INSTANTIATE_TEMPLATE_MV(%08x, %08x);\n", y, x);399bit_extract_fn = &Instruction::IsMaskedValueAbsent;400}401}402}403return bit_extract_fn;404}405406#undef INSTANTIATE_TEMPLATE_M407#undef INSTANTIATE_TEMPLATE_MV408409bool DecodeNode::TryCompileOptimisedDecodeTable(Decoder* decoder) {410// EitherOr optimisation: if there are only one or two patterns in the table,411// try to optimise the node to exploit that.412size_t table_size = pattern_table_.size();413if ((table_size <= 2) && (GetSampledBitsCount() > 1)) {414// TODO: support 'x' in this optimisation by dropping the sampled bit415// positions before making the mask/value.416if (!PatternContainsSymbol(pattern_table_[0].pattern,417PatternSymbol::kSymbolX) &&418(table_size == 1)) {419// A pattern table consisting of a fixed pattern with no x's, and an420// "otherwise" or absent case. Optimise this into an instruction mask and421// value test.422uint32_t single_decode_mask = 0;423uint32_t single_decode_value = 0;424const std::vector<uint8_t>& bits = GetSampledBits();425426// Construct the instruction mask and value from the pattern.427VIXL_ASSERT(bits.size() == GetPatternLength(pattern_table_[0].pattern));428for (size_t i = 0; i < bits.size(); i++) {429single_decode_mask |= 1U << bits[i];430if (GetSymbolAt(pattern_table_[0].pattern, i) ==431PatternSymbol::kSymbol1) {432single_decode_value |= 1U << bits[i];433}434}435BitExtractFn bit_extract_fn =436GetBitExtractFunction(single_decode_mask, single_decode_value);437438// Create a compiled node that contains a two entry table for the439// either/or cases.440CreateCompiledNode(bit_extract_fn, 2);441442// Set DecodeNode for when the instruction after masking doesn't match the443// value.444CompileNodeForBits(decoder, "unallocated", 0);445446// Set DecodeNode for when it does match.447CompileNodeForBits(decoder, pattern_table_[0].handler, 1);448449return true;450}451}452return false;453}454455CompiledDecodeNode* DecodeNode::Compile(Decoder* decoder) {456if (IsLeafNode()) {457// A leaf node is a simple wrapper around a visitor function, with no458// instruction decoding to do.459CreateVisitorNode();460} else if (!TryCompileOptimisedDecodeTable(decoder)) {461// The "otherwise" node is the default next node if no pattern matches.462std::string otherwise = "unallocated";463464// For each pattern in pattern_table_, create an entry in matches that465// has a corresponding mask and value for the pattern.466std::vector<MaskValuePair> matches;467for (size_t i = 0; i < pattern_table_.size(); i++) {468matches.push_back(GenerateMaskValuePair(469GenerateOrderedPattern(pattern_table_[i].pattern)));470}471472BitExtractFn bit_extract_fn =473GetBitExtractFunction(GenerateSampledBitsMask());474475// Create a compiled node that contains a table with an entry for every bit476// pattern.477CreateCompiledNode(bit_extract_fn,478static_cast<size_t>(1) << GetSampledBitsCount());479VIXL_ASSERT(compiled_node_ != NULL);480481// When we find a pattern matches the representation, set the node's decode482// function for that representation to the corresponding function.483for (uint32_t bits = 0; bits < (1U << GetSampledBitsCount()); bits++) {484for (size_t i = 0; i < matches.size(); i++) {485if ((bits & matches[i].first) == matches[i].second) {486// Only one instruction class should match for each value of bits, so487// if we get here, the node pointed to should still be unallocated.488VIXL_ASSERT(compiled_node_->GetNodeForBits(bits) == NULL);489CompileNodeForBits(decoder, pattern_table_[i].handler, bits);490break;491}492}493494// If the decode_table_ entry for these bits is still NULL, the495// instruction must be handled by the "otherwise" case, which by default496// is the Unallocated visitor.497if (compiled_node_->GetNodeForBits(bits) == NULL) {498CompileNodeForBits(decoder, otherwise, bits);499}500}501}502503VIXL_ASSERT(compiled_node_ != NULL);504return compiled_node_;505}506507void CompiledDecodeNode::Decode(const Instruction* instr) const {508if (IsLeafNode()) {509// If this node is a leaf, call the registered visitor function.510VIXL_ASSERT(decoder_ != NULL);511decoder_->VisitNamedInstruction(instr, instruction_name_);512} else {513// Otherwise, using the sampled bit extractor for this node, look up the514// next node in the decode tree, and call its Decode method.515VIXL_ASSERT(bit_extract_fn_ != NULL);516VIXL_ASSERT((instr->*bit_extract_fn_)() < decode_table_size_);517VIXL_ASSERT(decode_table_[(instr->*bit_extract_fn_)()] != NULL);518decode_table_[(instr->*bit_extract_fn_)()]->Decode(instr);519}520}521522DecodeNode::MaskValuePair DecodeNode::GenerateMaskValuePair(523uint32_t pattern) const {524uint32_t mask = 0, value = 0;525for (size_t i = 0; i < GetPatternLength(pattern); i++) {526PatternSymbol sym = GetSymbolAt(pattern, i);527mask = (mask << 1) | ((sym == PatternSymbol::kSymbolX) ? 0 : 1);528value = (value << 1) | (static_cast<uint32_t>(sym) & 1);529}530return std::make_pair(mask, value);531}532533uint32_t DecodeNode::GenerateOrderedPattern(uint32_t pattern) const {534const std::vector<uint8_t>& sampled_bits = GetSampledBits();535uint64_t temp = 0xffffffffffffffff;536537// Place symbols into the field of set bits. Symbols are two bits wide and538// take values 0, 1 or 2, so 3 will represent "no symbol".539for (size_t i = 0; i < sampled_bits.size(); i++) {540int shift = sampled_bits[i] * 2;541temp ^= static_cast<uint64_t>(kEndOfPattern) << shift;542temp |= static_cast<uint64_t>(GetSymbolAt(pattern, i)) << shift;543}544545// Iterate over temp and extract new pattern ordered by sample position.546uint32_t result = kEndOfPattern; // End of pattern marker.547548// Iterate over the pattern one symbol (two bits) at a time.549for (int i = 62; i >= 0; i -= 2) {550uint32_t sym = (temp >> i) & kPatternSymbolMask;551552// If this is a valid symbol, shift into the result.553if (sym != kEndOfPattern) {554result = (result << 2) | sym;555}556}557558// The length of the ordered pattern must be the same as the input pattern,559// and the number of sampled bits.560VIXL_ASSERT(GetPatternLength(result) == GetPatternLength(pattern));561VIXL_ASSERT(GetPatternLength(result) == sampled_bits.size());562563return result;564}565566uint32_t DecodeNode::GenerateSampledBitsMask() const {567uint32_t mask = 0;568for (int bit : GetSampledBits()) {569mask |= 1 << bit;570}571return mask;572}573574} // namespace aarch64575} // namespace vixl576577578