[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 19991220: CRAY SV1 (UNICOS 10.0.0.6): non-constant array size in ncx_cray.c



Fabien,

>Date: Tue, 28 Dec 1999 12:01:25 +0100 (MET)
>From: Fabien Durand <address@hidden>
>Organization: LEGOS/GRGS
>To: address@hidden
>Subject: Re: 19991220: CRAY SV1 (UNICOS 10.0.0.6): non-constant array size in 
>ncx_cray.c 
>Keywords: 199912201654.JAA02346

In the above message, you wrote:

> There might be a problem with this new version. Please look at the
> error message I obtained when running "make" (file "cpterendu"
> attached).
> Thanks a lot for your help.
> 
> Regards,
>  
> Fabien Durand
> LEGOS/GRGS
> 14 Avenue E.Belin
> 31400 Toulouse
> tel 05 61 33 29 56
> mail : address@hidden
> 
> --Pack_of_Dogs_457_000
> Content-Type: TEXT/plain; name=cpterendu; charset=US-ASCII; x-unix-mode=0644
> Content-Description: cpterendu
> UNKNOWN: SFv8FpSDgNj0u4O4e8exFQ==
> Content-Transfer-Encoding: QUOTED-PRINTABLE
> 
> Script started on Tue Dec 28 10:40:54 1999
> [/dev/ttyp014]
> jedi-ci:/tmp/durandf/netcdf-3.5/src $ make
> 
> Making `all' in directory /tmp/durandf/netcdf-3.5/src/libsrc
> 
> =09c89 -c -O -I.  -DNDEBUG ncx.c
> CC-20 c89: ERROR File =3D ncx.c, Line =3D 3462
>   The identifier "NC_ENOMEM" is undefined.
> 
>   =09=09=09return NC_ENOMEM;
>   =09=09=09       ^

You're right.  File "ncx_cray.c" needed some more modifications,
and also the file "ncx.h".  I've enclosed both of them (search for
"--------Begin").  Thank you for doing the compiling (I don't have a
Cray :-( ).

Let me know how they work.

Regards,
Steve Emmerson   <http://www.unidata.ucar.edu>

--------Begin ncx.h
/*
 *      Copyright 1996, University Corporation for Atmospheric Research
 *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
 */
/* "$Id: ncx.h,v 1.52 1997/06/04 22:27:12 davis Exp $" */

#ifndef _NCX_H_
#define _NCX_H_

/*
 * An external data representation interface.
 *
 * This started out as a general replacement for ONC XDR,
 * specifically, the xdrmem family of functions.
 * 
 * We eventually realized that we could write more portable
 * code if we decoupled any association between the 'C' types
 * and the external types. (XDR has this association between the 'C'
 * types and the external representations, like xdr_int() takes
 * an int argument and goes to an external int representation.) 
 * So, now there is a matrix of functions.
 * 
 */

#include "ncconfig.h" /* output of 'configure' */
#include "rnd.h"
#include <stddef.h> /* size_t */
#include <errno.h>
#include <sys/types.h> /* off_t */

#if defined(_CRAY) && !defined(_CRAYIEEE)
#define CRAYFLOAT 1 /* CRAY Floating point */
#elif defined(_SX) && defined(_FLOAT2)  /* NEC SUPER-UX in CRAY mode */
#define CRAYFLOAT 1 /* CRAY Floating point */
#endif

/*
 * The integer return code for the conversion routines
 * is 0 (ENOERR) when no error occured, or NC_ERANGE as appropriate
 * for an overflow conversion.
 */
#ifndef ENOERR
#define ENOERR 0
#endif
#ifndef NC_ERANGE
#define NC_ERANGE (-60) /* N.B. must match value in netcdf.h */
#endif
#ifndef NC_ENOMEM
#define NC_ENOMEM (-61) /* N.B. must match value in netcdf.h */
#endif


/*
 * External sizes of the primitive elements.
 */
#define X_SIZEOF_CHAR           1
#define X_SIZEOF_SHORT          2
#define X_SIZEOF_INT            4       /* xdr_int */
#if 0
#define X_SIZEOF_LONG           8 */    /* xdr_long_long */
#endif
#define X_SIZEOF_FLOAT          4
#define X_SIZEOF_DOUBLE         8

/*
 * For now, netcdf is limited to 32 bit offsets and sizes,
 *  see also X_SIZE_MAX, X_OFF_MAX below
 */
#define X_SIZEOF_OFF_T          X_SIZEOF_INT
#define X_SIZEOF_SIZE_T         X_SIZEOF_INT

/*
 * limits of the external representation
 */
#define X_SCHAR_MIN     (-128)
#define X_SCHAR_MAX     127
#define X_UCHAR_MAX     255U
#define X_SHORT_MIN     (-32768)
#define X_SHRT_MIN      X_SHORT_MIN     /* alias compatible with limits.h */
#define X_SHORT_MAX     32767
#define X_SHRT_MAX      X_SHORT_MAX     /* alias compatible with limits.h */
#define X_USHORT_MAX    65535U
#define X_USHRT_MAX     X_USHORT_MAX    /* alias compatible with limits.h */
#define X_INT_MIN       (-2147483647-1)
#define X_INT_MAX       2147483647
#define X_UINT_MAX      4294967295U
#if 0
#define X_LONG_MIN      (-2147483647-1)
#define X_LONG_MAX      2147483647
#define X_ULONG_MAX     4294967295U
#endif
#define X_FLOAT_MAX     3.40282347e+38f
#define X_FLOAT_MIN     (-X_FLOAT_MAX)
#define X_FLT_MAX       X_FLOAT_MAX     /* alias compatible with limits.h */
#if CRAYFLOAT
/* ldexp(1. - ldexp(.5 , -46), 1024) */
#define X_DOUBLE_MAX    1.79769313486230e+308
#else
/* scalb(1. - scalb(.5 , -52), 1024) */
#define X_DOUBLE_MAX    1.7976931348623157e+308 
#endif
#define X_DOUBLE_MIN    (-X_DOUBLE_MAX)
#define X_DBL_MAX       X_DOUBLE_MAX    /* alias compatible with limits.h */

#define X_SIZE_MAX      X_INT_MAX       /* N.B., just uses the signed range */
#define X_OFF_MAX       X_INT_MAX


/* Begin ncx_len */

/*
 * ncx_len_xxx() interfaces are defined as macros below, 
 * These give the length of an array of nelems of the type.
 * N.B. The 'char' and 'short' interfaces give the X_ALIGNED length.
 */
#define X_ALIGN                 4       /* a.k.a. BYTES_PER_XDR_UNIT */

#define ncx_len_char(nelems) \
        _RNDUP((nelems), X_ALIGN)

#define ncx_len_short(nelems) \
        (((nelems) + (nelems)%2)  * X_SIZEOF_SHORT)

#define ncx_len_int(nelems) \
        ((nelems) * X_SIZEOF_INT)

#define ncx_len_long(nelems) \
        ((nelems) * X_SIZEOF_LONG)

#define ncx_len_float(nelems) \
        ((nelems) * X_SIZEOF_FLOAT)

#define ncx_len_double(nelems) \
        ((nelems) * X_SIZEOF_DOUBLE)

/* End ncx_len */

#if __CHAR_UNSIGNED__
        /* 'char' is unsigned, declare ncbyte as 'signed char' */
typedef signed char schar;

#else
        /* 'char' is signed */
typedef signed char schar;

#endif  /* __CHAR_UNSIGNED__ */

/*
 * Primitive numeric conversion functions.
 * The `put' functions convert from native internal
 * type to the external type, while the `get' functions
 * convert from the external to the internal.
 *
 * These take the form
 *      int ncx_get_{external_type}_{internal_type}(
 *              const void *xp,
 *              internal_type *ip
 *      );
 *      int ncx_put_{external_type}_{internal_type}(
 *              void *xp,
 *              const internal_type *ip
 *      );
 * where
 *      `external_type' and `internal_type' chosen from
                schar
                uchar
                short
                ushort
                int
                uint
                long
                ulong
                float
                double
 *
 * Not all combinations make sense.
 * We may not implement all combinations that make sense.
 * The netcdf functions that use this ncx interface don't
 * use these primitive conversion functions. They use the
 * aggregate conversion functions declared below.
 *
 * Storage for a single element of external type is at the `void * xp'
 * argument.
 *
 * Storage for a single element of internal type is at `ip' argument.
 *
 * These functions return 0 (ENOERR) when no error occured,
 * or NC_ERANGE when the value being converted is too large.
 * When NC_ERANGE occurs, an undefined (implementation dependent)
 * conversion may have occured.
 *
 * Note that loss of precision may occur silently.
 *
 */

#if 0
extern int
ncx_get_schar_schar(const void *xp, schar *ip);
extern int
ncx_get_schar_uchar(const void *xp, uchar *ip);
extern int
ncx_get_schar_short(const void *xp, short *ip);
extern int
ncx_get_schar_int(const void *xp, int *ip);
extern int
ncx_get_schar_long(const void *xp, long *ip);
extern int
ncx_get_schar_float(const void *xp, float *ip);
extern int
ncx_get_schar_double(const void *xp, double *ip);

extern int
ncx_put_schar_schar(void *xp, const schar *ip);
extern int
ncx_put_schar_uchar(void *xp, const uchar *ip);
extern int
ncx_put_schar_short(void *xp, const short *ip);
extern int
ncx_put_schar_int(void *xp, const int *ip);
extern int
ncx_put_schar_long(void *xp, const long *ip);
extern int
ncx_put_schar_float(void *xp, const float *ip);
extern int
ncx_put_schar_double(void *xp, const double *ip);
#endif
 

extern int
ncx_get_short_schar(const void *xp, schar *ip);
extern int
ncx_get_short_uchar(const void *xp, uchar *ip);
extern int
ncx_get_short_short(const void *xp, short *ip);
extern int
ncx_get_short_int(const void *xp, int *ip);
extern int
ncx_get_short_long(const void *xp, long *ip);
extern int
ncx_get_short_float(const void *xp, float *ip);
extern int
ncx_get_short_double(const void *xp, double *ip);

extern int
ncx_put_short_schar(void *xp, const schar *ip);
extern int
ncx_put_short_uchar(void *xp, const uchar *ip);
extern int
ncx_put_short_short(void *xp, const short *ip);
extern int
ncx_put_short_int(void *xp, const int *ip);
extern int
ncx_put_short_long(void *xp, const long *ip);
extern int
ncx_put_short_float(void *xp, const float *ip);
extern int
ncx_put_short_double(void *xp, const double *ip);
 

extern int
ncx_get_int_schar(const void *xp, schar *ip);
extern int
ncx_get_int_uchar(const void *xp, uchar *ip);
extern int
ncx_get_int_short(const void *xp, short *ip);
extern int
ncx_get_int_int(const void *xp, int *ip);
extern int
ncx_get_int_long(const void *xp, long *ip);
extern int
ncx_get_int_float(const void *xp, float *ip);
extern int
ncx_get_int_double(const void *xp, double *ip);

extern int
ncx_put_int_schar(void *xp, const schar *ip);
extern int
ncx_put_int_uchar(void *xp, const uchar *ip);
extern int
ncx_put_int_short(void *xp, const short *ip);
extern int
ncx_put_int_int(void *xp, const int *ip);
extern int
ncx_put_int_long(void *xp, const long *ip);
extern int
ncx_put_int_float(void *xp, const float *ip);
extern int
ncx_put_int_double(void *xp, const double *ip);
 

extern int
ncx_get_float_schar(const void *xp, schar *ip);
extern int
ncx_get_float_uchar(const void *xp, uchar *ip);
extern int
ncx_get_float_short(const void *xp, short *ip);
extern int
ncx_get_float_int(const void *xp, int *ip);
extern int
ncx_get_float_long(const void *xp, long *ip);
extern int
ncx_get_float_float(const void *xp, float *ip);
extern int
ncx_get_float_double(const void *xp, double *ip);

extern int
ncx_put_float_schar(void *xp, const schar *ip);
extern int
ncx_put_float_uchar(void *xp, const uchar *ip);
extern int
ncx_put_float_short(void *xp, const short *ip);
extern int
ncx_put_float_int(void *xp, const int *ip);
extern int
ncx_put_float_long(void *xp, const long *ip);
extern int
ncx_put_float_float(void *xp, const float *ip);
extern int
ncx_put_float_double(void *xp, const double *ip);
 

extern int
ncx_get_double_schar(const void *xp, schar *ip);
extern int
ncx_get_double_uchar(const void *xp, uchar *ip);
extern int
ncx_get_double_short(const void *xp, short *ip);
extern int
ncx_get_double_int(const void *xp, int *ip);
extern int
ncx_get_double_long(const void *xp, long *ip);
extern int
ncx_get_double_float(const void *xp, float *ip);
extern int
ncx_get_double_double(const void *xp, double *ip);

extern int
ncx_put_double_schar(void *xp, const schar *ip);
extern int
ncx_put_double_uchar(void *xp, const uchar *ip);
extern int
ncx_put_double_short(void *xp, const short *ip);
extern int
ncx_put_double_int(void *xp, const int *ip);
extern int
ncx_put_double_long(void *xp, const long *ip);
extern int
ncx_put_double_float(void *xp, const float *ip);
extern int
ncx_put_double_double(void *xp, const double *ip);
 

/*
 * Other primitive conversion functions
 * N.B. slightly different interface
 * Used by netcdf.
 */

/* ncx_get_int_size_t */
extern int
ncx_get_size_t(const void **xpp, size_t *ulp);
/* ncx_get_int_off_t */
extern int
ncx_get_off_t(const void **xpp, off_t *lp);

/* ncx_put_int_size_t */
extern int
ncx_put_size_t(void **xpp, const size_t *ulp);
/* ncx_put_int_off_t */
extern int
ncx_put_off_t(void **xpp, const off_t *lp);


/*
 * Aggregate numeric conversion functions.
 * Convert an array.  Replaces xdr_array(...).
 * These functions are used by netcdf. Unlike the xdr
 * interface, we optimize for aggregate conversions.
 * This functions should be implemented to take advantage
 * of multiple processor / parallel hardware where available.
 *
 * These take the form
 *      int ncx_getn_{external_type}_{internal_type}(
 *              const void *xpp,
 *              size_t nelems,
 *              internal_type *ip
 *      );
 *      int ncx_putn_{external_type}_{internal_type}(
 *              void **xpp,
 *              size_t nelems,
 *              const internal_type *ip
 *      );
 * Where the types are as in the primitive numeric conversion functions.
 *
 * The value of the pointer to pointer argument, *xpp, is
 * expected to reference storage for `nelems' of the external
 * type.  On return, it modified to reference just past the last
 * converted external element.
 *
 * The types whose external size is less than X_ALIGN also have `pad'
 * interfaces. These round (and zero fill on put) *xpp up to X_ALIGN
 * boundaries. (This is the usual xdr behavior.)
 *
 * The `ip' argument should point to an array of `nelems' of
 * internal_type.
 *
 * Range errors (NC_ERANGE) for a individual values in the array 
 * DO NOT terminate the array conversion. All elements are converted,
 * with some having undefined values.
 * If any range error occurs, the function returns NC_ERANGE.
 *
 */

extern int
ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *ip);
extern int
ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *ip);
extern int
ncx_getn_schar_short(const void **xpp, size_t nelems, short *ip);
extern int
ncx_getn_schar_int(const void **xpp, size_t nelems, int *ip);
extern int
ncx_getn_schar_long(const void **xpp, size_t nelems, long *ip);
extern int
ncx_getn_schar_float(const void **xpp, size_t nelems, float *ip);
extern int
ncx_getn_schar_double(const void **xpp, size_t nelems, double *ip);

