[llvm-commits] [llvm] r136405 - in /llvm/trunk/utils/TableGen: FixedLenDecoderEmitter.cpp FixedLenDecoderEmitter.h
Owen Anderson
resistor at mac.com
Thu Jul 28 14:54:31 PDT 2011
Author: resistor
Date: Thu Jul 28 16:54:31 2011
New Revision: 136405
URL: http://llvm.org/viewvc/llvm-project?rev=136405&view=rev
Log:
Enhance the fixed-length decoder emitter to support parsing scattered fields.
Modified:
llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h
Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=136405&r1=136404&r2=136405&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Thu Jul 28 16:54:31 2011
@@ -331,6 +331,9 @@
// Emits code to decode the singleton, and then to decode the rest.
void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,Filter &Best);
+ void emitBinaryParser(raw_ostream &o , unsigned &Indentation,
+ OperandInfo &OpInfo);
+
// Assign a single filter and run with it.
void runSingleFilter(FilterChooser &owner, unsigned startBit, unsigned numBit,
bool mixed);
@@ -563,7 +566,7 @@
"static bool decode" << Namespace << "Instruction" << BitWidth
<< "(MCInst &MI, uint" << BitWidth << "_t insn, uint64_t Address, "
<< "const void *Decoder) {\n";
- o.indent(Indentation) << " unsigned tmp = 0;\n";
+ o.indent(Indentation) << " unsigned tmp = 0;\n(void)tmp;\n";
++Indentation; ++Indentation;
// Emits code to decode the instructions.
@@ -721,6 +724,33 @@
return Num;
}
+void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
+ OperandInfo &OpInfo) {
+ std::string &Decoder = OpInfo.Decoder;
+
+ if (OpInfo.numFields() == 1) {
+ OperandInfo::iterator OI = OpInfo.begin();
+ o.indent(Indentation) << " tmp = fieldFromInstruction" << BitWidth
+ << "(insn, " << OI->Base << ", " << OI->Width
+ << ");\n";
+ } else {
+ o.indent(Indentation) << " tmp = 0;\n";
+ for (OperandInfo::iterator OI = OpInfo.begin(), OE = OpInfo.end();
+ OI != OE; ++OI) {
+ o.indent(Indentation) << " tmp |= (fieldFromInstruction" << BitWidth
+ << "(insn, " << OI->Base << ", " << OI->Width
+ << ") << " << OI->Offset << ");\n";
+ }
+ }
+
+ if (Decoder != "")
+ o.indent(Indentation) << " " << Decoder
+ << "(MI, tmp, Address, Decoder);\n";
+ else
+ o.indent(Indentation) << " MI.addOperand(MCOperand::CreateImm(tmp));\n";
+
+}
+
// Emits code to decode the singleton. Return true if we have matched all the
// well-known bits.
bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
@@ -745,22 +775,13 @@
for (std::vector<OperandInfo>::iterator
I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
// If a custom instruction decoder was specified, use that.
- if (I->FieldBase == ~0U && I->FieldLength == ~0U) {
+ if (I->numFields() == 0 && I->Decoder.size()) {
o.indent(Indentation) << " " << I->Decoder
<< "(MI, insn, Address, Decoder);\n";
break;
}
- o.indent(Indentation)
- << " tmp = fieldFromInstruction" << BitWidth
- << "(insn, " << I->FieldBase << ", " << I->FieldLength << ");\n";
- if (I->Decoder != "") {
- o.indent(Indentation) << " " << I->Decoder
- << "(MI, tmp, Address, Decoder);\n";
- } else {
- o.indent(Indentation)
- << " MI.addOperand(MCOperand::CreateImm(tmp));\n";
- }
+ emitBinaryParser(o, Indentation, *I);
}
o.indent(Indentation) << " return true; // " << nameWithID(Opc)
@@ -799,23 +820,13 @@
for (std::vector<OperandInfo>::iterator
I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
// If a custom instruction decoder was specified, use that.
- if (I->FieldBase == ~0U && I->FieldLength == ~0U) {
+ if (I->numFields() == 0 && I->Decoder.size()) {
o.indent(Indentation) << " " << I->Decoder
<< "(MI, insn, Address, Decoder);\n";
break;
}
- o.indent(Indentation)
- << " tmp = fieldFromInstruction" << BitWidth
- << "(insn, " << I->FieldBase
- << ", " << I->FieldLength << ");\n";
- if (I->Decoder != "") {
- o.indent(Indentation) << " " << I->Decoder
- << "(MI, tmp, Address, Decoder);\n";
- } else {
- o.indent(Indentation)
- << " MI.addOperand(MCOperand::CreateImm(tmp));\n";
- }
+ emitBinaryParser(o, Indentation, *I);
}
o.indent(Indentation) << " return true; // " << nameWithID(Opc)
<< '\n';
@@ -1192,7 +1203,7 @@
// of trying to auto-generate the decoder.
std::string InstDecoder = Def.getValueAsString("DecoderMethod");
if (InstDecoder != "") {
- InsnOperands.push_back(OperandInfo(~0U, ~0U, InstDecoder));
+ InsnOperands.push_back(OperandInfo(InstDecoder));
Operands[Opc] = InsnOperands;
return true;
}
@@ -1215,69 +1226,73 @@
// For each operand, see if we can figure out where it is encoded.
for (std::vector<std::pair<Init*, std::string> >::iterator
NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) {
- unsigned PrevBit = ~0;
- unsigned Base = ~0;
- unsigned PrevPos = ~0;
std::string Decoder = "";
+ // At this point, we can locate the field, but we need to know how to
+ // interpret it. As a first step, require the target to provide callbacks
+ // for decoding register classes.
+ // FIXME: This need to be extended to handle instructions with custom
+ // decoder methods, and operands with (simple) MIOperandInfo's.
+ TypedInit *TI = dynamic_cast<TypedInit*>(NI->first);
+ RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType());
+ Record *TypeRecord = Type->getRecord();
+ bool isReg = false;
+ if (TypeRecord->isSubClassOf("RegisterOperand"))
+ TypeRecord = TypeRecord->getValueAsDef("RegClass");
+ if (TypeRecord->isSubClassOf("RegisterClass")) {
+ Decoder = "Decode" + TypeRecord->getName() + "RegisterClass";
+ isReg = true;
+ }
+
+ RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
+ StringInit *String = DecoderString ?
+ dynamic_cast<StringInit*>(DecoderString->getValue()) : 0;
+ if (!isReg && String && String->getValue() != "")
+ Decoder = String->getValue();
+
+ OperandInfo OpInfo(Decoder);
+ unsigned Base = ~0U;
+ unsigned Width = 0;
+ unsigned Offset = 0;
+
for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) {
VarBitInit *BI = dynamic_cast<VarBitInit*>(Bits.getBit(bi));
- if (!BI) continue;
+ if (!BI) {
+ if (Base != ~0U) {
+ OpInfo.addField(Base, Width, Offset);
+ Base = ~0U;
+ Width = 0;
+ Offset = 0;
+ }
+ continue;
+ }
VarInit *Var = dynamic_cast<VarInit*>(BI->getVariable());
assert(Var);
- unsigned CurrBit = BI->getBitNum();
- if (Var->getName() != NI->second) continue;
-
- // Figure out the lowest bit of the value, and the width of the field.
- // Deliberately don't try to handle cases where the field is scattered,
- // or where not all bits of the the field are explicit.
- if (Base == ~0U && PrevBit == ~0U && PrevPos == ~0U) {
- if (CurrBit == 0)
- Base = bi;
- else
- continue;
+ if (Var->getName() != NI->second) {
+ if (Base != ~0U) {
+ OpInfo.addField(Base, Width, Offset);
+ Base = ~0U;
+ Width = 0;
+ Offset = 0;
+ }
+ continue;
}
- if ((PrevPos != ~0U && bi-1 != PrevPos) ||
- (CurrBit != ~0U && CurrBit-1 != PrevBit)) {
- PrevBit = ~0;
- Base = ~0;
- PrevPos = ~0;
- }
-
- PrevPos = bi;
- PrevBit = CurrBit;
-
- // At this point, we can locate the field, but we need to know how to
- // interpret it. As a first step, require the target to provide callbacks
- // for decoding register classes.
- // FIXME: This need to be extended to handle instructions with custom
- // decoder methods, and operands with (simple) MIOperandInfo's.
- TypedInit *TI = dynamic_cast<TypedInit*>(NI->first);
- RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType());
- Record *TypeRecord = Type->getRecord();
- bool isReg = false;
- if (TypeRecord->isSubClassOf("RegisterOperand"))
- TypeRecord = TypeRecord->getValueAsDef("RegClass");
- if (TypeRecord->isSubClassOf("RegisterClass")) {
- Decoder = "Decode" + TypeRecord->getName() + "RegisterClass";
- isReg = true;
+ if (Base == ~0U) {
+ Base = bi;
+ Width = 1;
+ Offset = BI->getBitNum();
+ } else {
+ ++Width;
}
-
- RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
- StringInit *String = DecoderString ?
- dynamic_cast<StringInit*>(DecoderString->getValue()) :
- 0;
- if (!isReg && String && String->getValue() != "")
- Decoder = String->getValue();
}
- if (Base != ~0U) {
- InsnOperands.push_back(OperandInfo(Base, PrevBit+1, Decoder));
- DEBUG(errs() << "ENCODED OPERAND: $" << NI->second << " @ ("
- << utostr(Base+PrevBit) << ", " << utostr(Base) << ")\n");
- }
+ if (Base != ~0U)
+ OpInfo.addField(Base, Width, Offset);
+
+ if (OpInfo.numFields() > 0)
+ InsnOperands.push_back(OpInfo);
}
Operands[Opc] = InsnOperands;
Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h?rev=136405&r1=136404&r2=136405&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h Thu Jul 28 16:54:31 2011
@@ -22,13 +22,29 @@
namespace llvm {
+struct EncodingField {
+ unsigned Base, Width, Offset;
+ EncodingField(unsigned B, unsigned W, unsigned O)
+ : Base(B), Width(W), Offset(O) { }
+};
+
struct OperandInfo {
- unsigned FieldBase;
- unsigned FieldLength;
+ std::vector<EncodingField> Fields;
std::string Decoder;
- OperandInfo(unsigned FB, unsigned FL, std::string D)
- : FieldBase(FB), FieldLength(FL), Decoder(D) { }
+ OperandInfo(std::string D)
+ : Decoder(D) { }
+
+ void addField(unsigned Base, unsigned Width, unsigned Offset) {
+ Fields.push_back(EncodingField(Base, Width, Offset));
+ }
+
+ unsigned numFields() { return Fields.size(); }
+
+ typedef std::vector<EncodingField>::iterator iterator;
+
+ iterator begin() { return Fields.begin(); }
+ iterator end() { return Fields.end(); }
};
class FixedLenDecoderEmitter : public TableGenBackend {
More information about the llvm-commits
mailing list