[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 08/13] target-openrisc: Test for Overflow exception
From: |
Sebastian Macke |
Subject: |
[Qemu-devel] [PATCH 08/13] target-openrisc: Test for Overflow exception statically |
Date: |
Tue, 29 Oct 2013 20:04:50 +0100 |
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();
+ 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;
--
1.8.4.1
- Re: [Qemu-devel] [PATCH 03/13] target-openrisc: Separate of load/store instructions, (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 <=
- [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