All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/13] target/openrisc updates
@ 2019-09-04 20:44 Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 01/13] target/openrisc: Add DisasContext parameter to check_r0_write Richard Henderson
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

The following changes since commit a8b5ad8e1faef0d1bb3e550530328e8ec76fe87c:

  Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2019-09-04 17:22:34 +0100)

are available in the Git repository at:

  https://github.com/rth7680/qemu.git tags/pull-or1k-20190904

for you to fetch changes up to 9e3bab08d3e3f5808cc35a59af1912bfb6fe96fd:

  target/openrisc: Update cpu "any" to v1.3 (2019-09-04 13:01:56 -0700)

----------------------------------------------------------------
Updates for arch v1.3.

----------------------------------------------------------------
Richard Henderson (13):
      target/openrisc: Add DisasContext parameter to check_r0_write
      target/openrisc: Replace cpu register array with a function
      target/openrisc: Cache R0 in DisasContext
      target/openrisc: Make VR and PPC read-only
      target/openrisc: Move VR, UPR, DMMCFGR, IMMCFGR to cpu init
      target/openrisc: Add VR2 and AVR special processor registers
      target/openrisc: Fix lf.ftoi.s
      target/openrisc: Check CPUCFG_OF32S for float insns
      target/openrisc: Add support for ORFPX64A32
      target/openrisc: Implement unordered fp comparisons
      target/openrisc: Implement move to/from FPCSR
      target/openrisc: Implement l.adrp
      target/openrisc: Update cpu "any" to v1.3

 linux-user/openrisc/target_elf.h |   2 +-
 target/openrisc/cpu.h            |  24 +-
 target/openrisc/helper.h         |   6 +
 target/openrisc/cpu.c            |  30 +-
 target/openrisc/disas.c          |  81 +++++
 target/openrisc/fpu_helper.c     |  49 ++-
 target/openrisc/machine.c        |  11 +
 target/openrisc/sys_helper.c     |  38 ++-
 target/openrisc/translate.c      | 716 +++++++++++++++++++++++++++++----------
 target/openrisc/insns.decode     |  45 +++
 10 files changed, 774 insertions(+), 228 deletions(-)


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

* [Qemu-devel] [PULL 01/13] target/openrisc: Add DisasContext parameter to check_r0_write
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
@ 2019-09-04 20:44 ` Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 02/13] target/openrisc: Replace cpu register array with a function Richard Henderson
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

We will need this context in the next patch.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 96 +++++++++++++++++++------------------
 1 file changed, 49 insertions(+), 47 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index b189c506c5..8d72edf9b7 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -163,14 +163,16 @@ static void check_ov64s(DisasContext *dc)
 }
 #endif*/
 
-/* We're about to write to REG.  On the off-chance that the user is
-   writing to R0, re-instate the architectural register.  */
-#define check_r0_write(reg)             \
-    do {                                \
-        if (unlikely(reg == 0)) {       \
-            cpu_R[0] = cpu_R0;          \
-        }                               \
-    } while (0)
+/*
+ * We're about to write to REG.  On the off-chance that the user is
+ * writing to R0, re-instate the architectural register.
+ */
+static void check_r0_write(DisasContext *dc, int reg)
+{
+    if (unlikely(reg == 0)) {
+        cpu_R[0] = cpu_R0;
+    }
+}
 
 static void gen_ove_cy(DisasContext *dc)
 {
@@ -436,98 +438,98 @@ static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
 
 static bool trans_l_add(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_add(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_addc(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_addc(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sub(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_sub(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_and(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_and_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_or(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_or_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_xor(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_xor_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sll(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_shl_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_srl(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_shr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_sra(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_sar_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_ror(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_rotr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_exths(DisasContext *dc, arg_da *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_ext16s_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
 }
 
 static bool trans_l_extbs(DisasContext *dc, arg_da *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_ext8s_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
 }
 
 static bool trans_l_exthz(DisasContext *dc, arg_da *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_ext16u_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
 }
 
 static bool trans_l_extbz(DisasContext *dc, arg_da *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_ext8u_tl(cpu_R[a->d], cpu_R[a->a]);
     return true;
 }
@@ -536,7 +538,7 @@ static bool trans_l_cmov(DisasContext *dc, arg_dab *a)
 {
     TCGv zero;
 
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     zero = tcg_const_tl(0);
     tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[a->d], cpu_sr_f, zero,
                        cpu_R[a->a], cpu_R[a->b]);
@@ -546,7 +548,7 @@ static bool trans_l_cmov(DisasContext *dc, arg_dab *a)
 
 static bool trans_l_ff1(DisasContext *dc, arg_da *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_ctzi_tl(cpu_R[a->d], cpu_R[a->a], -1);
     tcg_gen_addi_tl(cpu_R[a->d], cpu_R[a->d], 1);
     return true;
@@ -554,7 +556,7 @@ static bool trans_l_ff1(DisasContext *dc, arg_da *a)
 
 static bool trans_l_fl1(DisasContext *dc, arg_da *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_clzi_tl(cpu_R[a->d], cpu_R[a->a], TARGET_LONG_BITS);
     tcg_gen_subfi_tl(cpu_R[a->d], TARGET_LONG_BITS, cpu_R[a->d]);
     return true;
@@ -562,28 +564,28 @@ static bool trans_l_fl1(DisasContext *dc, arg_da *a)
 
 static bool trans_l_mul(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_mul(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_mulu(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_mulu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_div(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_div(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
 
 static bool trans_l_divu(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_divu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
     return true;
 }
@@ -671,7 +673,7 @@ static bool trans_l_lwa(DisasContext *dc, arg_load *a)
 {
     TCGv ea;
 
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     ea = tcg_temp_new();
     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
     tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, MO_TEUL);
@@ -685,7 +687,7 @@ static void do_load(DisasContext *dc, arg_load *a, MemOp mop)
 {
     TCGv ea;
 
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     ea = tcg_temp_new();
     tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
     tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, mop);
@@ -798,7 +800,7 @@ static bool trans_l_addi(DisasContext *dc, arg_rri *a)
 {
     TCGv t0;
 
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     t0 = tcg_const_tl(a->i);
     gen_add(dc, cpu_R[a->d], cpu_R[a->a], t0);
     tcg_temp_free(t0);
@@ -809,7 +811,7 @@ static bool trans_l_addic(DisasContext *dc, arg_rri *a)
 {
     TCGv t0;
 
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     t0 = tcg_const_tl(a->i);
     gen_addc(dc, cpu_R[a->d], cpu_R[a->a], t0);
     tcg_temp_free(t0);
@@ -820,7 +822,7 @@ static bool trans_l_muli(DisasContext *dc, arg_rri *a)
 {
     TCGv t0;
 
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     t0 = tcg_const_tl(a->i);
     gen_mul(dc, cpu_R[a->d], cpu_R[a->a], t0);
     tcg_temp_free(t0);
@@ -839,28 +841,28 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a)
 
 static bool trans_l_andi(DisasContext *dc, arg_rrk *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_andi_tl(cpu_R[a->d], cpu_R[a->a], a->k);
     return true;
 }
 
 static bool trans_l_ori(DisasContext *dc, arg_rrk *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_ori_tl(cpu_R[a->d], cpu_R[a->a], a->k);
     return true;
 }
 
 static bool trans_l_xori(DisasContext *dc, arg_rri *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_xori_tl(cpu_R[a->d], cpu_R[a->a], a->i);
     return true;
 }
 
 static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
 
     if (is_user(dc)) {
         gen_illegal_exception(dc);
@@ -927,42 +929,42 @@ static bool trans_l_msbu(DisasContext *dc, arg_ab *a)
 
 static bool trans_l_slli(DisasContext *dc, arg_dal *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_shli_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_srli(DisasContext *dc, arg_dal *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_shri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_srai(DisasContext *dc, arg_dal *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_sari_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_rori(DisasContext *dc, arg_dal *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_rotri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_movi_tl(cpu_R[a->d], a->k << 16);
     return true;
 }
 
 static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     tcg_gen_trunc_i64_tl(cpu_R[a->d], cpu_mac);
     tcg_gen_movi_i64(cpu_mac, 0);
     return true;
@@ -1134,7 +1136,7 @@ static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a)
 static void do_fp2(DisasContext *dc, arg_da *a,
                    void (*fn)(TCGv, TCGv_env, TCGv))
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     fn(cpu_R[a->d], cpu_env, cpu_R[a->a]);
     gen_helper_update_fpcsr(cpu_env);
 }
@@ -1142,7 +1144,7 @@ static void do_fp2(DisasContext *dc, arg_da *a,
 static void do_fp3(DisasContext *dc, arg_dab *a,
                    void (*fn)(TCGv, TCGv_env, TCGv, TCGv))
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     fn(cpu_R[a->d], cpu_env, cpu_R[a->a], cpu_R[a->b]);
     gen_helper_update_fpcsr(cpu_env);
 }
@@ -1206,7 +1208,7 @@ static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a)
 
 static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a)
 {
-    check_r0_write(a->d);
+    check_r0_write(dc, a->d);
     gen_helper_float_madd_s(cpu_R[a->d], cpu_env, cpu_R[a->d],
                             cpu_R[a->a], cpu_R[a->b]);
     gen_helper_update_fpcsr(cpu_env);
-- 
2.17.1



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

* [Qemu-devel] [PULL 02/13] target/openrisc: Replace cpu register array with a function
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 01/13] target/openrisc: Add DisasContext parameter to check_r0_write Richard Henderson
@ 2019-09-04 20:44 ` Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 03/13] target/openrisc: Cache R0 in DisasContext Richard Henderson
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

The writes to cpu_R[0] are now a race across threads, now that we
do code generation in parallel.  Stage the change by introducing
a function to return the temp for R0.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 213 ++++++++++++++++++++----------------
 1 file changed, 116 insertions(+), 97 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 8d72edf9b7..d635a46f7e 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -63,7 +63,7 @@ static inline bool is_user(DisasContext *dc)
 #include "decode.inc.c"
 
 static TCGv cpu_sr;
-static TCGv cpu_R[32];
+static TCGv cpu_regs[32];
 static TCGv cpu_R0;
 static TCGv cpu_pc;
 static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
