llvm.org GIT mirror llvm / 9a3e49a
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 Chris Lattner 16 years ago
3 changed file(s) with 48 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
1414 # Make sure that tblgen is run, first thing.
1515 $(SourceDepend): X86GenRegisterInfo.h.inc X86GenRegisterNames.inc \
1616 X86GenRegisterInfo.inc X86GenInstrNames.inc \
17 X86GenInstrInfo.inc X86GenAsmWriter.inc
17 X86GenInstrInfo.inc X86GenATTAsmWriter.inc \
18 X86GenIntelAsmWriter.inc
1819
1920 TDFILES = $(SourceDir)/$(TARGET).td $(wildcard $(SourceDir)/*.td) \
2021 $(SourceDir)/../Target.td
3940 @echo "Building $(TARGET).td instruction information with tblgen"
4041 $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-instr-desc -o $@
4142
42 $(TARGET)GenAsmWriter.inc:: $(TDFILES) $(TBLGEN)
43 @echo "Building $(TARGET).td assembly writer with tblgen"
43 $(TARGET)GenATTAsmWriter.inc:: $(TDFILES) $(TBLGEN)
44 @echo "Building $(TARGET).td AT&T assembly writer with tblgen"
4445 $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-asm-writer -o $@
46
47 $(TARGET)GenIntelAsmWriter.inc:: $(TDFILES) $(TBLGEN)
48 @echo "Building $(TARGET).td Intel assembly writer with tblgen"
49 $(VERB) $(TBLGEN) -I $(BUILD_SRC_DIR) $< -gen-asm-writer -asmwriternum=1 -o $@
4550
4651 #$(TARGET)GenInstrSelector.inc:: $(TDFILES) $(TBLGEN)
4752 # @echo "Building $(TARGET).td instruction selector with tblgen"
4646 16];
4747 }
4848
49 // The X86 target supports two different syntaxes for emitting machine code.
50 // This is controlled by the -x86-asm-syntax={att|intel}
51 def ATTAsmWriter : AsmWriter {
52 string AsmWriterClassName = "ATTAsmPrinter";
53 int Variant = 0;
54 }
55 def IntelAsmWriter : AsmWriter {
56 string AsmWriterClassName = "IntelAsmPrinter";
57 int Variant = 1;
58 }
59
60
4961 def X86 : Target {
5062 // Specify the callee saved registers.
5163 let CalleeSavedRegisters = [ESI, EDI, EBX, EBP];
5567
5668 // Information about the instructions...
5769 let InstructionSet = X86InstrInfo;
70
71 let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter];
5872 }
3535
3636 namespace {
3737 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
38 enum AsmWriterFlavor { att, intel };
39
40 cl::opt
41 AsmWriterFlavor("x86-asm-syntax",
42 cl::desc("Choose style of code to emit from X86 backend:"),
43 cl::values(
44 clEnumVal(att, " Emit AT&T Style"),
45 clEnumVal(intel, " Emit Intel Style"),
46 clEnumValEnd),
47 cl::init(intel));
3848
3949 struct GasBugWorkaroundEmitter : public MachineCodeEmitter {
4050 GasBugWorkaroundEmitter(std::ostream& o)
6676 bool firstByte;
6777 };
6878
69 struct X86AsmPrinter : public AsmPrinter {
70 X86AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { }
79 struct X86IntelAsmPrinter : public AsmPrinter {
80 X86IntelAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { }
7181
7282 virtual const char *getPassName() const {
7383 return "X86 Assembly Printer";
127137 /// regardless of whether the function is in SSA form.
128138 ///
129139 FunctionPass *llvm::createX86CodePrinterPass(std::ostream &o,TargetMachine &tm){
130 return new X86AsmPrinter(o, tm);
140 if (AsmWriterFlavor != intel) {
141 std::cerr << "AT&T syntax not fully implemented yet!\n";
142 abort();
143 }
144
145 return new X86IntelAsmPrinter(o, tm);
131146 }
132147
133148
134149 // Include the auto-generated portion of the assembly writer.
135 #include "X86GenAsmWriter.inc"
150 #include "X86GenIntelAsmWriter.inc"
136151
137152
138153 /// printConstantPool - Print to the current output stream assembly
140155 /// used to print out constants which have been "spilled to memory" by
141156 /// the code generator.
142157 ///
143 void X86AsmPrinter::printConstantPool(MachineConstantPool *MCP) {
158 void X86IntelAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
144159 const std::vector &CP = MCP->getConstants();
145160 const TargetData &TD = TM.getTargetData();
146161
158173 /// runOnMachineFunction - This uses the printMachineInstruction()
159174 /// method to print assembly for each instruction.
160175 ///
161 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
176 bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
162177 setupMachineFunction(MF);
163178 O << "\n\n";
164179
206221
207222
208223
209 void X86AsmPrinter::printOp(const MachineOperand &MO,
224 void X86IntelAsmPrinter::printOp(const MachineOperand &MO,
210225 bool elideOffsetKeyword /* = false */) {
211226 const MRegisterInfo &RI = *TM.getRegisterInfo();
212227 switch (MO.getType()) {
252267 }
253268 }
254269
255 void X86AsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
270 void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op) {
256271 assert(isMem(MI, Op) && "Invalid memory reference!");
257272
258273 if (MI->getOperand(Op).isFrameIndex()) {
307322 /// printMachineInstruction -- Print out a single X86 LLVM instruction
308323 /// MI in Intel syntax to the current output stream.
309324 ///
310 void X86AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
325 void X86IntelAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
311326 ++EmittedInsts;
312327
313328 // gas bugs:
348363 }
349364 }
350365
351 bool X86AsmPrinter::doInitialization(Module &M) {
366 bool X86IntelAsmPrinter::doInitialization(Module &M) {
352367 AsmPrinter::doInitialization(M);
353368 // Tell gas we are outputting Intel syntax (not AT&T syntax) assembly.
354369 //
374389 }
375390 }
376391
377 bool X86AsmPrinter::doFinalization(Module &M) {
392 bool X86IntelAsmPrinter::doFinalization(Module &M) {
378393 const TargetData &TD = TM.getTargetData();
379394 std::string CurSection;
380395