X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86MCInstLower.cpp;h=4b55f00db6397f5110c19782f2a712e101de5e98;hp=6649c825b6c9e2dba8e7813b8ae73fd1ac8fa315;hb=b96e8338171ed4cb23a3b14d94db2361b0d544e8;hpb=8ddf988ef4aaa8275bb2b58e9ef8b65ef8009f8c diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp index 6649c825b6c..4b55f00db63 100644 --- a/lib/Target/X86/X86MCInstLower.cpp +++ b/lib/Target/X86/X86MCInstLower.cpp @@ -13,21 +13,25 @@ //===----------------------------------------------------------------------===// #include "X86AsmPrinter.h" +#include "X86RegisterInfo.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/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.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" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; namespace { @@ -56,6 +60,52 @@ private: } // end anonymous namespace +// Emit a minimal sequence of nops spanning NumBytes bytes. +static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit, + const MCSubtargetInfo &STI); + +namespace llvm { + X86AsmPrinter::StackMapShadowTracker::StackMapShadowTracker(TargetMachine &TM) + : TM(TM), Count(false), RequiredShadowSize(0), CurrentShadowSize(0) {} + + X86AsmPrinter::StackMapShadowTracker::~StackMapShadowTracker() {} + + void + X86AsmPrinter::StackMapShadowTracker::startFunction(MachineFunction &MF) { + CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(*TM.getInstrInfo(), + *TM.getRegisterInfo(), + *TM.getSubtargetImpl(), + MF.getContext())); + } + + void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst, + const MCSubtargetInfo &STI) { + if (Count) { + SmallString<256> Code; + SmallVector Fixups; + raw_svector_ostream VecOS(Code); + CodeEmitter->EncodeInstruction(Inst, VecOS, Fixups, STI); + VecOS.flush(); + CurrentShadowSize += Code.size(); + if (CurrentShadowSize >= RequiredShadowSize) + Count = false; // The shadow is big enough. Stop counting. + } + } + + void X86AsmPrinter::StackMapShadowTracker::emitShadowPadding( + MCStreamer &OutStreamer, const MCSubtargetInfo &STI) { + if (Count && CurrentShadowSize < RequiredShadowSize) + EmitNops(OutStreamer, RequiredShadowSize - CurrentShadowSize, + TM.getSubtarget().is64Bit(), STI); + Count = false; + } + + void X86AsmPrinter::EmitAndCountInstruction(MCInst &Inst) { + 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()), @@ -70,70 +120,77 @@ MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const { /// 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; + StringRef Suffix; + + switch (MO.getTargetFlags()) { + case X86II::MO_DLLIMPORT: + // Handle dllimport linkage. + Name += "__imp_"; + break; + case X86II::MO_DARWIN_STUB: + Suffix = "$stub"; + break; + case X86II::MO_DARWIN_NONLAZY: + case X86II::MO_DARWIN_NONLAZY_PIC_BASE: + case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: + Suffix = "$non_lazy_ptr"; + break; + } + + if (!Suffix.empty()) + Name += DL->getPrivateGlobalPrefix(); + + unsigned PrefixLen = Name.size(); if (MO.isGlobal()) { const GlobalValue *GV = MO.getGlobal(); - bool isImplicitlyPrivate = false; - if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB || - MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || - MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || - MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) - isImplicitlyPrivate = true; - - getMang()->getNameWithPrefix(Name, GV, isImplicitlyPrivate); + AsmPrinter.getNameWithPrefix(Name, GV); } else if (MO.isSymbol()) { - Name += MAI.getGlobalPrefix(); - Name += MO.getSymbolName(); + getMang()->getNameWithPrefix(Name, MO.getSymbolName()); } else if (MO.isMBB()) { Name += MO.getMBB()->getSymbol()->getName(); } + unsigned OrigLen = Name.size() - PrefixLen; + + Name += Suffix; + MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + + StringRef OrigName = StringRef(Name).substr(PrefixLen, OrigLen); // If the target flags on the operand changes the name of the symbol, do that // before we return the symbol. switch (MO.getTargetFlags()) { default: break; - case X86II::MO_DLLIMPORT: { - // Handle dllimport linkage. - const char *Prefix = "__imp_"; - Name.insert(Name.begin(), Prefix, Prefix+strlen(Prefix)); - break; - } case X86II::MO_DARWIN_NONLAZY: case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { - Name += "$non_lazy_ptr"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); - MachineModuleInfoImpl::StubValueTy &StubSym = getMachOMMI().getGVStubEntry(Sym); - if (StubSym.getPointer() == 0) { + if (!StubSym.getPointer()) { assert(MO.isGlobal() && "Extern symbol not handled yet"); StubSym = MachineModuleInfoImpl:: StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()), !MO.getGlobal()->hasInternalLinkage()); } - return Sym; + break; } case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { - Name += "$non_lazy_ptr"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); MachineModuleInfoImpl::StubValueTy &StubSym = getMachOMMI().getHiddenGVStubEntry(Sym); - if (StubSym.getPointer() == 0) { + if (!StubSym.getPointer()) { assert(MO.isGlobal() && "Extern symbol not handled yet"); StubSym = MachineModuleInfoImpl:: StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()), !MO.getGlobal()->hasInternalLinkage()); } - return Sym; + break; } case X86II::MO_DARWIN_STUB: { - Name += "$stub"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); MachineModuleInfoImpl::StubValueTy &StubSym = getMachOMMI().getFnStubEntry(Sym); if (StubSym.getPointer()) @@ -145,23 +202,22 @@ GetSymbolFromOperand(const MachineOperand &MO) const { StubValueTy(AsmPrinter.getSymbol(MO.getGlobal()), !MO.getGlobal()->hasInternalLinkage()); } else { - Name.erase(Name.end()-5, Name.end()); StubSym = MachineModuleInfoImpl:: - StubValueTy(Ctx.GetOrCreateSymbol(Name.str()), false); + StubValueTy(Ctx.GetOrCreateSymbol(OrigName), false); } - return Sym; + break; } } - return Ctx.GetOrCreateSymbol(Name.str()); + return 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 = 0; + const MCExpr *Expr = nullptr; MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; switch (MO.getTargetFlags()) { @@ -216,7 +272,7 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, break; } - if (Expr == 0) + if (!Expr) Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx); if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) @@ -227,13 +283,6 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, } -/// 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) { @@ -297,12 +346,12 @@ static void SimplifyShortMoveForm(X86AsmPrinter &Printer, MCInst &Inst, 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. @@ -322,17 +371,23 @@ static void SimplifyShortMoveForm(X86AsmPrinter &Printer, MCInst &Inst, } 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 { @@ -390,7 +445,6 @@ ReSimplify: 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); @@ -464,7 +518,7 @@ ReSimplify: case X86::EH_RETURN: case X86::EH_RETURN64: { OutMI = MCInst(); - OutMI.setOpcode(X86::RET); + OutMI.setOpcode(getRetOpcode(AsmPrinter.getSubtarget())); break; } @@ -596,9 +650,8 @@ ReSimplify: } } -static void LowerTlsAddr(MCStreamer &OutStreamer, - X86MCInstLower &MCInstLowering, - const MachineInstr &MI) { +void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering, + const MachineInstr &MI) { bool is64Bits = MI.getOpcode() == X86::TLS_addr64 || MI.getOpcode() == X86::TLS_base_addr64; @@ -608,7 +661,7 @@ static void LowerTlsAddr(MCStreamer &OutStreamer, MCContext &context = OutStreamer.getContext(); if (needsPadding) - OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX)); + EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX)); MCSymbolRefExpr::VariantKind SRVK; switch (MI.getOpcode()) { @@ -655,12 +708,12 @@ static void LowerTlsAddr(MCStreamer &OutStreamer, LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp LEA.addOperand(MCOperand::CreateReg(0)); // seg } - OutStreamer.EmitInstruction(LEA); + EmitAndCountInstruction(LEA); if (needsPadding) { - OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX)); - OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX)); - OutStreamer.EmitInstruction(MCInstBuilder(X86::REX64_PREFIX)); + EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX)); + EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX)); + EmitAndCountInstruction(MCInstBuilder(X86::REX64_PREFIX)); } StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr"; @@ -670,116 +723,78 @@ static void LowerTlsAddr(MCStreamer &OutStreamer, MCSymbolRefExpr::VK_PLT, context); - OutStreamer.EmitInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32 - : X86::CALLpcrel32) - .addExpr(tlsRef)); + EmitAndCountInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32 + : X86::CALLpcrel32) + .addExpr(tlsRef)); } -static std::pair -parseMemoryOperand(StackMaps::Location::LocationType LocTy, unsigned Size, - MachineInstr::const_mop_iterator MOI, - MachineInstr::const_mop_iterator MOE) { - - typedef StackMaps::Location Location; - - assert(std::distance(MOI, MOE) >= 5 && "Too few operands to encode mem op."); - - const MachineOperand &Base = *MOI; - const MachineOperand &Scale = *(++MOI); - const MachineOperand &Index = *(++MOI); - const MachineOperand &Disp = *(++MOI); - const MachineOperand &ZeroReg = *(++MOI); - - // Sanity check for supported operand format. - assert(Base.isReg() && - Scale.isImm() && Scale.getImm() == 1 && - Index.isReg() && Index.getReg() == 0 && - Disp.isImm() && ZeroReg.isReg() && (ZeroReg.getReg() == 0) && - "Unsupported x86 memory operand sequence."); - (void)Scale; - (void)Index; - (void)ZeroReg; - - return std::make_pair( - Location(LocTy, Size, Base.getReg(), Disp.getImm()), ++MOI); -} - -std::pair -X86AsmPrinter::stackmapOperandParser(MachineInstr::const_mop_iterator MOI, - MachineInstr::const_mop_iterator MOE, - const TargetMachine &TM) { - - typedef StackMaps::Location Location; - - const MachineOperand &MOP = *MOI; - assert(!MOP.isRegMask() && (!MOP.isReg() || !MOP.isImplicit()) && - "Register mask and implicit operands should not be processed."); - - if (MOP.isImm()) { - // Verify anyregcc - // [], , , , , , ... - - switch (MOP.getImm()) { - default: llvm_unreachable("Unrecognized operand type."); - case StackMaps::DirectMemRefOp: { - unsigned Size = TM.getDataLayout()->getPointerSizeInBits(); - assert((Size % 8) == 0 && "Need pointer size in bytes."); - Size /= 8; - return parseMemoryOperand(StackMaps::Location::Direct, Size, - llvm::next(MOI), MOE); - } - case StackMaps::IndirectMemRefOp: { - ++MOI; - int64_t Size = MOI->getImm(); - assert(Size > 0 && "Need a valid size for indirect memory locations."); - return parseMemoryOperand(StackMaps::Location::Indirect, Size, - llvm::next(MOI), MOE); - } - case StackMaps::ConstantOp: { - ++MOI; - assert(MOI->isImm() && "Expected constant operand."); - int64_t Imm = MOI->getImm(); - return std::make_pair( - Location(Location::Constant, sizeof(int64_t), 0, Imm), ++MOI); +/// \brief Emit the optimal amount of multi-byte nops on X86. +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"); + while (NumBytes) { + unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg; + Opc = IndexReg = Displacement = SegmentReg = 0; + BaseReg = X86::RAX; ScaleVal = 1; + switch (NumBytes) { + case 0: llvm_unreachable("Zero nops?"); break; + case 1: NumBytes -= 1; Opc = X86::NOOP; break; + case 2: NumBytes -= 2; Opc = X86::XCHG16ar; break; + case 3: NumBytes -= 3; Opc = X86::NOOPL; break; + case 4: NumBytes -= 4; Opc = X86::NOOPL; Displacement = 8; break; + case 5: NumBytes -= 5; Opc = X86::NOOPL; Displacement = 8; + IndexReg = X86::RAX; break; + case 6: NumBytes -= 6; Opc = X86::NOOPW; Displacement = 8; + IndexReg = X86::RAX; break; + case 7: NumBytes -= 7; Opc = X86::NOOPL; Displacement = 512; break; + case 8: NumBytes -= 8; Opc = X86::NOOPL; Displacement = 512; + IndexReg = X86::RAX; break; + case 9: NumBytes -= 9; Opc = X86::NOOPW; Displacement = 512; + IndexReg = X86::RAX; break; + default: NumBytes -= 10; Opc = X86::NOOPW; Displacement = 512; + IndexReg = X86::RAX; SegmentReg = X86::CS; break; } - } - } - // Otherwise this is a reg operand. The physical register number will - // ultimately be encoded as a DWARF regno. The stack map also records the size - // of a spill slot that can hold the register content. (The runtime can - // track the actual size of the data type if it needs to.) - assert(MOP.isReg() && "Expected register operand here."); - assert(TargetRegisterInfo::isPhysicalRegister(MOP.getReg()) && - "Virtreg operands should have been rewritten before now."); - const TargetRegisterClass *RC = - TM.getRegisterInfo()->getMinimalPhysRegClass(MOP.getReg()); - assert(!MOP.getSubReg() && "Physical subreg still around."); - return std::make_pair( - Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI); + unsigned NumPrefixes = std::min(NumBytes, 5U); + NumBytes -= NumPrefixes; + for (unsigned i = 0; i != NumPrefixes; ++i) + OS.EmitBytes("\x66"); + + switch (Opc) { + default: llvm_unreachable("Unexpected opcode"); break; + case X86::NOOP: + OS.EmitInstruction(MCInstBuilder(Opc), STI); + break; + case X86::XCHG16ar: + 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), STI); + break; + } + } // while (NumBytes) } // Lower a stackmap of the form: // , , ... -static void LowerSTACKMAP(MCStreamer &OutStreamer, - StackMaps &SM, - const MachineInstr &MI) -{ - unsigned NumNOPBytes = MI.getOperand(1).getImm(); +void X86AsmPrinter::LowerSTACKMAP(const MachineInstr &MI) { + SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo()); 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. - for (unsigned i = 0; i < NumNOPBytes; ++i) - OutStreamer.EmitInstruction(MCInstBuilder(X86::NOOP)); + unsigned NumShadowBytes = MI.getOperand(1).getImm(); + SMShadowTracker.reset(NumShadowBytes); } // Lower a patchpoint of the form: // [], , , , , , ... -static void LowerPATCHPOINT(MCStreamer &OutStreamer, - StackMaps &SM, - const MachineInstr &MI) { +void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI) { + assert(Subtarget->is64Bit() && "Patchpoint currently only supports X86-64"); + + SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo()); + SM.recordPatchPoint(MI); PatchPointOpers opers(&MI); @@ -789,34 +804,36 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer, if (CallTarget) { // 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. - // We conservatively assume that it is 12 bytes and emit in worst case one - // extra NOP byte. - EncodedBytes = 12; - OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64ri) - .addReg(MI.getOperand(ScratchIdx).getReg()) - .addImm(CallTarget)); - OutStreamer.EmitInstruction(MCInstBuilder(X86::CALL64r) - .addReg(MI.getOperand(ScratchIdx).getReg())); + unsigned ScratchReg = MI.getOperand(ScratchIdx).getReg(); + if (X86II::isX86_64ExtendedReg(ScratchReg)) + EncodedBytes = 13; + else + EncodedBytes = 12; + EmitAndCountInstruction(MCInstBuilder(X86::MOV64ri).addReg(ScratchReg) + .addImm(CallTarget)); + 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."); - for (unsigned i = EncodedBytes; i < NumBytes; ++i) - OutStreamer.EmitInstruction(MCInstBuilder(X86::NOOP)); + EmitNops(OutStreamer, NumBytes - EncodedBytes, Subtarget->is64Bit(), + getSubtargetInfo()); } void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { X86MCInstLower MCInstLowering(*MF, *this); + const X86RegisterInfo *RI = + static_cast(TM.getRegisterInfo()); + switch (MI->getOpcode()) { case TargetOpcode::DBG_VALUE: llvm_unreachable("Should be handled target independently"); // 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; @@ -839,7 +856,7 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { case X86::TLS_addr64: case X86::TLS_base_addr32: case X86::TLS_base_addr64: - return LowerTlsAddr(OutStreamer, MCInstLowering, *MI); + return LowerTlsAddr(MCInstLowering, *MI); case X86::MOVPC32r: { // This is a pseudo op for a two instruction sequence with a label, which @@ -852,15 +869,15 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { 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) + EmitAndCountInstruction(MCInstBuilder(X86::CALLpcrel32) .addExpr(MCSymbolRefExpr::Create(PICBase, OutContext))); // Emit the label. OutStreamer.EmitLabel(PICBase); // popl $reg - OutStreamer.EmitInstruction(MCInstBuilder(X86::POP32r) - .addReg(MI->getOperand(0).getReg())); + EmitAndCountInstruction(MCInstBuilder(X86::POP32r) + .addReg(MI->getOperand(0).getReg())); return; } @@ -890,7 +907,7 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { DotExpr = MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(OpSym,OutContext), DotExpr, OutContext); - OutStreamer.EmitInstruction(MCInstBuilder(X86::ADD32ri) + EmitAndCountInstruction(MCInstBuilder(X86::ADD32ri) .addReg(MI->getOperand(0).getReg()) .addReg(MI->getOperand(1).getReg()) .addExpr(DotExpr)); @@ -898,25 +915,56 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { } case TargetOpcode::STACKMAP: - return LowerSTACKMAP(OutStreamer, SM, *MI); + return LowerSTACKMAP(*MI); case TargetOpcode::PATCHPOINT: - return LowerPATCHPOINT(OutStreamer, SM, *MI); + return LowerPATCHPOINT(*MI); case X86::MORESTACK_RET: - OutStreamer.EmitInstruction(MCInstBuilder(X86::RET)); + EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget))); return; case X86::MORESTACK_RET_RESTORE_R10: // Return, then restore R10. - OutStreamer.EmitInstruction(MCInstBuilder(X86::RET)); - OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64rr) - .addReg(X86::R10) - .addReg(X86::RAX)); + EmitAndCountInstruction(MCInstBuilder(getRetOpcode(*Subtarget))); + EmitAndCountInstruction(MCInstBuilder(X86::MOV64rr) + .addReg(X86::R10) + .addReg(X86::RAX)); + return; + + case X86::SEH_PushReg: + 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()); + return; + + case X86::SEH_SaveXMM: + OutStreamer.EmitWinCFISaveXMM(RI->getSEHRegNum(MI->getOperand(0).getImm()), + MI->getOperand(1).getImm()); + return; + + case X86::SEH_StackAlloc: + OutStreamer.EmitWinCFIAllocStack(MI->getOperand(0).getImm()); + return; + + case X86::SEH_SetFrame: + OutStreamer.EmitWinCFISetFrame(RI->getSEHRegNum(MI->getOperand(0).getImm()), + MI->getOperand(1).getImm()); + return; + + case X86::SEH_PushFrame: + OutStreamer.EmitWinCFIPushFrame(MI->getOperand(0).getImm()); + return; + + case X86::SEH_EndPrologue: + OutStreamer.EmitWinCFIEndProlog(); return; } MCInst TmpInst; MCInstLowering.Lower(MI, TmpInst); - OutStreamer.EmitInstruction(TmpInst); + EmitAndCountInstruction(TmpInst); }