summaryrefslogtreecommitdiff
path: root/lib/Target/X86
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp5
-rw-r--r--lib/Target/X86/X86ISelLowering.h2
-rw-r--r--lib/Target/X86/X86MCInstLower.cpp25
3 files changed, 29 insertions, 3 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 55bfab449a..a8743afce9 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -1773,6 +1773,11 @@ X86TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
return CCInfo.CheckReturn(Outs, RetCC_X86);
}
+const uint16_t *X86TargetLowering::getScratchRegisters(CallingConv::ID) const {
+ static const uint16_t ScratchRegs[] = { X86::R11, 0 };
+ return ScratchRegs;
+}
+
SDValue
X86TargetLowering::LowerReturn(SDValue Chain,
CallingConv::ID CallConv, bool isVarArg,
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 08dc115de0..07a36f98c2 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -925,6 +925,8 @@ namespace llvm {
const SmallVectorImpl<ISD::OutputArg> &Outs,
LLVMContext &Context) const;
+ virtual const uint16_t *getScratchRegisters(CallingConv::ID CC) const;
+
/// Utility function to emit atomic-load-arith operations (and, or, xor,
/// nand, max, min, umax, umin). It takes the corresponding instruction to
/// expand, the associated machine basic block, and the associated X86
diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp
index fa15114f91..2cc038c889 100644
--- a/lib/Target/X86/X86MCInstLower.cpp
+++ b/lib/Target/X86/X86MCInstLower.cpp
@@ -785,6 +785,7 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer,
!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() &&
@@ -793,8 +794,20 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer,
assert(StartIdx == StartIdx2 &&
"Unexpected additonal definition in Patchpoint intrinsic.");
+ }
#endif
+ // Find the first scratch register (implicit def and early clobber)
+ unsigned ScratchIdx = StartIdx, e = MI.getNumOperands();
+ while (ScratchIdx < e &&
+ !(MI.getOperand(ScratchIdx).isReg() &&
+ MI.getOperand(ScratchIdx).isDef() &&
+ MI.getOperand(ScratchIdx).isImplicit() &&
+ MI.getOperand(ScratchIdx).isEarlyClobber()))
+ ++ScratchIdx;
+
+ assert(ScratchIdx != e && "No scratch register available");
+
int64_t ID = MI.getOperand(StartIdx).getImm();
assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
@@ -812,10 +825,16 @@ static void LowerPATCHPOINT(MCStreamer &OutStreamer,
getStackMapEndMOP(MI.operands_begin(), MI.operands_end()),
isAnyRegCC && hasDef);
- // Emit call. We need to know how many bytes we encoded here.
- unsigned EncodedBytes = 2;
+ // 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.
+ unsigned EncodedBytes = 12;
+ OutStreamer.EmitInstruction(MCInstBuilder(X86::MOV64ri)
+ .addReg(MI.getOperand(ScratchIdx).getReg())
+ .addImm(MI.getOperand(StartIdx + 2).getImm()));
OutStreamer.EmitInstruction(MCInstBuilder(X86::CALL64r)
- .addReg(MI.getOperand(StartIdx + 2).getReg()));
+ .addReg(MI.getOperand(ScratchIdx).getReg()));
// Emit padding.
unsigned NumNOPBytes = MI.getOperand(StartIdx + 1).getImm();