Commit 483a4bcc authored by Ryo's avatar Ryo Committed by Michael R. Crusoe

Fix qdmlsl instructions

The qdmlsl instructions were implemented without any saturation.
This has been fixed by utilising existing saturating instructions which
are implemented correctly.

Unit tests have also been updated to test for saturation.

Change-Id: Ia9e5a7bd850bc178920c19e390c17db5a3bfbc4f
parent f275fffd
......@@ -27,13 +27,9 @@
#if !defined(SIMDE_ARM_NEON_QDMLSL_H)
#define SIMDE_ARM_NEON_QDMLSL_H
#include "sub.h"
#include "mul.h"
#include "mul_n.h"
#include "movl.h"
#include "qadd.h"
#include "qsub.h"
#include "types.h"
#include "qsub.h"
#include "qdmull.h"
HEDLEY_DIAGNOSTIC_PUSH
SIMDE_DISABLE_UNWANTED_DIAGNOSTICS
......@@ -45,7 +41,7 @@ simde_vqdmlslh_s16(int32_t a, int16_t b, int16_t c) {
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
return vqdmlslh_s16(a, b, c);
#else
return a - HEDLEY_STATIC_CAST(int32_t, b) * HEDLEY_STATIC_CAST(int32_t, c) * 2;
return simde_vqsubs_s32(a, simde_vqdmullh_s16(b, c));
#endif
}
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
......@@ -59,7 +55,7 @@ simde_vqdmlsls_s32(int64_t a, int32_t b, int32_t c) {
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
return vqdmlsls_s32(a, b, c);
#else
return a - HEDLEY_STATIC_CAST(int64_t, b) * HEDLEY_STATIC_CAST(int64_t, c) * 2;
return simde_vqsubd_s64(a, simde_vqdmulls_s32(b, c));
#endif
}
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
......@@ -73,8 +69,7 @@ simde_vqdmlsl_s16(simde_int32x4_t a, simde_int16x4_t b, simde_int16x4_t c) {
#if defined(SIMDE_ARM_NEON_A32V7_NATIVE)
return vqdmlsl_s16(a, b, c);
#else
simde_int32x4_t temp = simde_vmulq_s32(simde_vmovl_s16(b), simde_vmovl_s16(c));
return simde_vqsubq_s32(a, simde_vqaddq_s32(temp, temp));
return simde_vqsubq_s32(a, simde_vqdmull_s16(b, c));
#endif
}
#if defined(SIMDE_ARM_NEON_A32V7_ENABLE_NATIVE_ALIASES)
......@@ -88,10 +83,7 @@ simde_vqdmlsl_s32(simde_int64x2_t a, simde_int32x2_t b, simde_int32x2_t c) {
#if defined(SIMDE_ARM_NEON_A32V7_NATIVE)
return vqdmlsl_s32(a, b, c);
#else
simde_int64x2_t r = simde_x_vmulq_s64(
simde_vmovl_s32(b),
simde_vmovl_s32(c));
return simde_vqsubq_s64(a, simde_vqaddq_s64(r, r));
return simde_vqsubq_s64(a, simde_vqdmull_s32(b, c));
#endif
}
#if defined(SIMDE_ARM_NEON_A32V7_ENABLE_NATIVE_ALIASES)
......
......@@ -28,10 +28,9 @@
#define SIMDE_ARM_NEON_QDMLSL_HIGH_H
#include "movl_high.h"
#include "sub.h"
#include "mul.h"
#include "mul_n.h"
#include "types.h"
#include "qdmull_high.h"
#include "qsub.h"
HEDLEY_DIAGNOSTIC_PUSH
SIMDE_DISABLE_UNWANTED_DIAGNOSTICS
......@@ -43,7 +42,7 @@ simde_vqdmlsl_high_s16(simde_int32x4_t a, simde_int16x8_t b, simde_int16x8_t c)
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
return vqdmlsl_high_s16(a, b, c);
#else
return simde_vsubq_s32(a, simde_vmulq_n_s32(simde_vmulq_s32(simde_vmovl_high_s16(b), simde_vmovl_high_s16(c)), 2));
return simde_vqsubq_s32(a, simde_vqdmull_high_s16(b, c));
#endif
}
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
......@@ -57,17 +56,7 @@ simde_vqdmlsl_high_s32(simde_int64x2_t a, simde_int32x4_t b, simde_int32x4_t c)
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
return vqdmlsl_high_s32(a, b, c);
#else
simde_int64x2_private r_ = simde_int64x2_to_private(
simde_x_vmulq_s64(
simde_vmovl_high_s32(b),
simde_vmovl_high_s32(c)));
SIMDE_VECTORIZE
for (size_t i = 0 ; i < (sizeof(r_.values) / sizeof(r_.values[0])) ; i++) {
r_.values[i] = r_.values[i] * HEDLEY_STATIC_CAST(int64_t, 2);
}
return simde_vsubq_s64(a, simde_int64x2_from_private(r_));
return simde_vqsubq_s64(a, simde_vqdmull_high_s32(b, c));
#endif
}
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
......
......@@ -27,91 +27,49 @@
#if !defined(SIMDE_ARM_NEON_QDMLSL_HIGH_LANE_H)
#define SIMDE_ARM_NEON_QDMLSL_HIGH_LANE_H
#include "movl_high.h"
#include "sub.h"
#include "mul.h"
#include "mul_n.h"
#include "dup_n.h"
#include "dup_lane.h"
#include "get_high.h"
#include "types.h"
#include "qdmlsl.h"
HEDLEY_DIAGNOSTIC_PUSH
SIMDE_DISABLE_UNWANTED_DIAGNOSTICS
SIMDE_BEGIN_DECLS_
SIMDE_FUNCTION_ATTRIBUTES
simde_int32x4_t
simde_vqdmlsl_high_lane_s16(simde_int32x4_t a, simde_int16x8_t b, simde_int16x4_t v, const int lane) SIMDE_REQUIRE_CONSTANT_RANGE(lane, 0, 3) {
return simde_vsubq_s32(a,
simde_vmulq_n_s32(
simde_vmulq_s32(
simde_vmovl_high_s16(b),
simde_vmovl_high_s16(simde_vdupq_n_s16(simde_int16x4_to_private(v).values[lane]))), 2));
}
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
#define simde_vqdmlsl_high_lane_s16(a, b, v, lane) vqdmlsl_high_lane_s16(a, b, v, lane)
#else
#define simde_vqdmlsl_high_lane_s16(a, b, v, lane) simde_vqdmlsl_s16((a), simde_vget_high_s16((b)), simde_vdup_lane_s16((v), (lane)))
#endif
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
#undef vqdmlsl_high_lane_s16
#define vqdmlsl_high_lane_s16(a, b, v, lane) simde_vqdmlsl_high_lane_s16((a), (b), (v), (lane))
#endif
SIMDE_FUNCTION_ATTRIBUTES
simde_int32x4_t
simde_vqdmlsl_high_laneq_s16(simde_int32x4_t a, simde_int16x8_t b, simde_int16x8_t v, const int lane) SIMDE_REQUIRE_CONSTANT_RANGE(lane, 0, 7) {
return simde_vsubq_s32(a,
simde_vmulq_n_s32(
simde_vmulq_s32(
simde_vmovl_high_s16(b),
simde_vmovl_high_s16(simde_vdupq_n_s16(simde_int16x8_to_private(v).values[lane]))), 2));
}
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
#define simde_vqdmlsl_high_laneq_s16(a, b, v, lane) vqdmlsl_high_laneq_s16(a, b, v, lane)
#else
#define simde_vqdmlsl_high_laneq_s16(a, b, v, lane) simde_vqdmlsl_s16((a), simde_vget_high_s16((b)), simde_vdup_laneq_s16((v), (lane)))
#endif
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
#undef vqdmlsl_high_laneq_s16
#define vqdmlsl_high_laneq_s16(a, b, v, lane) simde_vqdmlsl_high_laneq_s16((a), (b), (v), (lane))
#endif
SIMDE_FUNCTION_ATTRIBUTES
simde_int64x2_t
simde_vqdmlsl_high_lane_s32(simde_int64x2_t a, simde_int32x4_t b, simde_int32x2_t v, const int lane) SIMDE_REQUIRE_CONSTANT_RANGE(lane, 0, 1) {
simde_int64x2_private r_ = simde_int64x2_to_private(
simde_x_vmulq_s64(
simde_vmovl_high_s32(b),
simde_vmovl_high_s32(simde_vdupq_n_s32(simde_int32x2_to_private(v).values[lane]))));
SIMDE_VECTORIZE
for (size_t i = 0 ; i < (sizeof(r_.values) / sizeof(r_.values[0])) ; i++) {
r_.values[i] = r_.values[i] * HEDLEY_STATIC_CAST(int64_t, 2);
}
return simde_vsubq_s64(a, simde_int64x2_from_private(r_));
}
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
#define simde_vqdmlsl_high_lane_s32(a, b, v, lane) vqdmlsl_high_lane_s32(a, b, v, lane)
#else
#define simde_vqdmlsl_high_lane_s32(a, b, v, lane) simde_vqdmlsl_s32((a), simde_vget_high_s32((b)), simde_vdup_lane_s32((v), (lane)))
#endif
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
#undef vqdmlsl_high_lane_s32
#define vqdmlsl_high_lane_s32(a, b, v, lane) simde_vqdmlsl_high_lane_s32((a), (b), (v), (lane))
#endif
SIMDE_FUNCTION_ATTRIBUTES
simde_int64x2_t
simde_vqdmlsl_high_laneq_s32(simde_int64x2_t a, simde_int32x4_t b, simde_int32x4_t v, const int lane) SIMDE_REQUIRE_CONSTANT_RANGE(lane, 0, 3) {
simde_int64x2_private r_ = simde_int64x2_to_private(
simde_x_vmulq_s64(
simde_vmovl_high_s32(b),
simde_vmovl_high_s32(simde_vdupq_n_s32(simde_int32x4_to_private(v).values[lane]))));
SIMDE_VECTORIZE
for (size_t i = 0 ; i < (sizeof(r_.values) / sizeof(r_.values[0])) ; i++) {
r_.values[i] = r_.values[i] * HEDLEY_STATIC_CAST(int64_t, 2);
}
return simde_vsubq_s64(a, simde_int64x2_from_private(r_));
}
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
#define simde_vqdmlsl_high_laneq_s32(a, b, v, lane) vqdmlsl_high_laneq_s32(a, b, v, lane)
#else
#define simde_vqdmlsl_high_laneq_s32(a, b, v, lane) simde_vqdmlsl_s32((a), simde_vget_high_s32((b)), simde_vdup_laneq_s32((v), (lane)))
#endif
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
#undef vqdmlsl_high_laneq_s32
......
......@@ -29,10 +29,8 @@
#include "movl_high.h"
#include "dup_n.h"
#include "sub.h"
#include "mul.h"
#include "mul_n.h"
#include "types.h"
#include "qdmlsl_high.h"
HEDLEY_DIAGNOSTIC_PUSH
SIMDE_DISABLE_UNWANTED_DIAGNOSTICS
......@@ -44,11 +42,7 @@ simde_vqdmlsl_high_n_s16(simde_int32x4_t a, simde_int16x8_t b, int16_t c) {
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
return vqdmlsl_high_n_s16(a, b, c);
#else
return simde_vsubq_s32(a,
simde_vmulq_n_s32(
simde_vmulq_s32(
simde_vmovl_high_s16(b),
simde_vmovl_high_s16(simde_vdupq_n_s16(c))), 2));
return simde_vqdmlsl_high_s16(a, b, simde_vdupq_n_s16(c));
#endif
}
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
......@@ -62,17 +56,7 @@ simde_vqdmlsl_high_n_s32(simde_int64x2_t a, simde_int32x4_t b, int32_t c) {
#if defined(SIMDE_ARM_NEON_A64V8_NATIVE)
return vqdmlsl_high_n_s32(a, b, c);
#else
simde_int64x2_private r_ = simde_int64x2_to_private(
simde_x_vmulq_s64(
simde_vmovl_high_s32(b),
simde_vmovl_high_s32(simde_vdupq_n_s32(c))));
SIMDE_VECTORIZE
for (size_t i = 0 ; i < (sizeof(r_.values) / sizeof(r_.values[0])) ; i++) {
r_.values[i] = r_.values[i] * HEDLEY_STATIC_CAST(int64_t, 2);
}
return simde_vsubq_s64(a, simde_int64x2_from_private(r_));
return simde_vqdmlsl_high_s32(a, b, simde_vdupq_n_s32(c));
#endif
}
#if defined(SIMDE_ARM_NEON_A64V8_ENABLE_NATIVE_ALIASES)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment