aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-09-12 20:34:57 +0000
committerChris Lattner <sabre@nondot.org>2009-09-12 20:34:57 +0000
commit8fea32f9ff5cec2165661a3da986abe29c9bddb1 (patch)
tree64e7a3c102be9bf41093acb7640d592f98a6f3cf /lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
parent4e68a2a6320aa5d4db130569c46f2914a6cf9ded (diff)
split MachineInstr -> MCInst lowering into its own class (not
being embedded into X86ATTAsmPrinter). This still depends heavily on X86ATTAsmPrinter, but this is a step in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81627 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86/AsmPrinter/X86MCInstLower.cpp')
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp275
1 files changed, 147 insertions, 128 deletions
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index 9b2b71b089..ed8207415f 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -12,7 +12,7 @@
//
//===----------------------------------------------------------------------===//
-
+#include "X86MCInstLower.h"
#include "X86ATTAsmPrinter.h"
#include "X86MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
@@ -24,24 +24,32 @@
#include "llvm/ADT/SmallString.h"
using namespace llvm;
-MCSymbol *X86ATTAsmPrinter::GetPICBaseSymbol() {
+
+const X86Subtarget &X86MCInstLower::getSubtarget() const {
+ return AsmPrinter.getSubtarget();
+}
+
+
+MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
// FIXME: the actual label generated doesn't matter here! Just mangle in
// something unique (the function number) with Private prefix.
SmallString<60> Name;
- if (Subtarget->isTargetDarwin()) {
- raw_svector_ostream(Name) << 'L' << getFunctionNumber() << "$pb";
+ if (getSubtarget().isTargetDarwin()) {
+ raw_svector_ostream(Name) << 'L' << AsmPrinter.getFunctionNumber() << "$pb";
} else {
- assert(Subtarget->isTargetELF() && "Don't know how to print PIC label!");
- raw_svector_ostream(Name) << ".Lllvm$" << getFunctionNumber()<<".$piclabel";
+ assert(getSubtarget().isTargetELF() && "Don't know how to print PIC label!");
+ raw_svector_ostream(Name) << ".Lllvm$" << AsmPrinter.getFunctionNumber()
+ << ".$piclabel";
}
- return OutContext.GetOrCreateSymbol(Name.str());
+ return Ctx.GetOrCreateSymbol(Name.str());
}
/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
/// MCOperand.
-MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
+MCSymbol *X86MCInstLower::
+GetGlobalAddressSymbol(const MachineOperand &MO) const {
const GlobalValue *GV = MO.getGlobal();
bool isImplicitlyPrivate = false;
@@ -54,8 +62,8 @@ MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
- if (Subtarget->isTargetCygMing())
- DecorateCygMingName(Name, GV);
+ if (getSubtarget().isTargetCygMing())
+ AsmPrinter.DecorateCygMingName(Name, GV);
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
@@ -72,35 +80,34 @@ MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = GVStubs[Sym];
+ MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = AsmPrinter.GVStubs[Sym];
if (StubSym == 0) {
Name.clear();
Mang->getNameWithPrefix(Name, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(Name.str());
+ StubSym = Ctx.GetOrCreateSymbol(Name.str());
}
return Sym;
-
}
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = HiddenGVStubs[Sym];
+ MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = AsmPrinter.HiddenGVStubs[Sym];
if (StubSym == 0) {
Name.clear();
Mang->getNameWithPrefix(Name, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(Name.str());
+ StubSym = Ctx.GetOrCreateSymbol(Name.str());
}
return Sym;
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = FnStubs[Sym];
+ MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = AsmPrinter.FnStubs[Sym];
if (StubSym == 0) {
Name.clear();
Mang->getNameWithPrefix(Name, GV, false);
- StubSym = OutContext.GetOrCreateSymbol(Name.str());
+ StubSym = Ctx.GetOrCreateSymbol(Name.str());
}
return Sym;
}
@@ -116,12 +123,13 @@ MCSymbol *X86ATTAsmPrinter::GetGlobalAddressSymbol(const MachineOperand &MO) {
case X86II::MO_PLT: Name += "@PLT"; break;
}
- return OutContext.GetOrCreateSymbol(Name.str());
+ return Ctx.GetOrCreateSymbol(Name.str());
}
-MCSymbol *X86ATTAsmPrinter::GetExternalSymbolSymbol(const MachineOperand &MO) {
+MCSymbol *X86MCInstLower::
+GetExternalSymbolSymbol(const MachineOperand &MO) const {
SmallString<128> Name;
- Name += MAI->getGlobalPrefix();
+ Name += AsmPrinter.MAI->getGlobalPrefix();
Name += MO.getSymbolName();
switch (MO.getTargetFlags()) {
@@ -138,11 +146,11 @@ MCSymbol *X86ATTAsmPrinter::GetExternalSymbolSymbol(const MachineOperand &MO) {
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
- MCSymbol *Sym = OutContext.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = FnStubs[Sym];
+ MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
+ MCSymbol *&StubSym = AsmPrinter.FnStubs[Sym];
if (StubSym == 0) {
Name.erase(Name.end()-5, Name.end());
- StubSym = OutContext.GetOrCreateSymbol(Name.str());
+ StubSym = Ctx.GetOrCreateSymbol(Name.str());
}
return Sym;
}
@@ -158,13 +166,13 @@ MCSymbol *X86ATTAsmPrinter::GetExternalSymbolSymbol(const MachineOperand &MO) {
case X86II::MO_PLT: Name += "@PLT"; break;
}
- return OutContext.GetOrCreateSymbol(Name.str());
+ return Ctx.GetOrCreateSymbol(Name.str());
}
-MCSymbol *X86ATTAsmPrinter::GetJumpTableSymbol(const MachineOperand &MO) {
+MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
- raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
- << getFunctionNumber() << '_' << MO.getIndex();
+ raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "JTI"
+ << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
switch (MO.getTargetFlags()) {
default:
@@ -187,15 +195,15 @@ MCSymbol *X86ATTAsmPrinter::GetJumpTableSymbol(const MachineOperand &MO) {
}
// Create a symbol for the name.
- return OutContext.GetOrCreateSymbol(Name.str());
+ return Ctx.GetOrCreateSymbol(Name.str());
}
-MCSymbol *X86ATTAsmPrinter::
-GetConstantPoolIndexSymbol(const MachineOperand &MO) {
+MCSymbol *X86MCInstLower::
+GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
- raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "CPI"
- << getFunctionNumber() << '_' << MO.getIndex();
+ raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "CPI"
+ << AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
switch (MO.getTargetFlags()) {
default:
@@ -218,14 +226,14 @@ GetConstantPoolIndexSymbol(const MachineOperand &MO) {
}
// Create a symbol for the name.
- return OutContext.GetOrCreateSymbol(Name.str());
+ return Ctx.GetOrCreateSymbol(Name.str());
}
-MCOperand X86ATTAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
- MCSymbol *Sym) {
+MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
+ MCSymbol *Sym) const {
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
- const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, OutContext);
+ const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
@@ -251,8 +259,8 @@ MCOperand X86ATTAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
// Subtract the pic base.
Expr = MCBinaryExpr::CreateSub(Expr,
MCSymbolRefExpr::Create(GetPICBaseSymbol(),
- OutContext),
- OutContext);
+ Ctx),
+ Ctx);
break;
case X86II::MO_GOT_ABSOLUTE_ADDRESS: {
// For this, we want to print something like:
@@ -260,24 +268,25 @@ MCOperand X86ATTAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
// However, we can't generate a ".", so just emit a new label here and refer
// to it. We know that this operand flag occurs at most once per function.
SmallString<64> Name;
- raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "picbaseref"
- << getFunctionNumber();
- MCSymbol *DotSym = OutContext.GetOrCreateSymbol(Name.str());
- OutStreamer.EmitLabel(DotSym);
+ raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix()
+ << "picbaseref" << AsmPrinter.getFunctionNumber();
+ MCSymbol *DotSym = Ctx.GetOrCreateSymbol(Name.str());
+// FIXME: This instruction should be lowered before we get here...
+ AsmPrinter.OutStreamer.EmitLabel(DotSym);
- const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
+ const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, Ctx);
const MCExpr *PICBase = MCSymbolRefExpr::Create(GetPICBaseSymbol(),
- OutContext);
- DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext);
- Expr = MCBinaryExpr::CreateAdd(Expr, DotExpr, OutContext);
+ Ctx);
+ DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, Ctx);
+ Expr = MCBinaryExpr::CreateAdd(Expr, DotExpr, Ctx);
break;
}
}
if (!MO.isJTI() && MO.getOffset())
- Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(),
- OutContext),
- OutContext);
+ Expr = MCBinaryExpr::CreateAdd(Expr,
+ MCConstantExpr::Create(MO.getOffset(), Ctx),
+ Ctx);
return MCOperand::CreateExpr(Expr);
}
@@ -303,51 +312,9 @@ static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
}
-void X86ATTAsmPrinter::
-printInstructionThroughMCStreamer(const MachineInstr *MI) {
- MCInst TmpInst;
- switch (MI->getOpcode()) {
- case TargetInstrInfo::DBG_LABEL:
- case TargetInstrInfo::EH_LABEL:
- case TargetInstrInfo::GC_LABEL:
- printLabel(MI);
- return;
- case TargetInstrInfo::INLINEASM:
- O << '\t';
- printInlineAsm(MI);
- return;
- case TargetInstrInfo::IMPLICIT_DEF:
- printImplicitDef(MI);
- return;
- case X86::MOVPC32r: {
- // This is a pseudo op for a two instruction sequence with a label, which
- // looks like:
- // call "L1$pb"
- // "L1$pb":
- // popl %esi
-
- // Emit the call.
- MCSymbol *PICBase = GetPICBaseSymbol();
- TmpInst.setOpcode(X86::CALLpcrel32);
- // FIXME: We would like an efficient form for this, so we don't have to do a
- // lot of extra uniquing.
- TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
- OutContext)));
- printInstruction(&TmpInst);
- O << '\n';
-
- // Emit the label.
- OutStreamer.EmitLabel(PICBase);
-
- // popl $reg
- TmpInst.setOpcode(X86::POP32r);
- TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
- printInstruction(&TmpInst);
- return;
- }
- }
-
- TmpInst.setOpcode(MI->getOpcode());
+
+void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
+ OutMI.setOpcode(MI->getOpcode());
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
@@ -355,9 +322,8 @@ printInstructionThroughMCStreamer(const MachineInstr *MI) {
MCOperand MCOp;
switch (MO.getType()) {
default:
- O.flush();
- errs() << "Cannot lower operand #" << i << " of :" << *MI;
- llvm_unreachable("Unimp");
+ MI->dump();
+ llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
MCOp = MCOperand::CreateReg(MO.getReg());
break;
@@ -365,7 +331,8 @@ printInstructionThroughMCStreamer(const MachineInstr *MI) {
MCOp = MCOperand::CreateImm(MO.getImm());
break;
case MachineOperand::MO_MachineBasicBlock:
- MCOp = MCOperand::CreateMBBLabel(getFunctionNumber(),
+// FIXME: Kill MBBLabel operand type!
+ MCOp = MCOperand::CreateMBBLabel(AsmPrinter.getFunctionNumber(),
MO.getMBB()->getNumber());
break;
case MachineOperand::MO_GlobalAddress:
@@ -382,63 +349,115 @@ printInstructionThroughMCStreamer(const MachineInstr *MI) {
break;
}
- TmpInst.addOperand(MCOp);
+ OutMI.addOperand(MCOp);
}
// Handle a few special cases to eliminate operand modifiers.
- switch (TmpInst.getOpcode()) {
+ switch (OutMI.getOpcode()) {
case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
- lower_lea64_32mem(&TmpInst, 1);
+ lower_lea64_32mem(&OutMI, 1);
break;
case X86::MOV16r0:
- TmpInst.setOpcode(X86::MOV32r0);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOV32r0);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX16rr8:
- TmpInst.setOpcode(X86::MOVZX32rr8);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVZX32rr8);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX16rm8:
- TmpInst.setOpcode(X86::MOVZX32rm8);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVZX32rm8);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVSX16rr8:
- TmpInst.setOpcode(X86::MOVSX32rr8);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVSX32rr8);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVSX16rm8:
- TmpInst.setOpcode(X86::MOVSX32rm8);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVSX32rm8);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX64rr32:
- TmpInst.setOpcode(X86::MOV32rr);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOV32rr);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX64rm32:
- TmpInst.setOpcode(X86::MOV32rm);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOV32rm);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOV64ri64i32:
- TmpInst.setOpcode(X86::MOV32ri);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOV32ri);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX64rr8:
- TmpInst.setOpcode(X86::MOVZX32rr8);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVZX32rr8);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX64rm8:
- TmpInst.setOpcode(X86::MOVZX32rm8);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVZX32rm8);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX64rr16:
- TmpInst.setOpcode(X86::MOVZX32rr16);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVZX32rr16);
+ lower_subreg32(&OutMI, 0);
break;
case X86::MOVZX64rm16:
- TmpInst.setOpcode(X86::MOVZX32rm16);
- lower_subreg32(&TmpInst, 0);
+ OutMI.setOpcode(X86::MOVZX32rm16);
+ lower_subreg32(&OutMI, 0);
break;
}
+}
+
+
+
+void X86ATTAsmPrinter::
+printInstructionThroughMCStreamer(const MachineInstr *MI) {
+ X86MCInstLower MCInstLowering(OutContext, Mang, *this);
+ switch (MI->getOpcode()) {
+ case TargetInstrInfo::DBG_LABEL:
+ case TargetInstrInfo::EH_LABEL:
+ case TargetInstrInfo::GC_LABEL:
+ printLabel(MI);
+ return;
+ case TargetInstrInfo::INLINEASM:
+ O << '\t';
+ printInlineAsm(MI);
+ return;
+ case TargetInstrInfo::IMPLICIT_DEF:
+ printImplicitDef(MI);
+ return;
+ case X86::MOVPC32r: {
+ MCInst TmpInst;
+ // This is a pseudo op for a two instruction sequence with a label, which
+ // looks like:
+ // call "L1$pb"
+ // "L1$pb":
+ // popl %esi
+
+ // Emit the call.
+ MCSymbol *PICBase = MCInstLowering.GetPICBaseSymbol();
+ TmpInst.setOpcode(X86::CALLpcrel32);
+ // FIXME: We would like an efficient form for this, so we don't have to do a
+ // lot of extra uniquing.
+ TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
+ OutContext)));
+ printInstruction(&TmpInst);
+ O << '\n';
+
+ // Emit the label.
+ OutStreamer.EmitLabel(PICBase);
+
+ // popl $reg
+ TmpInst.setOpcode(X86::POP32r);
+ TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
+ printInstruction(&TmpInst);
+ return;
+ }
+ }
+
+ MCInst TmpInst;
+ MCInstLowering.Lower(MI, TmpInst);
+
printInstruction(&TmpInst);
}