extern int
ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *ip);
extern int
ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *ip);
extern int
ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *ip);
extern int
ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *ip);
extern int
ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *ip);
extern int
ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *ip);
extern int
ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *ip);

extern int
ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *ip);
extern int
ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *ip);
extern int
ncx_putn_schar_short(void **xpp, size_t nelems, const short *ip);
extern int
ncx_putn_schar_int(void **xpp, size_t nelems, const int *ip);
extern int
ncx_putn_schar_long(void **xpp, size_t nelems, const long *ip);
extern int
ncx_putn_schar_float(void **xpp, size_t nelems, const float *ip);
extern int
ncx_putn_schar_double(void **xpp, size_t nelems, const double *ip);
 
extern int
ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *ip);
extern int
ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *ip);
extern int
ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *ip);
extern int
ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *ip);
extern int
ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *ip);
extern int
ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *ip);
extern int
ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *ip);


extern int
ncx_getn_short_schar(const void **xpp, size_t nelems, schar *ip);
extern int
ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *ip);
extern int
ncx_getn_short_short(const void **xpp, size_t nelems, short *ip);
extern int
ncx_getn_short_int(const void **xpp, size_t nelems, int *ip);
extern int
ncx_getn_short_long(const void **xpp, size_t nelems, long *ip);
extern int
ncx_getn_short_float(const void **xpp, size_t nelems, float *ip);
extern int
ncx_getn_short_double(const void **xpp, size_t nelems, double *ip);

extern int
ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *ip);
extern int
ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *ip);
extern int
ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *ip);
extern int
ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *ip);
extern int
ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *ip);
extern int
ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *ip);
extern int
ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *ip);

extern int
ncx_putn_short_schar(void **xpp, size_t nelems, const schar *ip);
extern int
ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *ip);
extern int
ncx_putn_short_short(void **xpp, size_t nelems, const short *ip);
extern int
ncx_putn_short_int(void **xpp, size_t nelems, const int *ip);
extern int
ncx_putn_short_long(void **xpp, size_t nelems, const long *ip);
extern int
ncx_putn_short_float(void **xpp, size_t nelems, const float *ip);
extern int
ncx_putn_short_double(void **xpp, size_t nelems, const double *ip);
 
extern int
ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *ip);
extern int
ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *ip);
extern int
ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *ip);
extern int
ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *ip);
extern int
ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *ip);
extern int
ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *ip);
extern int
ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *ip);


extern int
ncx_getn_int_schar(const void **xpp, size_t nelems, schar *ip);
extern int
ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *ip);
extern int
ncx_getn_int_short(const void **xpp, size_t nelems, short *ip);
extern int
ncx_getn_int_int(const void **xpp, size_t nelems, int *ip);
extern int
ncx_getn_int_long(const void **xpp, size_t nelems, long *ip);
extern int
ncx_getn_int_float(const void **xpp, size_t nelems, float *ip);
extern int
ncx_getn_int_double(const void **xpp, size_t nelems, double *ip);

extern int
ncx_putn_int_schar(void **xpp, size_t nelems, const schar *ip);
extern int
ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *ip);
extern int
ncx_putn_int_short(void **xpp, size_t nelems, const short *ip);
extern int
ncx_putn_int_int(void **xpp, size_t nelems, const int *ip);
extern int
ncx_putn_int_long(void **xpp, size_t nelems, const long *ip);
extern int
ncx_putn_int_float(void **xpp, size_t nelems, const float *ip);
extern int
ncx_putn_int_double(void **xpp, size_t nelems, const double *ip);
 

extern int
ncx_getn_float_schar(const void **xpp, size_t nelems, schar *ip);
extern int
ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *ip);
extern int
ncx_getn_float_short(const void **xpp, size_t nelems, short *ip);
extern int
ncx_getn_float_int(const void **xpp, size_t nelems, int *ip);
extern int
ncx_getn_float_long(const void **xpp, size_t nelems, long *ip);
extern int
ncx_getn_float_float(const void **xpp, size_t nelems, float *ip);
extern int
ncx_getn_float_double(const void **xpp, size_t nelems, double *ip);

extern int
ncx_putn_float_schar(void **xpp, size_t nelems, const schar *ip);
extern int
ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *ip);
extern int
ncx_putn_float_short(void **xpp, size_t nelems, const short *ip);
extern int
ncx_putn_float_int(void **xpp, size_t nelems, const int *ip);
extern int
ncx_putn_float_long(void **xpp, size_t nelems, const long *ip);
extern int
ncx_putn_float_float(void **xpp, size_t nelems, const float *ip);
extern int
ncx_putn_float_double(void **xpp, size_t nelems, const double *ip);
 

