From patchwork Thu May 19 13:46:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 96406 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 17377B6F7B for ; Fri, 20 May 2011 01:04:47 +1000 (EST) Received: from localhost ([::1]:40978 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QN3lW-0007LX-Kk for incoming@patchwork.ozlabs.org; Thu, 19 May 2011 09:59:50 -0400 Received: from eggs.gnu.org ([140.186.70.92]:34147) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QN3iF-0001n5-BG for qemu-devel@nongnu.org; Thu, 19 May 2011 09:56:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QN3iE-0002S8-3C for qemu-devel@nongnu.org; Thu, 19 May 2011 09:56:27 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:33236) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QN3iD-0002RA-Sb for qemu-devel@nongnu.org; Thu, 19 May 2011 09:56:26 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1QN3YR-00062K-AM; Thu, 19 May 2011 14:46:19 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 19 May 2011 14:46:16 +0100 Message-Id: <1305812779-23175-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1305812779-23175-1-git-send-email-peter.maydell@linaro.org> References: <1305812779-23175-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 81.2.115.146 Cc: Paul Brook , Aurelien Jarno , patches@linaro.org Subject: [Qemu-devel] [PATCH v2 3/6] target-arm: Signal InvalidOp for Neon GE and GT compares of QNaN X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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))