Message ID | 1383073495-5332-9-git-send-email-sebastian@macke.de |
---|---|
State | New |
Headers | show |
On Tue, Oct 29, 2013 at 11:04 PM, Sebastian Macke <sebastian@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 <sebastian@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; >
On 29/10/2013 2:25 PM, Max Filippov wrote: > On Tue, Oct 29, 2013 at 11:04 PM, Sebastian Macke <sebastian@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 <sebastian@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. You are right with both suggestions. Thanks for your comments. Looks like there is still some optimization possible :) > >> 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; >>
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(); + 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: @@ -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;
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 <sebastian@macke.de> --- target-openrisc/cpu.h | 3 +- target-openrisc/translate.c | 78 ++++++++++++++++++++++++++------------------- 2 files changed, 48 insertions(+), 33 deletions(-)