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:
Wenyong Huang 2022-04-12 09:01:08 +08:00 committed by GitHub
parent 3b7bc63274
commit d4fe9fcbdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 186 additions and 187 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
} }

View File

@ -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);
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); jit_free(cc->_const_val._hash_table);

View File

@ -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)

View File

@ -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)
{ {