[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/7] target-arm: Signal InvalidOp for Neon GE and GT
From: |
Peter Maydell |
Subject: |
[Qemu-devel] [PATCH 3/7] target-arm: Signal InvalidOp for Neon GE and GT compares of QNaN |
Date: |
Fri, 6 May 2011 13:48:11 +0100 |
If the input to a Neon float comparison is a quiet NaN, the ARM ARM
specifies that we should raise InvalidOp if the comparison is GE or GT
but not for EQ. (Signaling NaNs raise InvalidOp regardless). This means
only EQ should use the _quiet version of the comparison function.
We implement this by cleaning up the comparison helpers to call the
appopriate versions of the softfloat simple comparison functions
(float32_le and friends) rather than the generic float32_compare functions.
This makes them simple enough that they are clearer opencoded rather
than macroised.
Signed-off-by: Peter Maydell <address@hidden>
---
target-arm/neon_helper.c | 40 ++++++++++++++++++----------------------
1 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index f5b173a..9165519 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -1802,41 +1802,37 @@ uint32_t HELPER(neon_mul_f32)(uint32_t a, uint32_t b)
return float32_val(float32_mul(make_float32(a), make_float32(b), NFS));
}
-/* Floating point comparisons produce an integer result. */
-#define NEON_VOP_FCMP(name, ok) \
-uint32_t HELPER(neon_##name)(uint32_t a, uint32_t b) \
-{ \
- switch (float32_compare_quiet(make_float32(a), make_float32(b), NFS)) { \
- ok return ~0; \
- default: return 0; \
- } \
+/* Floating point comparisons produce an integer result.
+ * Note that EQ doesn't signal InvalidOp for QNaNs but GE and GT do.
+ * Softfloat routines return 0/1, which we convert to the 0/-1 Neon requires.
+ */
+uint32_t HELPER(neon_ceq_f32)(uint32_t a, uint32_t b)
+{
+ return -float32_eq_quiet(make_float32(a), make_float32(b), NFS);
+}
+
+uint32_t HELPER(neon_cge_f32)(uint32_t a, uint32_t b)
+{
+ return -float32_le(make_float32(b), make_float32(a), NFS);
}
-NEON_VOP_FCMP(ceq_f32, case float_relation_equal:)
-NEON_VOP_FCMP(cge_f32, case float_relation_equal: case float_relation_greater:)
-NEON_VOP_FCMP(cgt_f32, case float_relation_greater:)
+uint32_t HELPER(neon_cgt_f32)(uint32_t a, uint32_t b)
+{
+ return -float32_lt(make_float32(b), make_float32(a), NFS);
+}
uint32_t HELPER(neon_acge_f32)(uint32_t a, uint32_t b)
{
float32 f0 = float32_abs(make_float32(a));
float32 f1 = float32_abs(make_float32(b));
- switch (float32_compare_quiet(f0, f1, NFS)) {
- case float_relation_equal:
- case float_relation_greater:
- return ~0;
- default:
- return 0;
- }
+ return -float32_le(f1, f0, NFS);
}
uint32_t HELPER(neon_acgt_f32)(uint32_t a, uint32_t b)
{
float32 f0 = float32_abs(make_float32(a));
float32 f1 = float32_abs(make_float32(b));
- if (float32_compare_quiet(f0, f1, NFS) == float_relation_greater) {
- return ~0;
- }
- return 0;
+ return -float32_lt(f1, f0, NFS);
}
#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
--
1.7.1
- [Qemu-devel] [PATCH 0/7] target-arm: Fix bugs in fp exception flag setting, Peter Maydell, 2011/05/06
- [Qemu-devel] [PATCH 3/7] target-arm: Signal InvalidOp for Neon GE and GT compares of QNaN,
Peter Maydell <=
- [Qemu-devel] [PATCH 7/7] target-arm: Signal Underflow when denormal flushed to zero on output, Peter Maydell, 2011/05/06
- [Qemu-devel] [PATCH 2/7] target-arm: Signal InputDenormal for VRECPE, VRSQRTE, VRECPS, VRSQRTS, Peter Maydell, 2011/05/06
- [Qemu-devel] [PATCH 1/7] target-arm: Don't set FP exceptions in recip, recip_sqrt estimate fns, Peter Maydell, 2011/05/06
- [Qemu-devel] [PATCH 6/7] softfloat: Add new flag for when denormal result is flushed to zero, Peter Maydell, 2011/05/06
- [Qemu-devel] [PATCH 5/7] target-arm: Add separate Neon float-int conversion helpers, Peter Maydell, 2011/05/06
- [Qemu-devel] [PATCH 4/7] target-arm: Refactor int-float conversions, Peter Maydell, 2011/05/06