@@ -117,12 +117,12 @@ void openrisc_translate_init(void)
                                      offsetof(CPUOpenRISCState, mac),
                                      "mac");
     for (i = 0; i < 32; i++) {
-        cpu_R[i] = tcg_global_mem_new(cpu_env,
-                                      offsetof(CPUOpenRISCState,
-                                               shadow_gpr[0][i]),
-                                      regnames[i]);
+        cpu_regs[i] = tcg_global_mem_new(cpu_env,
+                                         offsetof(CPUOpenRISCState,
+                                                  shadow_gpr[0][i]),
+                                         regnames[i]);
     }
-    cpu_R0 = cpu_R[0];
+    cpu_R0 = cpu_regs[0];
 }
 
 static void gen_exception(DisasContext *dc, unsigned int excp)
@@ -163,6 +163,11 @@ static void check_ov64s(DisasContext *dc)
 }
 #endif*/
 
+static TCGv cpu_R(DisasContext *dc, int reg)
+{
+    return cpu_regs[reg];
+}
+
 /*
  * We're about to write to REG.  On the off-chance that the user is
  * writing to R0, re-instate the architectural register.
@@ -170,7 +175,7 @@ static void check_ov64s(DisasContext *dc)
 static void check_r0_write(DisasContext *dc, int reg)
 {
     if (unlikely(reg == 0)) {
-        cpu_R[0] = cpu_R0;
+        cpu_regs[0] = cpu_R0;
     }
 }
 
@@ -439,98 +444,98 @@ static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
 static bool trans_l_add(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_add(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_addc(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_addc(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sub(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_sub(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    gen_sub(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_and(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_and_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_and_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_or(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_or_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_or_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_xor(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_xor_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_xor_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sll(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_shl_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_shl_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_srl(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_shr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_shr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sra(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_sar_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_sar_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_ror(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_rotr_tl(cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_rotr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_exths(DisasContext *dc, arg_da *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_ext16s_tl(cpu_R[a->d], cpu_R[a->a]);
+    tcg_gen_ext16s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
     return true;
 }
 
 static bool trans_l_extbs(DisasContext *dc, arg_da *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_ext8s_tl(cpu_R[a->d], cpu_R[a->a]);
+    tcg_gen_ext8s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
     return true;
 }
 
 static bool trans_l_exthz(DisasContext *dc, arg_da *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_ext16u_tl(cpu_R[a->d], cpu_R[a->a]);
+    tcg_gen_ext16u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
     return true;
 }
 
 static bool trans_l_extbz(DisasContext *dc, arg_da *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_ext8u_tl(cpu_R[a->d], cpu_R[a->a]);
+    tcg_gen_ext8u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
     return true;
 }
 
@@ -540,8 +545,8 @@ static bool trans_l_cmov(DisasContext *dc, arg_dab *a)
 
     check_r0_write(dc, a->d);
     zero = tcg_const_tl(0);
-    tcg_gen_movcond_tl(TCG_COND_NE, cpu_R[a->d], cpu_sr_f, zero,
-                       cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_movcond_tl(TCG_COND_NE, cpu_R(dc, a->d), cpu_sr_f, zero,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     tcg_temp_free(zero);
     return true;
 }
@@ -549,56 +554,56 @@ static bool trans_l_cmov(DisasContext *dc, arg_dab *a)
 static bool trans_l_ff1(DisasContext *dc, arg_da *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_ctzi_tl(cpu_R[a->d], cpu_R[a->a], -1);
-    tcg_gen_addi_tl(cpu_R[a->d], cpu_R[a->d], 1);
+    tcg_gen_ctzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), -1);
+    tcg_gen_addi_tl(cpu_R(dc, a->d), cpu_R(dc, a->d), 1);
     return true;
 }
 
 static bool trans_l_fl1(DisasContext *dc, arg_da *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_clzi_tl(cpu_R[a->d], cpu_R[a->a], TARGET_LONG_BITS);
-    tcg_gen_subfi_tl(cpu_R[a->d], TARGET_LONG_BITS, cpu_R[a->d]);
+    tcg_gen_clzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), TARGET_LONG_BITS);
+    tcg_gen_subfi_tl(cpu_R(dc, a->d), TARGET_LONG_BITS, cpu_R(dc, a->d));
     return true;
 }
 
 static bool trans_l_mul(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_mul(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_mulu(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_mulu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    gen_mulu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_div(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_div(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    gen_div(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_divu(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_divu(dc, cpu_R[a->d], cpu_R[a->a], cpu_R[a->b]);
+    gen_divu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_muld(DisasContext *dc, arg_ab *a)
 {
-    gen_muld(dc, cpu_R[a->a], cpu_R[a->b]);
+    gen_muld(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_muldu(DisasContext *dc, arg_ab *a)
 {
-    gen_muldu(dc, cpu_R[a->a], cpu_R[a->b]);
+    gen_muldu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
@@ -617,7 +622,7 @@ static bool trans_l_jal(DisasContext *dc, arg_l_jal *a)
     target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
     target_ulong ret_pc = dc->base.pc_next + 8;
 
-    tcg_gen_movi_tl(cpu_R[9], ret_pc);
+    tcg_gen_movi_tl(cpu_regs[9], ret_pc);
     /* Optimize jal being used to load the PC for PIC.  */
     if (tmp_pc != ret_pc) {
         tcg_gen_movi_tl(jmp_pc, tmp_pc);
@@ -656,15 +661,15 @@ static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a)
 
 static bool trans_l_jr(DisasContext *dc, arg_l_jr *a)
 {
-    tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
+    tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b));
     dc->delayed_branch = 2;
     return true;
 }
 
 static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a)
 {
-    tcg_gen_mov_tl(jmp_pc, cpu_R[a->b]);
-    tcg_gen_movi_tl(cpu_R[9], dc->base.pc_next + 8);
+    tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b));
+    tcg_gen_movi_tl(cpu_regs[9], dc->base.pc_next + 8);
     dc->delayed_branch = 2;
     return true;
 }
@@ -675,10 +680,10 @@ static bool trans_l_lwa(DisasContext *dc, arg_load *a)
 
     check_r0_write(dc, a->d);
     ea = tcg_temp_new();
-    tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
-    tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, MO_TEUL);
+    tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
+    tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, MO_TEUL);
     tcg_gen_mov_tl(cpu_lock_addr, ea);
-    tcg_gen_mov_tl(cpu_lock_value, cpu_R[a->d]);
+    tcg_gen_mov_tl(cpu_lock_value, cpu_R(dc, a->d));
     tcg_temp_free(ea);
     return true;
 }
@@ -689,8 +694,8 @@ static void do_load(DisasContext *dc, arg_load *a, MemOp mop)
 
     check_r0_write(dc, a->d);
     ea = tcg_temp_new();
-    tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
-    tcg_gen_qemu_ld_tl(cpu_R[a->d], ea, dc->mem_idx, mop);
+    tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
+    tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, mop);
     tcg_temp_free(ea);
 }
 
@@ -736,13 +741,13 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a)
     TCGLabel *lab_fail, *lab_done;
 
     ea = tcg_temp_new();
-    tcg_gen_addi_tl(ea, cpu_R[a->a], a->i);
+    tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
 
     /* For TB_FLAGS_R0_0, the branch below invalidates the temporary assigned
-       to cpu_R[0].  Since l.swa is quite often immediately followed by a
+       to cpu_regs[0].  Since l.swa is quite often immediately followed by a
        branch, don't bother reallocating; finish the TB using the "real" R0.
        This also takes care of RB input across the branch.  */
-    cpu_R[0] = cpu_R0;
+    cpu_regs[0] = cpu_R0;
 
     lab_fail = gen_new_label();
     lab_done = gen_new_label();
@@ -751,7 +756,7 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a)
 
     val = tcg_temp_new();
     tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
-                              cpu_R[a->b], dc->mem_idx, MO_TEUL);
+                              cpu_regs[a->b], dc->mem_idx, MO_TEUL);
     tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
     tcg_temp_free(val);
 
@@ -768,8 +773,8 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a)
 static void do_store(DisasContext *dc, arg_store *a, MemOp mop)
 {
     TCGv t0 = tcg_temp_new();
-    tcg_gen_addi_tl(t0, cpu_R[a->a], a->i);
-    tcg_gen_qemu_st_tl(cpu_R[a->b], t0, dc->mem_idx, mop);
+    tcg_gen_addi_tl(t0, cpu_R(dc, a->a), a->i);
+    tcg_gen_qemu_st_tl(cpu_R(dc, a->b), t0, dc->mem_idx, mop);
     tcg_temp_free(t0);
 }
 
@@ -802,7 +807,7 @@ static bool trans_l_addi(DisasContext *dc, arg_rri *a)
 
     check_r0_write(dc, a->d);
     t0 = tcg_const_tl(a->i);
-    gen_add(dc, cpu_R[a->d], cpu_R[a->a], t0);
+    gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0);
     tcg_temp_free(t0);
     return true;
 }
@@ -813,7 +818,7 @@ static bool trans_l_addic(DisasContext *dc, arg_rri *a)
 
     check_r0_write(dc, a->d);
     t0 = tcg_const_tl(a->i);
-    gen_addc(dc, cpu_R[a->d], cpu_R[a->a], t0);
+    gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0);
     tcg_temp_free(t0);
     return true;
 }
@@ -824,7 +829,7 @@ static bool trans_l_muli(DisasContext *dc, arg_rri *a)
 
     check_r0_write(dc, a->d);
     t0 = tcg_const_tl(a->i);
-    gen_mul(dc, cpu_R[a->d], cpu_R[a->a], t0);
+    gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), t0);
     tcg_temp_free(t0);
     return true;
 }
@@ -834,7 +839,7 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a)
     TCGv t0;
 
     t0 = tcg_const_tl(a->i);
-    gen_mac(dc, cpu_R[a->a], t0);
+    gen_mac(dc, cpu_R(dc, a->a), t0);
     tcg_temp_free(t0);
     return true;
 }
@@ -842,21 +847,21 @@ static bool trans_l_maci(DisasContext *dc, arg_l_maci *a)
 static bool trans_l_andi(DisasContext *dc, arg_rrk *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_andi_tl(cpu_R[a->d], cpu_R[a->a], a->k);
+    tcg_gen_andi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k);
     return true;
 }
 
 static bool trans_l_ori(DisasContext *dc, arg_rrk *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_ori_tl(cpu_R[a->d], cpu_R[a->a], a->k);
+    tcg_gen_ori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k);
     return true;
 }
 
 static bool trans_l_xori(DisasContext *dc, arg_rri *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_xori_tl(cpu_R[a->d], cpu_R[a->a], a->i);
+    tcg_gen_xori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->i);
     return true;
 }
 
