From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751936AbdG0QMh (ORCPT ); Thu, 27 Jul 2017 12:12:37 -0400 Received: from mx2.rt-rk.com ([89.216.37.149]:51821 "EHLO mail.rt-rk.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751539AbdG0QMd (ORCPT ); Thu, 27 Jul 2017 12:12:33 -0400 From: Aleksandar Markovic To: linux-mips@linux-mips.org Cc: Aleksandar Markovic , Douglas Leung , Miodrag Dinic , Goran Ferenc , "# 4 . 7+" , Bo Hu , James Hogan , Jin Qian , linux-kernel@vger.kernel.org, Paul Burton , Petar Jovanovic , Raghu Gandham , Ralf Baechle Subject: [PATCH v4 12/16] MIPS: math-emu: .: Fix some cases of infinite inputs Date: Thu, 27 Jul 2017 18:08:55 +0200 Message-Id: <1501171791-23690-13-git-send-email-aleksandar.markovic@rt-rk.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1501171791-23690-1-git-send-email-aleksandar.markovic@rt-rk.com> References: <1501171791-23690-1-git-send-email-aleksandar.markovic@rt-rk.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Aleksandar Markovic Fix the cases of . when any of two multiplicands is infinity. The correct behavior in such cases is affected by the nature of third input. Cases of addition of infinities with opposite signs and subtraction of infinities with same signs may arise and must be handles separately. Also, the value od flags argument (that determines whether the instruction is MADDF or MSUBF) affects the outcome. Relevant examples: MADDF.S fd,fs,ft: If fs contains +inf, ft contains +inf, and fd contains -inf, fd is going to contain indef (without this patch, it used to contain -inf). MSUBF.S fd,fs,ft: If fs contains +inf, ft contains 1.0, and fd contains +0.0, fd is going to contain -inf (without this patch, it used to contain +inf). Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction") Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction") Signed-off-by: Douglas Leung Signed-off-by: Miodrag Dinic Signed-off-by: Goran Ferenc Signed-off-by: Aleksandar Markovic Cc: # 4.7+ Reviewed-by: James Hogan --- arch/mips/math-emu/dp_maddf.c | 22 +++++++++++++++++++++- arch/mips/math-emu/sp_maddf.c | 22 +++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c index 8b1bd42..557a0a1 100644 --- a/arch/mips/math-emu/dp_maddf.c +++ b/arch/mips/math-emu/dp_maddf.c @@ -84,7 +84,27 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - return ieee754dp_inf(xs ^ ys); + if ((zc == IEEE754_CLASS_INF) && + ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) || + ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) { + /* + * Cases of addition of infinities with opposite signs + * or subtraction of infinities with same signs. + */ + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754dp_indef(); + } + /* + * z is here either not an infinity, or an infinity having the + * same sign as product (x*y) (in case of MADDF.D instruction) + * or product -(x*y) (in MSUBF.D case). The result must be an + * infinity, and its sign is determined only by the value of + * (flags & maddf_negate_product) and the signs of x and y. + */ + if (flags & maddf_negate_product) + return ieee754dp_inf(1 ^ (xs ^ ys)); + else + return ieee754dp_inf(xs ^ ys); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c index 6cdaa2a..0d8d25f 100644 --- a/arch/mips/math-emu/sp_maddf.c +++ b/arch/mips/math-emu/sp_maddf.c @@ -85,7 +85,27 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): - return ieee754sp_inf(xs ^ ys); + if ((zc == IEEE754_CLASS_INF) && + ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) || + ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) { + /* + * Cases of addition of infinities with opposite signs + * or subtraction of infinities with same signs. + */ + ieee754_setcx(IEEE754_INVALID_OPERATION); + return ieee754sp_indef(); + } + /* + * z is here either not an infinity, or an infinity having the + * same sign as product (x*y) (in case of MADDF.D instruction) + * or product -(x*y) (in MSUBF.D case). The result must be an + * infinity, and its sign is determined only by the value of + * (flags & maddf_negate_product) and the signs of x and y. + */ + if (flags & maddf_negate_product) + return ieee754sp_inf(1 ^ (xs ^ ys)); + else + return ieee754sp_inf(xs ^ ys); case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -- 2.7.4