Commit 0e0a5b49 authored by David Hildenbrand's avatar David Hildenbrand Committed by Cornelia Huck
Browse files

s390x/tcg: Implement VECTOR STORE WITH LENGTH



Very similar to VECTOR LOAD WITH LENGTH, just the opposite direction.
Properly probe write access before modifying memory.

Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Message-Id: <20190307121539.12842-32-david@redhat.com>
Signed-off-by: default avatarCornelia Huck <cohuck@redhat.com>
parent 29b8bcf1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ DEF_HELPER_5(gvec_vpkls_cc16, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vpkls_cc32, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_5(gvec_vpkls_cc64, void, ptr, cptr, cptr, env, i32)
DEF_HELPER_FLAGS_5(gvec_vperm, TCG_CALL_NO_RWG, void, ptr, cptr, cptr, cptr, i32)
DEF_HELPER_FLAGS_4(vstl, TCG_CALL_NO_WG, void, env, cptr, i64, i64)

#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
+2 −0
Original line number Diff line number Diff line
@@ -1043,6 +1043,8 @@
    E(0xe70a, VSTEG,   VRX,   V,   la2, 0, 0, 0, vste, 0, ES_64, IF_VEC)
/* VECTOR STORE MULTIPLE */
    F(0xe73e, VSTM,    VRS_a, V,   la2, 0, 0, 0, vstm, 0, IF_VEC)
/* VECTOR STORE WITH LENGTH */
    F(0xe73f, VSTL,    VRS_b, V,   la2, r3_32u, 0, 0, vstl, 0, IF_VEC)

#ifndef CONFIG_USER_ONLY
/* COMPARE AND SWAP AND PURGE */
+13 −0
Original line number Diff line number Diff line
@@ -882,3 +882,16 @@ static DisasJumpType op_vstm(DisasContext *s, DisasOps *o)
    tcg_temp_free_i64(tmp);
    return DISAS_NEXT;
}

static DisasJumpType op_vstl(DisasContext *s, DisasOps *o)
{
    const int v1_offs = vec_full_reg_offset(get_field(s->fields, v1));
    TCGv_ptr a0 = tcg_temp_new_ptr();

    /* convert highest index into an actual length */
    tcg_gen_addi_i64(o->in2, o->in2, 1);
    tcg_gen_addi_ptr(a0, cpu_env, v1_offs);
    gen_helper_vstl(cpu_env, a0, o->addr1, o->in2);
    tcg_temp_free_ptr(a0);
    return DISAS_NEXT;
}
+24 −0
Original line number Diff line number Diff line
@@ -167,3 +167,27 @@ void HELPER(gvec_vperm)(void *v1, const void *v2, const void *v3,
    }
    *(S390Vector *)v1 = tmp;
}

void HELPER(vstl)(CPUS390XState *env, const void *v1, uint64_t addr,
                  uint64_t bytes)
{
    /* Probe write access before actually modifying memory */
    probe_write_access(env, addr, bytes, GETPC());

    if (likely(bytes >= 16)) {
        cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 0), GETPC());
        addr = wrap_address(env, addr + 8);
        cpu_stq_data_ra(env, addr, s390_vec_read_element64(v1, 1), GETPC());
    } else {
        S390Vector tmp = {};
        int i;

        for (i = 0; i < bytes; i++) {
            uint8_t byte = s390_vec_read_element8(v1, i);

            cpu_stb_data_ra(env, addr, byte, GETPC());
            addr = wrap_address(env, addr + 1);
        }
        *(S390Vector *)v1 = tmp;
    }
}