All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/17] target-openrisc improvements
@ 2015-09-03  0:17 Richard Henderson
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS Richard Henderson
                   ` (16 more replies)
  0 siblings, 17 replies; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

This is a refresh of a branch I worked on in February, but I don't
believe was ever posted.  I'm doing so now in order to flush my set
of uncommitted branches.

The openrisc target is in terrible shape and, as far as I can tell
from the opencores mailing list, no one uses it.  The fact that it's
missing so many of the instructions in the ISA, so many that we
cannot execute the musl libc, is proof of that.

This patch set should probably be reviewed and merged, or we should
drop the whole target.


r~


Richard Henderson (17):
  target-openrisc: Always enable OPENRISC_DISAS
  target-openrisc: Streamline arithmetic and OVE
  target-openrisc: Invert the decoding in dec_calc
  target-openrisc: Keep SR_F in a separate variable
  target-openrisc: Use movcond where appropriate
  target-openrisc: Put SR[OVE] in TB flags
  target-openrisc: Keep SR_CY and SR_OV in a separate variables
  target-openrisc: Set flags on helpers
  target-openrisc: Implement ff1 and fl1 for 64-bit
  target-openrisc: Represent MACHI:MACLO as a single unit
  target-openrisc: Rationalize immediate extraction
  target-openrisc: Enable m[tf]spr from user mode
  target-openrisc: Enable trap, csync, msync, psync for user mode
  target-openrisc: Implement muld, muldu, macu, msbu
  target-openrisc: Fix madd
  target-openrisc: Write back result before FPE exception
  target-openrisc: Implement lwa, swa

 linux-user/main.c                  |   45 ++
 target-openrisc/cpu.c              |    1 +
 target-openrisc/cpu.h              |   41 +-
 target-openrisc/exception_helper.c |   31 +
 target-openrisc/fpu_helper.c       |  286 ++-----
 target-openrisc/gdbstub.c          |    4 +-
 target-openrisc/helper.h           |   42 +-
 target-openrisc/int_helper.c       |   57 +-
 target-openrisc/interrupt.c        |    3 +-
 target-openrisc/interrupt_helper.c |    3 +-
 target-openrisc/mmu.c              |    1 +
 target-openrisc/sys_helper.c       |   69 +-
 target-openrisc/translate.c        | 1443 ++++++++++++++++--------------------
 13 files changed, 883 insertions(+), 1143 deletions(-)

-- 
2.4.3

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-03 14:15   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE Richard Henderson
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Avoids warnings from unused variables etc.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/translate.c | 20 ++++----------------
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index aca1242..9d04753 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -33,14 +33,9 @@
 
 #include "trace-tcg.h"
 
-
-#define OPENRISC_DISAS
-
-#ifdef OPENRISC_DISAS
-#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
-#else
-#  define LOG_DIS(...) do { } while (0)
-#endif
+/* Set to 0 to completely disable.  */
+#define OPENRISC_DISAS  CPU_LOG_TB_IN_ASM
+#define LOG_DIS(...) qemu_log_mask(OPENRISC_DISAS, ## __VA_ARGS__)
 
 typedef struct DisasContext {
     TranslationBlock *tb;
@@ -704,9 +699,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1;
     uint32_t ra, rb, rd;
-#ifdef OPENRISC_DISAS
     uint32_t L6, K5;
-#endif
     uint32_t I16, I5, I11, N26, tmp;
     TCGMemOp mop;
 
@@ -715,10 +708,8 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     ra = extract32(insn, 16, 5);
     rb = extract32(insn, 11, 5);
     rd = extract32(insn, 21, 5);
-#ifdef OPENRISC_DISAS
     L6 = extract32(insn, 5, 6);
     K5 = extract32(insn, 0, 5);
-#endif
     I16 = extract32(insn, 0, 16);
     I5 = extract32(insn, 21, 5);
     I11 = extract32(insn, 0, 11);
@@ -1315,13 +1306,10 @@ static void dec_compi(DisasContext *dc, uint32_t insn)
 static void dec_sys(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0;
-#ifdef OPENRISC_DISAS
     uint32_t K16;
-#endif
+
     op0 = extract32(insn, 16, 10);
-#ifdef OPENRISC_DISAS
     K16 = extract32(insn, 0, 16);
-#endif
 
     switch (op0) {
     case 0x000:    /* l.sys */
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-03 14:16   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 03/17] target-openrisc: Invert the decoding in dec_calc Richard Henderson
                   ` (14 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Simplify overflow calculation.  Move overflow exception check
to a helper function, to eliminate inline branches.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/exception_helper.c |  12 ++
 target-openrisc/helper.h           |   1 +
 target-openrisc/translate.c        | 426 +++++++++++++++----------------------
 3 files changed, 190 insertions(+), 249 deletions(-)

diff --git a/target-openrisc/exception_helper.c b/target-openrisc/exception_helper.c
index 6093953..e6ab3e3 100644
--- a/target-openrisc/exception_helper.c
+++ b/target-openrisc/exception_helper.c
@@ -27,3 +27,15 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
 
     raise_exception(cpu, excp);
 }
+
+void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
+{
+    if (unlikely(test) && (env->sr & SR_OVE)) {
+        OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+        CPUState *cs = CPU(cpu);
+
+        cs->exception_index = EXCP_RANGE;
+        cpu_restore_state(cs, GETPC());
+        cpu_loop_exit(cs);
+    }
+}
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index f53fa21..9711f42 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -19,6 +19,7 @@
 
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
+DEF_HELPER_FLAGS_2(ove, TCG_CALL_NO_WG, void, env, tl)
 
 /* float */
 DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 9d04753..9a8f886 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -247,6 +247,166 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
     gen_sync_flags(dc);
 }
 
+static void gen_ove_cy(DisasContext *dc, TCGv cy)
+{
+    gen_helper_ove(cpu_env, cy);
+}
+
+static void gen_ove_ov(DisasContext *dc, TCGv ov)
+{
+    gen_helper_ove(cpu_env, ov);
+}
+
+static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov)
+{
+    TCGv t0 = tcg_temp_new();
+    tcg_gen_or_tl(t0, cy, ov);
+    gen_helper_ove(cpu_env, t0);
+    tcg_temp_free(t0);
+}
+
+static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv t0 = tcg_const_tl(0);
+    TCGv res = tcg_temp_new();
+    TCGv sr_cy = tcg_temp_new();
+    TCGv sr_ov = tcg_temp_new();
+
+    tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0);
+    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_xor_tl(t0, res, srcb);
+    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_temp_free(t0);
+
+    tcg_gen_mov_tl(dest, res);
+    tcg_temp_free(res);
+
+    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_cyov(dc, sr_ov, sr_cy);
+    tcg_temp_free(sr_ov);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv t0 = tcg_const_tl(0);
+    TCGv res = tcg_temp_new();
+    TCGv sr_cy = tcg_temp_new();
+    TCGv sr_ov = tcg_temp_new();
+
+    tcg_gen_shri_tl(sr_cy, cpu_sr, ctz32(SR_CY));
+    tcg_gen_andi_tl(sr_cy, sr_cy, 1);
+
+    tcg_gen_add2_tl(res, sr_cy, srca, t0, sr_cy, t0);
+    tcg_gen_add2_tl(res, sr_cy, res, sr_cy, srcb, t0);
+    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_xor_tl(t0, res, srcb);
+    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_temp_free(t0);
+
+    tcg_gen_mov_tl(dest, res);
+    tcg_temp_free(res);
+
+    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_cyov(dc, sr_ov, sr_cy);
+    tcg_temp_free(sr_ov);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv res = tcg_temp_new();
+    TCGv sr_cy = tcg_temp_new();
+    TCGv sr_ov = tcg_temp_new();
+
+    tcg_gen_sub_tl(res, srca, srcb);
+    tcg_gen_xor_tl(sr_cy, srca, srcb);
+    tcg_gen_xor_tl(sr_ov, res, srcb);
+    tcg_gen_and_tl(sr_ov, sr_ov, sr_cy);
+    tcg_gen_setcond_tl(TCG_COND_LTU, sr_cy, srca, srcb);
+
+    tcg_gen_mov_tl(dest, res);
+    tcg_temp_free(res);
+
+    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_cyov(dc, sr_ov, sr_cy);
+    tcg_temp_free(sr_ov);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_ov = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_muls2_tl(dest, sr_ov, srca, srcb);
+    tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
+    tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0);
+    tcg_temp_free(t0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_ov(dc, sr_ov);
+    tcg_temp_free(sr_ov);
+}
+
+static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_cy = tcg_temp_new();
+
+    tcg_gen_muls2_tl(dest, sr_cy, srca, srcb);
+    tcg_gen_setcondi_tl(TCG_COND_NE, sr_cy, sr_cy, 0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+
+    gen_ove_cy(dc, sr_cy);
+    tcg_temp_free(sr_cy);
+}
+
+static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_ov = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_ov, srcb, 0);
+    /* The result of divide-by-zero is undefined.
+       Supress the host-side exception by dividing by 1.  */
+    tcg_gen_or_tl(t0, srcb, sr_ov);
+    tcg_gen_div_tl(dest, srca, t0);
+    tcg_temp_free(t0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
+
+    gen_ove_ov(dc, sr_ov);
+    tcg_temp_free(sr_ov);
+}
+
+static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
+{
+    TCGv sr_cy = tcg_temp_new();
+    TCGv t0 = tcg_temp_new();
+
+    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_cy, srcb, 0);
+    /* The result of divide-by-zero is undefined.
+       Supress the host-side exception by dividing by 1.  */
+    tcg_gen_or_tl(t0, srcb, sr_cy);
+    tcg_gen_divu_tl(dest, srca, t0);
+    tcg_temp_free(t0);
+
+    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+
+    gen_ove_cy(dc, sr_cy);
+    tcg_temp_free(sr_cy);
+}
 
 static void dec_calc(DisasContext *dc, uint32_t insn)
 {
@@ -264,34 +424,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x00:    /* l.add */
             LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab = gen_new_label();
-                TCGv_i64 ta = tcg_temp_new_i64();
-                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);
-                tcg_gen_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 31);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                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);
-                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);
-            }
+            gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -303,42 +436,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x00:
             LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab = gen_new_label();
-                TCGv_i64 ta = tcg_temp_new_i64();
-                TCGv_i64 tb = tcg_temp_new_i64();
-                TCGv_i64 tcy = tcg_temp_local_new_i64();
-                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);
-                tcg_gen_extu_i32_i64(tcy, sr_cy);
-                tcg_gen_shri_i64(tcy, tcy, 10);
-                tcg_gen_add_i64(td, ta, tb);
-                tcg_gen_add_i64(td, td, tcy);
-                tcg_gen_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 32);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                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);
-                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(tcy);
-                tcg_temp_free_i64(td);
-                tcg_temp_free_i32(res);
-                tcg_temp_free_i32(sr_cy);
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -350,35 +448,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x00:
             LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab = gen_new_label();
-                TCGv_i64 ta = tcg_temp_new_i64();
-                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_sub_i64(td, ta, tb);
-                tcg_gen_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 31);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                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);
-                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);
-            }
+            gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -426,11 +496,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.mul */
             LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
-            if (ra != 0 && rb != 0) {
-                gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
-            } else {
-                tcg_gen_movi_tl(cpu_R[rd], 0x0);
-            }
+            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
         default:
             gen_illegal_exception(dc);
@@ -442,36 +508,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.div */
             LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab0 = gen_new_label();
-                TCGLabel *lab1 = gen_new_label();
-                TCGLabel *lab2 = gen_new_label();
-                TCGLabel *lab3 = gen_new_label();
-                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);
-                } else {
-                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],
-                                       0x00000000, lab1);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],
-                                       0x80000000, lab2);
-                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
-                                       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);
-                    gen_set_label(lab2);
-                    tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                    gen_set_label(lab3);
-                }
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
 
         default:
@@ -484,30 +521,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.divu */
             LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab0 = gen_new_label();
-                TCGLabel *lab1 = gen_new_label();
-                TCGLabel *lab2 = gen_new_label();
-                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);
-                } else {
-                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],
-                                       0x00000000, 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, lab2);
-                    gen_exception(dc, EXCP_RANGE);
-                    gen_set_label(lab1);
-                    tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                    gen_set_label(lab2);
-                }
-                tcg_temp_free_i32(sr_ove);
-            }
+            gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
 
         default:
@@ -520,34 +534,7 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         switch (op1) {
         case 0x03:    /* l.mulu */
             LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
-            if (rb != 0 && ra != 0) {
-                TCGv_i64 result = tcg_temp_local_new_i64();
-                TCGv_i64 tra = tcg_temp_local_new_i64();
-                TCGv_i64 trb = tcg_temp_local_new_i64();
-                TCGv_i64 high = tcg_temp_new_i64();
-                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
-                TCGLabel *lab = gen_new_label();
-                /* Calculate each result. */
-                tcg_gen_extu_i32_i64(tra, cpu_R[ra]);
-                tcg_gen_extu_i32_i64(trb, cpu_R[rb]);
-                tcg_gen_mul_i64(result, tra, trb);
-                tcg_temp_free_i64(tra);
-                tcg_temp_free_i64(trb);
-                tcg_gen_shri_i64(high, result, TARGET_LONG_BITS);
-                /* Overflow or not. */
-                tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab);
-                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, lab);
-                gen_exception(dc, EXCP_RANGE);
-                gen_set_label(lab);
-                tcg_temp_free_i64(high);
-                tcg_gen_trunc_i64_tl(cpu_R[rd], result);
-                tcg_temp_free_i64(result);
-                tcg_temp_free_i32(sr_ove);
-            } else {
-                tcg_gen_movi_tl(cpu_R[rd], 0);
-            }
+            gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             break;
 
         default:
@@ -702,6 +689,7 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     uint32_t L6, K5;
     uint32_t I16, I5, I11, N26, tmp;
     TCGMemOp mop;
+    TCGv t0;
 
     op0 = extract32(insn, 26, 6);
     op1 = extract32(insn, 24, 2);
@@ -878,72 +866,16 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 
     case 0x27:    /* l.addi */
         LOG_DIS("l.addi r%d, r%d, %d\n", rd, ra, I16);
-        {
-            if (I16 == 0) {
-                tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]);
-            } else {
-                TCGLabel *lab = gen_new_label();
-                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_extrl_i64_i32(res, td);
-                tcg_gen_shri_i64(td, td, 32);
-                tcg_gen_andi_i64(td, td, 0x3);
-                /* Jump to lab when no overflow.  */
-                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);
-                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);
-            }
-        }
+        t0 = tcg_const_tl(I16);
+        gen_add(dc, cpu_R[rd], cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x28:    /* l.addic */
         LOG_DIS("l.addic r%d, r%d, %d\n", rd, ra, I16);
-        {
-            TCGLabel *lab = gen_new_label();
-            TCGv_i64 ta = tcg_temp_new_i64();
-            TCGv_i64 td = tcg_temp_local_new_i64();
-            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);
-            tcg_gen_extu_i32_i64(tcy, sr_cy);
-            tcg_gen_addi_i64(td, ta, sign_extend(I16, 16));
-            tcg_gen_add_i64(td, td, tcy);
-            tcg_gen_extrl_i64_i32(res, td);
-            tcg_gen_shri_i64(td, td, 32);
-            tcg_gen_andi_i64(td, td, 0x3);
-            /* Jump to lab when no overflow.  */
-            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);
-            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_i64(tcy);
-            tcg_temp_free_i32(res);
-            tcg_temp_free_i32(sr_cy);
-            tcg_temp_free_i32(sr_ove);
-        }
+        t0 = tcg_const_tl(I16);
+        gen_addc(dc, cpu_R[rd], cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x29:    /* l.andi */
@@ -963,13 +895,9 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 
     case 0x2c:    /* l.muli */
         LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
-        if (ra != 0 && I16 != 0) {
-            TCGv_i32 im = tcg_const_i32(I16);
-            gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], im);
-            tcg_temp_free_i32(im);
-        } else {
-            tcg_gen_movi_tl(cpu_R[rd], 0x0);
-        }
+        t0 = tcg_const_tl(I16);
+        gen_mul(dc, cpu_R[rd], cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x2d:    /* l.mfspr */
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 03/17] target-openrisc: Invert the decoding in dec_calc
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS Richard Henderson
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-03 14:48   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 04/17] target-openrisc: Keep SR_F in a separate variable Richard Henderson
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Decoding the opcodes in the right order reduces by 100+ lines.
Also, it happens to put the opcodes in the same order as Chapter 17.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/translate.c | 300 ++++++++++++++------------------------------
 1 file changed, 94 insertions(+), 206 deletions(-)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 9a8f886..c9e3198 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -419,267 +419,155 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
     rb = extract32(insn, 11, 5);
     rd = extract32(insn, 21, 5);
 
