Add support for modifier strings in machine instr descriptions. This allows

us to avoid creating lots of "Operand" types with different printers, instead
we can fold several together and use modifiers.  For example, we can now use:

${target:call} to say that the operand should be printed like a 'call' operand.

llvm-svn: 26024
This commit is contained in:
Chris Lattner 2006-02-06 23:40:48 +00:00
parent 232dd5c069
commit cf81cdcf95

View File

@ -37,17 +37,23 @@ namespace {
/// MiOpNo - For isMachineInstrOperand, this is the operand number of the
/// machine instruction.
unsigned MIOpNo;
/// MiModifier - For isMachineInstrOperand, this is the modifier string for
/// an operand, specified with syntax like ${opname:modifier}.
std::string MiModifier;
AsmWriterOperand(const std::string &LitStr)
: OperandType(isLiteralTextOperand), Str(LitStr) {}
AsmWriterOperand(const std::string &Printer, unsigned OpNo)
: OperandType(isMachineInstrOperand), Str(Printer), MIOpNo(OpNo) {}
AsmWriterOperand(const std::string &Printer, unsigned OpNo,
const std::string &Modifier)
: OperandType(isMachineInstrOperand), Str(Printer), MIOpNo(OpNo),
MiModifier(Modifier) {}
bool operator!=(const AsmWriterOperand &Other) const {
if (OperandType != Other.OperandType || Str != Other.Str) return true;
if (OperandType == isMachineInstrOperand)
return MIOpNo != Other.MIOpNo;
return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
return false;
}
bool operator==(const AsmWriterOperand &Other) const {
@ -84,8 +90,12 @@ namespace {
void AsmWriterOperand::EmitCode(std::ostream &OS) const {
if (OperandType == isLiteralTextOperand)
OS << "O << \"" << Str << "\"; ";
else
OS << Str << "(MI, " << MIOpNo << "); ";
else {
OS << Str << "(MI, " << MIOpNo;
if (!MiModifier.empty())
OS << ", \"" << MiModifier << '"';
OS << "); ";
}
}
@ -155,6 +165,10 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
std::string VarName(AsmString.begin()+DollarPos+1,
AsmString.begin()+VarEnd);
// Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
// into printOperand.
std::string Modifier;
// In order to avoid starting the next string at the terminating curly
// brace, advance the end position past it if we found an opening curly
// brace.
@ -162,6 +176,23 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
if (VarEnd >= AsmString.size())
throw "Reached end of string before terminating curly brace in '"
+ CGI.TheDef->getName() + "'";
// Look for a modifier string.
if (AsmString[VarEnd] == ':') {
++VarEnd;
if (VarEnd >= AsmString.size())
throw "Reached end of string before terminating curly brace in '"
+ CGI.TheDef->getName() + "'";
unsigned ModifierStart = VarEnd;
while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
++VarEnd;
Modifier = std::string(AsmString.begin()+ModifierStart,
AsmString.begin()+VarEnd);
if (Modifier.empty())
throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'";
}
if (AsmString[VarEnd] != '}')
throw "Variable name beginning with '{' did not end with '}' in '"
+ CGI.TheDef->getName() + "'";
@ -185,7 +216,8 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
}
if (CurVariant == Variant || CurVariant == ~0U)
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp));
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
Modifier));
LastEmitted = VarEnd;
}
}