Add support for the -x86-asm-syntax flag, which can be used to choose between
authorChris Lattner <sabre@nondot.org>
Sun, 3 Oct 2004 20:36:57 +0000 (20:36 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 3 Oct 2004 20:36:57 +0000 (20:36 +0000)
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
lib/Target/X86/X86.td
lib/Target/X86/X86AsmPrinter.cpp

index 51208dfd6944152ba498a89e0b94c778e7f2abd4..dd745402fe8a9e55c7fd55a57cb4ad7a51e1b026 100644 (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 $@
index 5844621b836887fe7e533223298b36826af19ec5..874391dda9fd062eca31612c435ba35b89b2fe88 100644 (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];
 }
index 915ac3afd24d6402d3ecb8b6c46a985ce08f18e2..b6f4cd1cb1481856a3becf013955485f18a8e29c 100644 (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;