void _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v) { jit_int32_t regno, gpr; assert(v->code == jit_code_arg_d); regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); if (jit_arg_d_reg_p(v->u.w)) { jit_stxi_d(-8, JIT_FP, regno); jit_ldxi(_I0 + v->u.w, JIT_FP, -8); jit_ldxi(_I0 + v->u.w + 1, JIT_FP, -4); } else if (jit_arg_reg_p(v->u.w)) { gpr = jit_get_reg(jit_class_gpr); jit_stxi_d(-8, JIT_FP, regno); jit_ldxi(_I0 + v->u.w, JIT_FP, -8); jit_ldxi(gpr, JIT_FP, -4); jit_stxi(stack_framesize, JIT_FP, gpr); jit_unget_reg(gpr); } else if ((v->u.w & 7) == 0) jit_stxi_d(v->u.w, JIT_FP, regno); else { jit_stxi_d(-8, JIT_FP, regno); gpr = jit_get_reg(jit_class_gpr); jit_ldxi(gpr, JIT_FP, -8); jit_stxi(v->u.w, JIT_FP, gpr); jit_ldxi(gpr, JIT_FP, -4); jit_stxi(v->u.w + 4, JIT_FP, gpr); jit_unget_reg(gpr); } jit_unget_reg(regno); }
static void unwind_exception(jit_int32_t regval, obool_t unsafe) { jit_int32_t frame; jit_int32_t stack; jit_node_t *equal; /* Need to restore and resync thread state */ frame = GPR[FRAME] != JIT_NOREG ? GPR[FRAME] : JIT_R0; stack = GPR[STACK] != JIT_NOREG ? GPR[STACK] : JIT_R0; /* Restore fp */ jit_ldxi(frame, regval, offsetof(oexception_t, fp)); jit_stxi(offsetof(othread_t, fp), JIT_V0, frame); /* Restore sp */ if (unsafe) { /* If throw may be from another vm stack frame, need to * zero memory, or it may later be cast to the wrong object; * the logic is somewhat optimized, to zero memory before * function return instead of function call, but exceptions * break all rules. */ if (GPR[STACK] != JIT_NOREG) { jit_ldxi(GPR[STACK], regval, offsetof(oexception_t, sp)); jit_ldxi(JIT_R1, JIT_V0, offsetof(othread_t, sp)); equal = jit_beqr(GPR[STACK], JIT_R1); jit_subr(JIT_R0, GPR[STACK], JIT_R1); jit_prepare(); jit_pushargr(JIT_R1); jit_pushargi(0); jit_pushargr(JIT_R0); jit_finishi(memset); jit_patch(equal); jit_stxi(offsetof(othread_t, sp), JIT_V0, GPR[STACK]); } else { jit_ldxi(JIT_R0, regval, offsetof(oexception_t, sp)); jit_ldxi(JIT_R1, JIT_V0, offsetof(othread_t, sp)); equal = jit_beqr(JIT_R0, JIT_R1); jit_subr(JIT_R0, JIT_R0, JIT_R1); jit_prepare(); jit_pushargr(JIT_R1); jit_pushargi(0); jit_pushargr(JIT_R0); jit_finishi(memset); jit_ldxi(JIT_R0, regval, offsetof(oexception_t, sp)); jit_patch(equal); jit_stxi(offsetof(othread_t, sp), JIT_V0, JIT_R0); } } else { jit_ldxi(stack, regval, offsetof(oexception_t, sp)); jit_stxi(offsetof(othread_t, sp), JIT_V0, stack); } /* Restore this (if there is a this register) */ if (GPR[THIS] != JIT_NOREG) jit_ldxi(GPR[THIS], regval, offsetof(oexception_t, th)); /* Restore exception frame */ jit_ldxi(JIT_R0, regval, offsetof(oexception_t, ex)); jit_stxi(offsetof(othread_t, ex), JIT_V0, JIT_R0); }
static void store_exception(jit_int32_t regval, jit_int32_t ipreg) { jit_stxi(offsetof(oexception_t, ip), regval, ipreg); /* Current fp */ if (GPR[FRAME] != JIT_NOREG) jit_stxi(offsetof(oexception_t, fp), regval, GPR[FRAME]); else { jit_ldxi(JIT_R0, JIT_V0, offsetof(othread_t, fp)); jit_stxi(offsetof(oexception_t, fp), regval, JIT_R0); } /* Current sp */ if (GPR[STACK] != JIT_NOREG) jit_stxi(offsetof(oexception_t, sp), regval, GPR[STACK]); else { jit_ldxi(JIT_R0, JIT_V0, offsetof(othread_t, sp)); jit_stxi(offsetof(oexception_t, sp), regval, JIT_R0); } /* Current this (if there is a this register) */ if (GPR[THIS] != JIT_NOREG) jit_stxi(offsetof(oexception_t, th), regval, GPR[THIS]); /* Previous exception frame */ jit_ldxi(JIT_R0, JIT_V0, offsetof(othread_t, ex)); jit_stxi(offsetof(oexception_t, ex), regval, JIT_R0); /* Update current exception frame */ jit_stxi(offsetof(othread_t, ex), JIT_V0, regval); }
void _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg); if (jit_arg_reg_p(v->u.w)) jit_movr(_I0 + v->u.w, u); else jit_stxi(v->u.w, JIT_FP, u); }
void _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_d); assert(_jitc->function); if (jit_arg_d_reg_p(v->u.w)) { jit_stxi(-8, JIT_FP, _I0 + v->u.w); jit_stxi(-4, JIT_FP, _I0 + v->u.w + 1); jit_ldxi_d(u, JIT_FP, -8); } else if (jit_arg_reg_p(v->u.w)) { jit_stxi(-8, JIT_FP, _I0 + v->u.w); jit_ldxi_f(u, JIT_FP, -8); jit_ldxi_f(u + 1, JIT_FP, stack_framesize); } else { jit_ldxi_f(u, JIT_FP, v->u.w); jit_ldxi_f(u + 1, JIT_FP, v->u.w + 4); } }
void _jit_pushargr(jit_state_t *_jit, jit_int32_t u) { if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movr(_O0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; } else { jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, u); _jitc->function->call.size += sizeof(jit_word_t); } }
void _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); assert(_jitc->function); if (jit_arg_reg_p(v->u.w)) { jit_stxi(-4, JIT_FP, _I0 + v->u.w); jit_ldxi_f(u, JIT_FP, -4); } else jit_ldxi_f(u, JIT_FP, v->u.w); }
void _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg); if (jit_arg_reg_p(v->u.w)) jit_movi(_I0 + v->u.w, u); else { regno = jit_get_reg(jit_class_gpr); jit_movi(regno, u); jit_stxi(v->u.w, JIT_FP, regno); jit_unget_reg(regno); } }
void _jit_pushargi(jit_state_t *_jit, jit_word_t u) { jit_int32_t regno; if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_movi(_O0 + _jitc->function->call.argi, u); ++_jitc->function->call.argi; } else { regno = jit_get_reg(jit_class_gpr); jit_movi(regno, u); jit_stxi(_jitc->function->call.size + stack_framesize, JIT_SP, regno); jit_unget_reg(regno); _jitc->function->call.size += sizeof(jit_word_t); } }