Fix fast-jit callnative translation (#2765)

Lock i32 registers before and after preparing the function arguments
to prevent they are overwritten.
This commit is contained in:
Wenyong Huang 2023-11-15 18:30:51 +08:00 committed by GitHub
parent 40d33d806b
commit 0b8a904193
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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])) {
@ -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: