/* Copyright Greg Novak, released to the public domain */
#include "intel-fp-exceptions.h"
#define X87_INVALID_OPERATION 0x1
#define X87_DENORMALIZED_OPERAND 0x2
#define X87_DIVIDE_BY_ZERO 0x4
#define X87_NUMERIC_OVERFLOW 0x8
#define X87_NUMERIC_UNDERFLOW 0x10
#define X87_INEXACT_RESULT 0x20
#define SSE_INVALID_OPERATION 0x80
#define SSE_DENORMALIZED_OPERAND 0x100
#define SSE_DIVIDE_BY_ZERO 0x200
#define SSE_NUMERIC_OVERFLOW 0x400
#define SSE_NUMERIC_UNDERFLOW 0x800
#define SSE_INEXACT_RESULT 0x1000
short read_x87_control_register(void)
{
short result;
asm ("fstcw %0;"
:"=m"(result));
return result;
}
void write_x87_control_register(short cw)
{
asm ("fldcw %0;"
: : "m"(cw));
}
int read_sse_control_register(void)
{
int result;
asm ("stmxcsr %0;"
:"=m"(result));
return result;
}
void write_sse_control_register(int csr)
{
asm ("ldmxcsr %0;"
: : "m"(csr));
}
void enable_x87_exception(short mask)
{
short cw;
cw = read_x87_control_register();
cw &= ~mask;
write_x87_control_register(cw);
}
void disable_x87_exception(short mask)
{
short cw;
cw = read_x87_control_register();
cw |= mask;
write_x87_control_register(cw);
}
void enable_sse_exception(int mask)
{
int cw;
cw = read_sse_control_register();
cw &= ~mask;
write_sse_control_register(cw);
}
void disable_sse_exception(int mask)
{
int cw;
cw = read_sse_control_register();
cw |= mask;
write_sse_control_register(cw);
}
void enable_x87_invalid_operation_exception(void) {enable_x87_exception(X87_INVALID_OPERATION);}
void enable_x87_divide_by_zero_exception(void) {enable_x87_exception(X87_DIVIDE_BY_ZERO);}
void enable_x87_denormalized_operand_exception(void) {enable_x87_exception(X87_DENORMALIZED_OPERAND);}
void enable_x87_numeric_overflow_exception(void) {enable_x87_exception(X87_NUMERIC_OVERFLOW);}
void enable_x87_numeric_underflow_exception(void) {enable_x87_exception(X87_NUMERIC_UNDERFLOW);}
void enable_x87_inexact_result_exception(void) {enable_x87_exception(X87_INEXACT_RESULT);}
void disable_x87_invalid_operation_exception(void) {disable_x87_exception(X87_INVALID_OPERATION);}
void disable_x87_divide_by_zero_exception(void) {disable_x87_exception(X87_DIVIDE_BY_ZERO);}
void disable_x87_denormalized_operand_exception(void) {disable_x87_exception(X87_DENORMALIZED_OPERAND);}
void disable_x87_numeric_overflow_exception(void) {disable_x87_exception(X87_NUMERIC_OVERFLOW);}
void disable_x87_numeric_underflow_exception(void) {disable_x87_exception(X87_NUMERIC_UNDERFLOW);}
void disable_x87_inexact_result_exception(void) {disable_x87_exception(X87_INEXACT_RESULT);}
void enable_sse_invalid_operation_exception(void) {enable_sse_exception(SSE_INVALID_OPERATION);}
void enable_sse_divide_by_zero_exception(void) {enable_sse_exception(SSE_DIVIDE_BY_ZERO);}
void enable_sse_denormalized_operand_exception(void) {enable_sse_exception(SSE_DENORMALIZED_OPERAND);}
void enable_sse_numeric_overflow_exception(void) {enable_sse_exception(SSE_NUMERIC_OVERFLOW);}
void enable_sse_numeric_underflow_exception(void) {enable_sse_exception(SSE_NUMERIC_UNDERFLOW);}
void enable_sse_inexact_result_exception(void) {enable_sse_exception(SSE_INEXACT_RESULT);}
void disable_sse_invalid_operation_exception(void) {disable_sse_exception(SSE_INVALID_OPERATION);}
void disable_sse_divide_by_zero_exception(void) {disable_sse_exception(SSE_DIVIDE_BY_ZERO);}
void disable_sse_denormalized_operand_exception(void) {disable_sse_exception(SSE_DENORMALIZED_OPERAND);}
void disable_sse_numeric_overflow_exception(void) {disable_sse_exception(SSE_NUMERIC_OVERFLOW);}
void disable_sse_numeric_underflow_exception(void) {disable_sse_exception(SSE_NUMERIC_UNDERFLOW);}
void disable_sse_inexact_result_exception(void) {disable_sse_exception(SSE_INEXACT_RESULT);}
void enable_all_exceptions(void)
{
// cursory error checking
if (sizeof(short) != 2 ||
sizeof(int) != 4)
printf("Types not the expected size -- results may surpise you\n");
enable_x87_invalid_operation_exception();
enable_x87_divide_by_zero_exception();
enable_x87_denormalized_operand_exception();
enable_x87_numeric_overflow_exception();
enable_x87_numeric_underflow_exception();
enable_x87_inexact_result_exception();
enable_sse_invalid_operation_exception();
enable_sse_divide_by_zero_exception();
enable_sse_denormalized_operand_exception();
enable_sse_numeric_overflow_exception();
enable_sse_numeric_underflow_exception();
enable_sse_inexact_result_exception();
}
void disable_all_exceptions(void)
{
disable_x87_invalid_operation_exception();
disable_x87_divide_by_zero_exception();
disable_x87_denormalized_operand_exception();
disable_x87_numeric_overflow_exception();
disable_x87_numeric_underflow_exception();
disable_x87_inexact_result_exception();
disable_sse_invalid_operation_exception();
disable_sse_divide_by_zero_exception();
disable_sse_denormalized_operand_exception();
disable_sse_numeric_overflow_exception();
disable_sse_numeric_underflow_exception();
disable_sse_inexact_result_exception();
}
Answers/Code/IntelFloatingPointExceptionsDotC (last edited 2007-09-12 23:32:51 by GregNovak)