@@ -868,8 +873,8 @@ static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
         gen_illegal_exception(dc);
     } else {
         TCGv spr = tcg_temp_new();
-        tcg_gen_ori_tl(spr, cpu_R[a->a], a->k);
-        gen_helper_mfspr(cpu_R[a->d], cpu_env, cpu_R[a->d], spr);
+        tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
+        gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr);
         tcg_temp_free(spr);
     }
     return true;
@@ -896,8 +901,8 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
         dc->base.is_jmp = DISAS_EXIT;
 
         spr = tcg_temp_new();
-        tcg_gen_ori_tl(spr, cpu_R[a->a], a->k);
-        gen_helper_mtspr(cpu_env, spr, cpu_R[a->b]);
+        tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
+        gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b));
         tcg_temp_free(spr);
     }
     return true;
@@ -905,188 +910,202 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
 
 static bool trans_l_mac(DisasContext *dc, arg_ab *a)
 {
-    gen_mac(dc, cpu_R[a->a], cpu_R[a->b]);
+    gen_mac(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_msb(DisasContext *dc, arg_ab *a)
 {
-    gen_msb(dc, cpu_R[a->a], cpu_R[a->b]);
+    gen_msb(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_macu(DisasContext *dc, arg_ab *a)
 {
-    gen_macu(dc, cpu_R[a->a], cpu_R[a->b]);
+    gen_macu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_msbu(DisasContext *dc, arg_ab *a)
 {
-    gen_msbu(dc, cpu_R[a->a], cpu_R[a->b]);
+    gen_msbu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_slli(DisasContext *dc, arg_dal *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_shli_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
+    tcg_gen_shli_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
+                    a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_srli(DisasContext *dc, arg_dal *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_shri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
+    tcg_gen_shri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
+                    a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_srai(DisasContext *dc, arg_dal *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_sari_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
+    tcg_gen_sari_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
+                    a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_rori(DisasContext *dc, arg_dal *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_rotri_tl(cpu_R[a->d], cpu_R[a->a], a->l & (TARGET_LONG_BITS - 1));
+    tcg_gen_rotri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
+                     a->l & (TARGET_LONG_BITS - 1));
     return true;
 }
 
 static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_movi_tl(cpu_R[a->d], a->k << 16);
+    tcg_gen_movi_tl(cpu_R(dc, a->d), a->k << 16);
     return true;
 }
 
 static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a)
 {
     check_r0_write(dc, a->d);
-    tcg_gen_trunc_i64_tl(cpu_R[a->d], cpu_mac);
+    tcg_gen_trunc_i64_tl(cpu_R(dc, a->d), cpu_mac);
     tcg_gen_movi_i64(cpu_mac, 0);
     return true;
 }
 
 static bool trans_l_sfeq(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfne(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfltu(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfleu(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfgts(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfges(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sflts(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f,
+                       cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfles(DisasContext *dc, arg_ab *a)
 {
-    tcg_gen_setcond_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], cpu_R[a->b]);
+    tcg_gen_setcond_tl(TCG_COND_LE,
+                       cpu_sr_f, cpu_R(dc, a->a), cpu_R(dc, a->b));
     return true;
 }
 
 static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfnei(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfltui(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfleui(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
 static bool trans_l_sflesi(DisasContext *dc, arg_ai *a)
 {
-    tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R[a->a], a->i);
+    tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R(dc, a->a), a->i);
     return true;
 }
 
@@ -1137,7 +1156,7 @@ static void do_fp2(DisasContext *dc, arg_da *a,
                    void (*fn)(TCGv, TCGv_env, TCGv))
 {
     check_r0_write(dc, a->d);
-    fn(cpu_R[a->d], cpu_env, cpu_R[a->a]);
+    fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a));
     gen_helper_update_fpcsr(cpu_env);
 }
 
@@ -1145,7 +1164,7 @@ static void do_fp3(DisasContext *dc, arg_dab *a,
                    void (*fn)(TCGv, TCGv_env, TCGv, TCGv))
 {
     check_r0_write(dc, a->d);
-    fn(cpu_R[a->d], cpu_env, cpu_R[a->a], cpu_R[a->b]);
+    fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a), cpu_R(dc, a->b));
     gen_helper_update_fpcsr(cpu_env);
 }
 
@@ -1154,9 +1173,9 @@ static void do_fpcmp(DisasContext *dc, arg_ab *a,
                      bool inv, bool swap)
 {
     if (swap) {
-        fn(cpu_sr_f, cpu_env, cpu_R[a->b], cpu_R[a->a]);
+        fn(cpu_sr_f, cpu_env, cpu_R(dc, a->b), cpu_R(dc, a->a));
     } else {
-        fn(cpu_sr_f, cpu_env, cpu_R[a->a], cpu_R[a->b]);
+        fn(cpu_sr_f, cpu_env, cpu_R(dc, a->a), cpu_R(dc, a->b));
     }
     if (inv) {
         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
@@ -1209,8 +1228,8 @@ static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a)
 static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a)
 {
     check_r0_write(dc, a->d);
-    gen_helper_float_madd_s(cpu_R[a->d], cpu_env, cpu_R[a->d],
-                            cpu_R[a->a], cpu_R[a->b]);
+    gen_helper_float_madd_s(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d),
+                            cpu_R(dc, a->a), cpu_R(dc, a->b));
     gen_helper_update_fpcsr(cpu_env);
     return true;
 }
@@ -1273,9 +1292,9 @@ static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
     /* Allow the TCG optimizer to see that R0 == 0,
        when it's true, which is the common case.  */
     if (dc->tb_flags & TB_FLAGS_R0_0) {
-        cpu_R[0] = tcg_const_tl(0);
+        cpu_regs[0] = tcg_const_tl(0);
     } else {
-        cpu_R[0] = cpu_R0;
+        cpu_regs[0] = cpu_R0;
     }
 }
 
-- 
2.17.1



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

* [Qemu-devel] [PULL 03/13] target/openrisc: Cache R0 in DisasContext
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 01/13] target/openrisc: Add DisasContext parameter to check_r0_write Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 02/13] target/openrisc: Replace cpu register array with a function Richard Henderson
@ 2019-09-04 20:44 ` Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 04/13] target/openrisc: Make VR and PPC read-only Richard Henderson
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Finish the race condition fix from the previous patch.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/translate.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index d635a46f7e..341f923864 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -48,6 +48,9 @@ typedef struct DisasContext {
 
     /* If not -1, jmp_pc contains this value and so is a direct jump.  */
     target_ulong jmp_pc_imm;
+
+    /* The temporary corresponding to register 0 for this compilation.  */
+    TCGv R0;
 } DisasContext;
 
 static inline bool is_user(DisasContext *dc)
@@ -64,7 +67,6 @@ static inline bool is_user(DisasContext *dc)
 
 static TCGv cpu_sr;
 static TCGv cpu_regs[32];
-static TCGv cpu_R0;
 static TCGv cpu_pc;
 static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
 static TCGv cpu_ppc;
@@ -122,7 +124,6 @@ void openrisc_translate_init(void)
                                                   shadow_gpr[0][i]),
                                          regnames[i]);
     }
-    cpu_R0 = cpu_regs[0];
 }
 
 static void gen_exception(DisasContext *dc, unsigned int excp)
@@ -165,7 +166,11 @@ static void check_ov64s(DisasContext *dc)
 
 static TCGv cpu_R(DisasContext *dc, int reg)
 {
-    return cpu_regs[reg];
+    if (reg == 0) {
+        return dc->R0;
+    } else {
+        return cpu_regs[reg];
+    }
 }
 
 /*
@@ -175,7 +180,7 @@ static TCGv cpu_R(DisasContext *dc, int reg)
 static void check_r0_write(DisasContext *dc, int reg)
 {
     if (unlikely(reg == 0)) {
-        cpu_regs[0] = cpu_R0;
+        dc->R0 = cpu_regs[0];
     }
 }
 
@@ -747,7 +752,7 @@ static bool trans_l_swa(DisasContext *dc, arg_store *a)
        to cpu_regs[0].  Since l.swa is quite often immediately followed by a
        branch, don't bother reallocating; finish the TB using the "real" R0.
        This also takes care of RB input across the branch.  */
-    cpu_regs[0] = cpu_R0;
+    dc->R0 = cpu_regs[0];
 
     lab_fail = gen_new_label();
     lab_done = gen_new_label();
@@ -1292,9 +1297,9 @@ static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
     /* Allow the TCG optimizer to see that R0 == 0,
        when it's true, which is the common case.  */
     if (dc->tb_flags & TB_FLAGS_R0_0) {
-        cpu_regs[0] = tcg_const_tl(0);
+        dc->R0 = tcg_const_tl(0);
     } else {
-        cpu_regs[0] = cpu_R0;
+        dc->R0 = cpu_regs[0];
     }
 }
 
-- 
2.17.1



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

* [Qemu-devel] [PULL 04/13] target/openrisc: Make VR and PPC read-only
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (2 preceding siblings ...)
  2019-09-04 20:44 ` [Qemu-devel] [PULL 03/13] target/openrisc: Cache R0 in DisasContext Richard Henderson
@ 2019-09-04 20:44 ` Richard Henderson
  2019-09-04 20:44 ` [Qemu-devel] [PULL 05/13] target/openrisc: Move VR, UPR, DMMCFGR, IMMCFGR to cpu init Richard Henderson
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

These SPRs are read-only.  The writes can simply be ignored,
as we already do for other read-only (or missing) registers.
There is no reason to mask the value in env->vr.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h        |  3 ---
 target/openrisc/sys_helper.c | 10 +---------
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 561f0f7fad..755282f95d 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -68,9 +68,6 @@ enum {
                                       (reg) |= ((v & 0x1f) << 2);\
                                   } while (0)
 
-/* Version Register */
-#define SPR_VR 0xFFFF003F
-
 /* Interrupt */
 #define NR_IRQS  32
 
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index 1053409a04..d20f48b659 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -39,10 +39,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     int idx;
 
     switch (spr) {
-    case TO_SPR(0, 0): /* VR */
-        env->vr = rb;
-        break;
-
     case TO_SPR(0, 11): /* EVBAR */
         env->evbar = rb;
         break;
@@ -62,10 +58,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         cpu_set_sr(env, rb);
         break;
 
-    case TO_SPR(0, 18): /* PPC */
-        env->ppc = rb;
-        break;
-
     case TO_SPR(0, 32): /* EPCR */
         env->epcr = rb;
         break;
@@ -204,7 +196,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
 
     switch (spr) {
     case TO_SPR(0, 0): /* VR */
-        return env->vr & SPR_VR;
+        return env->vr;
 
     case TO_SPR(0, 1): /* UPR */
         return env->upr;    /* TT, DM, IM, UP present */
-- 
2.17.1



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

* [Qemu-devel] [PULL 05/13] target/openrisc: Move VR, UPR, DMMCFGR, IMMCFGR to cpu init
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (3 preceding siblings ...)
  2019-09-04 20:44 ` [Qemu-devel] [PULL 04/13] target/openrisc: Make VR and PPC read-only Richard Henderson
@ 2019-09-04 20:44 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 06/13] target/openrisc: Add VR2 and AVR special processor registers Richard Henderson
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

These registers are read-only and implementation specific.
Initiailize VR for the first time; take the OR1200 values
from the verilog source.

Note that moving fields within CPUOpenRISCState does not
affect migration.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h        |  8 ++++----
 target/openrisc/cpu.c        | 23 ++++++++++++++++-------
 target/openrisc/sys_helper.c |  4 ++--
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 755282f95d..18d7445e74 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -260,10 +260,6 @@ typedef struct CPUOpenRISCState {
     target_ulong sr_cy;       /* the SR_CY bit, values 0, 1.  */
     target_long  sr_ov;       /* the SR_OV bit (in the sign 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 dmmucfgr;        /* DMMU configure register */
-    uint32_t immucfgr;        /* IMMU configure register */
     uint32_t esr;             /* Exception supervisor register */
     uint32_t evbar;           /* Exception vector base address register */
     uint32_t pmr;             /* Power Management Register */
@@ -283,7 +279,11 @@ typedef struct CPUOpenRISCState {
     struct {} end_reset_fields;
 
     /* Fields from here on are preserved across CPU reset. */
+    uint32_t vr;              /* Version register */
+    uint32_t upr;             /* Unit presence register */
     uint32_t cpucfgr;         /* CPU configure register */
+    uint32_t dmmucfgr;        /* DMMU configure register */
+    uint32_t immucfgr;        /* IMMU configure register */
 
 #ifndef CONFIG_USER_ONLY
     QEMUTimer *timer;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index f19e482a55..d9f447e90c 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -56,13 +56,6 @@ static void openrisc_cpu_reset(CPUState *s)
     cpu->env.lock_addr = -1;
     s->exception_index = -1;
 
-    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP |
-                   UPR_PMP;
-    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
-                      | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
-    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
-                      | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
-
 #ifndef CONFIG_USER_ONLY
     cpu->env.picmr = 0x00000000;
     cpu->env.picsr = 0x00000000;
@@ -117,15 +110,31 @@ static void or1200_initfn(Object *obj)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 
+    cpu->env.vr = 0x13000008;
+    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
     cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
                        CPUCFGR_EVBARP;
+
+    /* 1Way, TLB_SIZE entries.  */
+    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
+                      | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
+    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
+                      | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
 }
 
 static void openrisc_any_initfn(Object *obj)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 
+    cpu->env.vr = 0x13000000;
+    cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
     cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_EVBARP;
+
+    /* 1Way, TLB_SIZE entries.  */
+    cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
+                      | (DMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
+    cpu->env.immucfgr = (IMMUCFGR_NTW & (0 << 2))
+                      | (IMMUCFGR_NTS & (ctz32(TLB_SIZE) << 2));
 }
 
 static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index d20f48b659..a2b1f52294 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -199,13 +199,13 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
         return env->vr;
 
     case TO_SPR(0, 1): /* UPR */
-        return env->upr;    /* TT, DM, IM, UP present */
+        return env->upr;
 
     case TO_SPR(0, 2): /* CPUCFGR */
         return env->cpucfgr;
 
     case TO_SPR(0, 3): /* DMMUCFGR */
-        return env->dmmucfgr;    /* 1Way, 64 entries */
+        return env->dmmucfgr;
 
     case TO_SPR(0, 4): /* IMMUCFGR */
         return env->immucfgr;
-- 
2.17.1



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

* [Qemu-devel] [PULL 06/13] target/openrisc: Add VR2 and AVR special processor registers
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (4 preceding siblings ...)
  2019-09-04 20:44 ` [Qemu-devel] [PULL 05/13] target/openrisc: Move VR, UPR, DMMCFGR, IMMCFGR to cpu init Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 07/13] target/openrisc: Fix lf.ftoi.s Richard Henderson
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Update the CPUCFG bits to arch v1.3.
Include support for AVRP for cpu "any".

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h        | 11 +++++++----
 target/openrisc/cpu.c        |  8 ++++++--
 target/openrisc/sys_helper.c |  6 ++++++
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 18d7445e74..71c5959828 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -96,11 +96,12 @@ enum {
     CPUCFGR_OF32S = (1 << 7),
     CPUCFGR_OF64S = (1 << 8),
     CPUCFGR_OV64S = (1 << 9),
-    /* CPUCFGR_ND = (1 << 10), */
-    /* CPUCFGR_AVRP = (1 << 11), */
+    CPUCFGR_ND = (1 << 10),
+    CPUCFGR_AVRP = (1 << 11),
     CPUCFGR_EVBARP = (1 << 12),
-    /* CPUCFGR_ISRP = (1 << 13), */
-    /* CPUCFGR_AECSRP = (1 << 14), */
+    CPUCFGR_ISRP = (1 << 13),
+    CPUCFGR_AECSRP = (1 << 14),
+    CPUCFGR_OF64A32S = (1 << 15),
 };
 
 /* DMMU configure register */
@@ -280,6 +281,8 @@ typedef struct CPUOpenRISCState {
 
     /* Fields from here on are preserved across CPU reset. */
     uint32_t vr;              /* Version register */
+    uint32_t vr2;             /* Version register 2 */
+    uint32_t avr;             /* Architecture version register */
     uint32_t upr;             /* Unit presence register */
     uint32_t cpucfgr;         /* CPU configure register */
     uint32_t dmmucfgr;        /* DMMU configure register */
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index d9f447e90c..9f566ad883 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -126,9 +126,13 @@ static void openrisc_any_initfn(Object *obj)
 {
     OpenRISCCPU *cpu = OPENRISC_CPU(obj);
 
-    cpu->env.vr = 0x13000000;
+    cpu->env.vr = 0x13000040;   /* Obsolete VER + UVRP for new SPRs */
+    cpu->env.vr2 = 0;           /* No version specific id */
+    cpu->env.avr = 0x01010000;  /* Architecture v1.1 */
+
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
-    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_EVBARP;
+    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S |
+                       CPUCFGR_AVRP | CPUCFGR_EVBARP;
 
     /* 1Way, TLB_SIZE entries.  */
     cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index a2b1f52294..cf8e637b08 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -210,6 +210,12 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
     case TO_SPR(0, 4): /* IMMUCFGR */
         return env->immucfgr;
 
+    case TO_SPR(0, 9): /* VR2 */
+        return env->vr2;
+
+    case TO_SPR(0, 10): /* AVR */
+        return env->avr;
+
     case TO_SPR(0, 11): /* EVBAR */
         return env->evbar;
 
-- 
2.17.1



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

* [Qemu-devel] [PULL 07/13] target/openrisc: Fix lf.ftoi.s
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (5 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 06/13] target/openrisc: Add VR2 and AVR special processor registers Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 08/13] target/openrisc: Check CPUCFG_OF32S for float insns Richard Henderson
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

The specification of this insn is round-to-zero.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/fpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c
index b9d2ebbb8c..4cc5b297c5 100644
--- a/target/openrisc/fpu_helper.c
+++ b/target/openrisc/fpu_helper.c
@@ -78,7 +78,7 @@ uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
 
 uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
 {
-    return float32_to_int32(val, &env->fp_status);
+    return float32_to_int32_round_to_zero(val, &env->fp_status);
 }
 
 #define FLOAT_CALC(name)                                                  \
-- 
2.17.1



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

* [Qemu-devel] [PULL 08/13] target/openrisc: Check CPUCFG_OF32S for float insns
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (6 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 07/13] target/openrisc: Fix lf.ftoi.s Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 09/13] target/openrisc: Add support for ORFPX64A32 Richard Henderson
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Make sure the OF32S insns are enabled before allowing execution.
Include the missing bit for cpu "any".

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.c       |  2 +-
 target/openrisc/translate.c | 84 ++++++++++++++++---------------------
 2 files changed, 36 insertions(+), 50 deletions(-)

diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 9f566ad883..f3c8134531 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -131,7 +131,7 @@ static void openrisc_any_initfn(Object *obj)
     cpu->env.avr = 0x01010000;  /* Architecture v1.1 */
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
-    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S |
+    cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
                        CPUCFGR_AVRP | CPUCFGR_EVBARP;
 
     /* 1Way, TLB_SIZE entries.  */
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 341f923864..2f5c969f21 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -45,6 +45,7 @@ typedef struct DisasContext {
     uint32_t mem_idx;
     uint32_t tb_flags;
     uint32_t delayed_branch;
+    uint32_t cpucfgr;
 
     /* If not -1, jmp_pc contains this value and so is a direct jump.  */
     target_ulong jmp_pc_imm;
@@ -140,30 +141,11 @@ static void gen_illegal_exception(DisasContext *dc)
     dc->base.is_jmp = DISAS_NORETURN;
 }
 
-/* not used yet, open it when we need or64.  */
-/*#ifdef TARGET_OPENRISC64
-static void check_ob64s(DisasContext *dc)
+static bool check_of32s(DisasContext *dc)
 {
-    if (!(dc->flags & CPUCFGR_OB64S)) {
-        gen_illegal_exception(dc);
-    }
+    return dc->cpucfgr & CPUCFGR_OF32S;
 }
 
-static void check_of64s(DisasContext *dc)
-{
-    if (!(dc->flags & CPUCFGR_OF64S)) {
-        gen_illegal_exception(dc);
-    }
-}
-
-static void check_ov64s(DisasContext *dc)
-{
-    if (!(dc->flags & CPUCFGR_OV64S)) {
-        gen_illegal_exception(dc);
-    }
-}
-#endif*/
-
 static TCGv cpu_R(DisasContext *dc, int reg)
 {
     if (reg == 0) {
@@ -1157,26 +1139,37 @@ static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a)
     return true;
 }
 
-static void do_fp2(DisasContext *dc, arg_da *a,
+static bool do_fp2(DisasContext *dc, arg_da *a,
                    void (*fn)(TCGv, TCGv_env, TCGv))
 {
+    if (!check_of32s(dc)) {
+        return false;
+    }
     check_r0_write(dc, a->d);
     fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a));
     gen_helper_update_fpcsr(cpu_env);
+    return true;
 }
 
-static void do_fp3(DisasContext *dc, arg_dab *a,
+static bool do_fp3(DisasContext *dc, arg_dab *a,
                    void (*fn)(TCGv, TCGv_env, TCGv, TCGv))
 {
+    if (!check_of32s(dc)) {
+        return false;
+    }
     check_r0_write(dc, a->d);
     fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a), cpu_R(dc, a->b));
     gen_helper_update_fpcsr(cpu_env);
+    return true;
 }
 
-static void do_fpcmp(DisasContext *dc, arg_ab *a,
+static bool do_fpcmp(DisasContext *dc, arg_ab *a,
                      void (*fn)(TCGv, TCGv_env, TCGv, TCGv),
                      bool inv, bool swap)
 {
+    if (!check_of32s(dc)) {
+        return false;
+    }
     if (swap) {
         fn(cpu_sr_f, cpu_env, cpu_R(dc, a->b), cpu_R(dc, a->a));
     } else {
@@ -1186,52 +1179,50 @@ static void do_fpcmp(DisasContext *dc, arg_ab *a,
         tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
     }
     gen_helper_update_fpcsr(cpu_env);
+    return true;
 }
 
 static bool trans_lf_add_s(DisasContext *dc, arg_dab *a)
 {
-    do_fp3(dc, a, gen_helper_float_add_s);
-    return true;
+    return do_fp3(dc, a, gen_helper_float_add_s);
 }
 
 static bool trans_lf_sub_s(DisasContext *dc, arg_dab *a)
 {
-    do_fp3(dc, a, gen_helper_float_sub_s);
-    return true;
+    return do_fp3(dc, a, gen_helper_float_sub_s);
 }
 
 static bool trans_lf_mul_s(DisasContext *dc, arg_dab *a)
 {
-    do_fp3(dc, a, gen_helper_float_mul_s);
-    return true;
+    return do_fp3(dc, a, gen_helper_float_mul_s);
 }
 
 static bool trans_lf_div_s(DisasContext *dc, arg_dab *a)
 {
-    do_fp3(dc, a, gen_helper_float_div_s);
-    return true;
+    return do_fp3(dc, a, gen_helper_float_div_s);
 }
 
 static bool trans_lf_rem_s(DisasContext *dc, arg_dab *a)
 {
-    do_fp3(dc, a, gen_helper_float_rem_s);
+    return do_fp3(dc, a, gen_helper_float_rem_s);
     return true;
 }
 
 static bool trans_lf_itof_s(DisasContext *dc, arg_da *a)
 {
-    do_fp2(dc, a, gen_helper_itofs);
-    return true;
+    return do_fp2(dc, a, gen_helper_itofs);
 }
 
 static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a)
 {
-    do_fp2(dc, a, gen_helper_ftois);
-    return true;
+    return do_fp2(dc, a, gen_helper_ftois);
 }
 
 static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a)
 {
+    if (!check_of32s(dc)) {
+        return false;
+    }
     check_r0_write(dc, a->d);
     gen_helper_float_madd_s(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d),
                             cpu_R(dc, a->a), cpu_R(dc, a->b));
@@ -1241,38 +1232,32 @@ static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a)
 
 static bool trans_lf_sfeq_s(DisasContext *dc, arg_ab *a)
 {
-    do_fpcmp(dc, a, gen_helper_float_eq_s, false, false);
-    return true;
+    return do_fpcmp(dc, a, gen_helper_float_eq_s, false, false);
 }
 
 static bool trans_lf_sfne_s(DisasContext *dc, arg_ab *a)
 {
-    do_fpcmp(dc, a, gen_helper_float_eq_s, true, false);
-    return true;
+    return do_fpcmp(dc, a, gen_helper_float_eq_s, true, false);
 }
 
 static bool trans_lf_sfgt_s(DisasContext *dc, arg_ab *a)
 {
-    do_fpcmp(dc, a, gen_helper_float_lt_s, false, true);
-    return true;
+    return do_fpcmp(dc, a, gen_helper_float_lt_s, false, true);
 }
 
 static bool trans_lf_sfge_s(DisasContext *dc, arg_ab *a)
 {
-    do_fpcmp(dc, a, gen_helper_float_le_s, false, true);
-    return true;
+    return do_fpcmp(dc, a, gen_helper_float_le_s, false, true);
 }
 
 static bool trans_lf_sflt_s(DisasContext *dc, arg_ab *a)
 {
-    do_fpcmp(dc, a, gen_helper_float_lt_s, false, false);
-    return true;
+    return do_fpcmp(dc, a, gen_helper_float_lt_s, false, false);
 }
 
 static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a)
 {
-    do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
-    return true;
+    return do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
 }
 
 static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
@@ -1284,6 +1269,7 @@ static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     dc->mem_idx = cpu_mmu_index(env, false);
     dc->tb_flags = dc->base.tb->flags;
     dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
+    dc->cpucfgr = env->cpucfgr;
     dc->jmp_pc_imm = -1;
 
     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
-- 
2.17.1



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

* [Qemu-devel] [PULL 09/13] target/openrisc: Add support for ORFPX64A32
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (7 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 08/13] target/openrisc: Check CPUCFG_OF32S for float insns Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 10/13] target/openrisc: Implement unordered fp comparisons Richard Henderson
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This is hardware support for double-precision floating-point using
pairs of 32-bit registers.  Fix latent bugs in the heretofore unused
helper_itofd and helper_ftoid.  Include the bit for cpu "any".
Change the default cpu for linux-user to "any".

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 linux-user/openrisc/target_elf.h |   2 +-
 target/openrisc/helper.h         |   2 +
 target/openrisc/cpu.c            |   2 +-
 target/openrisc/disas.c          |  56 ++++++++
 target/openrisc/fpu_helper.c     |  14 +-
 target/openrisc/translate.c      | 230 +++++++++++++++++++++++++++++++
 target/openrisc/insns.decode     |  31 +++++
 7 files changed, 333 insertions(+), 4 deletions(-)

