summaryrefslogtreecommitdiff
path: root/src/jit/codegenarmarch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/codegenarmarch.cpp')
-rw-r--r--src/jit/codegenarmarch.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp
index c57ce472e0..048e0e3ad3 100644
--- a/src/jit/codegenarmarch.cpp
+++ b/src/jit/codegenarmarch.cpp
@@ -23,6 +23,91 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "emit.h"
//------------------------------------------------------------------------
+// genStackPointerConstantAdjustment: add a specified constant value to the stack pointer.
+// No probe is done.
+//
+// Arguments:
+// spDelta - the value to add to SP. Must be negative or zero.
+//
+// Return Value:
+// None.
+//
+void CodeGen::genStackPointerConstantAdjustment(ssize_t spDelta)
+{
+ assert(spDelta < 0);
+
+ // We assert that the SP change is less than one page. If it's greater, you should have called a
+ // function that does a probe, which will in turn call this function.
+ assert((target_size_t)(-spDelta) <= compiler->eeGetPageSize());
+
+ inst_RV_IV(INS_sub, REG_SPBASE, -spDelta, EA_PTRSIZE);
+}
+
+//------------------------------------------------------------------------
+// genStackPointerConstantAdjustmentWithProbe: add a specified constant value to the stack pointer,
+// and probe the stack as appropriate. Should only be called as a helper for
+// genStackPointerConstantAdjustmentLoopWithProbe.
+//
+// Arguments:
+// spDelta - the value to add to SP. Must be negative or zero. If zero, the probe happens,
+// but the stack pointer doesn't move.
+// regTmp - temporary register to use as target for probe load instruction
+//
+// Return Value:
+// None.
+//
+void CodeGen::genStackPointerConstantAdjustmentWithProbe(ssize_t spDelta, regNumber regTmp)
+{
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regTmp, REG_SP, 0);
+ genStackPointerConstantAdjustment(spDelta);
+}
+
+//------------------------------------------------------------------------
+// genStackPointerConstantAdjustmentLoopWithProbe: Add a specified constant value to the stack pointer,
+// and probe the stack as appropriate. Generates one probe per page, up to the total amount required.
+// This will generate a sequence of probes in-line.
+//
+// Arguments:
+// spDelta - the value to add to SP. Must be negative.
+// regTmp - temporary register to use as target for probe load instruction
+//
+// Return Value:
+// Offset in bytes from SP to last probed address.
+//
+target_ssize_t CodeGen::genStackPointerConstantAdjustmentLoopWithProbe(ssize_t spDelta, regNumber regTmp)
+{
+ assert(spDelta < 0);
+
+ const target_size_t pageSize = compiler->eeGetPageSize();
+
+ ssize_t spRemainingDelta = spDelta;
+ do
+ {
+ ssize_t spOneDelta = -(ssize_t)min((target_size_t)-spRemainingDelta, pageSize);
+ genStackPointerConstantAdjustmentWithProbe(spOneDelta, regTmp);
+ spRemainingDelta -= spOneDelta;
+ } while (spRemainingDelta < 0);
+
+ // What offset from the final SP was the last probe? This depends on the fact that
+ // genStackPointerConstantAdjustmentWithProbe() probes first, then does "SUB SP".
+ target_size_t lastTouchDelta = (target_size_t)(-spDelta) % pageSize;
+ if ((lastTouchDelta == 0) || (lastTouchDelta + STACK_PROBE_BOUNDARY_THRESHOLD_BYTES > pageSize))
+ {
+ // We haven't probed almost a complete page. If lastTouchDelta==0, then spDelta was an exact
+ // multiple of pageSize, which means we last probed exactly one page back. Otherwise, we probed
+ // the page, but very far from the end. If the next action on the stack might subtract from SP
+ // first, before touching the current SP, then we do one more probe at the very bottom. This can
+ // happen on x86, for example, when we copy an argument to the stack using a "SUB ESP; REP MOV"
+ // strategy.
+
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regTmp, REG_SP, 0);
+ lastTouchDelta = 0;
+ }
+
+ return lastTouchDelta;
+}
+
+//------------------------------------------------------------------------
// genCodeForTreeNode Generate code for a single node in the tree.
//
// Preconditions: