main index

section index




/*-------------------------------------------------------------*/
/***************************************************************
 * Type netwib_uint64, can be represented as:                  *
 *  - a 64 bit integer                                         *
 *  - a structure containing two 32 bit integers               *
 * In the first case, math operations are supported by the     *
 * compiler.                                                   *
 * In the second case, following functions are needed.         *
 ***************************************************************/

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_8(a,b,c,d,e,f,g,h,x) x = netwib_c2_uint64_8(a,b,c,d,e,f,g,h)
 #define netwib__uint64_init_32(a,b,x) x = (((netwib_uint64)((netwib_uint32)(a))<<32)|(netwib_uint64)((netwib_uint32)(b)))
#else
 #define netwib__uint64_init_8(a,b,c,d,e,f,g,h,x) (x).high = netwib_c2_uint32_4(a,b,c,d); (x).low = netwib_c2_uint32_4(e,f,g,h)
 #define netwib__uint64_init_32(a,b,x) {(x).high = (a); (x).low = (b);}
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_uint32(a,x) x = ((netwib_uint64)(a))
#else
 #define netwib__uint64_init_uint32(a,x) netwib__uint64_init_32(0,a,x)
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_uintmax(a,x) x = ((netwib_uint64)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__uint64_init_uintmax(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__uint64_init_uintmax(a,x) netwib__uint64_init_uint32(a,x)
 #endif
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_uintptr(a,x) x = ((netwib_uint64)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__uint64_init_uintptr(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__uint64_init_uintptr(a,x) netwib__uint64_init_uint32(a,x)
 #endif
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int64_init_int32(a,x) x = ((netwib_int64)(netwib_int32)(a))
#else
 #define netwib__int64_init_int32(a,x) { if ((netwib_int32)(a) >= 0) { (x).high = 0; (x).low = (netwib_uint32)(a); } else { (x).high = 0xFFFFFFFFu; (x).low = (netwib_uint32)(netwib_int32)(a); } }
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int64_init_intmax(a,x) x = ((netwib_int64)(netwib_intmax)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__int64_init_intmax(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__int64_init_intmax(a,x) netwib__int64_init_int32(a,x)
 #endif
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int64_init_intptr(a,x) x = ((netwib_int64)(netwib_intptr)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__int64_init_intptr(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__int64_init_intptr(a,x) netwib__int64_init_int32(a,x)
 #endif
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint32_init_uint64(a,x) x = ((netwib_uint32)(a))
#else
 #define netwib__uint32_init_uint64(a,x) x = ((a).low)
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uintmax_init_uint64(a,x) x = ((netwib_uintmax)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__uintmax_init_uint64(a,x) x = (((netwib_uintmax)((netwib_uint32)((a).high))<<32)|(netwib_uint64)((netwib_uint32)((a).low)))
 #else
  #define netwib__uintmax_init_uint64(a,x) x = ((netwib_uintmax)(a).low)
 #endif
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uintptr_init_uint64(a,x) x = ((netwib_uintptr)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__uintptr_init_uint64(a,x) x = (((netwib_uintptr)((netwib_uint32)((a).high))<<32)|(netwib_uintptr)((netwib_uint32)((a).low)))
 #else
  #define netwib__uintptr_init_uint64(a,x) x = ((netwib_uintptr)(a).low)
 #endif
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int32_init_int64(a,x) x = ((netwib_int32)(a))
#else
 #define netwib__int32_init_int64(a,x) x = ((netwib_int32)(a).low)
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__intmax_init_int64(a,x) x = ((netwib_intmax)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__intmax_init_int64(a,x) x = (((netwib_intmax)((netwib_uint32)((a).high))<<32)|(netwib_uintmax)((netwib_uint32)((a).low)))
 #else
  #define netwib__intmax_init_int64(a,x) x = ((netwib_intmax)(a).low)
 #endif
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__intptr_init_int64(a,x) x = ((netwib_intptr)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__intptr_init_int64(a,x) x = (((netwib_intptr)((netwib_uint32)((a).high))<<32)|(netwib_uintptr)((netwib_uint32)((a).low)))
 #else
  #define netwib__intptr_init_int64(a,x) x = ((netwib_intptr)(a).low)
 #endif
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_add(a,b,x) x = (netwib_uint64)(a) + (netwib_uint64)(b);
#else
  #define netwib__uint64_add(a,b,x) { netwib_uint32 netwib__uint64_add_tmp, netwib__uint64_add_carry; netwib__uint64_add_tmp = (a).low + (b).low; netwib__uint64_add_carry = (netwib__uint64_add_tmp < (a).low) ? 1 : 0; (x).low = netwib__uint64_add_tmp; (x).high = (a).high + (b).high + netwib__uint64_add_carry; }
#endif
#define netwib__int64_add(a,b,x) netwib__uint64_add(a,b,x)

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_sub(a,b,x) x = (netwib_uint64)(a) - (netwib_uint64)(b);
#else
  #define netwib__uint64_sub(a,b,x) { netwib_uint32 netwib__uint64_add_tmp, netwib__uint64_add_carry; netwib__uint64_add_tmp = (a).low - (b).low; netwib__uint64_add_carry = (netwib__uint64_add_tmp > (a).low) ? 1 : 0; (x).low = netwib__uint64_add_tmp; (x).high = (a).high - (b).high - netwib__uint64_add_carry; }
#endif
#define netwib__int64_sub(a,b,x) netwib__uint64_sub(a,b,x)

/*-------------------------------------------------------------*/
void netwib__uint64_mul_private(netwib_uint64 a,
                                netwib_uint64 b,
                                netwib_uint64 *px);
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_mul(a,b,px) *(px) = (netwib_uint64)(a) * (netwib_uint64)(b)
#else
  #define netwib__uint64_mul(a,b,px) netwib__uint64_mul_private(a,b,px)
#endif
#define netwib__int64_mul(a,b,px) netwib__uint64_mul(a,b,px)

/*-------------------------------------------------------------*/
void netwib__uint64_div_private(netwib_uint64 a,
                                netwib_uint64 b,
                                netwib_uint64 *pq,
                                netwib_uint64 *pr);
void netwib__int64_div_private(netwib_int64 a,
                               netwib_int64 b,
                               netwib_int64 *pq,
                               netwib_int64 *pr);
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_div(a,b,pq,pr) { netwib_uint64 netwib__uint64_div_tmp; netwib__uint64_div_tmp = (netwib_uint64)(a) / (netwib_uint64)(b); *(pr) = (netwib_uint64)(a) % (netwib_uint64)(b); *(pq) = netwib__uint64_div_tmp; }
  #define netwib__int64_div(a,b,pq,pr) { netwib_int64 netwib__int64_div_tmp; netwib__int64_div_tmp = (netwib_int64)(a) / (netwib_int64)(b); *(pr) = (netwib_int64)(a) % (netwib_int64)(b); *(pq) = netwib__int64_div_tmp; }
#else
  #define netwib__uint64_div(a,b,pq,pr) netwib__uint64_div_private(a,b,pq,pr)
  #define netwib__int64_div(a,b,pq,pr) netwib__int64_div_private(a,b,pq,pr)
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_inc(x) x = (netwib_uint64)(x) + 1;
#else
  #define netwib__uint64_inc(x) { if ((x).low == 0xFFFFFFFFu) { (x).high++; (x).low = 0; } else { (x).low++; } }
#endif
#define netwib__int64_inc(x) netwib__uint64_inc(x)

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_dec(x) x = (netwib_uint64)(x) - 1;
#else
  #define netwib__uint64_dec(x) { if ((x).low == 0) { (x).high--; (x).low = 0xFFFFFFFFu; } else { (x).low--; } }
#endif
#define netwib__int64_dec(x) netwib__uint64_dec(x)

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_cmp_eq(a,b) ((netwib_uint64)(a) == (netwib_uint64)(b))
  #define netwib__uint64_cmp_ne(a,b) ((netwib_uint64)(a) != (netwib_uint64)(b))
  #define netwib__uint64_cmp_lt(a,b) ((netwib_uint64)(a) < (netwib_uint64)(b))
  #define netwib__uint64_cmp_le(a,b) ((netwib_uint64)(a) <= (netwib_uint64)(b))
  #define netwib__uint64_cmp_gt(a,b) ((netwib_uint64)(a) > (netwib_uint64)(b))
  #define netwib__uint64_cmp_ge(a,b) ((netwib_uint64)(a) >= (netwib_uint64)(b))
  #define netwib__int64_cmp_eq(a,b) ((netwib_int64)(a) == (netwib_int64)(b))
  #define netwib__int64_cmp_ne(a,b) ((netwib_int64)(a) != (netwib_int64)(b))
  #define netwib__int64_cmp_lt(a,b) ((netwib_int64)(a) < (netwib_int64)(b))
  #define netwib__int64_cmp_le(a,b) ((netwib_int64)(a) <= (netwib_int64)(b))
  #define netwib__int64_cmp_gt(a,b) ((netwib_int64)(a) > (netwib_int64)(b))
  #define netwib__int64_cmp_ge(a,b) ((netwib_int64)(a) >= (netwib_int64)(b))
#else
  #define netwib__uint64_cmp_eq(a,b) ( ((a).high == (b).high) && ((a).low == (b).low) )
  #define netwib__uint64_cmp_ne(a,b) ( ((a).high != (b).high) || ((a).low != (b).low) )
  #define netwib__uint64_cmp_lt(a,b) ( ((a).high < (b).high) || ( ((a).high == (b).high) && ((a).low < (b).low) ) )
  #define netwib__uint64_cmp_le(a,b) ( ((a).high < (b).high) || ( ((a).high == (b).high) && ((a).low <= (b).low) ) )
  #define netwib__uint64_cmp_gt(a,b) ( ((a).high > (b).high) || ( ((a).high == (b).high) && ((a).low > (b).low) ) )
  #define netwib__uint64_cmp_ge(a,b) ( ((a).high > (b).high) || ( ((a).high == (b).high) && ((a).low >= (b).low) ) )
  #define netwib__int64_cmp_eq(a,b) ( ((a).high == (b).high) && ((a).low == (b).low) )
  #define netwib__int64_cmp_ne(a,b) ( ((a).high != (b).high) || ((a).low != (b).low) )
  #define netwib__int64_cmp_lt(a,b) ( ((netwib_int32)(a).high < (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low < (netwib_int32)(b).low) ) )
  #define netwib__int64_cmp_le(a,b) ( ((netwib_int32)(a).high < (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low <= (netwib_int32)(b).low) ) )
  #define netwib__int64_cmp_gt(a,b) ( ((netwib_int32)(a).high > (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low > (netwib_int32)(b).low) ) )
  #define netwib__int64_cmp_ge(a,b) ( ((netwib_int32)(a).high > (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low >= (netwib_int32)(b).low) ) )
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__int64_neg(a,x) x = -(netwib_int64)(a);
#else
  #define netwib__int64_neg(a,x) { (x).high = ~(a).high; (x).low = ~(a).low; netwib__uint64_inc(x); }
#endif


/*-------------------------------------------------------------*/
/* For shl, shr, rol and rol, I encountered several problems with gcc
   on 32 bit architectures:
    - x << 64 = zero with "gcc -O"
    - x << 64 = unchanged with "gcc -O2"
   There are also problems under Solaris Sparc, with rol(0).
   I decided to normalize to have a coherent behavior.
*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_shl(a,n,x) { netwib_uint32 netwib__uint64_shl_n = (n); if (netwib__uint64_shl_n == 0) { (x) = (a); } else if (netwib__uint64_shl_n >= 64) { (x) = 0; } else {(x) = (a) << netwib__uint64_shl_n;} }
#else
  #define netwib__uint64_shl(a,n,x) { netwib_uint32 netwib__uint64_shl_tmp, netwib__uint64_shl_n = n; if (netwib__uint64_shl_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_shl_n >= 64) { (x).high = 0; (x).low = 0; } else if (netwib__uint64_shl_n < 32) { netwib__uint64_shl_tmp = (a).high << netwib__uint64_shl_n | ((a).low >> (32 - netwib__uint64_shl_n)); (x).low = (a).low << netwib__uint64_shl_n; (x).high = netwib__uint64_shl_tmp; } else { netwib__uint64_shl_n -= 32; (x).high = (a).low << netwib__uint64_shl_n ; (x).low = 0; } }
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_shr(a,n,x) { netwib_uint32 netwib__uint64_shr_n = (n);  if (netwib__uint64_shr_n == 0) { (x) = (a); } else if (netwib__uint64_shr_n >= 64) { (x) = 0; } else { x = (a) >> netwib__uint64_shr_n; } }
#else
  #define netwib__uint64_shr(a,n,x) { netwib_uint32 netwib__uint64_shr_tmp, netwib__uint64_shr_n = n; if (netwib__uint64_shr_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_shr_n >= 64) { (x).high = 0; (x).low = 0; } else if (netwib__uint64_shr_n < 32) { netwib__uint64_shr_tmp = (a).low >> netwib__uint64_shr_n | ((a).high << (32 - netwib__uint64_shr_n)); (x).high = (a).high >> netwib__uint64_shr_n; (x).low = netwib__uint64_shr_tmp; } else { netwib__uint64_shr_n -= 32; (x).low = (a).high >> netwib__uint64_shr_n; (x).high = 0; } }
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_rol(a,n,x) { netwib_uint32 netwib__uint64_rol_n = (n)%64; if (netwib__uint64_rol_n == 0) { x = (a); } else { x = ((netwib_uint64)( (netwib_uint64)((a)<<netwib__uint64_rol_n) | (netwib_uint64)((a)>>(64-netwib__uint64_rol_n)) )); } }
#else
  #define netwib__uint64_rol(a,n,x) { netwib_uint32 netwib__uint64_rol_tmp, netwib__uint64_rol_n = (n)%64; if (netwib__uint64_rol_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_rol_n < 32) { netwib__uint64_rol_tmp = (a).high << netwib__uint64_rol_n | ((a).low >> (32 - netwib__uint64_rol_n)); (x).low = (a).low << netwib__uint64_rol_n | ((a).high >> (32 - netwib__uint64_rol_n)); (x).high = netwib__uint64_rol_tmp; } else { netwib__uint64_rol_n -= 32; netwib__uint64_rol_tmp = (a).low << netwib__uint64_rol_n | ((a).high >> (32 - netwib__uint64_rol_n)); (x).low = (a).high << netwib__uint64_rol_n | ((a).low >> (32 - netwib__uint64_rol_n)); (x).high = netwib__uint64_rol_tmp; } }
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_ror(a,n,x) { netwib_uint32 netwib__uint64_ror_n = (n)%64; if (netwib__uint64_ror_n == 0) { x = (a); } else { x = ((netwib_uint64)( (netwib_uint64)((a)>>netwib__uint64_ror_n) | (netwib_uint64)((a)<<(64-netwib__uint64_ror_n)) )); } }
#else
  #define netwib__uint64_ror(a,n,x) { netwib_uint32 netwib__uint64_ror_tmp, netwib__uint64_ror_n = (n)%64; if (netwib__uint64_ror_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_ror_n < 32) { netwib__uint64_ror_tmp = (a).low >> netwib__uint64_ror_n | ((a).high << (32 - netwib__uint64_ror_n)); (x).high = (a).high >> netwib__uint64_ror_n | ((a).low << (32 - netwib__uint64_ror_n)); (x).low = netwib__uint64_ror_tmp; } else { netwib__uint64_ror_n -= 32; netwib__uint64_ror_tmp = (a).high >> netwib__uint64_ror_n | ((a).low << (32 - netwib__uint64_ror_n)); (x).high = (a).low >> netwib__uint64_ror_n | ((a).high << (32 - netwib__uint64_ror_n)); (x).low = netwib__uint64_ror_tmp;} }
#endif


/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_and(a,b,x) x = (netwib_uint64)(a) & (netwib_uint64)(b);
#else
  #define netwib__uint64_and(a,b,x) { (x).high = (a).high & (b).high; (x).low = (a).low & (b).low; }
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_or(a,b,x) x = (netwib_uint64)(a) | (netwib_uint64)(b);
#else
  #define netwib__uint64_or(a,b,x) { (x).high = (a).high | (b).high; (x).low = (a).low | (b).low; }
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_xor(a,b,x) x = (netwib_uint64)(a) ^ (netwib_uint64)(b);
#else
  #define netwib__uint64_xor(a,b,x) { (x).high = (a).high ^ (b).high; (x).low = (a).low ^ (b).low; }
#endif

/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_not(a,x) x = ~(netwib_uint64)(a);
#else
  #define netwib__uint64_not(a,x) { (x).high = ~(a).high; (x).low = ~(a).low; }
#endif


/*-------------------------------------------------------------*/
/* To represent values > 0xFFFFFFFF :
    - some Unixes (Solaris, HP-UX) need 0xf....fLL
    - Windows does not support LL
 */
#if defined NETWIBDEF_SYSNAME_Unix
  #define NETWIB_UINT_LL(x) (x ## LLU)
  #define NETWIB_INT_LL(x) (x ## LL)
#elif defined NETWIBDEF_SYSNAME_Windows
  #define NETWIB_UINT_LL(x) (x)
  #define NETWIB_INT_LL(x) (x)
#else
  #error "Unknown value for NETWIBDEF_SYSNAME"
#endif


/*-------------------------------------------------------------*/
/* To initialize a static variable */
#if NETWIB_INT64_FAKE == 0
  #define NETWIB_UINT_STATIC(ahigh,alow) (((netwib_uint64)((netwib_uint32)(ahigh))<<32)|(netwib_uint64)((netwib_uint32)(alow)))
  #define NETWIB_INT_STATIC(ahigh,alow) (((netwib_int64)((netwib_uint32)(ahigh))<<32)|(netwib_uint64)((netwib_uint32)(alow)))
#else
  #define NETWIB_UINT_STATIC(ahigh,alow) {(ahigh), (alow)}
  #define NETWIB_INT_STATIC(ahigh,alow) {(ahigh), (alow)}
#endif




main index

section index