diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index 2a56543612e..93c2f2b114a 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -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. diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index b28c3867889..9e94f7a52fa 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -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(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(CV)) { if (CVA->isString()) { - unsigned NumElts = CVA->getNumOperands(); - if (AscizDirective && NumElts && - cast(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)); diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp index e217eef00cc..18295f566c7 100755 --- a/lib/Target/X86/X86IntelAsmPrinter.cpp +++ b/lib/Target/X86/X86IntelAsmPrinter.cpp @@ -15,12 +15,31 @@ #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(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" diff --git a/lib/Target/X86/X86IntelAsmPrinter.h b/lib/Target/X86/X86IntelAsmPrinter.h index ffa3990ed1c..c6ad898d1db 100755 --- a/lib/Target/X86/X86IntelAsmPrinter.h +++ b/lib/Target/X86/X86IntelAsmPrinter.h @@ -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