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_LDU64:
|
||||
case JIT_OP_LDPTR:
|
||||
LOAD_3ARGS();
|
||||
LD_R_R_R(I64, 8, false);
|
||||
break;
|
||||
|
@ -4371,6 +4372,7 @@ jit_codegen_gen_native(JitCompContext *cc)
|
|||
break;
|
||||
|
||||
case JIT_OP_STI64:
|
||||
case JIT_OP_STPTR:
|
||||
LOAD_3ARGS_NO_ASSIGN();
|
||||
ST_R_R_R(I64, int64, 8);
|
||||
break;
|
||||
|
|
|
@ -321,25 +321,14 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
|
|||
{
|
||||
JitReg prev_frame, prev_frame_sp;
|
||||
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
prev_frame = jit_cc_new_reg_I64(cc);
|
||||
prev_frame_sp = jit_cc_new_reg_I64(cc);
|
||||
prev_frame = jit_cc_new_reg_ptr(cc);
|
||||
prev_frame_sp = jit_cc_new_reg_ptr(cc);
|
||||
|
||||
/* 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)));
|
||||
GEN_INSN(LDI64, prev_frame_sp, prev_frame,
|
||||
GEN_INSN(LDPTR, prev_frame_sp, prev_frame,
|
||||
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) {
|
||||
uint32 cell_num =
|
||||
|
@ -347,39 +336,21 @@ handle_func_return(JitCompContext *cc, JitBlock *block)
|
|||
|
||||
copy_block_arities(cc, prev_frame_sp, block->result_types,
|
||||
block->result_count);
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
/* prev_frame->sp += cell_num */
|
||||
GEN_INSN(ADD, prev_frame_sp, prev_frame_sp,
|
||||
NEW_CONST(I64, cell_num * 4));
|
||||
GEN_INSN(STI64, prev_frame_sp, prev_frame,
|
||||
NEW_CONST(PTR, cell_num * 4));
|
||||
GEN_INSN(STPTR, prev_frame_sp, prev_frame,
|
||||
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:
|
||||
exec_env->wasm_stack.s.top = cur_frame */
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
GEN_INSN(STI64, cc->fp_reg, cc->exec_env_reg,
|
||||
GEN_INSN(STPTR, cc->fp_reg, cc->exec_env_reg,
|
||||
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:
|
||||
exec_env->cur_frame = prev_frame */
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
GEN_INSN(STI64, prev_frame, cc->exec_env_reg,
|
||||
GEN_INSN(STPTR, prev_frame, cc->exec_env_reg,
|
||||
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 */
|
||||
GEN_INSN(MOV, cc->fp_reg, prev_frame);
|
||||
/* 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;
|
||||
|
||||
if (copy_arities) {
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
frame_sp_dst = jit_cc_new_reg_I64(cc);
|
||||
#else
|
||||
frame_sp_dst = jit_cc_new_reg_I32(cc);
|
||||
#endif
|
||||
frame_sp_dst = jit_cc_new_reg_ptr(cc);
|
||||
offset = offsetof(WASMInterpFrame, lp)
|
||||
+ (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(I64, offset));
|
||||
#else
|
||||
GEN_INSN(ADD, frame_sp_dst, cc->fp_reg, NEW_CONST(I32, offset));
|
||||
#endif
|
||||
GEN_INSN(ADD, frame_sp_dst, cc->fp_reg, NEW_CONST(PTR, offset));
|
||||
|
||||
/* 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);
|
||||
|
|
|
@ -23,46 +23,25 @@ jit_compile_op_call(JitCompContext *cc, uint32 func_idx, bool tail_call)
|
|||
JitInsn *insn;
|
||||
uint32 i, n, outs_off, jitted_func_idx;
|
||||
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
module_inst = jit_cc_new_reg_I64(cc);
|
||||
module_inst = jit_cc_new_reg_ptr(cc);
|
||||
/* 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)));
|
||||
if (func_idx >= wasm_module->import_function_count) {
|
||||
module = jit_cc_new_reg_I64(cc);
|
||||
func_ptrs = jit_cc_new_reg_I64(cc);
|
||||
jitted_code = jit_cc_new_reg_I64(cc);
|
||||
module = jit_cc_new_reg_ptr(cc);
|
||||
func_ptrs = jit_cc_new_reg_ptr(cc);
|
||||
jitted_code = jit_cc_new_reg_ptr(cc);
|
||||
/* module = module_inst->module */
|
||||
GEN_INSN(LDI64, module, module_inst,
|
||||
GEN_INSN(LDPTR, module, module_inst,
|
||||
NEW_CONST(I32, offsetof(WASMModuleInstance, module)));
|
||||
/* 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)));
|
||||
/* jitted_code = func_ptrs[func_idx - 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));
|
||||
}
|
||||
#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) {
|
||||
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
|
||||
native_ret = jit_cc_new_reg_I32(cc);
|
||||
#endif
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
insn =
|
||||
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
|
||||
insn = GEN_INSN(CALLNATIVE, native_ret,
|
||||
NEW_CONST(PTR, (uintptr_t)jit_invoke_native), 3);
|
||||
if (insn) {
|
||||
*(jit_insn_opndv(insn, 2)) = cc->exec_env_reg;
|
||||
*(jit_insn_opndv(insn, 3)) = NEW_CONST(I32, func_idx);
|
||||
|
|
|
@ -146,30 +146,17 @@ gen_commit_sp_ip(JitFrame *frame)
|
|||
JitReg sp;
|
||||
|
||||
if (frame->sp != frame->committed_sp) {
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
sp = jit_cc_new_reg_I64(cc);
|
||||
sp = jit_cc_new_reg_ptr(cc);
|
||||
GEN_INSN(ADD, sp, cc->fp_reg,
|
||||
NEW_CONST(I64, offset_of_local(frame->sp - frame->lp)));
|
||||
GEN_INSN(STI64, sp, cc->fp_reg,
|
||||
NEW_CONST(PTR, offset_of_local(frame->sp - frame->lp)));
|
||||
GEN_INSN(STPTR, sp, cc->fp_reg,
|
||||
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;
|
||||
}
|
||||
|
||||
if (frame->ip != frame->committed_ip) {
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
GEN_INSN(STI64, NEW_CONST(I64, (uint64)(uintptr_t)frame->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
|
||||
GEN_INSN(STPTR, NEW_CONST(PTR, (uintptr_t)frame->ip), cc->fp_reg,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, 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");
|
||||
}
|
||||
|
||||
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
|
||||
form_and_translate_func(JitCompContext *cc)
|
||||
{
|
||||
|
@ -192,6 +229,9 @@ form_and_translate_func(JitCompContext *cc)
|
|||
JitIncomingInsn *incoming_insn, *incoming_insn_next;
|
||||
uint32 i;
|
||||
|
||||
if (!create_fix_virtual_regs(cc))
|
||||
return false;
|
||||
|
||||
if (!(func_entry_basic_block = jit_frontend_translate_func(cc)))
|
||||
return false;
|
||||
|
||||
|
@ -231,19 +271,9 @@ form_and_translate_func(JitCompContext *cc)
|
|||
}
|
||||
cc->cur_basic_block = cc->exce_basic_blocks[i];
|
||||
if (i != EXCE_ALREADY_THROWN) {
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
insn = GEN_INSN(
|
||||
CALLNATIVE, 0,
|
||||
NEW_CONST(I64,
|
||||
(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
|
||||
NEW_CONST(PTR, (uintptr_t)jit_set_exception_with_id), 1);
|
||||
if (insn) {
|
||||
*(jit_insn_opndv(insn, 2)) = NEW_CONST(I32, i);
|
||||
}
|
||||
|
@ -343,21 +373,20 @@ init_func_translation(JitCompContext *cc)
|
|||
local_size =
|
||||
(cur_wasm_func->param_cell_num + cur_wasm_func->local_cell_num) * 4;
|
||||
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
top = jit_cc_new_reg_I64(cc);
|
||||
top_boundary = jit_cc_new_reg_I64(cc);
|
||||
new_top = jit_cc_new_reg_I64(cc);
|
||||
frame_boundary = jit_cc_new_reg_I64(cc);
|
||||
frame_sp = jit_cc_new_reg_I64(cc);
|
||||
top = jit_cc_new_reg_ptr(cc);
|
||||
top_boundary = jit_cc_new_reg_ptr(cc);
|
||||
new_top = jit_cc_new_reg_ptr(cc);
|
||||
frame_boundary = jit_cc_new_reg_ptr(cc);
|
||||
frame_sp = jit_cc_new_reg_ptr(cc);
|
||||
|
||||
/* 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)));
|
||||
/* 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)));
|
||||
/* 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 */
|
||||
GEN_INSN(CMP, cc->cmp_reg, frame_boundary, top_boundary);
|
||||
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 */
|
||||
/* 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 */
|
||||
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)));
|
||||
/* frame_sp = frame->lp + local_size */
|
||||
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 */
|
||||
GEN_INSN(STI64, frame_sp, top,
|
||||
GEN_INSN(STPTR, frame_sp, top,
|
||||
NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
|
||||
/* 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)));
|
||||
/* 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)));
|
||||
*/
|
||||
/* 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)));
|
||||
/* 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;
|
||||
}
|
||||
|
|
|
@ -444,15 +444,9 @@ jit_cc_init(JitCompContext *cc, unsigned htab_size)
|
|||
}
|
||||
|
||||
/* Create registers for frame pointer, exec_env and cmp. */
|
||||
#if UINTPTR_MAX == UINT64_MAX
|
||||
cc->fp_reg = jit_reg_new(JIT_REG_KIND_I64, cc->hreg_info->fp_hreg_index);
|
||||
cc->fp_reg = jit_reg_new(JIT_REG_KIND_PTR, cc->hreg_info->fp_hreg_index);
|
||||
cc->exec_env_reg =
|
||||
jit_reg_new(JIT_REG_KIND_I64, 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
|
||||
jit_reg_new(JIT_REG_KIND_PTR, cc->hreg_info->exec_env_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;
|
||||
|
@ -477,7 +471,19 @@ jit_cc_destroy(JitCompContext *cc)
|
|||
|
||||
jit_block_stack_destroy(&cc->block_stack);
|
||||
|
||||
jit_free(cc->jit_frame);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ INSN(LDI64, Reg, 3, 1)
|
|||
INSN(LDU64, Reg, 3, 1)
|
||||
INSN(LDF32, Reg, 3, 1)
|
||||
INSN(LDF64, Reg, 3, 1)
|
||||
INSN(LDPTR, Reg, 3, 1)
|
||||
INSN(LDV64, Reg, 3, 1)
|
||||
INSN(LDV128, Reg, 3, 1)
|
||||
INSN(LDV256, Reg, 3, 1)
|
||||
|
@ -146,6 +147,7 @@ INSN(STI32, Reg, 3, 0)
|
|||
INSN(STI64, Reg, 3, 0)
|
||||
INSN(STF32, Reg, 3, 0)
|
||||
INSN(STF64, Reg, 3, 0)
|
||||
INSN(STPTR, Reg, 3, 0)
|
||||
INSN(STV64, Reg, 3, 1)
|
||||
INSN(STV128, Reg, 3, 1)
|
||||
INSN(STV256, Reg, 3, 1)
|
||||
|
|
|
@ -118,6 +118,12 @@ typedef enum JitRegKind {
|
|||
JIT_REG_KIND_NUM /* number of register kinds */
|
||||
} 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.
|
||||
*
|
||||
|
@ -890,6 +896,27 @@ typedef struct JitValueSlot {
|
|||
uint32 committed_ref : 2;
|
||||
} 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 */
|
||||
typedef struct JitFrame {
|
||||
/* The current wasm module */
|
||||
|
@ -919,6 +946,23 @@ typedef struct JitFrame {
|
|||
/* Committed stack top pointer */
|
||||
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 */
|
||||
JitValueSlot lp[1];
|
||||
} JitFrame;
|
||||
|
@ -1015,6 +1059,23 @@ typedef struct JitCompContext {
|
|||
JitReg exec_env_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 */
|
||||
JitFrame *jit_frame;
|
||||
|
||||
|
@ -1291,6 +1352,12 @@ jit_cc_new_const_I32(JitCompContext *cc, int32 val)
|
|||
JitReg
|
||||
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.
|
||||
*
|
||||
|
@ -1623,6 +1690,12 @@ jit_cc_new_reg_I64(JitCompContext *cc)
|
|||
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
|
||||
jit_cc_new_reg_F32(JitCompContext *cc)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user