<div dir="ltr">Hi Daniel,<div><br><div>Looks like this broke a lot of buildbots. I reverted in r363747 to keep things green. See <a href="http://lab.llvm.org:8011/builders/clang-atom-d525-fedora-rel/builds/203/steps/build%20stage%201/logs/stdio">http://lab.llvm.org:8011/builders/clang-atom-d525-fedora-rel/builds/203/steps/build%20stage%201/logs/stdio</a> for an example.</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jun 18, 2019 at 2:52 PM Daniel Sanders via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: dsanders<br>
Date: Tue Jun 18 14:56:04 2019<br>
New Revision: 363744<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=363744&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=363744&view=rev</a><br>
Log:<br>
[tblgen][disasm] Allow multiple encodings to disassemble to the same instruction<br>
<br>
Summary:<br>
Add an AdditionalEncoding class which can be used to define additional encodings<br>
for a given instruction. This causes the disassembler to add an additional<br>
encoding to its matching tables that map to the specified instruction.<br>
<br>
Usage:<br>
def ADD1 : Instruction {<br>
bits<8> Reg;<br>
bits<32> Inst;<br>
<br>
let Size = 4;<br>
let Inst{0-7} = Reg;<br>
let Inst{8-14} = 0;<br>
let Inst{15} = 1; // Continuation bit<br>
let Inst{16-31} = 0;<br>
...<br>
}<br>
def : AdditionalEncoding<ADD1> {<br>
bits<8> Reg;<br>
bits<16> Inst; // You can also have bits<32> and it will still be a 16-bit encoding<br>
let Size = 2;<br>
let Inst{0-3} = 0;<br>
let Inst{4-7} = Reg;<br>
let Inst{8-15} = 0;<br>
...<br>
}<br>
with those definitions, llvm-mc will successfully disassemble both of these:<br>
0x01 0x00<br>
0x10 0x80 0x00 0x00<br>
to:<br>
ADD1 r1<br>
<br>
Depends on D52366<br>
<br>
Reviewers: bogner, charukcs<br>
<br>
Reviewed By: bogner<br>
<br>
Subscribers: nlguillemot, nhaehnle, llvm-commits<br>
<br>
Tags: #llvm<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D52369" rel="noreferrer" target="_blank">https://reviews.llvm.org/D52369</a><br>
<br>
Modified:<br>
llvm/trunk/include/llvm/Target/Target.td<br>
llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/Target/Target.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=363744&r1=363743&r2=363744&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=363744&r1=363743&r2=363744&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Target/Target.td (original)<br>
+++ llvm/trunk/include/llvm/Target/Target.td Tue Jun 18 14:56:04 2019<br>
@@ -398,11 +398,49 @@ include "llvm/Target/TargetSchedule.td"<br>
<br>
class Predicate; // Forward def<br>
<br>
+class InstructionEncoding {<br>
+ // Size of encoded instruction.<br>
+ int Size;<br>
+<br>
+ // The "namespace" in which this instruction exists, on targets like ARM<br>
+ // which multiple ISA namespaces exist.<br>
+ string DecoderNamespace = "";<br>
+<br>
+ // List of predicates which will be turned into isel matching code.<br>
+ list<Predicate> Predicates = [];<br>
+<br>
+ string DecoderMethod = "";<br>
+<br>
+ // Is the instruction decoder method able to completely determine if the<br>
+ // given instruction is valid or not. If the TableGen definition of the<br>
+ // instruction specifies bitpattern A??B where A and B are static bits, the<br>
+ // hasCompleteDecoder flag says whether the decoder method fully handles the<br>
+ // ?? space, i.e. if it is a final arbiter for the instruction validity.<br>
+ // If not then the decoder attempts to continue decoding when the decoder<br>
+ // method fails.<br>
+ //<br>
+ // This allows to handle situations where the encoding is not fully<br>
+ // orthogonal. Example:<br>
+ // * InstA with bitpattern 0b0000????,<br>
+ // * InstB with bitpattern 0b000000?? but the associated decoder method<br>
+ // DecodeInstB() returns Fail when ?? is 0b00 or 0b11.<br>
+ //<br>
+ // The decoder tries to decode a bitpattern that matches both InstA and<br>
+ // InstB bitpatterns first as InstB (because it is the most specific<br>
+ // encoding). In the default case (hasCompleteDecoder = 1), when<br>
+ // DecodeInstB() returns Fail the bitpattern gets rejected. By setting<br>
+ // hasCompleteDecoder = 0 in InstB, the decoder is informed that<br>
+ // DecodeInstB() is not able to determine if all possible values of ?? are<br>
+ // valid or not. If DecodeInstB() returns Fail the decoder will attempt to<br>
+ // decode the bitpattern as InstA too.<br>
+ bit hasCompleteDecoder = 1;<br>
+}<br>
+<br>
//===----------------------------------------------------------------------===//<br>
// Instruction set description - These classes correspond to the C++ classes in<br>
// the Target/TargetInstrInfo.h file.<br>
//<br>
-class Instruction {<br>
+class Instruction : InstructionEncoding {<br>
string Namespace = "";<br>
<br>
dag OutOperandList; // An dag containing the MI def operand list.<br>
@@ -427,10 +465,6 @@ class Instruction {<br>
// from the opcode.<br>
int Size = 0;<br>
<br>
- // DecoderNamespace - The "namespace" in which this instruction exists, on<br>
- // targets like ARM which multiple ISA namespaces exist.<br>
- string DecoderNamespace = "";<br>
-<br>
// Code size, for instruction selection.<br>
// FIXME: What does this actually mean?<br>
int CodeSize = 0;<br>
@@ -532,31 +566,6 @@ class Instruction {<br>
string DisableEncoding = "";<br>
<br>
string PostEncoderMethod = "";<br>
- string DecoderMethod = "";<br>
-<br>
- // Is the instruction decoder method able to completely determine if the<br>
- // given instruction is valid or not. If the TableGen definition of the<br>
- // instruction specifies bitpattern A??B where A and B are static bits, the<br>
- // hasCompleteDecoder flag says whether the decoder method fully handles the<br>
- // ?? space, i.e. if it is a final arbiter for the instruction validity.<br>
- // If not then the decoder attempts to continue decoding when the decoder<br>
- // method fails.<br>
- //<br>
- // This allows to handle situations where the encoding is not fully<br>
- // orthogonal. Example:<br>
- // * InstA with bitpattern 0b0000????,<br>
- // * InstB with bitpattern 0b000000?? but the associated decoder method<br>
- // DecodeInstB() returns Fail when ?? is 0b00 or 0b11.<br>
- //<br>
- // The decoder tries to decode a bitpattern that matches both InstA and<br>
- // InstB bitpatterns first as InstB (because it is the most specific<br>
- // encoding). In the default case (hasCompleteDecoder = 1), when<br>
- // DecodeInstB() returns Fail the bitpattern gets rejected. By setting<br>
- // hasCompleteDecoder = 0 in InstB, the decoder is informed that<br>
- // DecodeInstB() is not able to determine if all possible values of ?? are<br>
- // valid or not. If DecodeInstB() returns Fail the decoder will attempt to<br>
- // decode the bitpattern as InstA too.<br>
- bit hasCompleteDecoder = 1;<br>
<br>
/// Target-specific flags. This becomes the TSFlags field in TargetInstrDesc.<br>
bits<64> TSFlags = 0;<br>
@@ -593,6 +602,13 @@ class Instruction {<br>
bit FastISelShouldIgnore = 0;<br>
}<br>
<br>
+/// Defines an additional encoding that disassembles to the given instruction<br>
+/// Like Instruction, the Inst and SoftFail fields are omitted to allow targets<br>
+// to specify their size.<br>
+class AdditionalEncoding<Instruction I> : InstructionEncoding {<br>
+ Instruction AliasOf = I;<br>
+}<br>
+<br>
/// PseudoInstExpansion - Expansion information for a pseudo-instruction.<br>
/// Which instruction it expands to and how the operands map from the<br>
/// pseudo.<br>
<br>
Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=363744&r1=363743&r2=363744&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=363744&r1=363743&r2=363744&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original)<br>
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Tue Jun 18 14:56:04 2019<br>
@@ -16,9 +16,10 @@<br>
#include "llvm/ADT/APInt.h"<br>
#include "llvm/ADT/ArrayRef.h"<br>
#include "llvm/ADT/CachedHashString.h"<br>
-#include "llvm/ADT/SmallString.h"<br>
-#include "llvm/ADT/SetVector.h"<br>
#include "llvm/ADT/STLExtras.h"<br>
+#include "llvm/ADT/SetVector.h"<br>
+#include "llvm/ADT/SmallString.h"<br>
+#include "llvm/ADT/Statistic.h"<br>
#include "llvm/ADT/StringExtras.h"<br>
#include "llvm/ADT/StringRef.h"<br>
#include "llvm/MC/MCFixedLenDisassembler.h"<br>
@@ -47,6 +48,12 @@ using namespace llvm;<br>
<br>
namespace {<br>
<br>
+STATISTIC(NumEncodings, "Number of encodings considered");<br>
+STATISTIC(NumEncodingsLackingDisasm, "Number of encodings without disassembler info");<br>
+STATISTIC(NumInstructions, "Number of instructions considered");<br>
+STATISTIC(NumEncodingsSupported, "Number of encodings supported");<br>
+STATISTIC(NumEncodingsOmitted, "Number of encodings omitted");<br>
+<br>
struct EncodingField {<br>
unsigned Base, Width, Offset;<br>
EncodingField(unsigned B, unsigned W, unsigned O)<br>
@@ -94,6 +101,15 @@ struct EncodingAndInst {<br>
: EncodingDef(EncodingDef), Inst(Inst) {}<br>
};<br>
<br>
+struct EncodingIDAndOpcode {<br>
+ unsigned EncodingID;<br>
+ unsigned Opcode;<br>
+<br>
+ EncodingIDAndOpcode() : EncodingID(0), Opcode(0) {}<br>
+ EncodingIDAndOpcode(unsigned EncodingID, unsigned Opcode)<br>
+ : EncodingID(EncodingID), Opcode(Opcode) {}<br>
+};<br>
+<br>
raw_ostream &operator<<(raw_ostream &OS, const EncodingAndInst &Value) {<br>
if (Value.EncodingDef != Value.Inst->TheDef)<br>
OS << Value.EncodingDef->getName() << ":";<br>
@@ -102,6 +118,7 @@ raw_ostream &operator<<(raw_ostream &OS,<br>
}<br>
<br>
class FixedLenDecoderEmitter {<br>
+ RecordKeeper &RK;<br>
std::vector<EncodingAndInst> NumberedEncodings;<br>
<br>
public:<br>
@@ -113,7 +130,7 @@ public:<br>
std::string ROK = "MCDisassembler::Success",<br>
std::string RFail = "MCDisassembler::Fail",<br>
std::string L = "")<br>
- : Target(R), PredicateNamespace(std::move(PredicateNamespace)),<br>
+ : RK(R), Target(R), PredicateNamespace(std::move(PredicateNamespace)),<br>
GuardPrefix(std::move(GPrefix)), GuardPostfix(std::move(GPostfix)),<br>
ReturnOK(std::move(ROK)), ReturnFail(std::move(RFail)),<br>
Locals(std::move(L)) {}<br>
@@ -251,10 +268,11 @@ protected:<br>
bool Mixed; // a mixed region contains both set and unset bits<br>
<br>
// Map of well-known segment value to the set of uid's with that value.<br>
- std::map<uint64_t, std::vector<unsigned>> FilteredInstructions;<br>
+ std::map<uint64_t, std::vector<EncodingIDAndOpcode>><br>
+ FilteredInstructions;<br>
<br>
// Set of uid's with non-constant segment values.<br>
- std::vector<unsigned> VariableInstructions;<br>
+ std::vector<EncodingIDAndOpcode> VariableInstructions;<br>
<br>
// Map of well-known segment value to its delegate.<br>
std::map<unsigned, std::unique_ptr<const FilterChooser>> FilterChooserMap;<br>
@@ -263,7 +281,7 @@ protected:<br>
unsigned NumFiltered;<br>
<br>
// Keeps track of the last opcode in the filtered bucket.<br>
- unsigned LastOpcFiltered;<br>
+ EncodingIDAndOpcode LastOpcFiltered;<br>
<br>
public:<br>
Filter(Filter &&f);<br>
@@ -273,7 +291,7 @@ public:<br>
<br>
unsigned getNumFiltered() const { return NumFiltered; }<br>
<br>
- unsigned getSingletonOpc() const {<br>
+ EncodingIDAndOpcode getSingletonOpc() const {<br>
assert(NumFiltered == 1);<br>
return LastOpcFiltered;<br>
}<br>
@@ -337,10 +355,12 @@ protected:<br>
friend class Filter;<br>
<br>
// Vector of codegen instructions to choose our filter.<br>
- ArrayRef<EncodingAndInst> AllInstructions;<br>
+ ArrayRef<const EncodingAndInst> AllInstructions;<br>
<br>
// Vector of uid's for this filter chooser to work on.<br>
- const std::vector<unsigned> &Opcodes;<br>
+ // The first member of the pair is the opcode id being decoded, the second is<br>
+ // the opcode id that should be emitted.<br>
+ const std::vector<EncodingIDAndOpcode> &Opcodes;<br>
<br>
// Lookup table for the operand decoding of instructions.<br>
const std::map<unsigned, std::vector<OperandInfo>> &Operands;<br>
@@ -365,8 +385,8 @@ protected:<br>
const FixedLenDecoderEmitter *Emitter;<br>
<br>
public:<br>
- FilterChooser(ArrayRef<EncodingAndInst> Insts,<br>
- const std::vector<unsigned> &IDs,<br>
+ FilterChooser(ArrayRef<const EncodingAndInst> Insts,<br>
+ const std::vector<EncodingIDAndOpcode> &IDs,<br>
const std::map<unsigned, std::vector<OperandInfo>> &Ops,<br>
unsigned BW, const FixedLenDecoderEmitter *E)<br>
: AllInstructions(Insts), Opcodes(IDs), Operands(Ops),<br>
@@ -375,8 +395,8 @@ public:<br>
doFilter();<br>
}<br>
<br>
- FilterChooser(ArrayRef<EncodingAndInst> Insts,<br>
- const std::vector<unsigned> &IDs,<br>
+ FilterChooser(ArrayRef<const EncodingAndInst> Insts,<br>
+ const std::vector<EncodingIDAndOpcode> &IDs,<br>
const std::map<unsigned, std::vector<OperandInfo>> &Ops,<br>
const std::vector<bit_value_t> &ParentFilterBitValues,<br>
const FilterChooser &parent)<br>
@@ -412,6 +432,15 @@ protected:<br>
}<br>
}<br>
<br>
+ // Emit the name of the encoding/instruction pair.<br>
+ void emitNameWithID(raw_ostream &OS, unsigned Opcode) const {<br>
+ const Record *EncodingDef = AllInstructions[Opcode].EncodingDef;<br>
+ const Record *InstDef = AllInstructions[Opcode].Inst->TheDef;<br>
+ if (EncodingDef != InstDef)<br>
+ OS << EncodingDef->getName() << ":";<br>
+ OS << InstDef->getName();<br>
+ }<br>
+<br>
// Populates the field of the insn given the start position and the number of<br>
// consecutive bits to scan for.<br>
//<br>
@@ -462,7 +491,7 @@ protected:<br>
<br>
// Emits table entries to decode the singleton.<br>
void emitSingletonTableEntry(DecoderTableInfo &TableInfo,<br>
- unsigned Opc) const;<br>
+ EncodingIDAndOpcode Opc) const;<br>
<br>
// Emits code to decode the singleton, and then to decode the rest.<br>
void emitSingletonTableEntry(DecoderTableInfo &TableInfo,<br>
@@ -523,13 +552,13 @@ Filter::Filter(FilterChooser &owner, uns<br>
assert(StartBit + NumBits - 1 < Owner->BitWidth);<br>
<br>
NumFiltered = 0;<br>
- LastOpcFiltered = 0;<br>
+ LastOpcFiltered = {0, 0};<br>
<br>
for (unsigned i = 0, e = Owner->Opcodes.size(); i != e; ++i) {<br>
insn_t Insn;<br>
<br>
// Populates the insn given the uid.<br>
- Owner->insnWithID(Insn, Owner->Opcodes[i]);<br>
+ Owner->insnWithID(Insn, Owner->Opcodes[i].EncodingID);<br>
<br>
uint64_t Field;<br>
// Scans the segment for possibly well-specified encoding bits.<br>
@@ -1025,7 +1054,7 @@ unsigned FilterChooser::getIslands(std::<br>
// 1: Water (the bit value does not affect decoding)<br>
// 2: Island (well-known bit value needed for decoding)<br>
int State = 0;<br>
- int Val = -1;<br>
+ int64_t Val = -1;<br>
<br>
for (unsigned i = 0; i < BitWidth; ++i) {<br>
Val = Value(Insn[i]);<br>
@@ -1313,12 +1342,12 @@ void FilterChooser::emitSoftFailTableEnt<br>
<br>
// Emits table entries to decode the singleton.<br>
void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,<br>
- unsigned Opc) const {<br>
+ EncodingIDAndOpcode Opc) const {<br>
std::vector<unsigned> StartBits;<br>
std::vector<unsigned> EndBits;<br>
std::vector<uint64_t> FieldVals;<br>
insn_t Insn;<br>
- insnWithID(Insn, Opc);<br>
+ insnWithID(Insn, Opc.EncodingID);<br>
<br>
// Look for islands of undecoded bits of the singleton.<br>
getIslands(StartBits, EndBits, FieldVals, Insn);<br>
@@ -1326,7 +1355,7 @@ void FilterChooser::emitSingletonTableEn<br>
unsigned Size = StartBits.size();<br>
<br>
// Emit the predicate table entry if one is needed.<br>
- emitPredicateTableEntry(TableInfo, Opc);<br>
+ emitPredicateTableEntry(TableInfo, Opc.EncodingID);<br>
<br>
// Check any additional encoding fields needed.<br>
for (unsigned I = Size; I != 0; --I) {<br>
@@ -1350,10 +1379,11 @@ void FilterChooser::emitSingletonTableEn<br>
}<br>
<br>
// Check for soft failure of the match.<br>
- emitSoftFailTableEntry(TableInfo, Opc);<br>
+ emitSoftFailTableEntry(TableInfo, Opc.EncodingID);<br>
<br>
bool HasCompleteDecoder;<br>
- unsigned DIdx = getDecoderIndex(TableInfo.Decoders, Opc, HasCompleteDecoder);<br>
+ unsigned DIdx =<br>
+ getDecoderIndex(TableInfo.Decoders, Opc.EncodingID, HasCompleteDecoder);<br>
<br>
// Produce OPC_Decode or OPC_TryDecode opcode based on the information<br>
// whether the instruction decoder is complete or not. If it is complete<br>
@@ -1366,8 +1396,9 @@ void FilterChooser::emitSingletonTableEn<br>
// can decode it.<br>
TableInfo.Table.push_back(HasCompleteDecoder ? MCD::OPC_Decode :<br>
MCD::OPC_TryDecode);<br>
+ NumEncodingsSupported++;<br>
uint8_t Buffer[16], *p;<br>
- encodeULEB128(Opc, Buffer);<br>
+ encodeULEB128(Opc.Opcode, Buffer);<br>
for (p = Buffer; *p >= 128 ; ++p)<br>
TableInfo.Table.push_back(*p);<br>
TableInfo.Table.push_back(*p);<br>
@@ -1393,7 +1424,7 @@ void FilterChooser::emitSingletonTableEn<br>
// Emits table entries to decode the singleton, and then to decode the rest.<br>
void FilterChooser::emitSingletonTableEntry(DecoderTableInfo &TableInfo,<br>
const Filter &Best) const {<br>
- unsigned Opc = Best.getSingletonOpc();<br>
+ EncodingIDAndOpcode Opc = Best.getSingletonOpc();<br>
<br>
// complex singletons need predicate checks from the first singleton<br>
// to refer forward to the variable filterchooser that follows.<br>
@@ -1453,7 +1484,7 @@ bool FilterChooser::filterProcessor(bool<br>
std::vector<uint64_t> FieldVals;<br>
insn_t Insn;<br>
<br>
- insnWithID(Insn, Opcodes[i]);<br>
+ insnWithID(Insn, Opcodes[i].EncodingID);<br>
<br>
// Look for islands of undecoded bits of any instruction.<br>
if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {<br>
@@ -1497,7 +1528,7 @@ bool FilterChooser::filterProcessor(bool<br>
for (unsigned InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) {<br>
insn_t insn;<br>
<br>
- insnWithID(insn, Opcodes[InsnIndex]);<br>
+ insnWithID(insn, Opcodes[InsnIndex].EncodingID);<br>
<br>
for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) {<br>
switch (bitAttrs[BitIndex]) {<br>
@@ -1716,9 +1747,12 @@ void FilterChooser::emitTableEntries(Dec<br>
dumpStack(errs(), "\t\t");<br>
<br>
for (unsigned i = 0; i < Opcodes.size(); ++i) {<br>
- errs() << '\t' << AllInstructions[Opcodes[i]] << " ";<br>
- dumpBits(errs(),<br>
- getBitsField(*AllInstructions[Opcodes[i]].EncodingDef, "Inst"));<br>
+ errs() << '\t';<br>
+ emitNameWithID(errs(), Opcodes[i].EncodingID);<br>
+ errs() << " ";<br>
+ dumpBits(<br>
+ errs(),<br>
+ getBitsField(*AllInstructions[Opcodes[i].EncodingID].EncodingDef, "Inst"));<br>
errs() << '\n';<br>
}<br>
}<br>
@@ -1750,24 +1784,25 @@ static std::string findOperandDecoderMet<br>
return Decoder;<br>
}<br>
<br>
-static bool populateInstruction(CodeGenTarget &Target,<br>
- const CodeGenInstruction &CGI, unsigned Opc,<br>
- std::map<unsigned, std::vector<OperandInfo>> &Operands){<br>
+static bool<br>
+populateInstruction(CodeGenTarget &Target, const Record &EncodingDef,<br>
+ const CodeGenInstruction &CGI, unsigned Opc,<br>
+ std::map<unsigned, std::vector<OperandInfo>> &Operands) {<br>
const Record &Def = *CGI.TheDef;<br>
// If all the bit positions are not specified; do not decode this instruction.<br>
// We are bound to fail! For proper disassembly, the well-known encoding bits<br>
// of the instruction must be fully specified.<br>
<br>
- BitsInit &Bits = getBitsField(Def, "Inst");<br>
+ BitsInit &Bits = getBitsField(EncodingDef, "Inst");<br>
if (Bits.allInComplete()) return false;<br>
<br>
std::vector<OperandInfo> InsnOperands;<br>
<br>
// If the instruction has specified a custom decoding hook, use that instead<br>
// of trying to auto-generate the decoder.<br>
- StringRef InstDecoder = Def.getValueAsString("DecoderMethod");<br>
+ StringRef InstDecoder = EncodingDef.getValueAsString("DecoderMethod");<br>
if (InstDecoder != "") {<br>
- bool HasCompleteInstDecoder = Def.getValueAsBit("hasCompleteDecoder");<br>
+ bool HasCompleteInstDecoder = EncodingDef.getValueAsBit("hasCompleteDecoder");<br>
InsnOperands.push_back(OperandInfo(InstDecoder, HasCompleteInstDecoder));<br>
Operands[Opc] = InsnOperands;<br>
return true;<br>
@@ -2143,7 +2178,7 @@ static void emitDecodeInstruction(format<br>
<< " const FeatureBitset& Bits = STI.getFeatureBits();\n"<br>
<< "\n"<br>
<< " const uint8_t *Ptr = DecodeTable;\n"<br>
- << " uint32_t CurFieldValue = 0;\n"<br>
+ << " InsnType CurFieldValue = 0;\n"<br>
<< " DecodeStatus S = MCDisassembler::Success;\n"<br>
<< " while (true) {\n"<br>
<< " ptrdiff_t Loc = Ptr - DecodeTable;\n"<br>
@@ -2188,7 +2223,7 @@ static void emitDecodeInstruction(format<br>
<< " unsigned Len = *++Ptr;\n"<br>
<< " InsnType FieldValue = fieldFromInstruction(insn, Start, Len);\n"<br>
<< " // Decode the field value.\n"<br>
- << " uint32_t ExpectedValue = decodeULEB128(++Ptr, &Len);\n"<br>
+ << " InsnType ExpectedValue = decodeULEB128(++Ptr, &Len);\n"<br>
<< " Ptr += Len;\n"<br>
<< " // NumToSkip is a plain 24-bit integer.\n"<br>
<< " unsigned NumToSkip = *Ptr++;\n"<br>
@@ -2335,37 +2370,52 @@ void FixedLenDecoderEmitter::run(raw_ost<br>
// Parameterize the decoders based on namespace and instruction width.<br>
const auto &NumberedInstructions = Target.getInstructionsByEnumValue();<br>
NumberedEncodings.reserve(NumberedInstructions.size());<br>
- for (const auto &NumberedInstruction : NumberedInstructions)<br>
+ DenseMap<Record *, unsigned> IndexOfInstruction;<br>
+ for (const auto &NumberedInstruction : NumberedInstructions) {<br>
+ IndexOfInstruction[NumberedInstruction->TheDef] = NumberedEncodings.size();<br>
NumberedEncodings.emplace_back(NumberedInstruction->TheDef, NumberedInstruction);<br>
+ }<br>
+ for (const auto &NumberedAlias : RK.getAllDerivedDefinitions("AdditionalEncoding"))<br>
+ NumberedEncodings.emplace_back(<br>
+ NumberedAlias,<br>
+ &Target.getInstruction(NumberedAlias->getValueAsDef("AliasOf")));<br>
<br>
- std::map<std::pair<std::string, unsigned>,<br>
- std::vector<unsigned>> OpcMap;<br>
+ std::map<std::pair<std::string, unsigned>, std::vector<EncodingIDAndOpcode>><br>
+ OpcMap;<br>
std::map<unsigned, std::vector<OperandInfo>> Operands;<br>
<br>
for (unsigned i = 0; i < NumberedEncodings.size(); ++i) {<br>
+ const Record *EncodingDef = NumberedEncodings[i].EncodingDef;<br>
const CodeGenInstruction *Inst = NumberedEncodings[i].Inst;<br>
const Record *Def = Inst->TheDef;<br>
- unsigned Size = Def->getValueAsInt("Size");<br>
+ unsigned Size = EncodingDef->getValueAsInt("Size");<br>
if (Def->getValueAsString("Namespace") == "TargetOpcode" ||<br>
Def->getValueAsBit("isPseudo") ||<br>
Def->getValueAsBit("isAsmParserOnly") ||<br>
- Def->getValueAsBit("isCodeGenOnly"))<br>
+ Def->getValueAsBit("isCodeGenOnly")) {<br>
+ NumEncodingsLackingDisasm++;<br>
continue;<br>
+ }<br>
+<br>
+ if (i < NumberedInstructions.size())<br>
+ NumInstructions++;<br>
+ NumEncodings++;<br>
<br>
- StringRef DecoderNamespace = Def->getValueAsString("DecoderNamespace");<br>
+ StringRef DecoderNamespace = EncodingDef->getValueAsString("DecoderNamespace");<br>
<br>
if (Size) {<br>
- if (populateInstruction(Target, *Inst, i, Operands)) {<br>
- OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i);<br>
- }<br>
+ if (populateInstruction(Target, *EncodingDef, *Inst, i, Operands)) {<br>
+ OpcMap[std::make_pair(DecoderNamespace, Size)].emplace_back(i, IndexOfInstruction.find(Def)->second);<br>
+ } else<br>
+ NumEncodingsOmitted++;<br>
}<br>
}<br>
<br>
DecoderTableInfo TableInfo;<br>
for (const auto &Opc : OpcMap) {<br>
// Emit the decoder for this namespace+width combination.<br>
- ArrayRef<EncodingAndInst> NumberedEncodingsRef(NumberedEncodings.data(),<br>
- NumberedEncodings.size());<br>
+ ArrayRef<const EncodingAndInst> NumberedEncodingsRef(<br>
+ NumberedEncodings.data(), NumberedEncodings.size());<br>
FilterChooser FC(NumberedEncodingsRef, Opc.second, Operands,<br>
8 * Opc.first.second, this);<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>