/***************************************************************************** /* simpler64.h A few macros to try and make life simpler between 32 (VAX) and 64 bit (Alpha and Itanium) platforms. Transparency relies on quadwords being declared as long[2] and always given to the macros as addresses/pointers. VERSION HISTORY --------------- 01-FEB-2014 MGD long overdue */ /*****************************************************************************/ #ifndef SIMPLER64_H_LOADED #define SIMPLER64_H_LOADED 1 #include /* mainly to allow easy use of the __unaligned directive */ #define UINTPTR __unaligned unsigned int* #define ULONGPTR __unaligned unsigned long* #define USHORTPTR __unaligned unsigned short* #define INT64PTR __unaligned __int64* #ifndef USE_INT64 #ifdef __VAX #define USE_INT64 0 #else #define USE_INT64 1 #endif #endif /* demonstrated to be an order of magnitude faster than memcmp() */ #define MATCH0(ptr1,ptr2,len) (memcmp(ptr1,ptr2,len) == 0) #define MATCH1(ptr1,ptr2) (*(char*)(ptr1) == *(char*)(ptr2)) #define MATCH2(ptr1,ptr2) (*(USHORTPTR)(ptr1) == *(USHORTPTR)(ptr2)) #define MATCH3(ptr1,ptr2) ((*(ULONGPTR)(ptr1) & 0x00ffffff) == \ (*(ULONGPTR)(ptr2) & 0x00ffffff)) #define MATCH4(ptr1,ptr2) (*(ULONGPTR)(ptr1) == *(ULONGPTR)(ptr2)) #if USE_INT64 #define MATCH5(ptr1,ptr2) ((*(INT64PTR)(ptr1) & 0x000000ffffffffff) == \ (*(INT64PTR)(ptr2) & 0x000000ffffffffff)) #define MATCH6(ptr1,ptr2) ((*(INT64PTR)(ptr1) & 0x0000ffffffffffff) == \ (*(INT64PTR)(ptr2) & 0x0000ffffffffffff)) #define MATCH7(ptr1,ptr2) ((*(INT64PTR)(ptr1) & 0x00ffffffffffffff) == \ (*(INT64PTR)(ptr2) & 0x00ffffffffffffff)) #define MATCH8(ptr1,ptr2) (*(INT64PTR)(ptr1) == *(INT64PTR)(ptr2)) #else #define MATCH5(ptr1,ptr2) ((((ULONGPTR)(ptr1))[0] == ((ULONGPTR)(ptr2))[0]) && \ ((((ULONGPTR)(ptr1))[1] & 0x000000ff) == \ (((ULONGPTR)(ptr2))[1] & 0x000000ff))) #define MATCH6(ptr1,ptr2) ((((ULONGPTR)(ptr1))[0] == ((ULONGPTR)(ptr2))[0]) && \ ((((ULONGPTR)(ptr1))[1] & 0x0000ffff) == \ (((ULONGPTR)(ptr2))[1] & 0x0000ffff))) #define MATCH7(ptr1,ptr2) ((((ULONGPTR)(ptr1))[0] == ((ULONGPTR)(ptr2))[0]) && \ ((((ULONGPTR)(ptr1))[1] & 0x00ffffff) == \ (((ULONGPTR)(ptr2))[1] & 0x00ffffff))) #define MATCH8(ptr1,ptr2) ((((ULONGPTR)(ptr1))[0] == ((ULONGPTR)(ptr2))[0]) && \ (((ULONGPTR)(ptr1))[1] == ((ULONGPTR)(ptr2))[1])) #endif /* demonstrated to be 50% faster than comparable MATCH() */ #define SAME1(ptr,val) (*(char*)(ptr) == val) #define SAME2(ptr,val) (*(USHORTPTR)(ptr) == val) #define SAME3(ptr,val) ((*(ULONGPTR)(ptr) & 0x00ffffff) == val) #define SAME4(ptr,val) (*(ULONGPTR)(ptr) == val) #define SET2(ptr,val) (*(USHORTPTR)(ptr) = val) #define SET4(ptr,val) (*(ULONGPTR)(ptr) = val) /* these quad macros are designed for storage assigned as long[2] */ /* is the 64 bit number in 'a' the same as in 'b' */ #if USE_INT64 #define QUAD_EQUAL_QUAD(a,b) (*(INT64PTR)a == *(INT64PTR)b) #else #define QUAD_EQUAL_QUAD(a,b) (((ULONGPTR)a)[0] == \ ((ULONGPTR)b)[0] && \ ((ULONGPTR)a)[1] == \ ((ULONGPTR)b)[1]) #endif /* is the 64 bit number in 'a' larger than that in 'b'? */ /* BIZARRE!: QUAD_GT_QUAD() generated a syntax error! '_GT_' reserved? */ #if USE_INT64 #define QUAD_MORE_THAN_QUAD(a,b) (*(INT64PTR)a > *(INT64PTR)b) #else /* do it by checking the sign of a subtraction */ #define QUAD_MORE_THAN_QUAD(a,b) QUADMORETHANQUAD((ulong*)a,(ulong*)b) QUADMORETHANQUAD(ulong*a,ulong*b) { ulong q[2]; lib$subx (b, a, &q, 0); return ((q[1] & 0x80000000) != 0); } #endif /* is the 64 bit number zero? */ #if USE_INT64 #define QUAD_ZERO(a) (!*(INT64PTR)a) #else #define QUAD_ZERO(a) (!((ULONGPTR)a)[0] && !((ULONGPTR)a)[1]) #endif /* is the 64 bit number NOT zero? */ #if USE_INT64 #define QUAD_NOT_ZERO(a) (*(INT64PTR)a) #else #define QUAD_NOT_ZERO(a) (((ULONGPTR)a)[0] || ((ULONGPTR)a)[1]) #endif /* put the 64 bit number in 'a' into 'b' */ #if USE_INT64 #define PUT_QUAD_QUAD(a,b) { *(INT64PTR)b = *(INT64PTR)a; } #else #define PUT_QUAD_QUAD(a,b) { ((ULONGPTR)b)[0] = ((ULONGPTR)a)[0]; \ ((ULONGPTR)b)[1] = ((ULONGPTR)a)[1]; } #endif /* put the 32 bit number in 'a' into 'b' */ #if USE_INT64 #define PUT_LONG_QUAD(a,b) { *(INT64PTR)b = (long)a; } #else #define PUT_LONG_QUAD(a,b) { ((ULONGPTR)b)[0] = a; ((ULONGPTR)b)[1] = 0; } #endif /* zero the 64 bit number at 'a' */ #if USE_INT64 #define PUT_ZERO_QUAD(a) { *(INT64PTR)a = 0; } #else #define PUT_ZERO_QUAD(a) { ((ULONGPTR)a)[0] = ((ULONGPTR)a)[1] = 0; } #endif /* NOTE: adds and substracts CANNOT be used with pointers to quads! */ /* adds the 64 bit number at 'a' to the number at 'b' */ #if USE_INT64 #define ADD_QUAD_QUAD(a,b) *(INT64PTR)b = *(INT64PTR)b + *(INT64PTR)a; #else #define ADD_QUAD_QUAD(a,b) lib$addx(a,b,b,0); #endif /* adds the 64 bit number at 'a' to the number at 'b' result in 'c' */ #if USE_INT64 #define PLUS_QUAD_QUAD(a,b,c) *(INT64PTR)c = *(INT64PTR)b + *(INT64PTR)a; #else #define PLUS_QUAD_QUAD(a,b,c) lib$addx(a,b,c,0); #endif /* adds the 32 bit number in 'a' to the number in 'b' */ #if USE_INT64 #define ADD_LONG_QUAD(a,b) *(INT64PTR)b = *(INT64PTR)b + (long)a; #else #define ADD_LONG_QUAD(a,b) { \ ulong q[2] = { a, 0 }; \ lib$addx(&q,b,b,0); \ } #endif /* subtracts the 64 bit number at 'a' from the number at 'b' */ #if USE_INT64 #define SUB_QUAD_QUAD(a,b) { *(INT64PTR)b = *(INT64PTR)b - *(INT64PTR)a; } #else #define SUB_QUAD_QUAD(a,b) { lib$subx(b,a,b,0); } #endif /* subtracts the 64 bit number at 'a' from the number at 'b' stores in 'c'*/ #if USE_INT64 #define MINUS_QUAD_QUAD(a,b,c) (*(INT64PTR)c = *(INT64PTR)b - *(INT64PTR)a) #else #define MINUS_QUAD_QUAD(a,b,c) lib$subx(b,a,c,0) #endif /* subtracts the 32 bit number in 'a' from the number in 'b' */ #if USE_INT64 #define SUB_LONG_QUAD(a,b) (*(INT64PTR)b = *(INT64PTR)b - (long)a) #else #define SUB_LONG_QUAD(a,b) { \ ulong q[2] = { a, 0 }; \ lib$subx(b,q,b,0); \ } #endif /* multiplies the 32 bit "quadword" in 'b' by the 32 bit number in 'a' */ #if USE_INT64 #define MUL_LONG_QUAD(a,b) { *(INT64PTR)b = *(INT64PTR)b * (long)a; } #else #define MUL_LONG_QUAD(a,b) { \ int status; \ ulong EmulCand = (((ULONGPTR)b)[0]), \ EmulPlier = a, \ EmulAddend = 0; \ if (((ULONGPTR)b)[1]) status = SS$_BUGCHECK; \ else status = lib$emul (&EmulPlier, &EmulCand, &EmulAddend, b); \ } #endif /* make a float from the pointed-to quadword */ #if USE_INT64 #define FLOAT_FROM_QUAD(a) ((float)*(INT64PTR)a) #else #define FLOAT_FROM_QUAD(a) ((float)(((ulong*)a)[0]) + \ ((float)(((ulong*)a)[1])*4294967296.0)) #endif /* put a the float in 'a' into the quadword pointed to by 'b' */ #if USE_INT64 #define FLOAT_TO_QUAD(a,b) { (*(INT64PTR)b = (__int64)a); } #else #define FLOAT_TO_QUAD(a,b) \ { (((ulong*)b)[0]) = (ulong)(a - (a / 4294967296.0)); \ (((ulong*)b)[1]) = (ulong)(a / 4294967296.0); } #endif /* the smallest delta time */ #if USE_INT64 #define ZERO_DELTA_TIME(a) { *(INT64PTR)a = 0xffffffffffffffff; } #else #define ZERO_DELTA_TIME(a) { ((ULONGPTR)a)[0] = ((ULONGPTR)a)[1] = 0xffffffff; #endif /* is it the smallest delta time? */ #if USE_INT64 #define IS_ZERO_DELTA_TIME(a) (*(INT64PTR)a == 0xffffffffffffffff) #else #define IS_ZERO_DELTA_TIME(a) (((ULONGPTR)a)[0] == 0xffffffff && \ ((ULONGPTR)a)[1] == 0xffffffff) #endif #endif /* SIMPLER64_H_LOADED */ /*****************************************************************************/