Skip to content

Commit

Permalink
Fix fast-jit callnative translation (#2765)
Browse files Browse the repository at this point in the history
Lock i32 registers before and after preparing the function arguments
to prevent they are overwritten.
  • Loading branch information
wenyongh authored Nov 15, 2023
1 parent 40d33d8 commit 0b8a904
Showing 1 changed file with 32 additions and 2 deletions.
34 changes: 32 additions & 2 deletions core/iwasm/fast-jit/fe/jit_emit_function.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,23 +827,45 @@ emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res,
JitReg *params, uint32 param_count)
{
JitInsn *insn;
char *i32_arg_names[] = { "edi", "esi", "edx", "ecx" };
char *i64_arg_names[] = { "rdi", "rsi", "rdx", "rcx", "r8", "r9" };
char *f32_arg_names[] = { "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" };
char *f64_arg_names[] = { "xmm0_f64", "xmm1_f64", "xmm2_f64",
"xmm3_f64", "xmm4_f64", "xmm5_f64" };
JitReg i64_arg_regs[6], f32_arg_regs[6], f64_arg_regs[6], res_reg = 0;
JitReg i32_arg_regs[4], i64_arg_regs[6];
JitReg f32_arg_regs[6], f64_arg_regs[6], res_reg = 0;
JitReg eax_hreg = jit_codegen_get_hreg_by_name("eax");
JitReg xmm0_hreg = jit_codegen_get_hreg_by_name("xmm0");
uint32 i, i64_reg_idx, float_reg_idx;
uint32 i, i64_reg_idx, float_reg_idx, lock_i32_reg_num;

bh_assert(param_count <= 6);

for (i = 0; i < 4; i++) {
i32_arg_regs[i] = jit_codegen_get_hreg_by_name(i32_arg_names[i]);
}

for (i = 0; i < 6; i++) {
i64_arg_regs[i] = jit_codegen_get_hreg_by_name(i64_arg_names[i]);
f32_arg_regs[i] = jit_codegen_get_hreg_by_name(f32_arg_names[i]);
f64_arg_regs[i] = jit_codegen_get_hreg_by_name(f64_arg_names[i]);
}

lock_i32_reg_num = param_count < 4 ? param_count : 4;

/*
* Lock i32 registers so that they won't be allocated for the operand
* of below I32TOI64 insn, which may have been overwritten in the
* previous MOV, for example, in the below insns:
* MOV I5, I15
* I32TOI64 I6, i5
* CALLNATIVE VOID, native_func, I5, I6
* i5 is used in the second insn, but it has been overwritten in I5
* by the first insn
*/
for (i = 0; i < lock_i32_reg_num; i++) {
GEN_INSN(MOV, i32_arg_regs[i], i32_arg_regs[i]);
}

i64_reg_idx = float_reg_idx = 0;
for (i = 0; i < param_count; i++) {
switch (jit_reg_kind(params[i])) {
Expand All @@ -865,6 +887,14 @@ emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res,
}
}

/*
* Announce the locked i32 registers are being used, and do necessary
* spill ASAP
*/
for (i = 0; i < lock_i32_reg_num; i++) {
GEN_INSN(MOV, i32_arg_regs[i], i32_arg_regs[i]);
}

if (res) {
switch (jit_reg_kind(res)) {
case JIT_REG_KIND_I32:
Expand Down

0 comments on commit 0b8a904

Please sign in to comment.