mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-27 14:45:50 +00:00
move FlattenVariants out of AsmMatcherEmitter into a shared
CodeGenInstruction::FlattenAsmStringVariants method. Use it to simplify the code in AsmWriterInst, which now no longer needs to worry about variants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117886 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
52de0ef922
commit
4d43d0fd99
@ -92,54 +92,6 @@ static cl::opt<std::string>
|
||||
MatchPrefix("match-prefix", cl::init(""),
|
||||
cl::desc("Only match instructions with the given prefix"));
|
||||
|
||||
/// FlattenVariants - Flatten an .td file assembly string by selecting the
|
||||
/// variant at index \arg N.
|
||||
static std::string FlattenVariants(const std::string &AsmString,
|
||||
unsigned N) {
|
||||
StringRef Cur = AsmString;
|
||||
std::string Res = "";
|
||||
|
||||
for (;;) {
|
||||
// Find the start of the next variant string.
|
||||
size_t VariantsStart = 0;
|
||||
for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
|
||||
if (Cur[VariantsStart] == '{' &&
|
||||
(VariantsStart == 0 || (Cur[VariantsStart-1] != '$' &&
|
||||
Cur[VariantsStart-1] != '\\')))
|
||||
break;
|
||||
|
||||
// Add the prefix to the result.
|
||||
Res += Cur.slice(0, VariantsStart);
|
||||
if (VariantsStart == Cur.size())
|
||||
break;
|
||||
|
||||
++VariantsStart; // Skip the '{'.
|
||||
|
||||
// Scan to the end of the variants string.
|
||||
size_t VariantsEnd = VariantsStart;
|
||||
unsigned NestedBraces = 1;
|
||||
for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
|
||||
if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') {
|
||||
if (--NestedBraces == 0)
|
||||
break;
|
||||
} else if (Cur[VariantsEnd] == '{')
|
||||
++NestedBraces;
|
||||
}
|
||||
|
||||
// Select the Nth variant (or empty).
|
||||
StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
|
||||
for (unsigned i = 0; i != N; ++i)
|
||||
Selection = Selection.split('|').second;
|
||||
Res += Selection.split('|').first;
|
||||
|
||||
assert(VariantsEnd != Cur.size() &&
|
||||
"Unterminated variants in assembly string!");
|
||||
Cur = Cur.substr(VariantsEnd + 1);
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
/// TokenizeAsmString - Tokenize a simplified assembly string.
|
||||
static void TokenizeAsmString(StringRef AsmString,
|
||||
SmallVectorImpl<StringRef> &Tokens) {
|
||||
@ -516,7 +468,6 @@ struct InstructionInfo {
|
||||
return !(HasLT ^ HasGT);
|
||||
}
|
||||
|
||||
public:
|
||||
void dump();
|
||||
};
|
||||
|
||||
@ -932,7 +883,8 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
|
||||
|
||||
II->InstrName = CGI.TheDef->getName();
|
||||
II->Instr = &CGI;
|
||||
II->AsmString = FlattenVariants(CGI.AsmString, 0);
|
||||
// TODO: Eventually support asmparser for Variant != 0.
|
||||
II->AsmString = CGI.FlattenAsmStringVariants(CGI.AsmString, 0);
|
||||
|
||||
// Remove comments from the asm string. We know that the asmstring only
|
||||
// has one line.
|
||||
@ -944,7 +896,8 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
|
||||
|
||||
TokenizeAsmString(II->AsmString, II->Tokens);
|
||||
|
||||
// Ignore instructions which shouldn't be matched.
|
||||
// Ignore instructions which shouldn't be matched and diagnose invalid
|
||||
// instruction definitions with an error.
|
||||
if (!IsAssemblerInstruction(CGI.TheDef->getName(), CGI, II->Tokens))
|
||||
continue;
|
||||
|
||||
|
@ -53,8 +53,6 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
||||
int OperandSpacing) {
|
||||
this->CGI = &CGI;
|
||||
|
||||
unsigned CurVariant = ~0U; // ~0 if we are outside a {.|.|.} region, other #.
|
||||
|
||||
// This is the number of tabs we've seen if we're doing columnar layout.
|
||||
unsigned CurColumn = 0;
|
||||
|
||||
@ -62,54 +60,48 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
||||
// NOTE: Any extensions to this code need to be mirrored in the
|
||||
// AsmPrinter::printInlineAsm code that executes as compile time (assuming
|
||||
// that inline asm strings should also get the new feature)!
|
||||
const std::string &AsmString = CGI.AsmString;
|
||||
std::string AsmString = CGI.FlattenAsmStringVariants(CGI.AsmString, Variant);
|
||||
std::string::size_type LastEmitted = 0;
|
||||
while (LastEmitted != AsmString.size()) {
|
||||
std::string::size_type DollarPos =
|
||||
AsmString.find_first_of("${|}\\", LastEmitted);
|
||||
AsmString.find_first_of("$\\", LastEmitted);
|
||||
if (DollarPos == std::string::npos) DollarPos = AsmString.size();
|
||||
|
||||
// Emit a constant string fragment.
|
||||
|
||||
if (DollarPos != LastEmitted) {
|
||||
if (CurVariant == Variant || CurVariant == ~0U) {
|
||||
for (; LastEmitted != DollarPos; ++LastEmitted)
|
||||
switch (AsmString[LastEmitted]) {
|
||||
case '\n':
|
||||
AddLiteralString("\\n");
|
||||
break;
|
||||
case '\t':
|
||||
// If the asm writer is not using a columnar layout, \t is not
|
||||
// magic.
|
||||
if (FirstOperandColumn == -1 || OperandSpacing == -1) {
|
||||
AddLiteralString("\\t");
|
||||
} else {
|
||||
// We recognize a tab as an operand delimeter.
|
||||
unsigned DestColumn = FirstOperandColumn +
|
||||
CurColumn++ * OperandSpacing;
|
||||
Operands.push_back(
|
||||
AsmWriterOperand(
|
||||
"O.PadToColumn(" +
|
||||
utostr(DestColumn) + ");\n",
|
||||
AsmWriterOperand::isLiteralStatementOperand));
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
AddLiteralString("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
AddLiteralString("\\\\");
|
||||
break;
|
||||
default:
|
||||
AddLiteralString(std::string(1, AsmString[LastEmitted]));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
LastEmitted = DollarPos;
|
||||
}
|
||||
for (; LastEmitted != DollarPos; ++LastEmitted)
|
||||
switch (AsmString[LastEmitted]) {
|
||||
case '\n':
|
||||
AddLiteralString("\\n");
|
||||
break;
|
||||
case '\t':
|
||||
// If the asm writer is not using a columnar layout, \t is not
|
||||
// magic.
|
||||
if (FirstOperandColumn == -1 || OperandSpacing == -1) {
|
||||
AddLiteralString("\\t");
|
||||
} else {
|
||||
// We recognize a tab as an operand delimeter.
|
||||
unsigned DestColumn = FirstOperandColumn +
|
||||
CurColumn++ * OperandSpacing;
|
||||
Operands.push_back(
|
||||
AsmWriterOperand(
|
||||
"O.PadToColumn(" +
|
||||
utostr(DestColumn) + ");\n",
|
||||
AsmWriterOperand::isLiteralStatementOperand));
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
AddLiteralString("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
AddLiteralString("\\\\");
|
||||
break;
|
||||
default:
|
||||
AddLiteralString(std::string(1, AsmString[LastEmitted]));
|
||||
break;
|
||||
}
|
||||
} else if (AsmString[DollarPos] == '\\') {
|
||||
if (DollarPos+1 != AsmString.size() &&
|
||||
(CurVariant == Variant || CurVariant == ~0U)) {
|
||||
if (DollarPos+1 != AsmString.size()) {
|
||||
if (AsmString[DollarPos+1] == 'n') {
|
||||
AddLiteralString("\\n");
|
||||
} else if (AsmString[DollarPos+1] == 't') {
|
||||
@ -137,29 +129,9 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
||||
LastEmitted = DollarPos+2;
|
||||
continue;
|
||||
}
|
||||
} else if (AsmString[DollarPos] == '{') {
|
||||
if (CurVariant != ~0U)
|
||||
throw "Nested variants found for instruction '" +
|
||||
CGI.TheDef->getName() + "'!";
|
||||
LastEmitted = DollarPos+1;
|
||||
CurVariant = 0; // We are now inside of the variant!
|
||||
} else if (AsmString[DollarPos] == '|') {
|
||||
if (CurVariant == ~0U)
|
||||
throw "'|' character found outside of a variant in instruction '"
|
||||
+ CGI.TheDef->getName() + "'!";
|
||||
++CurVariant;
|
||||
++LastEmitted;
|
||||
} else if (AsmString[DollarPos] == '}') {
|
||||
if (CurVariant == ~0U)
|
||||
throw "'}' character found outside of a variant in instruction '"
|
||||
+ CGI.TheDef->getName() + "'!";
|
||||
++LastEmitted;
|
||||
CurVariant = ~0U;
|
||||
} else if (DollarPos+1 != AsmString.size() &&
|
||||
AsmString[DollarPos+1] == '$') {
|
||||
if (CurVariant == Variant || CurVariant == ~0U) {
|
||||
AddLiteralString("$"); // "$$" -> $
|
||||
}
|
||||
AddLiteralString("$"); // "$$" -> $
|
||||
LastEmitted = DollarPos+2;
|
||||
} else {
|
||||
// Get the name of the variable.
|
||||
@ -229,13 +201,9 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
||||
unsigned OpNo = CGI.getOperandNamed(VarName);
|
||||
CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
|
||||
|
||||
if (CurVariant == Variant || CurVariant == ~0U) {
|
||||
unsigned MIOp = OpInfo.MIOperandNo;
|
||||
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
|
||||
OpNo,
|
||||
MIOp,
|
||||
Modifier));
|
||||
}
|
||||
unsigned MIOp = OpInfo.MIOperandNo;
|
||||
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
|
||||
OpNo, MIOp, Modifier));
|
||||
}
|
||||
LastEmitted = VarEnd;
|
||||
}
|
||||
|
@ -321,3 +321,52 @@ HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
|
||||
return MVT::Other;
|
||||
}
|
||||
|
||||
|
||||
/// FlattenAsmStringVariants - Flatten the specified AsmString to only
|
||||
/// include text from the specified variant, returning the new string.
|
||||
std::string CodeGenInstruction::
|
||||
FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
|
||||
std::string Res = "";
|
||||
|
||||
for (;;) {
|
||||
// Find the start of the next variant string.
|
||||
size_t VariantsStart = 0;
|
||||
for (size_t e = Cur.size(); VariantsStart != e; ++VariantsStart)
|
||||
if (Cur[VariantsStart] == '{' &&
|
||||
(VariantsStart == 0 || (Cur[VariantsStart-1] != '$' &&
|
||||
Cur[VariantsStart-1] != '\\')))
|
||||
break;
|
||||
|
||||
// Add the prefix to the result.
|
||||
Res += Cur.slice(0, VariantsStart);
|
||||
if (VariantsStart == Cur.size())
|
||||
break;
|
||||
|
||||
++VariantsStart; // Skip the '{'.
|
||||
|
||||
// Scan to the end of the variants string.
|
||||
size_t VariantsEnd = VariantsStart;
|
||||
unsigned NestedBraces = 1;
|
||||
for (size_t e = Cur.size(); VariantsEnd != e; ++VariantsEnd) {
|
||||
if (Cur[VariantsEnd] == '}' && Cur[VariantsEnd-1] != '\\') {
|
||||
if (--NestedBraces == 0)
|
||||
break;
|
||||
} else if (Cur[VariantsEnd] == '{')
|
||||
++NestedBraces;
|
||||
}
|
||||
|
||||
// Select the Nth variant (or empty).
|
||||
StringRef Selection = Cur.slice(VariantsStart, VariantsEnd);
|
||||
for (unsigned i = 0; i != Variant; ++i)
|
||||
Selection = Selection.split('|').second;
|
||||
Res += Selection.split('|').first;
|
||||
|
||||
assert(VariantsEnd != Cur.size() &&
|
||||
"Unterminated variants in assembly string!");
|
||||
Cur = Cur.substr(VariantsEnd + 1);
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ namespace llvm {
|
||||
class Record;
|
||||
class DagInit;
|
||||
class CodeGenTarget;
|
||||
class StringRef;
|
||||
|
||||
class CodeGenInstruction {
|
||||
public:
|
||||
@ -201,6 +202,12 @@ namespace llvm {
|
||||
/// MVT::Other.
|
||||
MVT::SimpleValueType
|
||||
HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
|
||||
|
||||
|
||||
/// FlattenAsmStringVariants - Flatten the specified AsmString to only
|
||||
/// include text from the specified variant, returning the new string.
|
||||
static std::string FlattenAsmStringVariants(StringRef AsmString,
|
||||
unsigned Variant);
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user