diff options
author | Chris Lattner <sabre@nondot.org> | 2010-02-10 01:45:28 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-02-10 01:45:28 +0000 |
commit | a7d479c7bd9723cabdd7c9e1e9a1e6e482f78e7e (patch) | |
tree | 6bea005bcba8f83a6d53daf54b638d0b307390a5 | |
parent | 5532cf44a012149ce3afce43dbd0651b4d87a505 (diff) |
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 :).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95753 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | utils/TableGen/CodeGenInstruction.cpp | 25 | ||||
-rw-r--r-- | utils/TableGen/CodeGenInstruction.h | 31 | ||||
-rw-r--r-- | utils/TableGen/InstrInfoEmitter.cpp | 15 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 11 |
4 files changed, 57 insertions, 25 deletions
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index 684431a6f4..d31502b1ac 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -33,10 +33,10 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) { I->ParseOperandName(Name, false); // Build the string for the operand - std::string OpConstraint = "(1 << TOI::EARLY_CLOBBER)"; - if (!I->OperandList[Op.first].Constraints[Op.second].empty()) + if (!I->OperandList[Op.first].Constraints[Op.second].isNone()) 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; } @@ -65,13 +65,11 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) { 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!"; - 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) { @@ -210,18 +208,13 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) // For backward compatibility: isTwoAddress means operand 1 is tied to // operand 0. if (isTwoAddress) { - if (!OperandList[1].Constraints[0].empty()) + if (!OperandList[1].Constraints[0].isNone()) throw R->getName() + ": cannot use isTwoAddress property: instruction " "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. std::string DisableEncoding = R->getValueAsString("DisableEncoding"); while (1) { diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index d22ac3e13f..e81e7f43bf 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -32,6 +32,35 @@ namespace llvm { /// instruction. 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 /// operand list for a tablegen instruction. struct OperandInfo { @@ -67,7 +96,7 @@ namespace llvm { /// Constraint info for this operand. This operand can have pieces, so we /// 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, unsigned MION, unsigned MINO, DagInit *MIOI) diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 21d97c3878..898c92af8d 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -118,7 +118,20 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { Res += "|(1<<TOI::OptionalDef)"; // 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); } } diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 2b6e30d93d..da2de6b320 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -402,13 +402,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) { if (OperandList[operandIndex].Constraints.size()) { - const std::string &constraint = OperandList[operandIndex].Constraints[0]; - std::string::size_type tiedToPos; - - if ((tiedToPos = constraint.find(" << 16) | (1 << TOI::TIED_TO))")) != - constraint.npos) { - tiedToPos--; - operandMapping[operandIndex] = constraint[tiedToPos] - '0'; + const CodeGenInstruction::ConstraintInfo &Constraint = + OperandList[operandIndex].Constraints[0]; + if (Constraint.isTied()) { + operandMapping[operandIndex] = Constraint.getTiedOperand(); } else { ++numPhysicalOperands; operandMapping[operandIndex] = operandIndex; |