qemu-devel
[Top][All Lists]
Advanced

[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: Sebastian Macke
Subject: Re: [Qemu-devel] [PATCH 08/13] target-openrisc: Test for Overflow exception statically
Date: Tue, 29 Oct 2013 15:06:22 -0700
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.0.1

On 29/10/2013 2:25 PM, Max Filippov wrote:
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.

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;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]