[Stackmap] Add AnyReg calling convention support for patchpoint intrinsic.
[oota-llvm.git] / lib / Target / X86 / X86MCInstLower.cpp
index 92a111843f68bfed908887157fb01a99432df764..fa15114f9147c6504ed48b4dc9ba74892cd6c2f2 100644 (file)
@@ -780,26 +780,45 @@ static void LowerSTACKMAP(MCStreamer &OutStreamer,
 static void LowerPATCHPOINT(MCStreamer &OutStreamer,
                             X86MCInstLower &MCInstLowering,
                             StackMaps &SM,
-                            const MachineInstr &MI)
-{
-  int64_t ID = MI.getOperand(0).getImm();
+                            const MachineInstr &MI) {
+  bool hasDef = MI.getOperand(0).isReg() && MI.getOperand(0).isDef() &&
+                !MI.getOperand(0).isImplicit();
+  unsigned StartIdx = hasDef ? 1 : 0;
+#ifndef NDEBUG
+  unsigned StartIdx2 = 0, e = MI.getNumOperands();
+  while (StartIdx2 < e && MI.getOperand(StartIdx2).isReg() &&
+         MI.getOperand(StartIdx2).isDef() &&
+         !MI.getOperand(StartIdx2).isImplicit())
+    ++StartIdx2;
+
+  assert(StartIdx == StartIdx2 &&
+         "Unexpected additonal definition in Patchpoint intrinsic.");
+#endif
+
+  int64_t ID = MI.getOperand(StartIdx).getImm();
   assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
 
   // Get the number of arguments participating in the call. This number was
   // adjusted during call lowering by subtracting stack args.
-  int64_t StackMapIdx = MI.getOperand(3).getImm() + 4;
-  assert(StackMapIdx <= MI.getNumOperands() && "Patchpoint dropped args.");
+  bool isAnyRegCC = MI.getOperand(StartIdx + 4).getImm() == CallingConv::AnyReg;
+  assert(((hasDef && isAnyRegCC) || !hasDef) &&
+         "Only Patchpoints with AnyReg calling convention may have a result");
+  int64_t StackMapIdx = isAnyRegCC ? StartIdx + 5 :
+    StartIdx + 5 + MI.getOperand(StartIdx + 3).getImm();
+  assert(StackMapIdx <= MI.getNumOperands() &&
+         "Patchpoint intrinsic dropped arguments.");
 
   SM.recordStackMap(MI, ID, llvm::next(MI.operands_begin(), StackMapIdx),
-                     getStackMapEndMOP(MI.operands_begin(), MI.operands_end()));
+                    getStackMapEndMOP(MI.operands_begin(), MI.operands_end()),
+                    isAnyRegCC && hasDef);
 
   // Emit call. We need to know how many bytes we encoded here.
   unsigned EncodedBytes = 2;
   OutStreamer.EmitInstruction(MCInstBuilder(X86::CALL64r)
-                              .addReg(MI.getOperand(2).getReg()));
+                              .addReg(MI.getOperand(StartIdx + 2).getReg()));
 
   // Emit padding.
-  unsigned NumNOPBytes = MI.getOperand(1).getImm();
+  unsigned NumNOPBytes = MI.getOperand(StartIdx + 1).getImm();
   assert(NumNOPBytes >= EncodedBytes &&
          "Patchpoint can't request size less than the length of a call.");