From e895c6151589c1b7f6ac9ca992b76106fa197a37 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 20 Sep 2009 07:17:49 +0000 Subject: [PATCH] Add an intel syntax MCInstPrinter implementation. You can now transcode from AT&T to intel syntax with "llvm-mc foo.s -output-asm-variant=1" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82385 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/AsmPrinter/CMakeLists.txt | 1 + lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h | 6 - lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp | 5 +- .../X86/AsmPrinter/X86IntelInstPrinter.cpp | 138 ++++++++++++++++++ .../X86/AsmPrinter/X86IntelInstPrinter.h | 100 +++++++++++++ lib/Target/X86/X86InstrInfo.td | 4 +- test/MC/AsmParser/hello.s | 1 + tools/llvm-mc/llvm-mc.cpp | 8 +- 8 files changed, 250 insertions(+), 13 deletions(-) create mode 100644 lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp create mode 100644 lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h diff --git a/lib/Target/X86/AsmPrinter/CMakeLists.txt b/lib/Target/X86/AsmPrinter/CMakeLists.txt index 7a0bc4b30bd..a788c9b15f5 100644 --- a/lib/Target/X86/AsmPrinter/CMakeLists.txt +++ b/lib/Target/X86/AsmPrinter/CMakeLists.txt @@ -5,6 +5,7 @@ add_llvm_library(LLVMX86AsmPrinter X86ATTInstPrinter.cpp X86AsmPrinter.cpp X86IntelAsmPrinter.cpp + X86IntelInstPrinter.cpp X86MCInstLower.cpp ) add_dependencies(LLVMX86AsmPrinter X86CodeGenTable_gen) diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h index 3a269867506..d3c6fdb97aa 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.h @@ -94,9 +94,6 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { void printi128mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } - void printi256mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } void printf32mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } @@ -109,9 +106,6 @@ class VISIBILITY_HIDDEN X86ATTAsmPrinter : public AsmPrinter { void printf128mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } - void printf256mem(const MachineInstr *MI, unsigned OpNo) { - printMemReference(MI, OpNo); - } void printlea32mem(const MachineInstr *MI, unsigned OpNo) { printLeaMemReference(MI, OpNo); } diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp index 6b2da9ef8cf..f1b0d39ed98 100644 --- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp @@ -18,6 +18,7 @@ #include "X86ATTAsmPrinter.h" #include "X86IntelAsmPrinter.h" #include "X86ATTInstPrinter.h" +#include "X86IntelInstPrinter.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Target/TargetRegistry.h" using namespace llvm; @@ -42,8 +43,8 @@ static MCInstPrinter *createX86MCInstPrinter(const Target &T, raw_ostream &O) { if (SyntaxVariant == 0) return new X86ATTInstPrinter(O, MAI); - - // Don't support intel syntax instprinter yet. + if (SyntaxVariant == 1) + return new X86IntelInstPrinter(O, MAI); return 0; } diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp new file mode 100644 index 00000000000..8899c6b6e8a --- /dev/null +++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp @@ -0,0 +1,138 @@ +//===-- X86IntelInstPrinter.cpp - AT&T assembly instruction printing --------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file includes code for rendering MCInst instances as AT&T-style +// assembly. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "X86IntelInstPrinter.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +#include "X86GenInstrNames.inc" +using namespace llvm; + +// Include the auto-generated portion of the assembly writer. +#define MachineInstr MCInst +#define NO_ASM_WRITER_BOILERPLATE +#define X86IntelAsmPrinter X86IntelInstPrinter +#include "X86GenAsmWriter1.inc" +#undef MachineInstr + +void X86IntelInstPrinter::printInst(const MCInst *MI) { printInstruction(MI); } + +void X86IntelInstPrinter::printSSECC(const MCInst *MI, unsigned Op) { + switch (MI->getOperand(Op).getImm()) { + default: llvm_unreachable("Invalid ssecc argument!"); + case 0: O << "eq"; break; + case 1: O << "lt"; break; + case 2: O << "le"; break; + case 3: O << "unord"; break; + case 4: O << "neq"; break; + case 5: O << "nlt"; break; + case 6: O << "nle"; break; + case 7: O << "ord"; break; + } +} + +void X86IntelInstPrinter::printPICLabel(const MCInst *MI, unsigned Op) { + llvm_unreachable("This is only used for MOVPC32r," + "should lower before instruction printing!"); +} + +/// print_pcrel_imm - This is used to print an immediate value that ends up +/// being encoded as a pc-relative value. These print slightly differently, for +/// example, a $ is not emitted. +void X86IntelInstPrinter::print_pcrel_imm(const MCInst *MI, unsigned OpNo) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isImm()) + O << Op.getImm(); + else { + assert(Op.isExpr() && "unknown pcrel immediate operand"); + Op.getExpr()->print(O, &MAI); + } +} + +static void PrintRegName(raw_ostream &O, StringRef RegName) { + for (unsigned i = 0, e = RegName.size(); i != e; ++i) + O << (char)toupper(RegName[i]); +} + +void X86IntelInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + const char *Modifier) { + assert(Modifier == 0 && "Modifiers should not be used"); + + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + PrintRegName(O, getRegisterName(Op.getReg())); + } else if (Op.isImm()) { + O << Op.getImm(); + } else { + assert(Op.isExpr() && "unknown operand kind in printOperand"); + Op.getExpr()->print(O, &MAI); + } +} + +void X86IntelInstPrinter::printLeaMemReference(const MCInst *MI, unsigned Op) { + const MCOperand &BaseReg = MI->getOperand(Op); + unsigned ScaleVal = MI->getOperand(Op+1).getImm(); + const MCOperand &IndexReg = MI->getOperand(Op+2); + const MCOperand &DispSpec = MI->getOperand(Op+3); + + O << '['; + + bool NeedPlus = false; + if (BaseReg.getReg()) { + printOperand(MI, Op); + NeedPlus = true; + } + + if (IndexReg.getReg()) { + if (NeedPlus) O << " + "; + if (ScaleVal != 1) + O << ScaleVal << '*'; + printOperand(MI, Op+2); + NeedPlus = true; + } + + + if (!DispSpec.isImm()) { + if (NeedPlus) O << " + "; + assert(DispSpec.isExpr() && "non-immediate displacement for LEA?"); + DispSpec.getExpr()->print(O, &MAI); + } else { + int64_t DispVal = DispSpec.getImm(); + if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { + if (NeedPlus) { + if (DispVal > 0) + O << " + "; + else { + O << " - "; + DispVal = -DispVal; + } + } + O << DispVal; + } + } + + O << ']'; +} + +void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op) { + // If this has a segment register, print it. + if (MI->getOperand(Op+4).getReg()) { + printOperand(MI, Op+4); + O << ':'; + } + printLeaMemReference(MI, Op); +} diff --git a/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h new file mode 100644 index 00000000000..cec61bf2f99 --- /dev/null +++ b/lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h @@ -0,0 +1,100 @@ +//===-- X86IntelInstPrinter.h - Convert X86 MCInst to assembly syntax -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an X86 MCInst to intel style .s file syntax. +// +//===----------------------------------------------------------------------===// + +#ifndef X86_INTEL_INST_PRINTER_H +#define X86_INTEL_INST_PRINTER_H + +#include "llvm/MC/MCInstPrinter.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + class MCOperand; + +class X86IntelInstPrinter : public MCInstPrinter { +public: + X86IntelInstPrinter(raw_ostream &O, const MCAsmInfo &MAI) + : MCInstPrinter(O, MAI) {} + + virtual void printInst(const MCInst *MI); + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI); + static const char *getRegisterName(unsigned RegNo); + + + void printOperand(const MCInst *MI, unsigned OpNo, + const char *Modifier = 0); + void printMemReference(const MCInst *MI, unsigned Op); + void printLeaMemReference(const MCInst *MI, unsigned Op); + void printSSECC(const MCInst *MI, unsigned Op); + void printPICLabel(const MCInst *MI, unsigned Op); + void print_pcrel_imm(const MCInst *MI, unsigned OpNo); + + void printopaquemem(const MCInst *MI, unsigned OpNo) { + O << "OPAQUE PTR "; + printMemReference(MI, OpNo); + } + + void printi8mem(const MCInst *MI, unsigned OpNo) { + O << "BYTE PTR "; + printMemReference(MI, OpNo); + } + void printi16mem(const MCInst *MI, unsigned OpNo) { + O << "WORD PTR "; + printMemReference(MI, OpNo); + } + void printi32mem(const MCInst *MI, unsigned OpNo) { + O << "DWORD PTR "; + printMemReference(MI, OpNo); + } + void printi64mem(const MCInst *MI, unsigned OpNo) { + O << "QWORD PTR "; + printMemReference(MI, OpNo); + } + void printi128mem(const MCInst *MI, unsigned OpNo) { + O << "XMMWORD PTR "; + printMemReference(MI, OpNo); + } + void printf32mem(const MCInst *MI, unsigned OpNo) { + O << "DWORD PTR "; + printMemReference(MI, OpNo); + } + void printf64mem(const MCInst *MI, unsigned OpNo) { + O << "QWORD PTR "; + printMemReference(MI, OpNo); + } + void printf80mem(const MCInst *MI, unsigned OpNo) { + O << "XWORD PTR "; + printMemReference(MI, OpNo); + } + void printf128mem(const MCInst *MI, unsigned OpNo) { + O << "XMMWORD PTR "; + printMemReference(MI, OpNo); + } + void printlea32mem(const MCInst *MI, unsigned OpNo) { + O << "DWORD PTR "; + printLeaMemReference(MI, OpNo); + } + void printlea64mem(const MCInst *MI, unsigned OpNo) { + O << "QWORD PTR "; + printLeaMemReference(MI, OpNo); + } + void printlea64_32mem(const MCInst *MI, unsigned OpNo) { + O << "QWORD PTR "; + printLeaMemReference(MI, OpNo); + } +}; + +} + +#endif diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 101b7a8f3ca..992b3900e28 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -201,12 +201,12 @@ def i16mem : X86MemOperand<"printi16mem">; def i32mem : X86MemOperand<"printi32mem">; def i64mem : X86MemOperand<"printi64mem">; def i128mem : X86MemOperand<"printi128mem">; -def i256mem : X86MemOperand<"printi256mem">; +//def i256mem : X86MemOperand<"printi256mem">; def f32mem : X86MemOperand<"printf32mem">; def f64mem : X86MemOperand<"printf64mem">; def f80mem : X86MemOperand<"printf80mem">; def f128mem : X86MemOperand<"printf128mem">; -def f256mem : X86MemOperand<"printf256mem">; +//def f256mem : X86MemOperand<"printf256mem">; // A version of i8mem for use on x86-64 that uses GR64_NOREX instead of // plain GR64, so that it doesn't potentially require a REX prefix. diff --git a/test/MC/AsmParser/hello.s b/test/MC/AsmParser/hello.s index 891e47f94df..01e3b4d58a1 100644 --- a/test/MC/AsmParser/hello.s +++ b/test/MC/AsmParser/hello.s @@ -1,4 +1,5 @@ // RUN: llvm-mc -triple i386-unknown-unknown %s -o - +// RUN: llvm-mc -triple i386-unknown-unknown %s -o - -output-asm-variant=1 .text .align 4,0x90 diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index fad1dd1685e..329efe92329 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -44,6 +44,10 @@ OutputFilename("o", cl::desc("Output filename"), static cl::opt ShowEncoding("show-encoding", cl::desc("Show instruction encodings")); +static cl::opt +OutputAsmVariant("output-asm-variant", + cl::desc("Syntax variant to use for output printing")); + enum OutputFileType { OFT_AssemblyFile, OFT_ObjectFile @@ -252,9 +256,7 @@ static int AssembleInput(const char *ProgName) { assert(MAI && "Unable to create target asm info!"); if (FileType == OFT_AssemblyFile) { - // FIXME: Syntax Variant should be selectable somehow? - unsigned SyntaxVariant = 0; - IP.reset(TheTarget->createMCInstPrinter(SyntaxVariant, *MAI, *Out)); + IP.reset(TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *Out)); if (ShowEncoding) CE.reset(TheTarget->createCodeEmitter(*TM)); Str.reset(createAsmStreamer(Ctx, *Out, *MAI, IP.get(), CE.get())); -- 2.34.1