Note that truncating the store to r1 based on PSW_MASK_64
is incorrect.  We always modify the entire register.

Signed-off-by: Richard Henderson <r...@twiddle.net>
---
 target-s390x/helper.h      |  2 +-
 target-s390x/insn-data.def |  4 ++++
 target-s390x/mem_helper.c  | 13 +++----------
 target-s390x/translate.c   | 20 +++++++++-----------
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index 93931e4..4a041cb 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -140,7 +140,7 @@ DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
 DEF_HELPER_2(sacf, void, env, i64)
 DEF_HELPER_FLAGS_3(ipte, TCG_CALL_CONST, void, env, i64, i64)
 DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_CONST, void, env)
-DEF_HELPER_3(lra, i32, env, i64, i32)
+DEF_HELPER_2(lra, i64, env, i64)
 DEF_HELPER_3(stura, void, env, i64, i32)
 DEF_HELPER_3(cksm, void, env, i32, i32)
 
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index 301e509..a078cc5 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -461,6 +461,10 @@
     C(0x8300, DIAG,    RX_a,  Z,   0, 0, 0, 0, diag, 0)
 /* LOAD PSW */
     C(0x8200, LPSW,    S,     Z,   0, a2, 0, 0, lpsw, 0)
+/* LOAD REAL ADDRESS */
+    C(0xb100, LRA,     RX_a,  Z,   0, a2, r1, 0, lra, 0)
+    C(0xe313, LRAY,    RXY_a, LD,  0, a2, r1, 0, lra, 0)
+    C(0xe303, LRAG,    RXY_a, Z,   0, a2, r1, 0, lra, 0)
 /* MOVE TO PRIMARY */
     C(0xda00, MVCP,    SS_d,  Z,   la1, a2, 0, 0, mvcp, 0)
 /* MOVE TO SECONDARY */
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index b868346..961f748 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -1133,7 +1133,7 @@ void HELPER(stura)(CPUS390XState *env, uint64_t addr, 
uint32_t v1)
 }
 
 /* load real address */
-uint32_t HELPER(lra)(CPUS390XState *env, uint64_t addr, uint32_t r1)
+uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
 {
     uint32_t cc = 0;
     int old_exc = env->exception_index;
@@ -1157,14 +1157,7 @@ uint32_t HELPER(lra)(CPUS390XState *env, uint64_t addr, 
uint32_t r1)
     }
     env->exception_index = old_exc;
 
-    if (!(env->psw.mask & PSW_MASK_64)) {
-        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
-            (ret & 0xffffffffULL);
-    } else {
-        env->regs[r1] = ret;
-    }
-
-    return cc;
+    env->cc_op = cc;
+    return ret;
 }
-
 #endif
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index c8ab897..1829b25 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -2015,17 +2015,6 @@ static void disas_s390_insn(DisasContext *s)
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0xb1: /* LRA    R1,D2(X2, B2)     [RX] */
-        check_privileged(s);
-        insn = ld_code4(s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp32_1 = tcg_const_i32(r1);
-        potential_page_fault(s);
-        gen_helper_lra(cc_op, cpu_env, tmp, tmp32_1);
-        set_cc_static(s);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i32(tmp32_1);
-        break;
 #endif
     case 0xb2:
         insn = ld_code4(s->pc);
@@ -2887,6 +2876,15 @@ static ExitStatus op_ld64(DisasContext *s, DisasOps *o)
 }
 
 #ifndef CONFIG_USER_ONLY
+static ExitStatus op_lra(DisasContext *s, DisasOps *o)
+{
+    check_privileged(s);
+    potential_page_fault(s);
+    gen_helper_lra(o->out, cpu_env, o->in2);
+    set_cc_static(s);
+    return NO_EXIT;
+}
+
 static ExitStatus op_lpsw(DisasContext *s, DisasOps *o)
 {
     TCGv_i64 t1, t2;
-- 
1.7.11.4


Reply via email to