summaryrefslogtreecommitdiff
path: root/src/jit/codegenarm64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/codegenarm64.cpp')
-rw-r--r--src/jit/codegenarm64.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index 9f892e6ea8..15e0b7b095 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -5887,6 +5887,96 @@ void CodeGen::genHWIntrinsicShaRotateOp(GenTreeHWIntrinsic* node)
#endif // FEATURE_HW_INTRINSICS
+#ifdef PROFILING_SUPPORTED
+
+//-----------------------------------------------------------------------------------
+// genProfilingEnterCallback: Generate the profiling function enter callback.
+//
+// Arguments:
+// initReg - register to use as scratch register
+// pInitRegZeroed - OUT parameter. *pInitRegZeroed set to 'false' if 'initReg' is
+// not zero after this call.
+//
+// Return Value:
+// None
+//
+void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
+{
+ assert(compiler->compGeneratingProlog);
+
+ if (!compiler->compIsProfilerHookNeeded())
+ {
+ return;
+ }
+
+ if (compiler->compProfilerMethHndIndirected)
+ {
+ instGen_Set_Reg_To_Imm(EA_PTR_DSP_RELOC, REG_PROFILER_ENTER_ARG_FUNC_ID,
+ (ssize_t)compiler->compProfilerMethHnd);
+ getEmitter()->emitIns_R_R(INS_ldr, EA_PTRSIZE, REG_PROFILER_ENTER_ARG_FUNC_ID, REG_PROFILER_ENTER_ARG_FUNC_ID);
+ }
+ else
+ {
+ genSetRegToIcon(REG_PROFILER_ENTER_ARG_FUNC_ID, (ssize_t)compiler->compProfilerMethHnd, TYP_I_IMPL);
+ }
+
+ int callerSPOffset = compiler->lvaToCallerSPRelativeOffset(0, isFramePointerUsed());
+ genInstrWithConstant(INS_add, EA_PTRSIZE, REG_PROFILER_ENTER_ARG_CALLER_SP, genFramePointerReg(),
+ (ssize_t)(-callerSPOffset), REG_PROFILER_ENTER_ARG_CALLER_SP);
+
+ genEmitHelperCall(CORINFO_HELP_PROF_FCN_ENTER, 0, EA_UNKNOWN);
+
+ if ((genRegMask(initReg) & RBM_PROFILER_ENTER_TRASH) != RBM_NONE)
+ {
+ *pInitRegZeroed = false;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+// genProfilingLeaveCallback: Generate the profiling function leave or tailcall callback.
+// Technically, this is not part of the epilog; it is called when we are generating code for a GT_RETURN node.
+//
+// Arguments:
+// helper - which helper to call. Either CORINFO_HELP_PROF_FCN_LEAVE or CORINFO_HELP_PROF_FCN_TAILCALL
+//
+// Return Value:
+// None
+//
+void CodeGen::genProfilingLeaveCallback(unsigned helper)
+{
+ assert((helper == CORINFO_HELP_PROF_FCN_LEAVE) || (helper == CORINFO_HELP_PROF_FCN_TAILCALL));
+
+ if (!compiler->compIsProfilerHookNeeded())
+ {
+ return;
+ }
+
+ compiler->info.compProfilerCallback = true;
+
+ if (compiler->compProfilerMethHndIndirected)
+ {
+ instGen_Set_Reg_To_Imm(EA_PTR_DSP_RELOC, REG_PROFILER_LEAVE_ARG_FUNC_ID,
+ (ssize_t)compiler->compProfilerMethHnd);
+ getEmitter()->emitIns_R_R(INS_ldr, EA_PTRSIZE, REG_PROFILER_LEAVE_ARG_FUNC_ID, REG_PROFILER_LEAVE_ARG_FUNC_ID);
+ }
+ else
+ {
+ genSetRegToIcon(REG_PROFILER_LEAVE_ARG_FUNC_ID, (ssize_t)compiler->compProfilerMethHnd, TYP_I_IMPL);
+ }
+
+ gcInfo.gcMarkRegSetNpt(RBM_PROFILER_LEAVE_ARG_FUNC_ID);
+
+ int callerSPOffset = compiler->lvaToCallerSPRelativeOffset(0, isFramePointerUsed());
+ genInstrWithConstant(INS_add, EA_PTRSIZE, REG_PROFILER_LEAVE_ARG_CALLER_SP, genFramePointerReg(),
+ (ssize_t)(-callerSPOffset), REG_PROFILER_LEAVE_ARG_CALLER_SP);
+
+ gcInfo.gcMarkRegSetNpt(RBM_PROFILER_LEAVE_ARG_CALLER_SP);
+
+ genEmitHelperCall(helper, 0, EA_UNKNOWN);
+}
+
+#endif // PROFILING_SUPPORTED
+
/*****************************************************************************
* Unit testing of the ARM64 emitter: generate a bunch of instructions into the prolog
* (it's as good a place as any), then use COMPlus_JitLateDisasm=* to see if the late