diff --git a/linux-user/openrisc/target_elf.h b/linux-user/openrisc/target_elf.h
index 40ceb025c9..265ecd3079 100644
--- a/linux-user/openrisc/target_elf.h
+++ b/linux-user/openrisc/target_elf.h
@@ -9,6 +9,6 @@
 #define OPENRISC_TARGET_ELF_H
 static inline const char *cpu_get_model(uint32_t eflags)
 {
-    return "or1200";
+    return "any";
 }
 #endif
diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
index 96d79a8113..94b823580e 100644
--- a/target/openrisc/helper.h
+++ b/target/openrisc/helper.h
@@ -30,6 +30,8 @@ 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_2(stod, TCG_CALL_NO_RWG, i64, env, i32)
+DEF_HELPER_FLAGS_2(dtos, TCG_CALL_NO_RWG, i32, env, i64)
 
 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)
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index f3c8134531..b931605e62 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -132,7 +132,7 @@ static void openrisc_any_initfn(Object *obj)
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
     cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
-                       CPUCFGR_AVRP | CPUCFGR_EVBARP;
+                       CPUCFGR_AVRP | CPUCFGR_EVBARP | CPUCFGR_OF64A32S;
 
     /* 1Way, TLB_SIZE entries.  */
     cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 << 2))
