diff options
| author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2020-12-16 17:07:18 -0500 |
|---|---|---|
| committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:26 -0400 |
| commit | 40b70ef7c762701d26539e5a401449d7f3733b5a (patch) | |
| tree | 5cf1382c51d35303dce81ac76b4f72bea60bcd49 /ujit_codegen.c | |
| parent | bd7cc9ed98056d01dbdd592156e07ae6c6eff516 (diff) | |
WIP branch generation code
Diffstat (limited to 'ujit_codegen.c')
| -rw-r--r-- | ujit_codegen.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/ujit_codegen.c b/ujit_codegen.c index 01785d5fc4..1201c99c66 100644 --- a/ujit_codegen.c +++ b/ujit_codegen.c @@ -15,9 +15,6 @@ #include "ujit_asm.h" #include "ujit_utils.h" -// Code generation function signature -typedef bool (*codegen_fn)(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx); - // Map from YARV opcodes to code generation functions static st_table *gen_fns; @@ -889,6 +886,38 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) return true; } +void +gen_branchunless_branch(codeblock_t* cb, uint8_t* target0, uint8_t* target1, uint8_t shape) +{ + jz_ptr(cb, target0); + jmp_ptr(cb, target1); +} + +static bool +gen_branchunless(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) +{ + // Get the branch target instruction offsets + int32_t jump_idx = (int32_t)ctx_get_arg(ctx, 0); + int32_t next_idx = ctx->insn_idx + 1; + blockid_t jump_block = { ctx->iseq, jump_idx }; + blockid_t next_block = { ctx->iseq, next_idx }; + + // TODO: we need to eventually do an interrupt check when jumping/branching + // How can we do this while keeping the check logic out of line? + // RUBY_VM_CHECK_INTS(ec); + + // Test if any bit (outside of the Qnil bit) is on + // RUBY_Qfalse /* ...0000 0000 */ + // RUBY_Qnil /* ...0000 1000 */ + x86opnd_t val_opnd = ctx_stack_pop(ctx, 1); + test(cb, val_opnd, imm_opnd(~Qnil)); + + // Generate the branch instructions + gen_branch(cb, ocb, jump_block, next_block, gen_branchunless_branch); + + return true; +} + void ujit_init_codegen(void) { |