extern int
ncx_getn_double_schar(const void **xpp, size_t nelems, schar *ip);
extern int
ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *ip);
extern int
ncx_getn_double_short(const void **xpp, size_t nelems, short *ip);
extern int
ncx_getn_double_int(const void **xpp, size_t nelems, int *ip);
extern int
ncx_getn_double_long(const void **xpp, size_t nelems, long *ip);
extern int
ncx_getn_double_float(const void **xpp, size_t nelems, float *ip);
extern int
ncx_getn_double_double(const void **xpp, size_t nelems, double *ip);

extern int
ncx_putn_double_schar(void **xpp, size_t nelems, const schar *ip);
extern int
ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *ip);
extern int
ncx_putn_double_short(void **xpp, size_t nelems, const short *ip);
extern int
ncx_putn_double_int(void **xpp, size_t nelems, const int *ip);
extern int
ncx_putn_double_long(void **xpp, size_t nelems, const long *ip);
extern int
ncx_putn_double_float(void **xpp, size_t nelems, const float *ip);
extern int
ncx_putn_double_double(void **xpp, size_t nelems, const double *ip);
 

/*
 * Other aggregate conversion functions.
 */

/* read ASCII characters */
extern int
ncx_getn_text(const void **xpp, size_t nchars, char *cp);
extern int
ncx_pad_getn_text(const void **xpp, size_t nchars, char *cp);

/* write ASCII characters */
extern int
ncx_putn_text(void **xpp, size_t nchars, const char *cp);
extern int
ncx_pad_putn_text(void **xpp, size_t nchars, const char *cp);

/* for symmetry */
#define ncx_getn_char_char(xpp, nelems, fillp) ncx_getn_text(xpp, nelems, fillp)
#define ncx_putn_char_char(xpp, nelems, fillp) ncx_putn_text(xpp, nelems, fillp)

/* read opaque data */
extern int
ncx_getn_void(const void **xpp, size_t nchars, void *vp);
extern int
ncx_pad_getn_void(const void **xpp, size_t nchars, void *vp);

/* write opaque data */
extern int
ncx_putn_void(void **xpp, size_t nchars, const void *vp);
extern int
ncx_pad_putn_void(void **xpp, size_t nchars, const void *vp);

#endif /* _NCX_H_ */
--------Begin ncx_cray.c
/*
 *      Copyright 1996, University Corporation for Atmospheric Research
 *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
 *      
 */
/* $Id: ncx_cray.c,v 1.57 1999/12/20 18:14:36 steve Exp $ */
#ifndef _CRAY
#error "ncx_cray.c is a cray specific implementation"
#endif

/*
 * An external data representation interface.
 */
/*
 * TODO: Fix "off diagonal" functions (ncx_{put,get}[n]_t1_t2() s.t. t1 != t2)
 * to be use IEG functions when diagonals are.
 *
 * Whine to cray about IEG function limiting behavior.
 */

#include <string.h>
#include <limits.h>
/* alias poorly named limits.h macros */
#define  SHORT_MAX  SHRT_MAX
#define  SHORT_MIN  SHRT_MIN
#define USHORT_MAX USHRT_MAX
#include <float.h>
#include <assert.h>
#include "ncx.h"

/**/
#if USE_IEG
#define C_SIZE_T size_t

extern int
CRAY2IEG(
        const int *typep,
        const C_SIZE_T *nump,
        word *foreignp,
        const int *bitoffp,
        const void *local,
        const int *stride
);

extern int
IEG2CRAY(
        const int *typep,
        const C_SIZE_T *nump,
        const word *foreignp,
        const int *bitoffp,
        void *local,
        const int *stride
);


static const int Zero = 0;
static const C_SIZE_T One = 1;
static const int ThirtyTwo = 32;
static const int UnitStride = 1;
static const int Cray2_I32 = 1; /* 32 bit two complement */
static const int Cray2_F32 = 2; /* IEEE single precision */
static const int Cray2_I16 = 7; /* 16 bit twos complement */
static const int Cray2_F64 = 8; /* CRAY float to IEEE double */

#define SHORT_USE_IEG 1
#define INT_USE_IEG 1
#define FLOAT_USE_IEG 1
#define DOUBLE_USE_IEG 1

#if _CRAY1
/*
 * Return the number of bits "into" a word that (void *) is.
 * N.B. This is based on the CRAY1 (PVP) address structure,
 * which puts the address within a word in the leftmost 3 bits
 * of the address.
 */
static size_t
bitoff(const void *vp)
{
        const size_t bitoffset = ((size_t)vp >> (64 - 6)) & 0x3f;
        return bitoffset;
}
# else
#error "Don't use IEG2CRAY, CRAY2IEG except on CRAY1 (MPP) platforms"
#define bitoff(vp) ((size_t)(vp) % 64) /* N.B. Assumes 64 bit word */
# endif /* _CRAY1 */

#endif /* USE_IEG */

#if _CRAY1
/*
 * Return the number of bytes "into" a word that (void *) is.
 * N.B. This is based on the CRAY1 (PVP) address structure,
 * which puts the address within a word in the leftmost 3 bits
 * of the address.
 */
static size_t
byteoff(const void *vp)
{
        const size_t byteoffset = ((size_t)vp >> (64 - 3)) & 0x7;
        return byteoffset;
}
#else
#define byteoff(vp) ((size_t)(vp) % 8) /* N.B. Assumes 64 bit word */
#endif /* _CRAY1 */

/*
 * Return the number of bytes until the next "word" boundary
 */
static size_t
word_align(const void *vp)
{
        const size_t rem = byteoff(vp);
        if(rem == 0)
                return 0;
        return sizeof(word) - rem;
}


static const char nada[X_ALIGN] = {0, 0, 0, 0};


/*
 * Primitive numeric conversion functions.
 */

/* x_schar */

 /* We don't implement and x_schar primitives. */


/* x_short */

typedef short ix_short;
#define SIZEOF_IX_SHORT SIZEOF_SHORT
#define IX_SHORT_MAX SHORT_MAX

static void
cget_short_short(const void *xp, short *ip, int which)
{
        const long *wp = xp;

        switch(which) {
        case 0:
                *ip = (short)(*wp >> 48);
                break;
        case 1:
                *ip = (short)((*wp >> 32) & 0xffff);
                break;
        case 2:
                *ip = (short)((*wp >> 16) & 0xffff);
                break;
        case 3:
                *ip = (short)(*wp & 0xffff);
                break;
        }

        if(*ip & 0x8000)
        {
                /* extern is negative */
                *ip |= (~(0xffff));
        }
}
#define get_ix_short(xp, ip) cget_short_short((xp), (ip), 
byteoff(xp)/X_SIZEOF_SHORT)

