#include "AsmWriterInst.h"
#include "CodeGenTarget.h"
-#include "Record.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
using namespace llvm;
std::string Result = Str + "(MI";
if (MIOpNo != ~0U)
Result += ", " + utostr(MIOpNo);
+ Result += ", O";
if (!MiModifier.empty())
Result += ", \"" + MiModifier + '"';
return Result + "); ";
/// ParseAsmString - Parse the specified Instruction's AsmString into this
/// AsmWriterInst.
///
-AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter) {
+AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI,
+ unsigned Variant,
+ int FirstOperandColumn,
+ int OperandSpacing) {
this->CGI = &CGI;
- unsigned Variant = AsmWriter->getValueAsInt("Variant");
- int FirstOperandColumn = AsmWriter->getValueAsInt("FirstOperandColumn");
- int OperandSpacing = AsmWriter->getValueAsInt("OperandSpacing");
-
- 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;
// 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') {
unsigned DestColumn = FirstOperandColumn +
CurColumn++ * OperandSpacing;
Operands.push_back(
- AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
- AsmWriterOperand::isLiteralStatementOperand));
+ AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
+ AsmWriterOperand::isLiteralStatementOperand));
break;
} else if (std::string("${|}\\").find(AsmString[DollarPos+1])
!= std::string::npos) {
AddLiteralString(std::string(1, AsmString[DollarPos+1]));
} else {
- throw "Non-supported escaped character found in instruction '" +
- CGI.TheDef->getName() + "'!";
+ PrintFatalError("Non-supported escaped character found in instruction '" +
+ CGI.TheDef->getName() + "'!");
}
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.
// brace.
if (hasCurlyBraces) {
if (VarEnd >= AsmString.size())
- throw "Reached end of string before terminating curly brace in '"
- + CGI.TheDef->getName() + "'";
+ PrintFatalError("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() + "'";
+ PrintFatalError("Reached end of string before terminating curly brace in '"
+ + CGI.TheDef->getName() + "'");
unsigned ModifierStart = VarEnd;
while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
Modifier = std::string(AsmString.begin()+ModifierStart,
AsmString.begin()+VarEnd);
if (Modifier.empty())
- throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'";
+ PrintFatalError("Bad operand modifier name in '"+ CGI.TheDef->getName() + "'");
}
if (AsmString[VarEnd] != '}')
- throw "Variable name beginning with '{' did not end with '}' in '"
- + CGI.TheDef->getName() + "'";
+ PrintFatalError("Variable name beginning with '{' did not end with '}' in '"
+ + CGI.TheDef->getName() + "'");
++VarEnd;
}
if (VarName.empty() && Modifier.empty())
- throw "Stray '$' in '" + CGI.TheDef->getName() +
- "' asm string, maybe you want $$?";
+ PrintFatalError("Stray '$' in '" + CGI.TheDef->getName() +
+ "' asm string, maybe you want $$?");
if (VarName.empty()) {
// Just a modifier, pass this into PrintSpecial.
- Operands.push_back(AsmWriterOperand("PrintSpecial", ~0U, Modifier));
+ Operands.push_back(AsmWriterOperand("PrintSpecial",
+ ~0U,
+ ~0U,
+ Modifier));
} else {
// Otherwise, normal operand.
- unsigned OpNo = CGI.getOperandNamed(VarName);
- CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
+ unsigned OpNo = CGI.Operands.getOperandNamed(VarName);
+ CGIOperandList::OperandInfo OpInfo = CGI.Operands[OpNo];
- if (CurVariant == Variant || CurVariant == ~0U) {
- unsigned MIOp = OpInfo.MIOperandNo;
- Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
- Modifier));
- }
+ unsigned MIOp = OpInfo.MIOperandNo;
+ Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName,
+ OpNo, MIOp, Modifier));
}
LastEmitted = VarEnd;
}
}
Operands.push_back(AsmWriterOperand("return;",
- AsmWriterOperand::isLiteralStatementOperand));
+ AsmWriterOperand::isLiteralStatementOperand));
}
/// MatchesAllButOneOp - If this instruction is exactly identical to the
}
}
return MismatchOperand;
-}
\ No newline at end of file
+}