/*
 * @(#)typedefs_md.h     1.6 95/04/10
 *
 * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 */

/*
 * OS dependent type definitions
 */

#ifndef _OS2_TYPEDEF_MD_H_
#define _OS2_TYPEDEF_MD_H_

/* Macros for when the compiler supports the long long type are below */
/* Define 'INT64' to use them instead of the function package */

#ifndef INT64

#include "int64_md.h"              /* IBM INT64 package */

/* The following already existed [in system_md.c, math_md.c] */
/* [they call items in int64_md.c, now */
extern void ll2str(int64_t a, char *s, char *limit);
extern int64_t atoll(char *);

#else /* INT64 defined */

/* use these macros when the compiler supports the long long type */
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;


#define ll_high(a)       ((long)((a)>>32))
#define ll_low(a)        ((long)(a))
#define int2ll(a)        ((int64_t)(a))
#define ll2int(a)        ((int)(a))
#define ll_add(a, b)     ((a) + (b))
#define ll_and(a, b)     ((a) & (b))
#define ll_div(a, b)     ((a) / (b))
#define ll_mul(a, b)     ((a) * (b))
#define ll_neg(a)        (-(a))
#define ll_not(a)        (~(a))
#define ll_or(a, b)      ((a) | (b))
/* THE FOLLOWING DEFINITION IS NOW A FUNCTION CALL IN ORDER TO WORKAROUND
   OPTIMIZER BUG IN MSVC++ 2.1 (see system_md.c)
/* #define ll_shl(a, n)  ((a) << (n)) */
#define ll_shr(a, n)     ((a) >> (n))
#define ll_sub(a, b)     ((a) - (b))
#define ll_ushr(a, n)    ((uint64_t)(a) >> (n))
#define ll_xor(a, b)     ((a) ^ (b))
#define uint2ll(a)       ((uint64_t)(unsigned long)(a))
#define ll_mod(a,b)      ((a) % (b))

#define float2ll(f)      ((int64_t) (f))
#define ll2float(a)      ((float) (a))
#define ll2double(a)     ((double) (a))
#define double2ll(f)     ((int64_t) (f))

/* comparison operators */
#define ll_ltz(ll)       ((ll) < 0)
#define ll_gez(ll)       ((ll) >= 0)
#define ll_eqz(a)        ((a) == 0)
#define ll_eq(a, b)      ((a) == (b))
#define ll_ne(a,b)       ((a) != (b))
#define ll_ge(a,b)       ((a) >= (b))
#define ll_le(a,b)       ((a) <= (b))
#define ll_lt(a,b)       ((a) < (b))
#define ll_gt(a,b)       ((a) > (b))

#define ll_zero_const    ((int64_t) 0)
#define ll_one_const     ((int64_t) 1)

extern void ll2str(int64_t a, char *s, char *limit);
extern int64_t ll_shl(int64_t a, int bits);
#endif /* !INT64 */

/* [1a3] Comment out the following four lines if your compiler/machine
 * insists that doubles and int64_t's be aligned on 0 mod 8 boundaries.
 * The java interpreter only insists that the be on 0 mod 4 boundaries.
 *
 * If you comment out the following defines, be sure than an assembly
 * language definition exists.  See solaris/java/runtime/double_md.s for an
 * implementation on Sparc.
 */

#define GET_DOUBLE(address) (*(double *)(address))
#define GET_INT64(address)  (*(int64_t *)(address))
#define SET_DOUBLE(address, value) ((*(double *)(address)) = (value))
#define SET_INT64(address, value) ((*(int64_t *)(address)) = (value))

#endif /* !_OS2_TYPEDEF_MD_H_ */