static int
cput_short_short(void *xp, const short *ip, int which)
{
        word *wp = xp;

        switch(which) {
        case 0:
                *wp = (*ip << 48)
                            | (*wp & 0x0000ffffffffffff);
                break;
        case 1:
                *wp = ((*ip << 32) & 0x0000ffff00000000)
                            | (*wp & 0xffff0000ffffffff);
                break;
        case 2:
                *wp = ((*ip << 16) & 0x00000000ffff0000)
                            | (*wp & 0xffffffff0000ffff);
                break;
        case 3:
                *wp = (*ip         & 0x000000000000ffff)   
                            | (*wp & 0xffffffffffff0000);
                break;
        }

        if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_short_schar(const void *xp, schar *ip)
{
        ix_short xx;
        get_ix_short(xp, &xx);
        *ip = xx;
        if(xx > SCHAR_MAX || xx < SCHAR_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_short_uchar(const void *xp, uchar *ip)
{
        ix_short xx;
        get_ix_short(xp, &xx);
        *ip = xx;
        if(xx > UCHAR_MAX || xx < 0)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_short_short(const void *xp, short *ip)
{
        get_ix_short(xp, ip);
        return ENOERR;
}

int
ncx_get_short_int(const void *xp, int *ip)
{
        ix_short xx;
        get_ix_short(xp, &xx);
        *ip = xx;
        return ENOERR;
}

int
ncx_get_short_long(const void *xp, long *ip)
{
        ix_short xx;
        get_ix_short(xp, &xx);
        *ip = xx;
        return ENOERR;
}

int
ncx_get_short_float(const void *xp, float *ip)
{
        ix_short xx;
        get_ix_short(xp, &xx);
        *ip = xx;
        return ENOERR;
}

int
ncx_get_short_double(const void *xp, double *ip)
{
        ix_short xx;
        get_ix_short(xp, &xx);
        *ip = xx;
        return ENOERR;
}

int
ncx_put_short_schar(void *xp, const schar *ip)
{
        uchar *cp = xp;
        if(*ip & 0x80)
                *cp++ = 0xff;
        else
                *cp++ = 0;
        *cp = (uchar)*ip;
        return ENOERR;
}

int
ncx_put_short_uchar(void *xp, const uchar *ip)
{
        uchar *cp = xp;
        *cp++ = 0;
        *cp = *ip;
        return ENOERR;
}

int
ncx_put_short_short(void *xp, const short *ip)
{
        return cput_short_short(xp, ip, byteoff(xp)/X_SIZEOF_SHORT);
}

int
ncx_put_short_int(void *xp, const int *ip)
{
        ix_short xx = (ix_short)*ip;
        return cput_short_short(xp, &xx, byteoff(xp)/X_SIZEOF_SHORT);
}

int
ncx_put_short_long(void *xp, const long *ip)
{
        ix_short xx = (ix_short)*ip;
        return cput_short_short(xp, &xx, byteoff(xp)/X_SIZEOF_SHORT);
}

int
ncx_put_short_float(void *xp, const float *ip)
{
        ix_short xx = (ix_short)*ip;
        const int status = cput_short_short(xp, &xx, 
byteoff(xp)/X_SIZEOF_SHORT);
        if(status != ENOERR)
                return status;
        if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_put_short_double(void *xp, const double *ip)
{
        ix_short xx = (ix_short)*ip;
        const int status = cput_short_short(xp, &xx, 
byteoff(xp)/X_SIZEOF_SHORT);
        if(status != ENOERR)
                return status;
        if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

/* x_int */

typedef int ix_int;
#define SIZEOF_IX_INT SIZEOF_INT
#define IX_INT_MAX INT_MAX

static void
cget_int_int(const void *xp, int *ip, int which)
{
        const long *wp = xp;

        if(which == 0)
        {
                *ip = (int)(*wp >> 32);
        }
        else
        {
                *ip = (int)(*wp & 0xffffffff);
        }

        if(*ip & 0x80000000)
        {
                /* extern is negative */
                *ip |= (~(0xffffffff));
        }
}
#define get_ix_int(xp, ip) cget_int_int((xp), (ip), byteoff(xp))

static int
cput_int_int(void *xp, const int *ip, int which)
{
        word *wp = xp;

        if(which == 0)
        {
                *wp = (*ip << 32) | (*wp & 0xffffffff);
        }
        else
        {
                *wp = (*wp & ~0xffffffff) | (*ip & 0xffffffff);
        }
        if(*ip > X_INT_MAX || *ip < X_INT_MIN)
                return NC_ERANGE;
        return ENOERR;
}
#define put_ix_int(xp, ip) cput_int_int((xp), (ip), byteoff(xp))

int
ncx_get_int_schar(const void *xp, schar *ip)
{
        ix_int xx;
        get_ix_int(xp, &xx);
        *ip = xx;
        if(xx > SCHAR_MAX || xx < SCHAR_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_int_uchar(const void *xp, uchar *ip)
{
        ix_int xx;
        get_ix_int(xp, &xx);
        *ip = xx;
        if(xx > UCHAR_MAX || xx < 0)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_int_short(const void *xp, short *ip)
{
        ix_int xx;
        get_ix_int(xp, &xx);
        *ip = xx;
        if(xx > SHORT_MAX || xx < SHORT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_int_int(const void *xp, int *ip)
{
        ix_int xx;
        get_ix_int(xp, &xx);
        *ip = xx;
        return ENOERR;
}

static void
cget_int_long(const void *xp, long *ip, int which)
{
        const long *wp = xp;

        if(which == 0)
        {
                *ip = (int)(*wp >> 32);
        }
        else
        {
                *ip = (int)(*wp & 0xffffffff);
        }

        if(*ip & 0x80000000)
        {
                /* extern is negative */
                *ip |= (~(0xffffffff));
        }
}

int
ncx_get_int_long(const void *xp, long *ip)
{
        cget_int_long(xp, ip, byteoff(xp));
        return ENOERR;
}

int
ncx_get_int_float(const void *xp, float *ip)
{
        ix_int xx;
        get_ix_int(xp, &xx);
        *ip = xx;
        if(xx > FLT_MAX || xx < (-FLT_MAX))
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_int_double(const void *xp, double *ip)
{
        ix_int xx;
        get_ix_int(xp, &xx);
        *ip = xx;
        return ENOERR;
}

int
ncx_put_int_schar(void *xp, const schar *ip)
{
        uchar *cp = xp;
        if(*ip & 0x80)
        {
                *cp++ = 0xff;
                *cp++ = 0xff;
                *cp++ = 0xff;
        }
        else
        {
                *cp++ = 0x00;
                *cp++ = 0x00;
                *cp++ = 0x00;
        }
        *cp = (uchar)*ip;
        return ENOERR;
}

int
ncx_put_int_uchar(void *xp, const uchar *ip)
{
        uchar *cp = xp;
        *cp++ = 0x00;
        *cp++ = 0x00;
        *cp++ = 0x00;
        *cp   = *ip;
        return ENOERR;
}

int
ncx_put_int_short(void *xp, const short *ip)
{
        ix_int xx = (ix_int)(*ip);
        return put_ix_int(xp, &xx);
}

int
ncx_put_int_int(void *xp, const int *ip)
{
        return put_ix_int(xp, ip);
}

static int
cput_int_long(void *xp, const long *ip, int which)
{
        long *wp = xp;

        if(which == 0)
        {
                *wp = (*ip << 32) | (*wp & 0xffffffff);
        }
        else
        {
                *wp = (*wp & ~0xffffffff) | (*ip & 0xffffffff);
        }
        if(*ip > X_INT_MAX || *ip < X_INT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_put_int_long(void *xp, const long *ip)
{
        return cput_int_long(xp, ip, byteoff(xp));
}

int
ncx_put_int_float(void *xp, const float *ip)
{
        ix_int xx = (ix_int)(*ip);
        const int status = put_ix_int(xp, &xx);
        if(status != ENOERR)
                return status;
        if(*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_put_int_double(void *xp, const double *ip)
{
        ix_int xx = (ix_int)(*ip);
        const int status = put_ix_int(xp, &xx);
        if(status != ENOERR)
                return status;
        if(*ip > X_INT_MAX || *ip < X_INT_MIN)
                return NC_ERANGE;
        return ENOERR;
}
 

/* x_float */

#if defined(NO_IEEE_FLOAT)

struct cray_single {
        unsigned int    sign    : 1;
        unsigned int     exp    :15;
        unsigned int    mant    :48;
};
typedef struct cray_single cray_single;

static const int cs_ieis_bias = 0x4000 - 0x7f;

static const int cs_id_bias = 0x4000 - 0x3ff;

#endif

struct ieee_single_hi {
        unsigned int    sign    : 1;
        unsigned int     exp    : 8;
        unsigned int    mant    :23;
        unsigned int    pad     :32;
};
typedef struct ieee_single_hi ieee_single_hi;

struct ieee_single_lo {
        unsigned int    pad     :32;
        unsigned int    sign    : 1;
        unsigned int     exp    : 8;
        unsigned int    mant    :23;
};
typedef struct ieee_single_lo ieee_single_lo;

static const int ieee_single_bias = 0x7f;


struct ieee_double {
        unsigned int    sign    : 1;
        unsigned int     exp    :11;
        unsigned int    mant    :52;
};
typedef struct ieee_double ieee_double;

static const int ieee_double_bias = 0x3ff;

#if FLOAT_USE_IEG

static void
get_ix_float(const void *xp, float *ip)
{
        const int bo = bitoff(xp);
        (void) IEG2CRAY(&Cray2_F32, &One, (word *)xp, &bo, ip, &UnitStride);
}

static int
put_ix_float(void *xp, const float *ip)
{
        const int bo = bitoff(xp);
        int status = CRAY2IEG(&Cray2_F32, &One, (word *)xp, &bo, ip, 
&UnitStride);
        if(status != 0)
                status = NC_ERANGE;
        /* else, status == 0 == ENOERR */
        return status;
}

#else
        /* !FLOAT_USE_IEG */

#if defined(NO_IEEE_FLOAT)

static void
cget_float_float(const void *xp, float *ip, int which)
{

        if(which == 0)
        {
                const ieee_single_hi *isp = (const ieee_single_hi *) xp;
                cray_single *csp = (cray_single *) ip;

                if(isp->exp == 0)
                {
                        /* ieee subnormal */
                        *ip = (double)isp->mant;
                        if(isp->mant != 0)
                        {
                                csp->exp -= (ieee_single_bias + 22);
                        }
                }
                else
                {
                        csp->exp  = isp->exp + cs_ieis_bias + 1;
                        csp->mant = isp->mant << (48 - 1 - 23);
                        csp->mant |= (1 << (48 - 1));
                }
                csp->sign = isp->sign;


        }
        else
        {
                const ieee_single_lo *isp = (const ieee_single_lo *) xp;
                cray_single *csp = (cray_single *) ip;

                if(isp->exp == 0)
                {
                        /* ieee subnormal */
                        *ip = (double)isp->mant;
                        if(isp->mant != 0)
                        {
                                csp->exp -= (ieee_single_bias + 22);
                        }
                }
                else
                {
                        csp->exp  = isp->exp + cs_ieis_bias + 1;
                        csp->mant = isp->mant << (48 - 1 - 23);
                        csp->mant |= (1 << (48 - 1));
                }
                csp->sign = isp->sign;


        }
}

static int
cput_float_float(void *xp, const float *ip, int which)
{
        int status = ENOERR;
        if(which == 0)
        {
                ieee_single_hi *isp = (ieee_single_hi*)xp;
        const cray_single *csp = (const cray_single *) ip;
        int ieee_exp = csp->exp - cs_ieis_bias -1;

        isp->sign = csp->sign;

        if(ieee_exp >= 0xff
                        || *ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
        {
                /* NC_ERANGE => ieee Inf */
                isp->exp = 0xff;
                isp->mant = 0x0;
                return NC_ERANGE;
        }
        /* else */

        if(ieee_exp > 0)
        {
                /* normal ieee representation */
                isp->exp  = ieee_exp;
                /* assumes cray rep is in normal form */
                /* assert(csp->mant & 0x800000000000); */
                isp->mant = (((csp->mant << 1) &
                                0xffffffffffff) >> (48 - 23));
        }
        else if(ieee_exp > -23)
        {
                /* ieee subnormal, right  */
                const int rshift = (48 - 23 - ieee_exp);

                isp->mant = csp->mant >> rshift;
                isp->exp  = 0;
        }
        else
        {
                /* smaller than ieee can represent */
                isp->exp = 0;
                isp->mant = 0;
        }

        }
        else
        {
                ieee_single_lo *isp = (ieee_single_lo*)xp;
        const cray_single *csp = (const cray_single *) ip;
        int ieee_exp = csp->exp - cs_ieis_bias -1;

        isp->sign = csp->sign;

        if(ieee_exp >= 0xff
                        || *ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
        {
                /* NC_ERANGE => ieee Inf */
                isp->exp = 0xff;
                isp->mant = 0x0;
                return NC_ERANGE;
        }
        /* else */

        if(ieee_exp > 0)
        {
                /* normal ieee representation */
                isp->exp  = ieee_exp;
                /* assumes cray rep is in normal form */
                /* assert(csp->mant & 0x800000000000); */
                isp->mant = (((csp->mant << 1) &
                                0xffffffffffff) >> (48 - 23));
        }
        else if(ieee_exp > -23)
        {
                /* ieee subnormal, right  */
                const int rshift = (48 - 23 - ieee_exp);

                isp->mant = csp->mant >> rshift;
                isp->exp  = 0;
        }
        else
        {
                /* smaller than ieee can represent */
                isp->exp = 0;
                isp->mant = 0;
        }

        }
        return ENOERR;
}

#define get_ix_float(xp, ip) cget_float_float((xp), (ip), byteoff(xp))
#define put_ix_float(xp, ip) cput_float_float((xp), (ip), byteoff(xp))

#else
        /* IEEE Cray with only doubles */
static void
cget_float_float(const void *xp, float *ip, int which)
{

        ieee_double *idp = (ieee_double *) ip;

        if(which == 0)
        {
                const ieee_single_hi *isp = (const ieee_single_hi *) xp;
                if(isp->exp == 0 && isp->mant == 0)
                {
                        idp->exp = 0;
                        idp->mant = 0;
                }
                else
                {
                        idp->exp = isp->exp + (ieee_double_bias - 
ieee_single_bias);
                        idp->mant = isp->mant << (52 - 23);
                }
                idp->sign = isp->sign;
        }
        else
        {
                const ieee_single_lo *isp = (const ieee_single_lo *) xp;
                if(isp->exp == 0 && isp->mant == 0)
                {
                        idp->exp = 0;
                        idp->mant = 0;
                }
                else
                {
                        idp->exp = isp->exp + (ieee_double_bias - 
ieee_single_bias);
                        idp->mant = isp->mant << (52 - 23);
                }
                idp->sign = isp->sign;
        }
}

static int
cput_float_float(void *xp, const float *ip, int which)
{
        const ieee_double *idp = (const ieee_double *) ip;
        if(which == 0)
        {
                ieee_single_hi *isp = (ieee_single_hi*)xp;
                if(idp->exp > (ieee_double_bias - ieee_single_bias))
                        isp->exp = idp->exp - (ieee_double_bias - 
ieee_single_bias);
                else
                        isp->exp = 0;
                isp->mant = idp->mant >> (52 - 23);
                isp->sign = idp->sign;
        }
        else
        {
                ieee_single_lo *isp = (ieee_single_lo*)xp;
                if(idp->exp > (ieee_double_bias - ieee_single_bias))
                        isp->exp = idp->exp - (ieee_double_bias - 
ieee_single_bias);
                else
                        isp->exp = 0;
                isp->mant = idp->mant >> (52 - 23);
                isp->sign = idp->sign;
        }
        if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

#define get_ix_float(xp, ip) cget_float_float((xp), (ip), byteoff(xp))
#define put_ix_float(xp, ip) cput_float_float((xp), (ip), byteoff(xp))

#endif /* NO_IEEE_FLOAT */

#endif /* FLOAT_USE_IEG */


int
ncx_get_float_schar(const void *xp, schar *ip)
{
        float xx;
        get_ix_float(xp, &xx);
        *ip = (schar) xx;
        if(xx > SCHAR_MAX || xx < SCHAR_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_float_uchar(const void *xp, uchar *ip)
{
        float xx;
        get_ix_float(xp, &xx);
        *ip = (uchar) xx;
        if(xx > UCHAR_MAX || xx < 0)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_float_short(const void *xp, short *ip)
{
        float xx;
        get_ix_float(xp, &xx);
        *ip = (short) xx;
        if(xx > SHORT_MAX || xx < SHORT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_float_int(const void *xp, int *ip)
{
        float xx;
        get_ix_float(xp, &xx);
        *ip = (int) xx;
        if(xx > (double)INT_MAX || xx < (double)INT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_float_long(const void *xp, long *ip)
{
        float xx;
        get_ix_float(xp, &xx);
        *ip = (long) xx;
        if(xx > LONG_MAX || xx < LONG_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_float_float(const void *xp, float *ip)
{
        get_ix_float(xp, ip);
        return ENOERR;
}

int
ncx_get_float_double(const void *xp, double *ip)
{
#if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG
        return ncx_get_float_float(xp, (float *)ip);
#else
        float xx;
        get_ix_float(xp, &xx);
        *ip = xx;
        return ENOERR;
#endif
}


int
ncx_put_float_schar(void *xp, const schar *ip)
{
        float xx = (float) *ip;
        return put_ix_float(xp, &xx);
}

int
ncx_put_float_uchar(void *xp, const uchar *ip)
{
        float xx = (float) *ip;
        return put_ix_float(xp, &xx);
}

int
ncx_put_float_short(void *xp, const short *ip)
{
        float xx = (float) *ip;
        return put_ix_float(xp, &xx);
}

int
ncx_put_float_int(void *xp, const int *ip)
{
        float xx = (float) *ip;
        return put_ix_float(xp, &xx);
}

int
ncx_put_float_long(void *xp, const long *ip)
{
        float xx = (float) *ip;
        return put_ix_float(xp, &xx);
}

int
ncx_put_float_float(void *xp, const float *ip)
{
        return put_ix_float(xp, ip);
}

int
ncx_put_float_double(void *xp, const double *ip)
{
#if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG
        return put_ix_float(xp, (float *)ip);
#else
        float xx = (float) *ip;
        int status = put_ix_float(xp, &xx);
        if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
                return NC_ERANGE;
        return status;
#endif
}

/* x_double */


#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)

static void
get_ix_double(const void *xp, double *ip)
{
        (void) memcpy(ip, xp, sizeof(double));
}

static int
put_ix_double(void *xp, const double *ip)
{
        (void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
        return ENOERR;
}

#else

static void
cget_double_double(const void *xp, double *ip)
{
        const ieee_double *idp = (const ieee_double *) xp;
        cray_single *csp = (cray_single *) ip;

        if(idp->exp == 0)
        {
                /* ieee subnormal */
                *ip = (double)idp->mant;
                if(idp->mant != 0)
                {
                        csp->exp -= (ieee_double_bias + 51);
                }
        }
        else
        {
                csp->exp  = idp->exp + cs_id_bias + 1;
                csp->mant = idp->mant >> (52 - 48 + 1);
                csp->mant |= (1 << (48 - 1));
        }
        csp->sign = idp->sign;
}

static int
cput_double_double(void *xp, const double *ip)
{
        ieee_double *idp = (ieee_double *) xp;
        const cray_single *csp = (const cray_single *) ip;

        int ieee_exp = csp->exp - cs_id_bias -1;

        idp->sign = csp->sign;

        if(ieee_exp >= 0x7ff)
        {
                /* NC_ERANGE => ieee Inf */
                idp->exp = 0x7ff;
                idp->mant = 0x0;
                return NC_ERANGE;
        }
        /* else */

        if(ieee_exp > 0)
        {
                /* normal ieee representation */
                idp->exp  = ieee_exp;
                /* assumes cray rep is in normal form */
                assert(csp->mant & 0x800000000000);
                idp->mant = (((csp->mant << 1) &
                                0xffffffffffff) << (52 - 48));
        }
        else if(ieee_exp >= (-(52 -48)))
        {
                /* ieee subnormal, left  */
                const int lshift = (52 - 48) + ieee_exp;
                idp->mant = csp->mant << lshift;
                idp->exp  = 0;
        }
        else if(ieee_exp >= -52)
        {
                /* ieee subnormal, right  */
                const int rshift = (- (52 - 48) - ieee_exp);

                idp->mant = csp->mant >> rshift;
                idp->exp  = 0;
        }
        else
        {
                /* smaller than ieee can represent */
                idp->exp = 0;
                idp->mant = 0;
        }
        return ENOERR;
}

#define get_ix_double(xp, ip) cget_double_double((xp), (ip))
#define put_ix_double(xp, ip) cput_double_double((xp), (ip))

#endif /* NO_IEEE_FLOAT */

int
ncx_get_double_schar(const void *xp, schar *ip)
{
        double xx;
        get_ix_double(xp, &xx);
        *ip = (schar) xx;
        if(xx > SCHAR_MAX || xx < SCHAR_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_double_uchar(const void *xp, uchar *ip)
{
        double xx;
        get_ix_double(xp, &xx);
        *ip = (uchar) xx;
        if(xx > UCHAR_MAX || xx < 0)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_double_short(const void *xp, short *ip)
{
        double xx;
        get_ix_double(xp, &xx);
        *ip = (short) xx;
        if(xx > SHORT_MAX || xx < SHORT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_double_int(const void *xp, int *ip)
{
        double xx;
        get_ix_double(xp, &xx);
        *ip = (int) xx;
        if(xx > INT_MAX || xx < INT_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_double_long(const void *xp, long *ip)
{
        double xx;
        get_ix_double(xp, &xx);
        *ip = (long) xx;
        if(xx > LONG_MAX || xx < LONG_MIN)
                return NC_ERANGE;
        return ENOERR;
}

int
ncx_get_double_float(const void *xp, float *ip)
{
#if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG
        get_ix_double(xp, (double *)ip);
        return ENOERR;
#else
        double xx;
        get_ix_double(xp, &xx);
        if(xx > FLT_MAX || xx < (-FLT_MAX))
        {
                *ip = FLT_MAX;
                return NC_ERANGE;
        }
        if(xx < (-FLT_MAX))
        {
                *ip = (-FLT_MAX);
                return NC_ERANGE;
        }
        *ip = (float) xx;
        return ENOERR;
#endif
}

int
ncx_get_double_double(const void *xp, double *ip)
{
        get_ix_double(xp, ip);
        return ENOERR;
}


int
ncx_put_double_schar(void *xp, const schar *ip)
{
        double xx = (double) *ip;
        put_ix_double(xp, &xx);
        return ENOERR;
}

int
ncx_put_double_uchar(void *xp, const uchar *ip)
{
        double xx = (double) *ip;
        put_ix_double(xp, &xx);
        return ENOERR;
}

int
ncx_put_double_short(void *xp, const short *ip)
{
        double xx = (double) *ip;
        put_ix_double(xp, &xx);
        return ENOERR;
}

int
ncx_put_double_int(void *xp, const int *ip)
{
        double xx = (double) *ip;
        put_ix_double(xp, &xx);
        return ENOERR;
}

int
ncx_put_double_long(void *xp, const long *ip)
{
        double xx = (double) *ip;
        put_ix_double(xp, &xx);
        /* TODO: Deal with big guys */
        return ENOERR;
}

int
ncx_put_double_float(void *xp, const float *ip)
{
#if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG
        put_ix_double(xp, (double *)ip);
        return ENOERR;
#else
        double xx = (double) *ip;
        return put_ix_double(xp, &xx);
#endif
}

int
ncx_put_double_double(void *xp, const double *ip)
{
#if !defined(NO_IEEE_FLOAT)
        put_ix_double(xp, ip);
        return ENOERR;
#else
        return put_ix_double(xp, ip);
#endif
}


/* x_size_t */

int
ncx_put_size_t(void **xpp, const size_t *ulp)
{
        /* similar to put_ix_int() */
        uchar *cp = *xpp;
                /* sizes limited to 2^31 -1 in netcdf */
        assert(*ulp <= X_SIZE_MAX && (long) (*ulp) >= 0);

        *cp++ = (uchar)((*ulp) >> 24);
        *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16);
        *cp++ = (uchar)(((*ulp) & 0x0000ff00) >>  8);
        *cp   = (uchar)((*ulp) & 0x000000ff);

        *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T);
        return ENOERR;
}

int
ncx_get_size_t(const void **xpp,  size_t *ulp)
{
        /* similar to get_ix_int */
        const uchar *cp = *xpp;
        assert((*cp & 0x80) == 0); /* sizes limited to 2^31 -1 in netcdf */

        *ulp = *cp++ << 24;
        *ulp |= (*cp++ << 16);
        *ulp |= (*cp++ << 8);
        *ulp |= *cp; 

        *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
        return ENOERR;
}

/* x_off_t */

int
ncx_put_off_t(void **xpp, const off_t *lp)
{
        /* similar to put_ix_int() */
        uchar *cp = *xpp;
                /* No negative offsets stored in netcdf */
        assert(*lp >= 0 && *lp <= X_OFF_MAX);

        *cp++ = (uchar)((*lp) >> 24);
        *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
        *cp++ = (uchar)(((*lp) & 0x0000ff00) >>  8);
        *cp   = (uchar)((*lp) & 0x000000ff);

        *xpp = (void *)((char *)(*xpp) + X_SIZEOF_OFF_T);
        return ENOERR;
}

int
ncx_get_off_t(const void **xpp, off_t *lp)
{
        /* similar to get_ix_int() */
        const uchar *cp = *xpp;
        assert((*cp & 0x80) == 0); /* No negative offsets stored in netcdf */

        *lp = *cp++ << 24;
        *lp |= (*cp++ << 16);
        *lp |= (*cp++ << 8);
        *lp |= *cp; 

        *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_OFF_T);
        return ENOERR;
}


/*
 * Aggregate numeric conversion functions.
 */



/* schar */

int
ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
{
                (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);
        return ENOERR;

}
int
ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
{
                (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);
        return ENOERR;

}
int
ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp)
{
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (const void *)xp;
        return ENOERR;
}

int
ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp)
{
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (const void *)xp;
        return ENOERR;
}

int
ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp)
{
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (const void *)xp;
        return ENOERR;
}

int
ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp)
{
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (const void *)xp;
        return ENOERR;
}

int
ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp)
{
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (const void *)xp;
        return ENOERR;
}


int
ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
{
                size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems + rndup);

        return ENOERR;

}
int
ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
{
                size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems + rndup);

        return ENOERR;

}
int
ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp)
{
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (void *)(xp + rndup);
        return ENOERR;
}

int
ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp)
{
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (void *)(xp + rndup);
        return ENOERR;
}

int
ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp)
{
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (void *)(xp + rndup);
        return ENOERR;
}

int
ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp)
{
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (void *)(xp + rndup);
        return ENOERR;
}

int
ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp)
{
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                *tp++ = *xp++;
        }

        *xpp = (void *)(xp + rndup);
        return ENOERR;
}


int
ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
{
                (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        return ENOERR;

}
int
ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
{
                (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        return ENOERR;

}
int
ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp)
{
        int status = ENOERR;
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp)
{
        int status = ENOERR;
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp)
{
        int status = ENOERR;
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp)
{
        int status = ENOERR;
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp)
{
        int status = ENOERR;
        schar *xp = (schar *)(*xpp);

        while(nelems-- != 0)
        {
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }

        *xpp = (void *)xp;
        return status;
}


int
ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
{
                size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        if(rndup)
        {
                (void) memcpy(*xpp, nada, rndup);
                *xpp = (void *)((char *)(*xpp) + rndup);
        }
        
        return ENOERR;

}
int
ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
{
                size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        if(rndup)
        {
                (void) memcpy(*xpp, nada, rndup);
                *xpp = (void *)((char *)(*xpp) + rndup);
        }
        
        return ENOERR;

}
int
ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp)
{
        int status = ENOERR;
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                /* N.B. schar as signed */
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }


        if(rndup)
        {
                (void) memcpy(xp, nada, rndup);
                xp += rndup;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp)
{
        int status = ENOERR;
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                /* N.B. schar as signed */
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }


        if(rndup)
        {
                (void) memcpy(xp, nada, rndup);
                xp += rndup;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp)
{
        int status = ENOERR;
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                /* N.B. schar as signed */
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }


        if(rndup)
        {
                (void) memcpy(xp, nada, rndup);
                xp += rndup;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp)
{
        int status = ENOERR;
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                /* N.B. schar as signed */
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }


        if(rndup)
        {
                (void) memcpy(xp, nada, rndup);
                xp += rndup;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp)
{
        int status = ENOERR;
        size_t rndup = nelems % X_ALIGN;
        schar *xp = (schar *)(*xpp);

        if(rndup)
                rndup = X_ALIGN - rndup;

        while(nelems-- != 0)
        {
                /* N.B. schar as signed */
                if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN)
                        status = NC_ERANGE;
                *xp++ = (schar) *tp++;
        }


        if(rndup)
        {
                (void) memcpy(xp, nada, rndup);
                xp += rndup;
        }

        *xpp = (void *)xp;
        return status;
}



/* short */

int
ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

#if SHORT_USE_IEG
int
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
{
        if(nelems > 0)
        {
                const int bo = bitoff(*xpp);
                const word *wp = *xpp;
                int ierr;
                *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_SHORT);
                ierr = IEG2CRAY(&Cray2_I16, &nelems, wp,
                                &bo, tp, &UnitStride);
                assert(ierr >= 0);
                if(ierr > 0)
                        return NC_ERANGE;
        }
        return ENOERR;
}
#else
int
ncx_getn_short_short(const void **xpp, const size_t nelems, short *tp)
{
        if(nelems > 0)
        {
        const word *wp = *xpp;
        const short *const last = &tp[nelems -1];
        const int rem = word_align(*xpp)/X_SIZEOF_SHORT;
        *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_SHORT);

        switch(rem) {
        case 3:
                *tp = (short)((*wp >> 32) & 0xffff);
                if(*tp & 0x8000)
                        *tp |= (~(0xffff));
                if(tp == last)
                        return ENOERR;
                tp++;
                /*FALLTHRU*/    
        case 2:
                *tp = (short)((*wp >> 16) & 0xffff);
                if(*tp & 0x8000)
                        *tp |= (~(0xffff));
                if(tp == last)
                        return ENOERR;
                tp++;
                /*FALLTHRU*/    
        case 1:
                *tp = (short)(*wp & 0xffff);
                if(*tp & 0x8000)
                        *tp |= (~(0xffff));
                if(tp == last)
                        return ENOERR;
                tp++;
                wp++; /* Note Bene */
                /*FALLTHRU*/    
        }

        assert((nelems - rem) != 0);
        {
                const int nwords = ((nelems - rem) * X_SIZEOF_SHORT)
                                        / sizeof(word);
                const word *const endw = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < endw; wp++)
                {

                        *tp = (short)(*wp >> 48);
                        if(*tp & 0x8000)
                                *tp |= (~(0xffff));
                        tp++;

                        *tp = (short)((*wp >> 32) & 0xffff);
                        if(*tp & 0x8000)
                                *tp |= (~(0xffff));
                        tp++;

                        *tp = (short)((*wp >> 16) & 0xffff);
                        if(*tp & 0x8000)
                                *tp |= (~(0xffff));
                        tp++;

                        *tp = (short)(*wp & 0xffff);
                        if(*tp & 0x8000)
                                *tp |= (~(0xffff));
                        tp++;
                }
        }

        if(tp <= last)
        {
                *tp = (short)(*wp >> 48);
                if(*tp & 0x8000)
                        *tp |= (~(0xffff));
                tp++;
        }
        if(tp <= last)
        {
                *tp = (short)((*wp >> 32) & 0xffff);
                if(*tp & 0x8000)
                        *tp |= (~(0xffff));
                tp++;
        }
        if(tp <= last)
        {
                *tp = (short)((*wp >> 16) & 0xffff);
                if(*tp & 0x8000)
                        *tp |= (~(0xffff));
                tp++;
        }

        }
        return ENOERR;
}
#endif

int
ncx_getn_short_int(const void **xpp, size_t nelems, int *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_short_long(const void **xpp, size_t nelems, long *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_short_float(const void **xpp, size_t nelems, float *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_short_double(const void **xpp, size_t nelems, double *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}


int
ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp)
{
        const size_t rndup = nelems % 2;

        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
                xp += X_SIZEOF_SHORT;
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp)
{
        const size_t rndup = nelems % 2;

        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
                xp += X_SIZEOF_SHORT;
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp)
{
        const size_t rndup = nelems % 2;

        const int status = ncx_getn_short_short(xpp, nelems, tp);

        if(rndup != 0)
        {
                *xpp = ((char *) (*xpp) + X_SIZEOF_SHORT);
        }
                
        return status;
}

int
ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp)
{
        const size_t rndup = nelems % 2;

        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
                xp += X_SIZEOF_SHORT;
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp)
{
        const size_t rndup = nelems % 2;

        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
                xp += X_SIZEOF_SHORT;
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp)
{
        const size_t rndup = nelems % 2;

        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
                xp += X_SIZEOF_SHORT;
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp)
{
        const size_t rndup = nelems % 2;

        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_get_short_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
                xp += X_SIZEOF_SHORT;
                
        *xpp = (void *)xp;
        return status;
}


int
ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

#if SHORT_USE_IEG
int
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp)
{
        if(nelems > 0)
        {
                word *wp = *xpp;
                const int bo = bitoff(*xpp);
                int ierr;
        
                *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_SHORT);
        
                ierr = CRAY2IEG(&Cray2_I16, &nelems, wp,
                                &bo, tp, &UnitStride);
                assert(ierr >= 0);
                if(ierr > 0)
                        return NC_ERANGE;
        }
        return ENOERR;
}
#else
int
ncx_putn_short_short(void **xpp, const size_t nelems, const short *tp)
{
        int status = ENOERR;
        if(nelems == 0)
                return status;
{
        word *wp = *xpp;
        const short *const last = &tp[nelems -1];
        const int rem = word_align(*xpp)/X_SIZEOF_SHORT;
        *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_SHORT);

        switch(rem) {
        case 3:
                *wp = ((*tp << 32) & 0x0000ffff00000000)
                            | (*wp & 0xffff0000ffffffff);
                if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN)
                        status = NC_ERANGE;
                if(tp == last)
                        return status;
                tp++;
                /*FALLTHRU*/    
        case 2:
                *wp = ((*tp << 16) & 0x00000000ffff0000)
                            | (*wp & 0xffffffff0000ffff);
                if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN)
                        status = NC_ERANGE;
                if(tp == last)
                        return status;
                tp++;
                /*FALLTHRU*/    
        case 1:
                *wp = (*tp         & 0x000000000000ffff)   
                            | (*wp & 0xffffffffffff0000);
                if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN)
                        status = NC_ERANGE;
                if(tp == last)
                        return status;
                tp++;
                wp++; /* Note Bene */
                /*FALLTHRU*/    
        }

        assert((nelems - rem) != 0);
        {
                const int nwords = ((nelems - rem) * X_SIZEOF_SHORT)
                                        / sizeof(word);
                const word *const endw = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < endw; wp++)
                {
                        *wp =      (*tp      << 48)
                                | ((*(tp +1) << 32) & 0x0000ffff00000000)
                                | ((*(tp +2) << 16) & 0x00000000ffff0000)
                                | ((*(tp +3)      ) & 0x000000000000ffff);

                        { int ii = 0;
                        for(; ii < 4; ii++, tp++)
                                if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN)
                                        status = NC_ERANGE;
                        }
                }
        }

        if(tp <= last)
        {
                *wp = (*tp << 48)
                            | (*wp & 0x0000ffffffffffff);
                if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN)
                        status = NC_ERANGE;
                tp++;
        }
        if(tp <= last)
        {
                *wp = ((*tp << 32) & 0x0000ffff00000000)
                            | (*wp & 0xffff0000ffffffff);
                if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN)
                        status = NC_ERANGE;
                tp++;
        }
        if(tp <= last)
        {
                *wp = ((*tp << 16) & 0x00000000ffff0000)
                            | (*wp & 0xffffffff0000ffff);
                if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN)
                        status = NC_ERANGE;
        }

        return status;
}
}
#endif

int
ncx_putn_short_int(void **xpp, size_t nelems, const int *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_short_long(void **xpp, size_t nelems, const long *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_short_float(void **xpp, size_t nelems, const float *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_short_double(void **xpp, size_t nelems, const double *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}


int
ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp)
{
        const size_t rndup = nelems % 2;

        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
        {
                (void) memcpy(xp, nada, X_SIZEOF_SHORT);
                xp += X_SIZEOF_SHORT;   
        }
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp)
{
        const size_t rndup = nelems % 2;

        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
        {
                (void) memcpy(xp, nada, X_SIZEOF_SHORT);
                xp += X_SIZEOF_SHORT;   
        }
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp)
{
        const size_t rndup = nelems % 2;

        const int status = ncx_putn_short_short(xpp, nelems, tp);

        if(rndup != 0)
        {
                *xpp = ((char *) (*xpp) + X_SIZEOF_SHORT);
        }
                
        return status;
}

int
ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp)
{
        const size_t rndup = nelems % 2;

        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
        {
                (void) memcpy(xp, nada, X_SIZEOF_SHORT);
                xp += X_SIZEOF_SHORT;   
        }
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp)
{
        const size_t rndup = nelems % 2;

        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
        {
                (void) memcpy(xp, nada, X_SIZEOF_SHORT);
                xp += X_SIZEOF_SHORT;   
        }
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp)
{
        const size_t rndup = nelems % 2;

        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
        {
                (void) memcpy(xp, nada, X_SIZEOF_SHORT);
                xp += X_SIZEOF_SHORT;   
        }
                
        *xpp = (void *)xp;
        return status;
}

int
ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp)
{
        const size_t rndup = nelems % 2;

        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
        {
                const int lstatus = ncx_put_short_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        if(rndup != 0)
        {
                (void) memcpy(xp, nada, X_SIZEOF_SHORT);
                xp += X_SIZEOF_SHORT;   
        }
                
        *xpp = (void *)xp;
        return status;
}



/* int */

int
ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_get_int_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_get_int_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_int_short(const void **xpp, size_t nelems, short *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_get_int_short(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

#if INT_USE_IEG
int
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
{
        if(nelems > 0)
        {
                const int bo = bitoff(*xpp);
                const word *wp = *xpp;
                int ierr;
                *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_INT);
                ierr = IEG2CRAY(&Cray2_I32, &nelems, wp,
                                &bo, tp, &UnitStride);
                assert(ierr >= 0);
                if(ierr > 0)
                        return NC_ERANGE;
        }
        return ENOERR;
}
#else
int
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
{
        const int bo = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(bo != 0)
        {
                cget_int_int(*xpp, tp, bo);
                *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                nelems--;
                if(nelems == 0)
                        return ENOERR;
                tp++;
        }

        assert(byteoff(*xpp) == 0);

        {
                const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word);
                const word *wp = *xpp;
                const word *const end = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp += 2)
                {
                        cget_int_int(wp, tp, 0);
                        cget_int_int(wp, tp + 1, 1);
                }

                *xpp = ((char *) (*xpp) + nwords * sizeof(word)); 
                nelems -= (nwords * sizeof(word)/X_SIZEOF_INT);
                if(nelems != 0)
                {
                        cget_int_int(wp, tp, 0);
                        *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                }
        }

        return ENOERR;
}
#endif

int
ncx_getn_int_long(const void **xpp, size_t nelems, long *tp)
{
        const int bo = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(bo != 0)
        {
                cget_int_long(*xpp, tp, bo);
                *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                nelems--;
                if(nelems == 0)
                        return ENOERR;
                tp++;
        }

        assert(byteoff(*xpp) == 0);

        {
                const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word);
                const word *wp = *xpp;
                const word *const end = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp += 2)
                {
                        cget_int_long(wp, tp, 0);
                        cget_int_long(wp, tp + 1, 1);
                }

                *xpp = ((char *) (*xpp) + nwords * sizeof(word)); 
                nelems -= (nwords * sizeof(word)/X_SIZEOF_INT);
                if(nelems != 0)
                {
                        cget_int_long(wp, tp, 0);
                        *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                }
        }

        return ENOERR;
}

int
ncx_getn_int_float(const void **xpp, size_t nelems, float *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_get_int_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_int_double(const void **xpp, size_t nelems, double *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_get_int_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}


int
ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_put_int_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_put_int_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_int_short(void **xpp, size_t nelems, const short *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_put_int_short(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

#if INT_USE_IEG
int
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp)
{
        if(nelems > 0)
        {
                word *wp = *xpp;
                const int bo = bitoff(*xpp);
                int ierr;
        
                *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_INT);
        
                ierr = CRAY2IEG(&Cray2_I32, &nelems, wp,
                                &bo, tp, &UnitStride);
                assert(ierr >= 0);
                if(ierr > 0)
                        return NC_ERANGE;
        }
        return ENOERR;
}
#else
int
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp)
{
        int status = ENOERR;
        const int bo = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(bo != 0)
        {
                status = cput_int_int(*xpp, tp, bo);
                *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                nelems--;
                if(nelems == 0)
                        return status;
                tp++;
        }

        assert(byteoff(*xpp) == 0);

        {
                const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word);
                word *wp = *xpp;
                const word *const end = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp += 2)
                {
                        int lstatus = cput_int_int(wp, tp, 0);
                        if(lstatus != ENOERR)
                                status = lstatus;
                        lstatus = cput_int_int(wp, tp + 1, 1);
                        if(lstatus != ENOERR)
                                status = lstatus;
                }

                *xpp = ((char *) (*xpp) + nwords * sizeof(word)); 
                nelems -= (nwords * sizeof(word)/X_SIZEOF_INT);
                if(nelems != 0)
                {
                        const int lstatus = cput_int_int(wp, tp, 0);
                        if(lstatus != ENOERR)
                                status = lstatus;
                        *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                }
        }

        return status;
}
#endif

int
ncx_putn_int_long(void **xpp, size_t nelems, const long *tp)
{
        int status = ENOERR;
        const int bo = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(bo != 0)
        {
                status = cput_int_long(*xpp, tp, bo);
                *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                nelems--;
                if(nelems == 0)
                        return status;
                tp++;
        }

        assert(byteoff(*xpp) == 0);

        {
                const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word);
                word *wp = *xpp;
                const word *const end = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp += 2)
                {
                        int lstatus = cput_int_long(wp, tp, 0);
                        if(lstatus != ENOERR)
                                status = lstatus;
                        lstatus = cput_int_long(wp, tp + 1, 1);
                        if(lstatus != ENOERR)
                                status = lstatus;
                }

                *xpp = ((char *) (*xpp) + nwords * sizeof(word)); 
                nelems -= (nwords * sizeof(word)/X_SIZEOF_INT);
                if(nelems != 0)
                {
                        const int lstatus = cput_int_long(wp, tp, 0);
                        if(lstatus != ENOERR)
                                status = lstatus;
                        *xpp = ((char *) (*xpp) + X_SIZEOF_INT);
                }
        }

        return status;
}

