diff options
author | John Hawthorn <john@hawthorn.email> | 2021-06-08 07:52:57 -0700 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:35 -0400 |
commit | 67c2cdc59a5fc8a82804c72a30a2d23ba36f2366 (patch) | |
tree | 902dab23e1a473a4d931419e9c151a676d01891e /yjit_codegen.c | |
parent | 5432f46f6a7a35a8d2a924eae7b1e29289a58292 (diff) | |
download | ruby-67c2cdc59a5fc8a82804c72a30a2d23ba36f2366.tar.gz |
Implement gen_getlocal
This extracts the generation code from getlocal_wc1, since this is the
same just with more loops inside vm_get_ep.
Diffstat (limited to 'yjit_codegen.c')
-rw-r--r-- | yjit_codegen.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/yjit_codegen.c b/yjit_codegen.c index 87c5b12043..4870911404 100644 --- a/yjit_codegen.c +++ b/yjit_codegen.c @@ -787,22 +787,21 @@ gen_getlocal_wc0(jitstate_t* jit, ctx_t* ctx) } static codegen_status_t -gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx) +gen_getlocal_generic(ctx_t* ctx, uint32_t local_idx, uint32_t level) { - //fprintf(stderr, "gen_getlocal_wc1\n"); - // Load environment pointer EP from CFP mov(cb, REG0, member_opnd(REG_CFP, rb_control_frame_t, ep)); - // Get the previous EP from the current EP - // See GET_PREV_EP(ep) macro - // VALUE* prev_ep = ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03)) - mov(cb, REG0, mem_opnd(64, REG0, SIZEOF_VALUE * VM_ENV_DATA_INDEX_SPECVAL)); - and(cb, REG0, imm_opnd(~0x03)); + while (level--) { + // Get the previous EP from the current EP + // See GET_PREV_EP(ep) macro + // VALUE* prev_ep = ((VALUE *)((ep)[VM_ENV_DATA_INDEX_SPECVAL] & ~0x03)) + mov(cb, REG0, mem_opnd(64, REG0, SIZEOF_VALUE * VM_ENV_DATA_INDEX_SPECVAL)); + and(cb, REG0, imm_opnd(~0x03)); + } // Load the local from the block // val = *(vm_get_ep(GET_EP(), level) - idx); - int32_t local_idx = (int32_t)jit_get_arg(jit, 0); const int32_t offs = -(SIZEOF_VALUE * local_idx); mov(cb, REG0, mem_opnd(64, REG0, offs)); @@ -814,6 +813,21 @@ gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx) } static codegen_status_t +gen_getlocal(jitstate_t* jit, ctx_t* ctx) +{ + int32_t idx = (int32_t)jit_get_arg(jit, 0); + int32_t level = (int32_t)jit_get_arg(jit, 1); + return gen_getlocal_generic(ctx, idx, level); +} + +static codegen_status_t +gen_getlocal_wc1(jitstate_t* jit, ctx_t* ctx) +{ + int32_t idx = (int32_t)jit_get_arg(jit, 0); + return gen_getlocal_generic(ctx, idx, 1); +} + +static codegen_status_t gen_setlocal_wc0(jitstate_t* jit, ctx_t* ctx) { /* @@ -3067,6 +3081,7 @@ yjit_init_codegen(void) yjit_reg_op(BIN(putobject_INT2FIX_0_), gen_putobject_int2fix); yjit_reg_op(BIN(putobject_INT2FIX_1_), gen_putobject_int2fix); yjit_reg_op(BIN(putself), gen_putself); + yjit_reg_op(BIN(getlocal), gen_getlocal); yjit_reg_op(BIN(getlocal_WC_0), gen_getlocal_wc0); yjit_reg_op(BIN(getlocal_WC_1), gen_getlocal_wc1); yjit_reg_op(BIN(setlocal_WC_0), gen_setlocal_wc0); |