-    switch (op0) {
-    case 0x0000:
-        switch (op1) {
-        case 0x00:    /* l.add */
+    switch (op1) {
+    case 0:
+        switch (op0) {
+        case 0x0: /* l.add */
             LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
             gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0001:    /* l.addc */
-        switch (op1) {
-        case 0x00:
+        case 0x1: /* l.addc */
             LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
             gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0002:    /* l.sub */
-        switch (op1) {
-        case 0x00:
+        case 0x2: /* l.sub */
             LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
             gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0003:    /* l.and */
-        switch (op1) {
-        case 0x00:
+        case 0x3: /* l.and */
             LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0004:    /* l.or */
-        switch (op1) {
-        case 0x00:
+        case 0x4: /* l.or */
             LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0005:
-        switch (op1) {
-        case 0x00:    /* l.xor */
+        case 0x5: /* l.xor */
             LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
             tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x0006:
-        switch (op1) {
-        case 0x03:    /* l.mul */
-            LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
-            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x0009:
-        switch (op1) {
-        case 0x03:    /* l.div */
-            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
-            gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x000a:
-        switch (op1) {
-        case 0x03:    /* l.divu */
-            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
-            gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x000b:
-        switch (op1) {
-        case 0x03:    /* l.mulu */
-            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
-            gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x000e:
-        switch (op1) {
-        case 0x00:    /* l.cmov */
-            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
-            {
-                TCGLabel *lab = gen_new_label();
-                TCGv res = tcg_temp_local_new();
-                TCGv sr_f = tcg_temp_new();
-                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
-                tcg_gen_mov_tl(res, cpu_R[rb]);
-                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
-                tcg_gen_mov_tl(res, cpu_R[ra]);
-                gen_set_label(lab);
-                tcg_gen_mov_tl(cpu_R[rd], res);
-                tcg_temp_free(sr_f);
-                tcg_temp_free(res);
-            }
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x000f:
-        switch (op1) {
-        case 0x00:    /* l.ff1 */
-            LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
-            gen_helper_ff1(cpu_R[rd], cpu_R[ra]);
-            break;
-        case 0x01:    /* l.fl1 */
-            LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
-            gen_helper_fl1(cpu_R[rd], cpu_R[ra]);
-            break;
-
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
+            return;
 
-    case 0x0008:
-        switch (op1) {
-        case 0x00:
+        case 0x8:
             switch (op2) {
-            case 0x00:    /* l.sll */
+            case 0: /* l.sll */
                 LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
                 tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-            case 0x01:    /* l.srl */
+                return;
+            case 1: /* l.srl */
                 LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
                 tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-            case 0x02:    /* l.sra */
+                return;
+            case 2: /* l.sra */
                 LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
                 tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-            case 0x03:    /* l.ror */
+                return;
+            case 3: /* l.ror */
                 LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
                 tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
-                break;
-
-            default:
-                gen_illegal_exception(dc);
-                break;
+                return;
             }
             break;
 
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x000c:
-        switch (op1) {
-        case 0x00:
+        case 0xc:
             switch (op2) {
-            case 0x00:    /* l.exths */
+            case 0: /* l.exths */
                 LOG_DIS("l.exths r%d, r%d\n", rd, ra);
                 tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x01:    /* l.extbs */
+                return;
+            case 1: /* l.extbs */
                 LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
                 tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x02:    /* l.exthz */
+                return;
+            case 2: /* l.exthz */
                 LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
                 tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x03:    /* l.extbz */
+                return;
+            case 3: /* l.extbz */
                 LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
                 tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-
-            default:
-                gen_illegal_exception(dc);
-                break;
+                return;
             }
             break;
 
-        default:
-            gen_illegal_exception(dc);
-            break;
-        }
-        break;
-
-    case 0x000d:
-        switch (op1) {
-        case 0x00:
+        case 0xd:
             switch (op2) {
-            case 0x00:    /* l.extws */
+            case 0: /* l.extws */
                 LOG_DIS("l.extws r%d, r%d\n", rd, ra);
                 tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-            case 0x01:    /* l.extwz */
+                return;
+            case 1: /* l.extwz */
                 LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
                 tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
-                break;
-
-            default:
-                gen_illegal_exception(dc);
-                break;
+                return;
             }
             break;
 
-        default:
-            gen_illegal_exception(dc);
-            break;
+        case 0xe: /* l.cmov */
+            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
+            {
+                TCGLabel *lab = gen_new_label();
+                TCGv res = tcg_temp_local_new();
+                TCGv sr_f = tcg_temp_new();
+                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
+                tcg_gen_mov_tl(res, cpu_R[rb]);
+                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
+                tcg_gen_mov_tl(res, cpu_R[ra]);
+                gen_set_label(lab);
+                tcg_gen_mov_tl(cpu_R[rd], res);
+                tcg_temp_free(sr_f);
+                tcg_temp_free(res);
+            }
+            return;
+
+        case 0xf: /* l.ff1 */
+            LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
+            gen_helper_ff1(cpu_R[rd], cpu_R[ra]);
+            return;
         }
         break;
 
-    default:
-        gen_illegal_exception(dc);
+    case 1:
+        switch (op0) {
+        case 0xf: /* l.fl1 */
+            LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
+            gen_helper_fl1(cpu_R[rd], cpu_R[ra]);
+            return;
+        }
+        break;
+
+    case 2:
+        break;
+
+    case 3:
+        switch (op0) {
+        case 0x6: /* l.mul */
+            LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
+            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
+
+        case 0x9: /* l.div */
+            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
+            gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
+
+        case 0xa: /* l.divu */
+            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
+            gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
+
+        case 0xb: /* l.mulu */
+            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
+            gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
+            return;
+        }
         break;
     }
+    gen_illegal_exception(dc);
 }
 
 static void dec_misc(DisasContext *dc, uint32_t insn)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 04/17] target-openrisc: Keep SR_F in a separate variable
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (2 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 03/17] target-openrisc: Invert the decoding in dec_calc Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-03 15:09   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 05/17] target-openrisc: Use movcond where appropriate Richard Henderson
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

This avoids having to keep merging and extracting the flag from SR.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/cpu.h              | 15 +++++-
 target-openrisc/gdbstub.c          |  4 +-
 target-openrisc/interrupt.c        |  2 +-
 target-openrisc/interrupt_helper.c |  2 +-
 target-openrisc/sys_helper.c       |  5 +-
 target-openrisc/translate.c        | 96 +++++++++++++++-----------------------
 6 files changed, 56 insertions(+), 68 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 36c4f20..e91f2a9 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -288,7 +288,8 @@ typedef struct CPUOpenRISCState {
     target_ulong epcr;        /* Exception PC register */
     target_ulong eear;        /* Exception EA register */
 
-    uint32_t sr;              /* Supervisor register */
+    target_ulong sr_f;        /* the SR_F bit */
+    uint32_t sr;              /* Supervisor register, without SR_F */
     uint32_t vr;              /* Version register */
     uint32_t upr;             /* Unit presence register */
     uint32_t cpucfgr;         /* CPU configure register */
@@ -300,7 +301,6 @@ typedef struct CPUOpenRISCState {
 
     uint32_t flags;           /* cpu_flags, we only use it for exception
                                  in solt so far.  */
-    uint32_t btaken;          /* the SR_F bit */
 
     CPU_COMMON
 
@@ -411,6 +411,17 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env)
     return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
 }
 
+static inline uint32_t cpu_get_sr(CPUOpenRISCState *env)
+{
+    return env->sr + env->sr_f * SR_F;
+}
+
+static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
+{
+    env->sr_f = (val & SR_F) != 0;
+    env->sr = (val & ~SR_F) | SR_FO;
+}
+
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 
 #include "exec/exec-all.h"
diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c
index 18bcc46..96e9d89 100644
--- a/target-openrisc/gdbstub.c
+++ b/target-openrisc/gdbstub.c
@@ -37,7 +37,7 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
             return gdb_get_reg32(mem_buf, env->npc);
 
         case 34:    /* SR */
-            return gdb_get_reg32(mem_buf, env->sr);
+            return gdb_get_reg32(mem_buf, cpu_get_sr(env));
 
         default:
             break;
@@ -72,7 +72,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
             break;
 
         case 34: /* SR */
-            env->sr = tmp;
+            cpu_set_sr(env, tmp);
             break;
 
         default:
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index e480cfd..2d89acb 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -45,7 +45,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
        we need flush TLB when we enter&exit EXCP.  */
     tlb_flush(cs, 1);
 
-    env->esr = env->sr;
+    env->esr = cpu_get_sr(env);
     env->sr &= ~SR_DME;
     env->sr &= ~SR_IME;
     env->sr |= SR_SM;
diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c
index 55a780c..8695fe7 100644
--- a/target-openrisc/interrupt_helper.c
+++ b/target-openrisc/interrupt_helper.c
@@ -31,7 +31,7 @@ void HELPER(rfe)(CPUOpenRISCState *env)
 #endif
     cpu->env.pc = cpu->env.epcr;
     cpu->env.npc = cpu->env.epcr;
-    cpu->env.sr = cpu->env.esr;
+    cpu_set_sr(&cpu->env, cpu->env.esr);
 
 #ifndef CONFIG_USER_ONLY
     if (cpu->env.sr & SR_DME) {
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
index 53ca6bc..0d411eb 100644
--- a/target-openrisc/sys_helper.c
+++ b/target-openrisc/sys_helper.c
@@ -47,8 +47,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
             (rb & (SR_IME | SR_DME | SR_SM))) {
             tlb_flush(cs, 1);
         }
-        env->sr = rb;
-        env->sr |= SR_FO;      /* FO is const equal to 1 */
+        cpu_set_sr(env, rb);
         if (env->sr & SR_DME) {
             env->tlb->cpu_openrisc_map_address_data =
                 &cpu_openrisc_get_phys_data;
@@ -198,7 +197,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
         return env->npc;
 
     case TO_SPR(0, 17): /* SR */
-        return env->sr;
+        return cpu_get_sr(env);
 
     case TO_SPR(0, 18): /* PPC */
         return env->ppc;
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index c9e3198..6520896 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -54,7 +54,7 @@ static TCGv cpu_pc;
 static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
 static TCGv cpu_npc;
 static TCGv cpu_ppc;
-static TCGv_i32 env_btaken;    /* bf/bnf , F flag taken */
+static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
 static TCGv_i32 fpcsr;
 static TCGv machi, maclo;
 static TCGv fpmaddhi, fpmaddlo;
@@ -85,9 +85,8 @@ void openrisc_translate_init(void)
                                  offsetof(CPUOpenRISCState, ppc), "ppc");
     jmp_pc = tcg_global_mem_new(TCG_AREG0,
                                 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
-    env_btaken = tcg_global_mem_new_i32(TCG_AREG0,
-                                        offsetof(CPUOpenRISCState, btaken),
-                                        "btaken");
+    cpu_sr_f = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUOpenRISCState, sr_f), "sr_f");
     fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
@@ -110,16 +109,6 @@ void openrisc_translate_init(void)
     }
 }
 
-/* Writeback SR_F translation space to execution space.  */
-static inline void wb_SR_F(void)
-{
-    TCGLabel *label = gen_new_label();
-    tcg_gen_andi_tl(cpu_sr, cpu_sr, ~SR_F);
-    tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, label);
-    tcg_gen_ori_tl(cpu_sr, cpu_sr, SR_F);
-    gen_set_label(label);
-}
-
 static inline int zero_extend(unsigned int val, int width)
 {
     return val & ((1 << width) - 1);
@@ -220,14 +209,11 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
     case 0x04:     /* l.bf  */
         {
             TCGLabel *lab = gen_new_label();
-            TCGv sr_f = tcg_temp_new();
             tcg_gen_movi_tl(jmp_pc, dc->pc+8);
-            tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
             tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
-                                sr_f, SR_F, lab);
+                                cpu_sr_f, SR_F, lab);
             tcg_gen_movi_tl(jmp_pc, tmp_pc);
             gen_set_label(lab);
-            tcg_temp_free(sr_f);
         }
         break;
     case 0x11:     /* l.jr */
@@ -512,14 +498,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
             {
                 TCGLabel *lab = gen_new_label();
                 TCGv res = tcg_temp_local_new();
-                TCGv sr_f = tcg_temp_new();
-                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);
                 tcg_gen_mov_tl(res, cpu_R[rb]);
-                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);
+                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_sr_f, SR_F, lab);
                 tcg_gen_mov_tl(res, cpu_R[ra]);
                 gen_set_label(lab);
                 tcg_gen_mov_tl(cpu_R[rd], res);
-                tcg_temp_free(sr_f);
                 tcg_temp_free(res);
             }
             return;
@@ -986,7 +969,6 @@ static void dec_comp(DisasContext *dc, uint32_t insn)
     ra = extract32(insn, 16, 5);
     rb = extract32(insn, 11, 5);
 
-    tcg_gen_movi_i32(env_btaken, 0x0);
     /* unsigned integers  */
     tcg_gen_ext32u_tl(cpu_R[ra], cpu_R[ra]);
     tcg_gen_ext32u_tl(cpu_R[rb], cpu_R[rb]);
@@ -994,59 +976,58 @@ static void dec_comp(DisasContext *dc, uint32_t insn)
     switch (op0) {
     case 0x0:    /* l.sfeq */
         LOG_DIS("l.sfeq  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1:    /* l.sfne */
         LOG_DIS("l.sfne  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_NE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x2:    /* l.sfgtu */
         LOG_DIS("l.sfgtu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x3:    /* l.sfgeu */
         LOG_DIS("l.sfgeu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x4:    /* l.sfltu */
         LOG_DIS("l.sfltu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x5:    /* l.sfleu */
         LOG_DIS("l.sfleu  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xa:    /* l.sfgts */
         LOG_DIS("l.sfgts  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GT, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xb:    /* l.sfges */
         LOG_DIS("l.sfges  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_GE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xc:    /* l.sflts */
         LOG_DIS("l.sflts  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LT, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0xd:    /* l.sfles */
         LOG_DIS("l.sfles  r%d, r%d\n", ra, rb);
-        tcg_gen_setcond_tl(TCG_COND_LE, env_btaken, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], cpu_R[rb]);
         break;
 
     default:
         gen_illegal_exception(dc);
         break;
     }
-    wb_SR_F();
 }
 
 static void dec_compi(DisasContext *dc, uint32_t insn)
@@ -1058,65 +1039,63 @@ static void dec_compi(DisasContext *dc, uint32_t insn)
     ra = extract32(insn, 16, 5);
     I16 = extract32(insn, 0, 16);
 
-    tcg_gen_movi_i32(env_btaken, 0x0);
     I16 = sign_extend(I16, 16);
 
     switch (op0) {
     case 0x0:    /* l.sfeqi */
         LOG_DIS("l.sfeqi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_EQ, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x1:    /* l.sfnei */
         LOG_DIS("l.sfnei  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_NE, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x2:    /* l.sfgtui */
         LOG_DIS("l.sfgtui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GTU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x3:    /* l.sfgeui */
         LOG_DIS("l.sfgeui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GEU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x4:    /* l.sfltui */
         LOG_DIS("l.sfltui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LTU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0x5:    /* l.sfleui */
         LOG_DIS("l.sfleui  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LEU, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xa:    /* l.sfgtsi */
         LOG_DIS("l.sfgtsi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GT, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xb:    /* l.sfgesi */
         LOG_DIS("l.sfgesi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_GE, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xc:    /* l.sfltsi */
         LOG_DIS("l.sfltsi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LT, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     case 0xd:    /* l.sflesi */
         LOG_DIS("l.sflesi  r%d, %d\n", ra, I16);
-        tcg_gen_setcondi_tl(TCG_COND_LE, env_btaken, cpu_R[ra], I16);
+        tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[ra], I16);
         break;
 
     default:
         gen_illegal_exception(dc);
         break;
     }
-    wb_SR_F();
 }
 
 static void dec_sys(DisasContext *dc, uint32_t insn)
@@ -1249,32 +1228,32 @@ static void dec_float(DisasContext *dc, uint32_t insn)
 
     case 0x08:    /* lf.sfeq.s */
         LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
-        gen_helper_float_eq_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x09:    /* lf.sfne.s */
         LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
-        gen_helper_float_ne_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ne_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0a:    /* lf.sfgt.s */
         LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
-        gen_helper_float_gt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_gt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0b:    /* lf.sfge.s */
         LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
-        gen_helper_float_ge_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ge_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0c:    /* lf.sflt.s */
         LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
-        gen_helper_float_lt_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0d:    /* lf.sfle.s */
         LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
-        gen_helper_float_le_s(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
 /* not used yet, open it when we need or64.  */
@@ -1335,37 +1314,37 @@ static void dec_float(DisasContext *dc, uint32_t insn)
     case 0x18:     lf.sfeq.d
         LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_eq_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1a:     lf.sfgt.d
         LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_gt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_gt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1b:     lf.sfge.d
         LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_ge_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ge_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x19:     lf.sfne.d
         LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_ne_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_ne_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1c:     lf.sflt.d
         LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_lt_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x1d:     lf.sfle.d
         LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_le_d(env_btaken, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
         break;
 #endif*/
 
@@ -1373,7 +1352,6 @@ static void dec_float(DisasContext *dc, uint32_t insn)
         gen_illegal_exception(dc);
         break;
     }
-    wb_SR_F();
 }
 
 static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 05/17] target-openrisc: Use movcond where appropriate
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (3 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 04/17] target-openrisc: Keep SR_F in a separate variable Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-03 16:04   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags Richard Henderson
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/translate.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 6520896..1aa6bbf 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -208,12 +208,16 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
     case 0x03:     /* l.bnf */
     case 0x04:     /* l.bf  */
         {
-            TCGLabel *lab = gen_new_label();
-            tcg_gen_movi_tl(jmp_pc, dc->pc+8);
-            tcg_gen_brcondi_i32(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
-                                cpu_sr_f, SR_F, lab);
-            tcg_gen_movi_tl(jmp_pc, tmp_pc);
-            gen_set_label(lab);
+            TCGv t_next = tcg_const_tl(dc->pc + 8);
+            TCGv t_true = tcg_const_tl(tmp_pc);
+            TCGv t_zero = tcg_const_tl(0);
+
+            tcg_gen_movcond_tl(op0 == 0x03 ? TCG_COND_EQ : TCG_COND_NE,
+                               jmp_pc, cpu_sr_f, t_zero, t_true, t_next);
+
+            tcg_temp_free(t_next);
+            tcg_temp_free(t_true);
+            tcg_temp_free(t_zero);
         }
         break;
     case 0x11:     /* l.jr */
@@ -496,14 +500,10 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
         case 0xe: /* l.cmov */
             LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);
             {
-                TCGLabel *lab = gen_new_label();
-                TCGv res = tcg_temp_local_new();
-                tcg_gen_mov_tl(res, cpu_R[rb]);
-                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_sr_f, SR_F, lab);
-                tcg_gen_mov_tl(res, cpu_R[ra]);
-                gen_set_label(lab);
-                tcg_gen_mov_tl(cpu_R[rd], res);
-                tcg_temp_free(res);
+                TCGv zero = tcg_const_tl(0);
+                tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[rd], cpu_sr_f, zero,
+                                   cpu_R[ra], cpu_R[rb]);
+                tcg_temp_free(zero);
             }
             return;
 
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (4 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 05/17] target-openrisc: Use movcond where appropriate Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-04 13:05   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 07/17] target-openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
                   ` (10 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Removes a call at execution time for overflow exceptions.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/cpu.h              |  4 ++--
 target-openrisc/exception_helper.c |  2 +-
 target-openrisc/translate.c        | 24 +++++++++++++++---------
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index e91f2a9..8be53e4 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -399,8 +399,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);
+    /* D_FLAG -- branch instruction exception, OVE overflow trap enable.  */
+    *flags = (env->flags & D_FLAG) | (env->sr & SR_OVE);
 }
 
 static inline int cpu_mmu_index(CPUOpenRISCState *env)
diff --git a/target-openrisc/exception_helper.c b/target-openrisc/exception_helper.c
index e6ab3e3..efa3639 100644
--- a/target-openrisc/exception_helper.c
+++ b/target-openrisc/exception_helper.c
@@ -30,7 +30,7 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
 
 void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
 {
-    if (unlikely(test) && (env->sr & SR_OVE)) {
+    if (unlikely(test)) {
         OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
         CPUState *cs = CPU(cpu);
 
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 1aa6bbf..5813fde 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -129,8 +129,8 @@ static inline int sign_extend(unsigned int val, int width)
 static inline void gen_sync_flags(DisasContext *dc)
 {
     /* Sync the tb dependent flag between translate and runtime.  */
-    if (dc->tb_flags != dc->synced_flags) {
-        tcg_gen_movi_tl(env_flags, dc->tb_flags);
+    if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) {
+        tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG);
         dc->synced_flags = dc->tb_flags;
     }
 }
@@ -239,20 +239,26 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
 
 static void gen_ove_cy(DisasContext *dc, TCGv cy)
 {
-    gen_helper_ove(cpu_env, cy);
+    if (dc->tb_flags & SR_OVE) {
+        gen_helper_ove(cpu_env, cy);
+    }
 }
 
 static void gen_ove_ov(DisasContext *dc, TCGv ov)
 {
-    gen_helper_ove(cpu_env, ov);
+    if (dc->tb_flags & SR_OVE) {
+        gen_helper_ove(cpu_env, ov);
+    }
 }
 
 static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov)
 {
-    TCGv t0 = tcg_temp_new();
-    tcg_gen_or_tl(t0, cy, ov);
-    gen_helper_ove(cpu_env, t0);
-    tcg_temp_free(t0);
+    if (dc->tb_flags & SR_OVE) {
+        TCGv t0 = tcg_temp_new();
+        tcg_gen_or_tl(t0, cy, ov);
+        gen_helper_ove(cpu_env, t0);
+        tcg_temp_free(t0);
+    }
 }
 
 static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
@@ -1437,7 +1443,7 @@ static inline void gen_intermediate_code_internal(OpenRISCCPU *cpu,
     dc->flags = cpu->env.cpucfgr;
     dc->mem_idx = cpu_mmu_index(&cpu->env);
     dc->synced_flags = dc->tb_flags = tb->flags;
-    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
+    dc->delayed_branch = (dc->tb_flags & D_FLAG) != 0;
     dc->singlestep_enabled = cs->singlestep_enabled;
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("-----------------------------------------\n");
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 07/17] target-openrisc: Keep SR_CY and SR_OV in a separate variables
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (5 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-04 13:33   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 08/17] target-openrisc: Set flags on helpers Richard Henderson
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

This significantly streamlines carry and overflow production.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/cpu.h              |  13 +++-
 target-openrisc/exception_helper.c |  33 ++++++++---
 target-openrisc/helper.h           |   5 +-
 target-openrisc/int_helper.c       |  36 -----------
 target-openrisc/translate.c        | 118 ++++++++++++-------------------------
 5 files changed, 78 insertions(+), 127 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 8be53e4..99e6e08 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -289,7 +289,9 @@ typedef struct CPUOpenRISCState {
     target_ulong eear;        /* Exception EA register */
 
     target_ulong sr_f;        /* the SR_F bit */
-    uint32_t sr;              /* Supervisor register, without SR_F */
+    target_ulong sr_cy;       /* the SR_CY bit */
+    target_ulong sr_ov;       /* the SR_OV bit (in the high bit only) */
+    uint32_t sr;              /* Supervisor register, without SR_{F,CY,OV} */
     uint32_t vr;              /* Version register */
     uint32_t upr;             /* Unit presence register */
     uint32_t cpucfgr;         /* CPU configure register */
@@ -413,13 +415,18 @@ static inline int cpu_mmu_index(CPUOpenRISCState *env)
 
 static inline uint32_t cpu_get_sr(CPUOpenRISCState *env)
 {
-    return env->sr + env->sr_f * SR_F;
+    return (env->sr
+            + env->sr_f * SR_F
+            + env->sr_cy * SR_CY
+            + ((target_long)env->sr_ov < 0) * SR_OV);
 }
 
 static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
 {
     env->sr_f = (val & SR_F) != 0;
-    env->sr = (val & ~SR_F) | SR_FO;
+    env->sr_cy = (val & SR_CY) != 0;
+    env->sr_ov = (val & SR_OV ? -1 : 0);
+    env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
 }
 
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
diff --git a/target-openrisc/exception_helper.c b/target-openrisc/exception_helper.c
index efa3639..a08cf2d 100644
--- a/target-openrisc/exception_helper.c
+++ b/target-openrisc/exception_helper.c
@@ -28,14 +28,33 @@ void HELPER(exception)(CPUOpenRISCState *env, uint32_t excp)
     raise_exception(cpu, excp);
 }
 
-void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
+static void do_range(CPUOpenRISCState *env, uintptr_t pc)
 {
-    if (unlikely(test)) {
-        OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-        CPUState *cs = CPU(cpu);
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
+    cs->exception_index = EXCP_RANGE;
+    cpu_restore_state(cs, pc);
+    cpu_loop_exit(cs);
+}
+
+void HELPER(ove_cy)(CPUOpenRISCState *env)
+{
+    if (env->sr_cy) {
+        do_range(env, GETPC());
+    }
+}
+
+void HELPER(ove_ov)(CPUOpenRISCState *env)
+{
+    if ((target_long)env->sr_ov < 0) {
+        do_range(env, GETPC());
+    }
+}
 
-        cs->exception_index = EXCP_RANGE;
-        cpu_restore_state(cs, GETPC());
-        cpu_loop_exit(cs);
+void HELPER(ove_cyov)(CPUOpenRISCState *env)
+{
+    if (env->sr_cy || (target_long)env->sr_ov < 0) {
+        do_range(env, GETPC());
     }
 }
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 9711f42..136ec39 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -19,7 +19,9 @@
 
 /* exception */
 DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
-DEF_HELPER_FLAGS_2(ove, TCG_CALL_NO_WG, void, env, tl)
+DEF_HELPER_FLAGS_1(ove_cy, TCG_CALL_NO_WG, void, env)
+DEF_HELPER_FLAGS_1(ove_ov, TCG_CALL_NO_WG, void, env)
+DEF_HELPER_FLAGS_1(ove_cyov, TCG_CALL_NO_WG, void, env)
 
 /* float */
 DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
@@ -57,7 +59,6 @@ FOP_CMP(ge)
 /* int */
 DEF_HELPER_FLAGS_1(ff1, 0, tl, tl)
 DEF_HELPER_FLAGS_1(fl1, 0, tl, tl)
-DEF_HELPER_FLAGS_3(mul32, 0, i32, env, i32, i32)
 
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c
index 6e27aeb..f75e1b3 100644
--- a/target-openrisc/int_helper.c
+++ b/target-openrisc/int_helper.c
@@ -41,39 +41,3 @@ target_ulong HELPER(fl1)(target_ulong x)
     return 32 - clz32(x);
 /*#endif*/
 }
-
-uint32_t HELPER(mul32)(CPUOpenRISCState *env,
-                       uint32_t ra, uint32_t rb)
-{
-    uint64_t result;
-    uint32_t high, cy;
-
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
-    result = (uint64_t)ra * rb;
-    /* regisiers in or32 is 32bit, so 32 is NOT a magic number.
-       or64 is not handled in this function, and not implement yet,
-       TARGET_LONG_BITS for or64 is 64, it will break this function,
-       so, we didn't use TARGET_LONG_BITS here.  */
-    high = result >> 32;
-    cy = result >> (32 - 1);
-
-    if ((cy & 0x1) == 0x0) {
-        if (high == 0x0) {
-            return result;
-        }
-    }
-
-    if ((cy & 0x1) == 0x1) {
-        if (high == 0xffffffff) {
-            return result;
-        }
-    }
-
-    cpu->env.sr |= (SR_OV | SR_CY);
-    if (cpu->env.sr & SR_OVE) {
-        raise_exception(cpu, EXCP_RANGE);
-    }
-
-    return result;
-}
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 5813fde..c3eb3b1 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -55,6 +55,8 @@ static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
 static TCGv cpu_npc;
 static TCGv cpu_ppc;
 static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
+static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
+static TCGv cpu_sr_ov;          /* signed overflow */
 static TCGv_i32 fpcsr;
 static TCGv machi, maclo;
 static TCGv fpmaddhi, fpmaddlo;
@@ -87,6 +89,10 @@ void openrisc_translate_init(void)
                                 offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
     cpu_sr_f = tcg_global_mem_new(TCG_AREG0,
                                  offsetof(CPUOpenRISCState, sr_f), "sr_f");
+    cpu_sr_cy = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
+    cpu_sr_ov = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
     fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
@@ -237,27 +243,24 @@ static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
     gen_sync_flags(dc);
 }
 
-static void gen_ove_cy(DisasContext *dc, TCGv cy)
+static void gen_ove_cy(DisasContext *dc)
 {
     if (dc->tb_flags & SR_OVE) {
-        gen_helper_ove(cpu_env, cy);
+        gen_helper_ove_cy(cpu_env);
     }
 }
 
-static void gen_ove_ov(DisasContext *dc, TCGv ov)
+static void gen_ove_ov(DisasContext *dc)
 {
     if (dc->tb_flags & SR_OVE) {
-        gen_helper_ove(cpu_env, ov);
+        gen_helper_ove_ov(cpu_env);
     }
 }
 
-static void gen_ove_cyov(DisasContext *dc, TCGv cy, TCGv ov)
+static void gen_ove_cyov(DisasContext *dc)
 {
     if (dc->tb_flags & SR_OVE) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_or_tl(t0, cy, ov);
-        gen_helper_ove(cpu_env, t0);
-        tcg_temp_free(t0);
+        gen_helper_ove_cyov(cpu_env);
     }
 }
 
@@ -265,143 +268,100 @@ static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
     TCGv t0 = tcg_const_tl(0);
     TCGv res = tcg_temp_new();
-    TCGv sr_cy = tcg_temp_new();
-    TCGv sr_ov = tcg_temp_new();
 
-    tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0);
-    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, srcb, t0);
+    tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
     tcg_gen_xor_tl(t0, res, srcb);
-    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
     tcg_temp_free(t0);
 
     tcg_gen_mov_tl(dest, res);
     tcg_temp_free(res);
 
-    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_cyov(dc, sr_ov, sr_cy);
-    tcg_temp_free(sr_ov);
-    tcg_temp_free(sr_cy);
+    gen_ove_cyov(dc);
 }
 
 static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
     TCGv t0 = tcg_const_tl(0);
     TCGv res = tcg_temp_new();
-    TCGv sr_cy = tcg_temp_new();
-    TCGv sr_ov = tcg_temp_new();
-
-    tcg_gen_shri_tl(sr_cy, cpu_sr, ctz32(SR_CY));
-    tcg_gen_andi_tl(sr_cy, sr_cy, 1);
 
-    tcg_gen_add2_tl(res, sr_cy, srca, t0, sr_cy, t0);
-    tcg_gen_add2_tl(res, sr_cy, res, sr_cy, srcb, t0);
-    tcg_gen_xor_tl(sr_ov, srca, srcb);
+    tcg_gen_add2_tl(res, cpu_sr_cy, srca, t0, cpu_sr_cy, t0);
+    tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, t0);
+    tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
     tcg_gen_xor_tl(t0, res, srcb);
-    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
+    tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
     tcg_temp_free(t0);
 
     tcg_gen_mov_tl(dest, res);
     tcg_temp_free(res);
 
-    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_cyov(dc, sr_ov, sr_cy);
-    tcg_temp_free(sr_ov);
-    tcg_temp_free(sr_cy);
+    gen_ove_cyov(dc);
 }
 
 static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
     TCGv res = tcg_temp_new();
-    TCGv sr_cy = tcg_temp_new();
-    TCGv sr_ov = tcg_temp_new();
 
     tcg_gen_sub_tl(res, srca, srcb);
-    tcg_gen_xor_tl(sr_cy, srca, srcb);
-    tcg_gen_xor_tl(sr_ov, res, srcb);
-    tcg_gen_and_tl(sr_ov, sr_ov, sr_cy);
-    tcg_gen_setcond_tl(TCG_COND_LTU, sr_cy, srca, srcb);
+    tcg_gen_xor_tl(cpu_sr_cy, srca, srcb);
+    tcg_gen_xor_tl(cpu_sr_ov, res, srcb);
+    tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy);
+    tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb);
 
     tcg_gen_mov_tl(dest, res);
     tcg_temp_free(res);
 
-    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_cyov(dc, sr_ov, sr_cy);
-    tcg_temp_free(sr_ov);
-    tcg_temp_free(sr_cy);
+    gen_ove_cyov(dc);
 }
 
 static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_ov = tcg_temp_new();
     TCGv t0 = tcg_temp_new();
 
-    tcg_gen_muls2_tl(dest, sr_ov, srca, srcb);
+    tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb);
     tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
-    tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0);
+    tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0);
     tcg_temp_free(t0);
 
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_ov(dc, sr_ov);
-    tcg_temp_free(sr_ov);
+    tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
+    gen_ove_ov(dc);
 }
 
 static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_cy = tcg_temp_new();
-
-    tcg_gen_muls2_tl(dest, sr_cy, srca, srcb);
-    tcg_gen_setcondi_tl(TCG_COND_NE, sr_cy, sr_cy, 0);
-
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
+    tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb);
+    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0);
 
-    gen_ove_cy(dc, sr_cy);
-    tcg_temp_free(sr_cy);
+    gen_ove_cy(dc);
 }
 
 static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_ov = tcg_temp_new();
     TCGv t0 = tcg_temp_new();
 
-    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_ov, srcb, 0);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0);
     /* The result of divide-by-zero is undefined.
        Supress the host-side exception by dividing by 1.  */
-    tcg_gen_or_tl(t0, srcb, sr_ov);
+    tcg_gen_or_tl(t0, srcb, cpu_sr_ov);
     tcg_gen_div_tl(dest, srca, t0);
     tcg_temp_free(t0);
 
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
-
-    gen_ove_ov(dc, sr_ov);
-    tcg_temp_free(sr_ov);
+    gen_ove_ov(dc);
 }
 
 static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
 {
-    TCGv sr_cy = tcg_temp_new();
     TCGv t0 = tcg_temp_new();
 
-    tcg_gen_setcondi_tl(TCG_COND_EQ, sr_cy, srcb, 0);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0);
     /* The result of divide-by-zero is undefined.
        Supress the host-side exception by dividing by 1.  */
-    tcg_gen_or_tl(t0, srcb, sr_cy);
+    tcg_gen_or_tl(t0, srcb, cpu_sr_cy);
     tcg_gen_divu_tl(dest, srca, t0);
     tcg_temp_free(t0);
 
-    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
-
-    gen_ove_cy(dc, sr_cy);
-    tcg_temp_free(sr_cy);
+    gen_ove_cy(dc);
 }
 
 static void dec_calc(DisasContext *dc, uint32_t insn)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 08/17] target-openrisc: Set flags on helpers
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (6 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 07/17] target-openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-04 13:58   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 09/17] target-openrisc: Implement ff1 and fl1 for 64-bit Richard Henderson
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/helper.h | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 136ec39..4b0a935 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -18,26 +18,26 @@
  */
 
 /* exception */
-DEF_HELPER_FLAGS_2(exception, 0, void, env, i32)
+DEF_HELPER_FLAGS_2(exception, TCG_CALL_NO_WG, void, env, i32)
 DEF_HELPER_FLAGS_1(ove_cy, TCG_CALL_NO_WG, void, env)
 DEF_HELPER_FLAGS_1(ove_ov, TCG_CALL_NO_WG, void, env)
 DEF_HELPER_FLAGS_1(ove_cyov, TCG_CALL_NO_WG, void, env)
 
 /* float */
-DEF_HELPER_FLAGS_2(itofd, 0, i64, env, i64)
-DEF_HELPER_FLAGS_2(itofs, 0, i32, env, i32)
-DEF_HELPER_FLAGS_2(ftoid, 0, i64, env, i64)
-DEF_HELPER_FLAGS_2(ftois, 0, i32, env, i32)
+DEF_HELPER_FLAGS_2(itofd, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32)
+DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32)
 
 #define FOP_MADD(op)                                             \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
 FOP_MADD(muladd)
 #undef FOP_MADD
 
 #define FOP_CALC(op)                                            \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
 FOP_CALC(add)
 FOP_CALC(sub)
 FOP_CALC(mul)
@@ -46,8 +46,8 @@ FOP_CALC(rem)
 #undef FOP_CALC
 
 #define FOP_CMP(op)                                              \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, 0, i32, env, i32, i32)    \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, 0, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
 FOP_CMP(eq)
 FOP_CMP(lt)
 FOP_CMP(le)
@@ -57,12 +57,12 @@ FOP_CMP(ge)
 #undef FOP_CMP
 
 /* int */
-DEF_HELPER_FLAGS_1(ff1, 0, tl, tl)
-DEF_HELPER_FLAGS_1(fl1, 0, tl, tl)
+DEF_HELPER_FLAGS_1(ff1, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(fl1, TCG_CALL_NO_RWG_SE, tl, tl)
 
 /* interrupt */
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
 /* sys */
 DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl)
-DEF_HELPER_FLAGS_4(mfspr, 0, tl, env, tl, tl, tl)
+DEF_HELPER_FLAGS_4(mfspr, TCG_CALL_NO_WG, tl, env, tl, tl, tl)
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 09/17] target-openrisc: Implement ff1 and fl1 for 64-bit
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (7 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 08/17] target-openrisc: Set flags on helpers Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-04 13:59   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 10/17] target-openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

True, this is unused so far, but commented out is worse than
actually implemented properly.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/int_helper.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/target-openrisc/int_helper.c b/target-openrisc/int_helper.c
index f75e1b3..6e12fab 100644
--- a/target-openrisc/int_helper.c
+++ b/target-openrisc/int_helper.c
@@ -25,19 +25,20 @@
 
 target_ulong HELPER(ff1)(target_ulong x)
 {
-/*#ifdef TARGET_OPENRISC64
-    return x ? ctz64(x) + 1 : 0;
-#else*/
-    return x ? ctz32(x) + 1 : 0;
-/*#endif*/
+    if (x == 0) {
+        return 0;
+    } else if (TARGET_LONG_BITS == 64) {
+        return ctz64(x) + 1;
+    } else {
+        return ctz32(x) + 1;
+    }
 }
 
 target_ulong HELPER(fl1)(target_ulong x)
 {
-/* not used yet, open it when we need or64.  */
-/*#ifdef TARGET_OPENRISC64
-    return 64 - clz64(x);
-#else*/
-    return 32 - clz32(x);
-/*#endif*/
+    if (TARGET_LONG_BITS == 64) {
+        return 64 - clz64(x);
+    } else {
+        return 32 - clz32(x);
+    }
 }
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 10/17] target-openrisc: Represent MACHI:MACLO as a single unit
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (8 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 09/17] target-openrisc: Implement ff1 and fl1 for 64-bit Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-04 15:04   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction Richard Henderson
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Significantly simplifies the implementation of the use of MAC.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/cpu.h        |   3 +-
 target-openrisc/sys_helper.c |  13 +++++
 target-openrisc/translate.c  | 120 +++++++++++++++++++++++--------------------
 3 files changed, 78 insertions(+), 58 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 99e6e08..adb1410 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -279,8 +279,7 @@ typedef struct CPUOpenRISCState {
     target_ulong ppc;         /* Prev PC */
     target_ulong jmp_pc;      /* Jump PC */
 
-    target_ulong machi;       /* Multiply register MACHI */
-    target_ulong maclo;       /* Multiply register MACLO */
+    uint64_t mac;             /* Multiply registers MACHI:MACLO */
 
     target_ulong fpmaddhi;    /* Multiply and add float register FPMADDHI */
     target_ulong fpmaddlo;    /* Multiply and add float register FPMADDLO */
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
index 0d411eb..9f95a97 100644
--- a/target-openrisc/sys_helper.c
+++ b/target-openrisc/sys_helper.c
@@ -118,6 +118,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
+    case TO_SPR(5, 1):  /* MACLO */
+        env->mac = deposit64(env->mac, 0, 32, rb);
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        env->mac = deposit64(env->mac, 32, 32, rb);
+        break;
     case TO_SPR(9, 0):  /* PICMR */
         env->picmr |= rb;
         break;
@@ -243,6 +249,13 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
 
+    case TO_SPR(5, 1):  /* MACLO */
+        return (uint32_t)env->mac;
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        return env->mac >> 32;
+        break;
+
     case TO_SPR(9, 0):  /* PICMR */
         return env->picmr;
 
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index c3eb3b1..1411be8 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -58,7 +58,7 @@ static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
 static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
 static TCGv cpu_sr_ov;          /* signed overflow */
 static TCGv_i32 fpcsr;
-static TCGv machi, maclo;
+static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
 static TCGv fpmaddhi, fpmaddlo;
 static TCGv_i32 env_flags;
 #include "exec/gen-icount.h"
@@ -96,12 +96,9 @@ void openrisc_translate_init(void)
     fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
-    machi = tcg_global_mem_new(TCG_AREG0,
-                               offsetof(CPUOpenRISCState, machi),
-                               "machi");
-    maclo = tcg_global_mem_new(TCG_AREG0,
-                               offsetof(CPUOpenRISCState, maclo),
-                               "maclo");
+    cpu_mac = tcg_global_mem_new_i64(TCG_AREG0,
+                                     offsetof(CPUOpenRISCState, mac),
+                                     "mac");
     fpmaddhi = tcg_global_mem_new(TCG_AREG0,
                                   offsetof(CPUOpenRISCState, fpmaddhi),
                                   "fpmaddhi");
@@ -364,6 +361,58 @@ static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
     gen_ove_cy(dc);
 }
 
+static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during addition stage.  */
+    tcg_gen_xor_i64(t2, cpu_mac, t1);
+    tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_xor_i64(t1, t1, cpu_mac);
+    tcg_gen_andc_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+#if TARGET_LONG_BITS == 32
+    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
+#else
+    tcg_gen_mov_i64(cpu_sr_ov, t1);
+#endif
+    tcg_temp_free_i64(t1);
+
+    gen_ove_ov(dc);
+}
+
+static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during subtraction stage.  */
+    tcg_gen_xor_i64(t2, cpu_mac, t1);
+    tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_xor_i64(t1, t1, cpu_mac);
+    tcg_gen_and_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+#if TARGET_LONG_BITS == 32
+    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
+#else
+    tcg_gen_mov_i64(cpu_sr_ov, t1);
+#endif
+    tcg_temp_free_i64(t1);
+
+    gen_ove_ov(dc);
+}
+
 static void dec_calc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1, op2;
@@ -585,23 +634,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x13:    /* l.maci */
-        LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I11);
+        LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I16);
         {
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            TCGv_i32 dst = tcg_temp_new_i32();
-            TCGv ttmp = tcg_const_tl(tmp);
-            tcg_gen_mul_tl(dst, cpu_R[ra], ttmp);
-            tcg_gen_ext_i32_i64(t1, dst);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_add_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(dst);
-            tcg_temp_free(ttmp);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
+            TCGv imm = tcg_const_tl(sign_extend(I16, 16));
+            gen_mac(dc, cpu_R[ra], imm);
+            tcg_temp_free(imm);
         }
         break;
 
@@ -821,40 +858,12 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
     switch (op0) {
     case 0x0001:    /* l.mac */
         LOG_DIS("l.mac r%d, r%d\n", ra, rb);
-        {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
-            tcg_gen_ext_i32_i64(t1, t0);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_add_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(t0);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
-        }
+        gen_mac(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x0002:    /* l.msb */
         LOG_DIS("l.msb r%d, r%d\n", ra, rb);
-        {
-            TCGv_i32 t0 = tcg_temp_new_i32();
-            TCGv_i64 t1 = tcg_temp_new_i64();
-            TCGv_i64 t2 = tcg_temp_new_i64();
-            tcg_gen_mul_tl(t0, cpu_R[ra], cpu_R[rb]);
-            tcg_gen_ext_i32_i64(t1, t0);
-            tcg_gen_concat_i32_i64(t2, maclo, machi);
-            tcg_gen_sub_i64(t2, t2, t1);
-            tcg_gen_extrl_i64_i32(maclo, t2);
-            tcg_gen_shri_i64(t2, t2, 32);
-            tcg_gen_extrl_i64_i32(machi, t2);
-            tcg_temp_free_i32(t0);
-            tcg_temp_free_i64(t1);
-            tcg_temp_free_i64(t2);
-        }
+        gen_msb(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
     default:
@@ -915,9 +924,8 @@ static void dec_M(DisasContext *dc, uint32_t insn)
 
     case 0x1:    /* l.macrc */
         LOG_DIS("l.macrc  r%d\n", rd);
-        tcg_gen_mov_tl(cpu_R[rd], maclo);
-        tcg_gen_movi_tl(maclo, 0x0);
-        tcg_gen_movi_tl(machi, 0x0);
+        tcg_gen_trunc_i64_tl(cpu_R[rd], cpu_mac);
+        tcg_gen_movi_i64(cpu_mac, 0);
         break;
 
     default:
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (9 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 10/17] target-openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-04 15:24   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode Richard Henderson
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

The architecture manual is consistent in using "I" for signed
fields and "K" for unsigned fields.  Mirror that.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/translate.c | 200 +++++++++++++++++---------------------------
 1 file changed, 75 insertions(+), 125 deletions(-)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 1411be8..83f4ea6 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -112,23 +112,6 @@ void openrisc_translate_init(void)
     }
 }
 
-static inline int zero_extend(unsigned int val, int width)
-{
-    return val & ((1 << width) - 1);
-}
-
-static inline int sign_extend(unsigned int val, int width)
-{
-    int sval;
-
-    /* LSL */
-    val <<= TARGET_LONG_BITS - width;
-    sval = val;
-    /* ASR.  */
-    sval >>= TARGET_LONG_BITS - width;
-    return sval;
-}
-
 static inline void gen_sync_flags(DisasContext *dc)
 {
     /* Sync the tb dependent flag between translate and runtime.  */
@@ -152,29 +135,23 @@ static void gen_illegal_exception(DisasContext *dc)
     dc->is_jmp = DISAS_UPDATE;
 }
 
-/* not used yet, open it when we need or64.  */
-/*#ifdef TARGET_OPENRISC64
-static void check_ob64s(DisasContext *dc)
-{
-    if (!(dc->flags & CPUCFGR_OB64S)) {
-        gen_illegal_exception(dc);
-    }
-}
+#define check_ob64s(dc)                 \
+    do {                                \
+        gen_illegal_exception(dc);      \
+        return;                         \
+    } while (0)
 
-static void check_of64s(DisasContext *dc)
-{
-    if (!(dc->flags & CPUCFGR_OF64S)) {
-        gen_illegal_exception(dc);
-    }
-}
+#define check_of64s(dc)                 \
+    do {                                \
+        gen_illegal_exception(dc);      \
+        return;                         \
+    } while (0)
 
-static void check_ov64s(DisasContext *dc)
-{
-    if (!(dc->flags & CPUCFGR_OV64S)) {
-        gen_illegal_exception(dc);
-    }
-}
-#endif*/
+#define check_ov64s(dc)                 \
+    do {                                \
+        gen_illegal_exception(dc);      \
+        return;                         \
+    } while (0)
 
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
 {
@@ -194,11 +171,9 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
     }
 }
 
-static void gen_jump(DisasContext *dc, uint32_t imm, uint32_t reg, uint32_t op0)
+static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
 {
-    target_ulong tmp_pc;
-    /* N26, 26bits imm */
-    tmp_pc = sign_extend((imm<<2), 26) + dc->pc;
+    target_ulong tmp_pc = dc->pc + n26 * 4;
 
     switch (op0) {
     case 0x00:     /* l.j */
@@ -573,7 +548,8 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     uint32_t op0, op1;
     uint32_t ra, rb, rd;
     uint32_t L6, K5;
-    uint32_t I16, I5, I11, N26, tmp;
+    uint32_t K16, K5_11;
+    int32_t I16, I5_11, N26;
     TCGMemOp mop;
     TCGv t0;
 
@@ -584,11 +560,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
     rd = extract32(insn, 21, 5);
     L6 = extract32(insn, 5, 6);
     K5 = extract32(insn, 0, 5);
-    I16 = extract32(insn, 0, 16);
-    I5 = extract32(insn, 21, 5);
-    I11 = extract32(insn, 0, 11);
-    N26 = extract32(insn, 0, 26);
-    tmp = (I5<<11) + I11;
+    K16 = extract32(insn, 0, 16);
+    I16 = (int16_t)K16;
+    N26 = sextract32(insn, 0, 26);
+    K5_11 = (extract32(insn, 21, 5) << 11) | extract32(insn, 0, 11);
+    I5_11 = (int16_t)K5_11;
 
     switch (op0) {
     case 0x00:    /* l.j */
@@ -634,12 +610,10 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x13:    /* l.maci */
-        LOG_DIS("l.maci %d, r%d, %d\n", I5, ra, I16);
-        {
-            TCGv imm = tcg_const_tl(sign_extend(I16, 16));
-            gen_mac(dc, cpu_R[ra], imm);
-            tcg_temp_free(imm);
-        }
+        LOG_DIS("l.maci r%d, %d\n", ra, I16);
+        t0 = tcg_const_tl(I16);
+        gen_mac(dc, cpu_R[ra], t0);
+        tcg_temp_free(t0);
         break;
 
     case 0x09:    /* l.rfe */
@@ -690,52 +664,40 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         LOG_DIS("l.cust8\n");
         break;
 
-/* not used yet, open it when we need or64.  */
-/*#ifdef TARGET_OPENRISC64
-    case 0x20:     l.ld
+    case 0x20:    /* l.ld */
         LOG_DIS("l.ld r%d, r%d, %d\n", rd, ra, I16);
         check_ob64s(dc);
         mop = MO_TEQ;
         goto do_load;
-#endif*/
-
     case 0x21:    /* l.lwz */
         LOG_DIS("l.lwz r%d, r%d, %d\n", rd, ra, I16);
         mop = MO_TEUL;
         goto do_load;
-
     case 0x22:    /* l.lws */
         LOG_DIS("l.lws r%d, r%d, %d\n", rd, ra, I16);
         mop = MO_TESL;
         goto do_load;
-
     case 0x23:    /* l.lbz */
         LOG_DIS("l.lbz r%d, r%d, %d\n", rd, ra, I16);
         mop = MO_UB;
         goto do_load;
-
     case 0x24:    /* l.lbs */
         LOG_DIS("l.lbs r%d, r%d, %d\n", rd, ra, I16);
         mop = MO_SB;
         goto do_load;
-
     case 0x25:    /* l.lhz */
         LOG_DIS("l.lhz r%d, r%d, %d\n", rd, ra, I16);
         mop = MO_TEUW;
         goto do_load;
-
     case 0x26:    /* l.lhs */
         LOG_DIS("l.lhs r%d, r%d, %d\n", rd, ra, I16);
         mop = MO_TESW;
         goto do_load;
-
     do_load:
-        {
-            TCGv t0 = tcg_temp_new();
-            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(I16, 16));
-            tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop);
-            tcg_temp_free(t0);
-        }
+        t0 = tcg_temp_new();
+        tcg_gen_addi_tl(t0, cpu_R[ra], I16);
+        tcg_gen_qemu_ld_tl(cpu_R[rd], t0, dc->mem_idx, mop);
+        tcg_temp_free(t0);
         break;
 
     case 0x27:    /* l.addi */
@@ -753,18 +715,18 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x29:    /* l.andi */
-        LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, I16);
-        tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
+        LOG_DIS("l.andi r%d, r%d, %d\n", rd, ra, K16);
+        tcg_gen_andi_tl(cpu_R[rd], cpu_R[ra], K16);
         break;
 
     case 0x2a:    /* l.ori */
-        LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, I16);
-        tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], zero_extend(I16, 16));
+        LOG_DIS("l.ori r%d, r%d, %d\n", rd, ra, K16);
+        tcg_gen_ori_tl(cpu_R[rd], cpu_R[ra], K16);
         break;
 
     case 0x2b:    /* l.xori */
         LOG_DIS("l.xori r%d, r%d, %d\n", rd, ra, I16);
-        tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], sign_extend(I16, 16));
+        tcg_gen_xori_tl(cpu_R[rd], cpu_R[ra], I16);
         break;
 
     case 0x2c:    /* l.muli */
@@ -775,70 +737,57 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         break;
 
     case 0x2d:    /* l.mfspr */
-        LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, I16);
-        {
+        LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16);
 #if defined(CONFIG_USER_ONLY)
-            return;
+        return;
 #else
-            TCGv_i32 ti = tcg_const_i32(I16);
-            if (dc->mem_idx == MMU_USER_IDX) {
-                gen_illegal_exception(dc);
-                return;
-            }
-            gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], ti);
-            tcg_temp_free_i32(ti);
-#endif
+        if (dc->mem_idx == MMU_USER_IDX) {
+            gen_illegal_exception(dc);
+            return;
         }
+        t0 = tcg_const_i32(K16);
+        gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], t0);
+        tcg_temp_free(t0);
+#endif
         break;
 
     case 0x30:    /* l.mtspr */
-        LOG_DIS("l.mtspr %d, r%d, r%d, %d\n", I5, ra, rb, I11);
-        {
+        LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11);
 #if defined(CONFIG_USER_ONLY)
-            return;
+        return;
 #else
-            TCGv_i32 im = tcg_const_i32(tmp);
-            if (dc->mem_idx == MMU_USER_IDX) {
-                gen_illegal_exception(dc);
-                return;
-            }
-            gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], im);
-            tcg_temp_free_i32(im);
-#endif
+        if (dc->mem_idx == MMU_USER_IDX) {
+            gen_illegal_exception(dc);
+            return;
         }
+        t0 = tcg_const_tl(K5_11);
+        gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], t0);
+        tcg_temp_free(t0);
+#endif
         break;
 
-/* not used yet, open it when we need or64.  */
-/*#ifdef TARGET_OPENRISC64
-    case 0x34:     l.sd
-        LOG_DIS("l.sd %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+    case 0x34:    /* l.sd */
+        LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11);
         check_ob64s(dc);
         mop = MO_TEQ;
         goto do_store;
-#endif*/
-
     case 0x35:    /* l.sw */
-        LOG_DIS("l.sw %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.sw r%d, r%d, %d\n", ra, rb, I5_11);
         mop = MO_TEUL;
         goto do_store;
-
     case 0x36:    /* l.sb */
-        LOG_DIS("l.sb %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.sb r%d, r%d, %d\n", ra, rb, I5_11);
         mop = MO_UB;
         goto do_store;
-
     case 0x37:    /* l.sh */
-        LOG_DIS("l.sh %d, r%d, r%d, %d\n", I5, ra, rb, I11);
+        LOG_DIS("l.sh r%d, r%d, %d\n", ra, rb, I5_11);
         mop = MO_TEUW;
         goto do_store;
-
     do_store:
-        {
-            TCGv t0 = tcg_temp_new();
-            tcg_gen_addi_tl(t0, cpu_R[ra], sign_extend(tmp, 16));
-            tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop);
-            tcg_temp_free(t0);
-        }
+        t0 = tcg_temp_new();
+        tcg_gen_addi_tl(t0, cpu_R[ra], I5_11);
+        tcg_gen_qemu_st_tl(cpu_R[rb], t0, dc->mem_idx, mop);
+        tcg_temp_free(t0);
         break;
 
     default:
@@ -875,30 +824,32 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
 static void dec_logic(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0;
-    uint32_t rd, ra, L6;
+    uint32_t rd, ra, L6, S6;
     op0 = extract32(insn, 6, 2);
     rd = extract32(insn, 21, 5);
     ra = extract32(insn, 16, 5);
     L6 = extract32(insn, 0, 6);
+    S6 = L6 & (TARGET_LONG_BITS - 1);
 
     switch (op0) {
     case 0x00:    /* l.slli */
         LOG_DIS("l.slli r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        tcg_gen_shli_tl(cpu_R[rd], cpu_R[ra], S6);
         break;
 
     case 0x01:    /* l.srli */
         LOG_DIS("l.srli r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        tcg_gen_shri_tl(cpu_R[rd], cpu_R[ra], S6);
         break;
 
     case 0x02:    /* l.srai */
         LOG_DIS("l.srai r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f)); break;
+        tcg_gen_sari_tl(cpu_R[rd], cpu_R[ra], S6);
+        break;
 
     case 0x03:    /* l.rori */
         LOG_DIS("l.rori r%d, r%d, %d\n", rd, ra, L6);
-        tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], (L6 & 0x1f));
+        tcg_gen_rotri_tl(cpu_R[rd], cpu_R[ra], S6);
         break;
 
     default:
@@ -1007,13 +958,12 @@ static void dec_comp(DisasContext *dc, uint32_t insn)
 static void dec_compi(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0;
-    uint32_t ra, I16;
+    uint32_t ra;
+    int32_t I16;
 
     op0 = extract32(insn, 21, 5);
     ra = extract32(insn, 16, 5);
-    I16 = extract32(insn, 0, 16);
-
-    I16 = sign_extend(I16, 16);
+    I16 = sextract32(insn, 0, 16);
 
     switch (op0) {
     case 0x0:    /* l.sfeqi */
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (10 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-05 21:35   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 13/17] target-openrisc: Enable trap, csync, msync, psync for " Richard Henderson
                   ` (4 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

The architecture manual doesn't say these opcodes are user only.
Leaving them disabled excludes user mode from accessing interesting
SPRs like MACLO/MACHI.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/helper.h     |  4 +--
 target-openrisc/sys_helper.c | 77 +++++++++++++++++---------------------------
 target-openrisc/translate.c  | 32 +++++++-----------
 3 files changed, 43 insertions(+), 70 deletions(-)

diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 4b0a935..ef243cd 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -64,5 +64,5 @@ DEF_HELPER_FLAGS_1(fl1, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(rfe, 0, void, env)
 
 /* sys */
-DEF_HELPER_FLAGS_4(mtspr, 0, void, env, tl, tl, tl)
-DEF_HELPER_FLAGS_4(mfspr, TCG_CALL_NO_WG, tl, env, tl, tl, tl)
+DEF_HELPER_FLAGS_3(mtspr, 0, void, env, i32, tl)
+DEF_HELPER_FLAGS_2(mfspr, TCG_CALL_NO_WG, tl, env, i32)
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
index 9f95a97..19309a2 100644
--- a/target-openrisc/sys_helper.c
+++ b/target-openrisc/sys_helper.c
@@ -23,12 +23,11 @@
 
 #define TO_SPR(group, number) (((group) << 11) + (number))
 
-void HELPER(mtspr)(CPUOpenRISCState *env,
-                   target_ulong ra, target_ulong rb, target_ulong offset)
+void HELPER(mtspr)(CPUOpenRISCState *env, uint32_t spr, target_ulong rb)
 {
 #ifndef CONFIG_USER_ONLY
-    int spr = (ra | offset);
     int idx;
+#endif
 
     OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
     CPUState *cs = CPU(cpu);
@@ -48,6 +47,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
             tlb_flush(cs, 1);
         }
         cpu_set_sr(env, rb);
+#ifndef CONFIG_USER_ONLY
         if (env->sr & SR_DME) {
             env->tlb->cpu_openrisc_map_address_data =
                 &cpu_openrisc_get_phys_data;
@@ -63,6 +63,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
             env->tlb->cpu_openrisc_map_address_code =
                 &cpu_openrisc_get_phys_nommu;
         }
+#endif
         break;
 
     case TO_SPR(0, 18): /* PPC */
@@ -80,6 +81,15 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
     case TO_SPR(0, 64): /* ESR */
         env->esr = rb;
         break;
+
+    case TO_SPR(5, 1):  /* MACLO */
+        env->mac = deposit64(env->mac, 0, 32, rb);
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        env->mac = deposit64(env->mac, 32, 32, rb);
+        break;
+
+#ifndef CONFIG_USER_ONLY
     case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
         if (!(rb & 1)) {
@@ -87,7 +97,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         }
         env->tlb->dtlb[0][idx].mr = rb;
         break;
-
     case TO_SPR(1, 640) ... TO_SPR(1, 640+DTLB_SIZE-1): /* DTLBW0TR 0-127 */
         idx = spr - TO_SPR(1, 640);
         env->tlb->dtlb[0][idx].tr = rb;
@@ -106,7 +115,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         }
         env->tlb->itlb[0][idx].mr = rb;
         break;
-
     case TO_SPR(2, 640) ... TO_SPR(2, 640+ITLB_SIZE-1): /* ITLBW0TR 0-127 */
         idx = spr - TO_SPR(2, 640);
         env->tlb->itlb[0][idx].tr = rb;
@@ -118,12 +126,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
-    case TO_SPR(5, 1):  /* MACLO */
-        env->mac = deposit64(env->mac, 0, 32, rb);
-        break;
-    case TO_SPR(5, 2):  /* MACHI */
-        env->mac = deposit64(env->mac, 32, 32, rb);
-        break;
+
     case TO_SPR(9, 0):  /* PICMR */
         env->picmr |= rb;
         break;
@@ -167,21 +170,19 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
         }
         cpu_openrisc_timer_update(cpu);
         break;
-    default:
+#endif
 
+    default:
         break;
     }
-#endif
 }
 
-target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
-                           target_ulong rd, target_ulong ra, uint32_t offset)
+target_ulong HELPER(mfspr)(CPUOpenRISCState *env, uint32_t spr)
 {
 #ifndef CONFIG_USER_ONLY
-    int spr = (ra | offset);
-    int idx;
-
     OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    int idx;
+#endif
 
     switch (spr) {
     case TO_SPR(0, 0): /* VR */
@@ -217,6 +218,14 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(0, 64): /* ESR */
         return env->esr;
 
+    case TO_SPR(5, 1):  /* MACLO */
+        return (uint32_t)env->mac;
+        break;
+    case TO_SPR(5, 2):  /* MACHI */
+        return env->mac >> 32;
+        break;
+
+#ifndef CONFIG_USER_ONLY
     case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */
         idx = spr - TO_SPR(1, 512);
         return env->tlb->dtlb[0][idx].mr;
@@ -249,13 +258,6 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */
         break;
 
-    case TO_SPR(5, 1):  /* MACLO */
-        return (uint32_t)env->mac;
-        break;
-    case TO_SPR(5, 2):  /* MACHI */
-        return env->mac >> 32;
-        break;
-
     case TO_SPR(9, 0):  /* PICMR */
         return env->picmr;
 
@@ -268,31 +270,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
     case TO_SPR(10, 1): /* TTCR */
         cpu_openrisc_count_update(cpu);
         return env->ttcr;
+#endif
 
     default:
         break;
     }
-#endif
-
-/*If we later need to add tracepoints (or debug printfs) for the return
-value, it may be useful to structure the code like this:
-
-target_ulong ret = 0;
-
-switch() {
-case x:
- ret = y;
- break;
-case z:
- ret = 42;
- break;
-...
-}
-
-later something like trace_spr_read(ret);
-
-return ret;*/
-
-    /* for rd is passed in, if rd unchanged, just keep it back.  */
-    return rd;
+    return 0;
 }
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 83f4ea6..09c7af6 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -738,32 +738,24 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
 
     case 0x2d:    /* l.mfspr */
         LOG_DIS("l.mfspr r%d, r%d, %d\n", rd, ra, K16);
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
+        {
+            TCGv_i32 tmp = tcg_temp_new_i32();
+            tcg_gen_trunc_tl_i32(tmp, cpu_R[ra]);
+            tcg_gen_ori_i32(tmp, tmp, K16);
+            gen_helper_mfspr(cpu_R[rd], cpu_env, tmp);
+            tcg_temp_free_i32(tmp);
         }
-        t0 = tcg_const_i32(K16);
-        gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], t0);
-        tcg_temp_free(t0);
-#endif
         break;
 
     case 0x30:    /* l.mtspr */
         LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11);
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
+        {
+            TCGv_i32 tmp = tcg_temp_new_i32();
+            tcg_gen_trunc_tl_i32(tmp, cpu_R[ra]);
+            tcg_gen_ori_i32(tmp, tmp, K5_11);
+            gen_helper_mtspr(cpu_env, tmp, cpu_R[rb]);
+            tcg_temp_free_i32(tmp);
         }
-        t0 = tcg_const_tl(K5_11);
-        gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], t0);
-        tcg_temp_free(t0);
-#endif
         break;
 
     case 0x34:    /* l.sd */
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 13/17] target-openrisc: Enable trap, csync, msync, psync for user mode
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (11 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-06  9:30   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu Richard Henderson
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Not documented as disabled for user mode.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/translate.c | 32 --------------------------------
 1 file changed, 32 deletions(-)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 09c7af6..6b96c53 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1032,52 +1032,20 @@ static void dec_sys(DisasContext *dc, uint32_t insn)
 
     case 0x100:    /* l.trap */
         LOG_DIS("l.trap %d\n", K16);
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
         tcg_gen_movi_tl(cpu_pc, dc->pc);
         gen_exception(dc, EXCP_TRAP);
-#endif
         break;
 
     case 0x300:    /* l.csync */
         LOG_DIS("l.csync\n");
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
-#endif
         break;
 
     case 0x200:    /* l.msync */
         LOG_DIS("l.msync\n");
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
-#endif
         break;
 
     case 0x270:    /* l.psync */
         LOG_DIS("l.psync\n");
-#if defined(CONFIG_USER_ONLY)
-        return;
-#else
-        if (dc->mem_idx == MMU_USER_IDX) {
-            gen_illegal_exception(dc);
-            return;
-        }
-#endif
         break;
 
     default:
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (12 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 13/17] target-openrisc: Enable trap, csync, msync, psync for " Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-06 11:38   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd Richard Henderson
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/translate.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 6b96c53..cd684c7 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -336,6 +336,54 @@ static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
     gen_ove_cy(dc);
 }
 
+static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_ext_tl_i64(t1, srca);
+    tcg_gen_ext_tl_i64(t2, srcb);
+    if (TARGET_LONG_BITS == 32) {
+        tcg_gen_mul_i64(cpu_mac, t1, t2);
+    } else {
+        TCGv_i64 high = tcg_temp_new_i64();
+
+        tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
+        tcg_gen_sari_i64(t1, cpu_mac, 63);
+        tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high);
+        tcg_temp_free_i64(high);
+        tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
+        tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
+
+        gen_ove_ov(dc);
+    }
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+}
+
+static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_extu_tl_i64(t1, srca);
+    tcg_gen_extu_tl_i64(t2, srcb);
+    if (TARGET_LONG_BITS == 32) {
+        tcg_gen_mul_i64(cpu_mac, t1, t2);
+    } else {
+        TCGv_i64 high = tcg_temp_new_i64();
+
+        tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
+        tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
+        tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
+        tcg_temp_free_i64(high);
+
+        gen_ove_cy(dc);
+    }
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+}
+
 static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
 {
     TCGv_i64 t1 = tcg_temp_new_i64();
@@ -362,6 +410,25 @@ static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
     gen_ove_ov(dc);
 }
 
+static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_extu_tl_i64(t1, srca);
+    tcg_gen_extu_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+    tcg_temp_free_i64(t2);
+
+    /* Note that overflow is only computed during addition stage.  */
+    tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
+    tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
+    tcg_temp_free_i64(t1);
+
+    gen_ove_cy(dc);
+}
+
 static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
 {
     TCGv_i64 t1 = tcg_temp_new_i64();
@@ -388,6 +455,25 @@ static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
     gen_ove_ov(dc);
 }
 
