[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 08/13] target-openrisc: Test for Overflow except
From: |
Max Filippov |
Subject: |
Re: [Qemu-devel] [PATCH 08/13] target-openrisc: Test for Overflow exception statically |
Date: |
Wed, 30 Oct 2013 01:25:06 +0400 |
On Tue, Oct 29, 2013 at 11:04 PM, Sebastian Macke <address@hidden> 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 <address@hidden>
> ---
> 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
- [Qemu-devel] [PATCH 04/13] target-openrisc: sync flags only when necessary, (continued)
- [Qemu-devel] [PATCH 04/13] target-openrisc: sync flags only when necessary, Sebastian Macke, 2013/10/29
- [Qemu-devel] [PATCH 02/13] target-openrisc: Separate Delayed slot handling from main loop, Sebastian Macke, 2013/10/29
- [Qemu-devel] [PATCH 07/13] target-openrisc: Correct l.cmov conditional check, Sebastian Macke, 2013/10/29
- [Qemu-devel] [PATCH 05/13] target-openrisc: Remove TLB flush on exception, Sebastian Macke, 2013/10/29
- [Qemu-devel] [PATCH 08/13] target-openrisc: Test for Overflow exception statically, Sebastian Macke, 2013/10/29
- Re: [Qemu-devel] [PATCH 08/13] target-openrisc: Test for Overflow exception statically,
Max Filippov <=
- [Qemu-devel] [PATCH 09/13] target-openrisc: Add CPU which neglects Carry and Overflow Flag, Sebastian Macke, 2013/10/29
- [Qemu-devel] [PATCH 11/13] target-openrisc: use jmp_pc as flag variable for branches, Sebastian Macke, 2013/10/29