target: e2k: Add exceptions to wregs access.
This commit is contained in:
parent
ccb625ced0
commit
8f1771d67d
|
@ -239,8 +239,6 @@ void e2k_gen_exception(DisasContext *ctx, int which)
|
|||
|
||||
gen_save_cpu_state(ctx);
|
||||
gen_helper_raise_exception(cpu_env, t);
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
|
||||
tcg_temp_free_i32(t);
|
||||
}
|
||||
|
@ -328,10 +326,10 @@ static inline void do_commit(DisasContext *ctx)
|
|||
|
||||
switch(res->tag) {
|
||||
case RESULT_BASED_REG:
|
||||
e2k_gen_store_breg(res->u.reg.i, res->u.reg.v);
|
||||
e2k_gen_store_breg(ctx, res->u.reg.i, res->u.reg.v);
|
||||
break;
|
||||
case RESULT_REGULAR_REG:
|
||||
e2k_gen_store_wreg(res->u.reg.i, res->u.reg.v);
|
||||
e2k_gen_store_wreg(ctx, res->u.reg.i, res->u.reg.v);
|
||||
break;
|
||||
case RESULT_GLOBAL_REG:
|
||||
e2k_gen_store_greg(res->u.reg.i, res->u.reg.v);
|
||||
|
|
|
@ -218,10 +218,10 @@ static inline void e2k_gen_lcntex(TCGv_i32 ret)
|
|||
void e2k_gen_preg(TCGv_i64 ret, int reg);
|
||||
TCGv_i64 e2k_get_preg(DisasContext *dc, int reg);
|
||||
void e2k_gen_store_preg(int reg, TCGv_i64 val);
|
||||
TCGv_i64 e2k_get_wreg(DisasContext *dc, int reg);
|
||||
void e2k_gen_store_wreg(int reg, TCGv_i64 val);
|
||||
TCGv_i64 e2k_get_breg(DisasContext *dc, int reg);
|
||||
void e2k_gen_store_breg(int reg, TCGv_i64 val);
|
||||
TCGv_i64 e2k_get_wreg(DisasContext *ctx, int reg);
|
||||
void e2k_gen_store_wreg(DisasContext *ctx, int reg, TCGv_i64 val);
|
||||
TCGv_i64 e2k_get_breg(DisasContext *ctx, int reg);
|
||||
void e2k_gen_store_breg(DisasContext *ctx, int reg, TCGv_i64 val);
|
||||
TCGv_i64 e2k_get_greg(DisasContext *dc, int reg);
|
||||
void e2k_gen_store_greg(int reg, TCGv_i64 val);
|
||||
void e2k_gen_cond_i32(DisasContext *ctx, TCGv_i32 ret, uint8_t psrc);
|
||||
|
@ -239,6 +239,15 @@ static inline void e2k_gen_cond_i64(DisasContext *ctx, TCGv_i64 ret,
|
|||
|
||||
void e2k_gen_exception(DisasContext *dc, int which);
|
||||
|
||||
static inline void e2k_gen_exception2(int excp)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_const_i32(excp);
|
||||
|
||||
gen_helper_raise_exception(cpu_env, t0);
|
||||
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
void e2k_control_gen(DisasContext *dc);
|
||||
|
||||
void e2k_execute_alc(DisasContext *ctx, int index);
|
||||
|
|
|
@ -88,20 +88,19 @@ void e2k_gen_store_preg(int reg, TCGv_i64 val)
|
|||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
static inline void gen_wreg_index(TCGv_i32 ret, int reg)
|
||||
static inline void gen_wreg_index(TCGv_i32 ret, TCGv_i32 reg)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
TCGv_i32 t1 = tcg_const_i32(WREGS_SIZE);
|
||||
|
||||
/* TODO: exception if overflow window size */
|
||||
tcg_gen_addi_i32(t0, e2k_cs.wd_base, reg);
|
||||
tcg_gen_add_i32(t0, e2k_cs.wd_base, reg);
|
||||
tcg_gen_remu_i32(ret, t0, t1);
|
||||
|
||||
tcg_temp_free_i32(t1);
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static inline void gen_wreg_ptr(TCGv_ptr ret, int reg)
|
||||
static inline void gen_wreg_ptr(TCGv_ptr ret, TCGv_i32 reg)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
|
@ -117,12 +116,33 @@ static inline void gen_wreg_ptr(TCGv_ptr ret, int reg)
|
|||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
TCGv_i64 e2k_get_wreg(DisasContext *dc, int reg)
|
||||
static inline void gen_wregi_ptr(TCGv_ptr ret, int reg)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_const_i32(reg);
|
||||
|
||||
gen_wreg_ptr(ret, t0);
|
||||
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static inline void gen_wreg_check(DisasContext *ctx, int reg)
|
||||
{
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
|
||||
assert(reg < 64);
|
||||
|
||||
tcg_gen_brcondi_i32(TCG_COND_GTU, e2k_cs.wd_size, reg, l0);
|
||||
e2k_gen_exception(ctx, E2K_EXCP_MAPERR);
|
||||
gen_set_label(l0);
|
||||
}
|
||||
|
||||
TCGv_i64 e2k_get_wreg(DisasContext *ctx, int reg)
|
||||
{
|
||||
TCGv_ptr t0 = tcg_temp_new_ptr();
|
||||
TCGv_i64 t1 = e2k_get_temp_i64(dc);
|
||||
TCGv_i64 t1 = e2k_get_temp_i64(ctx);
|
||||
|
||||
gen_wreg_ptr(t0, reg);
|
||||
gen_wreg_check(ctx, reg);
|
||||
gen_wregi_ptr(t0, reg);
|
||||
tcg_gen_ld_i64(t1, t0, 0);
|
||||
|
||||
tcg_temp_free_ptr(t0);
|
||||
|
@ -130,67 +150,66 @@ TCGv_i64 e2k_get_wreg(DisasContext *dc, int reg)
|
|||
return t1;
|
||||
}
|
||||
|
||||
void e2k_gen_store_wreg(int reg, TCGv_i64 val)
|
||||
void e2k_gen_store_wreg(DisasContext *ctx, int reg, TCGv_i64 val)
|
||||
{
|
||||
TCGv_ptr t0 = tcg_temp_new_ptr();
|
||||
|
||||
gen_wreg_ptr(t0, reg);
|
||||
gen_wreg_check(ctx, reg);
|
||||
gen_wregi_ptr(t0, reg);
|
||||
tcg_gen_st_i64(val, t0, 0);
|
||||
|
||||
tcg_temp_free_ptr(t0);
|
||||
}
|
||||
|
||||
static inline void gen_breg_index(TCGv_i32 ret, int reg)
|
||||
static inline void gen_breg_index(TCGv_i32 ret, int idx)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
TCGv_i32 t2 = tcg_temp_new_i32();
|
||||
TCGv_i32 t3 = tcg_temp_new_i32();
|
||||
TCGv_i32 t4 = tcg_const_i32(WREGS_SIZE);
|
||||
|
||||
tcg_gen_addi_i32(t0, e2k_cs.bcur, reg);
|
||||
tcg_gen_addi_i32(t0, e2k_cs.bcur, idx);
|
||||
tcg_gen_remu_i32(t1, t0, e2k_cs.bsize);
|
||||
tcg_gen_add_i32(t2, t1, e2k_cs.boff);
|
||||
tcg_gen_add_i32(t3, t2, e2k_cs.wd_base);
|
||||
tcg_gen_remu_i32(ret, t3, t4);
|
||||
tcg_gen_add_i32(ret, t1, e2k_cs.boff);
|
||||
|
||||
tcg_temp_free_i32(t4);
|
||||
tcg_temp_free_i32(t3);
|
||||
tcg_temp_free_i32(t2);
|
||||
tcg_temp_free_i32(t1);
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static inline void gen_breg_ptr(TCGv_ptr ret, int reg)
|
||||
static inline void gen_bregi_ptr(DisasContext *ctx, TCGv_ptr ret, int idx)
|
||||
{
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
TCGv_ptr t2 = tcg_temp_new_ptr();
|
||||
|
||||
gen_breg_index(t0, reg);
|
||||
tcg_gen_muli_i32(t1, t0, 8);
|
||||
tcg_gen_ext_i32_ptr(t2, t1);
|
||||
tcg_gen_add_ptr(ret, e2k_cs.wptr, t2);
|
||||
assert(idx < 128);
|
||||
|
||||
tcg_gen_brcondi_i32(TCG_COND_LEU, e2k_cs.bsize, idx, l0);
|
||||
tcg_gen_add_i32(t0, e2k_cs.boff, e2k_cs.bsize);
|
||||
tcg_gen_brcond_i32(TCG_COND_LTU, e2k_cs.wd_size, t0, l0);
|
||||
tcg_gen_br(l1);
|
||||
gen_set_label(l0);
|
||||
e2k_gen_exception(ctx, E2K_EXCP_MAPERR);
|
||||
gen_set_label(l1);
|
||||
|
||||
gen_breg_index(t0, idx);
|
||||
gen_wreg_ptr(ret, t0);
|
||||
|
||||
tcg_temp_free_ptr(t2);
|
||||
tcg_temp_free_i32(t1);
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
TCGv_i64 e2k_get_breg(DisasContext *dc, int reg)
|
||||
TCGv_i64 e2k_get_breg(DisasContext *ctx, int reg)
|
||||
{
|
||||
TCGv_i64 ret = e2k_get_temp(dc);
|
||||
TCGv_i64 ret = e2k_get_temp(ctx);
|
||||
TCGv_ptr ptr = tcg_temp_new_ptr();
|
||||
gen_breg_ptr(ptr, reg);
|
||||
gen_bregi_ptr(ctx, ptr, reg);
|
||||
tcg_gen_ld_i64(ret, ptr, 0);
|
||||
tcg_temp_free_ptr(ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void e2k_gen_store_breg(int reg, TCGv_i64 val)
|
||||
void e2k_gen_store_breg(DisasContext *ctx, int reg, TCGv_i64 val)
|
||||
{
|
||||
TCGv_ptr ptr = tcg_temp_new_ptr();
|
||||
gen_breg_ptr(ptr, reg);
|
||||
gen_bregi_ptr(ctx, ptr, reg);
|
||||
tcg_gen_st_i64(val, ptr, 0);
|
||||
tcg_temp_free_ptr(ptr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue