forked from OSchip/llvm-project
parent
7ba78302b5
commit
1f7604d892
|
@ -537,8 +537,6 @@ Filter::~Filter() {
|
||||||
// instructions. In order to unambiguously decode the singleton, we need to
|
// instructions. In order to unambiguously decode the singleton, we need to
|
||||||
// match the remaining undecoded encoding bits against the singleton.
|
// match the remaining undecoded encoding bits against the singleton.
|
||||||
void Filter::recurse() {
|
void Filter::recurse() {
|
||||||
std::map<uint64_t, std::vector<unsigned> >::const_iterator mapIterator;
|
|
||||||
|
|
||||||
// Starts by inheriting our parent filter chooser's filter bit values.
|
// Starts by inheriting our parent filter chooser's filter bit values.
|
||||||
std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
|
std::vector<bit_value_t> BitValueArray(Owner->FilterBitValues);
|
||||||
|
|
||||||
|
@ -564,13 +562,11 @@ void Filter::recurse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, create sub choosers.
|
// Otherwise, create sub choosers.
|
||||||
for (mapIterator = FilteredInstructions.begin();
|
for (const auto &Inst : FilteredInstructions) {
|
||||||
mapIterator != FilteredInstructions.end();
|
|
||||||
mapIterator++) {
|
|
||||||
|
|
||||||
// Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
|
// Marks all the segment positions with either BIT_TRUE or BIT_FALSE.
|
||||||
for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
|
for (unsigned bitIndex = 0; bitIndex < NumBits; ++bitIndex) {
|
||||||
if (mapIterator->first & (1ULL << bitIndex))
|
if (Inst.first & (1ULL << bitIndex))
|
||||||
BitValueArray[StartBit + bitIndex] = BIT_TRUE;
|
BitValueArray[StartBit + bitIndex] = BIT_TRUE;
|
||||||
else
|
else
|
||||||
BitValueArray[StartBit + bitIndex] = BIT_FALSE;
|
BitValueArray[StartBit + bitIndex] = BIT_FALSE;
|
||||||
|
@ -579,8 +575,8 @@ void Filter::recurse() {
|
||||||
// Delegates to an inferior filter chooser for further processing on this
|
// Delegates to an inferior filter chooser for further processing on this
|
||||||
// category of instructions.
|
// category of instructions.
|
||||||
FilterChooserMap.insert(std::make_pair(
|
FilterChooserMap.insert(std::make_pair(
|
||||||
mapIterator->first, llvm::make_unique<FilterChooser>(
|
Inst.first, llvm::make_unique<FilterChooser>(
|
||||||
Owner->AllInstructions, mapIterator->second,
|
Owner->AllInstructions, Inst.second,
|
||||||
Owner->Operands, BitValueArray, *Owner)));
|
Owner->Operands, BitValueArray, *Owner)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -616,19 +612,14 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
|
||||||
// A new filter entry begins a new scope for fixup resolution.
|
// A new filter entry begins a new scope for fixup resolution.
|
||||||
TableInfo.FixupStack.push_back(FixupList());
|
TableInfo.FixupStack.push_back(FixupList());
|
||||||
|
|
||||||
std::map<unsigned,
|
|
||||||
std::unique_ptr<const FilterChooser>>::const_iterator filterIterator;
|
|
||||||
|
|
||||||
DecoderTable &Table = TableInfo.Table;
|
DecoderTable &Table = TableInfo.Table;
|
||||||
|
|
||||||
size_t PrevFilter = 0;
|
size_t PrevFilter = 0;
|
||||||
bool HasFallthrough = false;
|
bool HasFallthrough = false;
|
||||||
for (filterIterator = FilterChooserMap.begin();
|
for (auto &Filter : FilterChooserMap) {
|
||||||
filterIterator != FilterChooserMap.end();
|
|
||||||
filterIterator++) {
|
|
||||||
// Field value -1 implies a non-empty set of variable instructions.
|
// Field value -1 implies a non-empty set of variable instructions.
|
||||||
// See also recurse().
|
// See also recurse().
|
||||||
if (filterIterator->first == (unsigned)-1) {
|
if (Filter.first == (unsigned)-1) {
|
||||||
HasFallthrough = true;
|
HasFallthrough = true;
|
||||||
|
|
||||||
// Each scope should always have at least one filter value to check
|
// Each scope should always have at least one filter value to check
|
||||||
|
@ -643,7 +634,7 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
|
||||||
Table.push_back(MCD::OPC_FilterValue);
|
Table.push_back(MCD::OPC_FilterValue);
|
||||||
// Encode and emit the value to filter against.
|
// Encode and emit the value to filter against.
|
||||||
uint8_t Buffer[8];
|
uint8_t Buffer[8];
|
||||||
unsigned Len = encodeULEB128(filterIterator->first, Buffer);
|
unsigned Len = encodeULEB128(Filter.first, Buffer);
|
||||||
Table.insert(Table.end(), Buffer, Buffer + Len);
|
Table.insert(Table.end(), Buffer, Buffer + Len);
|
||||||
// Reserve space for the NumToSkip entry. We'll backpatch the value
|
// Reserve space for the NumToSkip entry. We'll backpatch the value
|
||||||
// later.
|
// later.
|
||||||
|
@ -656,7 +647,7 @@ void Filter::emitTableEntry(DecoderTableInfo &TableInfo) const {
|
||||||
// Now delegate to the sub filter chooser for further decodings.
|
// Now delegate to the sub filter chooser for further decodings.
|
||||||
// The case may fallthrough, which happens if the remaining well-known
|
// The case may fallthrough, which happens if the remaining well-known
|
||||||
// encoding bits do not match exactly.
|
// encoding bits do not match exactly.
|
||||||
filterIterator->second->emitTableEntries(TableInfo);
|
Filter.second->emitTableEntries(TableInfo);
|
||||||
|
|
||||||
// Now that we've emitted the body of the handler, update the NumToSkip
|
// Now that we've emitted the body of the handler, update the NumToSkip
|
||||||
// of the filter itself to be able to skip forward when false. Subtract
|
// of the filter itself to be able to skip forward when false. Subtract
|
||||||
|
@ -863,10 +854,9 @@ emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
|
||||||
OS.indent(Indentation) << "switch (Idx) {\n";
|
OS.indent(Indentation) << "switch (Idx) {\n";
|
||||||
OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
|
OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
|
||||||
unsigned Index = 0;
|
unsigned Index = 0;
|
||||||
for (PredicateSet::const_iterator I = Predicates.begin(), E = Predicates.end();
|
for (const auto &Predicate : Predicates) {
|
||||||
I != E; ++I, ++Index) {
|
OS.indent(Indentation) << "case " << Index++ << ":\n";
|
||||||
OS.indent(Indentation) << "case " << Index << ":\n";
|
OS.indent(Indentation+2) << "return (" << Predicate << ");\n";
|
||||||
OS.indent(Indentation+2) << "return (" << *I << ");\n";
|
|
||||||
}
|
}
|
||||||
OS.indent(Indentation) << "}\n";
|
OS.indent(Indentation) << "}\n";
|
||||||
} else {
|
} else {
|
||||||
|
@ -892,10 +882,9 @@ emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
|
||||||
OS.indent(Indentation) << "switch (Idx) {\n";
|
OS.indent(Indentation) << "switch (Idx) {\n";
|
||||||
OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
|
OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
|
||||||
unsigned Index = 0;
|
unsigned Index = 0;
|
||||||
for (DecoderSet::const_iterator I = Decoders.begin(), E = Decoders.end();
|
for (const auto &Decoder : Decoders) {
|
||||||
I != E; ++I, ++Index) {
|
OS.indent(Indentation) << "case " << Index++ << ":\n";
|
||||||
OS.indent(Indentation) << "case " << Index << ":\n";
|
OS << Decoder;
|
||||||
OS << *I;
|
|
||||||
OS.indent(Indentation+2) << "return S;\n";
|
OS.indent(Indentation+2) << "return S;\n";
|
||||||
}
|
}
|
||||||
OS.indent(Indentation) << "}\n";
|
OS.indent(Indentation) << "}\n";
|
||||||
|
@ -1071,20 +1060,16 @@ void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
|
||||||
|
|
||||||
void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
|
void FilterChooser::emitDecoder(raw_ostream &OS, unsigned Indentation,
|
||||||
unsigned Opc) const {
|
unsigned Opc) const {
|
||||||
std::map<unsigned, std::vector<OperandInfo> >::const_iterator OpIter =
|
for (const auto &Op : Operands.find(Opc)->second) {
|
||||||
Operands.find(Opc);
|
|
||||||
const std::vector<OperandInfo>& InsnOperands = OpIter->second;
|
|
||||||
for (std::vector<OperandInfo>::const_iterator
|
|
||||||
I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
|
|
||||||
// If a custom instruction decoder was specified, use that.
|
// If a custom instruction decoder was specified, use that.
|
||||||
if (I->numFields() == 0 && I->Decoder.size()) {
|
if (Op.numFields() == 0 && Op.Decoder.size()) {
|
||||||
OS.indent(Indentation) << Emitter->GuardPrefix << I->Decoder
|
OS.indent(Indentation) << Emitter->GuardPrefix << Op.Decoder
|
||||||
<< "(MI, insn, Address, Decoder)"
|
<< "(MI, insn, Address, Decoder)"
|
||||||
<< Emitter->GuardPostfix << "\n";
|
<< Emitter->GuardPostfix << "\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
emitBinaryParser(OS, Indentation, *I);
|
emitBinaryParser(OS, Indentation, Op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1864,20 +1849,20 @@ static bool populateInstruction(CodeGenTarget &Target,
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each operand, see if we can figure out where it is encoded.
|
// For each operand, see if we can figure out where it is encoded.
|
||||||
for (std::vector<std::pair<Init*, std::string> >::const_iterator
|
for (const auto &Op : InOutOperands) {
|
||||||
NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) {
|
if (!NumberedInsnOperands[Op.second].empty()) {
|
||||||
if (!NumberedInsnOperands[NI->second].empty()) {
|
|
||||||
InsnOperands.insert(InsnOperands.end(),
|
InsnOperands.insert(InsnOperands.end(),
|
||||||
NumberedInsnOperands[NI->second].begin(),
|
NumberedInsnOperands[Op.second].begin(),
|
||||||
NumberedInsnOperands[NI->second].end());
|
NumberedInsnOperands[Op.second].end());
|
||||||
continue;
|
continue;
|
||||||
} else if (!NumberedInsnOperands[TiedNames[NI->second]].empty()) {
|
}
|
||||||
if (!NumberedInsnOperandsNoTie.count(TiedNames[NI->second])) {
|
if (!NumberedInsnOperands[TiedNames[Op.second]].empty()) {
|
||||||
|
if (!NumberedInsnOperandsNoTie.count(TiedNames[Op.second])) {
|
||||||
// Figure out to which (sub)operand we're tied.
|
// Figure out to which (sub)operand we're tied.
|
||||||
unsigned i = CGI.Operands.getOperandNamed(TiedNames[NI->second]);
|
unsigned i = CGI.Operands.getOperandNamed(TiedNames[Op.second]);
|
||||||
int tiedTo = CGI.Operands[i].getTiedRegister();
|
int tiedTo = CGI.Operands[i].getTiedRegister();
|
||||||
if (tiedTo == -1) {
|
if (tiedTo == -1) {
|
||||||
i = CGI.Operands.getOperandNamed(NI->second);
|
i = CGI.Operands.getOperandNamed(Op.second);
|
||||||
tiedTo = CGI.Operands[i].getTiedRegister();
|
tiedTo = CGI.Operands[i].getTiedRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1885,7 +1870,7 @@ static bool populateInstruction(CodeGenTarget &Target,
|
||||||
std::pair<unsigned, unsigned> SO =
|
std::pair<unsigned, unsigned> SO =
|
||||||
CGI.Operands.getSubOperandNumber(tiedTo);
|
CGI.Operands.getSubOperandNumber(tiedTo);
|
||||||
|
|
||||||
InsnOperands.push_back(NumberedInsnOperands[TiedNames[NI->second]]
|
InsnOperands.push_back(NumberedInsnOperands[TiedNames[Op.second]]
|
||||||
[SO.second]);
|
[SO.second]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1899,7 +1884,7 @@ static bool populateInstruction(CodeGenTarget &Target,
|
||||||
// for decoding register classes.
|
// for decoding register classes.
|
||||||
// FIXME: This need to be extended to handle instructions with custom
|
// FIXME: This need to be extended to handle instructions with custom
|
||||||
// decoder methods, and operands with (simple) MIOperandInfo's.
|
// decoder methods, and operands with (simple) MIOperandInfo's.
|
||||||
TypedInit *TI = cast<TypedInit>(NI->first);
|
TypedInit *TI = cast<TypedInit>(Op.first);
|
||||||
RecordRecTy *Type = cast<RecordRecTy>(TI->getType());
|
RecordRecTy *Type = cast<RecordRecTy>(TI->getType());
|
||||||
Record *TypeRecord = Type->getRecord();
|
Record *TypeRecord = Type->getRecord();
|
||||||
bool isReg = false;
|
bool isReg = false;
|
||||||
|
@ -1943,8 +1928,8 @@ static bool populateInstruction(CodeGenTarget &Target,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Var->getName() != NI->second &&
|
if (Var->getName() != Op.second &&
|
||||||
Var->getName() != TiedNames[NI->second]) {
|
Var->getName() != TiedNames[Op.second]) {
|
||||||
if (Base != ~0U) {
|
if (Base != ~0U) {
|
||||||
OpInfo.addField(Base, Width, Offset);
|
OpInfo.addField(Base, Width, Offset);
|
||||||
Base = ~0U;
|
Base = ~0U;
|
||||||
|
@ -2181,12 +2166,10 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderTableInfo TableInfo;
|
DecoderTableInfo TableInfo;
|
||||||
for (std::map<std::pair<std::string, unsigned>,
|
for (const auto &Opc : OpcMap) {
|
||||||
std::vector<unsigned> >::const_iterator
|
|
||||||
I = OpcMap.begin(), E = OpcMap.end(); I != E; ++I) {
|
|
||||||
// Emit the decoder for this namespace+width combination.
|
// Emit the decoder for this namespace+width combination.
|
||||||
FilterChooser FC(*NumberedInstructions, I->second, Operands,
|
FilterChooser FC(*NumberedInstructions, Opc.second, Operands,
|
||||||
8*I->first.second, this);
|
8*Opc.first.second, this);
|
||||||
|
|
||||||
// The decode table is cleared for each top level decoder function. The
|
// The decode table is cleared for each top level decoder function. The
|
||||||
// predicates and decoders themselves, however, are shared across all
|
// predicates and decoders themselves, however, are shared across all
|
||||||
|
@ -2207,7 +2190,7 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) {
|
||||||
TableInfo.Table.push_back(MCD::OPC_Fail);
|
TableInfo.Table.push_back(MCD::OPC_Fail);
|
||||||
|
|
||||||
// Print the table to the output stream.
|
// Print the table to the output stream.
|
||||||
emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), I->first.first);
|
emitTable(OS, TableInfo.Table, 0, FC.getBitWidth(), Opc.first.first);
|
||||||
OS.flush();
|
OS.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue