NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.

To learn about what's going on, see About the Archive Site.


[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;

}