blob: b52d0932fbaa5ceb37274eebb6ee1a7831a3268a [file] [log] [blame]
#define FP_EX_INVALID 0x01
#define FP_EX_DIVZERO 0x02
#define FP_EX_OVERFLOW 0x04
#define FP_EX_UNDERFLOW 0x08
#define FP_EX_INEXACT 0x10
void
__sfp_handle_exceptions (int _fex)
{
const float fp_max = __FLT_MAX__;
const float fp_min = __FLT_MIN__;
const float fp_1e32 = 1.0e32f;
const float fp_zero = 0.0;
const float fp_one = 1.0;
unsigned long fpsr;
if (_fex & FP_EX_INVALID)
{
__asm__ __volatile__ ("fdiv\ts0, %s0, %s0"
:
: "w" (fp_zero)
: "s0");
__asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
}
if (_fex & FP_EX_DIVZERO)
{
__asm__ __volatile__ ("fdiv\ts0, %s0, %s1"
:
: "w" (fp_one), "w" (fp_zero)
: "s0");
__asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
}
if (_fex & FP_EX_OVERFLOW)
{
__asm__ __volatile__ ("fadd\ts0, %s0, %s1"
:
: "w" (fp_max), "w" (fp_1e32)
: "s0");
__asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
}
if (_fex & FP_EX_UNDERFLOW)
{
__asm__ __volatile__ ("fmul\ts0, %s0, %s0"
:
: "w" (fp_min)
: "s0");
__asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
}
if (_fex & FP_EX_INEXACT)
{
__asm__ __volatile__ ("fsub\ts0, %s0, %s1"
:
: "w" (fp_max), "w" (fp_one)
: "s0");
__asm__ __volatile__ ("mrs\t%0, fpsr" : "=r" (fpsr));
}
}