diff --git a/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp b/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp index 1f3784e55..2ced20052 100644 --- a/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp +++ b/core/iwasm/fast-jit/cg/x86-64/jit_codegen_x86_64.cpp @@ -214,7 +214,7 @@ class JitErrorHandler : public ErrorHandler }; /* Alu opcode */ -typedef enum { ADD, SUB, MUL, DIV, REM } ALU_OP; +typedef enum { ADD, SUB, MUL, DIV_S, REM_S, DIV_U, REM_U } ALU_OP; /* Bit opcode */ typedef enum { OR, XOR, AND } BIT_OP; /* Shift opcode */ @@ -1620,16 +1620,33 @@ alu_r_r_imm_i32(x86::Assembler &a, ALU_OP op, int32 reg_no_dst, a.imul(regs_i32[reg_no_dst], regs_i32[reg_no_src], imm); } break; - case DIV: - case REM: -#if 0 - imm_from_sz_v_s (imm, SZ32, data, true); - mov_r_imm (reg_I4_free, imm); - stream = cdq (stream); - idiv_r (reg_I4_free); -#endif - /* TODO */ - bh_assert(0); + case DIV_S: + case REM_S: + bh_assert(reg_no_src == REG_EAX_IDX); + if (op == DIV_S) { + bh_assert(reg_no_dst == REG_EAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_EDX_IDX); + } + a.mov(regs_i32[REG_I32_FREE_IDX], imm); + /* signed extend eax to edx:eax */ + a.cdq(); + a.idiv(regs_i32[REG_I32_FREE_IDX]); + break; + case DIV_U: + case REM_U: + bh_assert(reg_no_src == REG_EAX_IDX); + if (op == DIV_U) { + bh_assert(reg_no_dst == REG_EAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_EDX_IDX); + } + a.mov(regs_i32[REG_I32_FREE_IDX], imm); + /* unsigned extend eax to edx:eax */ + a.xor_(regs_i32[REG_EDX_IDX], regs_i32[REG_EDX_IDX]); + a.div(regs_i32[REG_I32_FREE_IDX]); break; default: bh_assert(0); @@ -1680,10 +1697,46 @@ alu_r_r_r_i32(x86::Assembler &a, ALU_OP op, int32 reg_no_dst, int32 reg_no1_src, else a.imul(regs_i32[reg_no2_src], regs_i32[reg_no1_src]); break; - case DIV: - case REM: - /* TODO */ - bh_assert(0); + case DIV_S: + case REM_S: + bh_assert(reg_no1_src == REG_EAX_IDX); + if (op == DIV_S) { + bh_assert(reg_no_dst == REG_EAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_EDX_IDX); + if (reg_no2_src == REG_EDX_IDX) { + /* convert `REM_S edx, eax, edx` into + `mov esi, edx` and `REM_S edx eax, rsi` to + avoid overwritting edx when a.cdq() */ + a.mov(regs_i32[REG_I32_FREE_IDX], regs_i32[REG_EDX_IDX]); + reg_no2_src = REG_I32_FREE_IDX; + } + } + /* signed extend eax to edx:eax */ + a.cdq(); + a.idiv(regs_i32[reg_no2_src]); + break; + case DIV_U: + case REM_U: + bh_assert(reg_no1_src == REG_EAX_IDX); + if (op == DIV_U) { + bh_assert(reg_no_dst == REG_EAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_EDX_IDX); + if (reg_no2_src == REG_EDX_IDX) { + /* convert `REM_U edx, eax, edx` into + `mov esi, edx` and `REM_U edx eax, rsi` to + avoid overwritting edx when unsigned extend + eax to edx:eax */ + a.mov(regs_i32[REG_I32_FREE_IDX], regs_i32[REG_EDX_IDX]); + reg_no2_src = REG_I32_FREE_IDX; + } + } + /* unsigned extend eax to edx:eax */ + a.xor_(regs_i32[REG_EDX_IDX], regs_i32[REG_EDX_IDX]); + a.div(regs_i32[reg_no2_src]); break; default: bh_assert(0); @@ -1721,12 +1774,18 @@ alu_imm_imm_to_r_i32(x86::Assembler &a, ALU_OP op, int32 reg_no_dst, case MUL: data = data1_src * data2_src; break; - case DIV: + case DIV_S: data = data1_src / data2_src; break; - case REM: + case REM_S: data = data1_src % data2_src; break; + case DIV_U: + data = (uint32)data1_src / (uint32)data2_src; + break; + case REM_U: + data = (uint32)data1_src % (uint32)data2_src; + break; default: bh_assert(0); break; @@ -1879,16 +1938,33 @@ alu_r_r_imm_i64(x86::Assembler &a, ALU_OP op, int32 reg_no_dst, a.imul(regs_i64[reg_no_dst], regs_i64[reg_no_src], imm); } break; - case DIV: - case REM: -#if 0 - imm_from_sz_v_s (imm, SZ32, data, true); - mov_r_imm (reg_I4_free, imm); - stream = cdq (stream); - idiv_r (reg_I4_free); -#endif - /* TODO */ - bh_assert(0); + case DIV_S: + case REM_S: + bh_assert(reg_no_src == REG_RAX_IDX); + if (op == DIV_S) { + bh_assert(reg_no_dst == REG_RAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_RDX_IDX); + } + a.mov(regs_i64[REG_I64_FREE_IDX], imm); + /* signed extend rax to rdx:rax */ + a.cqo(); + a.idiv(regs_i64[REG_I64_FREE_IDX]); + break; + case DIV_U: + case REM_U: + bh_assert(reg_no_src == REG_RAX_IDX); + if (op == DIV_U) { + bh_assert(reg_no_dst == REG_RAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_RDX_IDX); + } + a.mov(regs_i64[REG_I64_FREE_IDX], imm); + /* unsigned extend rax to rdx:rax */ + a.xor_(regs_i64[REG_RDX_IDX], regs_i64[REG_RDX_IDX]); + a.div(regs_i64[REG_I64_FREE_IDX]); break; default: bh_assert(0); @@ -1939,10 +2015,31 @@ alu_r_r_r_i64(x86::Assembler &a, ALU_OP op, int32 reg_no_dst, int32 reg_no1_src, else a.imul(regs_i64[reg_no2_src], regs_i64[reg_no1_src]); break; - case DIV: - case REM: - /* TODO */ - bh_assert(0); + case DIV_S: + case REM_S: + bh_assert(reg_no1_src == REG_RAX_IDX); + if (op == DIV_S) { + bh_assert(reg_no_dst == REG_RAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_RDX_IDX); + } + /* signed extend rax to rdx:rax */ + a.cqo(); + a.idiv(regs_i64[reg_no2_src]); + break; + case DIV_U: + case REM_U: + bh_assert(reg_no1_src == REG_RAX_IDX); + if (op == DIV_U) { + bh_assert(reg_no_dst == REG_RAX_IDX); + } + else { + bh_assert(reg_no_dst == REG_RDX_IDX); + } + /* unsigned extend rax to rdx:rax */ + a.xor_(regs_i64[REG_RDX_IDX], regs_i64[REG_RDX_IDX]); + a.div(regs_i64[reg_no2_src]); break; default: bh_assert(0); @@ -1980,12 +2077,18 @@ alu_imm_imm_to_r_i64(x86::Assembler &a, ALU_OP op, int32 reg_no_dst, case MUL: data = data1_src * data2_src; break; - case DIV: + case DIV_S: data = data1_src / data2_src; break; - case REM: + case REM_S: data = data1_src % data2_src; break; + case DIV_U: + data = (uint64)data1_src / (uint64)data2_src; + break; + case REM_U: + data = (uint64)data1_src % (uint64)data2_src; + break; default: bh_assert(0); break; @@ -2231,7 +2334,28 @@ alu_r_r_to_r_f64(x86::Assembler &a, ALU_OP op, int32 reg_no_dst, static bool bit_r_imm_i32(x86::Assembler &a, BIT_OP op, int32 reg_no, int32 data) { - return false; + Imm imm(data); + + switch (op) { + case OR: + if (data != 0) + a.or_(regs_i32[reg_no], imm); + break; + case XOR: + if (data == -1) + a.not_(regs_i32[reg_no]); + else if (data != 0) + a.xor_(regs_i32[reg_no], imm); + break; + case AND: + if (data != -1) + a.and_(regs_i32[reg_no], imm); + break; + default: + bh_assert(0); + break; + } + return true; } /** @@ -2247,7 +2371,21 @@ bit_r_imm_i32(x86::Assembler &a, BIT_OP op, int32 reg_no, int32 data) static bool bit_r_r_i32(x86::Assembler &a, BIT_OP op, int32 reg_no_dst, int32 reg_no_src) { - return false; + switch (op) { + case OR: + a.or_(regs_i32[reg_no_dst], regs_i32[reg_no_src]); + break; + case XOR: + a.xor_(regs_i32[reg_no_dst], regs_i32[reg_no_src]); + break; + case AND: + a.and_(regs_i32[reg_no_dst], regs_i32[reg_no_src]); + break; + default: + bh_assert(0); + break; + } + return true; } /** @@ -2265,7 +2403,25 @@ static bool bit_imm_imm_to_r_i32(x86::Assembler &a, BIT_OP op, int32 reg_no_dst, int32 data1_src, int32 data2_src) { - return false; + Imm imm; + + switch (op) { + case OR: + imm.setValue(data1_src | data2_src); + break; + case XOR: + imm.setValue(data1_src ^ data2_src); + break; + case AND: + imm.setValue(data1_src & data2_src); + break; + default: + bh_assert(0); + break; + } + + a.mov(regs_i32[reg_no_dst], imm); + return true; } /** @@ -2283,7 +2439,17 @@ static bool bit_imm_r_to_r_i32(x86::Assembler &a, BIT_OP op, int32 reg_no_dst, int32 data1_src, int32 reg_no2_src) { - return false; + if (op == AND && data1_src == 0) + a.xor_(regs_i32[reg_no_dst], regs_i32[reg_no_dst]); + else if (op == OR && data1_src == -1) { + Imm imm(-1); + a.mov(regs_i32[reg_no_dst], imm); + } + else { + mov_r_to_r_i32(a, reg_no_dst, reg_no2_src); + return bit_r_imm_i32(a, op, reg_no_dst, data1_src); + } + return true; } /** @@ -2301,7 +2467,7 @@ static bool bit_r_imm_to_r_i32(x86::Assembler &a, BIT_OP op, int32 reg_no_dst, int32 reg_no1_src, int32 data2_src) { - return false; + return bit_imm_r_to_r_i32(a, op, reg_no_dst, data2_src, reg_no1_src); } /** @@ -2319,6 +2485,12 @@ static bool bit_r_r_to_r_i32(x86::Assembler &a, BIT_OP op, int32 reg_no_dst, int32 reg_no1_src, int32 reg_no2_src) { + if (reg_no_dst != reg_no2_src) { + mov_r_to_r_i32(a, reg_no_dst, reg_no1_src); + return bit_r_r_i32(a, op, reg_no_dst, reg_no2_src); + } + else + return bit_r_r_i32(a, op, reg_no_dst, reg_no1_src); return false; } @@ -4242,8 +4414,10 @@ jit_codegen_gen_native(JitCompContext *cc) case JIT_OP_ADD: case JIT_OP_SUB: case JIT_OP_MUL: - case JIT_OP_DIV: - case JIT_OP_REM: + case JIT_OP_DIV_S: + case JIT_OP_REM_S: + case JIT_OP_DIV_U: + case JIT_OP_REM_U: LOAD_3ARGS(); if (!lower_alu(cc, a, (ALU_OP)(ADD + (insn->opcode - JIT_OP_ADD)), @@ -4704,3 +4878,18 @@ jit_codegen_get_hreg_info() { return &hreg_info; } + +JitReg +jit_codegen_get_hreg_by_name(const char *name) +{ + if (strcmp(name, "eax") == 0) + return jit_reg_new(JIT_REG_KIND_I32, REG_EAX_IDX); + else if (strcmp(name, "edx") == 0) + return jit_reg_new(JIT_REG_KIND_I32, REG_EDX_IDX); + else if (strcmp(name, "rax") == 0) + return jit_reg_new(JIT_REG_KIND_I64, REG_RAX_IDX); + else if (strcmp(name, "rdx") == 0) + return jit_reg_new(JIT_REG_KIND_I64, REG_RDX_IDX); + + return 0; +} diff --git a/core/iwasm/fast-jit/fe/jit_emit_control.c b/core/iwasm/fast-jit/fe/jit_emit_control.c index f99b37138..407a78544 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_control.c +++ b/core/iwasm/fast-jit/fe/jit_emit_control.c @@ -952,7 +952,7 @@ jit_compile_op_return(JitCompContext *cc, uint8 **p_frame_ip) bool jit_compile_op_unreachable(JitCompContext *cc, uint8 **p_frame_ip) { - if (!jit_emit_exception(cc, EXCE_UNREACHABLE, false, 0, NULL)) + if (!jit_emit_exception(cc, EXCE_UNREACHABLE, JIT_OP_JMP, 0, NULL)) return false; return handle_next_reachable_block(cc, p_frame_ip); diff --git a/core/iwasm/fast-jit/fe/jit_emit_function.c b/core/iwasm/fast-jit/fe/jit_emit_function.c index 371aa6200..070c27372 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_function.c +++ b/core/iwasm/fast-jit/fe/jit_emit_function.c @@ -6,6 +6,7 @@ #include "jit_emit_function.h" #include "jit_emit_exception.h" #include "../jit_frontend.h" +#include "../jit_codegen.h" extern bool jit_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, @@ -85,8 +86,8 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call) if (func_idx < wasm_module->import_function_count) { #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) - /* Set native_ret to x86::eax, 1 is hard reg index of eax */ - native_ret = jit_reg_new(JIT_REG_KIND_I32, 1); + /* Set native_ret to x86::eax */ + native_ret = jit_codegen_get_hreg_by_name("eax"); #else native_ret = jit_cc_new_reg_I32(cc); #endif @@ -101,7 +102,7 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call) /* Check whether there is exception thrown */ GEN_INSN(CMP, cc->cmp_reg, native_ret, NEW_CONST(I32, 0)); if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BEQ, - cc->cmp_reg, 0)) { + cc->cmp_reg, NULL)) { return false; } } diff --git a/core/iwasm/fast-jit/fe/jit_emit_numberic.c b/core/iwasm/fast-jit/fe/jit_emit_numberic.c index 75cfea645..1f5fba80b 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_numberic.c +++ b/core/iwasm/fast-jit/fe/jit_emit_numberic.c @@ -4,7 +4,10 @@ */ #include "jit_emit_numberic.h" +#include "jit_emit_exception.h" +#include "jit_emit_control.h" #include "../jit_frontend.h" +#include "../jit_codegen.h" #define PUSH_INT(v) \ do { \ @@ -176,12 +179,239 @@ compile_int_mul(JitCompContext *cc, JitReg left, JitReg right, bool is_i32) return res; } +static bool +compile_int_div_no_check(JitCompContext *cc, IntArithmetic arith_op, + bool is_i32, JitReg left, JitReg right, JitReg res) +{ +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) + JitReg eax_hreg = jit_codegen_get_hreg_by_name("eax"); + JitReg edx_hreg = jit_codegen_get_hreg_by_name("edx"); + JitReg rax_hreg = jit_codegen_get_hreg_by_name("rax"); + JitReg rdx_hreg = jit_codegen_get_hreg_by_name("rdx"); +#endif + + switch (arith_op) { +#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) + case INT_DIV_S: + case INT_DIV_U: + if (is_i32) { + GEN_INSN(MOV, eax_hreg, left); + if (arith_op == INT_DIV_S) + GEN_INSN(DIV_S, eax_hreg, eax_hreg, right); + else + GEN_INSN(DIV_U, eax_hreg, eax_hreg, right); + /* Just to indicate that edx is used, + register allocator cannot spill it out */ + GEN_INSN(MOV, edx_hreg, edx_hreg); + res = eax_hreg; + } + else { + GEN_INSN(MOV, rax_hreg, left); + /* Just to indicate that eax is used, + register allocator cannot spill it out */ + GEN_INSN(MOV, eax_hreg, eax_hreg); + if (arith_op == INT_DIV_S) + GEN_INSN(DIV_S, rax_hreg, rax_hreg, right); + else + GEN_INSN(DIV_U, rax_hreg, rax_hreg, right); + /* Just to indicate that edx is used, + register allocator cannot spill it out */ + GEN_INSN(MOV, edx_hreg, edx_hreg); + res = rax_hreg; + } + break; + case INT_REM_S: + case INT_REM_U: + if (is_i32) { + GEN_INSN(MOV, eax_hreg, left); + if (arith_op == INT_REM_S) + GEN_INSN(REM_S, edx_hreg, eax_hreg, right); + else + GEN_INSN(REM_U, edx_hreg, eax_hreg, right); + res = edx_hreg; + } + else { + GEN_INSN(MOV, rax_hreg, left); + /* Just to indicate that eax is used, + register allocator cannot spill it out */ + GEN_INSN(MOV, eax_hreg, eax_hreg); + if (arith_op == INT_REM_S) + GEN_INSN(REM_S, rdx_hreg, rax_hreg, right); + else + GEN_INSN(REM_U, rdx_hreg, rax_hreg, right); + /* Just to indicate that edx is used, + register allocator cannot spill it out */ + GEN_INSN(MOV, edx_hreg, edx_hreg); + res = rdx_hreg; + } + break; +#else + case INT_DIV_S: + GEN_INSN(DIV_S, res, left, right); + break; + case INT_DIV_U: + GEN_INSN(DIV_U, res, left, right); + break; + case INT_REM_S: + GEN_INSN(REM_S, res, left, right); + break; + case INT_REM_U: + GEN_INSN(REM_U, res, left, right); + break; +#endif /* defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) */ + default: + bh_assert(0); + return false; + } + + if (is_i32) + PUSH_I32(res); + else + PUSH_I64(res); + return true; +fail: + return false; +} + static bool compile_int_div(JitCompContext *cc, IntArithmetic arith_op, bool is_i32, uint8 **p_frame_ip) { - /* TODO */ - bh_assert(0); + JitReg left, right, res; + + bh_assert(arith_op == INT_DIV_S || arith_op == INT_DIV_U + || arith_op == INT_REM_S || arith_op == INT_REM_U); + + if (is_i32) { + POP_I32(right); + POP_I32(left); + res = jit_cc_new_reg_I32(cc); + } + else { + POP_I64(right); + POP_I64(left); + res = jit_cc_new_reg_I64(cc); + } + + if (jit_reg_is_const(right)) { + int64 right_val = is_i32 ? (int64)jit_cc_get_const_I32(cc, right) + : jit_cc_get_const_I64(cc, right); + + switch (right_val) { + case 0: + { + /* Directly throw exception if divided by zero */ + if (!(jit_emit_exception(cc, EXCE_INTEGER_DIVIDE_BY_ZERO, + JIT_OP_JMP, 0, NULL))) + goto fail; + + return jit_handle_next_reachable_block(cc, p_frame_ip); + } + case 1: + { + if (arith_op == INT_DIV_S || arith_op == INT_DIV_U) { + if (is_i32) + PUSH_I32(left); + else + PUSH_I64(left); + } + else { + if (is_i32) + PUSH_I32(NEW_CONST(I32, 0)); + else + PUSH_I64(NEW_CONST(I64, 0)); + } + return true; + } + case -1: + { + if (arith_op == INT_DIV_S) { + if (is_i32) + GEN_INSN(CMP, cc->cmp_reg, left, + NEW_CONST(I32, INT32_MIN)); + else + GEN_INSN(CMP, cc->cmp_reg, left, + NEW_CONST(I64, INT64_MIN)); + + /* Throw integer overflow exception if left is + INT32_MIN or INT64_MIN */ + if (!(jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, + JIT_OP_BEQ, cc->cmp_reg, NULL))) + goto fail; + + /* Push -(left) to stack */ + GEN_INSN(NEG, res, left); + if (is_i32) + PUSH_I32(res); + else + PUSH_I64(res); + return true; + } + else if (arith_op == INT_REM_S) { + if (is_i32) + PUSH_I32(NEW_CONST(I32, 0)); + else + PUSH_I64(NEW_CONST(I64, 0)); + return true; + } + else { + /* Build default div and rem */ + return compile_int_div_no_check(cc, arith_op, is_i32, left, + right, res); + } + } + default: + { + /* Build default div and rem */ + return compile_int_div_no_check(cc, arith_op, is_i32, left, + right, res); + } + } + } + else { + JitReg cmp1 = is_i32 ? jit_cc_new_reg_I32(cc) : jit_cc_new_reg_I64(cc); + JitReg cmp2 = is_i32 ? jit_cc_new_reg_I32(cc) : jit_cc_new_reg_I64(cc); + + GEN_INSN(CMP, cc->cmp_reg, right, + is_i32 ? NEW_CONST(I32, 0) : NEW_CONST(I64, 0)); + /* Throw integer divided by zero exception if right is zero */ + if (!(jit_emit_exception(cc, EXCE_INTEGER_DIVIDE_BY_ZERO, JIT_OP_BEQ, + cc->cmp_reg, NULL))) + goto fail; + + switch (arith_op) { + case INT_DIV_S: + case INT_REM_S: + /* Check integer overflow */ + GEN_INSN(CMP, cc->cmp_reg, left, + is_i32 ? NEW_CONST(I32, INT32_MIN) + : NEW_CONST(I64, INT64_MIN)); + GEN_INSN(SELECTEQ, cmp1, cc->cmp_reg, NEW_CONST(I32, 1), + NEW_CONST(I32, 0)); + GEN_INSN(CMP, cc->cmp_reg, right, + is_i32 ? NEW_CONST(I32, -1) : NEW_CONST(I64, -1LL)); + GEN_INSN(SELECTEQ, cmp2, cc->cmp_reg, NEW_CONST(I32, 1), + NEW_CONST(I32, 0)); + GEN_INSN(AND, cmp1, cmp1, cmp2); + GEN_INSN(CMP, cc->cmp_reg, cmp1, NEW_CONST(I32, 1)); + /* Throw integer overflow exception if left is INT32_MIN or + INT64_MIN, and right is -1 */ + if (!(jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_BEQ, + cc->cmp_reg, NULL))) + goto fail; + + /* Build default div and rem */ + return compile_int_div_no_check(cc, arith_op, is_i32, left, + right, res); + return true; + default: + /* Build default div and rem */ + return compile_int_div_no_check(cc, arith_op, is_i32, left, + right, res); + } + } + +fail: return false; } diff --git a/core/iwasm/fast-jit/jit_codegen.h b/core/iwasm/fast-jit/jit_codegen.h index 341fb61aa..666a239a6 100644 --- a/core/iwasm/fast-jit/jit_codegen.h +++ b/core/iwasm/fast-jit/jit_codegen.h @@ -35,6 +35,16 @@ jit_codegen_destroy(); const JitHardRegInfo * jit_codegen_get_hreg_info(); +/** + * Get hard register by name. + * + * @param name the name of the hard register + * + * @return the hard register of the name + */ +JitReg +jit_codegen_get_hreg_by_name(const char *name); + /** * Generate native code for the given compilation context * diff --git a/core/iwasm/fast-jit/jit_frontend.c b/core/iwasm/fast-jit/jit_frontend.c index 1799dd5b2..8fe59b645 100644 --- a/core/iwasm/fast-jit/jit_frontend.c +++ b/core/iwasm/fast-jit/jit_frontend.c @@ -617,11 +617,15 @@ form_and_translate_func(JitCompContext *cc) } cc->cur_basic_block = cc->exce_basic_blocks[i]; if (i != EXCE_ALREADY_THROWN) { + JitReg module_inst_reg = jit_cc_new_reg_ptr(cc); + GEN_INSN(LDPTR, module_inst_reg, cc->exec_env_reg, + NEW_CONST(I32, offsetof(WASMExecEnv, module_inst))); insn = GEN_INSN( CALLNATIVE, 0, - NEW_CONST(PTR, (uintptr_t)jit_set_exception_with_id), 1); + NEW_CONST(PTR, (uintptr_t)jit_set_exception_with_id), 2); if (insn) { - *(jit_insn_opndv(insn, 2)) = NEW_CONST(I32, i); + *(jit_insn_opndv(insn, 2)) = module_inst_reg; + *(jit_insn_opndv(insn, 3)) = NEW_CONST(I32, i); } } GEN_INSN(RETURN, NEW_CONST(I32, JIT_INTERP_ACTION_THROWN)); @@ -762,7 +766,7 @@ init_func_translation(JitCompContext *cc) /* if frame_boundary > top_boundary, throw stack overflow exception */ GEN_INSN(CMP, cc->cmp_reg, frame_boundary, top_boundary); if (!jit_emit_exception(cc, EXCE_OPERAND_STACK_OVERFLOW, JIT_OP_BGTU, - cc->cmp_reg, 0)) { + cc->cmp_reg, NULL)) { return NULL; } diff --git a/core/iwasm/fast-jit/jit_ir.def b/core/iwasm/fast-jit/jit_ir.def index 7c795ece9..6c87eabaf 100644 --- a/core/iwasm/fast-jit/jit_ir.def +++ b/core/iwasm/fast-jit/jit_ir.def @@ -102,8 +102,10 @@ INSN(NOT, Reg, 2, 1) INSN(ADD, Reg, 3, 1) INSN(SUB, Reg, 3, 1) INSN(MUL, Reg, 3, 1) -INSN(DIV, Reg, 3, 1) -INSN(REM, Reg, 3, 1) +INSN(DIV_S, Reg, 3, 1) +INSN(REM_S, Reg, 3, 1) +INSN(DIV_U, Reg, 3, 1) +INSN(REM_U, Reg, 3, 1) INSN(SHL, Reg, 3, 1) INSN(SHRS, Reg, 3, 1) INSN(SHRU, Reg, 3, 1)