aboutsummaryrefslogtreecommitdiff
path: root/target/arm/sve_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2018-05-18 17:48:09 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-05-18 17:48:09 +0100
commit24e82e68341e73ec0f65534c78c13fd03395b188 (patch)
tree7a1ad38a989015524ec3d53dcadf08aeb45c015f /target/arm/sve_helper.c
parenta1f233f25fd502f9a5b40c14df1b4dbdda463487 (diff)
target/arm: Implement SVE Element Count Group
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20180516223007.10256-23-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/sve_helper.c')
-rw-r--r--target/arm/sve_helper.c136
1 files changed, 136 insertions, 0 deletions
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 85a0639e3a..979aa5c409 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -1235,3 +1235,139 @@ void HELPER(sve_ftssel_d)(void *vd, void *vn, void *vm, uint32_t desc)
d[i] = nn ^ (mm & 2) << 62;
}
}
+
+/*
+ * Signed saturating addition with scalar operand.
+ */
+
+void HELPER(sve_sqaddi_b)(void *d, void *a, int32_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(int8_t)) {
+ int r = *(int8_t *)(a + i) + b;
+ if (r > INT8_MAX) {
+ r = INT8_MAX;
+ } else if (r < INT8_MIN) {
+ r = INT8_MIN;
+ }
+ *(int8_t *)(d + i) = r;
+ }
+}
+
+void HELPER(sve_sqaddi_h)(void *d, void *a, int32_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(int16_t)) {
+ int r = *(int16_t *)(a + i) + b;
+ if (r > INT16_MAX) {
+ r = INT16_MAX;
+ } else if (r < INT16_MIN) {
+ r = INT16_MIN;
+ }
+ *(int16_t *)(d + i) = r;
+ }
+}
+
+void HELPER(sve_sqaddi_s)(void *d, void *a, int64_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(int32_t)) {
+ int64_t r = *(int32_t *)(a + i) + b;
+ if (r > INT32_MAX) {
+ r = INT32_MAX;
+ } else if (r < INT32_MIN) {
+ r = INT32_MIN;
+ }
+ *(int32_t *)(d + i) = r;
+ }
+}
+
+void HELPER(sve_sqaddi_d)(void *d, void *a, int64_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(int64_t)) {
+ int64_t ai = *(int64_t *)(a + i);
+ int64_t r = ai + b;
+ if (((r ^ ai) & ~(ai ^ b)) < 0) {
+ /* Signed overflow. */
+ r = (r < 0 ? INT64_MAX : INT64_MIN);
+ }
+ *(int64_t *)(d + i) = r;
+ }
+}
+
+/*
+ * Unsigned saturating addition with scalar operand.
+ */
+
+void HELPER(sve_uqaddi_b)(void *d, void *a, int32_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
+ int r = *(uint8_t *)(a + i) + b;
+ if (r > UINT8_MAX) {
+ r = UINT8_MAX;
+ } else if (r < 0) {
+ r = 0;
+ }
+ *(uint8_t *)(d + i) = r;
+ }
+}
+
+void HELPER(sve_uqaddi_h)(void *d, void *a, int32_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
+ int r = *(uint16_t *)(a + i) + b;
+ if (r > UINT16_MAX) {
+ r = UINT16_MAX;
+ } else if (r < 0) {
+ r = 0;
+ }
+ *(uint16_t *)(d + i) = r;
+ }
+}
+
+void HELPER(sve_uqaddi_s)(void *d, void *a, int64_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
+ int64_t r = *(uint32_t *)(a + i) + b;
+ if (r > UINT32_MAX) {
+ r = UINT32_MAX;
+ } else if (r < 0) {
+ r = 0;
+ }
+ *(uint32_t *)(d + i) = r;
+ }
+}
+
+void HELPER(sve_uqaddi_d)(void *d, void *a, uint64_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
+ uint64_t r = *(uint64_t *)(a + i) + b;
+ if (r < b) {
+ r = UINT64_MAX;
+ }
+ *(uint64_t *)(d + i) = r;
+ }
+}
+
+void HELPER(sve_uqsubi_d)(void *d, void *a, uint64_t b, uint32_t desc)
+{
+ intptr_t i, oprsz = simd_oprsz(desc);
+
+ for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
+ uint64_t ai = *(uint64_t *)(a + i);
+ *(uint64_t *)(d + i) = (ai < b ? 0 : ai - b);
+ }
+}