+static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
+{
+    TCGv_i64 t1 = tcg_temp_new_i64();
+    TCGv_i64 t2 = tcg_temp_new_i64();
+
+    tcg_gen_extu_tl_i64(t1, srca);
+    tcg_gen_extu_tl_i64(t2, srcb);
+    tcg_gen_mul_i64(t1, t1, t2);
+
+    /* Note that overflow is only computed during subtraction stage.  */
+    tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
+    tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
+    tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
+    tcg_temp_free_i64(t2);
+    tcg_temp_free_i64(t1);
+
+    gen_ove_cy(dc);
+}
+
 static void dec_calc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1, op2;
@@ -523,6 +609,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
             gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             return;
 
+        case 0x7: /* l.muld */
+            LOG_DIS("l.muld r%d, r%d\n", ra, rb);
+            gen_muld(dc, cpu_R[ra], cpu_R[rb]);
+            break;
+
         case 0x9: /* l.div */
             LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
             gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
@@ -537,6 +628,11 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
             LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
             gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
             return;
+
+        case 0xc: /* l.muldu */
+            LOG_DIS("l.muldu r%d, r%d\n", ra, rb);
+            gen_muldu(dc, cpu_R[ra], cpu_R[rb]);
+            return;
         }
         break;
     }
@@ -807,6 +903,16 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
         gen_msb(dc, cpu_R[ra], cpu_R[rb]);
         break;
 