diff --git a/target/openrisc/disas.c b/target/openrisc/disas.c
index 7091832347..4de5c632de 100644
--- a/target/openrisc/disas.c
+++ b/target/openrisc/disas.c
@@ -166,3 +166,59 @@ FP_INSN(sfgt, s, "r%d, r%d", a->a, a->b)
 FP_INSN(sfge, s, "r%d, r%d", a->a, a->b)
 FP_INSN(sflt, s, "r%d, r%d", a->a, a->b)
 FP_INSN(sfle, s, "r%d, r%d", a->a, a->b)
+
+FP_INSN(add, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sub, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(mul, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(div, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(rem, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(madd, d, "r%d,r%d, r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+
+FP_INSN(itof, d, "r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1)
+FP_INSN(ftoi, d, "r%d,r%d, r%d,r%d",
+        a->d, a->d + a->dp + 1,
+        a->a, a->a + a->ap + 1)
+
+FP_INSN(stod, d, "r%d,r%d, r%d",
+        a->d, a->d + a->dp + 1, a->a)
+FP_INSN(dtos, d, "r%d r%d,r%d",
+        a->d, a->a, a->a + a->ap + 1)
+
+FP_INSN(sfeq, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfne, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfgt, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfge, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sflt, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfle, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c
index 4cc5b297c5..9d7dfc0fb9 100644
--- a/target/openrisc/fpu_helper.c
+++ b/target/openrisc/fpu_helper.c
@@ -63,7 +63,7 @@ void HELPER(update_fpcsr)(CPUOpenRISCState *env)
 
 uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
 {
-    return int32_to_float64(val, &env->fp_status);
+    return int64_to_float64(val, &env->fp_status);
 }
 
 uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
@@ -73,7 +73,7 @@ uint32_t HELPER(itofs)(CPUOpenRISCState *env, uint32_t val)
 
 uint64_t HELPER(ftoid)(CPUOpenRISCState *env, uint64_t val)
 {
-    return float32_to_int64(val, &env->fp_status);
+    return float64_to_int64_round_to_zero(val, &env->fp_status);
 }
 
 uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
@@ -81,6 +81,16 @@ uint32_t HELPER(ftois)(CPUOpenRISCState *env, uint32_t val)
     return float32_to_int32_round_to_zero(val, &env->fp_status);
 }
 
+uint64_t HELPER(stod)(CPUOpenRISCState *env, uint32_t val)
+{
+    return float32_to_float64(val, &env->fp_status);
+}
+
+uint32_t HELPER(dtos)(CPUOpenRISCState *env, uint64_t val)
+{
+    return float64_to_float32(val, &env->fp_status);
+}
+
 #define FLOAT_CALC(name)                                                  \
 uint64_t helper_float_ ## name ## _d(CPUOpenRISCState *env,               \
                                      uint64_t fdt0, uint64_t fdt1)        \
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 2f5c969f21..b8ef485903 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -146,6 +146,11 @@ static bool check_of32s(DisasContext *dc)
     return dc->cpucfgr & CPUCFGR_OF32S;
 }
 
+static bool check_of64a32s(DisasContext *dc)
+{
+    return dc->cpucfgr & CPUCFGR_OF64A32S;
+}
+
 static TCGv cpu_R(DisasContext *dc, int reg)
 {
     if (reg == 0) {
@@ -1260,6 +1265,231 @@ static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a)
     return do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
 }
 
+static bool check_pair(DisasContext *dc, int r, int p)
+{
+    return r + 1 + p < 32;
+}
+
+static void load_pair(DisasContext *dc, TCGv_i64 t, int r, int p)
+{
+    tcg_gen_concat_i32_i64(t, cpu_R(dc, r + 1 + p), cpu_R(dc, r));
+}
+
+static void save_pair(DisasContext *dc, TCGv_i64 t, int r, int p)
+{
+    tcg_gen_extr_i64_i32(cpu_R(dc, r + 1 + p), cpu_R(dc, r), t);
+}
+
+static bool do_dp3(DisasContext *dc, arg_dab_pair *a,
+                   void (*fn)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
+{
+    TCGv_i64 t0, t1;
+
+    if (!check_of64a32s(dc) ||
+        !check_pair(dc, a->a, a->ap) ||
+        !check_pair(dc, a->b, a->bp) ||
+        !check_pair(dc, a->d, a->dp)) {
+        return false;
+    }
+    check_r0_write(dc, a->d);
+
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
+    load_pair(dc, t0, a->a, a->ap);
+    load_pair(dc, t1, a->b, a->bp);
+    fn(t0, cpu_env, t0, t1);
+    save_pair(dc, t0, a->d, a->dp);
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
+
+    gen_helper_update_fpcsr(cpu_env);
+    return true;
+}
+
+static bool do_dp2(DisasContext *dc, arg_da_pair *a,
+                   void (*fn)(TCGv_i64, TCGv_env, TCGv_i64))
+{
+    TCGv_i64 t0;
+
+    if (!check_of64a32s(dc) ||
+        !check_pair(dc, a->a, a->ap) ||
+        !check_pair(dc, a->d, a->dp)) {
+        return false;
+    }
+    check_r0_write(dc, a->d);
+
+    t0 = tcg_temp_new_i64();
+    load_pair(dc, t0, a->a, a->ap);
+    fn(t0, cpu_env, t0);
+    save_pair(dc, t0, a->d, a->dp);
+    tcg_temp_free_i64(t0);
+
+    gen_helper_update_fpcsr(cpu_env);
+    return true;
+}
+
+static bool do_dpcmp(DisasContext *dc, arg_ab_pair *a,
+                     void (*fn)(TCGv, TCGv_env, TCGv_i64, TCGv_i64),
+                     bool inv, bool swap)
+{
+    TCGv_i64 t0, t1;
+
+    if (!check_of64a32s(dc) ||
+        !check_pair(dc, a->a, a->ap) ||
+        !check_pair(dc, a->b, a->bp)) {
+        return false;
+    }
+
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
+    load_pair(dc, t0, a->a, a->ap);
+    load_pair(dc, t1, a->b, a->bp);
+    if (swap) {
+        fn(cpu_sr_f, cpu_env, t1, t0);
+    } else {
+        fn(cpu_sr_f, cpu_env, t0, t1);
+    }
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
+
+    if (inv) {
+        tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
+    }
+    gen_helper_update_fpcsr(cpu_env);
+    return true;
+}
+
+static bool trans_lf_add_d(DisasContext *dc, arg_dab_pair *a)
+{
+    return do_dp3(dc, a, gen_helper_float_add_d);
+}
+
+static bool trans_lf_sub_d(DisasContext *dc, arg_dab_pair *a)
+{
+    return do_dp3(dc, a, gen_helper_float_sub_d);
+}
+
+static bool trans_lf_mul_d(DisasContext *dc, arg_dab_pair *a)
+{
+    return do_dp3(dc, a, gen_helper_float_mul_d);
+}
+
+static bool trans_lf_div_d(DisasContext *dc, arg_dab_pair *a)
+{
+    return do_dp3(dc, a, gen_helper_float_div_d);
+}
+
+static bool trans_lf_rem_d(DisasContext *dc, arg_dab_pair *a)
+{
+    return do_dp3(dc, a, gen_helper_float_rem_d);
+}
+
+static bool trans_lf_itof_d(DisasContext *dc, arg_da_pair *a)
+{
+    return do_dp2(dc, a, gen_helper_itofd);
+}
+
+static bool trans_lf_ftoi_d(DisasContext *dc, arg_da_pair *a)
+{
+    return do_dp2(dc, a, gen_helper_ftoid);
+}
+
+static bool trans_lf_stod_d(DisasContext *dc, arg_lf_stod_d *a)
+{
+    TCGv_i64 t0;
+
+    if (!check_of64a32s(dc) ||
+        !check_pair(dc, a->d, a->dp)) {
+        return false;
+    }
+    check_r0_write(dc, a->d);
+
+    t0 = tcg_temp_new_i64();
+    gen_helper_stod(t0, cpu_env, cpu_R(dc, a->a));
+    save_pair(dc, t0, a->d, a->dp);
+    tcg_temp_free_i64(t0);
+
+    gen_helper_update_fpcsr(cpu_env);
+    return true;
+}
+
+static bool trans_lf_dtos_d(DisasContext *dc, arg_lf_dtos_d *a)
+{
+    TCGv_i64 t0;
+
+    if (!check_of64a32s(dc) ||
+        !check_pair(dc, a->a, a->ap)) {
+        return false;
+    }
+    check_r0_write(dc, a->d);
+
+    t0 = tcg_temp_new_i64();
+    load_pair(dc, t0, a->a, a->ap);
+    gen_helper_dtos(cpu_R(dc, a->d), cpu_env, t0);
+    tcg_temp_free_i64(t0);
+
+    gen_helper_update_fpcsr(cpu_env);
+    return true;
+}
+
+static bool trans_lf_madd_d(DisasContext *dc, arg_dab_pair *a)
+{
+    TCGv_i64 t0, t1, t2;
+
+    if (!check_of64a32s(dc) ||
+        !check_pair(dc, a->a, a->ap) ||
+        !check_pair(dc, a->b, a->bp) ||
+        !check_pair(dc, a->d, a->dp)) {
+        return false;
+    }
+    check_r0_write(dc, a->d);
+
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
+    t2 = tcg_temp_new_i64();
+    load_pair(dc, t0, a->d, a->dp);
+    load_pair(dc, t1, a->a, a->ap);
+    load_pair(dc, t2, a->b, a->bp);
+    gen_helper_float_madd_d(t0, cpu_env, t0, t1, t2);
+    save_pair(dc, t0, a->d, a->dp);
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
+    tcg_temp_free_i64(t2);
+
+    gen_helper_update_fpcsr(cpu_env);
+    return true;
+}
+
+static bool trans_lf_sfeq_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_eq_d, false, false);
+}
+
+static bool trans_lf_sfne_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_eq_d, true, false);
+}
+
+static bool trans_lf_sfgt_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_lt_d, false, true);
+}
+
+static bool trans_lf_sfge_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_le_d, false, true);
+}
+
+static bool trans_lf_sflt_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_lt_d, false, false);
+}
+
+static bool trans_lf_sfle_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_le_d, false, false);
+}
+
 static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
 {
     DisasContext *dc = container_of(dcb, DisasContext, base);
diff --git a/target/openrisc/insns.decode b/target/openrisc/insns.decode
index 7df81c1f22..334d4e9668 100644
--- a/target/openrisc/insns.decode
+++ b/target/openrisc/insns.decode
@@ -22,6 +22,9 @@
 &ab             a b
 &dal            d a l
 &ai             a i
+&dab_pair       d a b dp ap bp
+&ab_pair        a b ap bp
+&da_pair        d a dp ap
 
 ####
 # System Instructions
@@ -187,3 +190,31 @@ lf_sfgt_s       110010 ----- a:5 b:5 --- 00001010
 lf_sfge_s       110010 ----- a:5 b:5 --- 00001011
 lf_sflt_s       110010 ----- a:5 b:5 --- 00001100
 lf_sfle_s       110010 ----- a:5 b:5 --- 00001101
+
+####
+# DP Instructions
+####
+
+@dab_pair       ...... d:5   a:5 b:5   dp:1 ap:1 bp:1 ........  &dab_pair
+@ab_pair        ...... ..... a:5 b:5   .    ap:1 bp:1 ........  &ab_pair
+@da_pair        ...... d:5   a:5 ..... dp:1 ap:1 .    ........  &da_pair
+
+lf_add_d        110010 ..... ..... ..... ... 00010000  @dab_pair
+lf_sub_d        110010 ..... ..... ..... ... 00010001  @dab_pair
+lf_mul_d        110010 ..... ..... ..... ... 00010010  @dab_pair
+lf_div_d        110010 ..... ..... ..... ... 00010011  @dab_pair
+lf_rem_d        110010 ..... ..... ..... ... 00010110  @dab_pair
+lf_madd_d       110010 ..... ..... ..... ... 00010111  @dab_pair
+
+lf_itof_d       110010 ..... ..... 00000 ..0 00010100  @da_pair
+lf_ftoi_d       110010 ..... ..... 00000 ..0 00010101  @da_pair
+
+lf_stod_d       110010 d:5 a:5 00000 dp:1 0 0 00110100
+lf_dtos_d       110010 d:5 a:5 00000 0 ap:1 0 00110101
+
+lf_sfeq_d       110010 00000 ..... ..... 0.. 00011000  @ab_pair
+lf_sfne_d       110010 00000 ..... ..... 0.. 00011001  @ab_pair
+lf_sfgt_d       110010 00000 ..... ..... 0.. 00011010  @ab_pair
+lf_sfge_d       110010 00000 ..... ..... 0.. 00011011  @ab_pair
+lf_sflt_d       110010 00000 ..... ..... 0.. 00011100  @ab_pair
+lf_sfle_d       110010 00000 ..... ..... 0.. 00011101  @ab_pair
-- 
2.17.1



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

* [Qemu-devel] [PULL 10/13] target/openrisc: Implement unordered fp comparisons
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (8 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 09/13] target/openrisc: Add support for ORFPX64A32 Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 11/13] target/openrisc: Implement move to/from FPCSR Richard Henderson
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

