JIT support has been added awhile ago.
[oota-llvm.git] / lib / Target / X86 / X86MCInstLower.cpp
index 96ab70a29a371f59f02955215debb9aaaefd5b21..892396bc4edab57ef181414c3cdcac20bbfd065b 100644 (file)
 #include "X86RegisterInfo.h"
 #include "InstPrinter/X86ATTInstPrinter.h"
 #include "MCTargetDesc/X86BaseInfo.h"
+#include "Utils/X86ShuffleDecode.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
 #include "llvm/CodeGen/StackMaps.h"
 #include "llvm/IR/DataLayout.h"
@@ -72,10 +75,10 @@ namespace llvm {
 
   void
   X86AsmPrinter::StackMapShadowTracker::startFunction(MachineFunction &MF) {
-    CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(*TM.getInstrInfo(),
-                                                         *TM.getRegisterInfo(),
-                                                         *TM.getSubtargetImpl(),
-                                                         MF.getContext()));
+    CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(
+        *TM.getSubtargetImpl()->getInstrInfo(),
+        *TM.getSubtargetImpl()->getRegisterInfo(), *TM.getSubtargetImpl(),
+        MF.getContext()));
   }
 
   void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst,
@@ -121,7 +124,7 @@ MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
 /// operand to an MCSymbol.
 MCSymbol *X86MCInstLower::
 GetSymbolFromOperand(const MachineOperand &MO) const {
-  const DataLayout *DL = TM.getDataLayout();
+  const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout();
   assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) && "Isn't a symbol reference");
 
   SmallString<128> Name;
@@ -823,10 +826,24 @@ void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI) {
            getSubtargetInfo());
 }
 
+// Returns instruction preceding MBBI in MachineFunction.
+// If MBBI is the first instruction of the first basic block, returns null.
+static MachineBasicBlock::const_iterator
+PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI) {
+  const MachineBasicBlock *MBB = MBBI->getParent();
+  while (MBBI == MBB->begin()) {
+    if (MBB == MBB->getParent()->begin())
+      return nullptr;
+    MBB = MBB->getPrevNode();
+    MBBI = MBB->end();
+  }
+  return --MBBI;
+}
+
 void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
   X86MCInstLower MCInstLowering(*MF, *this);
-  const X86RegisterInfo *RI =
-      static_cast<const X86RegisterInfo *>(TM.getRegisterInfo());
+  const X86RegisterInfo *RI = static_cast<const X86RegisterInfo *>(
+      TM.getSubtargetImpl()->getRegisterInfo());
 
   switch (MI->getOpcode()) {
   case TargetOpcode::DBG_VALUE:
@@ -963,6 +980,100 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
   case X86::SEH_EndPrologue:
     OutStreamer.EmitWinCFIEndProlog();
     return;
+
+  case X86::SEH_Epilogue: {
+    MachineBasicBlock::const_iterator MBBI(MI);
+    // Check if preceded by a call and emit nop if so.
+    for (MBBI = PrevCrossBBInst(MBBI); MBBI; MBBI = PrevCrossBBInst(MBBI)) {
+      // Conservatively assume that pseudo instructions don't emit code and keep
+      // looking for a call. We may emit an unnecessary nop in some cases.
+      if (!MBBI->isPseudo()) {
+        if (MBBI->isCall())
+          EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
+        break;
+      }
+    }
+    return;
+  }
+
+  case X86::PSHUFBrm:
+  case X86::VPSHUFBrm:
+    // Lower PSHUFB normally but add a comment if we can find a constant
+    // shuffle mask. We won't be able to do this at the MC layer because the
+    // mask isn't an immediate.
+    std::string Comment;
+    raw_string_ostream CS(Comment);
+    SmallVector<int, 16> Mask;
+
+    assert(MI->getNumOperands() >= 6 &&
+           "Wrong number of operands for PSHUFBrm or VPSHUFBrm");
+    const MachineOperand &DstOp = MI->getOperand(0);
+    const MachineOperand &SrcOp = MI->getOperand(1);
+    const MachineOperand &MaskOp = MI->getOperand(5);
+
+    // Compute the name for a register. This is really goofy because we have
+    // multiple instruction printers that could (in theory) use different
+    // names. Fortunately most people use the ATT style (outside of Windows)
+    // and they actually agree on register naming here. Ultimately, this is
+    // a comment, and so its OK if it isn't perfect.
+    auto GetRegisterName = [](unsigned RegNum) -> StringRef {
+      return X86ATTInstPrinter::getRegisterName(RegNum);
+    };
+
+    StringRef DstName = DstOp.isReg() ? GetRegisterName(DstOp.getReg()) : "mem";
+    StringRef SrcName = SrcOp.isReg() ? GetRegisterName(SrcOp.getReg()) : "mem";
+    CS << DstName << " = ";
+
+    if (MaskOp.isCPI()) {
+      ArrayRef<MachineConstantPoolEntry> Constants =
+          MI->getParent()->getParent()->getConstantPool()->getConstants();
+      const MachineConstantPoolEntry &MaskConstantEntry =
+          Constants[MaskOp.getIndex()];
+      Type *MaskTy = MaskConstantEntry.getType();
+      (void)MaskTy;
+      if (!MaskConstantEntry.isMachineConstantPoolEntry())
+        if (auto *C = dyn_cast<ConstantDataSequential>(
+                MaskConstantEntry.Val.ConstVal)) {
+          assert(MaskTy == C->getType() &&
+                 "Expected a constant of the same type!");
+
+          DecodePSHUFBMask(C, Mask);
+          assert(Mask.size() == MaskTy->getVectorNumElements() &&
+                 "Shuffle mask has a different size than its type!");
+        }
+    }
+
+    if (!Mask.empty()) {
+      bool NeedComma = false;
+      bool InSrc = false;
+      for (int M : Mask) {
+        // Wrap up any prior entry...
+        if (M == SM_SentinelZero && InSrc) {
+          InSrc = false;
+          CS << "]";
+        }
+        if (NeedComma)
+          CS << ",";
+        else
+          NeedComma = true;
+
+        // Print this shuffle...
+        if (M == SM_SentinelZero) {
+          CS << "zero";
+        } else {
+          if (!InSrc) {
+            InSrc = true;
+            CS << SrcName << "[";
+          }
+          CS << M;
+        }
+      }
+      if (InSrc)
+        CS << "]";
+
+      OutStreamer.AddComment(CS.str());
+    }
+    break;
   }
 
   MCInst TmpInst;