+    case 0x0003:    /* l.macu */
+        LOG_DIS("l.macu r%d, r%d\n", ra, rb);
+        gen_macu(dc, cpu_R[ra], cpu_R[rb]);
+        break;
+
+    case 0x0004:    /* l.msbu */
+        LOG_DIS("l.msbu r%d, r%d\n", ra, rb);
+        gen_msbu(dc, cpu_R[ra], cpu_R[rb]);
+        break;
+
     default:
         gen_illegal_exception(dc);
         break;
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (13 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-13  8:21   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception Richard Henderson
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa Richard Henderson
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Note that the specification for lf.madd.s is confused.  It's
the only mention of supposed FPMADDHI/FPMADDLO special registers.
On the other hand, or1ksim implements a somewhat normal non-fused
multiply and add.  Mirror that.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/cpu.h        |  3 --
 target-openrisc/fpu_helper.c | 68 ++++++++++++++++----------------------------
 target-openrisc/helper.h     |  7 ++---
 target-openrisc/translate.c  | 13 +++------
 4 files changed, 30 insertions(+), 61 deletions(-)

diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index adb1410..5ddf477 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -281,9 +281,6 @@ typedef struct CPUOpenRISCState {
 
     uint64_t mac;             /* Multiply registers MACHI:MACLO */
 
-    target_ulong fpmaddhi;    /* Multiply and add float register FPMADDHI */
-    target_ulong fpmaddlo;    /* Multiply and add float register FPMADDLO */
-
     target_ulong epcr;        /* Exception PC register */
     target_ulong eear;        /* Exception EA register */
 
diff --git a/target-openrisc/fpu_helper.c b/target-openrisc/fpu_helper.c
index c94ed35..d612012 100644
--- a/target-openrisc/fpu_helper.c
+++ b/target-openrisc/fpu_helper.c
@@ -145,52 +145,32 @@ FLOAT_CALC(div)
 FLOAT_CALC(rem)
 #undef FLOAT_CALC
 
-#define FLOAT_TERNOP(name1, name2)                                        \
-uint64_t helper_float_ ## name1 ## name2 ## _d(CPUOpenRISCState *env,     \
-                                               uint64_t fdt0,             \
-                                               uint64_t fdt1)             \
-{                                                                         \
-    uint64_t result, temp, hi, lo;                                        \
-    uint32_t val1, val2;                                                  \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    hi = env->fpmaddhi;                                                   \
-    lo = env->fpmaddlo;                                                   \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    result = float64_ ## name1(fdt0, fdt1, &cpu->env.fp_status);          \
-    lo &= 0xffffffff;                                                     \
-    hi &= 0xffffffff;                                                     \
-    temp = (hi << 32) | lo;                                               \
-    result = float64_ ## name2(result, temp, &cpu->env.fp_status);        \
-    val1 = result >> 32;                                                  \
-    val2 = (uint32_t) (result & 0xffffffff);                              \
-    update_fpcsr(cpu);                                                    \
-    cpu->env.fpmaddlo = val2;                                             \
-    cpu->env.fpmaddhi = val1;                                             \
-    return 0;                                                             \
-}                                                                         \
-                                                                          \
-uint32_t helper_float_ ## name1 ## name2 ## _s(CPUOpenRISCState *env,     \
-                                            uint32_t fdt0, uint32_t fdt1) \
-{                                                                         \
-    uint64_t result, temp, hi, lo;                                        \
-    uint32_t val1, val2;                                                  \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    hi = cpu->env.fpmaddhi;                                               \
-    lo = cpu->env.fpmaddlo;                                               \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    result = float64_ ## name1(fdt0, fdt1, &cpu->env.fp_status);          \
-    temp = (hi << 32) | lo;                                               \
-    result = float64_ ## name2(result, temp, &cpu->env.fp_status);        \
-    val1 = result >> 32;                                                  \
-    val2 = (uint32_t) (result & 0xffffffff);                              \
-    update_fpcsr(cpu);                                                    \
-    cpu->env.fpmaddlo = val2;                                             \
-    cpu->env.fpmaddhi = val1;                                             \
-    return 0;                                                             \
+
+uint64_t helper_float_madd_d(CPUOpenRISCState *env, uint64_t a,
+                             uint64_t b, uint64_t c)
+{
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    uint64_t result;
+    set_float_exception_flags(0, &cpu->env.fp_status);
+    /* Note that or1ksim doesn't use merged operation.  */
+    result = float64_mul(b, c, &cpu->env.fp_status);
+    result = float64_add(result, a, &cpu->env.fp_status);
+    update_fpcsr(cpu);
+    return result;
 }
 
-FLOAT_TERNOP(mul, add)
-#undef FLOAT_TERNOP
+uint32_t helper_float_madd_s(CPUOpenRISCState *env, uint32_t a,
+                             uint32_t b, uint32_t c)
+{
+    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
+    uint32_t result;
+    set_float_exception_flags(0, &cpu->env.fp_status);
+    /* Note that or1ksim doesn't use merged operation.  */
+    result = float32_mul(b, c, &cpu->env.fp_status);
+    result = float32_add(result, a, &cpu->env.fp_status);
+    update_fpcsr(cpu);
+    return result;
+}
 
 
 #define FLOAT_CMP(name)                                                   \
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index ef243cd..58abeb8 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -29,11 +29,8 @@ DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32)
 DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32)
 