These were added to the 1.3 spec.  For OF32S, validate AVR.
But OF64A32 is itself new to 1.3 so no extra check needed.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/helper.h     |  4 ++
 target/openrisc/disas.c      | 24 ++++++++++
 target/openrisc/fpu_helper.c | 20 +++++++++
 target/openrisc/translate.c  | 85 ++++++++++++++++++++++++++++++++++++
 target/openrisc/insns.decode | 12 +++++
 5 files changed, 145 insertions(+)

diff --git a/target/openrisc/helper.h b/target/openrisc/helper.h
index 94b823580e..d847814a28 100644
--- a/target/openrisc/helper.h
+++ b/target/openrisc/helper.h
@@ -52,6 +52,10 @@ 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(un)
+FOP_CMP(ueq)
+FOP_CMP(ule)
+FOP_CMP(ult)
 #undef FOP_CMP
 
 /* interrupt */
diff --git a/target/openrisc/disas.c b/target/openrisc/disas.c
index 4de5c632de..e51cbb24c6 100644
--- a/target/openrisc/disas.c
+++ b/target/openrisc/disas.c
@@ -166,6 +166,12 @@ FP_INSN(sfgt, s, "r%d, r%d", a->a, a->b)
 FP_INSN(sfge, s, "r%d, r%d", a->a, a->b)
 FP_INSN(sflt, s, "r%d, r%d", a->a, a->b)
 FP_INSN(sfle, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfun, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfueq, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfuge, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfugt, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfule, s, "r%d, r%d", a->a, a->b)
