From f1f674bc8d1bcb67449ac5428b10a7aa0387346a Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Thu, 14 Apr 2022 14:07:37 +0800 Subject: [PATCH] Emit JIT IRs for get/set wasm globals (#1085) WASM_OP_SET_GLOBAL_AUX_STACK is unsupported currently --- core/iwasm/fast-jit/fe/jit_emit_variable.c | 129 +++++++++++++++++++++ core/iwasm/interpreter/wasm.h | 8 ++ core/iwasm/interpreter/wasm_loader.c | 24 ++++ 3 files changed, 161 insertions(+) diff --git a/core/iwasm/fast-jit/fe/jit_emit_variable.c b/core/iwasm/fast-jit/fe/jit_emit_variable.c index 20c17a334..0ef0b9419 100644 --- a/core/iwasm/fast-jit/fe/jit_emit_variable.c +++ b/core/iwasm/fast-jit/fe/jit_emit_variable.c @@ -161,9 +161,82 @@ fail: return false; } +static uint8 +get_global_type(const WASMModule *module, uint32 global_idx) +{ + return module->globals[global_idx].type; +} + +static uint32 +get_global_data_offset(const WASMModule *module, uint32 global_idx) +{ + if (global_idx < module->import_global_count) { + const WASMGlobalImport *import_global = + &((module->import_globals + global_idx)->u.global); + return import_global->data_offset; + } + else { + const WASMGlobal *global = module->globals + global_idx; + return global->data_offset; + } +} + bool jit_compile_op_get_global(JitCompContext *cc, uint32 global_idx) { + uint32 data_offset; + uint8 global_type = 0; + JitReg value = 0; + + bh_assert(global_idx < cc->cur_wasm_module->import_global_count + + cc->cur_wasm_module->global_count); + + data_offset = get_global_data_offset(cc->cur_wasm_module, global_idx); + global_type = get_global_type(cc->cur_wasm_module, global_idx); + switch (global_type) { + case VALUE_TYPE_I32: +#if WASM_ENABLE_REF_TYPES != 0 + case VALUE_TYPE_EXTERNREF: + case VALUE_TYPE_FUNCREF: +#endif + { + value = jit_cc_new_reg_I32(cc); + GEN_INSN(LDI32, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + case VALUE_TYPE_I64: + { + value = jit_cc_new_reg_I64(cc); + GEN_INSN(LDI64, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + case VALUE_TYPE_F32: + { + value = jit_cc_new_reg_F32(cc); + GEN_INSN(LDF32, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + case VALUE_TYPE_F64: + { + value = jit_cc_new_reg_F64(cc); + GEN_INSN(LDF64, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + default: + { + jit_set_last_error(cc, "unexpected global type"); + goto fail; + } + } + + PUSH(value, global_type); + + return true; +fail: return false; } @@ -171,5 +244,61 @@ bool jit_compile_op_set_global(JitCompContext *cc, uint32 global_idx, bool is_aux_stack) { + uint32 data_offset; + uint8 global_type = 0; + JitReg value = 0; + + if (is_aux_stack) { + jit_set_last_error(cc, "doesn't support set global_aux_stack"); + goto fail; + } + + bh_assert(global_idx < cc->cur_wasm_module->import_global_count + + cc->cur_wasm_module->global_count); + + data_offset = get_global_data_offset(cc->cur_wasm_module, global_idx); + global_type = get_global_type(cc->cur_wasm_module, global_idx); + switch (global_type) { + case VALUE_TYPE_I32: +#if WASM_ENABLE_REF_TYPES != 0 + case VALUE_TYPE_EXTERNREF: + case VALUE_TYPE_FUNCREF: +#endif + { + POP_I32(value); + GEN_INSN(STI32, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + case VALUE_TYPE_I64: + { + POP_I64(value); + GEN_INSN(STI64, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + case VALUE_TYPE_F32: + { + POP_F32(value); + GEN_INSN(STF32, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + case VALUE_TYPE_F64: + { + POP_F64(value); + GEN_INSN(STF64, value, get_global_data_reg(cc->jit_frame), + NEW_CONST(I32, data_offset)); + break; + } + default: + { + jit_set_last_error(cc, "unexpected global type"); + goto fail; + } + } + + return true; +fail: return false; } diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 074eec23a..89ec5aa34 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -204,6 +204,10 @@ typedef struct WASMGlobalImport { WASMModule *import_module; WASMGlobal *import_global_linked; #endif +#if WASM_ENABLE_FAST_JIT != 0 + /* The data offset of current global in global data */ + uint32 data_offset; +#endif } WASMGlobalImport; typedef struct WASMImport { @@ -263,6 +267,10 @@ struct WASMGlobal { uint8 type; bool is_mutable; InitializerExpression init_expr; +#if WASM_ENABLE_FAST_JIT != 0 + /* The data offset of current global in global data */ + uint32 data_offset; +#endif }; typedef struct WASMExport { diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index d54f63a02..1886fc14d 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -2851,6 +2851,28 @@ fail: return false; } +#if WASM_ENABLE_FAST_JIT != 0 +static void +calculate_global_data_offset(WASMModule *module) +{ + uint32 i, data_offset; + + data_offset = 0; + for (i = 0; i < module->import_global_count; i++) { + WASMGlobalImport *import_global = + &((module->import_globals + i)->u.global); + import_global->data_offset = data_offset; + data_offset += wasm_value_type_size(import_global->type); + } + + for (i = 0; i < module->global_count; i++) { + WASMGlobal *global = module->globals + i; + global->data_offset = data_offset; + data_offset += wasm_value_type_size(global->type); + } +} +#endif + static bool wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func, uint32 cur_func_idx, char *error_buf, @@ -3239,6 +3261,8 @@ load_from_sections(WASMModule *module, WASMSection *sections, } #if WASM_ENABLE_FAST_JIT != 0 + calculate_global_data_offset(module); + if (!(module->fast_jit_func_ptrs = loader_malloc(sizeof(void *) * module->function_count, error_buf, error_buf_size))) {