Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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];
}
Beispiel #5
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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);
    }
}
Beispiel #8
0
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);
}
Beispiel #9
0
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);
	}
    }
}