From 9a3e49a1b3f54e6f29496108b13aed3111f004a0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 3 Oct 2004 20:36:57 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16639 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/Makefile | 11 +++++++--- lib/Target/X86/X86.td | 14 ++++++++++++ lib/Target/X86/X86AsmPrinter.cpp | 37 ++++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/lib/Target/X86/Makefile b/lib/Target/X86/Makefile index 51208dfd694..dd745402fe8 100644 --- a/lib/Target/X86/Makefile +++ b/lib/Target/X86/Makefile @@ -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 $@ diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index 5844621b836..874391dda9f 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -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]; } diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 915ac3afd24..b6f4cd1cb14 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -36,6 +36,16 @@ using namespace llvm; namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); + enum AsmWriterFlavor { att, intel }; + + cl::opt + 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 &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;