#include "X86AsmPrinter.h"
#include "InstPrinter/X86ATTInstPrinter.h"
-#include "X86COFFMachineModuleInfo.h"
+#include "MCTargetDesc/X86BaseInfo.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/StackMaps.h"
-#include "llvm/IR/Type.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Target/Mangler.h"
using namespace llvm;
namespace {
/// operand to an MCSymbol.
MCSymbol *X86MCInstLower::
GetSymbolFromOperand(const MachineOperand &MO) const {
+ const DataLayout *DL = TM.getDataLayout();
assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) && "Isn't a symbol reference");
SmallString<128> Name;
}
if (!Suffix.empty())
- Name += MAI.getPrivateGlobalPrefix();
+ Name += DL->getPrivateGlobalPrefix();
unsigned PrefixLen = Name.size();
if (MO.isGlobal()) {
const GlobalValue *GV = MO.getGlobal();
- getMang()->getNameWithPrefix(Name, GV, false);
+ AsmPrinter.getNameWithPrefix(Name, GV);
} else if (MO.isSymbol()) {
getMang()->getNameWithPrefix(Name, MO.getSymbolName());
} else if (MO.isMBB()) {
case X86II::MO_DARWIN_NONLAZY_PIC_BASE: {
MachineModuleInfoImpl::StubValueTy &StubSym =
getMachOMMI().getGVStubEntry(Sym);
- if (StubSym.getPointer() == 0) {
+ if (!StubSym.getPointer()) {
assert(MO.isGlobal() && "Extern symbol not handled yet");
StubSym =
MachineModuleInfoImpl::
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: {
MachineModuleInfoImpl::StubValueTy &StubSym =
getMachOMMI().getHiddenGVStubEntry(Sym);
- if (StubSym.getPointer() == 0) {
+ if (!StubSym.getPointer()) {
assert(MO.isGlobal() && "Extern symbol not handled yet");
StubSym =
MachineModuleInfoImpl::
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 = 0;
+ const MCExpr *Expr = nullptr;
MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
switch (MO.getTargetFlags()) {
break;
}
- if (Expr == 0)
+ if (!Expr)
Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
}
-/// LowerUnaryToTwoAddr - R = setb -> R = sbb R, R
-static void LowerUnaryToTwoAddr(MCInst &OutMI, unsigned NewOpc) {
- OutMI.setOpcode(NewOpc);
- OutMI.addOperand(OutMI.getOperand(0));
- OutMI.addOperand(OutMI.getOperand(0));
-}
-
/// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
/// a short fixed-register form.
static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) {
unsigned RegOp = IsStore ? 0 : 5;
unsigned AddrOp = AddrBase + 3;
assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() &&
- Inst.getOperand(AddrBase + 0).isReg() && // base
- Inst.getOperand(AddrBase + 1).isImm() && // scale
- Inst.getOperand(AddrBase + 2).isReg() && // index register
- (Inst.getOperand(AddrOp).isExpr() || // address
- Inst.getOperand(AddrOp).isImm())&&
- Inst.getOperand(AddrBase + 4).isReg() && // segment
+ Inst.getOperand(AddrBase + X86::AddrBaseReg).isReg() &&
+ Inst.getOperand(AddrBase + X86::AddrScaleAmt).isImm() &&
+ Inst.getOperand(AddrBase + X86::AddrIndexReg).isReg() &&
+ Inst.getOperand(AddrBase + X86::AddrSegmentReg).isReg() &&
+ (Inst.getOperand(AddrOp).isExpr() ||
+ Inst.getOperand(AddrOp).isImm()) &&
"Unexpected instruction!");
// Check whether the destination register can be fixed.
}
if (Absolute &&
- (Inst.getOperand(AddrBase + 0).getReg() != 0 ||
- Inst.getOperand(AddrBase + 2).getReg() != 0 ||
- Inst.getOperand(AddrBase + 4).getReg() != 0 ||
- Inst.getOperand(AddrBase + 1).getImm() != 1))
+ (Inst.getOperand(AddrBase + X86::AddrBaseReg).getReg() != 0 ||
+ Inst.getOperand(AddrBase + X86::AddrScaleAmt).getImm() != 1 ||
+ Inst.getOperand(AddrBase + X86::AddrIndexReg).getReg() != 0))
return;
// If so, rewrite the instruction.
MCOperand Saved = Inst.getOperand(AddrOp);
+ MCOperand Seg = Inst.getOperand(AddrBase + X86::AddrSegmentReg);
Inst = MCInst();
Inst.setOpcode(Opcode);
Inst.addOperand(Saved);
+ Inst.addOperand(Seg);
+}
+
+static unsigned getRetOpcode(const X86Subtarget &Subtarget)
+{
+ return Subtarget.is64Bit() ? X86::RETQ : X86::RETL;
}
void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
assert(OutMI.getOperand(1+X86::AddrSegmentReg).getReg() == 0 &&
"LEA has segment specified!");
break;
- case X86::MOV32r0: LowerUnaryToTwoAddr(OutMI, X86::XOR32rr); break;
case X86::MOV32ri64:
OutMI.setOpcode(X86::MOV32ri);
case X86::EH_RETURN:
case X86::EH_RETURN64: {
OutMI = MCInst();
- OutMI.setOpcode(X86::RET);
+ OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget()));
break;
}
static void LowerTlsAddr(MCStreamer &OutStreamer,
X86MCInstLower &MCInstLowering,
- const MachineInstr &MI) {
+ const MachineInstr &MI,
+ const MCSubtargetInfo& STI) {
bool is64Bits = MI.getOpcode() == X86::TLS_addr64 ||
MI.getOpcode() == X86::TLS_base_addr64;
MCContext &context = OutStreamer.getContext();
if (needsPadding)
- OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX));
+ OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX), STI);
MCSymbolRefExpr::VariantKind SRVK;
switch (MI.getOpcode()) {
LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp
LEA.addOperand(MCOperand::CreateReg(0)); // seg
}
- OutStreamer.EmitInstruction(LEA);
+ OutStreamer.EmitInstruction(LEA, STI);
if (needsPadding) {
- OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX));
- OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX));
- OutStreamer.EmitInstruction(MCInstBuilder(X86::REX64_PREFIX));
+ OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX), STI);
+ OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX), STI);
+ OutStreamer.EmitInstruction(MCInstBuilder(X86::REX64_PREFIX), STI);
}
StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr";
OutStreamer.EmitInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32
: X86::CALLpcrel32)
- .addExpr(tlsRef));
+ .addExpr(tlsRef), STI);
}
/// \brief Emit the optimal amount of multi-byte nops on X86.
-static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit) {
+static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit, const MCSubtargetInfo &STI) {
// This works only for 64bit. For 32bit we have to do additional checking if
// the CPU supports multi-byte nops.
assert(Is64Bit && "EmitNops only supports X86-64");
switch (Opc) {
default: llvm_unreachable("Unexpected opcode"); break;
case X86::NOOP:
- OS.EmitInstruction(MCInstBuilder(Opc));
+ OS.EmitInstruction(MCInstBuilder(Opc), STI);
break;
case X86::XCHG16ar:
- OS.EmitInstruction(MCInstBuilder(Opc).addReg(X86::AX));
+ OS.EmitInstruction(MCInstBuilder(Opc).addReg(X86::AX), STI);
break;
case X86::NOOPL:
case X86::NOOPW:
OS.EmitInstruction(MCInstBuilder(Opc).addReg(BaseReg).addImm(ScaleVal)
.addReg(IndexReg)
.addImm(Displacement)
- .addReg(SegmentReg));
+ .addReg(SegmentReg), STI);
break;
}
} // while (NumBytes)
// Lower a stackmap of the form:
// <id>, <shadowBytes>, ...
static void LowerSTACKMAP(MCStreamer &OS, StackMaps &SM,
- const MachineInstr &MI, bool Is64Bit) {
+ const MachineInstr &MI, bool Is64Bit, const MCSubtargetInfo& STI) {
unsigned NumBytes = MI.getOperand(1).getImm();
SM.recordStackMap(MI);
// Emit padding.
// FIXME: These nops ensure that the stackmap's shadow is covered by
// instructions from the same basic block, but the nops should not be
// necessary if instructions from the same block follow the stackmap.
- EmitNops(OS, NumBytes, Is64Bit);
+ EmitNops(OS, NumBytes, Is64Bit, STI);
}
// Lower a patchpoint of the form:
// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
static void LowerPATCHPOINT(MCStreamer &OS, StackMaps &SM,
- const MachineInstr &MI, bool Is64Bit) {
+ const MachineInstr &MI, bool Is64Bit, const MCSubtargetInfo& STI) {
assert(Is64Bit && "Patchpoint currently only supports X86-64");
SM.recordPatchPoint(MI);
else
EncodedBytes = 12;
OS.EmitInstruction(MCInstBuilder(X86::MOV64ri).addReg(ScratchReg)
- .addImm(CallTarget));
- OS.EmitInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
+ .addImm(CallTarget), STI);
+ OS.EmitInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg), STI);
}
// Emit padding.
unsigned NumBytes = opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
assert(NumBytes >= EncodedBytes &&
"Patchpoint can't request size less than the length of a call.");
- EmitNops(OS, NumBytes - EncodedBytes, Is64Bit);
+ EmitNops(OS, NumBytes - EncodedBytes, Is64Bit, STI);
}
void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Emit nothing here but a comment if we can.
case X86::Int_MemBarrier:
- if (OutStreamer.hasRawTextSupport())
- OutStreamer.EmitRawText(StringRef("\t#MEMBARRIER"));
+ OutStreamer.emitRawComment("MEMBARRIER");
return;
case X86::TLS_addr64:
case X86::TLS_base_addr32:
case X86::TLS_base_addr64:
- return LowerTlsAddr(OutStreamer, MCInstLowering, *MI);
+ return LowerTlsAddr(OutStreamer, MCInstLowering, *MI, getSubtargetInfo());
case X86::MOVPC32r: {
// This is a pseudo op for a two instruction sequence with a label, which
MCSymbol *PICBase = MF->getPICBaseSymbol();
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
- OutStreamer.EmitInstruction(MCInstBuilder(X86::CALLpcrel32)
+ EmitToStreamer(OutStreamer, MCInstBuilder(X86::CALLpcrel32)
.addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
// Emit the label.
OutStreamer.EmitLabel(PICBase);
// popl $reg
- OutStreamer.EmitInstruction(MCInstBuilder(X86::POP32r)
+ EmitToStreamer(OutStreamer, MCInstBuilder(X86::POP32r)
.addReg(MI->getOperand(0).getReg()));
return;
}
DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext),
DotExpr, OutContext);
- OutStreamer.EmitInstruction(MCInstBuilder(X86::ADD32ri)
+ EmitToStreamer(OutStreamer, MCInstBuilder(X86::ADD32ri)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(1).getReg())
.addExpr(DotExpr));
}
case TargetOpcode::STACKMAP:
- return LowerSTACKMAP(OutStreamer, SM, *MI, Subtarget->is64Bit());
+ return LowerSTACKMAP(OutStreamer, SM, *MI, Subtarget->is64Bit(), getSubtargetInfo());
case TargetOpcode::PATCHPOINT:
- return LowerPATCHPOINT(OutStreamer, SM, *MI, Subtarget->is64Bit());
+ return LowerPATCHPOINT(OutStreamer, SM, *MI, Subtarget->is64Bit(), getSubtargetInfo());
case X86::MORESTACK_RET:
- OutStreamer.EmitInstruction(MCInstBuilder(X86::RET));
+ EmitToStreamer(OutStreamer, MCInstBuilder(getRetOpcode(*Subtarget)));
return;
case X86::MORESTACK_RET_RESTORE_R10:
// Return, then restore R10.
- OutStreamer.EmitInstruction(MCInstBuilder(X86::RET));
- OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64rr)
+ EmitToStreamer(OutStreamer, MCInstBuilder(getRetOpcode(*Subtarget)));
+ EmitToStreamer(OutStreamer, MCInstBuilder(X86::MOV64rr)
.addReg(X86::R10)
.addReg(X86::RAX));
return;
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
- OutStreamer.EmitInstruction(TmpInst);
+ EmitToStreamer(OutStreamer, TmpInst);
}