On Tue, Oct 29, 2013 at 11:04 PM, Sebastian Macke <sebast...@macke.de> wrote: > Instead of testing the overflow exception dynamically every time > The flag will be reckognized by the tcg as changed code and > will recompile the code with the correct checks. > > Signed-off-by: Sebastian Macke <sebast...@macke.de> > --- > target-openrisc/cpu.h | 3 +- > target-openrisc/translate.c | 78 > ++++++++++++++++++++++++++------------------- > 2 files changed, 48 insertions(+), 33 deletions(-) > > diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h > index bac61e5..94bbb17 100644 > --- a/target-openrisc/cpu.h > +++ b/target-openrisc/cpu.h > @@ -412,7 +412,8 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState > *env, > *pc = env->pc; > *cs_base = 0; > /* D_FLAG -- branch instruction exception */ > - *flags = (env->flags & D_FLAG) | (env->sr & (SR_SM | SR_DME | SR_IME)); > + *flags = (env->flags & D_FLAG) | > + (env->sr & (SR_SM | SR_DME | SR_IME | SR_OVE)); > } > > static inline int cpu_mmu_index(CPUOpenRISCState *env) > diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c > index 9fd1126..b1f73c4 100644 > --- a/target-openrisc/translate.c > +++ b/target-openrisc/translate.c > @@ -271,7 +271,6 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > TCGv_i64 tb = tcg_temp_new_i64(); > TCGv_i64 td = tcg_temp_local_new_i64(); > TCGv_i32 res = tcg_temp_local_new_i32(); > - TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > tcg_gen_extu_i32_i64(ta, cpu_R[ra]); > tcg_gen_extu_i32_i64(tb, cpu_R[rb]); > tcg_gen_add_i64(td, ta, tb); > @@ -282,16 +281,19 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); > tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); > - tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > - tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > - gen_exception(dc, EXCP_RANGE); > + if (dc->tb_flags & SR_OVE) { > + TCGv_i32 sr_ove = tcg_temp_local_new_i32();
This temp doesn't need to be local. > + tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > + tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > + gen_exception(dc, EXCP_RANGE); > + tcg_temp_free_i32(sr_ove); > + } Repetitions of this code call for making it a nice separate function. > gen_set_label(lab); > tcg_gen_mov_i32(cpu_R[rd], res); > tcg_temp_free_i64(ta); > tcg_temp_free_i64(tb); > tcg_temp_free_i64(td); > tcg_temp_free_i32(res); > - tcg_temp_free_i32(sr_ove); > } > break; > default: > @@ -312,7 +314,6 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > TCGv_i64 td = tcg_temp_local_new_i64(); > TCGv_i32 res = tcg_temp_local_new_i32(); > TCGv_i32 sr_cy = tcg_temp_local_new_i32(); > - TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > tcg_gen_extu_i32_i64(ta, cpu_R[ra]); > tcg_gen_extu_i32_i64(tb, cpu_R[rb]); > tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY); > @@ -327,9 +328,13 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); > tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); > - tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > - tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > - gen_exception(dc, EXCP_RANGE); > + if (dc->tb_flags & SR_OVE) { > + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > + tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > + tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > + gen_exception(dc, EXCP_RANGE); > + tcg_temp_free_i32(sr_ove); > + } > gen_set_label(lab); > tcg_gen_mov_i32(cpu_R[rd], res); > tcg_temp_free_i64(ta); > @@ -338,7 +343,6 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > tcg_temp_free_i64(td); > tcg_temp_free_i32(res); > tcg_temp_free_i32(sr_cy); > - tcg_temp_free_i32(sr_ove); > } > break; > default: > @@ -357,7 +361,6 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > TCGv_i64 tb = tcg_temp_new_i64(); > TCGv_i64 td = tcg_temp_local_new_i64(); > TCGv_i32 res = tcg_temp_local_new_i32(); > - TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > > tcg_gen_extu_i32_i64(ta, cpu_R[ra]); > tcg_gen_extu_i32_i64(tb, cpu_R[rb]); > @@ -369,16 +372,19 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); > tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); > - tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > - tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > - gen_exception(dc, EXCP_RANGE); > + if (dc->tb_flags & SR_OVE) { > + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > + tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > + tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > + gen_exception(dc, EXCP_RANGE); > + tcg_temp_free_i32(sr_ove); > + } > gen_set_label(lab); > tcg_gen_mov_i32(cpu_R[rd], res); > tcg_temp_free_i64(ta); > tcg_temp_free_i64(tb); > tcg_temp_free_i64(td); > tcg_temp_free_i32(res); > - tcg_temp_free_i32(sr_ove); > } > break; > default: > @@ -451,10 +457,12 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > if (rb == 0) { > tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); > - tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); > - tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0); > - gen_exception(dc, EXCP_RANGE); > - gen_set_label(lab0); > + if (dc->tb_flags & SR_OVE) { > + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); > + tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, > lab0); > + gen_exception(dc, EXCP_RANGE); > + gen_set_label(lab0); > + } > } else { > tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb], > 0x00000000, lab1); > @@ -464,9 +472,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn) > 0xffffffff, lab2); > gen_set_label(lab1); > tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY)); > - tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); > - tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab3); > - gen_exception(dc, EXCP_RANGE); > + if (dc->tb_flags & SR_OVE) { > + tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE); > + tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, > lab3); > + gen_exception(dc, EXCP_RANGE); > + } > gen_set_label(lab2); > tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]); > gen_set_label(lab3); > @@ -950,7 +960,6 @@ static void dec_misc(DisasContext *dc, uint32_t insn) > TCGv_i64 ta = tcg_temp_new_i64(); > TCGv_i64 td = tcg_temp_local_new_i64(); > TCGv_i32 res = tcg_temp_local_new_i32(); > - TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > tcg_gen_extu_i32_i64(ta, cpu_R[ra]); > tcg_gen_addi_i64(td, ta, sign_extend(I16, 16)); > tcg_gen_trunc_i64_i32(res, td); > @@ -960,15 +969,18 @@ static void dec_misc(DisasContext *dc, uint32_t insn) > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); > tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); > - tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > - tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > - gen_exception(dc, EXCP_RANGE); > + if (dc->tb_flags & SR_OVE) { > + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > + tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > + tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > + gen_exception(dc, EXCP_RANGE); > + tcg_temp_free_i32(sr_ove); > + } > gen_set_label(lab); > tcg_gen_mov_i32(cpu_R[rd], res); > tcg_temp_free_i64(ta); > tcg_temp_free_i64(td); > tcg_temp_free_i32(res); > - tcg_temp_free_i32(sr_ove); > } > } > break; > @@ -982,7 +994,6 @@ static void dec_misc(DisasContext *dc, uint32_t insn) > TCGv_i64 tcy = tcg_temp_local_new_i64(); > TCGv_i32 res = tcg_temp_local_new_i32(); > TCGv_i32 sr_cy = tcg_temp_local_new_i32(); > - TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > tcg_gen_extu_i32_i64(ta, cpu_R[ra]); > tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY); > tcg_gen_shri_i32(sr_cy, sr_cy, 10); > @@ -996,9 +1007,13 @@ static void dec_misc(DisasContext *dc, uint32_t insn) > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab); > tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab); > tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY)); > - tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > - tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > - gen_exception(dc, EXCP_RANGE); > + if (dc->tb_flags & SR_OVE) { > + TCGv_i32 sr_ove = tcg_temp_local_new_i32(); > + tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE); > + tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab); > + gen_exception(dc, EXCP_RANGE); > + tcg_temp_free_i32(sr_ove); > + } > gen_set_label(lab); > tcg_gen_mov_i32(cpu_R[rd], res); > tcg_temp_free_i64(ta); > @@ -1006,7 +1021,6 @@ static void dec_misc(DisasContext *dc, uint32_t insn) > tcg_temp_free_i64(tcy); > tcg_temp_free_i32(res); > tcg_temp_free_i32(sr_cy); > - tcg_temp_free_i32(sr_ove); > } > break; > -- Thanks. -- Max