summaryrefslogtreecommitdiff
path: root/ujit_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'ujit_core.c')
-rw-r--r--ujit_core.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/ujit_core.c b/ujit_core.c
new file mode 100644
index 0000000000..5ac6407219
--- /dev/null
+++ b/ujit_core.c
@@ -0,0 +1,68 @@
+#include "ujit_asm.h"
+#include "ujit_iface.h"
+#include "ujit_core.h"
+
+// Get the current instruction opcode from the context object
+int
+ctx_get_opcode(ctx_t *ctx)
+{
+ return opcode_at_pc(ctx->iseq, ctx->pc);
+}
+
+// Get an instruction argument from the context object
+VALUE
+ctx_get_arg(ctx_t* ctx, size_t arg_idx)
+{
+ assert (arg_idx + 1 < insn_len(ctx_get_opcode(ctx)));
+ return *(ctx->pc + arg_idx + 1);
+}
+
+/*
+Get an operand for the adjusted stack pointer address
+*/
+x86opnd_t
+ctx_sp_opnd(ctx_t* ctx, int32_t offset_bytes)
+{
+ int32_t offset = (ctx->stack_diff) * 8 + offset_bytes;
+ return mem_opnd(64, REG_SP, offset);
+}
+
+/*
+Make space on the stack for N values
+Return a pointer to the new stack top
+*/
+x86opnd_t
+ctx_stack_push(ctx_t* ctx, size_t n)
+{
+ ctx->stack_diff += n;
+
+ // SP points just above the topmost value
+ int32_t offset = (ctx->stack_diff - 1) * 8;
+ return mem_opnd(64, REG_SP, offset);
+}
+
+/*
+Pop N values off the stack
+Return a pointer to the stack top before the pop operation
+*/
+x86opnd_t
+ctx_stack_pop(ctx_t* ctx, size_t n)
+{
+ // SP points just above the topmost value
+ int32_t offset = (ctx->stack_diff - 1) * 8;
+ x86opnd_t top = mem_opnd(64, REG_SP, offset);
+
+ ctx->stack_diff -= n;
+
+ return top;
+}
+
+x86opnd_t
+ctx_stack_opnd(ctx_t* ctx, int32_t idx)
+{
+ // SP points just above the topmost value
+ int32_t offset = (ctx->stack_diff - 1 - idx) * 8;
+ x86opnd_t opnd = mem_opnd(64, REG_SP, offset);
+
+ return opnd;
+}