/*
 * @(#)int64_md.h    0.0 95/07/23
 *
 * Copyright (c) 1995 International Business Machines Corporation.
 * All Rights Reserved.
 *
 * These are the headers for the int64 package.
 *
 * Define x86 for use with little-endian (Intel) software
 *
 */

#ifndef _INT64_H_
#define _INT64_H_

/* 64-bit integer structures (big or little-endian).  */
#ifdef x86
  /* Little-endian */
  #define CONST64(hi, lo) {lo, hi}

  /* Note these *must* be fully little-endian */
  /* so union with double float (and back) will work. */
  typedef struct Int64 {           /* a 64-bit integer */
    long lo;                       /* low  32 bits [little-endian] */
    long hi;                       /* high 32 bits */
    } int64_t, *Pint64_t;

  typedef struct UInt64 {          /* an unsigned  64-bit integer  */
    long lo;                       /* low  32 bits [little-endian] */
    long hi;                       /* high 32 bits */
    } uint64_t, *Puint64_t;

#else
  /* Big-endian */
  #define CONST64(hi, lo) {hi, lo}
  typedef struct Int64 {             /* a 64-bit integer */
    long hi;                         /* high 32 bits */
    long lo;                         /* low  32 bits [big-endian] */
    } int64_t, *Pint64_t;

  typedef struct UInt64 {            /* an unsigned  64-bit integer  */
    long hi;                         /* high 32 bits */
    long lo;                         /* low  32 bits [big-endian] */
    } uint64_t, *Puint64_t;
#endif

/* easy ones */
#define ll_high(a)  ((a).hi)            /* ((long)((a)>>32))               */
#define ll_low(a)   ((a).lo)            /* ((long)(a))                     */
#define ll2int(a)   ((signed int)(a).lo)/* ((int)(a))                      */
/* [many others, especially comparisons, could be macros too] */

/* The following refer to functions or statics in int64_md.c */
extern int64_t int2ll(int)             ;/* ((int64_t)(a))                  */
extern int64_t ll_add(int64_t, int64_t);/* ((a) + (b))                     */
extern int64_t ll_and(int64_t, int64_t);/* ((a) & (b))                     */
extern int64_t ll_div(int64_t, int64_t);/* ((a) / (b))                     */
extern int64_t ll_mul(int64_t, int64_t);/* ((a) * (b))                     */
extern int64_t ll_neg(int64_t)         ;/* (-(a))                          */
extern int64_t ll_not(int64_t)         ;/* (~(a))                          */
extern int64_t ll_or(int64_t, int64_t) ;/* ((a) | (b))                     */
extern int64_t ll_shl(int64_t, int)    ;/* ((a) << (n))                    */
extern int64_t ll_shr(int64_t, int)    ;/* ((a) >> (n))                    */
extern int64_t ll_sub(int64_t, int64_t);/* ((a) - (b))                     */
extern int64_t ll_ushr(int64_t, int)   ;/* ((uint64_t)(a) >> (n))          */
extern int64_t ll_xor(int64_t, int64_t);/* ((a) ^ (b))                     */
extern int64_t uint2ll(unsigned long)  ;/* ((uint64_t)(unsigned long)(a))  */
extern int64_t ll_mod(int64_t,int64_t) ;/* ((a) % (b))                     */

extern int64_t float2ll(float)         ;/* ((int64_t) (f))                 */
extern float   ll2float(int64_t)       ;/* ((float) (a))                   */
extern double  ll2double(int64_t)      ;/* ((double) (a))                  */
extern int64_t double2ll(double)       ;/* ((int64_t) (f))                 */

/* comparison operators */
extern int ll_ltz(int64_t)             ;/* ((ll)<0)                        */
extern int ll_gez(int64_t)             ;/* ((ll)>=0)                       */
extern int ll_eqz(int64_t)             ;/* ((a) == 0)                      */
extern int ll_eq(int64_t, int64_t)     ;/* ((a) == (b))                    */
extern int ll_ne(int64_t, int64_t)     ;/* !l_leq(a,b)                     */
extern int ll_ge(int64_t, int64_t)     ;/* ll_gez(ll_sub(a,b))             */
extern int ll_le(int64_t, int64_t)     ;/* ll_gez(ll_sub(b,a))             */
extern int ll_lt(int64_t, int64_t)     ;/* ll_ltz(ll_sub(a,b))             */
extern int ll_gt(int64_t, int64_t)     ;/* ll_ltz(ll_sub(b,a))             */

/* constants */
extern int64_t ll_zero_const;          ;/* ((int64_t) 0)                   */
extern int64_t ll_one_const;           ;/* ((int64_t) 1)                   */
extern int64_t ll_bad_const;           ;/* ((int64_t) 0x80000000 00000000  */

/* to/from strings */
int64_t string2ll(char *)              ;/* atol-like, with checking        */
int     ll2string(int64_t, char *, int);/* lay out number, with checking   */


#endif /* !_INT64_H_ */
