aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/vec_helper.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2019-03-07 13:15:38 +0100
committerCornelia Huck <cohuck@redhat.com>2019-03-11 09:31:01 +0100
commit0e0a5b49ad58aa98eaa94b7cac60b5a799456150 (patch)
treed84217539dca0b393d9307f7f5d3c7897486941e /target/s390x/vec_helper.c
parent29b8bcf140d7f31ad38b811278074fd202ed1275 (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.c24
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;
+ }
+}