mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 22:50:47 +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(""),
|
MatchPrefix("match-prefix", cl::init(""),
|
||||||
cl::desc("Only match instructions with the given prefix"));
|
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.
|
/// TokenizeAsmString - Tokenize a simplified assembly string.
|
||||||
static void TokenizeAsmString(StringRef AsmString,
|
static void TokenizeAsmString(StringRef AsmString,
|
||||||
SmallVectorImpl<StringRef> &Tokens) {
|
SmallVectorImpl<StringRef> &Tokens) {
|
||||||
@ -516,7 +468,6 @@ struct InstructionInfo {
|
|||||||
return !(HasLT ^ HasGT);
|
return !(HasLT ^ HasGT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
void dump();
|
void dump();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -932,7 +883,8 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
|
|||||||
|
|
||||||
II->InstrName = CGI.TheDef->getName();
|
II->InstrName = CGI.TheDef->getName();
|
||||||
II->Instr = &CGI;
|
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
|
// Remove comments from the asm string. We know that the asmstring only
|
||||||
// has one line.
|
// has one line.
|
||||||
@ -944,7 +896,8 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
|
|||||||
|
|
||||||
TokenizeAsmString(II->AsmString, II->Tokens);
|
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))
|
if (!IsAssemblerInstruction(CGI.TheDef->getName(), CGI, II->Tokens))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -53,8 +53,6 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
|||||||
int OperandSpacing) {
|
int OperandSpacing) {
|
||||||
this->CGI = &CGI;
|
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.
|
// This is the number of tabs we've seen if we're doing columnar layout.
|
||||||
unsigned CurColumn = 0;
|
unsigned CurColumn = 0;
|
||||||
|
|
||||||
@ -62,54 +60,48 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
|||||||
// NOTE: Any extensions to this code need to be mirrored in the
|
// NOTE: Any extensions to this code need to be mirrored in the
|
||||||
// AsmPrinter::printInlineAsm code that executes as compile time (assuming
|
// AsmPrinter::printInlineAsm code that executes as compile time (assuming
|
||||||
// that inline asm strings should also get the new feature)!
|
// 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;
|
std::string::size_type LastEmitted = 0;
|
||||||
while (LastEmitted != AsmString.size()) {
|
while (LastEmitted != AsmString.size()) {
|
||||||
std::string::size_type DollarPos =
|
std::string::size_type DollarPos =
|
||||||
AsmString.find_first_of("${|}\\", LastEmitted);
|
AsmString.find_first_of("$\\", LastEmitted);
|
||||||
if (DollarPos == std::string::npos) DollarPos = AsmString.size();
|
if (DollarPos == std::string::npos) DollarPos = AsmString.size();
|
||||||
|
|
||||||
// Emit a constant string fragment.
|
// Emit a constant string fragment.
|
||||||
|
|
||||||
if (DollarPos != LastEmitted) {
|
if (DollarPos != LastEmitted) {
|
||||||
if (CurVariant == Variant || CurVariant == ~0U) {
|
for (; LastEmitted != DollarPos; ++LastEmitted)
|
||||||
for (; LastEmitted != DollarPos; ++LastEmitted)
|
switch (AsmString[LastEmitted]) {
|
||||||
switch (AsmString[LastEmitted]) {
|
case '\n':
|
||||||
case '\n':
|
AddLiteralString("\\n");
|
||||||
AddLiteralString("\\n");
|
break;
|
||||||
break;
|
case '\t':
|
||||||
case '\t':
|
// If the asm writer is not using a columnar layout, \t is not
|
||||||
// If the asm writer is not using a columnar layout, \t is not
|
// magic.
|
||||||
// magic.
|
if (FirstOperandColumn == -1 || OperandSpacing == -1) {
|
||||||
if (FirstOperandColumn == -1 || OperandSpacing == -1) {
|
AddLiteralString("\\t");
|
||||||
AddLiteralString("\\t");
|
} else {
|
||||||
} else {
|
// We recognize a tab as an operand delimeter.
|
||||||
// We recognize a tab as an operand delimeter.
|
unsigned DestColumn = FirstOperandColumn +
|
||||||
unsigned DestColumn = FirstOperandColumn +
|
CurColumn++ * OperandSpacing;
|
||||||
CurColumn++ * OperandSpacing;
|
Operands.push_back(
|
||||||
Operands.push_back(
|
AsmWriterOperand(
|
||||||
AsmWriterOperand(
|
"O.PadToColumn(" +
|
||||||
"O.PadToColumn(" +
|
utostr(DestColumn) + ");\n",
|
||||||
utostr(DestColumn) + ");\n",
|
AsmWriterOperand::isLiteralStatementOperand));
|
||||||
AsmWriterOperand::isLiteralStatementOperand));
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case '"':
|
||||||
case '"':
|
AddLiteralString("\\\"");
|
||||||
AddLiteralString("\\\"");
|
break;
|
||||||
break;
|
case '\\':
|
||||||
case '\\':
|
AddLiteralString("\\\\");
|
||||||
AddLiteralString("\\\\");
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
AddLiteralString(std::string(1, AsmString[LastEmitted]));
|
||||||
AddLiteralString(std::string(1, AsmString[LastEmitted]));
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LastEmitted = DollarPos;
|
|
||||||
}
|
|
||||||
} else if (AsmString[DollarPos] == '\\') {
|
} else if (AsmString[DollarPos] == '\\') {
|
||||||
if (DollarPos+1 != AsmString.size() &&
|
if (DollarPos+1 != AsmString.size()) {
|
||||||
(CurVariant == Variant || CurVariant == ~0U)) {
|
|
||||||
if (AsmString[DollarPos+1] == 'n') {
|
if (AsmString[DollarPos+1] == 'n') {
|
||||||
AddLiteralString("\\n");
|
AddLiteralString("\\n");
|
||||||
} else if (AsmString[DollarPos+1] == 't') {
|
} else if (AsmString[DollarPos+1] == 't') {
|
||||||
@ -137,29 +129,9 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
|||||||
LastEmitted = DollarPos+2;
|
LastEmitted = DollarPos+2;
|
||||||
continue;
|
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() &&
|
} else if (DollarPos+1 != AsmString.size() &&
|
||||||
AsmString[DollarPos+1] == '$') {
|
AsmString[DollarPos+1] == '$') {
|
||||||
if (CurVariant == Variant || CurVariant == ~0U) {
|
AddLiteralString("$"); // "$$" -> $
|
||||||
AddLiteralString("$"); // "$$" -> $
|
|
||||||
}
|
|
||||||
LastEmitted = DollarPos+2;
|
LastEmitted = DollarPos+2;
|
||||||
} else {
|
} else {
|
||||||
// Get the name of the variable.
|
// Get the name of the variable.
|
||||||
@ -229,13 +201,9 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
|
|||||||
unsigned OpNo = CGI.getOperandNamed(VarName);
|
unsigned OpNo = CGI.getOperandNamed(VarName);
|
||||||
CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
|
CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
|
||||||
|
|
||||||
if (CurVariant == Variant || CurVariant == ~0U) {
|
unsigned MIOp = OpInfo.MIOperandNo;
|
||||||
unsigned MIOp = OpInfo.MIOperandNo;
|
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
|
||||||
Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
|
OpNo, MIOp, Modifier));
|
||||||
OpNo,
|
|
||||||
MIOp,
|
|
||||||
Modifier));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LastEmitted = VarEnd;
|
LastEmitted = VarEnd;
|
||||||
}
|
}
|
||||||
|
@ -321,3 +321,52 @@ HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const {
|
|||||||
return MVT::Other;
|
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 Record;
|
||||||
class DagInit;
|
class DagInit;
|
||||||
class CodeGenTarget;
|
class CodeGenTarget;
|
||||||
|
class StringRef;
|
||||||
|
|
||||||
class CodeGenInstruction {
|
class CodeGenInstruction {
|
||||||
public:
|
public:
|
||||||
@ -201,6 +202,12 @@ namespace llvm {
|
|||||||
/// MVT::Other.
|
/// MVT::Other.
|
||||||
MVT::SimpleValueType
|
MVT::SimpleValueType
|
||||||
HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const;
|
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