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_pushargi_d(jit_state_t *_jit, jit_float64_t u) { jit_int32_t regno; regno = jit_get_reg(jit_class_fpr); jit_movi_d(regno, u); if (jit_arg_d_reg_p(_jitc->function->call.argi)) { jit_stxi_d(-8, JIT_FP, regno); jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); jit_ldxi(_O0 + _jitc->function->call.argi + 1, JIT_FP, -4); _jitc->function->call.argi += 2; } else if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_stxi_f(-8, JIT_FP, regno); jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -8); ++_jitc->function->call.argi; jit_stxi_f(stack_framesize, JIT_SP, regno + 1); _jitc->function->call.size += sizeof(jit_float32_t); } else { jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, regno); jit_stxi_f(_jitc->function->call.size + stack_framesize + 4, JIT_SP, regno + 1); _jitc->function->call.size += sizeof(jit_float64_t); } 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); }
jit_value pop_int(Frame* frame) { jit_value reg = pop_reg(frame); struct jit* jit = frame->jit; jit_ldxi(jit, frame->accum[1], reg, offsetof(YValue, type), sizeof(void*)); jit_movi(jit, frame->accum[2], 0); jit_op* not_int_jump = jit_bner(jit, (intptr_t) JIT_FORWARD, frame->accum[1], frame->IntType); jit_ldxi(jit, frame->accum[2], reg, offsetof(YInteger, value), sizeof(int64_t)); jit_patch(jit, not_int_jump); jit_movr(jit, frame->accum[0], frame->accum[2]); return frame->accum[0]; }
void _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v) { assert(v->code == jit_code_arg_f); if (jit_arg_reg_p(v->u.w)) { jit_stxi_f(-4, JIT_FP, u); jit_ldxi(_I0 + v->u.w, JIT_FP, -4); } else jit_stxi_f(v->u.w, JIT_FP, u); }
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); }
void _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) { if (jit_arg_reg_p(_jitc->function->call.argi)) { jit_stxi_f(-4, JIT_FP, u); jit_ldxi(_O0 + _jitc->function->call.argi, JIT_FP, -4); ++_jitc->function->call.argi; } else { jit_stxi_f(_jitc->function->call.size + stack_framesize, JIT_SP, u); _jitc->function->call.size += sizeof(jit_float32_t); } }
void _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v) { jit_int32_t regno; assert(v->code == jit_code_arg_f); regno = jit_get_reg(jit_class_fpr); jit_movi_f(regno, u); if (jit_arg_reg_p(v->u.w)) { jit_stxi_f(-4, JIT_FP, regno); jit_ldxi(_I0 + v->u.w, JIT_FP, -4); } else jit_stxi_f(v->u.w, JIT_FP, regno); jit_unget_reg(regno); }
static void load_exception(jit_int32_t regval, oword_t offset) { if (otype(current_record) == t_namespace) { if (GPR[GLOBAL] != JIT_NOREG) jit_addi(regval, GPR[GLOBAL], offset); else jit_movi(regval, (oword_t)gd + offset); } else { if (GPR[FRAME] != JIT_NOREG) jit_addi(regval, GPR[FRAME], offset); else { jit_ldxi(regval, JIT_V0, offsetof(othread_t, fp)); jit_addi(regval, regval, offset); } } }