-#define FOP_MADD(op)                                             \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
-FOP_MADD(muladd)
-#undef FOP_MADD
+DEF_HELPER_FLAGS_4(float_madd_s, TCG_CALL_NO_WG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(float_madd_d, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
 
 #define FOP_CALC(op)                                            \
 DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index cd684c7..ca1827e 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -59,7 +59,6 @@ static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
 static TCGv cpu_sr_ov;          /* signed overflow */
 static TCGv_i32 fpcsr;
 static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
-static TCGv fpmaddhi, fpmaddlo;
 static TCGv_i32 env_flags;
 #include "exec/gen-icount.h"
 
@@ -99,12 +98,6 @@ void openrisc_translate_init(void)
     cpu_mac = tcg_global_mem_new_i64(TCG_AREG0,
                                      offsetof(CPUOpenRISCState, mac),
                                      "mac");
-    fpmaddhi = tcg_global_mem_new(TCG_AREG0,
-                                  offsetof(CPUOpenRISCState, fpmaddhi),
-                                  "fpmaddhi");
-    fpmaddlo = tcg_global_mem_new(TCG_AREG0,
-                                  offsetof(CPUOpenRISCState, fpmaddlo),
-                                  "fpmaddlo");
     for (i = 0; i < 32; i++) {
         cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
                                       offsetof(CPUOpenRISCState, gpr[i]),
@@ -1213,7 +1206,8 @@ static void dec_float(DisasContext *dc, uint32_t insn)
 
     case 0x07:    /* lf.madd.s */
         LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
-        gen_helper_float_muladd_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
+                                cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x08:    /* lf.sfeq.s */
@@ -1298,7 +1292,8 @@ static void dec_float(DisasContext *dc, uint32_t insn)
     case 0x17:     lf.madd.d
         LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
-        gen_helper_float_muladd_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
+                                cpu_R[ra], cpu_R[rb]);
         break;
 
     case 0x18:     lf.sfeq.d
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (14 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-15 13:02   ` Bastian Koppelmann
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa Richard Henderson
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

The architecture manual is unclear about this, but the or1ksim
does writeback before the exception.  This requires splitting
the helpers in half, with the exception raised by the second.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-openrisc/fpu_helper.c | 252 +++++++++----------------------------------
 target-openrisc/helper.h     |  25 +++--
 target-openrisc/translate.c  | 118 +++++++++++---------
 3 files changed, 129 insertions(+), 266 deletions(-)

diff --git a/target-openrisc/fpu_helper.c b/target-openrisc/fpu_helper.c
index d612012..05b1077 100644
--- a/target-openrisc/fpu_helper.c
+++ b/target-openrisc/fpu_helper.c
@@ -22,121 +22,70 @@
 #include "exec/helper-proto.h"
 #include "exception.h"
 
-static inline uint32_t ieee_ex_to_openrisc(OpenRISCCPU *cpu, int fexcp)
+static int ieee_ex_to_openrisc(int fexcp)
 {
     int ret = 0;
-    if (fexcp) {
-        if (fexcp & float_flag_invalid) {
-            cpu->env.fpcsr |= FPCSR_IVF;
-            ret = 1;
-        }
-        if (fexcp & float_flag_overflow) {
-            cpu->env.fpcsr |= FPCSR_OVF;
-            ret = 1;
-        }
-        if (fexcp & float_flag_underflow) {
-            cpu->env.fpcsr |= FPCSR_UNF;
-            ret = 1;
-        }
-        if (fexcp & float_flag_divbyzero) {
-            cpu->env.fpcsr |= FPCSR_DZF;
-            ret = 1;
-        }
-        if (fexcp & float_flag_inexact) {
-            cpu->env.fpcsr |= FPCSR_IXF;
-            ret = 1;
-        }
+    if (fexcp & float_flag_invalid) {
+        ret |= FPCSR_IVF;
+    }
+    if (fexcp & float_flag_overflow) {
+        ret |= FPCSR_OVF;
+    }
+    if (fexcp & float_flag_underflow) {
+        ret |= FPCSR_UNF;
+    }
+    if (fexcp & float_flag_divbyzero) {
+        ret |= FPCSR_DZF;
+    }
+    if (fexcp & float_flag_inexact) {
+        ret |= FPCSR_IXF;
     }
-
     return ret;
 }
 
-static inline void update_fpcsr(OpenRISCCPU *cpu)
+void HELPER(update_fpcsr)(CPUOpenRISCState *env)
 {
-    int tmp = ieee_ex_to_openrisc(cpu,
-                              get_float_exception_flags(&cpu->env.fp_status));
-
-    SET_FP_CAUSE(cpu->env.fpcsr, tmp);
-    if ((GET_FP_ENABLE(cpu->env.fpcsr) & tmp) &&
-        (cpu->env.fpcsr & FPCSR_FPEE)) {
-        helper_exception(&cpu->env, EXCP_FPE);
-    } else {
-        UPDATE_FP_FLAGS(cpu->env.fpcsr, tmp);
+    int tmp = get_float_exception_flags(&env->fp_status);
+
+    if (tmp) {
+        set_float_exception_flags(0, &env->fp_status);
+        tmp = ieee_ex_to_openrisc(tmp);
+        if (tmp) {
+            env->fpcsr |= tmp;
+            if (env->fpcsr & FPCSR_FPEE) {
+                helper_exception(env, EXCP_FPE);
+            }
+        }
     }
 }
 
 uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
 {
-    uint64_t itofd;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
-    set_float_exception_flags(0, &cpu->env.fp_status);
-    itofd = int32_to_float64(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
-
-    return itofd;
+    return int32_to_float64(val, &env->fp_status);
 }
 
 uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
 {
-    uint32_t itofs;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
-    set_float_exception_flags(0, &cpu->env.fp_status);
-    itofs = int32_to_float32(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
-
-    return itofs;
+    return int32_to_float32(val, &env->fp_status);
 }
 
 uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
 {
-    uint64_t ftoid;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
-    set_float_exception_flags(0, &cpu->env.fp_status);
-    ftoid = float32_to_int64(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
-
-    return ftoid;
+    return float32_to_int64(val, &env->fp_status);
 }
 
 uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
 {
-    uint32_t ftois;
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-
-    set_float_exception_flags(0, &cpu->env.fp_status);
-    ftois = float32_to_int32(val, &cpu->env.fp_status);
-    update_fpcsr(cpu);
-
-    return ftois;
+    return float32_to_int32(val, &env->fp_status);
 }
 
-#define FLOAT_OP(name, p) void helper_float_##_##p(void)
-
 #define FLOAT_CALC(name)                                                  \
 uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
                                      uint64_t fdt0, uint64_t fdt1)        \
-{                                                                         \
-    uint64_t result;                                                      \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    result = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status);           \
-    update_fpcsr(cpu);                                                    \
-    return result;                                                        \
-}                                                                         \
-                                                                          \
+{ return float64_ ## name(fdt0, fdt1, &env->fp_status); }                 \
 uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
                                      uint32_t fdt0, uint32_t fdt1)        \
-{                                                                         \
-    uint32_t result;                                                      \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    result = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status);           \
-    update_fpcsr(cpu);                                                    \
-    return result;                                                        \
-}                                                                         \
+{ return float32_ ## name(fdt0, fdt1, &env->fp_status); }
 
 FLOAT_CALC(add)
 FLOAT_CALC(sub)
@@ -149,132 +98,29 @@ FLOAT_CALC(rem)
 uint64_t helper_float_madd_d(CPUOpenRISCState *env, uint64_t a,
                              uint64_t b, uint64_t c)
 {
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-    uint64_t result;
-    set_float_exception_flags(0, &cpu->env.fp_status);
-    /* Note that or1ksim doesn't use merged operation.  */
-    result = float64_mul(b, c, &cpu->env.fp_status);
-    result = float64_add(result, a, &cpu->env.fp_status);
-    update_fpcsr(cpu);
-    return result;
+    /* Note that or1ksim doesn't use fused operation.  */
+    b = float64_mul(b, c, &env->fp_status);
+    return float64_add(a, b, &env->fp_status);
 }
 
 uint32_t helper_float_madd_s(CPUOpenRISCState *env, uint32_t a,
                              uint32_t b, uint32_t c)
 {
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-    uint32_t result;
-    set_float_exception_flags(0, &cpu->env.fp_status);
-    /* Note that or1ksim doesn't use merged operation.  */
-    result = float32_mul(b, c, &cpu->env.fp_status);
-    result = float32_add(result, a, &cpu->env.fp_status);
-    update_fpcsr(cpu);
-    return result;
+    /* Note that or1ksim doesn't use fused operation.  */
+    b = float32_mul(b, c, &env->fp_status);
+    return float32_add(a, b, &env->fp_status);
 }
 
 
-#define FLOAT_CMP(name)                                                   \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
-                                     uint64_t fdt0, uint64_t fdt1)        \
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = float64_ ## name(fdt0, fdt1, &cpu->env.fp_status);              \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}                                                                         \
-                                                                          \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
-                                             uint32_t fdt0, uint32_t fdt1)\
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = float32_ ## name(fdt0, fdt1, &cpu->env.fp_status);              \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}
+#define FLOAT_CMP(name, impl)                                             \
+target_ulong helper_float_ ## name ## _d(CPUOpenRISCState *env,           \
+                                         uint64_t fdt0, uint64_t fdt1)    \
+{ return float64_ ## impl(fdt0, fdt1, &env->fp_status); }                 \
+target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env,           \
+                                         uint32_t fdt0, uint32_t fdt1)    \
+{ return float32_ ## impl(fdt0, fdt1, &env->fp_status); }
 
-FLOAT_CMP(le)
-FLOAT_CMP(eq)
-FLOAT_CMP(lt)
+FLOAT_CMP(le, le)
+FLOAT_CMP(lt, lt)
+FLOAT_CMP(eq, eq_quiet)
 #undef FLOAT_CMP
-
-
-#define FLOAT_CMPNE(name)                                                 \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
-                                     uint64_t fdt0, uint64_t fdt1)        \
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = !float64_eq_quiet(fdt0, fdt1, &cpu->env.fp_status);             \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}                                                                         \
-                                                                          \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
-                                     uint32_t fdt0, uint32_t fdt1)        \
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = !float32_eq_quiet(fdt0, fdt1, &cpu->env.fp_status);             \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}
-
-FLOAT_CMPNE(ne)
-#undef FLOAT_CMPNE
-
-#define FLOAT_CMPGT(name)                                                 \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
-                                     uint64_t fdt0, uint64_t fdt1)        \
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = !float64_le(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}                                                                         \
-                                                                          \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
-                                     uint32_t fdt0, uint32_t fdt1)        \
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = !float32_le(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}
-FLOAT_CMPGT(gt)
-#undef FLOAT_CMPGT
-
-#define FLOAT_CMPGE(name)                                                 \
-uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
-                                     uint64_t fdt0, uint64_t fdt1)        \
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = !float64_lt(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}                                                                         \
-                                                                          \
-uint32_t helper_float_ ## name ## _s(CPUOpenRISCState *env,               \
-                                     uint32_t fdt0, uint32_t fdt1)        \
-{                                                                         \
-    int res;                                                              \
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);                         \
-    set_float_exception_flags(0, &cpu->env.fp_status);                    \
-    res = !float32_lt(fdt0, fdt1, &cpu->env.fp_status);                   \
-    update_fpcsr(cpu);                                                    \
-    return res;                                                           \
-}
-
-FLOAT_CMPGE(ge)
-#undef FLOAT_CMPGE
diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
index 58abeb8..4bc2251 100644
--- a/target-openrisc/helper.h
+++ b/target-openrisc/helper.h
@@ -24,17 +24,19 @@ DEF_HELPER_FLAGS_1(ove_ov, TCG_CALL_NO_WG, void, env)
 DEF_HELPER_FLAGS_1(ove_cyov, TCG_CALL_NO_WG, void, env)
 
 /* float */
-DEF_HELPER_FLAGS_2(itofd, TCG_CALL_NO_WG, i64, env, i64)
-DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_WG, i32, env, i32)
-DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_WG, i64, env, i64)
-DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_WG, i32, env, i32)
+DEF_HELPER_FLAGS_1(update_fpcsr, TCG_CALL_NO_WG, void, env)
 
-DEF_HELPER_FLAGS_4(float_madd_s, TCG_CALL_NO_WG, i32, env, i32, i32, i32)
-DEF_HELPER_FLAGS_4(float_madd_d, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_2(itofd, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(itofs, TCG_CALL_NO_RWG, i32, env, i32)
+DEF_HELPER_FLAGS_2(ftoid, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(ftois, TCG_CALL_NO_RWG, i32, env, i32)
+
+DEF_HELPER_FLAGS_4(float_madd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(float_madd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
 
 #define FOP_CALC(op)                                            \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_RWG, i32, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_RWG, i64, env, i64, i64)
 FOP_CALC(add)
 FOP_CALC(sub)
 FOP_CALC(mul)
@@ -43,14 +45,11 @@ FOP_CALC(rem)
 #undef FOP_CALC
 
 #define FOP_CMP(op)                                              \
-DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_WG, i32, env, i32, i32) \
-DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(float_ ## op ## _s, TCG_CALL_NO_RWG, tl, env, i32, i32) \
+DEF_HELPER_FLAGS_3(float_ ## op ## _d, TCG_CALL_NO_RWG, tl, env, i64, i64)
 FOP_CMP(eq)
 FOP_CMP(lt)
 FOP_CMP(le)
-FOP_CMP(ne)
-FOP_CMP(gt)
-FOP_CMP(ge)
 #undef FOP_CMP
 
 /* int */
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index ca1827e..569f4ab 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -1163,175 +1163,193 @@ static void dec_float(DisasContext *dc, uint32_t insn)
     rd = extract32(insn, 21, 5);
 
     switch (op0) {
-    case 0x00:    /* lf.add.s */
+    case 0x00: /* lf.add.s */
         LOG_DIS("lf.add.s r%d, r%d, r%d\n", rd, ra, rb);
         gen_helper_float_add_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x01:    /* lf.sub.s */
+    case 0x01: /* lf.sub.s */
         LOG_DIS("lf.sub.s r%d, r%d, r%d\n", rd, ra, rb);
         gen_helper_float_sub_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-
-    case 0x02:    /* lf.mul.s */
+    case 0x02: /* lf.mul.s */
         LOG_DIS("lf.mul.s r%d, r%d, r%d\n", rd, ra, rb);
-        if (ra != 0 && rb != 0) {
-            gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
-        } else {
-            tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
-            tcg_gen_movi_i32(cpu_R[rd], 0x0);
-        }
+        gen_helper_float_mul_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x03:    /* lf.div.s */
+    case 0x03: /* lf.div.s */
         LOG_DIS("lf.div.s r%d, r%d, r%d\n", rd, ra, rb);
         gen_helper_float_div_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x04:    /* lf.itof.s */
+    case 0x04: /* lf.itof.s */
         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
         gen_helper_itofs(cpu_R[rd], cpu_env, cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x05:    /* lf.ftoi.s */
+    case 0x05: /* lf.ftoi.s */
         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
         gen_helper_ftois(cpu_R[rd], cpu_env, cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x06:    /* lf.rem.s */
+    case 0x06: /* lf.rem.s */
         LOG_DIS("lf.rem.s r%d, r%d, r%d\n", rd, ra, rb);
         gen_helper_float_rem_s(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x07:    /* lf.madd.s */
+    case 0x07: /* lf.madd.s */
         LOG_DIS("lf.madd.s r%d, r%d, r%d\n", rd, ra, rb);
         gen_helper_float_madd_s(cpu_R[rd], cpu_env, cpu_R[rd],
                                 cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x08:    /* lf.sfeq.s */
+    case 0x08: /* lf.sfeq.s */
         LOG_DIS("lf.sfeq.s r%d, r%d\n", ra, rb);
         gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x09:    /* lf.sfne.s */
+    case 0x09: /* lf.sfne.s */
         LOG_DIS("lf.sfne.s r%d, r%d\n", ra, rb);
-        gen_helper_float_ne_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_eq_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x0a:    /* lf.sfgt.s */
+    case 0x0a: /* lf.sfgt.s */
         LOG_DIS("lf.sfgt.s r%d, r%d\n", ra, rb);
-        gen_helper_float_gt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x0b:    /* lf.sfge.s */
+    case 0x0b: /* lf.sfge.s */
         LOG_DIS("lf.sfge.s r%d, r%d\n", ra, rb);
-        gen_helper_float_ge_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x0c:    /* lf.sflt.s */
+    case 0x0c: /* lf.sflt.s */
         LOG_DIS("lf.sflt.s r%d, r%d\n", ra, rb);
         gen_helper_float_lt_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x0d:    /* lf.sfle.s */
+    case 0x0d: /* lf.sfle.s */
         LOG_DIS("lf.sfle.s r%d, r%d\n", ra, rb);
         gen_helper_float_le_s(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-/* not used yet, open it when we need or64.  */
-/*#ifdef TARGET_OPENRISC64
-    case 0x10:     lf.add.d
+#ifdef TARGET_OPENRISC64
+    case 0x10: /* lf.add.d */
         LOG_DIS("lf.add.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
         gen_helper_float_add_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x11:     lf.sub.d
+    case 0x11: /* lf.sub.d */
         LOG_DIS("lf.sub.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
         gen_helper_float_sub_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x12:     lf.mul.d
+    case 0x12: /* lf.mul.d */
         LOG_DIS("lf.mul.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
-        if (ra != 0 && rb != 0) {
-            gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
-        } else {
-            tcg_gen_ori_tl(fpcsr, fpcsr, FPCSR_ZF);
-            tcg_gen_movi_i64(cpu_R[rd], 0x0);
-        }
+        gen_helper_float_mul_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x13:     lf.div.d
+    case 0x13: /* lf.div.d */
         LOG_DIS("lf.div.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
         gen_helper_float_div_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x14:     lf.itof.d
+    case 0x14: /* lf.itof.d */
         LOG_DIS("lf.itof r%d, r%d\n", rd, ra);
         check_of64s(dc);
         gen_helper_itofd(cpu_R[rd], cpu_env, cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x15:     lf.ftoi.d
+    case 0x15: /* lf.ftoi.d */
         LOG_DIS("lf.ftoi r%d, r%d\n", rd, ra);
         check_of64s(dc);
         gen_helper_ftoid(cpu_R[rd], cpu_env, cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x16:     lf.rem.d
+    case 0x16: /* lf.rem.d */
         LOG_DIS("lf.rem.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
         gen_helper_float_rem_d(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x17:     lf.madd.d
+    case 0x17: /* lf.madd.d */
         LOG_DIS("lf.madd.d r%d, r%d, r%d\n", rd, ra, rb);
         check_of64s(dc);
         gen_helper_float_madd_d(cpu_R[rd], cpu_env, cpu_R[rd],
                                 cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x18:     lf.sfeq.d
+    case 0x18: /* lf.sfeq.d */
         LOG_DIS("lf.sfeq.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
         gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x1a:     lf.sfgt.d
+    case 0x1a: /* lf.sfgt.d */
         LOG_DIS("lf.sfgt.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_gt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x1b:     lf.sfge.d
+    case 0x1b: /* lf.sfge.d */
         LOG_DIS("lf.sfge.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_ge_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[rb], cpu_R[ra]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x19:     lf.sfne.d
+    case 0x19: /* lf.sfne.d */
         LOG_DIS("lf.sfne.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
-        gen_helper_float_ne_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_float_eq_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x1c:     lf.sflt.d
+    case 0x1c: /* lf.sflt.d */
         LOG_DIS("lf.sflt.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
         gen_helper_float_lt_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
 
-    case 0x1d:     lf.sfle.d
+    case 0x1d: /* lf.sfle.d */
         LOG_DIS("lf.sfle.d r%d, r%d\n", ra, rb);
         check_of64s(dc);
         gen_helper_float_le_d(cpu_sr_f, cpu_env, cpu_R[ra], cpu_R[rb]);
+        gen_helper_update_fpcsr(cpu_env);
         break;
-#endif*/
+#endif
 
     default:
         gen_illegal_exception(dc);
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa
  2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
                   ` (15 preceding siblings ...)
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception Richard Henderson
@ 2015-09-03  0:17 ` Richard Henderson
  2015-09-15 13:04   ` Bastian Koppelmann
  16 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03  0:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, proljc

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 linux-user/main.c                  | 45 ++++++++++++++++++++++++
 target-openrisc/cpu.c              |  1 +
 target-openrisc/cpu.h              |  9 +++++
 target-openrisc/interrupt.c        |  1 +
 target-openrisc/interrupt_helper.c |  1 +
 target-openrisc/mmu.c              |  1 +
 target-openrisc/translate.c        | 70 ++++++++++++++++++++++++++++++++++++++
 7 files changed, 128 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 2c9658e..77b301c 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2644,6 +2644,48 @@ error:
 #endif
 
 #ifdef TARGET_OPENRISC
+static void do_store_exclusive(CPUOpenRISCState *env)
+{
+    target_ulong addr, val, tmp;
+    target_siginfo_t info;
+    int ret = 0;
+
+    addr = env->lock_addr;
+    tmp = env->lock_st_addr;
+    env->lock_addr = -1;
+    env->lock_st_addr = 0;
+
+    start_exclusive();
+    mmap_lock();
+
+    if (addr == tmp) {
+        if (get_user_u32(val, addr)) {
+            goto do_sigsegv;
+        }
+        if (val == env->lock_value) {
+            if (put_user_u32(env->lock_st_value, addr)) {
+                goto do_sigsegv;
+            }
+            ret = 1;
+        }
+    }
+    env->sr_f = ret;
+    env->pc += 4;
+
+    mmap_unlock();
+    end_exclusive();
+    return;
+
+ do_sigsegv:
+    mmap_unlock();
+    end_exclusive();
+
+    info.si_signo = TARGET_SIGSEGV;
+    info.si_errno = 0;
+    info.si_code = TARGET_SEGV_MAPERR;
+    info._sifields._sigfault._addr = addr;
+    queue_signal(env, TARGET_SIGSEGV, &info);
+}
 
 void cpu_loop(CPUOpenRISCState *env)
 {
@@ -2713,6 +2755,9 @@ void cpu_loop(CPUOpenRISCState *env)
         case EXCP_NR:
             qemu_log("\nNR\n");
             break;
+	case EXCP_SWA:
+            do_store_exclusive(env);
+            break;
         default:
             qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n",
                      trapnr);
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index d97f3c0..56ceba4 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -52,6 +52,7 @@ static void openrisc_cpu_reset(CPUState *s)
 
     cpu->env.pc = 0x100;
     cpu->env.sr = SR_FO | SR_SM;
+    cpu->env.lock_addr = -1;
     s->exception_index = -1;
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP;
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index 5ddf477..e3afe26 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -171,6 +171,8 @@ enum {
     EXCP_FPE      = 0xd,
     EXCP_TRAP     = 0xe,
     EXCP_NR,
+    /* For usermode emulation.  */
+    EXCP_SWA,
 };
 
 /* Supervisor register */
@@ -297,6 +299,13 @@ typedef struct CPUOpenRISCState {
     uint32_t fpcsr;           /* Float register */
     float_status fp_status;
 
+    target_ulong lock_addr;
+    target_ulong lock_value;
+#ifdef CONFIG_USER_ONLY
+    target_ulong lock_st_addr;
+    target_ulong lock_st_value;
+#endif
+
     uint32_t flags;           /* cpu_flags, we only use it for exception
                                  in solt so far.  */
 
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 2d89acb..428314f 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -53,6 +53,7 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
     env->sr &= ~SR_TEE;
     env->tlb->cpu_openrisc_map_address_data = &cpu_openrisc_get_phys_nommu;
     env->tlb->cpu_openrisc_map_address_code = &cpu_openrisc_get_phys_nommu;
+    env->lock_addr = -1;
 
     if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
         env->pc = (cs->exception_index << 8);
diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c
index 8695fe7..70e64a3 100644
--- a/target-openrisc/interrupt_helper.c
+++ b/target-openrisc/interrupt_helper.c
@@ -32,6 +32,7 @@ void HELPER(rfe)(CPUOpenRISCState *env)
     cpu->env.pc = cpu->env.epcr;
     cpu->env.npc = cpu->env.epcr;
     cpu_set_sr(&cpu->env, cpu->env.esr);
+    cpu->env.lock_addr = -1;
 
 #ifndef CONFIG_USER_ONLY
     if (cpu->env.sr & SR_DME) {
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index 750a936..a656232 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -172,6 +172,7 @@ static void cpu_openrisc_raise_mmu_exception(OpenRISCCPU *cpu,
 
     cs->exception_index = exception;
     cpu->env.eear = address;
+    cpu->env.lock_addr = -1;
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 569f4ab..80d2b84 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -57,6 +57,8 @@ static TCGv cpu_ppc;
 static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
 static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
 static TCGv cpu_sr_ov;          /* signed overflow */
+static TCGv cpu_lock_addr;
+static TCGv cpu_lock_value;
 static TCGv_i32 fpcsr;
 static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
 static TCGv_i32 env_flags;
@@ -92,6 +94,12 @@ void openrisc_translate_init(void)
                                  offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
     cpu_sr_ov = tcg_global_mem_new(TCG_AREG0,
                                  offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
+    cpu_lock_addr = tcg_global_mem_new(TCG_AREG0,
+                                       offsetof(CPUOpenRISCState, lock_addr),
+                                       "lock_addr");
+    cpu_lock_value = tcg_global_mem_new(TCG_AREG0,
+                                        offsetof(CPUOpenRISCState, lock_value),
+                                        "lock_value");
     fpcsr = tcg_global_mem_new_i32(TCG_AREG0,
                                    offsetof(CPUOpenRISCState, fpcsr),
                                    "fpcsr");
@@ -467,6 +475,58 @@ static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
     gen_ove_cy(dc);
 }
 
+static void gen_lwa(DisasContext *dc, TCGv rd, TCGv ra, int32_t ofs)
+{
+    TCGv ea = tcg_temp_new();
+
+    tcg_gen_addi_tl(ea, ra, ofs);
+    tcg_gen_qemu_ld_tl(rd, ea, dc->mem_idx, MO_TEUL);
+    tcg_gen_mov_tl(cpu_lock_addr, ea);
+    tcg_gen_mov_tl(cpu_lock_value, rd);
+    tcg_temp_free(ea);
+}
+
+static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs)
+{
+#ifdef CONFIG_USER_ONLY
+    TCGv ea = tcg_temp_new();
+    tcg_gen_addi_tl(ea, ra, ofs);
+    tcg_gen_st_tl(ea, cpu_env, offsetof(CPUOpenRISCState, lock_st_addr));
+    tcg_temp_free(ea);
+
+    tcg_gen_st32_tl(rb, cpu_env, offsetof(CPUOpenRISCState, lock_st_value));
+
+    tcg_gen_movi_tl(cpu_pc, dc->pc);
+    gen_exception(dc, EXCP_SWA);
+    dc->is_jmp = DISAS_UPDATE;
+#else
+    TCGv ea, val;
+    TCGLabel *lab_fail, *lab_done;
+
+    ea = tcg_temp_new();
+    tcg_gen_addi_tl(ea, ra, ofs);
+
+    lab_fail = gen_new_label();
+    lab_done = gen_new_label();
+    tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
+    tcg_temp_free(ea);
+
+    val = tcg_temp_new();
+    tcg_gen_qemu_ld_tl(val, cpu_lock_addr, dc->mem_idx, MO_TEUL);
+    tcg_gen_brcond_tl(TCG_COND_NE, val, cpu_lock_value, lab_fail);
+
+    tcg_gen_qemu_st_tl(rb, cpu_lock_addr, dc->mem_idx, MO_TEUL);
+    tcg_gen_movi_tl(cpu_sr_f, 1);
+    tcg_gen_br(lab_done);
+
+    gen_set_label(lab_fail);
+    tcg_gen_movi_tl(cpu_sr_f, 0);
+
+    gen_set_label(lab_done);
+    tcg_gen_movi_tl(cpu_lock_addr, -1);
+#endif
+}
+
 static void dec_calc(DisasContext *dc, uint32_t insn)
 {
     uint32_t op0, op1, op2;
@@ -721,6 +781,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         }
         break;
 
+    case 0x1b: /* l.lwa */
+        LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16);
+        gen_lwa(dc, cpu_R[rd], cpu_R[ra], I16);
+        break;
+
     case 0x1c:    /* l.cust1 */
         LOG_DIS("l.cust1\n");
         break;
@@ -847,6 +912,11 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
         }
         break;
 
+    case 0x33: /* l.swa */
+        LOG_DIS("l.swa r%d, r%d, %d\n", ra, rb, I5_11);
+        gen_swa(dc, cpu_R[rb], cpu_R[ra], I5_11);
+        break;
+
     case 0x34:    /* l.sd */
         LOG_DIS("l.sd r%d, r%d, %d\n", ra, rb, I5_11);
         check_ob64s(dc);
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS Richard Henderson
@ 2015-09-03 14:15   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-03 14:15 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Avoids warnings from unused variables etc.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/translate.c | 20 ++++----------------
>   1 file changed, 4 insertions(+), 16 deletions(-)
>
>
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE Richard Henderson
@ 2015-09-03 14:16   ` Bastian Koppelmann
  2015-09-03 14:44     ` Richard Henderson
  0 siblings, 1 reply; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-03 14:16 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> +
> +void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
> +{
> +    if (unlikely(test) && (env->sr & SR_OVE)) {
> +        OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
> +        CPUState *cs = CPU(cpu);
> +
> +        cs->exception_index = EXCP_RANGE;
> +        cpu_restore_state(cs, GETPC());
> +        cpu_loop_exit(cs);
> +    }
> +}

You forgot to check the AECR register, whether the exception really occurs.

>   
> +static void gen_ove_cy(DisasContext *dc, TCGv cy)
> +{
> +    gen_helper_ove(cpu_env, cy);
> +}
> +
> +static void gen_ove_ov(DisasContext *dc, TCGv ov)
> +{
> +    gen_helper_ove(cpu_env, ov);
> +}
> +

Do we really need two functions here? They differ only by the name of 
the second argument. We should directly use gen_helper_ove ().

> +static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
> +{
> +    TCGv t0 = tcg_const_tl(0);
> +    TCGv res = tcg_temp_new();
> +    TCGv sr_cy = tcg_temp_new();
> +    TCGv sr_ov = tcg_temp_new();
> +
> +    tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0);
> +    tcg_gen_xor_tl(sr_ov, srca, srcb);
> +    tcg_gen_xor_tl(t0, res, srcb);
> +    tcg_gen_andc_tl(sr_ov, t0, sr_ov);
> +    tcg_temp_free(t0);
> +
> +    tcg_gen_mov_tl(dest, res);
> +    tcg_temp_free(res);
> +
> +    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);
> +    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);
> +    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);
> +
> +    gen_ove_cyov(dc, sr_ov, sr_cy);
> +    tcg_temp_free(sr_ov);
> +    tcg_temp_free(sr_cy);
> +}

