Patchwork [057/147] target-s390: Convert STNSM, STOSM

login
register
mail settings
Submitter Richard Henderson
Date Sept. 27, 2012, 11:49 p.m.
Message ID <1348789751-25103-1-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/187571/
State New
Headers show

Comments

Richard Henderson - Sept. 27, 2012, 11:49 p.m.
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-s390x/insn-data.def |  4 ++++
 target-s390x/translate.c   | 43 +++++++++++++++++++++++++------------------
 2 files changed, 29 insertions(+), 18 deletions(-)

Patch

diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index 2383a36..9859b3b 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -444,4 +444,8 @@ 
     C(0x010e, SAM64,   E,     Z,   0, 0, 0, 0, 0, 0)
 /* SET SYSTEM MASK */
     C(0x8000, SSM,     S,     Z,   0, m2_8u, 0, 0, ssm, 0)
+/* STORE THEN AND SYSTEM MASK */
+    C(0xac00, STNSM,   SI,    Z,   la1, 0, 0, 0, stnosm, 0)
+/* STORE THEN OR SYSTEM MASK */
+    C(0xad00, STOSM,   SI,    Z,   la1, 0, 0, 0, stnosm, 0)
 #endif /* CONFIG_USER_ONLY */
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 331580f..3cca318 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -2226,7 +2226,7 @@  static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
     TCGv_i32 tmp32_1, tmp32_2;
     unsigned char opc;
     uint64_t insn;
-    int op, r1, r2, r3, d1, d2, x2, b1, b2, i2, r1b;
+    int op, r1, r2, r3, d1, d2, x2, b1, b2, r1b;
     TCGv_i32 vl;
 
     opc = cpu_ldub_code(env, s->pc);
@@ -2284,23 +2284,6 @@  static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         tcg_temp_free_i32(tmp32_2);
         break;
 #ifndef CONFIG_USER_ONLY
-    case 0xac: /* STNSM   D1(B1),I2     [SI] */
-    case 0xad: /* STOSM   D1(B1),I2     [SI] */
-        check_privileged(s);
-        insn = ld_code4(env, s->pc);
-        tmp = decode_si(s, insn, &i2, &b1, &d1);
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_shri_i64(tmp2, psw_mask, 56);
-        tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
-        if (opc == 0xac) {
-            tcg_gen_andi_i64(psw_mask, psw_mask,
-                    ((uint64_t)i2 << 56) | 0x00ffffffffffffffULL);
-        } else {
-            tcg_gen_ori_i64(psw_mask, psw_mask, (uint64_t)i2 << 56);
-        }
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0xae: /* SIGP   R1,R3,D2(B2)     [RS] */
         check_privileged(s);
         insn = ld_code4(env, s->pc);
@@ -3485,6 +3468,30 @@  static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
     tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
     return NO_EXIT;
 }
+
+static ExitStatus op_stnosm(DisasContext *s, DisasOps *o)
+{
+    uint64_t i2 = get_field(s->fields, i2);
+    TCGv_i64 t;
+
+    check_privileged(s);
+
+    /* It is important to do what the instruction name says: STORE THEN.
+       If we let the output hook perform the store then if we fault and
+       restart, we'll have the wrong SYSTEM MASK in place.  */
+    t = tcg_temp_new_i64();
+    tcg_gen_shri_i64(t, psw_mask, 56);
+    tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s));
+    tcg_temp_free_i64(t);
+
+    if (s->fields->op == 0xac) {
+        tcg_gen_andi_i64(psw_mask, psw_mask,
+                         (i2 << 56) | 0x00ffffffffffffffull);
+    } else {
+        tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
+    }
+    return NO_EXIT;
+}
 #endif
 
 static ExitStatus op_st8(DisasContext *s, DisasOps *o)