//===----------------------------------------------------------------------===//
#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;
MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
- SmallString<60> Name;
- raw_svector_ostream(Name) << AsmPrinter.MAI->getPrivateGlobalPrefix()
- << AsmPrinter.getFunctionNumber() << "$pb";
- return Ctx.GetOrCreateSymbol(Name.str());
+ 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::
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ 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());
const MCSymbol *&StubSym = getMachOMMI().getHiddenGVStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
case X86II::MO_DARWIN_STUB: {
Name += "$stub";
MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str());
const MCSymbol *&StubSym = getMachOMMI().getFnStubEntry(Sym);
- if (StubSym == 0) {
- Name.clear();
- Mang->getNameWithPrefix(Name, GV, false);
- StubSym = Ctx.GetOrCreateSymbol(Name.str());
- }
+ if (StubSym == 0)
+ StubSym = AsmPrinter.GetGlobalValueSymbol(GV);
return Sym;
}
// FIXME: These probably should be a modifier on the symbol or something??
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
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:
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
- AsmPrinter.GetMBBSymbol(MO.getMBB()->getNumber()), Ctx));
+ 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)));
- printMCInst(&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());
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
return;
}
// 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.
- SmallString<64> Name;
- raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
- << "picbaseref" << getFunctionNumber();
- MCSymbol *DotSym = OutContext.GetOrCreateSymbol(Name.str());
+ 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.
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
TmpInst.addOperand(MCOperand::CreateExpr(DotExpr));
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
return;
}
}
MCInstLowering.Lower(MI, TmpInst);
- printMCInst(&TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}