I do wonder, if we should use TCG globals for sr_cy and sr_ov, as you 
recommended for the TriCore target. It would not change the helper in 
case of no ovf/carry, but simplify addc. And we would not need two 
deposits for every add/sub.

> -            if (ra != 0 && rb != 0) {
> -                gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
> -            } else {
> -                tcg_gen_movi_tl(cpu_R[rd], 0x0);
> -            }
> +            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);

What happened to this special case here? r0 should always hold zero, so 
we can keep this optimization here, or at least move it to gen_mul().

> -            if (rb != 0 && ra != 0) {
> -                TCGv_i64 result = tcg_temp_local_new_i64();
> -                TCGv_i64 tra = tcg_temp_local_new_i64();
> -                TCGv_i64 trb = tcg_temp_local_new_i64();
> -                TCGv_i64 high = tcg_temp_new_i64();
> -                TCGv_i32 sr_ove = tcg_temp_local_new_i32();
> -                TCGLabel *lab = gen_new_label();
> -                /* Calculate each result. */
> -                tcg_gen_extu_i32_i64(tra, cpu_R[ra]);
> -                tcg_gen_extu_i32_i64(trb, cpu_R[rb]);
> -                tcg_gen_mul_i64(result, tra, trb);
> -                tcg_temp_free_i64(tra);
> -                tcg_temp_free_i64(trb);
> -                tcg_gen_shri_i64(high, result, TARGET_LONG_BITS);
> -                /* Overflow or not. */
> -                tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab);
> -                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, lab);
> -                gen_exception(dc, EXCP_RANGE);
> -                gen_set_label(lab);
> -                tcg_temp_free_i64(high);
> -                tcg_gen_trunc_i64_tl(cpu_R[rd], result);
> -                tcg_temp_free_i64(result);
> -                tcg_temp_free_i32(sr_ove);
> -            } else {
> -                tcg_gen_movi_tl(cpu_R[rd], 0);
> -            }
> +            gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
>               break;

