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

target/s390x: add EX support for TRT and TRTR



Improves "b213c9f5: target/s390x: Implement TRTR" by introducing the
intermediate functions, which are compatible with dx_helper type.

Signed-off-by: default avatarPavel Zbitskiy <pavel.zbitskiy@gmail.com>
Message-Id: <20180821025104.19604-6-pavel.zbitskiy@gmail.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parent 478d360c
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -1299,12 +1299,26 @@ static inline uint32_t do_helper_trt(CPUS390XState *env, int len,
    return 0;
}

static uint32_t do_helper_trt_fwd(CPUS390XState *env, uint32_t len,
                                  uint64_t array, uint64_t trans,
                                  uintptr_t ra)
{
    return do_helper_trt(env, len, array, trans, 1, ra);
}

uint32_t HELPER(trt)(CPUS390XState *env, uint32_t len, uint64_t array,
                     uint64_t trans)
{
    return do_helper_trt(env, len, array, trans, 1, GETPC());
}

static uint32_t do_helper_trt_bkwd(CPUS390XState *env, uint32_t len,
                                   uint64_t array, uint64_t trans,
                                   uintptr_t ra)
{
    return do_helper_trt(env, len, array, trans, -1, ra);
}

uint32_t HELPER(trtr)(CPUS390XState *env, uint32_t len, uint64_t array,
                      uint64_t trans)
{
@@ -2193,12 +2207,14 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, uint64_t r1, uint64_t addr)
        typedef uint32_t (*dx_helper)(CPUS390XState *, uint32_t, uint64_t,
                                      uint64_t, uintptr_t);
        static const dx_helper dx[16] = {
            [0x0] = do_helper_trt_bkwd,
            [0x2] = do_helper_mvc,
            [0x4] = do_helper_nc,
            [0x5] = do_helper_clc,
            [0x6] = do_helper_oc,
            [0x7] = do_helper_xc,
            [0xc] = do_helper_tr,
            [0xd] = do_helper_trt_fwd,
        };
        dx_helper helper = dx[opc & 0xf];

+2 −0
Original line number Diff line number Diff line
@@ -3,3 +3,5 @@ CFLAGS+=-march=zEC12 -m64
TESTS+=hello-s390x
TESTS+=csst
TESTS+=ipm
TESTS+=exrl-trt
TESTS+=exrl-trtr
+48 −0
Original line number Diff line number Diff line
#include <stdint.h>
#include <unistd.h>

int main(void)
{
    char op1[] = "hello";
    char op2[256];
    uint64_t r1 = 0xffffffffffffffffull;
    uint64_t r2 = 0xffffffffffffffffull;
    uint64_t cc;
    int i;

    for (i = 0; i < 256; i++) {
        if (i == 0) {
            op2[i] = 0xaa;
        } else {
            op2[i] = 0;
        }
    }
    asm volatile(
        "    j 2f\n"
        "1:  trt 0(1,%[op1]),0(%[op2])\n"
        "2:  exrl %[op1_len],1b\n"
        "    lgr %[r1],%%r1\n"
        "    lgr %[r2],%%r2\n"
        "    ipm %[cc]\n"
        : [r1] "+r" (r1),
          [r2] "+r" (r2),
          [cc] "=r" (cc)
        : [op1] "r" (&op1),
          [op1_len] "r" (5),
          [op2] "r" (&op2)
        : "r1", "r2", "cc");
    cc = (cc >> 28) & 3;
    if (cc != 2) {
        write(1, "bad cc\n", 7);
        return 1;
    }
    if ((char *)r1 != &op1[5]) {
        write(1, "bad r1\n", 7);
        return 1;
    }
    if (r2 != 0xffffffffffffffaaull) {
        write(1, "bad r2\n", 7);
        return 1;
    }
    return 0;
}
+48 −0
Original line number Diff line number Diff line
#include <stdint.h>
#include <unistd.h>

int main(void)
{
    char op1[] = {0, 1, 2, 3};
    char op2[256];
    uint64_t r1 = 0xffffffffffffffffull;
    uint64_t r2 = 0xffffffffffffffffull;
    uint64_t cc;
    int i;

    for (i = 0; i < 256; i++) {
        if (i == 1) {
            op2[i] = 0xbb;
        } else {
            op2[i] = 0;
        }
    }
    asm volatile(
        "    j 2f\n"
        "1:  trtr 3(1,%[op1]),0(%[op2])\n"
        "2:  exrl %[op1_len],1b\n"
        "    lgr %[r1],%%r1\n"
        "    lgr %[r2],%%r2\n"
        "    ipm %[cc]\n"
        : [r1] "+r" (r1),
          [r2] "+r" (r2),
          [cc] "=r" (cc)
        : [op1] "r" (&op1),
          [op1_len] "r" (3),
          [op2] "r" (&op2)
        : "r1", "r2", "cc");
    cc = (cc >> 28) & 3;
    if (cc != 1) {
        write(1, "bad cc\n", 7);
        return 1;
    }
    if ((char *)r1 != &op1[1]) {
        write(1, "bad r1\n", 7);
        return 1;
    }
    if (r2 != 0xffffffffffffffbbull) {
        write(1, "bad r2\n", 7);
        return 1;
    }
    return 0;
}