target/s390x: fix CSST decoding and runtime alignment check
authorPavel Zbitskiy <pavel.zbitskiy@gmail.com>
Tue, 21 Aug 2018 02:51:00 +0000 (22:51 -0400)
committerCornelia Huck <cohuck@redhat.com>
Tue, 28 Aug 2018 15:37:01 +0000 (17:37 +0200)
CSST is defined as:

    C(0xc802, CSST,    SSF,   CASS, la1, a2, 0, 0, csst, 0)

It means that the first parameter is handled by in1_la1().
in1_la1() fills addr1 field, and not in1.

Furthermore, when extract32() is used for the alignment check, the
third parameter should specify the number of trailing bits that must
be 0. For FC these numbers are:

    FC=0 (word, 4 bytes):        2
    FC=1 (double word, 8 bytes): 3
    FC=2 (quad word, 16 bytes):  4

For SC these numbers correspond to the size:

    SC=0: 0
    SC=1: 1
    SC=2: 2
    SC=3: 3
    SC=4: 4

Signed-off-by: Pavel Zbitskiy <pavel.zbitskiy@gmail.com>
Message-Id: <20180821025104.19604-4-pavel.zbitskiy@gmail.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
target/s390x/mem_helper.c
target/s390x/translate.c
tests/tcg/s390x/Makefile.target
tests/tcg/s390x/csst.c [new file with mode: 0644]

index e21a47fb4d85aa582c31793e30e8e8fee52fa5d6..c94dbf3fcbd48bb264dd6485d4a56721b0b33fca 100644 (file)
@@ -1442,7 +1442,7 @@ static uint32_t do_csst(CPUS390XState *env, uint32_t r3, uint64_t a1,
     }
 
     /* Sanity check the alignments.  */
-    if (extract32(a1, 0, 4 << fc) || extract32(a2, 0, 1 << sc)) {
+    if (extract32(a1, 0, fc + 2) || extract32(a2, 0, sc)) {
         goto spec_exception;
     }
 
index 9caae5af843dd3d56c2f4ea6cc473feb71b8af17..4f62a38c971215a285a6309b0a044077b45a9877 100644 (file)
@@ -2058,9 +2058,9 @@ static DisasJumpType op_csst(DisasContext *s, DisasOps *o)
     TCGv_i32 t_r3 = tcg_const_i32(r3);
 
     if (tb_cflags(s->base.tb) & CF_PARALLEL) {
-        gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->in1, o->in2);
+        gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->addr1, o->in2);
     } else {
-        gen_helper_csst(cc_op, cpu_env, t_r3, o->in1, o->in2);
+        gen_helper_csst(cc_op, cpu_env, t_r3, o->addr1, o->in2);
     }
     tcg_temp_free_i32(t_r3);
 
index 9f4076901f205ddff32f5dc458670b0e9fbe29c5..f62f950d8e6ffdb2e683fe7d7330df48a4f09588 100644 (file)
@@ -1,3 +1,4 @@
 VPATH+=$(SRC_PATH)/tests/tcg/s390x
 CFLAGS+=-march=zEC12 -m64
 TESTS+=hello-s390x
+TESTS+=csst
diff --git a/tests/tcg/s390x/csst.c b/tests/tcg/s390x/csst.c
new file mode 100644 (file)
index 0000000..1dae907
--- /dev/null
@@ -0,0 +1,43 @@
+#include <stdint.h>
+#include <unistd.h>
+
+int main(void)
+{
+    uint64_t parmlist[] = {
+        0xfedcba9876543210ull,
+        0,
+        0x7777777777777777ull,
+        0,
+    };
+    uint64_t op1 = 0x0123456789abcdefull;
+    uint64_t op2 = 0;
+    uint64_t op3 = op1;
+    uint64_t cc;
+
+    asm volatile(
+        "    lghi %%r0,%[flags]\n"
+        "    la %%r1,%[parmlist]\n"
+        "    csst %[op1],%[op2],%[op3]\n"
+        "    ipm %[cc]\n"
+        : [op1] "+m" (op1),
+          [op2] "+m" (op2),
+          [op3] "+r" (op3),
+          [cc] "=r" (cc)
+        : [flags] "K" (0x0301),
+          [parmlist] "m" (parmlist)
+        : "r0", "r1", "cc", "memory");
+    cc = (cc >> 28) & 3;
+    if (cc) {
+        write(1, "bad cc\n", 7);
+        return 1;
+    }
+    if (op1 != parmlist[0]) {
+        write(1, "bad op1\n", 8);
+        return 1;
+    }
+    if (op2 != parmlist[2]) {
+        write(1, "bad op2\n", 8);
+        return 1;
+    }
+    return 0;
+}