int
ncx_putn_int_float(void **xpp, size_t nelems, const float *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_put_int_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_int_double(void **xpp, size_t nelems, const double *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
        {
                const int lstatus = ncx_put_int_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}



/* float */

int
ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_get_float_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_get_float_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_float_short(const void **xpp, size_t nelems, short *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_get_float_short(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_float_int(const void **xpp, size_t nelems, int *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_get_float_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_float_long(const void **xpp, size_t nelems, long *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_get_float_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

#if FLOAT_USE_IEG
int
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
{
        if(nelems > 0)
        {
                const int bo = bitoff(*xpp);
                const word *wp = *xpp;
                int ierr;
                *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_FLOAT);
                ierr = IEG2CRAY(&Cray2_F32, &nelems, wp,
                                &bo, tp, &UnitStride);
                assert(ierr >= 0);
                if(ierr > 0)
                        return NC_ERANGE;
        }
        return ENOERR;

}
#else
int
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
{
        const int bo = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(bo != 0)
        {
                cget_float_float(*xpp, tp, bo);
                *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT);
                nelems--;
                if(nelems == 0)
                        return ENOERR;
                tp++;
        }

        assert(byteoff(*xpp) == 0);

        {
                const int nwords = (nelems * X_SIZEOF_FLOAT)/sizeof(word);
                const word *wp = *xpp;
                const word *const end = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp += 2)
                {
                        cget_float_float(wp, tp, 0);
                        cget_float_float(wp, tp + 1, 1);
                }

                *xpp = ((char *) (*xpp) + nwords * sizeof(word)); 
                nelems -= (nwords * sizeof(word)/X_SIZEOF_FLOAT);
                if(nelems != 0)
                {
                        cget_float_float(wp, tp, 0);
                        *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT);
                }
        }

        return ENOERR;
}
#endif

int
ncx_getn_float_double(const void **xpp, size_t nelems, double *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_get_float_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}


int
ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_put_float_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_put_float_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_float_short(void **xpp, size_t nelems, const short *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_put_float_short(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_float_int(void **xpp, size_t nelems, const int *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_put_float_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_float_long(void **xpp, size_t nelems, const long *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_put_float_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

#if FLOAT_USE_IEG
int
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp)
{
        if(nelems > 0)
        {
                word *wp = *xpp;
                const int bo = bitoff(*xpp);
                int ierr;
        
                *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_FLOAT);
        
                ierr = CRAY2IEG(&Cray2_F32, &nelems, wp,
                                &bo, tp, &UnitStride);
                assert(ierr >= 0);
                if(ierr > 0)
                        return NC_ERANGE;
        }
        return ENOERR;
}
#else
int
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp)
{
        int status = ENOERR;
        const int bo = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(bo != 0)
        {
                status = cput_float_float(*xpp, tp, bo);
                *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT);
                nelems--;
                if(nelems == 0)
                        return status;
                tp++;
        }

        assert(byteoff(*xpp) == 0);

        {
                const int nwords = (nelems * X_SIZEOF_FLOAT)/sizeof(word);
                word *wp = *xpp;
                const word *const end = &wp[nwords];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp += 2)
                {
                        int lstatus = cput_float_float(wp, tp, 0);
                        if(lstatus != ENOERR)
                                status = lstatus;
                        lstatus = cput_float_float(wp, tp + 1, 1);
                        if(lstatus != ENOERR)
                                status = lstatus;
                }

                *xpp = ((char *) (*xpp) + nwords * sizeof(word)); 
                nelems -= (nwords * sizeof(word)/X_SIZEOF_FLOAT);
                if(nelems != 0)
                {
                        const int lstatus = cput_float_float(wp, tp, 0);
                        if(lstatus != ENOERR)
                                status = lstatus;
                        *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT);
                }
        }

        return status;
}
#endif

