diff --git a/src/jit/backend/x64/x64_backend.cc b/src/jit/backend/x64/x64_backend.cc index d2f10d7c..34d884f5 100644 --- a/src/jit/backend/x64/x64_backend.cc +++ b/src/jit/backend/x64/x64_backend.cc @@ -1652,6 +1652,15 @@ EMITTER(CALL_EXTERNAL) { e.call(e.rax); } +EMITTER(CALL_FALLBACK) { + void *fallback = (void *)instr->arg[0]->i64; + uint32_t addr = instr->arg[1]->i32; + + e.mov(arg0, addr); + e.mov(e.rax, reinterpret_cast(fallback)); + e.call(e.rax); +} + struct jit_backend *x64_backend_create(const struct jit_guest *guest) { struct x64_backend *backend = reinterpret_cast( calloc(1, sizeof(struct x64_backend))); diff --git a/src/jit/ir/ir.c b/src/jit/ir/ir.c index a61b421d..0f061fff 100644 --- a/src/jit/ir/ir.c +++ b/src/jit/ir/ir.c @@ -737,3 +737,9 @@ void ir_call_external_2(struct ir *ir, struct ir_value *addr, ir_set_arg0(ir, instr, addr); ir_set_arg1(ir, instr, arg0); } + +void ir_call_fallback(struct ir *ir, void *fallback, uint32_t raw_instr) { + struct ir_instr *instr = ir_append_instr(ir, OP_CALL_FALLBACK, VALUE_V); + ir_set_arg0(ir, instr, ir_alloc_i64(ir, (uint64_t)fallback)); + ir_set_arg1(ir, instr, ir_alloc_i32(ir, raw_instr)); +} diff --git a/src/jit/ir/ir.h b/src/jit/ir/ir.h index 714b3fcc..751357d5 100644 --- a/src/jit/ir/ir.h +++ b/src/jit/ir/ir.h @@ -325,5 +325,6 @@ void ir_branch_cond(struct ir *ir, struct ir_value *cond, void ir_call_external_1(struct ir *ir, struct ir_value *addr); void ir_call_external_2(struct ir *ir, struct ir_value *addr, struct ir_value *arg0); +void ir_call_fallback(struct ir *ir, void *fallback, uint32_t raw_instr); #endif diff --git a/src/jit/ir/ir_ops.inc b/src/jit/ir/ir_ops.inc index e8228690..752c769b 100644 --- a/src/jit/ir/ir_ops.inc +++ b/src/jit/ir/ir_ops.inc @@ -48,3 +48,4 @@ IR_OP(LSHD) IR_OP(BRANCH) IR_OP(BRANCH_COND) IR_OP(CALL_EXTERNAL) +IR_OP(CALL_FALLBACK) diff --git a/src/jit/jit.c b/src/jit/jit.c index 00f093ef..dbea1851 100644 --- a/src/jit/jit.c +++ b/src/jit/jit.c @@ -287,9 +287,9 @@ struct jit *jit_create(struct jit_guest *guest, struct jit_frontend *frontend, // initialize all entries in block jit to reference the default block jit->default_code = default_code; - jit->code = malloc(jit->guest.max_blocks * sizeof(struct jit_block)); + jit->code = malloc(jit->guest.block_max * sizeof(struct jit_block)); - for (int i = 0; i < jit->guest.max_blocks; i++) { + for (int i = 0; i < jit->guest.block_max; i++) { jit->code[i] = default_code; } diff --git a/src/jit/jit.h b/src/jit/jit.h index a71daf69..78313787 100644 --- a/src/jit/jit.h +++ b/src/jit/jit.h @@ -25,7 +25,7 @@ struct jit_guest { // used by the jit to map guest addresses to block offsets uint32_t block_mask; uint32_t block_shift; - int max_blocks; + int block_max; // used by the backend void *ctx_base;