The same here.

> -        {
> -            if (I16 == 0) {
> -                tcg_gen_mov_tl(cpu_R[rd], cpu_R[ra]);
> -            } else {
> -                TCGLabel *lab = gen_new_label();
> -                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_extrl_i64_i32(res, td);
> -                tcg_gen_shri_i64(td, td, 32);
> -                tcg_gen_andi_i64(td, td, 0x3);
> -                /* Jump to lab when no overflow.  */
> -                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);
> -                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);
> -            }
> -        }
> +        t0 = tcg_const_tl(I16);
> +        gen_add(dc, cpu_R[rd], cpu_R[ra], t0);
> +        tcg_temp_free(t0);
>           break;

Again, why remove the special case?

>       case 0x29:    /* l.andi */
> @@ -963,13 +895,9 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
>   
>       case 0x2c:    /* l.muli */
>           LOG_DIS("l.muli r%d, r%d, %d\n", rd, ra, I16);
> -        if (ra != 0 && I16 != 0) {
> -            TCGv_i32 im = tcg_const_i32(I16);
> -            gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], im);
> -            tcg_temp_free_i32(im);
> -        } else {
> -            tcg_gen_movi_tl(cpu_R[rd], 0x0);
> -        }
> +        t0 = tcg_const_tl(I16);
> +        gen_mul(dc, cpu_R[rd], cpu_R[ra], t0);
> +        tcg_temp_free(t0);
Again, why remove the special case?

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE
  2015-09-03 14:16   ` Bastian Koppelmann
@ 2015-09-03 14:44     ` Richard Henderson
  2015-09-04 13:12       ` Bastian Koppelmann
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-03 14:44 UTC (permalink / raw)
  To: Bastian Koppelmann, qemu-devel; +Cc: peter.maydell, proljc

On 09/03/2015 07:16 AM, Bastian Koppelmann wrote:
>
>
> On 09/03/2015 02:17 AM, Richard Henderson wrote:
>> +
>> +void HELPER(ove)(CPUOpenRISCState *env, target_ulong test)
>> +{
>> +    if (unlikely(test) && (env->sr & SR_OVE)) {
>> +        OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
>> +        CPUState *cs = CPU(cpu);
>> +
>> +        cs->exception_index = EXCP_RANGE;
>> +        cpu_restore_state(cs, GETPC());
>> +        cpu_loop_exit(cs);
>> +    }
>> +}
>
> You forgot to check the AECR register, whether the exception really occurs.

The current state of the port suggests it's written to a (pre?) 1.0 
specification, prior to the AECR register being invented.  Let's not try to 
introduce new features just yet.

>> +static void gen_ove_cy(DisasContext *dc, TCGv cy)
>> +{
>> +    gen_helper_ove(cpu_env, cy);
>> +}
>> +
>> +static void gen_ove_ov(DisasContext *dc, TCGv ov)
>> +{
>> +    gen_helper_ove(cpu_env, ov);
>> +}
>> +
>
> Do we really need two functions here? They differ only by the name of the
> second argument. We should directly use gen_helper_ove ().

This is prep work for patch 7/17.

> I do wonder, if we should use TCG globals for sr_cy and sr_ov, as you
> recommended for the TriCore target. It would not change the helper in case of
> no ovf/carry, but simplify addc. And we would not need two deposits for every
> add/sub.

That's patch 7/17.  ;-)

>
>> -            if (ra != 0 && rb != 0) {
>> -                gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);
>> -            } else {
>> -                tcg_gen_movi_tl(cpu_R[rd], 0x0);
>> -            }
>> +            gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
>
> What happened to this special case here? r0 should always hold zero, so we can
> keep this optimization here, or at least move it to gen_mul().

R0 is not an *architectural* zero.  It's a software convention.  The spec is 
fairly clear on this point.

I agree that there ought to be some special-casing of the software convention, 
but that should require a TB flag to verify the convention is followed.  But 
even then I would not bother retaining the special case here in multiply.  I 
would only use it in the "move" and constant formation types of pseudo 
instructions (or, ori, etc).


r~

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 03/17] target-openrisc: Invert the decoding in dec_calc
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 03/17] target-openrisc: Invert the decoding in dec_calc Richard Henderson
@ 2015-09-03 14:48   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-03 14:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Decoding the opcodes in the right order reduces by 100+ lines.
> Also, it happens to put the opcodes in the same order as Chapter 17.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/translate.c | 300 ++++++++++++++------------------------------
>   1 file changed, 94 insertions(+), 206 deletions(-)
>
> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
> index 9a8f886..c9e3198 100644
> --- a/target-openrisc/translate.c
> +++ b/target-openrisc/translate.c
> @@ -419,267 +419,155 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
>       rb = extract32(insn, 11, 5);
>       rd = extract32(insn, 21, 5);
>   
> -    switch (op0) {

I think it's worth while to group all instructions with op0 = 0 into a 
separate decoding function.

> -
> -    case 0x000c:
> -        switch (op1) {
> -        case 0x00:
> +        case 0xc:
>               switch (op2) {
> -            case 0x00:    /* l.exths */
> +            case 0: /* l.exths */
>                   LOG_DIS("l.exths r%d, r%d\n", rd, ra);
>                   tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
Nitpick: l.exths comes before l.add in chapter 17 of my manual [1]

However those are mostly minor issues, so
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

[1] 
https://github.com/openrisc/doc/blob/master/openrisc-arch-1.1-rev0.pdf?raw=true

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 04/17] target-openrisc: Keep SR_F in a separate variable
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 04/17] target-openrisc: Keep SR_F in a separate variable Richard Henderson
@ 2015-09-03 15:09   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-03 15:09 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> This avoids having to keep merging and extracting the flag from SR.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/cpu.h              | 15 +++++-
>   target-openrisc/gdbstub.c          |  4 +-
>   target-openrisc/interrupt.c        |  2 +-
>   target-openrisc/interrupt_helper.c |  2 +-
>   target-openrisc/sys_helper.c       |  5 +-
>   target-openrisc/translate.c        | 96 +++++++++++++++-----------------------
>   6 files changed, 56 insertions(+), 68 deletions(-)
>
> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
> index 36c4f20..e91f2a9 100644
> --- a/target-openrisc/cpu.h
> +++ b/target-openrisc/cpu.h
> @@ -288,7 +288,8 @@ typedef struct CPUOpenRISCState {
>       target_ulong epcr;        /* Exception PC register */
>       target_ulong eear;        /* Exception EA register */
>   
> -    uint32_t sr;              /* Supervisor register */
> +    target_ulong sr_f;        /* the SR_F bit */

A comment that states the expected value of sr_f would be nice.

Other then that,
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 05/17] target-openrisc: Use movcond where appropriate
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 05/17] target-openrisc: Use movcond where appropriate Richard Henderson
@ 2015-09-03 16:04   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-03 16:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/translate.c | 28 ++++++++++++++--------------
>   1 file changed, 14 insertions(+), 14 deletions(-)
>   
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags Richard Henderson
@ 2015-09-04 13:05   ` Bastian Koppelmann
  2015-09-04 14:29     ` Richard Henderson
  0 siblings, 1 reply; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-04 13:05 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
>   {
>       /* Sync the tb dependent flag between translate and runtime.  */
> -    if (dc->tb_flags != dc->synced_flags) {
> -        tcg_gen_movi_tl(env_flags, dc->tb_flags);
> +    if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) {
> +        tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG);
>           dc->synced_flags = dc->tb_flags;
>       }
>   }
Why do we only need to sync D_FLAG? Will there only be D_FLAG, which 
needs to be synced?

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE
  2015-09-03 14:44     ` Richard Henderson
