2015-08-13 09:56:35 +02:00
/*
* IEEE754 floating point arithmetic
* single precision : MIN { , A } . f
* MIN : Scalar Floating - Point Minimum
* MINA : Scalar Floating - Point argument with Minimum Absolute Value
*
* MIN . S : FPR [ fd ] = minNum ( FPR [ fs ] , FPR [ ft ] )
* MINA . S : FPR [ fd ] = maxNumMag ( FPR [ fs ] , FPR [ ft ] )
*
* MIPS floating point support
* Copyright ( C ) 2015 Imagination Technologies , Ltd .
* Author : Markos Chandras < markos . chandras @ imgtec . com >
*
* This program is free software ; you can distribute it and / or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation ; version 2 of the License .
*/
# include "ieee754sp.h"
union ieee754sp ieee754sp_fmin ( union ieee754sp x , union ieee754sp y )
{
COMPXSP ;
COMPYSP ;
EXPLODEXSP ;
EXPLODEYSP ;
FLUSHXSP ;
FLUSHYSP ;
ieee754_clearcx ( ) ;
switch ( CLPAIR ( xc , yc ) ) {
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_SNAN ) :
return ieee754sp_nanxcpt ( y ) ;
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_DNORM ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_INF ) :
return ieee754sp_nanxcpt ( x ) ;
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix quiet NaN propagation
Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S> fd,fs,ft, if both
inputs are quiet NaNs. The <MAX|MAXA|MIN|MINA>.<D|S> specifications
state that the returned value in such cases should be the quiet NaN
contained in register fs.
A relevant example:
MAX.S fd,fs,ft:
If fs contains qNaN1, and ft contains qNaN2, fd is going to contain
qNaN1 (without this patch, it used to contain qNaN2).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Cc: Bo Hu <bohu@google.com>
Cc: Douglas Leung <douglas.leung@imgtec.com>
Cc: Jin Qian <jinqian@google.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
Cc: Raghu Gandham <raghu.gandham@imgtec.com>
Cc: <stable@vger.kernel.org> # 4.3+
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16880/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2017-07-27 18:08:48 +02:00
/*
* Quiet NaN handling
*/
/*
* The case of both inputs quiet NaNs
*/
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_QNAN ) :
return x ;
/*
* The cases of exactly one input quiet NaN ( numbers
* are here preferred as returned values to NaNs )
*/
2015-08-13 09:56:35 +02:00
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_QNAN ) :
return x ;
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_DNORM ) :
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_INF ) :
return y ;
/*
* Infinity and zero handling
*/
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_DNORM ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_ZERO ) :
return xs ? x : y ;
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_DNORM ) :
return ys ? y : x ;
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_ZERO ) :
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix cases of both inputs zero
Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S>, if both inputs
are zeros. The right behavior in such cases is stated in instruction
reference manual and is as follows:
fs ft MAX MIN MAXA MINA
---------------------------------------------
0 0 0 0 0 0
0 -0 0 -0 0 -0
-0 0 0 -0 0 -0
-0 -0 -0 -0 -0 -0
Prior to this patch, some of the above cases were yielding correct
results. However, for the sake of code consistency, all such cases
are rewritten in this patch.
A relevant example:
MAX.S fd,fs,ft:
If fs contains +0.0, and ft contains -0.0, fd is going to contain
+0.0 (without this patch, it used to contain -0.0).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Cc: Bo Hu <bohu@google.com>
Cc: Douglas Leung <douglas.leung@imgtec.com>
Cc: Jin Qian <jinqian@google.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
Cc: Raghu Gandham <raghu.gandham@imgtec.com>
Cc: <stable@vger.kernel.org> # 4.3+
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16881/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2017-07-27 18:08:49 +02:00
return ieee754sp_zero ( xs | ys ) ;
2015-08-13 09:56:35 +02:00
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_DNORM ) :
SPDNORMX ;
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_DNORM ) :
SPDNORMY ;
break ;
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_NORM ) :
SPDNORMX ;
}
/* Finally get to do some computation */
assert ( xm & SP_HIDDEN_BIT ) ;
assert ( ym & SP_HIDDEN_BIT ) ;
/* Compare signs */
if ( xs > ys )
return x ;
else if ( xs < ys )
return y ;
2017-07-27 18:08:50 +02:00
/* Signs of inputs are the same, let's compare exponents */
if ( xs = = 0 ) {
/* Inputs are both positive */
if ( xe > ye )
return y ;
else if ( xe < ye )
return x ;
} else {
/* Inputs are both negative */
if ( xe > ye )
return x ;
else if ( xe < ye )
return y ;
}
2015-08-13 09:56:35 +02:00
2017-07-27 18:08:50 +02:00
/* Signs and exponents of inputs are equal, let's compare mantissas */
if ( xs = = 0 ) {
/* Inputs are both positive, with equal signs and exponents */
if ( xm < = ym )
return x ;
return y ;
}
/* Inputs are both negative, with equal signs and exponents */
2015-08-13 09:56:35 +02:00
if ( xm < = ym )
2017-07-27 18:08:50 +02:00
return y ;
return x ;
2015-08-13 09:56:35 +02:00
}
union ieee754sp ieee754sp_fmina ( union ieee754sp x , union ieee754sp y )
{
COMPXSP ;
COMPYSP ;
EXPLODEXSP ;
EXPLODEYSP ;
FLUSHXSP ;
FLUSHYSP ;
ieee754_clearcx ( ) ;
switch ( CLPAIR ( xc , yc ) ) {
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_SNAN ) :
return ieee754sp_nanxcpt ( y ) ;
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_SNAN ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_DNORM ) :
case CLPAIR ( IEEE754_CLASS_SNAN , IEEE754_CLASS_INF ) :
return ieee754sp_nanxcpt ( x ) ;
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix quiet NaN propagation
Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S> fd,fs,ft, if both
inputs are quiet NaNs. The <MAX|MAXA|MIN|MINA>.<D|S> specifications
state that the returned value in such cases should be the quiet NaN
contained in register fs.
A relevant example:
MAX.S fd,fs,ft:
If fs contains qNaN1, and ft contains qNaN2, fd is going to contain
qNaN1 (without this patch, it used to contain qNaN2).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Cc: Bo Hu <bohu@google.com>
Cc: Douglas Leung <douglas.leung@imgtec.com>
Cc: Jin Qian <jinqian@google.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
Cc: Raghu Gandham <raghu.gandham@imgtec.com>
Cc: <stable@vger.kernel.org> # 4.3+
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16880/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2017-07-27 18:08:48 +02:00
/*
* Quiet NaN handling
*/
/*
* The case of both inputs quiet NaNs
*/
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_QNAN ) :
return x ;
/*
* The cases of exactly one input quiet NaN ( numbers
* are here preferred as returned values to NaNs )
*/
2015-08-13 09:56:35 +02:00
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_QNAN ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_QNAN ) :
return x ;
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_DNORM ) :
case CLPAIR ( IEEE754_CLASS_QNAN , IEEE754_CLASS_INF ) :
return y ;
/*
* Infinity and zero handling
*/
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_DNORM ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_ZERO ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_ZERO ) :
return x ;
case CLPAIR ( IEEE754_CLASS_INF , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_INF ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_NORM ) :
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_DNORM ) :
return y ;
case CLPAIR ( IEEE754_CLASS_ZERO , IEEE754_CLASS_ZERO ) :
MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix cases of both inputs zero
Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S>, if both inputs
are zeros. The right behavior in such cases is stated in instruction
reference manual and is as follows:
fs ft MAX MIN MAXA MINA
---------------------------------------------
0 0 0 0 0 0
0 -0 0 -0 0 -0
-0 0 0 -0 0 -0
-0 -0 -0 -0 -0 -0
Prior to this patch, some of the above cases were yielding correct
results. However, for the sake of code consistency, all such cases
are rewritten in this patch.
A relevant example:
MAX.S fd,fs,ft:
If fs contains +0.0, and ft contains -0.0, fd is going to contain
+0.0 (without this patch, it used to contain -0.0).
Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction")
Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Cc: Bo Hu <bohu@google.com>
Cc: Douglas Leung <douglas.leung@imgtec.com>
Cc: Jin Qian <jinqian@google.com>
Cc: Paul Burton <paul.burton@imgtec.com>
Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
Cc: Raghu Gandham <raghu.gandham@imgtec.com>
Cc: <stable@vger.kernel.org> # 4.3+
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/16881/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2017-07-27 18:08:49 +02:00
return ieee754sp_zero ( xs | ys ) ;
2015-08-13 09:56:35 +02:00
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_DNORM ) :
SPDNORMX ;
case CLPAIR ( IEEE754_CLASS_NORM , IEEE754_CLASS_DNORM ) :
SPDNORMY ;
break ;
case CLPAIR ( IEEE754_CLASS_DNORM , IEEE754_CLASS_NORM ) :
SPDNORMX ;
}
/* Finally get to do some computation */
assert ( xm & SP_HIDDEN_BIT ) ;
assert ( ym & SP_HIDDEN_BIT ) ;
/* Compare exponent */
if ( xe > ye )
return y ;
else if ( xe < ye )
return x ;
/* Compare mantissa */
if ( xm < = ym )
return x ;
return y ;
}