Add support for the -x86-asm-syntax flag, which can be used to choose between

Intel and AT&T style assembly language.  The ultimate goal of this is to
eliminate the GasBugWorkaroundEmitter class, but for now AT&T style emission
is not fully operational.

llvm-svn: 16639
This commit is contained in:
Chris Lattner 2004-10-03 20:36:57 +00:00
parent 4e59a14909
commit 5683260187
3 changed files with 48 additions and 14 deletions

View File

@ -15,7 +15,8 @@ TARGET = X86
# Make sure that tblgen is run, first thing.
$(SourceDepend): X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
X86GenRegisterInfo.inc X86GenInstrNames.inc \
X86GenInstrInfo.inc X86GenAsmWriter.inc
X86GenInstrInfo.inc X86GenATTAsmWriter.inc \
X86GenIntelAsmWriter.inc
TDFILES = $(SourceDir)/$(TARGET).td $(wildcard $(SourceDir)/*.td) \
$(SourceDir)/../Target.td
@ -40,10 +41,14 @@ $(TARGET)GenInstrInfo.inc:: $(TDFILES) $(TBLGEN)
@echo "Building $(TARGET).td instruction information with tblgen"
$(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-instr-desc -o $@
$(TARGET)GenAsmWriter.inc:: $(TDFILES) $(TBLGEN)
@echo "Building $(TARGET).td assembly writer with tblgen"
$(TARGET)GenATTAsmWriter.inc:: $(TDFILES) $(TBLGEN)
@echo "Building $(TARGET).td AT&T assembly writer with tblgen"
$(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-asm-writer -o $@
$(TARGET)GenIntelAsmWriter.inc:: $(TDFILES) $(TBLGEN)
@echo "Building $(TARGET).td Intel assembly writer with tblgen"
$(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-asm-writer -asmwriternum=1 -o $@
#$(TARGET)GenInstrSelector.inc:: $(TDFILES) $(TBLGEN)
# @echo "Building $(TARGET).td instruction selector with tblgen"
# $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-instr-selector -o $@

View File

@ -47,6 +47,18 @@ def X86InstrInfo : InstrInfo {
16];
}
// The X86 target supports two different syntaxes for emitting machine code.
// This is controlled by the -x86-asm-syntax={att|intel}
def ATTAsmWriter : AsmWriter {
string AsmWriterClassName = "ATTAsmPrinter";
int Variant = 0;
}
def IntelAsmWriter : AsmWriter {
string AsmWriterClassName = "IntelAsmPrinter";
int Variant = 1;
}
def X86 : Target {
// Specify the callee saved registers.
let CalleeSavedRegisters = [ESI, EDI, EBX, EBP];
@ -56,4 +68,6 @@ def X86 : Target {
// Information about the instructions...
let InstructionSet = X86InstrInfo;
let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter];
}

View File

@ -36,6 +36,16 @@ using namespace llvm;
namespace {
Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
enum AsmWriterFlavor { att, intel };
cl::opt<AsmWriterFlavor>
AsmWriterFlavor("x86-asm-syntax",
cl::desc("Choose style of code to emit from X86 backend:"),
cl::values(
clEnumVal(att, " Emit AT&T Style"),
clEnumVal(intel, " Emit Intel Style"),
clEnumValEnd),
cl::init(intel));
struct GasBugWorkaroundEmitter : public MachineCodeEmitter {
GasBugWorkaroundEmitter(std::ostream& o)
@ -67,8 +77,8 @@ namespace {
bool firstByte;
};
struct X86AsmPrinter : public AsmPrinter {
X86AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { }
struct X86IntelAsmPrinter : public AsmPrinter {
X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { }
virtual const char *getPassName() const {
return "X86 Assembly Printer";
@ -128,12 +138,17 @@ namespace {
/// regardless of whether the function is in SSA form.
///
FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
return new X86AsmPrinter(o, tm);
if (AsmWriterFlavor != intel) {
std::cerr << "AT&T syntax not fully implemented yet!\n";
abort();
}
return new X86IntelAsmPrinter(o, tm);
}
// Include the auto-generated portion of the assembly writer.
#include "X86GenAsmWriter.inc"
#include "X86GenIntelAsmWriter.inc"
/// printConstantPool - Print to the current output stream assembly
@ -141,7 +156,7 @@ FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
///
void X86AsmPrinter::printConstantPool(MachineConstantPool *MCP) {
void X86IntelAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
const std::vector<Constant*> &CP = MCP->getConstants();
const TargetData &TD = TM.getTargetData();
@ -159,7 +174,7 @@ void X86AsmPrinter::printConstantPool(MachineConstantPool *MCP) {
/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
setupMachineFunction(MF);
O << "\n\n";
@ -207,7 +222,7 @@ static bool isMem(const MachineInstr *MI, unsigned Op) {
void X86AsmPrinter::printOp(const MachineOperand &MO,
void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
bool elideOffsetKeyword /* = false */) {
const MRegisterInfo &RI = *TM.getRegisterInfo();
switch (MO.getType()) {
@ -253,7 +268,7 @@ void X86AsmPrinter::printOp(const MachineOperand &MO,
}
}
void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
assert(isMem(MI, Op) && "Invalid memory reference!");
if (MI->getOperand(Op).isFrameIndex()) {
@ -308,7 +323,7 @@ void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
/// printMachineInstruction -- Print out a single X86 LLVM instruction
/// MI in Intel syntax to the current output stream.
///
void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
++EmittedInsts;
// gas bugs:
@ -349,7 +364,7 @@ void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
}
}
bool X86AsmPrinter::doInitialization(Module &M) {
bool X86IntelAsmPrinter::doInitialization(Module &M) {
AsmPrinter::doInitialization(M);
// Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
//
@ -375,7 +390,7 @@ static void SwitchSection(std::ostream &OS, std::string &CurSection,
}
}
bool X86AsmPrinter::doFinalization(Module &M) {
bool X86IntelAsmPrinter::doFinalization(Module &M) {
const TargetData &TD = TM.getTargetData();
std::string CurSection;