summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-08-01 07:43:02 +0000
committerChris Lattner <sabre@nondot.org>2004-08-01 07:43:02 +0000
commit076efa771aa634801202f7b8189e33ee79dfc4ed (patch)
tree461513a67cf6ea30917607c71b1bebf231b8c59a /utils
parent87c5905e0b6f551e21c9a96f1b6418920d908210 (diff)
downloadllvm-076efa771aa634801202f7b8189e33ee79dfc4ed.tar.gz
llvm-076efa771aa634801202f7b8189e33ee79dfc4ed.tar.bz2
llvm-076efa771aa634801202f7b8189e33ee79dfc4ed.tar.xz
Add support for asm printing machine instructions that have operands.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15391 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp50
1 files changed, 48 insertions, 2 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index b2cf1072b9..319fe4f1e9 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -17,6 +17,13 @@
#include <ostream>
using namespace llvm;
+static bool isIdentChar(char C) {
+ return (C >= 'a' && C <= 'z') ||
+ (C >= 'A' && C <= 'Z') ||
+ (C >= '0' && C <= '9') ||
+ C == '_';
+}
+
void AsmWriterEmitter::run(std::ostream &O) {
EmitSourceFileHeader("Assembly Writer Source Fragment", O);
@@ -37,8 +44,47 @@ void AsmWriterEmitter::run(std::ostream &O) {
E = Target.inst_end(); I != E; ++I)
if (!I->second.AsmString.empty()) {
const std::string &AsmString = I->second.AsmString;
- O << " case " << Namespace << "::" << I->first << ": O << \""
- << AsmString << "\" << '\\n'; break;\n";
+ O << " case " << Namespace << "::" << I->first << ": O ";
+
+ std::string::size_type LastEmitted = 0;
+ while (LastEmitted != AsmString.size()) {
+ std::string::size_type DollarPos = AsmString.find('$', LastEmitted);
+ if (DollarPos == std::string::npos) DollarPos = AsmString.size();
+
+ // Emit a constant string fragment.
+ if (DollarPos != LastEmitted) {
+ // TODO: this should eventually handle escaping.
+ O << " << \"" << std::string(AsmString.begin()+LastEmitted,
+ AsmString.begin()+DollarPos) << "\"";
+ LastEmitted = DollarPos;
+ } else if (DollarPos+1 != AsmString.size() &&
+ AsmString[DollarPos+1] == '$') {
+ O << " << '$'"; // "$$" -> $
+ } else {
+ // Get the name of the variable.
+ // TODO: should eventually handle ${foo}bar as $foo
+ std::string::size_type VarEnd = DollarPos+1;
+ while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
+ ++VarEnd;
+ std::string VarName(AsmString.begin()+DollarPos+1,
+ AsmString.begin()+VarEnd);
+ if (VarName.empty())
+ throw "Stray '$' in '" + I->first +
+ "' asm string, maybe you want $$?";
+ unsigned OpNo = I->second.getOperandNamed(VarName);
+
+ // If this is a two-address instruction and we are not accessing the
+ // 0th operand, remove an operand.
+ if (I->second.isTwoAddress && OpNo != 0)
+ --OpNo;
+
+ O << "; printOperand(MI->getOperand(" << OpNo << "), MVT::"
+ << getName(I->second.OperandList[OpNo].Ty) << "); O ";
+ LastEmitted = VarEnd;
+ }
+ }
+
+ O << " << '\\n'; break;\n";
}
O << " }\n"