forked from OSchip/llvm-project
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:
parent
75c9a4eeae
commit
a9dfb1bc07
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue