aboutsummaryrefslogtreecommitdiff
path: root/target/s390x/vec_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/s390x/vec_helper.c')
-rw-r--r--target/s390x/vec_helper.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/target/s390x/vec_helper.c b/target/s390x/vec_helper.c
index 5b2333a..7f68020 100644
--- a/target/s390x/vec_helper.c
+++ b/target/s390x/vec_helper.c
@@ -15,6 +15,7 @@
#include "internal.h"
#include "vec.h"
#include "tcg/tcg.h"
+#include "tcg/tcg-gvec-desc.h"
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
#include "exec/exec-all.h"
@@ -42,3 +43,107 @@ void HELPER(vll)(CPUS390XState *env, void *v1, uint64_t addr, uint64_t bytes)
*(S390Vector *)v1 = tmp;
}
}
+
+#define DEF_VPK_HFN(BITS, TBITS) \
+typedef uint##TBITS##_t (*vpk##BITS##_fn)(uint##BITS##_t, int *); \
+static int vpk##BITS##_hfn(S390Vector *v1, const S390Vector *v2, \
+ const S390Vector *v3, vpk##BITS##_fn fn) \
+{ \
+ int i, saturated = 0; \
+ S390Vector tmp; \
+ \
+ for (i = 0; i < (128 / TBITS); i++) { \
+ uint##BITS##_t src; \
+ \
+ if (i < (128 / BITS)) { \
+ src = s390_vec_read_element##BITS(v2, i); \
+ } else { \
+ src = s390_vec_read_element##BITS(v3, i - (128 / BITS)); \
+ } \
+ s390_vec_write_element##TBITS(&tmp, i, fn(src, &saturated)); \
+ } \
+ *v1 = tmp; \
+ return saturated; \
+}
+DEF_VPK_HFN(64, 32)
+DEF_VPK_HFN(32, 16)
+DEF_VPK_HFN(16, 8)
+
+#define DEF_VPK(BITS, TBITS) \
+static uint##TBITS##_t vpk##BITS##e(uint##BITS##_t src, int *saturated) \
+{ \
+ return src; \
+} \
+void HELPER(gvec_vpk##BITS)(void *v1, const void *v2, const void *v3, \
+ uint32_t desc) \
+{ \
+ vpk##BITS##_hfn(v1, v2, v3, vpk##BITS##e); \
+}
+DEF_VPK(64, 32)
+DEF_VPK(32, 16)
+DEF_VPK(16, 8)
+
+#define DEF_VPKS(BITS, TBITS) \
+static uint##TBITS##_t vpks##BITS##e(uint##BITS##_t src, int *saturated) \
+{ \
+ if ((int##BITS##_t)src > INT##TBITS##_MAX) { \
+ (*saturated)++; \
+ return INT##TBITS##_MAX; \
+ } else if ((int##BITS##_t)src < INT##TBITS##_MIN) { \
+ (*saturated)++; \
+ return INT##TBITS##_MIN; \
+ } \
+ return src; \
+} \
+void HELPER(gvec_vpks##BITS)(void *v1, const void *v2, const void *v3, \
+ uint32_t desc) \
+{ \
+ vpk##BITS##_hfn(v1, v2, v3, vpks##BITS##e); \
+} \
+void HELPER(gvec_vpks_cc##BITS)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ int saturated = vpk##BITS##_hfn(v1, v2, v3, vpks##BITS##e); \
+ \
+ if (saturated == (128 / TBITS)) { \
+ env->cc_op = 3; \
+ } else if (saturated) { \
+ env->cc_op = 1; \
+ } else { \
+ env->cc_op = 0; \
+ } \
+}
+DEF_VPKS(64, 32)
+DEF_VPKS(32, 16)
+DEF_VPKS(16, 8)
+
+#define DEF_VPKLS(BITS, TBITS) \
+static uint##TBITS##_t vpkls##BITS##e(uint##BITS##_t src, int *saturated) \
+{ \
+ if (src > UINT##TBITS##_MAX) { \
+ (*saturated)++; \
+ return UINT##TBITS##_MAX; \
+ } \
+ return src; \
+} \
+void HELPER(gvec_vpkls##BITS)(void *v1, const void *v2, const void *v3, \
+ uint32_t desc) \
+{ \
+ vpk##BITS##_hfn(v1, v2, v3, vpkls##BITS##e); \
+} \
+void HELPER(gvec_vpkls_cc##BITS)(void *v1, const void *v2, const void *v3, \
+ CPUS390XState *env, uint32_t desc) \
+{ \
+ int saturated = vpk##BITS##_hfn(v1, v2, v3, vpkls##BITS##e); \
+ \
+ if (saturated == (128 / TBITS)) { \
+ env->cc_op = 3; \
+ } else if (saturated) { \
+ env->cc_op = 1; \
+ } else { \
+ env->cc_op = 0; \
+ } \
+}
+DEF_VPKLS(64, 32)
+DEF_VPKLS(32, 16)
+DEF_VPKLS(16, 8)