summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2016-04-08 16:15:29 -0700
committerBruce Forstall <brucefo@microsoft.com>2016-04-08 16:15:29 -0700
commit2bded17025299f91787e150baa1791967ab4f597 (patch)
tree8f1a26726d54f9c2b5cf2e63fde38f03e79fa9c8 /src/jit
parent4ee08c7f344a49e27dfece22cf0ff5159158e22b (diff)
downloadcoreclr-2bded17025299f91787e150baa1791967ab4f597.tar.gz
coreclr-2bded17025299f91787e150baa1791967ab4f597.tar.bz2
coreclr-2bded17025299f91787e150baa1791967ab4f597.zip
Add genEstablishFramePointer() to enapsulate frame pointer creation
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/codegen.h2
-rw-r--r--src/jit/codegencommon.cpp81
2 files changed, 54 insertions, 29 deletions
diff --git a/src/jit/codegen.h b/src/jit/codegen.h
index f1ad82db38..5d23bd97ba 100644
--- a/src/jit/codegen.h
+++ b/src/jit/codegen.h
@@ -296,7 +296,7 @@ protected:
// Prolog functions and data (there are a few exceptions for more generally used things)
//
-
+ void genEstablishFramePointer(int delta, bool reportUnwindData);
void genFnPrologCalleeRegArgs(regNumber xtraReg,
bool * pXtraRegClobbered,
RegState *regState);
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index b96f5c0956..3c86d43717 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -236,6 +236,7 @@ int CodeGenInterface::genSPtoFPdelta()
delta = -genCallerSPtoInitialSPdelta() + genCallerSPtoFPdelta();
+ assert(delta >= 0);
return delta;
}
@@ -8355,6 +8356,51 @@ void CodeGen::genFinalizeFrame()
#endif
}
+//------------------------------------------------------------------------
+// genEstablishFramePointer: Set up the frame pointer by adding an offset to the stack pointer.
+//
+// Arguments:
+// delta - the offset to add to the current stack pointer to establish the frame pointer
+// reportUnwindData - true if establishing the frame pointer should be reported in the OS unwind data.
+
+void CodeGen::genEstablishFramePointer(int delta, bool reportUnwindData)
+{
+ assert(compiler->compGeneratingProlog);
+
+#if defined(_TARGET_XARCH_)
+
+ if (delta == 0)
+ {
+ getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_FPBASE, REG_SPBASE);
+ psiMoveESPtoEBP();
+ }
+ else
+ {
+ getEmitter()->emitIns_R_AR(INS_lea, EA_PTRSIZE, REG_FPBASE, REG_SPBASE, delta);
+ // We don't update prolog scope info (there is no function to handle lea), but that is currently dead code anyway.
+ }
+
+ if (reportUnwindData)
+ {
+ compiler->unwindSetFrameReg(REG_FPBASE, delta);
+ }
+
+#elif defined(_TARGET_ARM_)
+
+ assert(arm_Valid_Imm_For_Add_SP(delta));
+ getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, REG_FPBASE, REG_SPBASE, delta);
+
+ if (reportUnwindData)
+ {
+ compiler->unwindPadding();
+ }
+
+#else
+ NYI("establish frame pointer");
+#endif
+}
+
+
/*****************************************************************************
*
@@ -8658,7 +8704,7 @@ void CodeGen::genFnProlog()
#ifdef _TARGET_ARM_
// If we have a variable sized frame (compLocallocUsed is true)
- // then using REG_SAVED_LOCALALLOC_SP in the prolog is not allowed
+ // then using REG_SAVED_LOCALLOC_SP in the prolog is not allowed
if (compiler->compLocallocUsed)
{
excludeMask |= RBM_SAVED_LOCALLOC_SP;
@@ -8738,9 +8784,8 @@ void CodeGen::genFnProlog()
psiAdjustStackLevel(REGSIZE_BYTES);
#ifndef _TARGET_AMD64_ // On AMD64, establish the frame pointer after the "sub rsp"
- inst_RV_RV(INS_mov, REG_FPBASE, REG_SPBASE);
- compiler->unwindSetFrameReg(REG_FPBASE, 0);
- psiMoveESPtoEBP();
+ genEstablishFramePointer(0, /*reportUnwindData*/ true);
+#endif // !_TARGET_AMD64_
#if DOUBLE_ALIGN
if (compiler->genDoubleAlign())
@@ -8751,7 +8796,6 @@ void CodeGen::genFnProlog()
inst_RV_IV(INS_AND, REG_SPBASE, -8, EA_PTRSIZE);
}
#endif // DOUBLE_ALIGN
-#endif // !_TARGET_AMD64_
}
#endif // _TARGET_XARCH_
@@ -8779,8 +8823,7 @@ void CodeGen::genFnProlog()
if (!arm_Valid_Imm_For_Add_SP(afterLclFrameSPtoFPdelta))
{
// Oh well, it looks too big. Go ahead and establish the frame pointer here.
- getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, REG_FPBASE, REG_SPBASE, SPtoFPdelta);
- compiler->unwindPadding();
+ genEstablishFramePointer(SPtoFPdelta, /*reportUnwindData*/ true);
needToEstablishFP = false;
}
}
@@ -8825,25 +8868,8 @@ void CodeGen::genFnProlog()
// Establish the AMD64 frame pointer after the OS-reported prolog.
if (doubleAlignOrFramePointerUsed())
{
- int delta = compiler->codeGen->genSPtoFPdelta();
-
- if (delta == 0)
- {
- getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_FPBASE, REG_SPBASE);
- }
- else
- {
- getEmitter()->emitIns_R_AR(INS_lea, EA_PTRSIZE, REG_FPBASE, REG_SPBASE, delta);
- }
-
- if (compiler->compLocallocUsed || compiler->opts.compDbgEnC)
- {
- compiler->unwindSetFrameReg(REG_FPBASE, delta);
- }
-
-#ifdef DEBUGGING_SUPPORT
- // TODO-AMD64-Bug?: do we need to do something with debugging?
-#endif // DEBUGGING_SUPPORT
+ bool reportUnwindData = compiler->compLocallocUsed || compiler->opts.compDbgEnC;
+ genEstablishFramePointer(compiler->codeGen->genSPtoFPdelta(), reportUnwindData);
}
#endif //_TARGET_AMD64_
@@ -8856,8 +8882,7 @@ void CodeGen::genFnProlog()
#ifdef _TARGET_ARM_
if (needToEstablishFP)
{
- assert(arm_Valid_Imm_For_Add_SP(afterLclFrameSPtoFPdelta));
- getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, REG_FPBASE, REG_SPBASE, afterLclFrameSPtoFPdelta);
+ genEstablishFramePointer(afterLclFrameSPtoFPdelta, /*reportUnwindData*/ false);
needToEstablishFP = false; // nobody uses this later, but set it anyway, just to be explicit
}
#endif // _TARGET_ARM_