diff mbox

[08/13] target-openrisc: Test for Overflow exception statically

Message ID 1383073495-5332-9-git-send-email-sebastian@macke.de
State New
Headers show

Commit Message

Sebastian Macke Oct. 29, 2013, 7:04 p.m. UTC
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(-)

Comments

Max Filippov Oct. 29, 2013, 9:25 p.m. UTC | #1
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;
>
Sebastian Macke Oct. 29, 2013, 10:06 p.m. UTC | #2
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 mbox

Patch

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;