#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCStreamer.h"
X86AsmPrinter::StackMapShadowTracker::~StackMapShadowTracker() {}
void
- X86AsmPrinter::StackMapShadowTracker::startFunction(MachineFunction &MF) {
+ X86AsmPrinter::StackMapShadowTracker::startFunction(MachineFunction &F) {
+ MF = &F;
CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(
- *TM.getSubtargetImpl()->getInstrInfo(),
- *TM.getSubtargetImpl()->getRegisterInfo(), *TM.getSubtargetImpl(),
- MF.getContext()));
+ *MF->getSubtarget().getInstrInfo(),
+ *MF->getSubtarget().getRegisterInfo(), MF->getContext()));
}
void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst,
SmallString<256> Code;
SmallVector<MCFixup, 4> Fixups;
raw_svector_ostream VecOS(Code);
- CodeEmitter->EncodeInstruction(Inst, VecOS, Fixups, STI);
+ CodeEmitter->encodeInstruction(Inst, VecOS, Fixups, STI);
VecOS.flush();
CurrentShadowSize += Code.size();
if (CurrentShadowSize >= RequiredShadowSize)
if (InShadow && CurrentShadowSize < RequiredShadowSize) {
InShadow = false;
EmitNops(OutStreamer, RequiredShadowSize - CurrentShadowSize,
- TM.getSubtarget<X86Subtarget>().is64Bit(), STI);
+ MF->getSubtarget<X86Subtarget>().is64Bit(), STI);
}
}
void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) {
- OutStreamer.EmitInstruction(Inst, getSubtargetInfo());
+ OutStreamer->EmitInstruction(Inst, getSubtargetInfo());
SMShadowTracker.count(Inst, getSubtargetInfo());
}
} // end llvm namespace
X86MCInstLower::X86MCInstLower(const MachineFunction &mf,
X86AsmPrinter &asmprinter)
-: Ctx(mf.getContext()), MF(mf), TM(mf.getTarget()),
- MAI(*TM.getMCAsmInfo()), AsmPrinter(asmprinter) {}
+ : Ctx(mf.getContext()), MF(mf), TM(mf.getTarget()), MAI(*TM.getMCAsmInfo()),
+ AsmPrinter(asmprinter) {}
MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
return MF.getMMI().getObjFileInfo<MachineModuleInfoMachO>();
/// operand to an MCSymbol.
MCSymbol *X86MCInstLower::
GetSymbolFromOperand(const MachineOperand &MO) const {
- const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout();
+ const DataLayout *DL = TM.getDataLayout();
assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) && "Isn't a symbol reference");
+ MCSymbol *Sym = nullptr;
SmallString<128> Name;
StringRef Suffix;
const GlobalValue *GV = MO.getGlobal();
AsmPrinter.getNameWithPrefix(Name, GV);
} else if (MO.isSymbol()) {
- getMang()->getNameWithPrefix(Name, MO.getSymbolName());
+ if (MO.getTargetFlags() == X86II::MO_NOPREFIX)
+ Name += MO.getSymbolName();
+ else
+ getMang()->getNameWithPrefix(Name, MO.getSymbolName());
} else if (MO.isMBB()) {
- Name += MO.getMBB()->getSymbol()->getName();
+ assert(Suffix.empty());
+ Sym = MO.getMBB()->getSymbol();
}
unsigned OrigLen = Name.size() - PrefixLen;
Name += Suffix;
- MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name);
+ if (!Sym)
+ Sym = Ctx.getOrCreateSymbol(Name);
StringRef OrigName = StringRef(Name).substr(PrefixLen, OrigLen);
} else {
StubSym =
MachineModuleInfoImpl::
- StubValueTy(Ctx.GetOrCreateSymbol(OrigName), false);
+ StubValueTy(Ctx.getOrCreateSymbol(OrigName), false);
}
break;
}
case X86II::MO_DARWIN_NONLAZY:
case X86II::MO_DLLIMPORT:
case X86II::MO_DARWIN_STUB:
+ case X86II::MO_NOPREFIX:
break;
case X86II::MO_TLVP: RefKind = MCSymbolRefExpr::VK_TLVP; break;
case X86II::MO_TLVP_PIC_BASE:
- Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
+ Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
// Subtract the pic base.
- Expr = MCBinaryExpr::CreateSub(Expr,
- MCSymbolRefExpr::Create(MF.getPICBaseSymbol(),
+ Expr = MCBinaryExpr::createSub(Expr,
+ MCSymbolRefExpr::create(MF.getPICBaseSymbol(),
Ctx),
Ctx);
break;
case X86II::MO_PIC_BASE_OFFSET:
case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
- Expr = MCSymbolRefExpr::Create(Sym, Ctx);
+ Expr = MCSymbolRefExpr::create(Sym, Ctx);
// Subtract the pic base.
- Expr = MCBinaryExpr::CreateSub(Expr,
- MCSymbolRefExpr::Create(MF.getPICBaseSymbol(), Ctx),
+ Expr = MCBinaryExpr::createSub(Expr,
+ MCSymbolRefExpr::create(MF.getPICBaseSymbol(), Ctx),
Ctx);
- if (MO.isJTI() && MAI.hasSetDirective()) {
+ if (MO.isJTI()) {
+ assert(MAI.doesSetDirectiveSuppressesReloc());
// If .set directive is supported, use it to reduce the number of
// relocations the assembler will generate for differences between
// local labels. This is only safe when the symbols are in the same
// section so we are restricting it to jumptable references.
- MCSymbol *Label = Ctx.CreateTempSymbol();
- AsmPrinter.OutStreamer.EmitAssignment(Label, Expr);
- Expr = MCSymbolRefExpr::Create(Label, Ctx);
+ MCSymbol *Label = Ctx.createTempSymbol();
+ AsmPrinter.OutStreamer->EmitAssignment(Label, Expr);
+ Expr = MCSymbolRefExpr::create(Label, Ctx);
}
break;
}
if (!Expr)
- Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
+ Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
- Expr = MCBinaryExpr::CreateAdd(Expr,
- MCConstantExpr::Create(MO.getOffset(), Ctx),
+ Expr = MCBinaryExpr::createAdd(Expr,
+ MCConstantExpr::create(MO.getOffset(), Ctx),
Ctx);
- return MCOperand::CreateExpr(Expr);
+ return MCOperand::createExpr(Expr);
}
Inst.addOperand(Seg);
}
-static unsigned getRetOpcode(const X86Subtarget &Subtarget)
-{
- return Subtarget.is64Bit() ? X86::RETQ : X86::RETL;
+static unsigned getRetOpcode(const X86Subtarget &Subtarget) {
+ return Subtarget.is64Bit() ? X86::RETQ : X86::RETL;
}
void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit()) continue;
- MCOp = MCOperand::CreateReg(MO.getReg());
+ MCOp = MCOperand::createReg(MO.getReg());
break;
case MachineOperand::MO_Immediate:
- MCOp = MCOperand::CreateImm(MO.getImm());
+ MCOp = MCOperand::createImm(MO.getImm());
break;
case MachineOperand::MO_MachineBasicBlock:
case MachineOperand::MO_GlobalAddress:
// inputs modeled as normal uses instead of implicit uses. As such, truncate
// off all but the first operand (the callee). FIXME: Change isel.
case X86::TAILJMPr64:
+ case X86::TAILJMPr64_REX:
case X86::CALL64r:
case X86::CALL64pcrel32: {
unsigned Opcode = OutMI.getOpcode();
break;
}
+ case X86::DEC16r:
+ case X86::DEC32r:
+ case X86::INC16r:
+ case X86::INC32r:
+ // If we aren't in 64-bit mode we can use the 1-byte inc/dec instructions.
+ if (!AsmPrinter.getSubtarget().is64Bit()) {
+ unsigned Opcode;
+ switch (OutMI.getOpcode()) {
+ default: llvm_unreachable("Invalid opcode");
+ case X86::DEC16r: Opcode = X86::DEC16r_alt; break;
+ case X86::DEC32r: Opcode = X86::DEC32r_alt; break;
+ case X86::INC16r: Opcode = X86::INC16r_alt; break;
+ case X86::INC32r: Opcode = X86::INC32r_alt; break;
+ }
+ OutMI.setOpcode(Opcode);
+ }
+ break;
+
// These are pseudo-ops for OR to help with the OR->ADD transformation. We do
// this with an ugly goto in case the resultant OR uses EAX and needs the
// short form.
case X86::ADD32ri8_DB: OutMI.setOpcode(X86::OR32ri8); goto ReSimplify;
case X86::ADD64ri8_DB: OutMI.setOpcode(X86::OR64ri8); goto ReSimplify;
- // The assembler backend wants to see branches in their small form and relax
- // them to their large form. The JIT can only handle the large form because
- // it does not do relaxation. For now, translate the large form to the
- // small one here.
- case X86::JMP_4: OutMI.setOpcode(X86::JMP_1); break;
- case X86::JO_4: OutMI.setOpcode(X86::JO_1); break;
- case X86::JNO_4: OutMI.setOpcode(X86::JNO_1); break;
- case X86::JB_4: OutMI.setOpcode(X86::JB_1); break;
- case X86::JAE_4: OutMI.setOpcode(X86::JAE_1); break;
- case X86::JE_4: OutMI.setOpcode(X86::JE_1); break;
- case X86::JNE_4: OutMI.setOpcode(X86::JNE_1); break;
- case X86::JBE_4: OutMI.setOpcode(X86::JBE_1); break;
- case X86::JA_4: OutMI.setOpcode(X86::JA_1); break;
- case X86::JS_4: OutMI.setOpcode(X86::JS_1); break;
- case X86::JNS_4: OutMI.setOpcode(X86::JNS_1); break;
- case X86::JP_4: OutMI.setOpcode(X86::JP_1); break;
- case X86::JNP_4: OutMI.setOpcode(X86::JNP_1); break;
- case X86::JL_4: OutMI.setOpcode(X86::JL_1); break;
- case X86::JGE_4: OutMI.setOpcode(X86::JGE_1); break;
- case X86::JLE_4: OutMI.setOpcode(X86::JLE_1); break;
- case X86::JG_4: OutMI.setOpcode(X86::JG_1); break;
-
// Atomic load and store require a separate pseudo-inst because Acquire
// implies mayStore and Release implies mayLoad; fix these to regular MOV
// instructions here
// MOV64ao8, MOV64o8a
// XCHG16ar, XCHG32ar, XCHG64ar
case X86::MOV8mr_NOREX:
- case X86::MOV8mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8ao8); break;
+ case X86::MOV8mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8o32a); break;
case X86::MOV8rm_NOREX:
- case X86::MOV8rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8o8a); break;
- case X86::MOV16mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16ao16); break;
- case X86::MOV16rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16o16a); break;
- case X86::MOV32mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32ao32); break;
- case X86::MOV32rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32o32a); break;
+ case X86::MOV8rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV8ao32); break;
+ case X86::MOV16mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16o32a); break;
+ case X86::MOV16rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV16ao32); break;
+ case X86::MOV32mr: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32o32a); break;
+ case X86::MOV32rm: SimplifyShortMoveForm(AsmPrinter, OutMI, X86::MOV32ao32); break;
case X86::ADC8ri: SimplifyShortImmForm(OutMI, X86::ADC8i8); break;
case X86::ADC16ri: SimplifyShortImmForm(OutMI, X86::ADC16i16); break;
bool needsPadding = MI.getOpcode() == X86::TLS_addr64;
- MCContext &context = OutStreamer.getContext();
+ MCContext &context = OutStreamer->getContext();
if (needsPadding)
EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX));
}
MCSymbol *sym = MCInstLowering.GetSymbolFromOperand(MI.getOperand(3));
- const MCSymbolRefExpr *symRef = MCSymbolRefExpr::Create(sym, SRVK, context);
+ const MCSymbolRefExpr *symRef = MCSymbolRefExpr::create(sym, SRVK, context);
MCInst LEA;
if (is64Bits) {
LEA.setOpcode(X86::LEA64r);
- LEA.addOperand(MCOperand::CreateReg(X86::RDI)); // dest
- LEA.addOperand(MCOperand::CreateReg(X86::RIP)); // base
- LEA.addOperand(MCOperand::CreateImm(1)); // scale
- LEA.addOperand(MCOperand::CreateReg(0)); // index
- LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp
- LEA.addOperand(MCOperand::CreateReg(0)); // seg
+ LEA.addOperand(MCOperand::createReg(X86::RDI)); // dest
+ LEA.addOperand(MCOperand::createReg(X86::RIP)); // base
+ LEA.addOperand(MCOperand::createImm(1)); // scale
+ LEA.addOperand(MCOperand::createReg(0)); // index
+ LEA.addOperand(MCOperand::createExpr(symRef)); // disp
+ LEA.addOperand(MCOperand::createReg(0)); // seg
} else if (SRVK == MCSymbolRefExpr::VK_TLSLDM) {
LEA.setOpcode(X86::LEA32r);
- LEA.addOperand(MCOperand::CreateReg(X86::EAX)); // dest
- LEA.addOperand(MCOperand::CreateReg(X86::EBX)); // base
- LEA.addOperand(MCOperand::CreateImm(1)); // scale
- LEA.addOperand(MCOperand::CreateReg(0)); // index
- LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp
- LEA.addOperand(MCOperand::CreateReg(0)); // seg
+ LEA.addOperand(MCOperand::createReg(X86::EAX)); // dest
+ LEA.addOperand(MCOperand::createReg(X86::EBX)); // base
+ LEA.addOperand(MCOperand::createImm(1)); // scale
+ LEA.addOperand(MCOperand::createReg(0)); // index
+ LEA.addOperand(MCOperand::createExpr(symRef)); // disp
+ LEA.addOperand(MCOperand::createReg(0)); // seg
} else {
LEA.setOpcode(X86::LEA32r);
- LEA.addOperand(MCOperand::CreateReg(X86::EAX)); // dest
- LEA.addOperand(MCOperand::CreateReg(0)); // base
- LEA.addOperand(MCOperand::CreateImm(1)); // scale
- LEA.addOperand(MCOperand::CreateReg(X86::EBX)); // index
- LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp
- LEA.addOperand(MCOperand::CreateReg(0)); // seg
+ LEA.addOperand(MCOperand::createReg(X86::EAX)); // dest
+ LEA.addOperand(MCOperand::createReg(0)); // base
+ LEA.addOperand(MCOperand::createImm(1)); // scale
+ LEA.addOperand(MCOperand::createReg(X86::EBX)); // index
+ LEA.addOperand(MCOperand::createExpr(symRef)); // disp
+ LEA.addOperand(MCOperand::createReg(0)); // seg
}
EmitAndCountInstruction(LEA);
}
StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr";
- MCSymbol *tlsGetAddr = context.GetOrCreateSymbol(name);
+ MCSymbol *tlsGetAddr = context.getOrCreateSymbol(name);
const MCSymbolRefExpr *tlsRef =
- MCSymbolRefExpr::Create(tlsGetAddr,
+ MCSymbolRefExpr::create(tlsGetAddr,
MCSymbolRefExpr::VK_PLT,
context);
} // while (NumBytes)
}
+void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI,
+ X86MCInstLower &MCIL) {
+ assert(Subtarget->is64Bit() && "Statepoint currently only supports X86-64");
+
+ StatepointOpers SOpers(&MI);
+ if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
+ EmitNops(*OutStreamer, PatchBytes, Subtarget->is64Bit(),
+ getSubtargetInfo());
+ } else {
+ // Lower call target and choose correct opcode
+ const MachineOperand &CallTarget = SOpers.getCallTarget();
+ MCOperand CallTargetMCOp;
+ unsigned CallOpcode;
+ switch (CallTarget.getType()) {
+ case MachineOperand::MO_GlobalAddress:
+ case MachineOperand::MO_ExternalSymbol:
+ CallTargetMCOp = MCIL.LowerSymbolOperand(
+ CallTarget, MCIL.GetSymbolFromOperand(CallTarget));
+ CallOpcode = X86::CALL64pcrel32;
+ // Currently, we only support relative addressing with statepoints.
+ // Otherwise, we'll need a scratch register to hold the target
+ // address. You'll fail asserts during load & relocation if this
+ // symbol is to far away. (TODO: support non-relative addressing)
+ break;
+ case MachineOperand::MO_Immediate:
+ CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
+ CallOpcode = X86::CALL64pcrel32;
+ // Currently, we only support relative addressing with statepoints.
+ // Otherwise, we'll need a scratch register to hold the target
+ // immediate. You'll fail asserts during load & relocation if this
+ // address is to far away. (TODO: support non-relative addressing)
+ break;
+ case MachineOperand::MO_Register:
+ CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
+ CallOpcode = X86::CALL64r;
+ break;
+ default:
+ llvm_unreachable("Unsupported operand type in statepoint call target");
+ break;
+ }
+
+ // Emit call
+ MCInst CallInst;
+ CallInst.setOpcode(CallOpcode);
+ CallInst.addOperand(CallTargetMCOp);
+ OutStreamer->EmitInstruction(CallInst, getSubtargetInfo());
+ }
+
+ // Record our statepoint node in the same section used by STACKMAP
+ // and PATCHPOINT
+ SM.recordStatepoint(MI);
+}
+
+
// Lower a stackmap of the form:
// <id>, <shadowBytes>, ...
void X86AsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
- SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo());
+ SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
SM.recordStackMap(MI);
unsigned NumShadowBytes = MI.getOperand(1).getImm();
SMShadowTracker.reset(NumShadowBytes);
// Lower a patchpoint of the form:
// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
-void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI) {
+void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
+ X86MCInstLower &MCIL) {
assert(Subtarget->is64Bit() && "Patchpoint currently only supports X86-64");
- SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo());
+ SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
SM.recordPatchPoint(MI);
PatchPointOpers opers(&MI);
unsigned ScratchIdx = opers.getNextScratchIdx();
unsigned EncodedBytes = 0;
- int64_t CallTarget = opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
- if (CallTarget) {
+ const MachineOperand &CalleeMO =
+ opers.getMetaOper(PatchPointOpers::TargetPos);
+
+ // Check for null target. If target is non-null (i.e. is non-zero or is
+ // symbolic) then emit a call.
+ if (!(CalleeMO.isImm() && !CalleeMO.getImm())) {
+ MCOperand CalleeMCOp;
+ switch (CalleeMO.getType()) {
+ default:
+ /// FIXME: Add a verifier check for bad callee types.
+ llvm_unreachable("Unrecognized callee operand type.");
+ case MachineOperand::MO_Immediate:
+ if (CalleeMO.getImm())
+ CalleeMCOp = MCOperand::createImm(CalleeMO.getImm());
+ break;
+ case MachineOperand::MO_ExternalSymbol:
+ case MachineOperand::MO_GlobalAddress:
+ CalleeMCOp =
+ MCIL.LowerSymbolOperand(CalleeMO,
+ MCIL.GetSymbolFromOperand(CalleeMO));
+ break;
+ }
+
// Emit MOV to materialize the target address and the CALL to target.
// This is encoded with 12-13 bytes, depending on which register is used.
unsigned ScratchReg = MI.getOperand(ScratchIdx).getReg();
EncodedBytes = 13;
else
EncodedBytes = 12;
- EmitAndCountInstruction(MCInstBuilder(X86::MOV64ri).addReg(ScratchReg)
- .addImm(CallTarget));
+
+ EmitAndCountInstruction(
+ MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).addOperand(CalleeMCOp));
EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg));
}
+
// 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(OutStreamer, NumBytes - EncodedBytes, Subtarget->is64Bit(),
+ EmitNops(*OutStreamer, NumBytes - EncodedBytes, Subtarget->is64Bit(),
getSubtargetInfo());
}
void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
X86MCInstLower MCInstLowering(*MF, *this);
- const X86RegisterInfo *RI = static_cast<const X86RegisterInfo *>(
- TM.getSubtargetImpl()->getRegisterInfo());
+ const X86RegisterInfo *RI = MF->getSubtarget<X86Subtarget>().getRegisterInfo();
switch (MI->getOpcode()) {
case TargetOpcode::DBG_VALUE:
// Emit nothing here but a comment if we can.
case X86::Int_MemBarrier:
- OutStreamer.emitRawComment("MEMBARRIER");
+ OutStreamer->emitRawComment("MEMBARRIER");
return;
case X86::EH_RETURN64: {
// Lower these as normal, but add some comments.
unsigned Reg = MI->getOperand(0).getReg();
- OutStreamer.AddComment(StringRef("eh_return, addr: %") +
- X86ATTInstPrinter::getRegisterName(Reg));
+ OutStreamer->AddComment(StringRef("eh_return, addr: %") +
+ X86ATTInstPrinter::getRegisterName(Reg));
break;
}
case X86::TAILJMPr:
+ case X86::TAILJMPm:
case X86::TAILJMPd:
+ case X86::TAILJMPr64:
+ case X86::TAILJMPm64:
case X86::TAILJMPd64:
+ case X86::TAILJMPr64_REX:
+ case X86::TAILJMPm64_REX:
+ case X86::TAILJMPd64_REX:
// Lower these as normal, but add some comments.
- OutStreamer.AddComment("TAILCALL");
+ OutStreamer->AddComment("TAILCALL");
break;
case X86::TLS_addr32:
// FIXME: We would like an efficient form for this, so we don't have to do a
// lot of extra uniquing.
EmitAndCountInstruction(MCInstBuilder(X86::CALLpcrel32)
- .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext)));
+ .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
// Emit the label.
- OutStreamer.EmitLabel(PICBase);
+ OutStreamer->EmitLabel(PICBase);
// popl $reg
EmitAndCountInstruction(MCInstBuilder(X86::POP32r)
// MYGLOBAL + (. - PICBASE)
// However, we can't generate a ".", so just emit a new label here and refer
// to it.
- MCSymbol *DotSym = OutContext.CreateTempSymbol();
- OutStreamer.EmitLabel(DotSym);
+ MCSymbol *DotSym = OutContext.createTempSymbol();
+ OutStreamer->EmitLabel(DotSym);
// Now that we have emitted the label, lower the complex operand expression.
MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2));
- const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext);
+ const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
const MCExpr *PICBase =
- MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), OutContext);
- DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext);
+ MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
+ DotExpr = MCBinaryExpr::createSub(DotExpr, PICBase, OutContext);
- DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext),
+ DotExpr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(OpSym,OutContext),
DotExpr, OutContext);
EmitAndCountInstruction(MCInstBuilder(X86::ADD32ri)
.addExpr(DotExpr));
return;
}
+ case TargetOpcode::STATEPOINT:
+ return LowerSTATEPOINT(*MI, MCInstLowering);
case TargetOpcode::STACKMAP:
return LowerSTACKMAP(*MI);
case TargetOpcode::PATCHPOINT:
- return LowerPATCHPOINT(*MI);
+ return LowerPATCHPOINT(*MI, MCInstLowering);
case X86::MORESTACK_RET:
EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget)));
return;
case X86::SEH_PushReg:
- OutStreamer.EmitWinCFIPushReg(RI->getSEHRegNum(MI->getOperand(0).getImm()));
+ OutStreamer->EmitWinCFIPushReg(RI->getSEHRegNum(MI->getOperand(0).getImm()));
return;
case X86::SEH_SaveReg:
- OutStreamer.EmitWinCFISaveReg(RI->getSEHRegNum(MI->getOperand(0).getImm()),
- MI->getOperand(1).getImm());
+ OutStreamer->EmitWinCFISaveReg(RI->getSEHRegNum(MI->getOperand(0).getImm()),
+ MI->getOperand(1).getImm());
return;
case X86::SEH_SaveXMM:
- OutStreamer.EmitWinCFISaveXMM(RI->getSEHRegNum(MI->getOperand(0).getImm()),
- MI->getOperand(1).getImm());
+ OutStreamer->EmitWinCFISaveXMM(RI->getSEHRegNum(MI->getOperand(0).getImm()),
+ MI->getOperand(1).getImm());
return;
case X86::SEH_StackAlloc:
- OutStreamer.EmitWinCFIAllocStack(MI->getOperand(0).getImm());
+ OutStreamer->EmitWinCFIAllocStack(MI->getOperand(0).getImm());
return;
case X86::SEH_SetFrame:
- OutStreamer.EmitWinCFISetFrame(RI->getSEHRegNum(MI->getOperand(0).getImm()),
- MI->getOperand(1).getImm());
+ OutStreamer->EmitWinCFISetFrame(RI->getSEHRegNum(MI->getOperand(0).getImm()),
+ MI->getOperand(1).getImm());
return;
case X86::SEH_PushFrame:
- OutStreamer.EmitWinCFIPushFrame(MI->getOperand(0).getImm());
+ OutStreamer->EmitWinCFIPushFrame(MI->getOperand(0).getImm());
return;
case X86::SEH_EndPrologue:
- OutStreamer.EmitWinCFIEndProlog();
+ OutStreamer->EmitWinCFIEndProlog();
return;
case X86::SEH_Epilogue: {
case X86::PSHUFBrm:
case X86::VPSHUFBrm:
case X86::VPSHUFBYrm: {
- if (!OutStreamer.isVerboseAsm())
+ if (!OutStreamer->isVerboseAsm())
break;
assert(MI->getNumOperands() > 5 &&
"We should always have at least 5 operands!");
SmallVector<int, 16> Mask;
DecodePSHUFBMask(C, Mask);
if (!Mask.empty())
- OutStreamer.AddComment(getShuffleComment(DstOp, SrcOp, Mask));
+ OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp, Mask));
}
break;
}
case X86::VPERMILPDrm:
case X86::VPERMILPSYrm:
case X86::VPERMILPDYrm: {
- if (!OutStreamer.isVerboseAsm())
+ if (!OutStreamer->isVerboseAsm())
break;
assert(MI->getNumOperands() > 5 &&
"We should always have at least 5 operands!");
SmallVector<int, 16> Mask;
DecodeVPERMILPMask(C, Mask);
if (!Mask.empty())
- OutStreamer.AddComment(getShuffleComment(DstOp, SrcOp, Mask));
+ OutStreamer->AddComment(getShuffleComment(DstOp, SrcOp, Mask));
}
break;
}
case X86::MOVDQUrm:
case X86::VMOVDQUrm:
case X86::VMOVDQUYrm:
- if (!OutStreamer.isVerboseAsm())
+ if (!OutStreamer->isVerboseAsm())
break;
if (MI->getNumOperands() > 4)
if (auto *C = getConstantFromPool(*MI, MI->getOperand(4))) {
CS << "?";
}
CS << "]";
- OutStreamer.AddComment(CS.str());
+ OutStreamer->AddComment(CS.str());
} else if (auto *CV = dyn_cast<ConstantVector>(C)) {
CS << "<";
for (int i = 0, NumOperands = CV->getNumOperands(); i < NumOperands; ++i) {
}
}
CS << ">";
- OutStreamer.AddComment(CS.str());
+ OutStreamer->AddComment(CS.str());
}
}
break;
MCInst TmpInst;
MCInstLowering.Lower(MI, TmpInst);
+
+ // Stackmap shadows cannot include branch targets, so we can count the bytes
+ // in a call towards the shadow, but must ensure that the no thread returns
+ // in to the stackmap shadow. The only way to achieve this is if the call
+ // is at the end of the shadow.
+ if (MI->isCall()) {
+ // Count then size of the call towards the shadow
+ SMShadowTracker.count(TmpInst, getSubtargetInfo());
+ // Then flush the shadow so that we fill with nops before the call, not
+ // after it.
+ SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
+ // Then emit the call
+ OutStreamer->EmitInstruction(TmpInst, getSubtargetInfo());
+ return;
+ }
+
EmitAndCountInstruction(TmpInst);
}