int
ncx_putn_float_double(void **xpp, size_t nelems, const double *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
        {
                const int lstatus = ncx_put_float_double(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}



/* double */

int
ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_get_double_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_get_double_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_double_short(const void **xpp, size_t nelems, short *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_get_double_short(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_double_int(const void **xpp, size_t nelems, int *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_get_double_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

int
ncx_getn_double_long(const void **xpp, size_t nelems, long *tp)
{
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_get_double_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
}

#if DOUBLE_USE_IEG
int
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
{
        const size_t noff = byteoff(*xpp);
        int ierr;

        if(nelems == 0)
                return ENOERR;

        if(noff != 0)
        {
                /* (*xpp) not word aligned, forced to make a copy */
                word *xbuf = (word*)malloc(nelems*sizeof(word));
                if (xbuf == NULL)
                        return NC_ENOMEM;
                (void) memcpy(xbuf, *xpp, nelems * X_SIZEOF_DOUBLE);
                ierr = IEG2CRAY(&Cray2_F64, &nelems, xbuf,
                        &Zero, tp, &UnitStride);
                (void)free(xbuf);
        }
        else
        {
                ierr = IEG2CRAY(&Cray2_F64, &nelems, *xpp,
                                &Zero, tp, &UnitStride);
        }

        *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);

        assert(ierr >= 0);

        return ierr > 0 ? NC_ERANGE : ENOERR;
}
#elif X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
int
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
{
        (void) memcpy(tp, *xpp, nelems * X_SIZEOF_DOUBLE);
        *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
        return ENOERR;
}
#else
int
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
{
        const size_t noff = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(noff != 0)
        {
                /* (*xpp) not word aligned, forced to make a copy */
                word *xbuf = (word*)malloc(nelems*sizeof(word));
                if (xbuf == NULL)
                {
                        return NC_ENOMEM;
                }
                else
                {
                        const word *wp = xbuf;
                        const word *const end = &wp[nelems];

                        (void) memcpy(
                                (void*)xbuf, *xpp, nelems * X_SIZEOF_DOUBLE);

#pragma _CRI ivdep
                        for( ; wp < end; wp++, tp++)
                        {
                                cget_double_double(wp, tp);
                        }

                        (void)free(xbuf);
                }
        }
        else
        {
                const word *wp = *xpp;
                const word *const end = &wp[nelems];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp++)
                {
                        cget_double_double(wp, tp);
                }

        }
        *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
        return ENOERR;
}
#endif

int
ncx_getn_double_float(const void **xpp, size_t nelems, float *tp)
{
#if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG
        return ncx_getn_double_double(xpp, nelems, (double *)tp);
#else
        const char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_get_double_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (const void *)xp;
        return status;
#endif
}


int
ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_put_double_schar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_put_double_uchar(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_double_short(void **xpp, size_t nelems, const short *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_put_double_short(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_double_int(void **xpp, size_t nelems, const int *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_put_double_int(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

int
ncx_putn_double_long(void **xpp, size_t nelems, const long *tp)
{
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_put_double_long(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
}

#if DOUBLE_USE_IEG
int
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
{
        const size_t noff = byteoff(*xpp);
        int ierr;

        if(nelems == 0)
                return ENOERR;

        if(noff != 0)
        {
                /* (*xpp) not word aligned, forced to make a copy */
                word *xbuf = (word*)malloc(nelems*sizeof(word));
                if (xbuf == NULL)
                        return NC_ENOMEM;
                ierr = CRAY2IEG(&Cray2_F64, &nelems, xbuf,
                        &Zero, tp, &UnitStride);
                assert(ierr >= 0);
                (void) memcpy(*xpp, xbuf, nelems * X_SIZEOF_DOUBLE);
                (void)free(xbuf);
        }
        else
        {
                ierr = CRAY2IEG(&Cray2_F64, &nelems, *xpp,
                                &Zero, tp, &UnitStride);
                assert(ierr >= 0);
        }

        *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);

        return ierr > 0 ? NC_ERANGE : ENOERR;
}
#elif X_SIZEOF_DOUBLE == SIZEOF_DOUBLE  && !defined(NO_IEEE_FLOAT)
int
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
{
        const size_t noff = byteoff(*xpp);
        (void) memcpy(*xpp, tp, nelems * X_SIZEOF_DOUBLE);
        *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
        return ENOERR;
}
#else
int
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
{
        int status = ENOERR;
        const size_t noff = byteoff(*xpp);

        if(nelems == 0)
                return ENOERR;

        if(noff != 0)
        {
                /* (*xpp) not word aligned, forced to make a copy */
                word *xbuf = (word*)malloc(nelems*sizeof(word));
                if (xbuf == NULL)
                {
                        return NC_ENOMEM;
                }
                else
                {
                        word *wp = xbuf;
                        const word *const end = &wp[nelems];

#pragma _CRI ivdep
                        for( ; wp < end; wp++, tp++)
                        {
                                const int lstatus = cput_double_double(wp, tp);
                                if(lstatus != ENOERR)
                                        status = lstatus;
                        }

                        (void) memcpy(
                                *xpp, (void*)xbuf, nelems * X_SIZEOF_DOUBLE);
                        (void)free(xbuf);
                }
        }
        else
        {
                word *wp = *xpp;
                const word *const end = &wp[nelems];

#pragma _CRI ivdep
                for( ; wp < end; wp++, tp++)
                {
                        const int lstatus = cput_double_double(wp, tp);
                        if(lstatus != ENOERR)
                                status = lstatus;
                }

        }

        *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
        return status;
}
#endif

int
ncx_putn_double_float(void **xpp, size_t nelems, const float *tp)
{
#if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG
        return ncx_putn_double_double(xpp, nelems, (double *)tp);
#else
        char *xp = *xpp;
        int status = ENOERR;

        for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
        {
                const int lstatus = ncx_put_double_float(xp, tp);
                if(lstatus != ENOERR)
                        status = lstatus;
        }

        *xpp = (void *)xp;
        return status;
#endif
}



/*
 * Other aggregate conversion functions.
 */

/* text */

int
ncx_getn_text(const void **xpp, size_t nelems, char *tp)
{
        (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);
        return ENOERR;

}

int
ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
{
        size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems + rndup);

        return ENOERR;

}

int
ncx_putn_text(void **xpp, size_t nelems, const char *tp)
{
        (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        return ENOERR;

}

int
ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
{
        size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        if(rndup)
        {
                (void) memcpy(*xpp, nada, rndup);
                *xpp = (void *)((char *)(*xpp) + rndup);
        }
        
        return ENOERR;

}


/* opaque */

int
ncx_getn_void(const void **xpp, size_t nelems, void *tp)
{
        (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);
        return ENOERR;

}

int
ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
{
        size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(tp, *xpp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems + rndup);

        return ENOERR;

}

int
ncx_putn_void(void **xpp, size_t nelems, const void *tp)
{
        (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        return ENOERR;

}

int
ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
{
        size_t rndup = nelems % X_ALIGN;

        if(rndup)
                rndup = X_ALIGN - rndup;

        (void) memcpy(*xpp, tp, nelems);
        *xpp = (void *)((char *)(*xpp) + nelems);

        if(rndup)
        {
                (void) memcpy(*xpp, nada, rndup);
                *xpp = (void *)((char *)(*xpp) + rndup);
        }
        
        return ENOERR;

}