F-15
GUIDELINES FOR WRITING SIMD FLOATING-POINT EXCEPTION
The emulation function returns RAISE_EXCEPTION to the filter function if an exception has
to be raised (the exception_cause field will indicate the cause); otherwise, the emulation func-
tion returns DO_NOT_ RAISE_EXCEPTION. In the first case, the result will be provided by
the user exception handler called by the filter function. In the second case, it is provided by the
emulation function. The filter function has to collect all the partial results, and to assemble the
scalar or packed result that will be used if execution is to be continued.
Example F-2. SIMD Floating-Point Emulation
// masks for individual status word bits
#define PRECISION_MASK 0x20
#define UNDERFLOW_MASK 0x10
#define OVERFLOW_MASK 0x08
#define ZERODIVIDE_MASK 0x04
#define DENORMAL_MASK 0x02
#define INVALID_MASK 0x01
// 32-bit constants
static unsigned ZEROF_ARRAY[] = {0x00000000};
#define ZEROF *(float *) ZEROF_ARRAY
// +0.0
static unsigned NZEROF_ARRAY[] = {0x80000000};
#define NZEROF *(float *) NZEROF_ARRAY
// -0.0
static unsigned POSINFF_ARRAY[] = {0x7f800000};
#define POSINFF *(float *)POSINFF_ARRAY
// +Inf
static unsigned NEGINFF_ARRAY[] = {0xff800000};
#define NEGINFF *(float *)NEGINFF_ARRAY
// -Inf
// 64-bit constants
static unsigned MIN_SINGLE_NORMAL_ARRAY [] = {0x00000000, 0x38100000};
#define MIN_SINGLE_NORMAL *(double *)MIN_SINGLE_NORMAL_ARRAY
// +1.0 * 2^-126
static unsigned MAX_SINGLE_NORMAL_ARRAY [] = {0x70000000, 0x47efffff};
#define MAX_SINGLE_NORMAL *(double *)MAX_SINGLE_NORMAL_ARRAY
// +1.1...1*2^127
static unsigned TWO_TO_192_ARRAY[] = {0x00000000, 0x4bf00000};
#define TWO_TO_192 *(double *)TWO_TO_192_ARRAY
// +1.0 * 2^192
static unsigned TWO_TO_M192_ARRAY[] = {0x00000000, 0x33f00000};
#define TWO_TO_M192 *(double *)TWO_TO_M192_ARRAY
// +1.0 * 2^-192
// auxiliary functions
static int isnanf (float f); // returns 1 if f is a NaN, and 0 otherwise