mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-06-18 02:59:21 +00:00
Add pointer reg and LDPTR/STPTR to refine the code (#1079)
And define the fixed virtual registers, create them at the beginning.
This commit is contained in:
parent
3b7bc63274
commit
d4fe9fcbdc
|
@ -4341,6 +4341,7 @@ jit_codegen_gen_native(JitCompContext *cc)
|
||||||
|
|
||||||
case JIT_OP_LDI64:
|
case JIT_OP_LDI64:
|
||||||
case JIT_OP_LDU64:
|
case JIT_OP_LDU64:
|
||||||
|
case JIT_OP_LDPTR:
|
||||||
LOAD_3ARGS();
|
LOAD_3ARGS();
|
||||||
LD_R_R_R(I64, 8, false);
|
LD_R_R_R(I64, 8, false);
|
||||||
break;
|
break;
|
||||||
|
@ -4371,6 +4372,7 @@ jit_codegen_gen_native(JitCompContext *cc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JIT_OP_STI64:
|
case JIT_OP_STI64:
|
||||||
|
case JIT_OP_STPTR:
|
||||||
LOAD_3ARGS_NO_ASSIGN();
|
LOAD_3ARGS_NO_ASSIGN();
|
||||||
ST_R_R_R(I64, int64, 8);
|
ST_R_R_R(I64, int64, 8);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -321,25 +321,14 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
|
||||||
{
|
{
|
||||||
JitReg prev_frame, prev_frame_sp;
|
JitReg prev_frame, prev_frame_sp;
|
||||||
|
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
prev_frame = jit_cc_new_reg_ptr(cc);
|
||||||
prev_frame = jit_cc_new_reg_I64(cc);
|
prev_frame_sp = jit_cc_new_reg_ptr(cc);
|
||||||
prev_frame_sp = jit_cc_new_reg_I64(cc);
|
|
||||||
|
|
||||||
/* prev_frame = cur_frame->prev_frame */
|
/* prev_frame = cur_frame->prev_frame */
|
||||||
GEN_INSN(LDI64, prev_frame, cc->fp_reg,
|
GEN_INSN(LDPTR, prev_frame, cc->fp_reg,
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
||||||
GEN_INSN(LDI64, prev_frame_sp, prev_frame,
|
GEN_INSN(LDPTR, prev_frame_sp, prev_frame,
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||||
#else
|
|
||||||
prev_frame = jit_cc_new_reg_I32(cc);
|
|
||||||
prev_frame_sp = jit_cc_new_reg_I32(cc);
|
|
||||||
|
|
||||||
/* prev_frame = cur_frame->prev_frame */
|
|
||||||
GEN_INSN(LDI32, prev_frame, cc->fp_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
|
||||||
GEN_INSN(LDI32, prev_frame_sp, prev_frame,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (block->result_count) {
|
if (block->result_count) {
|
||||||
uint32 cell_num =
|
uint32 cell_num =
|
||||||
|
@ -347,39 +336,21 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
|
||||||
|
|
||||||
copy_block_arities(cc, prev_frame_sp, block->result_types,
|
copy_block_arities(cc, prev_frame_sp, block->result_types,
|
||||||
block->result_count);
|
block->result_count);
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
|
||||||
/* prev_frame->sp += cell_num */
|
/* prev_frame->sp += cell_num */
|
||||||
GEN_INSN(ADD, prev_frame_sp, prev_frame_sp,
|
GEN_INSN(ADD, prev_frame_sp, prev_frame_sp,
|
||||||
NEW_CONST(I64, cell_num * 4));
|
NEW_CONST(PTR, cell_num * 4));
|
||||||
GEN_INSN(STI64, prev_frame_sp, prev_frame,
|
GEN_INSN(STPTR, prev_frame_sp, prev_frame,
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||||
#else
|
|
||||||
/* prev_frame->sp += cell_num */
|
|
||||||
GEN_INSN(ADD, prev_frame_sp, prev_frame_sp,
|
|
||||||
NEW_CONST(I32, cell_num * 4));
|
|
||||||
GEN_INSN(STI32, prev_frame_sp, prev_frame,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free stack space of the current frame:
|
/* Free stack space of the current frame:
|
||||||
exec_env->wasm_stack.s.top = cur_frame */
|
exec_env->wasm_stack.s.top = cur_frame */
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
GEN_INSN(STPTR, cc->fp_reg, cc->exec_env_reg,
|
||||||
GEN_INSN(STI64, cc->fp_reg, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
||||||
#else
|
|
||||||
GEN_INSN(STI32, cc->fp_reg, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
|
||||||
#endif
|
|
||||||
/* Set the prev_frame as the current frame:
|
/* Set the prev_frame as the current frame:
|
||||||
exec_env->cur_frame = prev_frame */
|
exec_env->cur_frame = prev_frame */
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
GEN_INSN(STPTR, prev_frame, cc->exec_env_reg,
|
||||||
GEN_INSN(STI64, prev_frame, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
|
NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
|
||||||
#else
|
|
||||||
GEN_INSN(STI32, prev_frame, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
|
|
||||||
#endif
|
|
||||||
/* fp_reg = prev_frame */
|
/* fp_reg = prev_frame */
|
||||||
GEN_INSN(MOV, cc->fp_reg, prev_frame);
|
GEN_INSN(MOV, cc->fp_reg, prev_frame);
|
||||||
/* return 0 */
|
/* return 0 */
|
||||||
|
@ -810,18 +781,10 @@ handle_op_br(JitCompContext *cc, uint32 br_depth, uint8 **p_frame_ip)
|
||||||
copy_arities = (block_dst->frame_sp_begin != frame_sp_src) ? true : false;
|
copy_arities = (block_dst->frame_sp_begin != frame_sp_src) ? true : false;
|
||||||
|
|
||||||
if (copy_arities) {
|
if (copy_arities) {
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
frame_sp_dst = jit_cc_new_reg_ptr(cc);
|
||||||
frame_sp_dst = jit_cc_new_reg_I64(cc);
|
|
||||||
#else
|
|
||||||
frame_sp_dst = jit_cc_new_reg_I32(cc);
|
|
||||||
#endif
|
|
||||||
offset = offsetof(WASMInterpFrame, lp)
|
offset = offsetof(WASMInterpFrame, lp)
|
||||||
+ (block_dst->frame_sp_begin - jit_frame->lp) * 4;
|
+ (block_dst->frame_sp_begin - jit_frame->lp) * 4;
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
GEN_INSN(ADD, frame_sp_dst, cc->fp_reg, NEW_CONST(PTR, offset));
|
||||||
GEN_INSN(ADD, frame_sp_dst, cc->fp_reg, NEW_CONST(I64, offset));
|
|
||||||
#else
|
|
||||||
GEN_INSN(ADD, frame_sp_dst, cc->fp_reg, NEW_CONST(I32, offset));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* No need to commit results as they will be copied to dest block */
|
/* No need to commit results as they will be copied to dest block */
|
||||||
gen_commit_values(jit_frame, jit_frame->lp, block->frame_sp_begin);
|
gen_commit_values(jit_frame, jit_frame->lp, block->frame_sp_begin);
|
||||||
|
|
|
@ -23,46 +23,25 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call)
|
||||||
JitInsn *insn;
|
JitInsn *insn;
|
||||||
uint32 i, n, outs_off, jitted_func_idx;
|
uint32 i, n, outs_off, jitted_func_idx;
|
||||||
|
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
module_inst = jit_cc_new_reg_ptr(cc);
|
||||||
module_inst = jit_cc_new_reg_I64(cc);
|
|
||||||
/* module_inst = exec_env->module_inst */
|
/* module_inst = exec_env->module_inst */
|
||||||
GEN_INSN(LDI64, module_inst, cc->exec_env_reg,
|
GEN_INSN(LDPTR, module_inst, cc->exec_env_reg,
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, module_inst)));
|
NEW_CONST(I32, offsetof(WASMExecEnv, module_inst)));
|
||||||
if (func_idx >= wasm_module->import_function_count) {
|
if (func_idx >= wasm_module->import_function_count) {
|
||||||
module = jit_cc_new_reg_I64(cc);
|
module = jit_cc_new_reg_ptr(cc);
|
||||||
func_ptrs = jit_cc_new_reg_I64(cc);
|
func_ptrs = jit_cc_new_reg_ptr(cc);
|
||||||
jitted_code = jit_cc_new_reg_I64(cc);
|
jitted_code = jit_cc_new_reg_ptr(cc);
|
||||||
/* module = module_inst->module */
|
/* module = module_inst->module */
|
||||||
GEN_INSN(LDI64, module, module_inst,
|
GEN_INSN(LDPTR, module, module_inst,
|
||||||
NEW_CONST(I32, offsetof(WASMModuleInstance, module)));
|
NEW_CONST(I32, offsetof(WASMModuleInstance, module)));
|
||||||
/* func_ptrs = module->fast_jit_func_ptrs */
|
/* func_ptrs = module->fast_jit_func_ptrs */
|
||||||
GEN_INSN(LDI64, func_ptrs, module,
|
GEN_INSN(LDPTR, func_ptrs, module,
|
||||||
NEW_CONST(I32, offsetof(WASMModule, fast_jit_func_ptrs)));
|
NEW_CONST(I32, offsetof(WASMModule, fast_jit_func_ptrs)));
|
||||||
/* jitted_code = func_ptrs[func_idx - import_function_count] */
|
/* jitted_code = func_ptrs[func_idx - import_function_count] */
|
||||||
jitted_func_idx = func_idx - wasm_module->import_function_count;
|
jitted_func_idx = func_idx - wasm_module->import_function_count;
|
||||||
GEN_INSN(LDI64, jitted_code, func_ptrs,
|
GEN_INSN(LDPTR, jitted_code, func_ptrs,
|
||||||
NEW_CONST(I32, (uint32)sizeof(void *) * jitted_func_idx));
|
NEW_CONST(I32, (uint32)sizeof(void *) * jitted_func_idx));
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
module_inst = jit_cc_new_reg_I32(cc);
|
|
||||||
GEN_INSN(LDI32, module_inst, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, module_inst)));
|
|
||||||
if (func_idx >= wasm_module->import_function_count) {
|
|
||||||
module = jit_cc_new_reg_I32(cc);
|
|
||||||
func_ptrs = jit_cc_new_reg_I32(cc);
|
|
||||||
jitted_code = jit_cc_new_reg_I32(cc);
|
|
||||||
/* module = module_inst->module */
|
|
||||||
GEN_INSN(LDI32, module, module_inst,
|
|
||||||
NEW_CONST(I32, offsetof(WASMModuleInstance, module)));
|
|
||||||
/* func_ptrs = module->fast_jit_func_ptrs */
|
|
||||||
GEN_INSN(LDI32, func_ptrs, module,
|
|
||||||
NEW_CONST(I32, offsetof(WASMModule, fast_jit_func_ptrs)));
|
|
||||||
/* jitted_code = func_ptrs[func_idx - import_function_count] */
|
|
||||||
jitted_func_idx = func_idx - wasm_module->import_function_count;
|
|
||||||
GEN_INSN(LDI32, jitted_code, func_ptrs,
|
|
||||||
NEW_CONST(I32, (uint32)sizeof(void *) * jitted_func_idx));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (func_idx < wasm_module->import_function_count) {
|
if (func_idx < wasm_module->import_function_count) {
|
||||||
func_import = &wasm_module->import_functions[func_idx].u.function;
|
func_import = &wasm_module->import_functions[func_idx].u.function;
|
||||||
|
@ -121,15 +100,8 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call)
|
||||||
#else
|
#else
|
||||||
native_ret = jit_cc_new_reg_I32(cc);
|
native_ret = jit_cc_new_reg_I32(cc);
|
||||||
#endif
|
#endif
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
insn = GEN_INSN(CALLNATIVE, native_ret,
|
||||||
insn =
|
NEW_CONST(PTR, (uintptr_t)jit_invoke_native), 3);
|
||||||
GEN_INSN(CALLNATIVE, native_ret,
|
|
||||||
NEW_CONST(I64, (uint64)(uintptr_t)jit_invoke_native), 3);
|
|
||||||
#else
|
|
||||||
insn =
|
|
||||||
GEN_INSN(CALLNATIVE, native_ret,
|
|
||||||
NEW_CONST(I32, (uint32)(uintptr_t)jit_invoke_native), 3);
|
|
||||||
#endif
|
|
||||||
if (insn) {
|
if (insn) {
|
||||||
*(jit_insn_opndv(insn, 2)) = cc->exec_env_reg;
|
*(jit_insn_opndv(insn, 2)) = cc->exec_env_reg;
|
||||||
*(jit_insn_opndv(insn, 3)) = NEW_CONST(I32, func_idx);
|
*(jit_insn_opndv(insn, 3)) = NEW_CONST(I32, func_idx);
|
||||||
|
|
|
@ -146,30 +146,17 @@ gen_commit_sp_ip(JitFrame *frame)
|
||||||
JitReg sp;
|
JitReg sp;
|
||||||
|
|
||||||
if (frame->sp != frame->committed_sp) {
|
if (frame->sp != frame->committed_sp) {
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
sp = jit_cc_new_reg_ptr(cc);
|
||||||
sp = jit_cc_new_reg_I64(cc);
|
|
||||||
GEN_INSN(ADD, sp, cc->fp_reg,
|
GEN_INSN(ADD, sp, cc->fp_reg,
|
||||||
NEW_CONST(I64, offset_of_local(frame->sp - frame->lp)));
|
NEW_CONST(PTR, offset_of_local(frame->sp - frame->lp)));
|
||||||
GEN_INSN(STI64, sp, cc->fp_reg,
|
GEN_INSN(STPTR, sp, cc->fp_reg,
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||||
#else
|
|
||||||
sp = jit_cc_new_reg_I32(cc);
|
|
||||||
GEN_INSN(ADD, sp, cc->fp_reg,
|
|
||||||
NEW_CONST(I32, offset_of_local(frame->sp - frame->lp)));
|
|
||||||
GEN_INSN(STI32, sp, cc->fp_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
|
||||||
#endif
|
|
||||||
frame->committed_sp = frame->sp;
|
frame->committed_sp = frame->sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame->ip != frame->committed_ip) {
|
if (frame->ip != frame->committed_ip) {
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
GEN_INSN(STPTR, NEW_CONST(PTR, (uintptr_t)frame->ip), cc->fp_reg,
|
||||||
GEN_INSN(STI64, NEW_CONST(I64, (uint64)(uintptr_t)frame->ip),
|
NEW_CONST(I32, offsetof(WASMInterpFrame, ip)));
|
||||||
cc->fp_reg, NEW_CONST(I32, offsetof(WASMInterpFrame, ip)));
|
|
||||||
#else
|
|
||||||
GEN_INSN(STI32, NEW_CONST(I32, (uint32)(uintptr_t)frame->ip),
|
|
||||||
cc->fp_reg, NEW_CONST(I32, offsetof(WASMInterpFrame, ip)));
|
|
||||||
#endif
|
|
||||||
frame->committed_ip = frame->ip;
|
frame->committed_ip = frame->ip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,6 +170,56 @@ jit_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id)
|
||||||
wasm_set_exception(module_inst, "unknown exception");
|
wasm_set_exception(module_inst, "unknown exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
create_fix_virtual_regs(JitCompContext *cc)
|
||||||
|
{
|
||||||
|
WASMModule *module = cc->cur_wasm_module;
|
||||||
|
uint64 total_size;
|
||||||
|
uint32 i, count;
|
||||||
|
|
||||||
|
cc->module_inst_reg = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->module_reg = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->func_ptrs_reg = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->global_data_reg = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->aux_stack_bound_reg = jit_cc_new_reg_I32(cc);
|
||||||
|
cc->aux_stack_bottom_reg = jit_cc_new_reg_I32(cc);
|
||||||
|
|
||||||
|
count = module->import_memory_count + module->memory_count;
|
||||||
|
total_size = (uint64)sizeof(JitMemRegs) * count;
|
||||||
|
if (total_size > UINT32_MAX
|
||||||
|
|| !(cc->memory_regs = jit_calloc((uint32)total_size))) {
|
||||||
|
jit_set_last_error(cc, "allocate memory failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
cc->memory_regs[i].memory_inst = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->memory_regs[i].memory_data = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->memory_regs[i].memory_data_end = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->memory_regs[i].mem_bound_check_1byte = jit_cc_new_reg_I32(cc);
|
||||||
|
cc->memory_regs[i].mem_bound_check_2bytes = jit_cc_new_reg_I32(cc);
|
||||||
|
cc->memory_regs[i].mem_bound_check_4bytes = jit_cc_new_reg_I32(cc);
|
||||||
|
cc->memory_regs[i].mem_bound_check_8bytes = jit_cc_new_reg_I32(cc);
|
||||||
|
cc->memory_regs[i].mem_bound_check_16bytes = jit_cc_new_reg_I32(cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
count = module->import_table_count + module->table_count;
|
||||||
|
total_size = (uint64)sizeof(JitTableRegs) * count;
|
||||||
|
if (total_size > UINT32_MAX
|
||||||
|
|| !(cc->table_regs = jit_calloc((uint32)total_size))) {
|
||||||
|
jit_set_last_error(cc, "allocate memory failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
cc->table_regs[i].table_inst = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->table_regs[i].table_data = jit_cc_new_reg_ptr(cc);
|
||||||
|
cc->table_regs[i].table_cur_size = jit_cc_new_reg_I32(cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
form_and_translate_func(JitCompContext *cc)
|
form_and_translate_func(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
@ -192,6 +229,9 @@ form_and_translate_func(JitCompContext *cc)
|
||||||
JitIncomingInsn *incoming_insn, *incoming_insn_next;
|
JitIncomingInsn *incoming_insn, *incoming_insn_next;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
|
if (!create_fix_virtual_regs(cc))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!(func_entry_basic_block = jit_frontend_translate_func(cc)))
|
if (!(func_entry_basic_block = jit_frontend_translate_func(cc)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -231,19 +271,9 @@ form_and_translate_func(JitCompContext *cc)
|
||||||
}
|
}
|
||||||
cc->cur_basic_block = cc->exce_basic_blocks[i];
|
cc->cur_basic_block = cc->exce_basic_blocks[i];
|
||||||
if (i != EXCE_ALREADY_THROWN) {
|
if (i != EXCE_ALREADY_THROWN) {
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
|
||||||
insn = GEN_INSN(
|
insn = GEN_INSN(
|
||||||
CALLNATIVE, 0,
|
CALLNATIVE, 0,
|
||||||
NEW_CONST(I64,
|
NEW_CONST(PTR, (uintptr_t)jit_set_exception_with_id), 1);
|
||||||
(uint64)(uintptr_t)jit_set_exception_with_id),
|
|
||||||
1);
|
|
||||||
#else
|
|
||||||
insn = GEN_INSN(
|
|
||||||
CALLNATIVE, 0,
|
|
||||||
NEW_CONST(I32,
|
|
||||||
(uint32)(uintptr_t)jit_set_exception_with_id),
|
|
||||||
1);
|
|
||||||
#endif
|
|
||||||
if (insn) {
|
if (insn) {
|
||||||
*(jit_insn_opndv(insn, 2)) = NEW_CONST(I32, i);
|
*(jit_insn_opndv(insn, 2)) = NEW_CONST(I32, i);
|
||||||
}
|
}
|
||||||
|
@ -343,21 +373,20 @@ init_func_translation(JitCompContext *cc)
|
||||||
local_size =
|
local_size =
|
||||||
(cur_wasm_func->param_cell_num + cur_wasm_func->local_cell_num) * 4;
|
(cur_wasm_func->param_cell_num + cur_wasm_func->local_cell_num) * 4;
|
||||||
|
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
top = jit_cc_new_reg_ptr(cc);
|
||||||
top = jit_cc_new_reg_I64(cc);
|
top_boundary = jit_cc_new_reg_ptr(cc);
|
||||||
top_boundary = jit_cc_new_reg_I64(cc);
|
new_top = jit_cc_new_reg_ptr(cc);
|
||||||
new_top = jit_cc_new_reg_I64(cc);
|
frame_boundary = jit_cc_new_reg_ptr(cc);
|
||||||
frame_boundary = jit_cc_new_reg_I64(cc);
|
frame_sp = jit_cc_new_reg_ptr(cc);
|
||||||
frame_sp = jit_cc_new_reg_I64(cc);
|
|
||||||
|
|
||||||
/* top = exec_env->wasm_stack.s.top */
|
/* top = exec_env->wasm_stack.s.top */
|
||||||
GEN_INSN(LDI64, top, cc->exec_env_reg,
|
GEN_INSN(LDPTR, top, cc->exec_env_reg,
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
||||||
/* top_boundary = exec_env->wasm_stack.s.top_boundary */
|
/* top_boundary = exec_env->wasm_stack.s.top_boundary */
|
||||||
GEN_INSN(LDI64, top_boundary, cc->exec_env_reg,
|
GEN_INSN(LDPTR, top_boundary, cc->exec_env_reg,
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top_boundary)));
|
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top_boundary)));
|
||||||
/* frame_boundary = top + frame_size + outs_size */
|
/* frame_boundary = top + frame_size + outs_size */
|
||||||
GEN_INSN(ADD, frame_boundary, top, NEW_CONST(I64, frame_size + outs_size));
|
GEN_INSN(ADD, frame_boundary, top, NEW_CONST(PTR, frame_size + outs_size));
|
||||||
/* if frame_boundary > top_boundary, throw stack overflow exception */
|
/* if frame_boundary > top_boundary, throw stack overflow exception */
|
||||||
GEN_INSN(CMP, cc->cmp_reg, frame_boundary, top_boundary);
|
GEN_INSN(CMP, cc->cmp_reg, frame_boundary, top_boundary);
|
||||||
if (!jit_emit_exception(cc, EXCE_OPERAND_STACK_OVERFLOW, JIT_OP_BGTU,
|
if (!jit_emit_exception(cc, EXCE_OPERAND_STACK_OVERFLOW, JIT_OP_BGTU,
|
||||||
|
@ -367,77 +396,29 @@ init_func_translation(JitCompContext *cc)
|
||||||
|
|
||||||
/* Add first and then sub to reduce one used register */
|
/* Add first and then sub to reduce one used register */
|
||||||
/* new_top = frame_boundary - outs_size = top + frame_size */
|
/* new_top = frame_boundary - outs_size = top + frame_size */
|
||||||
GEN_INSN(SUB, new_top, frame_boundary, NEW_CONST(I64, outs_size));
|
GEN_INSN(SUB, new_top, frame_boundary, NEW_CONST(PTR, outs_size));
|
||||||
/* exec_env->wasm_stack.s.top = new_top */
|
/* exec_env->wasm_stack.s.top = new_top */
|
||||||
GEN_INSN(STI64, new_top, cc->exec_env_reg,
|
GEN_INSN(STPTR, new_top, cc->exec_env_reg,
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
||||||
/* frame_sp = frame->lp + local_size */
|
/* frame_sp = frame->lp + local_size */
|
||||||
GEN_INSN(ADD, frame_sp, top,
|
GEN_INSN(ADD, frame_sp, top,
|
||||||
NEW_CONST(I64, offsetof(WASMInterpFrame, lp) + local_size));
|
NEW_CONST(PTR, offsetof(WASMInterpFrame, lp) + local_size));
|
||||||
/* frame->sp = frame_sp */
|
/* frame->sp = frame_sp */
|
||||||
GEN_INSN(STI64, frame_sp, top,
|
GEN_INSN(STPTR, frame_sp, top,
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||||
/* frame->prev_frame = fp_reg */
|
/* frame->prev_frame = fp_reg */
|
||||||
GEN_INSN(STI64, cc->fp_reg, top,
|
GEN_INSN(STPTR, cc->fp_reg, top,
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
||||||
/* TODO: do we need to set frame->function? */
|
/* TODO: do we need to set frame->function? */
|
||||||
/*
|
/*
|
||||||
GEN_INSN(STI64, func_inst, top,
|
GEN_INSN(STPTR, func_inst, top,
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, function)));
|
NEW_CONST(I32, offsetof(WASMInterpFrame, function)));
|
||||||
*/
|
*/
|
||||||
/* exec_env->cur_frame = top */
|
/* exec_env->cur_frame = top */
|
||||||
GEN_INSN(STI64, top, cc->exec_env_reg,
|
GEN_INSN(STPTR, top, cc->exec_env_reg,
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
|
NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
|
||||||
/* fp_reg = top */
|
/* fp_reg = top */
|
||||||
GEN_INSN(MOV, cc->fp_reg, top);
|
GEN_INSN(MOV, cc->fp_reg, top);
|
||||||
#else
|
|
||||||
top = jit_cc_new_reg_I32(cc);
|
|
||||||
top_boundary = jit_cc_new_reg_I32(cc);
|
|
||||||
new_top = jit_cc_new_reg_I32(cc);
|
|
||||||
frame_boundary = jit_cc_new_reg_I32(cc);
|
|
||||||
frame_sp = jit_cc_new_reg_I32(cc);
|
|
||||||
|
|
||||||
/* top = exec_env->wasm_stack.s.top */
|
|
||||||
GEN_INSN(LDI32, top, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
|
||||||
/* top_boundary = exec_env->wasm_stack.s.top_boundary */
|
|
||||||
GEN_INSN(LDI32, top_boundary, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top_boundary)));
|
|
||||||
/* frame_boundary = top + frame_size + outs_size */
|
|
||||||
GEN_INSN(ADD, frame_boundary, top, NEW_CONST(I32, frame_size + outs_size));
|
|
||||||
/* 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)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add first and then sub to reduce one used register */
|
|
||||||
/* new_top = frame_boundary - outs_size = top + frame_size */
|
|
||||||
GEN_INSN(SUB, new_top, frame_boundary, NEW_CONST(I32, outs_size));
|
|
||||||
/* exec_env->wasm_stack.s.top = new_top */
|
|
||||||
GEN_INSN(STI32, new_top, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
|
|
||||||
/* frame_sp = frame->lp + local_size */
|
|
||||||
GEN_INSN(ADD, frame_sp, top,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, lp) + local_size));
|
|
||||||
/* frame->sp = frame_sp */
|
|
||||||
GEN_INSN(STI32, frame_sp, top,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
|
||||||
/* frame->prev_frame = fp_reg */
|
|
||||||
GEN_INSN(STI32, cc->fp_reg, top,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
|
|
||||||
/* TODO: do we need to set frame->function? */
|
|
||||||
/*
|
|
||||||
GEN_INSN(STI32, func_inst, top,
|
|
||||||
NEW_CONST(I32, offsetof(WASMInterpFrame, function)));
|
|
||||||
*/
|
|
||||||
/* exec_env->cur_frame = top */
|
|
||||||
GEN_INSN(STI32, top, cc->exec_env_reg,
|
|
||||||
NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
|
|
||||||
/* fp_reg = top */
|
|
||||||
GEN_INSN(MOV, cc->fp_reg, top);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return jit_frame;
|
return jit_frame;
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,15 +444,9 @@ jit_cc_init(JitCompContext *cc, unsigned htab_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create registers for frame pointer, exec_env and cmp. */
|
/* Create registers for frame pointer, exec_env and cmp. */
|
||||||
#if UINTPTR_MAX == UINT64_MAX
|
cc->fp_reg = jit_reg_new(JIT_REG_KIND_PTR, cc->hreg_info->fp_hreg_index);
|
||||||
cc->fp_reg = jit_reg_new(JIT_REG_KIND_I64, cc->hreg_info->fp_hreg_index);
|
|
||||||
cc->exec_env_reg =
|
cc->exec_env_reg =
|
||||||
jit_reg_new(JIT_REG_KIND_I64, cc->hreg_info->exec_env_hreg_index);
|
jit_reg_new(JIT_REG_KIND_PTR, cc->hreg_info->exec_env_hreg_index);
|
||||||
#else
|
|
||||||
cc->fp_reg = jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->fp_hreg_index);
|
|
||||||
cc->exec_env_reg =
|
|
||||||
jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->exec_env_hreg_index);
|
|
||||||
#endif
|
|
||||||
cc->cmp_reg = jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->cmp_hreg_index);
|
cc->cmp_reg = jit_reg_new(JIT_REG_KIND_I32, cc->hreg_info->cmp_hreg_index);
|
||||||
|
|
||||||
cc->_const_val._hash_table_size = htab_size;
|
cc->_const_val._hash_table_size = htab_size;
|
||||||
|
@ -477,7 +471,19 @@ jit_cc_destroy(JitCompContext *cc)
|
||||||
|
|
||||||
jit_block_stack_destroy(&cc->block_stack);
|
jit_block_stack_destroy(&cc->block_stack);
|
||||||
|
|
||||||
|
if (cc->jit_frame) {
|
||||||
|
if (cc->jit_frame->memory_regs)
|
||||||
|
jit_free(cc->jit_frame->memory_regs);
|
||||||
|
if (cc->jit_frame->table_regs)
|
||||||
|
jit_free(cc->jit_frame->table_regs);
|
||||||
jit_free(cc->jit_frame);
|
jit_free(cc->jit_frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cc->memory_regs)
|
||||||
|
jit_free(cc->memory_regs);
|
||||||
|
|
||||||
|
if (cc->table_regs)
|
||||||
|
jit_free(cc->table_regs);
|
||||||
|
|
||||||
jit_free(cc->_const_val._hash_table);
|
jit_free(cc->_const_val._hash_table);
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@ INSN(LDI64, Reg, 3, 1)
|
||||||
INSN(LDU64, Reg, 3, 1)
|
INSN(LDU64, Reg, 3, 1)
|
||||||
INSN(LDF32, Reg, 3, 1)
|
INSN(LDF32, Reg, 3, 1)
|
||||||
INSN(LDF64, Reg, 3, 1)
|
INSN(LDF64, Reg, 3, 1)
|
||||||
|
INSN(LDPTR, Reg, 3, 1)
|
||||||
INSN(LDV64, Reg, 3, 1)
|
INSN(LDV64, Reg, 3, 1)
|
||||||
INSN(LDV128, Reg, 3, 1)
|
INSN(LDV128, Reg, 3, 1)
|
||||||
INSN(LDV256, Reg, 3, 1)
|
INSN(LDV256, Reg, 3, 1)
|
||||||
|
@ -146,6 +147,7 @@ INSN(STI32, Reg, 3, 0)
|
||||||
INSN(STI64, Reg, 3, 0)
|
INSN(STI64, Reg, 3, 0)
|
||||||
INSN(STF32, Reg, 3, 0)
|
INSN(STF32, Reg, 3, 0)
|
||||||
INSN(STF64, Reg, 3, 0)
|
INSN(STF64, Reg, 3, 0)
|
||||||
|
INSN(STPTR, Reg, 3, 0)
|
||||||
INSN(STV64, Reg, 3, 1)
|
INSN(STV64, Reg, 3, 1)
|
||||||
INSN(STV128, Reg, 3, 1)
|
INSN(STV128, Reg, 3, 1)
|
||||||
INSN(STV256, Reg, 3, 1)
|
INSN(STV256, Reg, 3, 1)
|
||||||
|
|
|
@ -118,6 +118,12 @@ typedef enum JitRegKind {
|
||||||
JIT_REG_KIND_NUM /* number of register kinds */
|
JIT_REG_KIND_NUM /* number of register kinds */
|
||||||
} JitRegKind;
|
} JitRegKind;
|
||||||
|
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
#define JIT_REG_KIND_PTR JIT_REG_KIND_I64
|
||||||
|
#else
|
||||||
|
#define JIT_REG_KIND_PTR JIT_REG_KIND_I32
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new JIT IR register from the kind and no.
|
* Construct a new JIT IR register from the kind and no.
|
||||||
*
|
*
|
||||||
|
@ -890,6 +896,27 @@ typedef struct JitValueSlot {
|
||||||
uint32 committed_ref : 2;
|
uint32 committed_ref : 2;
|
||||||
} JitValueSlot;
|
} JitValueSlot;
|
||||||
|
|
||||||
|
typedef struct JitMemRegs {
|
||||||
|
JitReg memory_inst;
|
||||||
|
/* The following registers should be re-loaded after memory.grow,
|
||||||
|
and callbc, callnative */
|
||||||
|
JitReg memory_data;
|
||||||
|
JitReg memory_data_end;
|
||||||
|
JitReg mem_bound_check_1byte;
|
||||||
|
JitReg mem_bound_check_2bytes;
|
||||||
|
JitReg mem_bound_check_4bytes;
|
||||||
|
JitReg mem_bound_check_8bytes;
|
||||||
|
JitReg mem_bound_check_16bytes;
|
||||||
|
} JitMemRegs;
|
||||||
|
|
||||||
|
typedef struct JitTableRegs {
|
||||||
|
JitReg table_inst;
|
||||||
|
JitReg table_data;
|
||||||
|
/* Should be re-loaded after table.grow,
|
||||||
|
and callbc, callnative */
|
||||||
|
JitReg table_cur_size;
|
||||||
|
} JitTableRegs;
|
||||||
|
|
||||||
/* Frame information for translation */
|
/* Frame information for translation */
|
||||||
typedef struct JitFrame {
|
typedef struct JitFrame {
|
||||||
/* The current wasm module */
|
/* The current wasm module */
|
||||||
|
@ -919,6 +946,23 @@ typedef struct JitFrame {
|
||||||
/* Committed stack top pointer */
|
/* Committed stack top pointer */
|
||||||
JitValueSlot *committed_sp;
|
JitValueSlot *committed_sp;
|
||||||
|
|
||||||
|
/* WASM module instance */
|
||||||
|
JitReg module_inst_reg;
|
||||||
|
/* WASM module */
|
||||||
|
JitReg module_reg;
|
||||||
|
/* module->fast_jit_func_ptrs */
|
||||||
|
JitReg func_ptrs_reg;
|
||||||
|
/* Base address of global data */
|
||||||
|
JitReg global_data_reg;
|
||||||
|
/* Boundary of auxiliary stack */
|
||||||
|
JitReg aux_stack_bound_reg;
|
||||||
|
/* Bottom of auxiliary stack */
|
||||||
|
JitReg aux_stack_bottom_reg;
|
||||||
|
/* Data of memory instances */
|
||||||
|
JitMemRegs *memory_regs;
|
||||||
|
/* Data of table instances */
|
||||||
|
JitTableRegs *table_regs;
|
||||||
|
|
||||||
/* Local variables */
|
/* Local variables */
|
||||||
JitValueSlot lp[1];
|
JitValueSlot lp[1];
|
||||||
} JitFrame;
|
} JitFrame;
|
||||||
|
@ -1015,6 +1059,23 @@ typedef struct JitCompContext {
|
||||||
JitReg exec_env_reg;
|
JitReg exec_env_reg;
|
||||||
JitReg cmp_reg;
|
JitReg cmp_reg;
|
||||||
|
|
||||||
|
/* WASM module instance */
|
||||||
|
JitReg module_inst_reg;
|
||||||
|
/* WASM module */
|
||||||
|
JitReg module_reg;
|
||||||
|
/* module->fast_jit_func_ptrs */
|
||||||
|
JitReg func_ptrs_reg;
|
||||||
|
/* Base address of global data */
|
||||||
|
JitReg global_data_reg;
|
||||||
|
/* Boundary of auxiliary stack */
|
||||||
|
JitReg aux_stack_bound_reg;
|
||||||
|
/* Bottom of auxiliary stack */
|
||||||
|
JitReg aux_stack_bottom_reg;
|
||||||
|
/* Data of memory instances */
|
||||||
|
JitMemRegs *memory_regs;
|
||||||
|
/* Data of table instances */
|
||||||
|
JitTableRegs *table_regs;
|
||||||
|
|
||||||
/* Current frame information for translation */
|
/* Current frame information for translation */
|
||||||
JitFrame *jit_frame;
|
JitFrame *jit_frame;
|
||||||
|
|
||||||
|
@ -1291,6 +1352,12 @@ jit_cc_new_const_I32(JitCompContext *cc, int32 val)
|
||||||
JitReg
|
JitReg
|
||||||
jit_cc_new_const_I64(JitCompContext *cc, int64 val);
|
jit_cc_new_const_I64(JitCompContext *cc, int64 val);
|
||||||
|
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
#define jit_cc_new_const_PTR jit_cc_new_const_I64
|
||||||
|
#else
|
||||||
|
#define jit_cc_new_const_PTR jit_cc_new_const_I32
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a F32 constant value into the compilation context.
|
* Create a F32 constant value into the compilation context.
|
||||||
*
|
*
|
||||||
|
@ -1623,6 +1690,12 @@ jit_cc_new_reg_I64(JitCompContext *cc)
|
||||||
return jit_cc_new_reg(cc, JIT_REG_KIND_I64);
|
return jit_cc_new_reg(cc, JIT_REG_KIND_I64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if UINTPTR_MAX == UINT64_MAX
|
||||||
|
#define jit_cc_new_reg_ptr jit_cc_new_reg_I64
|
||||||
|
#else
|
||||||
|
#define jit_cc_new_reg_ptr jit_cc_new_reg_I32
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline JitReg
|
static inline JitReg
|
||||||
jit_cc_new_reg_F32(JitCompContext *cc)
|
jit_cc_new_reg_F32(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user