Make Intel syntax mode friendlier to Microsoft ML assembler (still needs more work).
authorJeff Cohen <jeffc@jolt-lang.org>
Tue, 2 May 2006 01:16:28 +0000 (01:16 +0000)
committerJeff Cohen <jeffc@jolt-lang.org>
Tue, 2 May 2006 01:16:28 +0000 (01:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28044 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/AsmPrinter.h
lib/CodeGen/AsmPrinter.cpp
lib/Target/X86/X86IntelAsmPrinter.cpp
lib/Target/X86/X86IntelAsmPrinter.h

index 2a56543612e5db5cecc4d3824c70684875323b04..93c2f2b114ac02c0a0dcb876d345ff6b66b7f790 100644 (file)
@@ -21,6 +21,7 @@
 
 namespace llvm {
   class Constant;
+  class ConstantArray;
   class Mangler;
   class GlobalVariable;
 
@@ -253,7 +254,11 @@ namespace llvm {
 
     /// EmitZeros - Emit a block of zeros.
     ///
-    void EmitZeros(uint64_t NumZeros) const;
+    virtual void EmitZeros(uint64_t NumZeros) const;
+
+    /// EmitString - Emit a zero-byte-terminated string constant.
+    ///
+    virtual void EmitString(const ConstantArray *CVA) const;
 
     /// EmitConstantValueOnly - Print out the specified constant, without a
     /// storage class.  Only constants of first-class type are allowed here.
index b28c386788949fe3d6ea08a47464ea9355f7d1c5..9e94f7a52fa618d75916557bf13daf5e4f9eae5c 100644 (file)
@@ -372,6 +372,21 @@ static void printAsCString(std::ostream &O, const ConstantArray *CVA,
   O << "\"";
 }
 
+/// EmitString - Emit a zero-byte-terminated string constant.
+///
+void AsmPrinter::EmitString(const ConstantArray *CVA) const {
+  unsigned NumElts = CVA->getNumOperands();
+  if (AscizDirective && NumElts && 
+      cast<ConstantInt>(CVA->getOperand(NumElts-1))->getRawValue() == 0) {
+    O << AscizDirective;
+    printAsCString(O, CVA, NumElts-1);
+  } else {
+    O << AsciiDirective;
+    printAsCString(O, CVA, NumElts);
+  }
+  O << "\n";
+}
+
 /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
 ///
 void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
@@ -382,16 +397,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
     return;
   } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
     if (CVA->isString()) {
-      unsigned NumElts = CVA->getNumOperands();
-      if (AscizDirective && NumElts && 
-          cast<ConstantInt>(CVA->getOperand(NumElts-1))->getRawValue() == 0) {
-        O << AscizDirective;
-        printAsCString(O, CVA, NumElts-1);
-      } else {
-        O << AsciiDirective;
-        printAsCString(O, CVA, NumElts);
-      }
-      O << "\n";
+      EmitString(CVA);
     } else { // Not a string.  Print the values in successive locations
       for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
         EmitGlobalConstant(CVA->getOperand(i));
index e217eef00cc06d053bbac442c51a709f6cf15edd..18295f566c7078e2fb7565aded0c122ff713a78c 100755 (executable)
 
 #include "X86IntelAsmPrinter.h"
 #include "X86.h"
+#include "llvm/Constants.h"
 #include "llvm/Module.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
+X86IntelAsmPrinter::X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM)
+    : X86SharedAsmPrinter(O, TM) {
+  CommentString = ";";
+  GlobalPrefix = "_";
+  PrivateGlobalPrefix = "$";
+  AlignDirective = "\talign\t";
+  ZeroDirective = 0;
+  AsciiDirective = "\tdb\t";
+  AscizDirective = 0;
+  Data8bitsDirective = "\t.db\t";
+  Data16bitsDirective = "\t.dw\t";
+  Data32bitsDirective = "\t.dd\t";
+  Data64bitsDirective = "\t.dq\t";
+  HasDotTypeDotSizeDirective = false;
+
+  O << "\t.686\n\t.model flat\n\toption dotname\n";
+}
+
 /// runOnMachineFunction - This uses the printMachineInstruction()
 /// method to print assembly for each instruction.
 ///
@@ -38,12 +57,11 @@ bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   EmitConstantPool(MF.getConstantPool());
 
   // Print out labels for the function.
-  SwitchSection("\t.text\n", MF.getFunction());
+  SwitchSection(".code\n", MF.getFunction());
   EmitAlignment(4);
-  O << "\t.globl\t" << CurrentFnName << "\n";
-  if (HasDotTypeDotSizeDirective)
-    O << "\t.type\t" << CurrentFnName << ", @function\n";
-  O << CurrentFnName << ":\n";
+  if (MF.getFunction()->getLinkage() == GlobalValue::ExternalLinkage)
+    O << "\tpublic " << CurrentFnName << "\n";
+  O << CurrentFnName << "\tproc near\n";
   
   if (forDarwin) {
     // Emit pre-function debug information.
@@ -71,6 +89,8 @@ bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     DW.EndFunction();
   }
 
+  O << CurrentFnName << "\tendp\n";
+
   // We didn't modify anything.
   return false;
 }
@@ -403,17 +423,75 @@ void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
 
 bool X86IntelAsmPrinter::doInitialization(Module &M) {
   X86SharedAsmPrinter::doInitialization(M);
-  // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
-  //
-  // Bug: gas in `intel_syntax noprefix' mode interprets the symbol `Sp' in an
-  // instruction as a reference to the register named sp, and if you try to
-  // reference a symbol `Sp' (e.g. `mov ECX, OFFSET Sp') then it gets lowercased
-  // before being looked up in the symbol table. This creates spurious
-  // `undefined symbol' errors when linking. Workaround: Do not use `noprefix'
-  // mode, and decorate all register names with percent signs.
-  O << "\t.intel_syntax\n";
+  Mang->markCharUnacceptable('.');
   return false;
 }
 
+void X86IntelAsmPrinter::EmitZeros(uint64_t NumZeros) const {
+  if (NumZeros) {
+    O << "\tdb " << NumZeros << " dup(0)\n";
+  }
+}
+
+void X86IntelAsmPrinter::EmitString(const ConstantArray *CVA) const {
+  unsigned NumElts = CVA->getNumOperands();
+  if (NumElts) {
+    // ML does not have escape sequences except '' for '.  It also has a maximum
+    // string length of 255.
+    unsigned len = 0;
+    bool inString = false;
+    for (unsigned i = 0; i < NumElts; i++) {
+      int n = cast<ConstantInt>(CVA->getOperand(i))->getRawValue() & 255;
+      if (len == 0)
+        O << "\tdb ";
+
+      if (n >= 32 && n <= 127) {
+        if (!inString) {
+          if (len > 0) {
+            O << ",'";
+            len += 2;
+          } else {
+            O << "'";
+            len++;
+          }
+          inString = true;
+        }
+        if (n == '\'') {
+          O << "'";
+          len++;
+        }
+        O << char(n);
+      } else {
+        if (inString) {
+          O << "'";
+          len++;
+          inString = false;
+        }
+        if (len > 0) {
+          O << ",";
+          len++;
+        }
+        O << n;
+        len += 1 + (n > 9) + (n > 99);
+      }
+
+      if (len > 60) {
+        if (inString) {
+          O << "'";
+          inString = false;
+        }
+        O << "\n";
+        len = 0;
+      }
+    }
+
+    if (len > 0) {
+      if (inString)
+        O << "'";
+      O << "\n";
+    }
+  }
+}
+
 // Include the auto-generated portion of the assembly writer.
 #include "X86GenAsmWriter1.inc"
index ffa3990ed1cec249d68bbd25087a9d31c03a24bd..c6ad898d1db0a66697ae7e9f426fb6a59053751d 100755 (executable)
@@ -21,8 +21,7 @@
 namespace llvm {
 
 struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
- X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM)
-    : X86SharedAsmPrinter(O, TM) { }
+  X86IntelAsmPrinter(std::ostream &O, X86TargetMachine &TM);
 
   virtual const char *getPassName() const {
     return "X86 Intel-Style Assembly Printer";
@@ -84,13 +83,16 @@ struct X86IntelAsmPrinter : public X86SharedAsmPrinter {
                        unsigned AsmVariant, const char *ExtraCode);
   bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                              unsigned AsmVariant, const char *ExtraCode);
-    void printMachineInstruction(const MachineInstr *MI);
+  void printMachineInstruction(const MachineInstr *MI);
   void printOp(const MachineOperand &MO, const char *Modifier = 0);
   void printSSECC(const MachineInstr *MI, unsigned Op);
   void printMemReference(const MachineInstr *MI, unsigned Op);
   void printPICLabel(const MachineInstr *MI, unsigned Op);
   bool runOnMachineFunction(MachineFunction &F);
   bool doInitialization(Module &M);
+
+  virtual void EmitZeros(uint64_t NumZeros) const;
+  virtual void EmitString(const ConstantArray *CVA) const;
 };
 
 } // end namespace llvm