Forgot to check that debug information is supported.
[oota-llvm.git] / utils / TableGen / AsmWriterEmitter.cpp
index e3d806ade2bc7d560cb041704606486cb1688fcb..6d2fa5578c9c7e99f40744ae7955d632e5e574ab 100644 (file)
@@ -45,7 +45,10 @@ namespace llvm {
     /// an operand, specified with syntax like ${opname:modifier}.
     std::string MiModifier;
 
-    AsmWriterOperand(const std::string &LitStr)
+    // To make VS STL happy
+    AsmWriterOperand():OperandType(isLiteralTextOperand) {}
+
+    explicit AsmWriterOperand(const std::string &LitStr)
       : OperandType(isLiteralTextOperand), Str(LitStr) {}
 
     AsmWriterOperand(const std::string &Printer, unsigned OpNo, 
@@ -122,7 +125,7 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned 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.
@@ -132,6 +135,23 @@ AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
         AddLiteralString(std::string(AsmString.begin()+LastEmitted,
                                      AsmString.begin()+DollarPos));
       LastEmitted = DollarPos;
+    } else if (AsmString[DollarPos] == '\\') {
+      if (DollarPos+1 != AsmString.size() &&
+          (CurVariant == Variant || CurVariant == ~0U)) {
+        if (AsmString[DollarPos+1] == 'n') {
+          AddLiteralString("\\n");
+        } else if (AsmString[DollarPos+1] == 't') {
+          AddLiteralString("\\t");
+        } 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() + "'!";
+        }
+        LastEmitted = DollarPos+2;
+        continue;
+      }
     } else if (AsmString[DollarPos] == '{') {
       if (CurVariant != ~0U)
         throw "Nested variants found for instruction '" +
@@ -242,11 +262,12 @@ unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
 
   unsigned MismatchOperand = ~0U;
   for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
-    if (Operands[i] != Other.Operands[i])
+    if (Operands[i] != Other.Operands[i]) {
       if (MismatchOperand != ~0U)  // Already have one mismatch?
         return ~1U;
       else
         MismatchOperand = i;
+    }
   }
   return MismatchOperand;
 }
@@ -345,7 +366,7 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
   
   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
     const AsmWriterInst *Inst = getAsmWriterInstByID(i);
-    if (Inst == 0) continue;  // PHI, INLINEASM, LABEL, etc.
+    if (Inst == 0) continue;  // PHI, INLINEASM, DBG_LABEL, etc.
     
     std::string Command;
     if (Inst->Operands.empty())
@@ -518,7 +539,7 @@ void AsmWriterEmitter::run(std::ostream &O) {
   }
   
   // Figure out how many bits we used for the string index.
-  unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx);
+  unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+1);
   
   // To reduce code size, we compactify common instructions into a few bits
   // in the opcode-indexed table.
@@ -619,14 +640,34 @@ void AsmWriterEmitter::run(std::ostream &O) {
   }
   O << "\";\n\n";
 
+  O << "  if (TAI->doesSupportDebugInformation()) {\n"
+    << "    const MachineFunction *MF = MI->getParent()->getParent();\n"
+    << "    static DebugLoc PrevDL = DebugLoc::getUnknownLoc();\n"
+    << "    DebugLoc CurDL = MI->getDebugLoc();\n\n"
+    << "    if (!CurDL.isUnknown() && PrevDL != CurDL) {\n"
+    << "      DebugLocTuple DLT = MF->getDebugLocTuple(CurDL);\n"
+    << "      printLabel(DW->RecordSourceLine(DLT.Line, DLT.Col, DLT.Src));\n"
+    << "    }\n\n"
+    << "    PrevDL = CurDL;\n"
+    << "  }\n\n";
+
   O << "  if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {\n"
+    << "    O << \"\\t\";\n"
     << "    printInlineAsm(MI);\n"
     << "    return true;\n"
-    << "  } else if (MI->getOpcode() == TargetInstrInfo::LABEL) {\n"
+    << "  } else if (MI->isLabel()) {\n"
     << "    printLabel(MI);\n"
     << "    return true;\n"
+    << "  } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) {\n"
+    << "    printDeclare(MI);\n"
+    << "    return true;\n"
+    << "  } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {\n"
+    << "    printImplicitDef(MI);\n"
+    << "    return true;\n"
     << "  }\n\n";
   
+  O << "  O << \"\\t\";\n\n";
+
   O << "  // Emit the opcode for the instruction.\n"
     << "  unsigned Bits = OpInfo[MI->getOpcode()];\n"
     << "  if (Bits == 0) return false;\n"