aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/vec_int_helper.c
diff options
context:
space:
mode:
authorDavid Hildenbrand <david@redhat.com>2019-04-11 11:56:49 +0200
committerDavid Hildenbrand <david@redhat.com>2019-05-17 10:54:13 +0200
commit1b430aec4157b62b9add981b1849c8c23ca78f5a (patch)
tree7c9c386b9af7d4f48be22341d3469019bbfb59e2 /target/s390x/vec_int_helper.c
parent86f521b601b2a6c51fc637a60ba9d92b1e78e0db (diff)
s390x/tcg: Implement VECTOR MULTIPLY AND ADD *
Quite some variants to handle. At least handle some 32-bit element variants via gvec expansion (we could also handle 16/32-bit variants for ODD and EVEN easily via gvec expansion, but let's keep it simple for now). Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Hildenbrand <david@redhat.com>
Diffstat (limited to 'target/s390x/vec_int_helper.c')
-rw-r--r--target/s390x/vec_int_helper.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/target/s390x/vec_int_helper.c b/target/s390x/vec_int_helper.c
index 20a1034dd8..171c20fc54 100644
--- a/target/s390x/vec_int_helper.c
+++ b/target/s390x/vec_int_helper.c
@@ -241,3 +241,126 @@ void HELPER(gvec_vgfma64)(void *v1, const void *v2, const void *v3,
s390_vec_xor(&tmp1, &tmp1, &tmp2);
s390_vec_xor(v1, &tmp1, v4);
}
+
+#define DEF_VMAL(BITS) \
+void HELPER(gvec_vmal##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, uint32_t desc) \
+{ \
+ int i; \
+ \
+ for (i = 0; i < (128 / BITS); i++) { \
+ const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
+ const uint##BITS##_t b = s390_vec_read_element##BITS(v3, i); \
+ const uint##BITS##_t c = s390_vec_read_element##BITS(v4, i); \
+ \
+ s390_vec_write_element##BITS(v1, i, a * b + c); \
+ } \
+}
+DEF_VMAL(8)
+DEF_VMAL(16)
+
+#define DEF_VMAH(BITS) \
+void HELPER(gvec_vmah##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, uint32_t desc) \
+{ \
+ int i; \
+ \
+ for (i = 0; i < (128 / BITS); i++) { \
+ const int32_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, i); \
+ const int32_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, i); \
+ const int32_t c = (int##BITS##_t)s390_vec_read_element##BITS(v4, i); \
+ \
+ s390_vec_write_element##BITS(v1, i, (a * b + c) >> BITS); \
+ } \
+}
+DEF_VMAH(8)
+DEF_VMAH(16)
+
+#define DEF_VMALH(BITS) \
+void HELPER(gvec_vmalh##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, uint32_t desc) \
+{ \
+ int i; \
+ \
+ for (i = 0; i < (128 / BITS); i++) { \
+ const uint##BITS##_t a = s390_vec_read_element##BITS(v2, i); \
+ const uint##BITS##_t b = s390_vec_read_element##BITS(v3, i); \
+ const uint##BITS##_t c = s390_vec_read_element##BITS(v4, i); \
+ \
+ s390_vec_write_element##BITS(v1, i, (a * b + c) >> BITS); \
+ } \
+}
+DEF_VMALH(8)
+DEF_VMALH(16)
+
+#define DEF_VMAE(BITS, TBITS) \
+void HELPER(gvec_vmae##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, uint32_t desc) \
+{ \
+ int i, j; \
+ \
+ for (i = 0, j = 0; i < (128 / TBITS); i++, j += 2) { \
+ int##TBITS##_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, j); \
+ int##TBITS##_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, j); \
+ int##TBITS##_t c = (int##BITS##_t)s390_vec_read_element##BITS(v4, j); \
+ \
+ s390_vec_write_element##TBITS(v1, i, a * b + c); \
+ } \
+}
+DEF_VMAE(8, 16)
+DEF_VMAE(16, 32)
+DEF_VMAE(32, 64)
+
+#define DEF_VMALE(BITS, TBITS) \
+void HELPER(gvec_vmale##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, uint32_t desc) \
+{ \
+ int i, j; \
+ \
+ for (i = 0, j = 0; i < (128 / TBITS); i++, j += 2) { \
+ uint##TBITS##_t a = s390_vec_read_element##BITS(v2, j); \
+ uint##TBITS##_t b = s390_vec_read_element##BITS(v3, j); \
+ uint##TBITS##_t c = s390_vec_read_element##BITS(v4, j); \
+ \
+ s390_vec_write_element##TBITS(v1, i, a * b + c); \
+ } \
+}
+DEF_VMALE(8, 16)
+DEF_VMALE(16, 32)
+DEF_VMALE(32, 64)
+
+#define DEF_VMAO(BITS, TBITS) \
+void HELPER(gvec_vmao##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, uint32_t desc) \
+{ \
+ int i, j; \
+ \
+ for (i = 0, j = 1; i < (128 / TBITS); i++, j += 2) { \
+ int##TBITS##_t a = (int##BITS##_t)s390_vec_read_element##BITS(v2, j); \
+ int##TBITS##_t b = (int##BITS##_t)s390_vec_read_element##BITS(v3, j); \
+ int##TBITS##_t c = (int##BITS##_t)s390_vec_read_element##BITS(v4, j); \
+ \
+ s390_vec_write_element##TBITS(v1, i, a * b + c); \
+ } \
+}
+DEF_VMAO(8, 16)
+DEF_VMAO(16, 32)
+DEF_VMAO(32, 64)
+
+#define DEF_VMALO(BITS, TBITS) \
+void HELPER(gvec_vmalo##BITS)(void *v1, const void *v2, const void *v3, \
+ const void *v4, uint32_t desc) \
+{ \
+ int i, j; \
+ \
+ for (i = 0, j = 1; i < (128 / TBITS); i++, j += 2) { \
+ uint##TBITS##_t a = s390_vec_read_element##BITS(v2, j); \
+ uint##TBITS##_t b = s390_vec_read_element##BITS(v3, j); \
+ uint##TBITS##_t c = s390_vec_read_element##BITS(v4, j); \
+ \
+ s390_vec_write_element##TBITS(v1, i, a * b + c); \
+ } \
+}
+DEF_VMALO(8, 16)
+DEF_VMALO(16, 32)
+DEF_VMALO(32, 64)