+FP_INSN(sfult, s, "r%d, r%d", a->a, a->b)
 
 FP_INSN(add, d,  "r%d,r%d, r%d,r%d, r%d,r%d",
         a->d, a->d + a->dp + 1,
@@ -222,3 +228,21 @@ FP_INSN(sflt, d, "r%d,r%d, r%d,r%d",
 FP_INSN(sfle, d, "r%d,r%d, r%d,r%d",
         a->a, a->a + a->ap + 1,
         a->b, a->b + a->bp + 1)
+FP_INSN(sfun, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfueq, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfuge, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfugt, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfule, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
+FP_INSN(sfult, d, "r%d,r%d, r%d,r%d",
+        a->a, a->a + a->ap + 1,
+        a->b, a->b + a->bp + 1)
diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c
index 9d7dfc0fb9..7bcef9dc53 100644
--- a/target/openrisc/fpu_helper.c
+++ b/target/openrisc/fpu_helper.c
@@ -135,4 +135,24 @@ target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env,           \
 FLOAT_CMP(le, le)
 FLOAT_CMP(lt, lt)
 FLOAT_CMP(eq, eq_quiet)
+FLOAT_CMP(un, unordered_quiet)
 #undef FLOAT_CMP
+
+#define FLOAT_UCMP(name, expr) \
+target_ulong helper_float_ ## name ## _d(CPUOpenRISCState *env,           \
+                                         uint64_t fdt0, uint64_t fdt1)    \
+{                                                                         \
+    int r = float64_compare_quiet(fdt0, fdt1, &env->fp_status);           \
+    return expr;                                                          \
+}                                                                         \
+target_ulong helper_float_ ## name ## _s(CPUOpenRISCState *env,           \
+                                         uint32_t fdt0, uint32_t fdt1)    \
+{                                                                         \
+    int r = float32_compare_quiet(fdt0, fdt1, &env->fp_status);           \
+    return expr;                                                          \
+}
+
+FLOAT_UCMP(ueq, r == float_relation_equal || r == float_relation_unordered)
+FLOAT_UCMP(ult, r == float_relation_less || r == float_relation_unordered)
+FLOAT_UCMP(ule, r != float_relation_greater)
+#undef FLOAT_UCMP
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index b8ef485903..6e8bc23568 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -46,6 +46,7 @@ typedef struct DisasContext {
     uint32_t tb_flags;
     uint32_t delayed_branch;
     uint32_t cpucfgr;
+    uint32_t avr;
 
     /* If not -1, jmp_pc contains this value and so is a direct jump.  */
     target_ulong jmp_pc_imm;
@@ -141,6 +142,11 @@ static void gen_illegal_exception(DisasContext *dc)
     dc->base.is_jmp = DISAS_NORETURN;
 }
 
+static bool check_v1_3(DisasContext *dc)
+{
+    return dc->avr >= 0x01030000;
+}
+
 static bool check_of32s(DisasContext *dc)
 {
     return dc->cpucfgr & CPUCFGR_OF32S;
@@ -1265,6 +1271,54 @@ static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a)
     return do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
 }
 
+static bool trans_lf_sfueq_s(DisasContext *dc, arg_ab *a)
+{
+    if (!check_v1_3(dc)) {
+        return false;
+    }
+    return do_fpcmp(dc, a, gen_helper_float_ueq_s, false, false);
+}
+
+static bool trans_lf_sfult_s(DisasContext *dc, arg_ab *a)
+{
+    if (!check_v1_3(dc)) {
+        return false;
+    }
+    return do_fpcmp(dc, a, gen_helper_float_ult_s, false, false);
+}
+
+static bool trans_lf_sfugt_s(DisasContext *dc, arg_ab *a)
+{
+    if (!check_v1_3(dc)) {
+        return false;
+    }
+    return do_fpcmp(dc, a, gen_helper_float_ult_s, false, true);
+}
+
+static bool trans_lf_sfule_s(DisasContext *dc, arg_ab *a)
+{
+    if (!check_v1_3(dc)) {
+        return false;
+    }
+    return do_fpcmp(dc, a, gen_helper_float_ule_s, false, false);
+}
+
+static bool trans_lf_sfuge_s(DisasContext *dc, arg_ab *a)
+{
+    if (!check_v1_3(dc)) {
+        return false;
+    }
+    return do_fpcmp(dc, a, gen_helper_float_ule_s, false, true);
+}
+
+static bool trans_lf_sfun_s(DisasContext *dc, arg_ab *a)
+{
+    if (!check_v1_3(dc)) {
+        return false;
+    }
+    return do_fpcmp(dc, a, gen_helper_float_un_s, false, false);
+}
+
 static bool check_pair(DisasContext *dc, int r, int p)
 {
     return r + 1 + p < 32;
@@ -1490,6 +1544,36 @@ static bool trans_lf_sfle_d(DisasContext *dc, arg_ab_pair *a)
     return do_dpcmp(dc, a, gen_helper_float_le_d, false, false);
 }
 
+static bool trans_lf_sfueq_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_ueq_d, false, false);
+}
+
+static bool trans_lf_sfule_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_ule_d, false, false);
+}
+
+static bool trans_lf_sfuge_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_ule_d, false, true);
+}
+
+static bool trans_lf_sfult_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_ult_d, false, false);
+}
+
+static bool trans_lf_sfugt_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_ult_d, false, true);
+}
+
+static bool trans_lf_sfun_d(DisasContext *dc, arg_ab_pair *a)
+{
+    return do_dpcmp(dc, a, gen_helper_float_un_d, false, false);
+}
+
 static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
 {
     DisasContext *dc = container_of(dcb, DisasContext, base);
@@ -1500,6 +1584,7 @@ static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
     dc->tb_flags = dc->base.tb->flags;
     dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
     dc->cpucfgr = env->cpucfgr;
+    dc->avr = env->avr;
     dc->jmp_pc_imm = -1;
 
     bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
diff --git a/target/openrisc/insns.decode b/target/openrisc/insns.decode
index 334d4e9668..71e0d740db 100644
--- a/target/openrisc/insns.decode
+++ b/target/openrisc/insns.decode
@@ -190,6 +190,12 @@ lf_sfgt_s       110010 ----- a:5 b:5 --- 00001010
 lf_sfge_s       110010 ----- a:5 b:5 --- 00001011
 lf_sflt_s       110010 ----- a:5 b:5 --- 00001100
 lf_sfle_s       110010 ----- a:5 b:5 --- 00001101
+lf_sfueq_s      110010 ----- a:5 b:5 --- 00101000
+lf_sfuge_s      110010 ----- a:5 b:5 --- 00101011
+lf_sfugt_s      110010 ----- a:5 b:5 --- 00101010
+lf_sfule_s      110010 ----- a:5 b:5 --- 00101101
+lf_sfult_s      110010 ----- a:5 b:5 --- 00101100
+lf_sfun_s       110010 ----- a:5 b:5 --- 00101110
 
 ####
 # DP Instructions
@@ -218,3 +224,9 @@ lf_sfgt_d       110010 00000 ..... ..... 0.. 00011010  @ab_pair
 lf_sfge_d       110010 00000 ..... ..... 0.. 00011011  @ab_pair
 lf_sflt_d       110010 00000 ..... ..... 0.. 00011100  @ab_pair
 lf_sfle_d       110010 00000 ..... ..... 0.. 00011101  @ab_pair
+lf_sfueq_d      110010 00000 ..... ..... 0.. 00111000  @ab_pair
+lf_sfuge_d      110010 00000 ..... ..... 0.. 00111011  @ab_pair
+lf_sfugt_d      110010 00000 ..... ..... 0.. 00111010  @ab_pair
+lf_sfule_d      110010 00000 ..... ..... 0.. 00111101  @ab_pair
+lf_sfult_d      110010 00000 ..... ..... 0.. 00111100  @ab_pair
+lf_sfun_d       110010 00000 ..... ..... 0.. 00111110  @ab_pair
-- 
2.17.1



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

* [Qemu-devel] [PULL 11/13] target/openrisc: Implement move to/from FPCSR
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (9 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 10/13] target/openrisc: Implement unordered fp comparisons Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 12/13] target/openrisc: Implement l.adrp Richard Henderson
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.h        |  2 ++
 target/openrisc/cpu.c        |  1 +
 target/openrisc/fpu_helper.c | 13 +++++++++++++
 target/openrisc/machine.c    | 11 +++++++++++
 target/openrisc/sys_helper.c | 18 ++++++++++++------
 5 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 71c5959828..0ad02eab79 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -413,6 +413,8 @@ static inline void cpu_set_sr(CPUOpenRISCState *env, uint32_t val)
     env->sr = (val & ~(SR_F | SR_CY | SR_OV)) | SR_FO;
 }
 
