mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-30 04:37:20 +00:00
Make Intel syntax mode friendlier to Microsoft ML assembler (still needs more work).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28044 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
eff5c36238
commit
c884db47f1
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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<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"
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user