mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
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
This commit is contained in:
parent
fd40d038b3
commit
e895c61515
@ -5,6 +5,7 @@ add_llvm_library(LLVMX86AsmPrinter
|
||||
X86ATTInstPrinter.cpp
|
||||
X86AsmPrinter.cpp
|
||||
X86IntelAsmPrinter.cpp
|
||||
X86IntelInstPrinter.cpp
|
||||
X86MCInstLower.cpp
|
||||
)
|
||||
add_dependencies(LLVMX86AsmPrinter X86CodeGenTable_gen)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
138
lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
Normal file
138
lib/Target/X86/AsmPrinter/X86IntelInstPrinter.cpp
Normal file
@ -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);
|
||||
}
|
100
lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
Normal file
100
lib/Target/X86/AsmPrinter/X86IntelInstPrinter.h
Normal file
@ -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
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -44,6 +44,10 @@ OutputFilename("o", cl::desc("Output filename"),
|
||||
static cl::opt<bool>
|
||||
ShowEncoding("show-encoding", cl::desc("Show instruction encodings"));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
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()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user