diff options
author | David Hildenbrand <david@redhat.com> | 2019-03-07 13:15:38 +0100 |
---|---|---|
committer | Cornelia Huck <cohuck@redhat.com> | 2019-03-11 09:31:01 +0100 |
commit | 0e0a5b49ad58aa98eaa94b7cac60b5a799456150 (patch) | |
tree | d84217539dca0b393d9307f7f5d3c7897486941e /target/s390x/vec_helper.c | |
parent | 29b8bcf140d7f31ad38b811278074fd202ed1275 (diff) |
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: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20190307121539.12842-32-david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
Diffstat (limited to 'target/s390x/vec_helper.c')
-rw-r--r-- | target/s390x/vec_helper.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/target/s390x/vec_helper.c b/target/s390x/vec_helper.c index 021695b38c..bb4c9304f0 100644 --- a/target/s390x/vec_helper.c +++ b/target/s390x/vec_helper.c @@ -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; + } +} |