@ 2015-09-04 13:12       ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-04 13:12 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 04:44 PM, Richard Henderson wrote:
> That's patch 7/17.  ;-)

Woops , I just realized ;-)

> R0 is not an *architectural* zero.  It's a software convention.  The 
> spec is fairly clear on this point.
>
> I agree that there ought to be some special-casing of the software 
> convention, but that should require a TB flag to verify the convention 
> is followed.  But even then I would not bother retaining the special 
> case here in multiply.  I would only use it in the "move" and constant 
> formation types of pseudo instructions (or, ori, etc).

That sounds reasonable and is clearly for another patch, so

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 07/17] target-openrisc: Keep SR_CY and SR_OV in a separate variables
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 07/17] target-openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
@ 2015-09-04 13:33   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-04 13:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> -
> -uint32_t HELPER(mul32)(CPUOpenRISCState *env,
> -                       uint32_t ra, uint32_t rb)
> -{
> -    uint64_t result;
> -    uint32_t high, cy;
> -
> -    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
> -
> -    result = (uint64_t)ra * rb;
> -    /* regisiers in or32 is 32bit, so 32 is NOT a magic number.
> -       or64 is not handled in this function, and not implement yet,
> -       TARGET_LONG_BITS for or64 is 64, it will break this function,
> -       so, we didn't use TARGET_LONG_BITS here.  */
> -    high = result >> 32;
> -    cy = result >> (32 - 1);
> -
> -    if ((cy & 0x1) == 0x0) {
> -        if (high == 0x0) {
> -            return result;
> -        }
> -    }
> -
> -    if ((cy & 0x1) == 0x1) {
> -        if (high == 0xffffffff) {
> -            return result;
> -        }
> -    }
> -
> -    cpu->env.sr |= (SR_OV | SR_CY);
> -    if (cpu->env.sr & SR_OVE) {
> -        raise_exception(cpu, EXCP_RANGE);
> -    }
> -
> -    return result;
> -}
This ought to be part of patch 02, where you removed the last use of 
helper_mul32.

Other than that,
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 08/17] target-openrisc: Set flags on helpers
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 08/17] target-openrisc: Set flags on helpers Richard Henderson
@ 2015-09-04 13:58   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-04 13:58 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/helper.h | 28 ++++++++++++++--------------
>   1 file changed, 14 insertions(+), 14 deletions(-)
>
>
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 09/17] target-openrisc: Implement ff1 and fl1 for 64-bit
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 09/17] target-openrisc: Implement ff1 and fl1 for 64-bit Richard Henderson
@ 2015-09-04 13:59   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-04 13:59 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> True, this is unused so far, but commented out is worse than
> actually implemented properly.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/int_helper.c | 23 ++++++++++++-----------
>   1 file changed, 12 insertions(+), 11 deletions(-)
>
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags
  2015-09-04 13:05   ` Bastian Koppelmann
@ 2015-09-04 14:29     ` Richard Henderson
  0 siblings, 0 replies; 42+ messages in thread
From: Richard Henderson @ 2015-09-04 14:29 UTC (permalink / raw)
  To: Bastian Koppelmann, qemu-devel; +Cc: peter.maydell, proljc

On 09/04/2015 06:05 AM, Bastian Koppelmann wrote:
>
>
> On 09/03/2015 02:17 AM, Richard Henderson wrote:
>>   {
>>       /* Sync the tb dependent flag between translate and runtime.  */
>> -    if (dc->tb_flags != dc->synced_flags) {
>> -        tcg_gen_movi_tl(env_flags, dc->tb_flags);
>> +    if ((dc->tb_flags ^ dc->synced_flags) & D_FLAG) {
>> +        tcg_gen_movi_tl(env_flags, dc->tb_flags & D_FLAG);
>>           dc->synced_flags = dc->tb_flags;
>>       }
>>   }
> Why do we only need to sync D_FLAG? Will there only be D_FLAG, which needs to
> be synced?

It's a somewhat silly way to mark the delayed branch status.  I don't recall if 
I eventually got around to fixing this or not.


r~

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 10/17] target-openrisc: Represent MACHI:MACLO as a single unit
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 10/17] target-openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
@ 2015-09-04 15:04   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-04 15:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Significantly simplifies the implementation of the use of MAC.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/cpu.h        |   3 +-
>   target-openrisc/sys_helper.c |  13 +++++
>   target-openrisc/translate.c  | 120 +++++++++++++++++++++++--------------------
>   3 files changed, 78 insertions(+), 58 deletions(-)
>
>

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction Richard Henderson
@ 2015-09-04 15:24   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-04 15:24 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> The architecture manual is consistent in using "I" for signed
> fields and "K" for unsigned fields.  Mirror that.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/translate.c | 200 +++++++++++++++++---------------------------
>   1 file changed, 75 insertions(+), 125 deletions(-)
>

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode Richard Henderson
@ 2015-09-05 21:35   ` Bastian Koppelmann
  2015-09-06 20:36     ` Richard Henderson
  0 siblings, 1 reply; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-05 21:35 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc

On 09/03/2015 02:17 AM, Richard Henderson wrote:
> -        if (dc->mem_idx == MMU_USER_IDX) {
> -            gen_illegal_exception(dc);
> -            return;
> +        {
> +            TCGv_i32 tmp = tcg_temp_new_i32();
> +            tcg_gen_trunc_tl_i32(tmp, cpu_R[ra]);
> +            tcg_gen_ori_i32(tmp, tmp, K16);
> +            gen_helper_mfspr(cpu_R[rd], cpu_env, tmp);
> +            tcg_temp_free_i32(tmp);
>           }
> -        t0 = tcg_const_i32(K16);
> -        gen_helper_mfspr(cpu_R[rd], cpu_env, cpu_R[rd], cpu_R[ra], t0);
> -        tcg_temp_free(t0);
> -#endif
>           break;

IIRC a lot of the registers are supervisor only, e.g. VR, NPC or SR and 
the manual is fairly clear about that. User mode cpu ought not to read 
these registers unconditionally.

>   
>       case 0x30:    /* l.mtspr */
>           LOG_DIS("l.mtspr r%d, r%d, %d\n", ra, rb, K5_11);
> -#if defined(CONFIG_USER_ONLY)
> -        return;
> -#else
> -        if (dc->mem_idx == MMU_USER_IDX) {
> -            gen_illegal_exception(dc);
> -            return;
> +        {
> +            TCGv_i32 tmp = tcg_temp_new_i32();
> +            tcg_gen_trunc_tl_i32(tmp, cpu_R[ra]);
> +            tcg_gen_ori_i32(tmp, tmp, K5_11);
> +            gen_helper_mtspr(cpu_env, tmp, cpu_R[rb]);
> +            tcg_temp_free_i32(tmp);
>           }
> -        t0 = tcg_const_tl(K5_11);
> -        gen_helper_mtspr(cpu_env, cpu_R[ra], cpu_R[rb], t0);
> -        tcg_temp_free(t0);
> -#endif
>           break;

Same as above, unconditional write.

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 13/17] target-openrisc: Enable trap, csync, msync, psync for user mode
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 13/17] target-openrisc: Enable trap, csync, msync, psync for " Richard Henderson
@ 2015-09-06  9:30   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-06  9:30 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Not documented as disabled for user mode.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/translate.c | 32 --------------------------------
>   1 file changed, 32 deletions(-)
>

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu Richard Henderson
@ 2015-09-06 11:38   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-06 11:38 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/translate.c | 106 ++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 106 insertions(+)
>

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode
  2015-09-05 21:35   ` Bastian Koppelmann
@ 2015-09-06 20:36     ` Richard Henderson
  2015-09-13  8:34       ` Bastian Koppelmann
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-06 20:36 UTC (permalink / raw)
  To: Bastian Koppelmann; +Cc: peter.maydell, Ethan Hunt, qemu-devel

On Sep 5, 2015 14:35, Bastian Koppelmann <kbastian@mail.uni-paderborn.de> wrote:
> IIRC a lot of the registers are supervisor only, e.g. VR, NPC or SR and 
> the manual is fairly clear about that. User mode cpu ought not to read 
> these registers unconditionally. 

When I last discussed this on the openrisc list, back in March, there was no real specification for user mode, and what bits are or should be accessible.

Looking at 
  http://opencores.org/or1k/Architecture_Specification
today, that still seems to be the case.

In the meantime, dropping the privilege check makes linux-user GCC tests work better.

r~

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd Richard Henderson
@ 2015-09-13  8:21   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-13  8:21 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Note that the specification for lf.madd.s is confused.  It's
> the only mention of supposed FPMADDHI/FPMADDLO special registers.
> On the other hand, or1ksim implements a somewhat normal non-fused
> multiply and add.  Mirror that.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/cpu.h        |  3 --
>   target-openrisc/fpu_helper.c | 68 ++++++++++++++++----------------------------
>   target-openrisc/helper.h     |  7 ++---
>   target-openrisc/translate.c  | 13 +++------
>   4 files changed, 30 insertions(+), 61 deletions(-)
>
>
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode
  2015-09-06 20:36     ` Richard Henderson
@ 2015-09-13  8:34       ` Bastian Koppelmann
  2015-09-14 17:11         ` Richard Henderson
  0 siblings, 1 reply; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-13  8:34 UTC (permalink / raw)
  To: Richard Henderson; +Cc: peter.maydell, Ethan Hunt, qemu-devel



On 09/06/2015 10:36 PM, Richard Henderson wrote:
> On Sep 5, 2015 14:35, Bastian Koppelmann <kbastian@mail.uni-paderborn.de> wrote:
>> IIRC a lot of the registers are supervisor only, e.g. VR, NPC or SR and
>> the manual is fairly clear about that. User mode cpu ought not to read
>> these registers unconditionally.
> When I last discussed this on the openrisc list, back in March, there was no real specification for user mode, and what bits are or should be accessible.
>
> Looking at
>    http://opencores.org/or1k/Architecture_Specification
> today, that still seems to be the case.
>
> In the meantime, dropping the privilege check makes linux-user GCC tests work better.
>
Looking at the article, user mode seems to be optional, so I'm not 
against it, but it does look weird. How does ork1sim do it?

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode
  2015-09-13  8:34       ` Bastian Koppelmann
@ 2015-09-14 17:11         ` Richard Henderson
  2015-09-15  7:22           ` Bastian Koppelmann
  0 siblings, 1 reply; 42+ messages in thread
From: Richard Henderson @ 2015-09-14 17:11 UTC (permalink / raw)
  To: Bastian Koppelmann; +Cc: peter.maydell, Ethan Hunt, qemu-devel

On 09/13/2015 01:34 AM, Bastian Koppelmann wrote:
> Looking at the article, user mode seems to be optional, so I'm not against it,
> but it does look weird. How does ork1sim do it?

It's haphazard.  There are checks for supervisor in the l_mtspr and l_mfspr
insns, but not other uses of the sprs, such as l_rfe.

In the meantime, testing of the multiply-accumulate instructions is hindered by
the fact that linux-user can't read the MACHI and MACLO special registers.


r~

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode
  2015-09-14 17:11         ` Richard Henderson
@ 2015-09-15  7:22           ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-15  7:22 UTC (permalink / raw)
  To: Richard Henderson; +Cc: peter.maydell, Ethan Hunt, qemu-devel



On 09/14/2015 07:11 PM, Richard Henderson wrote:
> On 09/13/2015 01:34 AM, Bastian Koppelmann wrote:
>> Looking at the article, user mode seems to be optional, so I'm not against it,
>> but it does look weird. How does ork1sim do it?
> It's haphazard.  There are checks for supervisor in the l_mtspr and l_mfspr
> insns, but not other uses of the sprs, such as l_rfe.
How about we make the optional user mode a feature bit? This way we are 
closer to ork1sim, but don't have the problem that testing is hindered.

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception Richard Henderson
@ 2015-09-15 13:02   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-15 13:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> The architecture manual is unclear about this, but the or1ksim
> does writeback before the exception.  This requires splitting
> the helpers in half, with the exception raised by the second.
>
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   target-openrisc/fpu_helper.c | 252 +++++++++----------------------------------
>   target-openrisc/helper.h     |  25 +++--
>   target-openrisc/translate.c  | 118 +++++++++++---------
>   3 files changed, 129 insertions(+), 266 deletions(-)
>

Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa
  2015-09-03  0:17 ` [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa Richard Henderson
@ 2015-09-15 13:04   ` Bastian Koppelmann
  0 siblings, 0 replies; 42+ messages in thread
From: Bastian Koppelmann @ 2015-09-15 13:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: peter.maydell, proljc



On 09/03/2015 02:17 AM, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>   linux-user/main.c                  | 45 ++++++++++++++++++++++++
>   target-openrisc/cpu.c              |  1 +
>   target-openrisc/cpu.h              |  9 +++++
>   target-openrisc/interrupt.c        |  1 +
>   target-openrisc/interrupt_helper.c |  1 +
>   target-openrisc/mmu.c              |  1 +
>   target-openrisc/translate.c        | 70 ++++++++++++++++++++++++++++++++++++++
>   7 files changed, 128 insertions(+)

This looks good to me. However I don't feel confident enough to give a rb.

Cheers,
Bastian

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2015-09-15 13:22 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-03  0:17 [Qemu-devel] [PATCH 00/17] target-openrisc improvements Richard Henderson
2015-09-03  0:17 ` [Qemu-devel] [PATCH 01/17] target-openrisc: Always enable OPENRISC_DISAS Richard Henderson
2015-09-03 14:15   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 02/17] target-openrisc: Streamline arithmetic and OVE Richard Henderson
2015-09-03 14:16   ` Bastian Koppelmann
2015-09-03 14:44     ` Richard Henderson
2015-09-04 13:12       ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 03/17] target-openrisc: Invert the decoding in dec_calc Richard Henderson
2015-09-03 14:48   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 04/17] target-openrisc: Keep SR_F in a separate variable Richard Henderson
2015-09-03 15:09   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 05/17] target-openrisc: Use movcond where appropriate Richard Henderson
2015-09-03 16:04   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 06/17] target-openrisc: Put SR[OVE] in TB flags Richard Henderson
2015-09-04 13:05   ` Bastian Koppelmann
2015-09-04 14:29     ` Richard Henderson
2015-09-03  0:17 ` [Qemu-devel] [PATCH 07/17] target-openrisc: Keep SR_CY and SR_OV in a separate variables Richard Henderson
2015-09-04 13:33   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 08/17] target-openrisc: Set flags on helpers Richard Henderson
2015-09-04 13:58   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 09/17] target-openrisc: Implement ff1 and fl1 for 64-bit Richard Henderson
2015-09-04 13:59   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 10/17] target-openrisc: Represent MACHI:MACLO as a single unit Richard Henderson
2015-09-04 15:04   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 11/17] target-openrisc: Rationalize immediate extraction Richard Henderson
2015-09-04 15:24   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 12/17] target-openrisc: Enable m[tf]spr from user mode Richard Henderson
2015-09-05 21:35   ` Bastian Koppelmann
2015-09-06 20:36     ` Richard Henderson
2015-09-13  8:34       ` Bastian Koppelmann
2015-09-14 17:11         ` Richard Henderson
2015-09-15  7:22           ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 13/17] target-openrisc: Enable trap, csync, msync, psync for " Richard Henderson
2015-09-06  9:30   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 14/17] target-openrisc: Implement muld, muldu, macu, msbu Richard Henderson
2015-09-06 11:38   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 15/17] target-openrisc: Fix madd Richard Henderson
2015-09-13  8:21   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 16/17] target-openrisc: Write back result before FPE exception Richard Henderson
2015-09-15 13:02   ` Bastian Koppelmann
2015-09-03  0:17 ` [Qemu-devel] [PATCH 17/17] target-openrisc: Implement lwa, swa Richard Henderson
2015-09-15 13:04   ` Bastian Koppelmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.