diff options
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_function.c')
-rw-r--r-- | fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_function.c | 945 |
1 files changed, 0 insertions, 945 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_function.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_function.c deleted file mode 100644 index 3ac9e3ed6..000000000 --- a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/fast-jit/fe/jit_emit_function.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Copyright (C) 2019 Intel Corporation. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - */ - -#include "jit_emit_function.h" -#include "jit_emit_exception.h" -#include "jit_emit_control.h" -#include "../jit_frontend.h" -#include "../jit_codegen.h" -#include "../../interpreter/wasm_runtime.h" - -static bool -emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res, - JitReg *params, uint32 param_count); - -/* Prepare parameters for the function to call */ -static bool -pre_call(JitCompContext *cc, const WASMType *func_type) -{ - JitReg value; - uint32 i, outs_off; - /* Prepare parameters for the function to call */ - outs_off = - cc->total_frame_size + offsetof(WASMInterpFrame, lp) - + wasm_get_cell_num(func_type->types, func_type->param_count) * 4; - - for (i = 0; i < func_type->param_count; i++) { - switch (func_type->types[func_type->param_count - 1 - i]) { - case VALUE_TYPE_I32: -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - case VALUE_TYPE_FUNCREF: -#endif - POP_I32(value); - outs_off -= 4; - GEN_INSN(STI32, value, cc->fp_reg, NEW_CONST(I32, outs_off)); - break; - case VALUE_TYPE_I64: - POP_I64(value); - outs_off -= 8; - GEN_INSN(STI64, value, cc->fp_reg, NEW_CONST(I32, outs_off)); - break; - case VALUE_TYPE_F32: - POP_F32(value); - outs_off -= 4; - GEN_INSN(STF32, value, cc->fp_reg, NEW_CONST(I32, outs_off)); - break; - case VALUE_TYPE_F64: - POP_F64(value); - outs_off -= 8; - GEN_INSN(STF64, value, cc->fp_reg, NEW_CONST(I32, outs_off)); - break; - default: - bh_assert(0); - goto fail; - } - } - - /* Commit sp as the callee may use it to store the results */ - gen_commit_sp_ip(cc->jit_frame); - - return true; -fail: - return false; -} - -/* Push results */ -static bool -post_return(JitCompContext *cc, const WASMType *func_type, JitReg first_res, - bool update_committed_sp) -{ - uint32 i, n; - JitReg value; - - n = cc->jit_frame->sp - cc->jit_frame->lp; - for (i = 0; i < func_type->result_count; i++) { - switch (func_type->types[func_type->param_count + i]) { - case VALUE_TYPE_I32: -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - case VALUE_TYPE_FUNCREF: -#endif - if (i == 0 && first_res) { - bh_assert(jit_reg_kind(first_res) == JIT_REG_KIND_I32); - value = first_res; - } - else { - value = jit_cc_new_reg_I32(cc); - GEN_INSN(LDI32, value, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - } - PUSH_I32(value); - n++; - break; - case VALUE_TYPE_I64: - if (i == 0 && first_res) { - bh_assert(jit_reg_kind(first_res) == JIT_REG_KIND_I64); - value = first_res; - } - else { - value = jit_cc_new_reg_I64(cc); - GEN_INSN(LDI64, value, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - } - PUSH_I64(value); - n += 2; - break; - case VALUE_TYPE_F32: - if (i == 0 && first_res) { - bh_assert(jit_reg_kind(first_res) == JIT_REG_KIND_F32); - value = first_res; - } - else { - value = jit_cc_new_reg_F32(cc); - GEN_INSN(LDF32, value, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - } - PUSH_F32(value); - n++; - break; - case VALUE_TYPE_F64: - if (i == 0 && first_res) { - bh_assert(jit_reg_kind(first_res) == JIT_REG_KIND_F64); - value = first_res; - } - else { - value = jit_cc_new_reg_F64(cc); - GEN_INSN(LDF64, value, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - } - PUSH_F64(value); - n += 2; - break; - default: - bh_assert(0); - goto fail; - } - } - - if (update_committed_sp) - /* Update the committed_sp as the callee has updated the frame sp */ - cc->jit_frame->committed_sp = cc->jit_frame->sp; - - return true; -fail: - return false; -} - -static bool -pre_load(JitCompContext *cc, JitReg *argvs, const WASMType *func_type) -{ - JitReg value; - uint32 i; - - /* Prepare parameters for the function to call */ - for (i = 0; i < func_type->param_count; i++) { - switch (func_type->types[func_type->param_count - 1 - i]) { - case VALUE_TYPE_I32: -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - case VALUE_TYPE_FUNCREF: -#endif - POP_I32(value); - argvs[func_type->param_count - 1 - i] = value; - break; - case VALUE_TYPE_I64: - POP_I64(value); - argvs[func_type->param_count - 1 - i] = value; - break; - case VALUE_TYPE_F32: - POP_F32(value); - argvs[func_type->param_count - 1 - i] = value; - break; - case VALUE_TYPE_F64: - POP_F64(value); - argvs[func_type->param_count - 1 - i] = value; - break; - default: - bh_assert(0); - goto fail; - } - } - - gen_commit_sp_ip(cc->jit_frame); - - return true; -fail: - return false; -} - -static JitReg -create_first_res_reg(JitCompContext *cc, const WASMType *func_type) -{ - if (func_type->result_count) { - switch (func_type->types[func_type->param_count]) { - case VALUE_TYPE_I32: -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - case VALUE_TYPE_FUNCREF: -#endif - return jit_cc_new_reg_I32(cc); - case VALUE_TYPE_I64: - return jit_cc_new_reg_I64(cc); - case VALUE_TYPE_F32: - return jit_cc_new_reg_F32(cc); - case VALUE_TYPE_F64: - return jit_cc_new_reg_F64(cc); - default: - bh_assert(0); - return 0; - } - } - return 0; -} - -bool -jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call) -{ - WASMModule *wasm_module = cc->cur_wasm_module; - WASMFunctionImport *func_import; - WASMFunction *func; - WASMType *func_type; - JitFrame *jit_frame = cc->jit_frame; - JitReg fast_jit_func_ptrs, jitted_code = 0; - JitReg native_func, *argvs = NULL, *argvs1 = NULL, func_params[5]; - JitReg native_addr_ptr, module_inst_reg, ret, res; - uint32 jitted_func_idx, i; - uint64 total_size; - const char *signature = NULL; - /* Whether the argument is a pointer/str argument and - need to call jit_check_app_addr_and_convert */ - bool is_pointer_arg; - bool return_value = false; - -#if WASM_ENABLE_THREAD_MGR != 0 - /* Insert suspend check point */ - if (!jit_check_suspend_flags(cc)) - goto fail; -#endif - - if (func_idx < wasm_module->import_function_count) { - /* The function to call is an import function */ - func_import = &wasm_module->import_functions[func_idx].u.function; - func_type = func_import->func_type; - - /* Call fast_jit_invoke_native in some cases */ - if (!func_import->func_ptr_linked /* import func hasn't been linked */ - || func_import->call_conv_wasm_c_api /* linked by wasm_c_api */ - || func_import->call_conv_raw /* registered as raw mode */ - || func_type->param_count >= 5 /* registered as normal mode, but - jit_emit_callnative only supports - maximum 6 registers now - (include exec_nev) */) { - JitReg arg_regs[3]; - - if (!pre_call(cc, func_type)) { - goto fail; - } - - /* Call fast_jit_invoke_native */ - ret = jit_cc_new_reg_I32(cc); - arg_regs[0] = cc->exec_env_reg; - arg_regs[1] = NEW_CONST(I32, func_idx); - arg_regs[2] = cc->fp_reg; - if (!jit_emit_callnative(cc, fast_jit_invoke_native, ret, arg_regs, - 3)) { - goto fail; - } - - /* Convert the return value from bool to uint32 */ - GEN_INSN(AND, ret, ret, NEW_CONST(I32, 0xFF)); - - /* Check whether there is exception thrown */ - GEN_INSN(CMP, cc->cmp_reg, ret, NEW_CONST(I32, 0)); - if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BEQ, - cc->cmp_reg, NULL)) { - goto fail; - } - - if (!post_return(cc, func_type, 0, true)) { - goto fail; - } - -#if WASM_ENABLE_THREAD_MGR != 0 - /* Insert suspend check point */ - if (!jit_check_suspend_flags(cc)) - goto fail; -#endif - - return true; - } - - /* Import function was registered as normal mode, and its argument count - is no more than 5, we directly call it */ - - signature = func_import->signature; - bh_assert(signature); - - /* Allocate memory for argvs*/ - total_size = sizeof(JitReg) * (uint64)(func_type->param_count); - if (total_size > 0) { - if (total_size >= UINT32_MAX - || !(argvs = jit_malloc((uint32)total_size))) { - goto fail; - } - } - - /* Pop function params from stack and store them into argvs */ - if (!pre_load(cc, argvs, func_type)) { - goto fail; - } - - ret = jit_cc_new_reg_I32(cc); - func_params[0] = module_inst_reg = get_module_inst_reg(jit_frame); - func_params[4] = native_addr_ptr = jit_cc_new_reg_ptr(cc); - GEN_INSN(ADD, native_addr_ptr, cc->exec_env_reg, - NEW_CONST(PTR, offsetof(WASMExecEnv, jit_cache))); - - /* Traverse each pointer/str argument, call - jit_check_app_addr_and_convert to check whether it is - in the range of linear memory and and convert it from - app offset into native address */ - for (i = 0; i < func_type->param_count; i++) { - - is_pointer_arg = false; - - if (signature[i + 1] == '*') { - /* param is a pointer */ - is_pointer_arg = true; - func_params[1] = NEW_CONST(I32, false); /* is_str = false */ - func_params[2] = argvs[i]; - if (signature[i + 2] == '~') { - /* pointer with length followed */ - func_params[3] = argvs[i + 1]; - } - else { - /* pointer with length followed */ - func_params[3] = NEW_CONST(I32, 1); - } - } - else if (signature[i + 1] == '$') { - /* param is a string */ - is_pointer_arg = true; - func_params[1] = NEW_CONST(I32, true); /* is_str = true */ - func_params[2] = argvs[i]; - func_params[3] = NEW_CONST(I32, 1); - } - - if (is_pointer_arg) { - if (!jit_emit_callnative(cc, jit_check_app_addr_and_convert, - ret, func_params, 5)) { - goto fail; - } - - /* Convert the return value from bool to uint32 */ - GEN_INSN(AND, ret, ret, NEW_CONST(I32, 0xFF)); - /* Check whether there is exception thrown */ - GEN_INSN(CMP, cc->cmp_reg, ret, NEW_CONST(I32, 0)); - if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BEQ, - cc->cmp_reg, NULL)) { - return false; - } - - /* Load native addr from pointer of native addr, - or exec_env->jit_cache */ - argvs[i] = jit_cc_new_reg_ptr(cc); - GEN_INSN(LDPTR, argvs[i], native_addr_ptr, NEW_CONST(I32, 0)); - } - } - - res = create_first_res_reg(cc, func_type); - - /* Prepare arguments of the native function */ - if (!(argvs1 = - jit_calloc(sizeof(JitReg) * (func_type->param_count + 1)))) { - goto fail; - } - argvs1[0] = cc->exec_env_reg; - for (i = 0; i < func_type->param_count; i++) { - argvs1[i + 1] = argvs[i]; - } - - /* Call the native function */ - native_func = NEW_CONST(PTR, (uintptr_t)func_import->func_ptr_linked); - if (!emit_callnative(cc, native_func, res, argvs1, - func_type->param_count + 1)) { - jit_free(argvs1); - goto fail; - } - jit_free(argvs1); - - /* Check whether there is exception thrown */ - GEN_INSN(LDI8, ret, module_inst_reg, - NEW_CONST(I32, offsetof(WASMModuleInstance, cur_exception))); - GEN_INSN(CMP, cc->cmp_reg, ret, NEW_CONST(I32, 0)); - if (!jit_emit_exception(cc, EXCE_ALREADY_THROWN, JIT_OP_BNE, - cc->cmp_reg, NULL)) { - goto fail; - } - - if (!post_return(cc, func_type, res, false)) { - goto fail; - } - } - else { - /* The function to call is a bytecode function */ - func = wasm_module - ->functions[func_idx - wasm_module->import_function_count]; - func_type = func->func_type; - - /* jitted_code = func_ptrs[func_idx - import_function_count] */ - fast_jit_func_ptrs = get_fast_jit_func_ptrs_reg(jit_frame); - jitted_code = jit_cc_new_reg_ptr(cc); - jitted_func_idx = func_idx - wasm_module->import_function_count; - GEN_INSN(LDPTR, jitted_code, fast_jit_func_ptrs, - NEW_CONST(I32, (uint32)sizeof(void *) * jitted_func_idx)); - - if (!pre_call(cc, func_type)) { - goto fail; - } - - res = create_first_res_reg(cc, func_type); - - GEN_INSN(CALLBC, res, 0, jitted_code, NEW_CONST(I32, func_idx)); - - if (!post_return(cc, func_type, res, true)) { - goto fail; - } - } - -#if WASM_ENABLE_THREAD_MGR != 0 - /* Insert suspend check point */ - if (!jit_check_suspend_flags(cc)) - goto fail; -#endif - - /* Clear part of memory regs and table regs as their values - may be changed in the function call */ - if (cc->cur_wasm_module->possible_memory_grow) - clear_memory_regs(jit_frame); - clear_table_regs(jit_frame); - - /* Ignore tail call currently */ - (void)tail_call; - - return_value = true; - -fail: - if (argvs) - jit_free(argvs); - - return return_value; -} - -static JitReg -pack_argv(JitCompContext *cc) -{ - /* reuse the stack of the next frame */ - uint32 stack_base; - JitReg argv; - - stack_base = cc->total_frame_size + offsetof(WASMInterpFrame, lp); - argv = jit_cc_new_reg_ptr(cc); - GEN_INSN(ADD, argv, cc->fp_reg, NEW_CONST(PTR, stack_base)); - if (jit_get_last_error(cc)) { - return (JitReg)0; - } - return argv; -} - -bool -jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx, - uint32 tbl_idx) -{ - WASMModule *wasm_module = cc->cur_wasm_module; - JitBasicBlock *block_import, *block_nonimport, *func_return; - JitReg elem_idx, native_ret, argv, arg_regs[6]; - JitFrame *jit_frame = cc->jit_frame; - JitReg tbl_size, offset, offset_i32; - JitReg func_import, func_idx, tbl_elems, func_count; - JitReg func_type_indexes, func_type_idx, fast_jit_func_ptrs; - JitReg offset1_i32, offset1, func_type_idx1, res; - JitReg import_func_ptrs, jitted_code_idx, jitted_code; - WASMType *func_type; - uint32 n; - - POP_I32(elem_idx); - - /* check elem_idx */ - tbl_size = get_table_cur_size_reg(jit_frame, tbl_idx); - - GEN_INSN(CMP, cc->cmp_reg, elem_idx, tbl_size); - if (!jit_emit_exception(cc, EXCE_UNDEFINED_ELEMENT, JIT_OP_BGEU, - cc->cmp_reg, NULL)) - goto fail; - - /* check func_idx */ - if (UINTPTR_MAX == UINT64_MAX) { - offset_i32 = jit_cc_new_reg_I32(cc); - offset = jit_cc_new_reg_I64(cc); - GEN_INSN(SHL, offset_i32, elem_idx, NEW_CONST(I32, 2)); - GEN_INSN(I32TOI64, offset, offset_i32); - } - else { - offset = jit_cc_new_reg_I32(cc); - GEN_INSN(SHL, offset, elem_idx, NEW_CONST(I32, 2)); - } - func_idx = jit_cc_new_reg_I32(cc); - tbl_elems = get_table_elems_reg(jit_frame, tbl_idx); - GEN_INSN(LDI32, func_idx, tbl_elems, offset); - - GEN_INSN(CMP, cc->cmp_reg, func_idx, NEW_CONST(I32, -1)); - if (!jit_emit_exception(cc, EXCE_UNINITIALIZED_ELEMENT, JIT_OP_BEQ, - cc->cmp_reg, NULL)) - goto fail; - - func_count = NEW_CONST(I32, wasm_module->import_function_count - + wasm_module->function_count); - GEN_INSN(CMP, cc->cmp_reg, func_idx, func_count); - if (!jit_emit_exception(cc, EXCE_INVALID_FUNCTION_INDEX, JIT_OP_BGTU, - cc->cmp_reg, NULL)) - goto fail; - - /* check func_type */ - /* get func_type_idx from func_type_indexes */ - if (UINTPTR_MAX == UINT64_MAX) { - offset1_i32 = jit_cc_new_reg_I32(cc); - offset1 = jit_cc_new_reg_I64(cc); - GEN_INSN(SHL, offset1_i32, func_idx, NEW_CONST(I32, 2)); - GEN_INSN(I32TOI64, offset1, offset1_i32); - } - else { - offset1 = jit_cc_new_reg_I32(cc); - GEN_INSN(SHL, offset1, func_idx, NEW_CONST(I32, 2)); - } - - func_type_indexes = get_func_type_indexes_reg(jit_frame); - func_type_idx = jit_cc_new_reg_I32(cc); - GEN_INSN(LDI32, func_type_idx, func_type_indexes, offset1); - - type_idx = wasm_get_smallest_type_idx(wasm_module->types, - wasm_module->type_count, type_idx); - func_type_idx1 = NEW_CONST(I32, type_idx); - GEN_INSN(CMP, cc->cmp_reg, func_type_idx, func_type_idx1); - if (!jit_emit_exception(cc, EXCE_INVALID_FUNCTION_TYPE_INDEX, JIT_OP_BNE, - cc->cmp_reg, NULL)) - goto fail; - - /* pop function arguments and store it to out area of callee stack frame */ - func_type = wasm_module->types[type_idx]; - if (!pre_call(cc, func_type)) { - goto fail; - } - - /* store elem_idx and func_idx to exec_env->jit_cache */ - GEN_INSN(STI32, elem_idx, cc->exec_env_reg, - NEW_CONST(I32, offsetof(WASMExecEnv, jit_cache))); - GEN_INSN(STI32, func_idx, cc->exec_env_reg, - NEW_CONST(I32, offsetof(WASMExecEnv, jit_cache) + 4)); - -#if WASM_ENABLE_THREAD_MGR != 0 - /* Insert suspend check point */ - if (!jit_check_suspend_flags(cc)) - goto fail; -#endif - - block_import = jit_cc_new_basic_block(cc, 0); - block_nonimport = jit_cc_new_basic_block(cc, 0); - func_return = jit_cc_new_basic_block(cc, 0); - if (!block_import || !block_nonimport || !func_return) { - goto fail; - } - - /* Commit register values to locals and stacks */ - gen_commit_values(jit_frame, jit_frame->lp, jit_frame->sp); - /* Clear frame values */ - clear_values(jit_frame); - - /* jump to block_import or block_nonimport */ - GEN_INSN(CMP, cc->cmp_reg, func_idx, - NEW_CONST(I32, cc->cur_wasm_module->import_function_count)); - GEN_INSN(BLTU, cc->cmp_reg, jit_basic_block_label(block_import), - jit_basic_block_label(block_nonimport)); - - /* block_import */ - cc->cur_basic_block = block_import; - - elem_idx = jit_cc_new_reg_I32(cc); - GEN_INSN(LDI32, elem_idx, cc->exec_env_reg, - NEW_CONST(I32, offsetof(WASMExecEnv, jit_cache))); - GEN_INSN(LDI32, func_idx, cc->exec_env_reg, - NEW_CONST(I32, offsetof(WASMExecEnv, jit_cache) + 4)); - - argv = pack_argv(cc); - if (!argv) { - goto fail; - } - native_ret = jit_cc_new_reg_I32(cc); - arg_regs[0] = cc->exec_env_reg; - arg_regs[1] = NEW_CONST(I32, tbl_idx); - arg_regs[2] = elem_idx; - arg_regs[3] = NEW_CONST(I32, type_idx); - arg_regs[4] = NEW_CONST(I32, func_type->param_cell_num); - arg_regs[5] = argv; - - import_func_ptrs = get_import_func_ptrs_reg(jit_frame); - func_import = jit_cc_new_reg_ptr(cc); - if (UINTPTR_MAX == UINT64_MAX) { - JitReg func_import_offset = jit_cc_new_reg_I32(cc); - JitReg func_import_offset_i64 = jit_cc_new_reg_I64(cc); - GEN_INSN(SHL, func_import_offset, func_idx, NEW_CONST(I32, 3)); - GEN_INSN(I32TOI64, func_import_offset_i64, func_import_offset); - GEN_INSN(LDPTR, func_import, import_func_ptrs, func_import_offset_i64); - } - else { - JitReg func_import_offset = jit_cc_new_reg_I32(cc); - GEN_INSN(SHL, func_import_offset, func_idx, NEW_CONST(I32, 2)); - GEN_INSN(LDPTR, func_import, import_func_ptrs, func_import_offset); - } - if (!jit_emit_callnative(cc, fast_jit_call_indirect, native_ret, arg_regs, - 6)) { - goto fail; - } - - /* Convert bool to uint32 */ - GEN_INSN(AND, native_ret, native_ret, NEW_CONST(I32, 0xFF)); - - /* 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, - NULL)) { - return false; - } - - /* Store res into current frame, so that post_return in - block func_return can get the value */ - n = cc->jit_frame->sp - cc->jit_frame->lp; - if (func_type->result_count > 0) { - switch (func_type->types[func_type->param_count]) { - case VALUE_TYPE_I32: -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - case VALUE_TYPE_FUNCREF: -#endif - res = jit_cc_new_reg_I32(cc); - GEN_INSN(LDI32, res, argv, NEW_CONST(I32, 0)); - GEN_INSN(STI32, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - case VALUE_TYPE_I64: - res = jit_cc_new_reg_I64(cc); - GEN_INSN(LDI64, res, argv, NEW_CONST(I32, 0)); - GEN_INSN(STI64, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - case VALUE_TYPE_F32: - res = jit_cc_new_reg_F32(cc); - GEN_INSN(LDF32, res, argv, NEW_CONST(I32, 0)); - GEN_INSN(STF32, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - case VALUE_TYPE_F64: - res = jit_cc_new_reg_F64(cc); - GEN_INSN(LDF64, res, argv, NEW_CONST(I32, 0)); - GEN_INSN(STF64, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - default: - bh_assert(0); - goto fail; - } - } - - gen_commit_values(jit_frame, jit_frame->lp, jit_frame->sp); - clear_values(jit_frame); - GEN_INSN(JMP, jit_basic_block_label(func_return)); - - /* basic_block non_import */ - cc->cur_basic_block = block_nonimport; - - GEN_INSN(LDI32, func_idx, cc->exec_env_reg, - NEW_CONST(I32, offsetof(WASMExecEnv, jit_cache) + 4)); - - /* get jitted_code */ - fast_jit_func_ptrs = get_fast_jit_func_ptrs_reg(jit_frame); - jitted_code_idx = jit_cc_new_reg_I32(cc); - jitted_code = jit_cc_new_reg_ptr(cc); - GEN_INSN(SUB, jitted_code_idx, func_idx, - NEW_CONST(I32, cc->cur_wasm_module->import_function_count)); - if (UINTPTR_MAX == UINT64_MAX) { - JitReg jitted_code_offset = jit_cc_new_reg_I32(cc); - JitReg jitted_code_offset_64 = jit_cc_new_reg_I64(cc); - GEN_INSN(SHL, jitted_code_offset, jitted_code_idx, NEW_CONST(I32, 3)); - GEN_INSN(I32TOI64, jitted_code_offset_64, jitted_code_offset); - GEN_INSN(LDPTR, jitted_code, fast_jit_func_ptrs, jitted_code_offset_64); - } - else { - JitReg jitted_code_offset = jit_cc_new_reg_I32(cc); - GEN_INSN(SHL, jitted_code_offset, jitted_code_idx, NEW_CONST(I32, 2)); - GEN_INSN(LDPTR, jitted_code, fast_jit_func_ptrs, jitted_code_offset); - } - - res = 0; - if (func_type->result_count > 0) { - switch (func_type->types[func_type->param_count]) { - case VALUE_TYPE_I32: -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - case VALUE_TYPE_FUNCREF: -#endif - res = jit_cc_new_reg_I32(cc); - break; - case VALUE_TYPE_I64: - res = jit_cc_new_reg_I64(cc); - break; - case VALUE_TYPE_F32: - res = jit_cc_new_reg_F32(cc); - break; - case VALUE_TYPE_F64: - res = jit_cc_new_reg_F64(cc); - break; - default: - bh_assert(0); - goto fail; - } - } - GEN_INSN(CALLBC, res, 0, jitted_code, func_idx); - /* Store res into current frame, so that post_return in - block func_return can get the value */ - n = cc->jit_frame->sp - cc->jit_frame->lp; - if (func_type->result_count > 0) { - switch (func_type->types[func_type->param_count]) { - case VALUE_TYPE_I32: -#if WASM_ENABLE_REF_TYPES != 0 - case VALUE_TYPE_EXTERNREF: - case VALUE_TYPE_FUNCREF: -#endif - GEN_INSN(STI32, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - case VALUE_TYPE_I64: - GEN_INSN(STI64, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - case VALUE_TYPE_F32: - GEN_INSN(STF32, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - case VALUE_TYPE_F64: - GEN_INSN(STF64, res, cc->fp_reg, - NEW_CONST(I32, offset_of_local(n))); - break; - default: - bh_assert(0); - goto fail; - } - } - /* commit and clear jit frame, then jump to block func_ret */ - gen_commit_values(jit_frame, jit_frame->lp, jit_frame->sp); - clear_values(jit_frame); - GEN_INSN(JMP, jit_basic_block_label(func_return)); - - /* translate block func_return */ - cc->cur_basic_block = func_return; - if (!post_return(cc, func_type, 0, true)) { - goto fail; - } - -#if WASM_ENABLE_THREAD_MGR != 0 - /* Insert suspend check point */ - if (!jit_check_suspend_flags(cc)) - goto fail; -#endif - - /* Clear part of memory regs and table regs as their values - may be changed in the function call */ - if (cc->cur_wasm_module->possible_memory_grow) - clear_memory_regs(cc->jit_frame); - clear_table_regs(cc->jit_frame); - return true; -fail: - return false; -} - -#if WASM_ENABLE_REF_TYPES != 0 -bool -jit_compile_op_ref_null(JitCompContext *cc, uint32 ref_type) -{ - PUSH_I32(NEW_CONST(I32, NULL_REF)); - (void)ref_type; - return true; -fail: - return false; -} - -bool -jit_compile_op_ref_is_null(JitCompContext *cc) -{ - JitReg ref, res; - - POP_I32(ref); - - GEN_INSN(CMP, cc->cmp_reg, ref, NEW_CONST(I32, NULL_REF)); - res = jit_cc_new_reg_I32(cc); - GEN_INSN(SELECTEQ, res, cc->cmp_reg, NEW_CONST(I32, 1), NEW_CONST(I32, 0)); - PUSH_I32(res); - - return true; -fail: - return false; -} - -bool -jit_compile_op_ref_func(JitCompContext *cc, uint32 func_idx) -{ - PUSH_I32(NEW_CONST(I32, func_idx)); - return true; -fail: - return false; -} -#endif - -#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) -static bool -emit_callnative(JitCompContext *cc, JitReg native_func_reg, JitReg res, - JitReg *params, uint32 param_count) -{ - JitInsn *insn; - 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 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; - - bh_assert(param_count <= 6); - - 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]); - } - - i64_reg_idx = float_reg_idx = 0; - for (i = 0; i < param_count; i++) { - switch (jit_reg_kind(params[i])) { - case JIT_REG_KIND_I32: - GEN_INSN(I32TOI64, i64_arg_regs[i64_reg_idx++], params[i]); - break; - case JIT_REG_KIND_I64: - GEN_INSN(MOV, i64_arg_regs[i64_reg_idx++], params[i]); - break; - case JIT_REG_KIND_F32: - GEN_INSN(MOV, f32_arg_regs[float_reg_idx++], params[i]); - break; - case JIT_REG_KIND_F64: - GEN_INSN(MOV, f64_arg_regs[float_reg_idx++], params[i]); - break; - default: - bh_assert(0); - return false; - } - } - - if (res) { - switch (jit_reg_kind(res)) { - case JIT_REG_KIND_I32: - res_reg = eax_hreg; - break; - case JIT_REG_KIND_I64: - res_reg = res; - break; - case JIT_REG_KIND_F32: - res_reg = xmm0_hreg; - break; - case JIT_REG_KIND_F64: - res_reg = res; - break; - default: - bh_assert(0); - return false; - } - } - - insn = GEN_INSN(CALLNATIVE, res_reg, native_func_reg, param_count); - if (!insn) { - return false; - } - - i64_reg_idx = float_reg_idx = 0; - for (i = 0; i < param_count; i++) { - switch (jit_reg_kind(params[i])) { - case JIT_REG_KIND_I32: - case JIT_REG_KIND_I64: - *(jit_insn_opndv(insn, i + 2)) = i64_arg_regs[i64_reg_idx++]; - break; - case JIT_REG_KIND_F32: - *(jit_insn_opndv(insn, i + 2)) = f32_arg_regs[float_reg_idx++]; - break; - case JIT_REG_KIND_F64: - *(jit_insn_opndv(insn, i + 2)) = f64_arg_regs[float_reg_idx++]; - break; - default: - bh_assert(0); - return false; - } - } - - if (res && res != res_reg) { - GEN_INSN(MOV, res, res_reg); - } - - return true; -} -#else -static bool -emit_callnative(JitCompContext *cc, JitRef native_func_reg, JitReg res, - JitReg *params, uint32 param_count) -{ - JitInsn *insn; - uint32 i; - - bh_assert(param_count <= 6); - - insn = GEN_INSN(CALLNATIVE, res, native_func_reg, param_count); - if (!insn) - return false; - - for (i = 0; i < param_count; i++) { - *(jit_insn_opndv(insn, i + 2)) = params[i]; - } - return true; -} -#endif - -bool -jit_emit_callnative(JitCompContext *cc, void *native_func, JitReg res, - JitReg *params, uint32 param_count) -{ - return emit_callnative(cc, NEW_CONST(PTR, (uintptr_t)native_func), res, - params, param_count); -} |