/* This file is part of Cloudy and is copyright (C)1978-2006 by Gary J. Ferland
 * For conditions of distribution and use see copyright notice in license.txt */
/* cpu.h: store CPU specific information */

/* >>chng 05 dec 14, added this file, PvH */
EXTERN struct t_cpu
{
	/* alias an int32 to 4 chars to test if we are on a big-endian or little-endian CPU */
	/* the array cpu.endian.c[] is initialized in cdInit() */
	union
	{
		char c[4];
		int32 i;
	} endian;
	int32 Float_SNaN_Value;
	int32 Double_SNaN_Value[2];
} cpu;

#define CPU_IS_BIG_ENDIAN    ( cpu.endian.i == 0x12345678 )
#define CPU_IS_LITTLE_ENDIAN ( cpu.endian.i == 0x78563412 )

/* define preprocessor symbols for setting float and double signaling NaN
 * The bitpattern for an SNaN is implementation defined, but this should
 * work on most modern CPU's. The system definition is preferred, so in
 * C++ this should be replaced by numeric_limits<TYPE>::signaling_NaN() */
#define SET_FLT_SNAN(X)                                 \
{                                                       \
/*lint -e740 unusual pointer cast */                    \
	if( sizeof(X) == 4 )                            \
		*((int32*)(&X)) = cpu.Float_SNaN_Value; \
	else                                            \
		X = -FLT_MAX;                           \
/*lint +e740 unusual pointer cast */                    \
}

#define SET_DBL_SNAN(X)                                         \
{                                                               \
/*lint -e740 unusual pointer cast */                            \
	if( sizeof(X) == 8 )                                    \
	{                                                       \
		*((int32*)(&X)) = cpu.Double_SNaN_Value[0];     \
		*(((int32*)(&X))+1) = cpu.Double_SNaN_Value[1]; \
	}                                                       \
	else                                                    \
		X = -DBL_MAX;                                   \
/*lint +e740 unusual pointer cast */                            \
}
