Commit dc95b31d authored by Pavel Zbitskiy's avatar Pavel Zbitskiy Committed by Cornelia Huck
Browse files

target/s390x: fix CSST decoding and runtime alignment check



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: default avatarPavel Zbitskiy <pavel.zbitskiy@gmail.com>
Message-Id: <20180821025104.19604-4-pavel.zbitskiy@gmail.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parent e1db291b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
    }

+2 −2
Original line number Diff line number Diff line
@@ -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);

+1 −0
Original line number Diff line number Diff line
VPATH+=$(SRC_PATH)/tests/tcg/s390x
CFLAGS+=-march=zEC12 -m64
TESTS+=hello-s390x
TESTS+=csst

tests/tcg/s390x/csst.c

0 → 100644
+43 −0
Original line number Diff line number Diff line
#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;
}