//===----------------------------------------------------------------------===//
#include "X86MCInstLower.h"
-#include "X86ATTAsmPrinter.h"
+#include "X86AsmPrinter.h"
#include "X86MCAsmInfo.h"
+#include "X86COFFMachineModuleInfo.h"
+#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Mangler.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
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 (getSubtarget().isTargetDarwin()) {
- raw_svector_ostream(Name) << 'L' << AsmPrinter.getFunctionNumber() << "$pb";
- } else {
- assert(getSubtarget().isTargetELF() && "Don't know how to print PIC label!");
- raw_svector_ostream(Name) << ".Lllvm$" << AsmPrinter.getFunctionNumber()
- << ".$piclabel";
- }
- return Ctx.GetOrCreateSymbol(Name.str());
+MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
+ assert(getSubtarget().isTargetDarwin() &&"Can only get MachO info on darwin");
+ return AsmPrinter.MMI->getObjFileInfo<MachineModuleInfoMachO>();
}
-MCOperand X86MCInstLower::LowerMBBOperand(const MachineOperand &MO) const {
- SmallString<60> Name;
- raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "BB"
- << AsmPrinter.getFunctionNumber() << '_' << MO.getMBB()->getNumber();
- MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- return MCOperand::CreateExpr(MCSymbolRefExpr::Create(Sym, Ctx));
+MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
+ const TargetLowering *TLI = AsmPrinter.TM.getTargetLowering();
+ return static_cast<const X86TargetLowering*>(TLI)->
+ getPICBaseSymbol(AsmPrinter.MF, Ctx);
}
-
-
/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
/// MCOperand.
MCSymbol *X86MCInstLower::
SmallString<128> Name;
Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
- if (getSubtarget().isTargetCygMing())
- AsmPrinter.DecorateCygMingName(Name, GV);
+ if (getSubtarget().isTargetCygMing()) {
+ X86COFFMachineModuleInfo &COFFMMI =
+ AsmPrinter.MMI->getObjFileInfo<X86COFFMachineModuleInfo>();
+ COFFMMI.DecorateCygMingName(Name, GV, *AsmPrinter.TM.getTargetData());
+ }
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on GV operand");
case X86II::MO_NO_FLAG: // No flag.
- case X86II::MO_GOT_ABSOLUTE_ADDRESS: // Doesn't modify symbol name.
case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name.
break;
case X86II::MO_DLLIMPORT: {
case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = AsmPrinter.GVStubs[Sym];
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+
+ const MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym);
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
Name += "$non_lazy_ptr";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = AsmPrinter.HiddenGVStubs[Sym];
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ const MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym);
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = AsmPrinter.FnStubs[Sym];
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
// FIXME: These probably should be a modifier on the symbol or something??
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
- MCSymbol *&StubSym = AsmPrinter.FnStubs[Sym];
+ const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
+
if (StubSym == 0) {
Name.erase(Name.end()-5, Name.end());
StubSym = Ctx.GetOrCreateSymbol(Name.str());
MCSymbol *X86MCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
+ // FIXME: Use AsmPrinter.GetJTISymbol. @TLSGD shouldn't be part of the symbol
+ // name!
raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "JTI"
<< AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
MCSymbol *X86MCInstLower::
GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
SmallString<256> Name;
+ // FIXME: USe AsmPrinter.GetCPISymbol. @TLSGD shouldn't be part of the symbol
+ // name!
raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix() << "CPI"
<< AsmPrinter.getFunctionNumber() << '_' << MO.getIndex();
return Ctx.GetOrCreateSymbol(Name.str());
}
+MCSymbol *X86MCInstLower::
+GetBlockAddressSymbol(const MachineOperand &MO) const {
+ const char *Suffix = "";
+ switch (MO.getTargetFlags()) {
+ default: llvm_unreachable("Unknown target flag on BA operand");
+ case X86II::MO_NO_FLAG: break; // No flag.
+ case X86II::MO_PIC_BASE_OFFSET: break; // Doesn't modify symbol name.
+ case X86II::MO_GOTOFF: Suffix = "@GOTOFF"; break;
+ }
+
+ return AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress(), Suffix);
+}
+
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
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
// Subtract the pic base.
Expr = MCBinaryExpr::CreateSub(Expr,
- MCSymbolRefExpr::Create(GetPICBaseSymbol(),
- Ctx),
+ MCSymbolRefExpr::Create(GetPICBaseSymbol(), Ctx),
Ctx);
break;
- case X86II::MO_GOT_ABSOLUTE_ADDRESS: {
- // For this, we want to print something like:
- // MYSYMBOL + (. - PICBASE)
- // 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) << 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, Ctx);
- const MCExpr *PICBase = MCSymbolRefExpr::Create(GetPICBaseSymbol(),
- Ctx);
- DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, Ctx);
- Expr = MCBinaryExpr::CreateAdd(Expr, DotExpr, Ctx);
- break;
- }
}
if (!MO.isJTI() && MO.getOffset())
MI->dump();
llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
+ // Ignore all implicit register operands.
+ if (MO.isImplicit()) continue;
MCOp = MCOperand::CreateReg(MO.getReg());
break;
case MachineOperand::MO_Immediate:
MCOp = MCOperand::CreateImm(MO.getImm());
break;
case MachineOperand::MO_MachineBasicBlock:
- MCOp = LowerMBBOperand(MO);
+ MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
+ MO.getMBB()->getSymbol(Ctx), Ctx));
break;
case MachineOperand::MO_GlobalAddress:
MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
case MachineOperand::MO_ConstantPoolIndex:
MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
break;
+ case MachineOperand::MO_BlockAddress:
+ MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
+ break;
}
OutMI.addOperand(MCOp);
case X86::LEA64_32r: // Handle 'subreg rewriting' for the lea64_32mem operand.
lower_lea64_32mem(&OutMI, 1);
break;
- case X86::MOV16r0:
- OutMI.setOpcode(X86::MOV32r0);
- lower_subreg32(&OutMI, 0);
- break;
case X86::MOVZX16rr8:
OutMI.setOpcode(X86::MOVZX32rr8);
lower_subreg32(&OutMI, 0);
OutMI.setOpcode(X86::MOVZX32rm16);
lower_subreg32(&OutMI, 0);
break;
+ case X86::MOV16r0:
+ OutMI.setOpcode(X86::MOV32r0);
+ lower_subreg32(&OutMI, 0);
+ break;
+ case X86::MOV64r0:
+ OutMI.setOpcode(X86::MOV32r0);
+ lower_subreg32(&OutMI, 0);
+ break;
}
}
-void X86ATTAsmPrinter::
-printInstructionThroughMCStreamer(const MachineInstr *MI) {
+void X86AsmPrinter::EmitInstruction(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);
+ case TargetInstrInfo::DEBUG_VALUE: {
+ // FIXME: if this is implemented for another target before it goes
+ // away completely, the common part should be moved into AsmPrinter.
+ if (!VerboseAsm)
+ return;
+ O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
+ unsigned NOps = MI->getNumOperands();
+ // cast away const; DIetc do not take const operands for some reason.
+ DIVariable V((MDNode*)(MI->getOperand(NOps-1).getMetadata()));
+ O << V.getName();
+ O << " <- ";
+ if (NOps==3) {
+ // Register or immediate value. Register 0 means undef.
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Register ||
+ MI->getOperand(0).getType()==MachineOperand::MO_Immediate ||
+ MI->getOperand(0).getType()==MachineOperand::MO_FPImmediate);
+ if (MI->getOperand(0).getType()==MachineOperand::MO_Register &&
+ MI->getOperand(0).getReg()==0) {
+ // Suppress offset in this case, it is not meaningful.
+ O << "undef";
+ return;
+ } else if (MI->getOperand(0).getType()==MachineOperand::MO_FPImmediate) {
+ // This is more naturally done in printOperand, but since the only use
+ // of such an operand is in this comment and that is temporary, we
+ // prefer to keep this localized.
+ O << '$';
+ MI->getOperand(0).print(O, &TM);
+ } else
+ printOperand(MI, 0);
+ } else {
+ // Frame address. Currently handles register +- offset only.
+ assert(MI->getOperand(0).getType()==MachineOperand::MO_Register);
+ assert(MI->getOperand(3).getType()==MachineOperand::MO_Immediate);
+ O << '['; printOperand(MI, 0); O << '+'; printOperand(MI, 3); O << ']';
+ }
+ O << "+";
+ printOperand(MI, NOps-2);
+ O << '\n';
return;
+ }
case X86::MOVPC32r: {
MCInst TmpInst;
// This is a pseudo op for a two instruction sequence with a label, which
// lot of extra uniquing.
TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(PICBase,
OutContext)));
- printInstruction(&TmpInst);
- O << '\n';
+ OutStreamer.EmitInstruction(TmpInst);
// Emit the label.
OutStreamer.EmitLabel(PICBase);
// popl $reg
TmpInst.setOpcode(X86::POP32r);
TmpInst.getOperand(0) = MCOperand::CreateReg(MI->getOperand(0).getReg());
- printInstruction(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
return;
- }
+ }
+
+ case X86::ADD32ri: {
+ // Lower the MO_GOT_ABSOLUTE_ADDRESS form of ADD32ri.
+ if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS)
+ break;
+
+ // Okay, we have something like:
+ // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL)
+
+ // For this, we want to print something like:
+ // MYGLOBAL + (. - PICBASE)
+ // 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.
+ const char *Prefix = MAI->getPrivateGlobalPrefix();
+ MCSymbol *DotSym = OutContext.GetOrCreateSymbol(Twine(Prefix)+"picbaseref"+
+ Twine(getFunctionNumber()));
+ OutStreamer.EmitLabel(DotSym);
+
+ // Now that we have emitted the label, lower the complex operand expression.
+ MCSymbol *OpSym = MCInstLowering.GetExternalSymbolSymbol(MI->getOperand(2));
+
+ const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
+ const MCExpr *PICBase =
+ MCSymbolRefExpr::Create(MCInstLowering.GetPICBaseSymbol(), OutContext);
+ DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext);
+
+ DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext),
+ DotExpr, OutContext);
+
+ MCInst TmpInst;
+ TmpInst.setOpcode(X86::ADD32ri);
+ TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
+ TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
+ TmpInst.addOperand(MCOperand::CreateExpr(DotExpr));
+ OutStreamer.EmitInstruction(TmpInst);
+ return;
+ }
}
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
- printInstruction(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}
+