+void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val);
+
 #define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
 
 #endif /* OPENRISC_CPU_H */
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index b931605e62..f96a69e278 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -55,6 +55,7 @@ static void openrisc_cpu_reset(CPUState *s)
     cpu->env.sr = SR_FO | SR_SM;
     cpu->env.lock_addr = -1;
     s->exception_index = -1;
+    cpu_set_fpcsr(&cpu->env, 0);
 
 #ifndef CONFIG_USER_ONLY
     cpu->env.picmr = 0x00000000;
diff --git a/target/openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c
index 7bcef9dc53..59e1413279 100644
--- a/target/openrisc/fpu_helper.c
+++ b/target/openrisc/fpu_helper.c
@@ -61,6 +61,19 @@ void HELPER(update_fpcsr)(CPUOpenRISCState *env)
     }
 }
 
+void cpu_set_fpcsr(CPUOpenRISCState *env, uint32_t val)
+{
+    static const int rm_to_sf[] = {
+        float_round_nearest_even,
+        float_round_to_zero,
+        float_round_up,
+        float_round_down
+    };
+
+    env->fpcsr = val & 0x7ff;
+    set_float_rounding_mode(rm_to_sf[extract32(val, 1, 2)], &env->fp_status);
+}
+
 uint64_t HELPER(itofd)(CPUOpenRISCState *env, uint64_t val)
 {
     return int64_to_float64(val, &env->fp_status);
diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c
index 0a96404dc6..b92985d99b 100644
--- a/target/openrisc/machine.c
+++ b/target/openrisc/machine.c
@@ -121,10 +121,21 @@ static const VMStateDescription vmstate_env = {
     }
 };
 
+static int cpu_post_load(void *opaque, int version_id)
+{
+    OpenRISCCPU *cpu = opaque;
+    CPUOpenRISCState *env = &cpu->env;
+
+    /* Update env->fp_status to match env->fpcsr.  */
+    cpu_set_fpcsr(env, env->fpcsr);
+    return 0;
+}
+
 const VMStateDescription vmstate_openrisc_cpu = {
     .name = "cpu",
     .version_id = 1,
     .minimum_version_id = 1,
+    .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_CPU(),
         VMSTATE_STRUCT(env, OpenRISCCPU, 1, vmstate_env, CPUOpenRISCState),
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c
index cf8e637b08..d9fe6c5948 100644
--- a/target/openrisc/sys_helper.c
+++ b/target/openrisc/sys_helper.c
@@ -37,8 +37,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
     CPUState *cs = env_cpu(env);
     target_ulong mr;
     int idx;
+#endif
 
     switch (spr) {
+#ifndef CONFIG_USER_ONLY
     case TO_SPR(0, 11): /* EVBAR */
         env->evbar = rb;
         break;
@@ -179,10 +181,12 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb)
         }
         cpu_openrisc_timer_update(cpu);
         break;
-    default:
+#endif
+
+    case TO_SPR(0, 20): /* FPCSR */
+        cpu_set_fpcsr(env, rb);
         break;
     }
-#endif
 }
 
 target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
@@ -193,8 +197,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
     OpenRISCCPU *cpu = env_archcpu(env);
     CPUState *cs = env_cpu(env);
     int idx;
+#endif
 
     switch (spr) {
+#ifndef CONFIG_USER_ONLY
     case TO_SPR(0, 0): /* VR */
         return env->vr;
 
@@ -303,12 +309,12 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd,
     case TO_SPR(10, 1): /* TTCR */
         cpu_openrisc_count_update(cpu);
         return cpu_openrisc_count_get(cpu);
-
-    default:
-        break;
-    }
 #endif
 
+    case TO_SPR(0, 20): /* FPCSR */
+        return env->fpcsr;
+    }
+
     /* for rd is passed in, if rd unchanged, just keep it back.  */
     return rd;
 }
-- 
2.17.1



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

* [Qemu-devel] [PULL 12/13] target/openrisc: Implement l.adrp
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (10 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 11/13] target/openrisc: Implement move to/from FPCSR Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-04 20:45 ` [Qemu-devel] [PULL 13/13] target/openrisc: Update cpu "any" to v1.3 Richard Henderson
  2019-09-05  9:25 ` [Qemu-devel] [PULL 00/13] target/openrisc updates Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

This was added to the 1.3 spec.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/disas.c      |  1 +
 target/openrisc/translate.c  | 13 +++++++++++++
 target/openrisc/insns.decode |  2 ++
 3 files changed, 16 insertions(+)

diff --git a/target/openrisc/disas.c b/target/openrisc/disas.c
index e51cbb24c6..ce112640b9 100644
--- a/target/openrisc/disas.c
+++ b/target/openrisc/disas.c
@@ -98,6 +98,7 @@ INSN(sw,     "%d(r%d), r%d", a->i, a->a, a->b)
 INSN(sb,     "%d(r%d), r%d", a->i, a->a, a->b)
 INSN(sh,     "%d(r%d), r%d", a->i, a->a, a->b)
 INSN(nop,    "")
+INSN(adrp,   "r%d, %d", a->d, a->i)
 INSN(addi,   "r%d, r%d, %d", a->d, a->a, a->i)
 INSN(addic,  "r%d, r%d, %d", a->d, a->a, a->i)
 INSN(muli,   "r%d, r%d, %d", a->d, a->a, a->i)
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 6e8bc23568..6addbac8d6 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -799,6 +799,19 @@ static bool trans_l_nop(DisasContext *dc, arg_l_nop *a)
     return true;
 }
 
+static bool trans_l_adrp(DisasContext *dc, arg_l_adrp *a)
+{
+    if (!check_v1_3(dc)) {
+        return false;
+    }
+    check_r0_write(dc, a->d);
+
+    tcg_gen_movi_i32(cpu_R(dc, a->d),
+                     (dc->base.pc_next & TARGET_PAGE_MASK) +
+                     ((target_long)a->i << TARGET_PAGE_BITS));
+    return true;
+}
+
 static bool trans_l_addi(DisasContext *dc, arg_rri *a)
 {
     TCGv t0;
diff --git a/target/openrisc/insns.decode b/target/openrisc/insns.decode
index 71e0d740db..0d6f7c29f8 100644
--- a/target/openrisc/insns.decode
+++ b/target/openrisc/insns.decode
@@ -102,6 +102,8 @@ l_maci          010011 ----- a:5 i:s16
 l_movhi         000110 d:5 ----0 k:16
 l_macrc         000110 d:5 ----1 00000000 00000000
 
+l_adrp          000010 d:5 i:s21
+
 ####
 # Arithmetic Instructions
 ####
-- 
2.17.1



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

* [Qemu-devel] [PULL 13/13] target/openrisc: Update cpu "any" to v1.3
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (11 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 12/13] target/openrisc: Implement l.adrp Richard Henderson
@ 2019-09-04 20:45 ` Richard Henderson
  2019-09-05  9:25 ` [Qemu-devel] [PULL 00/13] target/openrisc updates Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Richard Henderson @ 2019-09-04 20:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell

Now that the two updates from v1.3 are implemented,
update the "any" cpu to enable it.

Reviewed-by: Stafford Horne <shorne@gmail.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/openrisc/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index f96a69e278..506aec6bfb 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -129,7 +129,7 @@ static void openrisc_any_initfn(Object *obj)
 
     cpu->env.vr = 0x13000040;   /* Obsolete VER + UVRP for new SPRs */
     cpu->env.vr2 = 0;           /* No version specific id */
-    cpu->env.avr = 0x01010000;  /* Architecture v1.1 */
+    cpu->env.avr = 0x01030000;  /* Architecture v1.3 */
 
     cpu->env.upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP | UPR_PMP;
     cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_OF32S |
-- 
2.17.1



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

* Re: [Qemu-devel] [PULL 00/13] target/openrisc updates
  2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
                   ` (12 preceding siblings ...)
  2019-09-04 20:45 ` [Qemu-devel] [PULL 13/13] target/openrisc: Update cpu "any" to v1.3 Richard Henderson
@ 2019-09-05  9:25 ` Peter Maydell
  13 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2019-09-05  9:25 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers

On Wed, 4 Sep 2019 at 21:45, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The following changes since commit a8b5ad8e1faef0d1bb3e550530328e8ec76fe87c:
>
>   Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2019-09-04 17:22:34 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/rth7680/qemu.git tags/pull-or1k-20190904
>
> for you to fetch changes up to 9e3bab08d3e3f5808cc35a59af1912bfb6fe96fd:
>
>   target/openrisc: Update cpu "any" to v1.3 (2019-09-04 13:01:56 -0700)
>
> ----------------------------------------------------------------
> Updates for arch v1.3.


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.2
for any user-visible changes.

-- PMM


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

end of thread, other threads:[~2019-09-05  9:26 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-04 20:44 [Qemu-devel] [PULL 00/13] target/openrisc updates Richard Henderson
2019-09-04 20:44 ` [Qemu-devel] [PULL 01/13] target/openrisc: Add DisasContext parameter to check_r0_write Richard Henderson
2019-09-04 20:44 ` [Qemu-devel] [PULL 02/13] target/openrisc: Replace cpu register array with a function Richard Henderson
2019-09-04 20:44 ` [Qemu-devel] [PULL 03/13] target/openrisc: Cache R0 in DisasContext Richard Henderson
2019-09-04 20:44 ` [Qemu-devel] [PULL 04/13] target/openrisc: Make VR and PPC read-only Richard Henderson
2019-09-04 20:44 ` [Qemu-devel] [PULL 05/13] target/openrisc: Move VR, UPR, DMMCFGR, IMMCFGR to cpu init Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 06/13] target/openrisc: Add VR2 and AVR special processor registers Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 07/13] target/openrisc: Fix lf.ftoi.s Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 08/13] target/openrisc: Check CPUCFG_OF32S for float insns Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 09/13] target/openrisc: Add support for ORFPX64A32 Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 10/13] target/openrisc: Implement unordered fp comparisons Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 11/13] target/openrisc: Implement move to/from FPCSR Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 12/13] target/openrisc: Implement l.adrp Richard Henderson
2019-09-04 20:45 ` [Qemu-devel] [PULL 13/13] target/openrisc: Update cpu "any" to v1.3 Richard Henderson
2019-09-05  9:25 ` [Qemu-devel] [PULL 00/13] target/openrisc updates Peter Maydell

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.