Introduce a new CodeGenInstruction::ConstraintInfo class

for representing constraint info semantically instead of
as a c expression that will be blatted out to the .inc
file.  Fix X86RecognizableInstr to use this instead of
parsing C code :).

llvm-svn: 95753
This commit is contained in:
Chris Lattner 2010-02-10 01:45:28 +00:00
parent 75c9a4eeae
commit a9dfb1bc07
4 changed files with 57 additions and 25 deletions

View File

@ -33,10 +33,10 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
I->ParseOperandName(Name, false); I->ParseOperandName(Name, false);
// Build the string for the operand // Build the string for the operand
std::string OpConstraint = "(1 << TOI::EARLY_CLOBBER)"; if (!I->OperandList[Op.first].Constraints[Op.second].isNone())
if (!I->OperandList[Op.first].Constraints[Op.second].empty())
throw "Operand '" + Name + "' cannot have multiple constraints!"; throw "Operand '" + Name + "' cannot have multiple constraints!";
I->OperandList[Op.first].Constraints[Op.second] = OpConstraint; I->OperandList[Op.first].Constraints[Op.second] =
CodeGenInstruction::ConstraintInfo::getEarlyClobber();
return; return;
} }
@ -65,13 +65,11 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp); unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
// Build the string for the operand.
std::string OpConstraint =
"((" + utostr(FlatOpNo) + " << 16) | (1 << TOI::TIED_TO))";
if (!I->OperandList[DestOp.first].Constraints[DestOp.second].empty()) if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone())
throw "Operand '" + DestOpName + "' cannot have multiple constraints!"; throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
I->OperandList[DestOp.first].Constraints[DestOp.second] = OpConstraint; I->OperandList[DestOp.first].Constraints[DestOp.second] =
CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo);
} }
static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) { static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
@ -210,18 +208,13 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
// For backward compatibility: isTwoAddress means operand 1 is tied to // For backward compatibility: isTwoAddress means operand 1 is tied to
// operand 0. // operand 0.
if (isTwoAddress) { if (isTwoAddress) {
if (!OperandList[1].Constraints[0].empty()) if (!OperandList[1].Constraints[0].isNone())
throw R->getName() + ": cannot use isTwoAddress property: instruction " throw R->getName() + ": cannot use isTwoAddress property: instruction "
"already has constraint set!"; "already has constraint set!";
OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))"; OperandList[1].Constraints[0] =
CodeGenInstruction::ConstraintInfo::getTied(0);
} }
// Any operands with unset constraints get 0 as their constraint.
for (unsigned op = 0, e = OperandList.size(); op != e; ++op)
for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j)
if (OperandList[op].Constraints[j].empty())
OperandList[op].Constraints[j] = "0";
// Parse the DisableEncoding field. // Parse the DisableEncoding field.
std::string DisableEncoding = R->getValueAsString("DisableEncoding"); std::string DisableEncoding = R->getValueAsString("DisableEncoding");
while (1) { while (1) {

View File

@ -32,6 +32,35 @@ namespace llvm {
/// instruction. /// instruction.
std::string AsmString; std::string AsmString;
class ConstraintInfo {
enum { None, EarlyClobber, Tied } Kind;
unsigned OtherTiedOperand;
public:
ConstraintInfo() : Kind(None) {}
static ConstraintInfo getEarlyClobber() {
ConstraintInfo I;
I.Kind = EarlyClobber;
return I;
}
static ConstraintInfo getTied(unsigned Op) {
ConstraintInfo I;
I.Kind = Tied;
I.OtherTiedOperand = Op;
return I;
}
bool isNone() const { return Kind == None; }
bool isEarlyClobber() const { return Kind == EarlyClobber; }
bool isTied() const { return Kind == Tied; }
unsigned getTiedOperand() const {
assert(isTied());
return OtherTiedOperand;
}
};
/// OperandInfo - The information we keep track of for each operand in the /// OperandInfo - The information we keep track of for each operand in the
/// operand list for a tablegen instruction. /// operand list for a tablegen instruction.
struct OperandInfo { struct OperandInfo {
@ -67,7 +96,7 @@ namespace llvm {
/// Constraint info for this operand. This operand can have pieces, so we /// Constraint info for this operand. This operand can have pieces, so we
/// track constraint info for each. /// track constraint info for each.
std::vector<std::string> Constraints; std::vector<ConstraintInfo> Constraints;
OperandInfo(Record *R, const std::string &N, const std::string &PMN, OperandInfo(Record *R, const std::string &N, const std::string &PMN,
unsigned MION, unsigned MINO, DagInit *MIOI) unsigned MION, unsigned MINO, DagInit *MIOI)

View File

@ -118,7 +118,20 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
Res += "|(1<<TOI::OptionalDef)"; Res += "|(1<<TOI::OptionalDef)";
// Fill in constraint info. // Fill in constraint info.
Res += ", " + Inst.OperandList[i].Constraints[j]; Res += ", ";
const CodeGenInstruction::ConstraintInfo &Constraint =
Inst.OperandList[i].Constraints[j];
if (Constraint.isNone())
Res += "0";
else if (Constraint.isEarlyClobber())
Res += "(1 << TOI::EARLY_CLOBBER)";
else {
assert(Constraint.isTied());
Res += "((" + utostr(Constraint.getTiedOperand()) +
" << 16) | (1 << TOI::TIED_TO))";
}
Result.push_back(Res); Result.push_back(Res);
} }
} }

View File

@ -402,13 +402,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) { for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
if (OperandList[operandIndex].Constraints.size()) { if (OperandList[operandIndex].Constraints.size()) {
const std::string &constraint = OperandList[operandIndex].Constraints[0]; const CodeGenInstruction::ConstraintInfo &Constraint =
std::string::size_type tiedToPos; OperandList[operandIndex].Constraints[0];
if (Constraint.isTied()) {
if ((tiedToPos = constraint.find(" << 16) | (1 << TOI::TIED_TO))")) != operandMapping[operandIndex] = Constraint.getTiedOperand();
constraint.npos) {
tiedToPos--;
operandMapping[operandIndex] = constraint[tiedToPos] - '0';
} else { } else {
++numPhysicalOperands; ++numPhysicalOperands;
operandMapping[operandIndex] = operandIndex; operandMapping[operandIndex] = operandIndex;