/* Do not edit this file. It is produced from the corresponding .m4 source */
/*
 *  Copyright (C) 2014, Northwestern University and Argonne National Laboratory
 *  See COPYRIGHT notice in top-level directory.
 */
/* $Id$ */

#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif





#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>


#include <pnetcdf.h>
#include <pnc_debug.h>
#include <ncx.h>





#ifdef HAVE_INTTYPES_H
#include <inttypes.h> /* uint16_t, uint32_t, uint64_t */
#elif defined(HAVE_STDINT_H)
#include <stdint.h>   /* uint16_t, uint32_t, uint64_t */
#endif



/*
 * The only error code returned from subroutines in this file is NC_ERANGE,
 * if errors are detected.
 */

/*
 * An external data representation interface.
 */

/* alias poorly named limits.h macros */
#define  SHORT_MAX  SHRT_MAX
#define  SHORT_MIN  SHRT_MIN
#define USHORT_MAX USHRT_MAX
#ifndef LLONG_MAX
#   define LLONG_MAX	9223372036854775807LL
#   define LLONG_MIN	(-LLONG_MAX - 1LL)
#   define ULLONG_MAX	18446744073709551615ULL
#endif
#ifndef LONG_LONG_MAX
#define LONG_LONG_MAX LLONG_MAX
#endif
#ifndef LONGLONG_MAX
#define LONGLONG_MAX LONG_LONG_MAX
#endif
#ifndef LONG_LONG_MIN
#define LONG_LONG_MIN LLONG_MIN
#endif
#ifndef LONGLONG_MIN
#define LONGLONG_MIN LONG_LONG_MIN
#endif
#ifndef ULONG_LONG_MAX
#define ULONG_LONG_MAX ULLONG_MAX
#endif
#ifndef ULONGLONG_MAX
#define ULONGLONG_MAX ULONG_LONG_MAX
#endif
#include <float.h>
#ifndef FLT_MAX /* This POSIX macro missing on some systems */
# ifndef NO_IEEE_FLOAT
# define FLT_MAX 3.40282347e+38f
# else
# error "You will need to define FLT_MAX"
# endif
#endif
/* alias poorly named float.h macros */
#define FLOAT_MAX FLT_MAX
#define FLOAT_MIN (-FLT_MAX)
#define DOUBLE_MAX DBL_MAX
#define DOUBLE_MIN (-DBL_MAX)
#define FLOAT_MAX_EXP FLT_MAX_EXP
#define DOUBLE_MAX_EXP DBL_MAX_EXP
#include <assert.h>
#define UCHAR_MIN 0
#define Min(a,b) ((a) < (b) ? (a) : (b))
#define Max(a,b) ((a) > (b) ? (a) : (b))

#ifndef SIZEOF_UCHAR
#ifdef  SIZEOF_UNSIGNED_CHAR
#define SIZEOF_UCHAR SIZEOF_UNSIGNED_CHAR
#else
#error "unknown SIZEOF_UCHAR"
#endif
#endif

#ifndef SIZEOF_USHORT
#ifdef  SIZEOF_UNSIGNED_SHORT_INT
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT
#elif defined(SIZEOF_UNSIGNED_SHORT)
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT
#else
#error "unknown SIZEOF_USHORT"
#endif
#endif

#ifndef SIZEOF_UINT
#ifdef  SIZEOF_UNSIGNED_INT
#define SIZEOF_UINT SIZEOF_UNSIGNED_INT
#else
#error "unknown SIZEOF_UINT"
#endif
#endif

#ifndef SIZEOF_LONGLONG
#ifdef  SIZEOF_LONG_LONG
#define SIZEOF_LONGLONG SIZEOF_LONG_LONG
#else
#error "unknown SIZEOF_LONGLONG"
#endif
#endif

#ifndef SIZEOF_INT64
#ifdef  SIZEOF_LONG_LONG
#define SIZEOF_INT64 SIZEOF_LONG_LONG
#elif defined(SIZEOF_LONGLONG)
#define SIZEOF_INT64 SIZEOF_LONGLONG
#else
#error "unknown SIZEOF_INT64"
#endif
#endif

#ifndef SIZEOF_ULONGLONG
#ifdef  SIZEOF_UNSIGNED_LONG_LONG
#define SIZEOF_ULONGLONG SIZEOF_UNSIGNED_LONG_LONG
#else
#error "unknown SIZEOF_ULONGLONG"
#endif
#endif

#ifndef SIZEOF_UINT64
#ifdef  SIZEOF_UNSIGNED_LONG_LONG
#define SIZEOF_UINT64 SIZEOF_UNSIGNED_LONG_LONG
#elif defined(SIZEOF_ULONGLONG)
#define SIZEOF_UINT64 SIZEOF_ULONGLONG
#else
#error "unknown SIZEOF_UINT64"
#endif
#endif

/*
 * If the machine's float domain is "smaller" than the external one
 * use the machine domain
 */
#if defined(FLT_MAX_EXP) && FLT_MAX_EXP < 128 /* 128 is X_FLT_MAX_EXP */
#undef X_FLOAT_MAX
# define X_FLOAT_MAX FLT_MAX
#undef X_FLOAT_MIN
# define X_FLOAT_MIN (-X_FLOAT_MAX)
#endif

#if defined(_SX) && _SX != 0 /* NEC SUPER UX */
#define LOOPCNT 256    /* must be no longer than hardware vector length */
#if _INT64
#undef  INT_MAX /* workaround cpp bug */
#define INT_MAX  X_INT_MAX
#undef  INT_MIN /* workaround cpp bug */
#define INT_MIN  X_INT_MIN
#undef  LONG_MAX /* workaround cpp bug */
#define LONG_MAX  X_INT_MAX
#undef  LONG_MIN /* workaround cpp bug */
#define LONG_MIN  X_INT_MIN
#elif _LONG64
#undef  LONG_MAX /* workaround cpp bug */
#define LONG_MAX  4294967295L
#undef  LONG_MIN /* workaround cpp bug */
#define LONG_MIN -4294967295L
#endif
#if !_FLOAT0
#error "FLOAT1 and FLOAT2 not supported"
#endif
#endif /* _SX */

/* Note nada[] is used to fill the padding. However, CDF file format
 * specifications require different contents between header and data sections.
 * It says "Header padding uses null (\x00) bytes. In data, padding uses
 * variable's fill value." Please be warned that PnetCDF has not implemented
 * this for data section and still uses nadap[] for padding.
 */
static const char nada[X_ALIGN] = {0, 0, 0, 0};

#ifndef WORDS_BIGENDIAN
/* LITTLE_ENDIAN: DEC and intel */
/*
 * Routines to convert to BIG ENDIAN.
 * Optimize the swapn?b() and swap?b() routines aggressively.
 */

#define SWAP2(a) ( (((a) & 0xff) << 8) | \
                   (((a) >> 8) & 0xff) )

#define SWAP4(a) ( ((a) << 24) | \
                  (((a) <<  8) & 0x00ff0000) | \
                  (((a) >>  8) & 0x0000ff00) | \
                  (((a) >> 24) & 0x000000ff) )

#define SWAP8(a) ( (((a) & 0x00000000000000FFULL) << 56) | \
                   (((a) & 0x000000000000FF00ULL) << 40) | \
                   (((a) & 0x0000000000FF0000ULL) << 24) | \
                   (((a) & 0x00000000FF000000ULL) <<  8) | \
                   (((a) & 0x000000FF00000000ULL) >>  8) | \
                   (((a) & 0x0000FF0000000000ULL) >> 24) | \
                   (((a) & 0x00FF000000000000ULL) >> 40) | \
                   (((a) & 0xFF00000000000000ULL) >> 56) )


static void
swapn2b(void *dst, const void *src, MPI_Offset nn)
{
    /* it is OK if dst == src */
    int i;
    uint16_t *op = (uint16_t*) dst;
    uint16_t *ip = (uint16_t*) src;
    for (i=0; i<nn; i++) {
        uint16_t tmp = ip[i];
        op[i] = (uint16_t)SWAP2(tmp);
    }
}

# ifndef vax
static void
swap4b(void *dst, const void *src)
{
    /* copy over, make the below swap in-place */
    uint32_t dst_tmp, src_tmp = *(uint32_t*)src;
    dst_tmp = SWAP4(src_tmp);
    memcpy(dst, &dst_tmp, 4);

    /* Codes below will cause "break strict-aliasing rules" in gcc
    uint32_t *op = (uint32_t*)dst;
    *op = *(uint32_t*)src;
    *op = SWAP4(*op);
    */
}
# endif /* !vax */

static void
swapn4b(void *dst, const void *src, MPI_Offset nn)
{
    int i;
    uint32_t *op = (uint32_t*) dst;
    uint32_t *ip = (uint32_t*) src;
    for (i=0; i<nn; i++) {
        uint32_t tmp = ip[i];
        op[i] = SWAP4(tmp);
    }
}

# ifndef vax
static void
swap8b(void *dst, const void *src)
{
#ifdef FLOAT_WORDS_BIGENDIAN
    /* copy over, make the below swap in-place */
    *(uint64_t*)dst = *(uint64_t*)src;

    uint32_t *op = (uint32_t*)dst;
    *op = SWAP4(*op);
    op = (uint32_t*)((char*)dst+4);
    *op = SWAP4(*op);
#else
    uint64_t tmp = *(uint64_t*)src;
    tmp = SWAP8(tmp);
    memcpy(dst, &tmp, 8);

    /* Codes below will cause "break strict-aliasing rules" in gcc
    uint64_t *op = (uint64_t*)dst;
    *op = *(uint64_t*)src;
    *op = SWAP8(*op);
    */
#endif
}
# endif /* !vax */

# ifndef vax
static void
swapn8b(void *dst, const void *src, MPI_Offset nn)
{
#if 0
#ifdef FLOAT_WORDS_BIGENDIAN
    int i;
    uint64_t *dst_p = (uint64_t*) dst;
    uint64_t *src_p = (uint64_t*) src;
    for (i=0; i<nn; i++) {
        /* copy over, make the below swap in-place */
        dst_p[i] = src_p[i];
        uint32_t *op = (uint32_t*)(&dst_p[i]);
        *op = SWAP4(*op);
        op = (uint32_t*)((char*)op+4);
        *op = SWAP4(*op);
    }
#else
    int i;
    uint64_t *op = (uint64_t*) dst;
    uint64_t *ip = (uint64_t*) src;
    for (i=0; i<nn; i++) {
        /* copy over, make the below swap in-place */
        op[i] = ip[i];
        op[i] = SWAP8(op[i]); /* Using gcc/clang -fsanitize=undefined causes:
                                 runtime error: store to misaligned address
                                 for type 'uint64_t', which requires 8 byte
                                 alignment */
    }
#endif

#else
	char *op = dst;
	const char *ip = src;

/* unroll the following to reduce loop overhead
 *	while (nn-- > 0)
 *	{
 *		op[0] = ip[7];
 *		op[1] = ip[6];
 *		op[2] = ip[5];
 *		op[3] = ip[4];
 *		op[4] = ip[3];
 *		op[5] = ip[2];
 *		op[6] = ip[1];
 *		op[7] = ip[0];
 *		op += 8;
 *		ip += 8;
 *	}
 */
#  ifndef FLOAT_WORDS_BIGENDIAN
	while (nn > 1)
	{
		op[0] = ip[7];
		op[1] = ip[6];
		op[2] = ip[5];
		op[3] = ip[4];
		op[4] = ip[3];
		op[5] = ip[2];
		op[6] = ip[1];
		op[7] = ip[0];
		op[8] = ip[15];
		op[9] = ip[14];
		op[10] = ip[13];
		op[11] = ip[12];
		op[12] = ip[11];
		op[13] = ip[10];
		op[14] = ip[9];
		op[15] = ip[8];
		op += 16;
		ip += 16;
		nn -= 2;
	}
	while (nn-- > 0)
	{
		op[0] = ip[7];
		op[1] = ip[6];
		op[2] = ip[5];
		op[3] = ip[4];
		op[4] = ip[3];
		op[5] = ip[2];
		op[6] = ip[1];
		op[7] = ip[0];
		op += 8;
		ip += 8;
	}
#  else
	while (nn-- > 0)
	{
		op[0] = ip[3];
		op[1] = ip[2];
		op[2] = ip[1];
		op[3] = ip[0];
		op[4] = ip[7];
		op[5] = ip[6];
		op[6] = ip[5];
		op[7] = ip[4];
		op += 8;
		ip += 8;
	}
#endif
#endif
}
# endif /* !vax */

#endif /* LITTLE_ENDIAN */






/*
 * Primitive numeric conversion functions.
 */





/* x_schar */
/* x_uchar */

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


/* external NC_SHORT --------------------------------------------------------*/

#if SHORT_MAX == X_SHORT_MAX
typedef short ix_short;
#define SIZEOF_IX_SHORT SIZEOF_SHORT
#define IX_SHORT_MAX SHORT_MAX
#elif INT_MAX >= X_SHORT_MAX
typedef int ix_short;
#define SIZEOF_IX_SHORT SIZEOF_INT
#define IX_SHORT_MAX INT_MAX
#elif LONG_MAX >= X_SHORT_MAX
typedef long ix_short;
#define SIZEOF_IX_SHORT SIZEOF_LONG
#define IX_SHORT_MAX LONG_MAX
#elif LLONG_MAX >= X_SHORT_MAX
typedef long long ix_short;
#define SIZEOF_IX_SHORT SIZEOF_LONGLONG
#define IX_SHORT_MAX LLONG_MAX
#else
#error "ix_short implementation"
#endif

static void
get_ix_short(const void *xp, ix_short *ip)
{
	const uchar *cp = (const uchar *) xp;
	*ip = (ix_short)(*cp++) << 8;
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
	if (*ip & 0x8000)
	{
		/* extern is negative */
		*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
	}
#endif
	*ip = (ix_short)(*ip | *cp);
}

static void
put_ix_short(void *xp, const ix_short *ip)
{
	uchar *cp = (uchar *) xp;
	*cp++ = (uchar)(*ip >> 8);
	*cp   = (uchar)(*ip & 0xff);
}

static int
ncmpix_get_NC_SHORT_schar(const void *xp, schar *ip)
{
    int err=NC_NOERR;
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > SCHAR_MAX
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
        *ip = NC_FILL_BYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (schar) xx;
    return err;
}

static int
ncmpix_get_NC_SHORT_short(const void *xp, short *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
    get_ix_short(xp, (ix_short *)ip);
#else
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > SHORT_MAX
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
        *ip = NC_FILL_SHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (short) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_SHORT_int(const void *xp, int *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
    get_ix_short(xp, (ix_short *)ip);
#else
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > INT_MAX
    if (xx > INT_MAX || xx < INT_MIN) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (int) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_SHORT_long(const void *xp, long *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
    get_ix_short(xp, (ix_short *)ip);
#else
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > LONG_MAX
    if (xx > LONG_MAX || xx < LONG_MIN) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (long) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_SHORT_longlong(const void *xp, longlong *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
    get_ix_short(xp, (ix_short *)ip);
#else
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > LONGLONG_MAX
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
        *ip = NC_FILL_INT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (longlong) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_SHORT_ushort(const void *xp, ushort *ip)
{
    int err=NC_NOERR;
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > USHORT_MAX
    if (xx > USHORT_MAX) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (ushort) xx;
    return err;
}

static int
ncmpix_get_NC_SHORT_uchar(const void *xp, uchar *ip)
{
    int err=NC_NOERR;
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > UCHAR_MAX
    if (xx > UCHAR_MAX) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (uchar) xx;
    return err;
}

static int
ncmpix_get_NC_SHORT_uint(const void *xp, uint *ip)
{
    int err=NC_NOERR;
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > UINT_MAX
    if (xx > UINT_MAX) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (uint) xx;
    return err;
}

static int
ncmpix_get_NC_SHORT_ulonglong(const void *xp, ulonglong *ip)
{
    int err=NC_NOERR;
    ix_short xx;
    get_ix_short(xp, &xx);

#if IX_SHORT_MAX > ULONGLONG_MAX
    if (xx > ULONGLONG_MAX) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (ulonglong) xx;
    return err;
}

static int
ncmpix_get_NC_SHORT_float(const void *xp, float *ip)
{
	ix_short xx;
	get_ix_short(xp, &xx);
	*ip = (float)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_SHORT_double(const void *xp, double *ip)
{
	ix_short xx;
	get_ix_short(xp, &xx);
	*ip = (double)xx;
	return NC_NOERR;
}


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

static int
ncmpix_put_NC_SHORT_uchar(void *xp, const uchar *ip, void *fillp)
{
	uchar *cp = (uchar *) xp;
	*cp++ = 0;
	*cp = *ip;
	return NC_NOERR;
}

static int
ncmpix_put_NC_SHORT_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_SHORT && IX_SHORT_MAX == SHORT_MAX
    put_ix_short(xp, (const ix_short *)ip);
#else
    ix_short xx = NC_FILL_SHORT;

#if IX_SHORT_MAX < SHORT_MAX
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_SHORT_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_INT && IX_SHORT_MAX == INT_MAX
    put_ix_short(xp, (const ix_short *)ip);
#else
    ix_short xx = NC_FILL_SHORT;

#if IX_SHORT_MAX < INT_MAX
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_SHORT_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_LONG && IX_SHORT_MAX == LONG_MAX
    put_ix_short(xp, (const ix_short *)ip);
#else
    ix_short xx = NC_FILL_SHORT;

#if IX_SHORT_MAX < LONG_MAX
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_SHORT_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_SHORT == SIZEOF_LONGLONG && IX_SHORT_MAX == LONGLONG_MAX
    put_ix_short(xp, (const ix_short *)ip);
#else
    ix_short xx = NC_FILL_SHORT;

#if IX_SHORT_MAX < LONGLONG_MAX
    if (*ip > IX_SHORT_MAX || *ip < X_SHORT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_SHORT_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_short xx = NC_FILL_SHORT;

#if IX_SHORT_MAX < USHORT_MAX
    if (*ip > IX_SHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_SHORT_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_short xx = NC_FILL_SHORT;

#if IX_SHORT_MAX < UINT_MAX
    if (*ip > IX_SHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_SHORT_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_short xx = NC_FILL_SHORT;

#if IX_SHORT_MAX < ULONGLONG_MAX
    if (*ip > IX_SHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_SHORT_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_short xx = NC_FILL_SHORT;

    if (*ip > (double)X_SHORT_MAX || *ip < (double)X_SHORT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_SHORT_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_short xx = NC_FILL_SHORT;

    if (*ip > (double)X_SHORT_MAX || *ip < X_SHORT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_short)*ip;

    put_ix_short(xp, &xx);
    return err;
}


/* external NC_USHORT -------------------------------------------------------*/

#if USHORT_MAX == X_USHORT_MAX
typedef unsigned short ix_ushort;
#define SIZEOF_IX_USHORT SIZEOF_USHORT
#define IX_USHORT_MAX USHORT_MAX
#elif UINT_MAX >= X_USHORT_MAX
typedef unsigned int ix_ushort;
#define SIZEOF_IX_USHORT SIZEOF_UINT
#define IX_USHORT_MAX UINT_MAX
#elif ULONG_MAX >= X_USHORT_MAX
typedef unsigned long ix_ushort;
#define SIZEOF_IX_USHORT SIZEOF_ULONG
#define IX_USHORT_MAX ULONG_MAX
#elif ULLONG_MAX >= X_USHORT_MAX
typedef unsigned long long ix_ushort;
#define SIZEOF_IX_USHORT SIZEOF_ULONGLONG
#define IX_USHORT_MAX ULLONG_MAX
#else
#error "ix_ushort implementation"
#endif

static void
get_ix_ushort(const void *xp, ix_ushort *ip)
{
	const uchar *cp = (const uchar *) xp;
	*ip = (ix_ushort)(*cp++) << 8;
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
	if (*ip & 0x8000)
	{
		/* extern is negative */
		*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
	}
#endif
	*ip = (ix_ushort)(*ip | *cp);
}

static void
put_ix_ushort(void *xp, const ix_ushort *ip)
{
	uchar *cp = (uchar *) xp;
	*cp++ = (uchar)(*ip >> 8);
	*cp   = (uchar)(*ip & 0xff);
}

static int
ncmpix_get_NC_USHORT_schar(const void *xp, schar *ip)
{
    int err=NC_NOERR;
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > SCHAR_MAX
    if (xx > SCHAR_MAX) {
        *ip = NC_FILL_BYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (schar) xx;
    return err;
}

static int
ncmpix_get_NC_USHORT_short(const void *xp, short *ip)
{
    int err=NC_NOERR;
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > SHORT_MAX
    if (xx > SHORT_MAX) {
        *ip = NC_FILL_SHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (short) xx;
    return err;
}

static int
ncmpix_get_NC_USHORT_int(const void *xp, int *ip)
{
    int err=NC_NOERR;
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > INT_MAX
    if (xx > INT_MAX) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (int) xx;
    return err;
}

static int
ncmpix_get_NC_USHORT_long(const void *xp, long *ip)
{
    int err=NC_NOERR;
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > LONG_MAX
    if (xx > LONG_MAX) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (long) xx;
    return err;
}

static int
ncmpix_get_NC_USHORT_longlong(const void *xp, longlong *ip)
{
    int err=NC_NOERR;
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > LONGLONG_MAX
    if (xx > LONGLONG_MAX) {
        *ip = NC_FILL_INT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (longlong) xx;
    return err;
}

static int
ncmpix_get_NC_USHORT_ushort(const void *xp, ushort *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
    get_ix_ushort(xp, (ix_ushort *)ip);
#else
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > USHORT_MAX
    if (xx > USHORT_MAX) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (ushort) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_USHORT_uchar(const void *xp, uchar *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_USHORT == SIZEOF_UCHAR && IX_USHORT_MAX == UCHAR_MAX
    get_ix_ushort(xp, (ix_ushort *)ip);
#else
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > UCHAR_MAX
    if (xx > UCHAR_MAX) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (uchar) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_USHORT_uint(const void *xp, uint *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
    get_ix_ushort(xp, (ix_ushort *)ip);
#else
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > UINT_MAX
    if (xx > UINT_MAX) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (uint) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_USHORT_ulonglong(const void *xp, ulonglong *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
    get_ix_ushort(xp, (ix_ushort *)ip);
#else
    ix_ushort xx;
    get_ix_ushort(xp, &xx);

#if IX_USHORT_MAX > ULONGLONG_MAX
    if (xx > ULONGLONG_MAX) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (ulonglong) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_USHORT_float(const void *xp, float *ip)
{
	ix_ushort xx;
	get_ix_ushort(xp, &xx);
	*ip = (float)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_USHORT_double(const void *xp, double *ip)
{
	ix_ushort xx;
	get_ix_ushort(xp, &xx);
	*ip = (double)xx;
	return NC_NOERR;
}


static int
ncmpix_put_NC_USHORT_schar(void *xp, const schar *ip, void *fillp)
{
    int err=NC_NOERR;
    uchar *cp;
    if (*ip < 0) {
        if (fillp != NULL) memcpy(xp, fillp, 2);
#ifndef WORDS_BIGENDIAN
        swapn2b(xp, xp, 1);
#endif
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }

    cp = (uchar *) xp;
    if (*ip & 0x80)
        *cp++ = 0xff;
    else
        *cp++ = 0;
    *cp = (uchar)*ip;

    return err;
}

static int
ncmpix_put_NC_USHORT_uchar(void *xp, const uchar *ip, void *fillp)
{
	uchar *cp = (uchar *) xp;
	*cp++ = 0;
	*cp = *ip;
	return NC_NOERR;
}

static int
ncmpix_put_NC_USHORT_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_ushort xx = NC_FILL_USHORT;

#if IX_USHORT_MAX < SHORT_MAX
    if (*ip > IX_USHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_USHORT_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_ushort xx = NC_FILL_USHORT;

#if IX_USHORT_MAX < INT_MAX
    if (*ip > IX_USHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_USHORT_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_ushort xx = NC_FILL_USHORT;

#if IX_USHORT_MAX < LONG_MAX
    if (*ip > IX_USHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_USHORT_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_ushort xx = NC_FILL_USHORT;

#if IX_USHORT_MAX < LONGLONG_MAX
    if (*ip > IX_USHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_USHORT_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_USHORT == SIZEOF_USHORT && IX_USHORT_MAX == USHORT_MAX
    put_ix_ushort(xp, (const ix_ushort *)ip);
#else
    ix_ushort xx = NC_FILL_USHORT;

#if IX_USHORT_MAX < USHORT_MAX
    if (*ip > IX_USHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_USHORT_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_USHORT == SIZEOF_UINT && IX_USHORT_MAX == UINT_MAX
    put_ix_ushort(xp, (const ix_ushort *)ip);
#else
    ix_ushort xx = NC_FILL_USHORT;

#if IX_USHORT_MAX < UINT_MAX
    if (*ip > IX_USHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_USHORT_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_USHORT == SIZEOF_ULONGLONG && IX_USHORT_MAX == ULONGLONG_MAX
    put_ix_ushort(xp, (const ix_ushort *)ip);
#else
    ix_ushort xx = NC_FILL_USHORT;

#if IX_USHORT_MAX < ULONGLONG_MAX
    if (*ip > IX_USHORT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_USHORT_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_ushort xx = NC_FILL_USHORT;

    if (*ip > (double)X_USHORT_MAX || *ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_USHORT_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_ushort xx = NC_FILL_USHORT;

    if (*ip > (double)X_USHORT_MAX || *ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 2);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_ushort)*ip;

    put_ix_ushort(xp, &xx);
    return err;
}


/* external NC_INT ----------------------------------------------------------*/

#if SHORT_MAX == X_INT_MAX
typedef short ix_int;
#define SIZEOF_IX_INT SIZEOF_SHORT
#define IX_INT_MAX SHORT_MAX
#elif INT_MAX  >= X_INT_MAX
typedef int ix_int;
#define SIZEOF_IX_INT SIZEOF_INT
#define IX_INT_MAX INT_MAX
#elif LONG_MAX  >= X_INT_MAX
typedef long ix_int;
#define SIZEOF_IX_INT SIZEOF_LONG
#define IX_INT_MAX LONG_MAX
#else
#error "ix_int implementation"
#endif


#if USHORT_MAX == X_UINT_MAX
typedef ushort ix_uint;
#define SIZEOF_IX_UINT SIZEOF_USHORT
#define IX_UINT_MAX USHORT_MAX
#elif UINT_MAX  >= X_UINT_MAX
typedef uint ix_uint;
#define SIZEOF_IX_UINT SIZEOF_UINT
#define IX_UINT_MAX UINT_MAX
#elif ULONG_MAX  >= X_UINT_MAX
typedef ulong ix_uint;
#define SIZEOF_IX_UINT SIZEOF_ULONG
#define IX_UINT_MAX ULONG_MAX
#else
#error "ix_uint implementation"
#endif


static void
get_ix_int(const void *xp, ix_int *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(ip, xp, 4);
#else

    /* must use unsigned type to do byte swap. Otherwise, we may get error
     * message below when using "-fsanitize=undefined" compile flag:
     * runtime error: left shift of 1618607871 by 8 places cannot be
     * represented in type 'int'
     */

    ix_uint tmp;
    memcpy(&tmp, xp, 4);
    *ip = SWAP4(tmp);
#endif
}

static void
put_ix_int(void *xp, const ix_int *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(xp, ip, 4);
#else

    /* must use unsigned type to do byte swap. Otherwise, we may get error
     * message below when using "-fsanitize=undefined" compile flag:
     * runtime error: left shift of 1618607871 by 8 places cannot be
     * represented in type 'int'
     */

    ix_uint xtmp;
    memcpy(&xtmp, ip, 4);
    xtmp = SWAP4(xtmp);
    memcpy(xp, &xtmp, 4);
#endif
}

#if X_SIZEOF_INT != SIZEOF_INT
static int
ncmpix_get_NC_INT_int(const void *xp, int *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
    get_ix_int(xp, (ix_int *)ip);
#else
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > INT_MAX
    if (xx > INT_MAX || xx < INT_MIN) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (int) xx;
#endif
    return err;
}

#endif
static int
ncmpix_get_NC_INT_schar(const void *xp, schar *ip)
{
    int err=NC_NOERR;
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > SCHAR_MAX
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
        *ip = NC_FILL_BYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (schar) xx;
    return err;
}

static int
ncmpix_get_NC_INT_short(const void *xp, short *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
    get_ix_int(xp, (ix_int *)ip);
#else
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > SHORT_MAX
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
        *ip = NC_FILL_SHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (short) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_INT_long(const void *xp, long *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
    get_ix_int(xp, (ix_int *)ip);
#else
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > LONG_MAX
    if (xx > LONG_MAX || xx < LONG_MIN) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (long) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_INT_longlong(const void *xp, longlong *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
    get_ix_int(xp, (ix_int *)ip);
#else
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > LONGLONG_MAX
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
        *ip = NC_FILL_INT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (longlong) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_INT_ushort(const void *xp, ushort *ip)
{
    int err=NC_NOERR;
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > USHORT_MAX
    if (xx > USHORT_MAX) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (ushort) xx;
    return err;
}

static int
ncmpix_get_NC_INT_uchar(const void *xp, uchar *ip)
{
    int err=NC_NOERR;
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > UCHAR_MAX
    if (xx > UCHAR_MAX) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (uchar) xx;
    return err;
}

static int
ncmpix_get_NC_INT_uint(const void *xp, uint *ip)
{
    int err=NC_NOERR;
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > UINT_MAX
    if (xx > UINT_MAX) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (uint) xx;
    return err;
}

static int
ncmpix_get_NC_INT_ulonglong(const void *xp, ulonglong *ip)
{
    int err=NC_NOERR;
    ix_int xx;
    get_ix_int(xp, &xx);

#if IX_INT_MAX > ULONGLONG_MAX
    if (xx > ULONGLONG_MAX) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (ulonglong) xx;
    return err;
}

static int
ncmpix_get_NC_INT_float(const void *xp, float *ip)
{
	ix_int xx;
	get_ix_int(xp, &xx);
	*ip = (float)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_INT_double(const void *xp, double *ip)
{
	ix_int xx;
	get_ix_int(xp, &xx);
	*ip = (double)xx;
	return NC_NOERR;
}


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

static int
ncmpix_put_NC_INT_uchar(void *xp, const uchar *ip, void *fillp)
{
	uchar *cp = (uchar *) xp;
	*cp++ = 0x00;
	*cp++ = 0x00;
	*cp++ = 0x00;
	*cp   = *ip;
	return NC_NOERR;
}

#if X_SIZEOF_INT != SIZEOF_INT
static int
ncmpix_put_NC_INT_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_INT && IX_INT_MAX == INT_MAX
    put_ix_int(xp, (const ix_int *)ip);
#else
    ix_int xx = NC_FILL_INT;

#if IX_INT_MAX < INT_MAX
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
#endif
    return err;
}

#endif
static int
ncmpix_put_NC_INT_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_SHORT && IX_INT_MAX == SHORT_MAX
    put_ix_int(xp, (const ix_int *)ip);
#else
    ix_int xx = NC_FILL_INT;

#if IX_INT_MAX < SHORT_MAX
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_INT_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_LONG && IX_INT_MAX == LONG_MAX
    put_ix_int(xp, (const ix_int *)ip);
#else
    ix_int xx = NC_FILL_INT;

#if IX_INT_MAX < LONG_MAX
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_INT_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT == SIZEOF_LONGLONG && IX_INT_MAX == LONGLONG_MAX
    put_ix_int(xp, (const ix_int *)ip);
#else
    ix_int xx = NC_FILL_INT;

#if IX_INT_MAX < LONGLONG_MAX
    if (*ip > IX_INT_MAX || *ip < X_INT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_INT_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int xx = NC_FILL_INT;

#if IX_INT_MAX < USHORT_MAX
    if (*ip > IX_INT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int xx = NC_FILL_INT;

#if IX_INT_MAX < UINT_MAX
    if (*ip > IX_INT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int xx = NC_FILL_INT;

#if IX_INT_MAX < ULONGLONG_MAX
    if (*ip > IX_INT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int xx = NC_FILL_INT;

    if (*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int xx = NC_FILL_INT;

    if (*ip > (double)X_INT_MAX || *ip < X_INT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_int)*ip;

    put_ix_int(xp, &xx);
    return err;
}



/* external NC_UINT ---------------------------------------------------------*/

static void
get_ix_uint(const void *xp, ix_uint *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(ip, xp, 4);
#else
    ix_uint tmp;
    memcpy(&tmp, xp, 4);
    *ip = SWAP4(tmp);
#endif
}

static void
put_ix_uint(void *xp, const ix_uint *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(xp, ip, 4);
#else
    ix_uint xtmp, itmp = *ip;
    xtmp = SWAP4(itmp);
    memcpy(xp, &xtmp, 4);
#endif
}

#if X_SIZEOF_UINT != SIZEOF_UINT
static int
ncmpix_get_NC_UINT_uint(const void *xp, uint *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
    get_ix_uint(xp, (ix_uint *)ip);
#else
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > UINT_MAX
    if (xx > UINT_MAX) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (uint) xx;
#endif
    return err;
}

#endif

static int
ncmpix_get_NC_UINT_schar(const void *xp, schar *ip)
{
    int err=NC_NOERR;
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > SCHAR_MAX
    if (xx > SCHAR_MAX) {
        *ip = NC_FILL_BYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (schar) xx;
    return err;
}

static int
ncmpix_get_NC_UINT_short(const void *xp, short *ip)
{
    int err=NC_NOERR;
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > SHORT_MAX
    if (xx > SHORT_MAX) {
        *ip = NC_FILL_SHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (short) xx;
    return err;
}

static int
ncmpix_get_NC_UINT_int(const void *xp, int *ip)
{
    int err=NC_NOERR;
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > INT_MAX
    if (xx > INT_MAX) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (int) xx;
    return err;
}

static int
ncmpix_get_NC_UINT_long(const void *xp, long *ip)
{
    int err=NC_NOERR;
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > LONG_MAX
    if (xx > LONG_MAX) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (long) xx;
    return err;
}

static int
ncmpix_get_NC_UINT_longlong(const void *xp, longlong *ip)
{
    int err=NC_NOERR;
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > LONGLONG_MAX
    if (xx > LONGLONG_MAX) {
        *ip = NC_FILL_INT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (longlong) xx;
    return err;
}

static int
ncmpix_get_NC_UINT_ushort(const void *xp, ushort *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
    get_ix_uint(xp, (ix_uint *)ip);
#else
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > USHORT_MAX
    if (xx > USHORT_MAX) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (ushort) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_UINT_uchar(const void *xp, uchar *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT == SIZEOF_UCHAR && IX_UINT_MAX == UCHAR_MAX
    get_ix_uint(xp, (ix_uint *)ip);
#else
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > UCHAR_MAX
    if (xx > UCHAR_MAX) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (uchar) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_UINT_ulonglong(const void *xp, ulonglong *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
    get_ix_uint(xp, (ix_uint *)ip);
#else
    ix_uint xx;
    get_ix_uint(xp, &xx);

#if IX_UINT_MAX > ULONGLONG_MAX
    if (xx > ULONGLONG_MAX) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (ulonglong) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_UINT_float(const void *xp, float *ip)
{
	ix_uint xx;
	get_ix_uint(xp, &xx);
	*ip = (float)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_UINT_double(const void *xp, double *ip)
{
	ix_uint xx;
	get_ix_uint(xp, &xx);
	*ip = (double)xx;
	return NC_NOERR;
}


static int
ncmpix_put_NC_UINT_schar(void *xp, const schar *ip, void *fillp)
{
    uchar *cp;
    if (*ip < 0) {
        if (fillp != NULL) memcpy(xp, fillp, 4);
#ifndef WORDS_BIGENDIAN
        swapn4b(xp, xp, 1);
#endif
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }

    cp = (uchar *) xp;
    *cp++ = 0x00;
    *cp++ = 0x00;
    *cp++ = 0x00;
    *cp = (uchar)*ip;

    return NC_NOERR;
}

static int
ncmpix_put_NC_UINT_uchar(void *xp, const uchar *ip, void *fillp)
{
	uchar *cp = (uchar *) xp;
	*cp++ = 0x00;
	*cp++ = 0x00;
	*cp++ = 0x00;
	*cp   = *ip;
	return NC_NOERR;
}

#if X_SIZEOF_UINT != SIZEOF_UINT
static int
ncmpix_put_NC_UINT_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT == SIZEOF_UINT && IX_UINT_MAX == UINT_MAX
    put_ix_uint(xp, (const ix_uint *)ip);
#else
    ix_uint xx = NC_FILL_UINT;

#if IX_UINT_MAX < UINT_MAX
    if (*ip > IX_UINT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
#endif
    return err;
}

#endif

static int
ncmpix_put_NC_UINT_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint xx = NC_FILL_UINT;

#if IX_UINT_MAX < SHORT_MAX
    if (*ip > IX_UINT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint xx = NC_FILL_UINT;

#if IX_UINT_MAX < INT_MAX
    if (*ip > IX_UINT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint xx = NC_FILL_UINT;

#if IX_UINT_MAX < LONG_MAX
    if (*ip > IX_UINT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint xx = NC_FILL_UINT;

#if IX_UINT_MAX < LONGLONG_MAX
    if (*ip > IX_UINT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT == SIZEOF_USHORT && IX_UINT_MAX == USHORT_MAX
    put_ix_uint(xp, (const ix_uint *)ip);
#else
    ix_uint xx = NC_FILL_UINT;

#if IX_UINT_MAX < USHORT_MAX
    if (*ip > IX_UINT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_UINT_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT == SIZEOF_ULONGLONG && IX_UINT_MAX == ULONGLONG_MAX
    put_ix_uint(xp, (const ix_uint *)ip);
#else
    ix_uint xx = NC_FILL_UINT;

#if IX_UINT_MAX < ULONGLONG_MAX
    if (*ip > IX_UINT_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_UINT_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint xx = NC_FILL_UINT;

    if (*ip > (double)X_UINT_MAX || *ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint xx = NC_FILL_UINT;

    if (*ip > (double)X_UINT_MAX || *ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_uint)*ip;

    put_ix_uint(xp, &xx);
    return err;
}



/* external NC_FLOAT --------------------------------------------------------*/

#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)

static void
get_ix_float(const void *xp, float *ip)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(ip, xp, SIZEOF_FLOAT);
#else
	swap4b(ip, xp);
#endif
}

static void
put_ix_float(void *xp, const float *ip)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(xp, ip, X_SIZEOF_FLOAT);
#else
	swap4b(xp, ip);
#endif
}

#elif defined(vax) && vax != 0

/* What IEEE single precision floating point looks like on a Vax */
struct	ieee_single {
	unsigned int	exp_hi       : 7;
	unsigned int	sign         : 1;
	unsigned int 	mant_hi      : 7;
	unsigned int	exp_lo       : 1;
	unsigned int	mant_lo_hi   : 8;
	unsigned int	mant_lo_lo   : 8;
};

/* Vax single precision floating point */
struct	vax_single {
	unsigned int	mantissa1 : 7;
	unsigned int	exp       : 8;
	unsigned int	sign      : 1;
	unsigned int	mantissa2 : 16;
};

#define VAX_SNG_BIAS	0x81
#define IEEE_SNG_BIAS	0x7f

static struct sgl_limits {
	struct vax_single s;
	struct ieee_single ieee;
} max = {
	{ 0x7f, 0xff, 0x0, 0xffff },	/* Max Vax */
	{ 0x7f, 0x0, 0x0, 0x1, 0x0, 0x0 }		/* Max IEEE */
};
static struct sgl_limits min = {
	{ 0x0, 0x0, 0x0, 0x0 },	/* Min Vax */
	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }		/* Min IEEE */
};

static void
get_ix_float(const void *xp, float *ip)
{
		struct vax_single *const vsp = (struct vax_single *) ip;
		const struct ieee_single *const isp =
			 (const struct ieee_single *) xp;
		unsigned exp = isp->exp_hi << 1 | isp->exp_lo;

		switch(exp) {
		case 0 :
			/* ieee subnormal */
			if (isp->mant_hi == min.ieee.mant_hi
				&& isp->mant_lo_hi == min.ieee.mant_lo_hi
				&& isp->mant_lo_lo == min.ieee.mant_lo_lo)
			{
				*vsp = min.s;
			}
			else
			{
				unsigned mantissa = (isp->mant_hi << 16)
					 | isp->mant_lo_hi << 8
					 | isp->mant_lo_lo;
				unsigned tmp = mantissa >> 20;
				if (tmp >= 4) {
					vsp->exp = 2;
				} else if (tmp >= 2) {
					vsp->exp = 1;
				} else {
					*vsp = min.s;
					break;
				} /* else */
				tmp = mantissa - (1 << (20 + vsp->exp ));
				tmp <<= 3 - vsp->exp;
				vsp->mantissa2 = tmp;
				vsp->mantissa1 = (tmp >> 16);
			}
			break;
		case 0xfe :
		case 0xff :
			*vsp = max.s;
			break;
		default :
			vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
			vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
			vsp->mantissa1 = isp->mant_hi;
		}

		vsp->sign = isp->sign;

}


static void
put_ix_float(void *xp, const float *ip)
{
		const struct vax_single *const vsp =
			 (const struct vax_single *)ip;
		struct ieee_single *const isp = (struct ieee_single *) xp;

		switch(vsp->exp){
		case 0 :
			/* all vax float with zero exponent map to zero */
			*isp = min.ieee;
			break;
		case 2 :
		case 1 :
		{
			/* These will map to subnormals */
			unsigned mantissa = (vsp->mantissa1 << 16)
					 | vsp->mantissa2;
			mantissa >>= 3 - vsp->exp;
			mantissa += (1 << (20 + vsp->exp));
			isp->mant_lo_lo = mantissa;
			isp->mant_lo_hi = mantissa >> 8;
			isp->mant_hi = mantissa >> 16;
			isp->exp_lo = 0;
			isp->exp_hi = 0;
		}
			break;
		case 0xff : /* max.s.exp */
			if (vsp->mantissa2 == max.s.mantissa2 &&
			    vsp->mantissa1 == max.s.mantissa1)
			{
				/* map largest vax float to ieee infinity */
				*isp = max.ieee;
				break;
			} /* else, fall thru */
		default :
		{
			unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
			isp->exp_hi = exp >> 1;
			isp->exp_lo = exp;
			isp->mant_lo_lo = vsp->mantissa2;
			isp->mant_lo_hi = vsp->mantissa2 >> 8;
			isp->mant_hi = vsp->mantissa1;
		}
		}

		isp->sign = vsp->sign;

}

	/* vax */
#elif defined(_CRAY) && !defined(__crayx1)

/*
 * Return the number of bytes until the next "word" boundary
 * N.B. This is based on the very weird YMP address structure,
 * which puts the address within a word in the leftmost 3 bits
 * of the address.
 */
static size_t
word_align(const void *vp)
{
	size_t rem = ((size_t)vp >> (64 - 3)) & 0x7;
	return (rem != 0);
}

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


static void
get_ix_float(const void *xp, float *ip)
{
	if (word_align(xp) == 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 void
put_ix_float(void *xp, const float *ip)
{
	if (word_align(xp) == 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)
	{
		/* NC_ERANGE => ieee Inf */
		isp->exp = 0xff;
		isp->mant = 0x0;
	}
	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 shift */
		const int rshift = (48 - 23 - ieee_exp);

		isp->mant = csp->mant >> rshift;

#if 0
		if (csp->mant & (1 << (rshift -1)))
		{
			/* round up */
			isp->mant++;
		}
#endif

		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)
	{
		/* NC_ERANGE => ieee Inf */
		isp->exp = 0xff;
		isp->mant = 0x0;
	}
	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 shift */
		const int rshift = (48 - 23 - ieee_exp);

		isp->mant = csp->mant >> rshift;

#if 0
		if (csp->mant & (1 << (rshift -1)))
		{
			/* round up */
			isp->mant++;
		}
#endif

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

	}
}

#else
	/* IEEE Cray with only doubles */
static void
get_ix_float(const void *xp, float *ip)
{
	ieee_double *idp = (ieee_double *) ip;

	if (word_align(xp) == 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 void
put_ix_float(void *xp, const float *ip)
{
	const ieee_double *idp = (const ieee_double *) ip;
	if (word_align(xp) == 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;
	}
}
#endif

#else
#error "ix_float implementation"
#endif

#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
static int
ncmpix_get_NC_FLOAT_float(const void *xp, float *ip, void *fillp)
{
	/* TODO */
	get_ix_float(xp, ip);
	return NC_NOERR;
}
#endif

#define ix_float float

static int
ncmpix_get_NC_FLOAT_schar(const void *xp, schar *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
            *ip = NC_FILL_BYTE;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (schar)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_short(const void *xp, short *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
            *ip = NC_FILL_SHORT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (short)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_int(const void *xp, int *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
            *ip = NC_FILL_INT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (int)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_long(const void *xp, long *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
            *ip = NC_FILL_INT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                if (xx == (double)LONG_MAX) *ip = LONG_MAX; else
        *ip = (long)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_double(const void *xp, double *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	*ip = (double)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_longlong(const void *xp, longlong *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx == (float)LONGLONG_MAX)      *ip = LONGLONG_MAX;
	else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
	else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
            *ip = NC_FILL_INT64;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
	else *ip = (longlong)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_uchar(const void *xp, uchar *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx > (double)UCHAR_MAX || xx < 0) {
            *ip = NC_FILL_UBYTE;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (uchar)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_ushort(const void *xp, ushort *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx > (double)USHORT_MAX || xx < 0) {
            *ip = NC_FILL_USHORT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (ushort)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_uint(const void *xp, uint *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx > (double)UINT_MAX || xx < 0) {
            *ip = NC_FILL_UINT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (uint)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_FLOAT_ulonglong(const void *xp, ulonglong *ip)
{
	ix_float xx;
	get_ix_float(xp, &xx);
	if (xx == (float)ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
	else if (xx > (double)ULONGLONG_MAX || xx < 0) {
            *ip = NC_FILL_UINT64;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
	else *ip = (ulonglong)xx;
	return NC_NOERR;
}


#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
static int
ncmpix_put_NC_FLOAT_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    float *_ip=ip;
#ifdef NO_IEEE_FLOAT
    float tmp;
    if (*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
        if (fillp != NULL) memcpy(&tmp, fillp, 4);
        _ip = &tmp;
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    }
#endif
    put_ix_float(xp, _ip);
    return err;
}
#endif

static int
ncmpix_put_NC_FLOAT_schar(void *xp, const schar *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    if (*ip > (double)X_FLOAT_MAX || *ip < X_FLOAT_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 4);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_uchar(void *xp, const uchar *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_FLOAT_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_float xx = NC_FILL_FLOAT;

    
        xx = (ix_float)*ip;

    put_ix_float(xp, &xx);
    return err;
}



/* external NC_DOUBLE -------------------------------------------------------*/

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

static void
get_ix_double(const void *xp, double *ip)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(ip, xp, SIZEOF_DOUBLE);
#else
	swap8b(ip, xp);
#endif
}

static void
put_ix_double(void *xp, const double *ip)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(xp, ip, X_SIZEOF_DOUBLE);
#else
	swap8b(xp, ip);
#endif
}

#elif defined(vax) && vax != 0

/* What IEEE double precision floating point looks like on a Vax */
struct	ieee_double {
	unsigned int	exp_hi   : 7;
	unsigned int	sign     : 1;
	unsigned int 	mant_6   : 4;
	unsigned int	exp_lo   : 4;
	unsigned int	mant_5   : 8;
	unsigned int	mant_4   : 8;

	unsigned int	mant_lo  : 32;
};

/* Vax double precision floating point */
struct  vax_double {
	unsigned int	mantissa1 : 7;
	unsigned int	exp       : 8;
	unsigned int	sign      : 1;
	unsigned int	mantissa2 : 16;
	unsigned int	mantissa3 : 16;
	unsigned int	mantissa4 : 16;
};

#define VAX_DBL_BIAS	0x81
#define IEEE_DBL_BIAS	0x3ff
#define MASK(nbits)	((1 << nbits) - 1)

static const struct dbl_limits {
	struct	vax_double d;
	struct	ieee_double ieee;
} dbl_limits[2] = {
	{{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },	/* Max Vax */
	{ 0x7f, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0}}, /* Max IEEE */
	{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},		/* Min Vax */
	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}, /* Min IEEE */
};


static void
get_ix_double(const void *xp, double *ip)
{
	struct vax_double *const vdp =
			 (struct vax_double *)ip;
	const struct ieee_double *const idp =
			 (const struct ieee_double *) xp;
	{
		const struct dbl_limits *lim;
		int ii;
		for (ii = 0, lim = dbl_limits;
			ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
			ii++, lim++)
		{
			if ((idp->mant_lo == lim->ieee.mant_lo)
				&& (idp->mant_4 == lim->ieee.mant_4)
				&& (idp->mant_5 == lim->ieee.mant_5)
				&& (idp->mant_6 == lim->ieee.mant_6)
				&& (idp->exp_lo == lim->ieee.exp_lo)
				&& (idp->exp_hi == lim->ieee.exp_hi)
				)
			{
				*vdp = lim->d;
				goto doneit;
			}
		}
	}
	{
		unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
		vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
	}
	{
		unsigned mant_hi = ((idp->mant_6 << 16)
				 | (idp->mant_5 << 8)
				 | idp->mant_4);
		unsigned mant_lo = SWAP4(idp->mant_lo);
		vdp->mantissa1 = (mant_hi >> 13);
		vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
				| (mant_lo >> 29);
		vdp->mantissa3 = (mant_lo >> 13);
		vdp->mantissa4 = (mant_lo << 3);
	}
	doneit:
		vdp->sign = idp->sign;

}


static void
put_ix_double(void *xp, const double *ip)
{
	const struct vax_double *const vdp =
			(const struct vax_double *)ip;
	struct ieee_double *const idp =
			 (struct ieee_double *) xp;

	if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
		(vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
		(vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
		(vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
		(vdp->exp == dbl_limits[0].d.exp))
	{
		*idp = dbl_limits[0].ieee;
		goto shipit;
	}
	if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
		(vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
		(vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
		(vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
		(vdp->exp == dbl_limits[1].d.exp))
	{
		*idp = dbl_limits[1].ieee;
		goto shipit;
	}

	{
		unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;

		unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
			(vdp->mantissa3 << 13) |
			((vdp->mantissa4 >> 3) & MASK(13));

		unsigned mant_hi = (vdp->mantissa1 << 13)
				 | (vdp->mantissa2 >> 3);

		if ((vdp->mantissa4 & 7) > 4)
		{
			/* round up */
			mant_lo++;
			if (mant_lo == 0)
			{
				mant_hi++;
				if (mant_hi > 0xffffff)
				{
					mant_hi = 0;
					exp++;
				}
			}
		}

		idp->mant_lo = SWAP4(mant_lo);
		idp->mant_6 = mant_hi >> 16;
		idp->mant_5 = (mant_hi & 0xff00) >> 8;
		idp->mant_4 = mant_hi;
		idp->exp_hi = exp >> 4;
		idp->exp_lo = exp;
	}

	shipit:
		idp->sign = vdp->sign;

}

	/* vax */
#elif defined(_CRAY) && !defined(__crayx1)

static void
get_ix_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 void
put_ix_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;
	}
	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 shift */
		const int lshift = (52 - 48) + ieee_exp;
		idp->mant = csp->mant << lshift;
		idp->exp  = 0;
	}
	else if (ieee_exp >= -52)
	{
		/* ieee subnormal, right shift */
		const int rshift = (- (52 - 48) - ieee_exp);

		idp->mant = csp->mant >> rshift;

#if 0
		if (csp->mant & (1 << (rshift -1)))
		{
			/* round up */
			idp->mant++;
		}
#endif

		idp->exp  = 0;
	}
	else
	{
		/* smaller than ieee can represent */
		idp->exp = 0;
		idp->mant = 0;
	}
}
#else
#error "ix_double implementation"
#endif

#define ix_double double

static int
ncmpix_get_NC_DOUBLE_schar(const void *xp, schar *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx > (double)SCHAR_MAX || xx < (double)SCHAR_MIN) {
            *ip = NC_FILL_BYTE;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (schar)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_short(const void *xp, short *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx > (double)SHORT_MAX || xx < (double)SHORT_MIN) {
            *ip = NC_FILL_SHORT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (short)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_int(const void *xp, int *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx > (double)INT_MAX || xx < (double)INT_MIN) {
            *ip = NC_FILL_INT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (int)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_long(const void *xp, long *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx > (double)LONG_MAX || xx < (double)LONG_MIN) {
            *ip = NC_FILL_INT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                if (xx == (double)LONG_MAX) *ip = LONG_MAX; else
        *ip = (long)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_longlong(const void *xp, longlong *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx == (double)LONGLONG_MAX)      *ip = LONGLONG_MAX;
	else if (xx == LONGLONG_MIN) *ip = LONGLONG_MIN;
	else if (xx > (double)LONGLONG_MAX || xx < (double)LONGLONG_MIN) {
            *ip = NC_FILL_INT64;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
	else *ip = (longlong)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_uchar(const void *xp, uchar *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx > (double)UCHAR_MAX || xx < 0) {
            *ip = NC_FILL_UBYTE;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (uchar)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_ushort(const void *xp, ushort *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx > (double)USHORT_MAX || xx < 0) {
            *ip = NC_FILL_USHORT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (ushort)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_uint(const void *xp, uint *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx > (double)UINT_MAX || xx < 0) {
            *ip = NC_FILL_UINT;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
                                
        *ip = (uint)xx;

	return NC_NOERR;
}

static int
ncmpix_get_NC_DOUBLE_ulonglong(const void *xp, ulonglong *ip)
{
	ix_double xx;
	get_ix_double(xp, &xx);
	if (xx == (double)ULONGLONG_MAX)      *ip = ULONGLONG_MAX;
	else if (xx > (double)ULONGLONG_MAX || xx < 0) {
            *ip = NC_FILL_UINT64;
            DEBUG_RETURN_ERROR(NC_ERANGE)
        }
	else *ip = (ulonglong)xx;
	return NC_NOERR;
}


static int
ncmpix_get_NC_DOUBLE_float(const void *xp, float *ip)
{
    double xx;
    get_ix_double(xp, &xx);
    if (xx > FLT_MAX) {
        *ip = NC_FILL_FLOAT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
    if (xx < (-FLT_MAX)) {
        *ip = NC_FILL_FLOAT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
    *ip = (float) xx;
    return NC_NOERR;
}

#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
static int
ncmpix_get_NC_DOUBLE_double(const void *xp, double *ip, void *fillp)
{
	/* TODO */
	get_ix_double(xp, ip);
	return NC_NOERR;
}
#endif

static int
ncmpix_put_NC_DOUBLE_schar(void *xp, const schar *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_uchar(void *xp, const uchar *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_DOUBLE_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_double xx = NC_FILL_DOUBLE;

    
        xx = (ix_double)*ip;

    put_ix_double(xp, &xx);
    return err;
}


static int
ncmpix_put_NC_DOUBLE_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    double xx = NC_FILL_DOUBLE;
#if 1	/* TODO: figure this out (if condition below will never be true)*/
    if ((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (double) *ip;

    put_ix_double(xp, &xx);
    return err;
}

#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE  || defined(NO_IEEE_FLOAT)
static int
ncmpix_put_NC_DOUBLE_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    double *_ip = ip;
#ifdef NO_IEEE_FLOAT
    double tmp=NC_FILL_DOUBLE;
    if (*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN) {
        if (fillp != NULL) memcpy(&tmp, fillp, 8);
        _ip = &tmp;
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    }
#endif
    put_ix_double(xp, _ip);
    return err;
}
#endif


/* external NC_INT64 --------------------------------------------------------*/

#if SHORT_MAX == X_INT64_MAX
typedef short ix_int64;
#define SIZEOF_IX_INT64 SIZEOF_SHORT
#define IX_INT64_MAX SHORT_MAX
#elif LONG_LONG_MAX  >= X_INT64_MAX
typedef longlong ix_int64;
#define SIZEOF_IX_INT64 SIZEOF_LONGLONG
#define IX_INT64_MAX LONG_LONG_MAX
#elif LONG_MAX  >= X_INT64_MAX
typedef long ix_int64;
#define SIZEOF_IX_INT64 SIZEOF_LONG
#define IX_INT64_MAX LONG_MAX
#else
#error "ix_int64 implementation"
#endif


static void
get_ix_int64(const void *xp, ix_int64 *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(ip, xp, 8);
#else
    ix_int64 tmp;
    memcpy(&tmp, xp, 8);
    *ip = SWAP8(tmp);
#endif
}

static void
put_ix_int64(void *xp, const ix_int64 *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(xp, ip, 8);
#else
    ix_int64 xtmp, itmp = *ip;
    xtmp = SWAP8(itmp);
    memcpy(xp, &xtmp, 8);
#endif
}

#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
static int
ncmpix_get_NC_INT64_longlong(const void *xp, longlong *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
    get_ix_int64(xp, (ix_int64 *)ip);
#else
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > LONGLONG_MAX
    if (xx > LONGLONG_MAX || xx < LONGLONG_MIN) {
        *ip = NC_FILL_INT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (longlong) xx;
#endif
    return err;
}

#endif
static int
ncmpix_get_NC_INT64_schar(const void *xp, schar *ip)
{
    int err=NC_NOERR;
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > SCHAR_MAX
    if (xx > SCHAR_MAX || xx < SCHAR_MIN) {
        *ip = NC_FILL_BYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (schar) xx;
    return err;
}

static int
ncmpix_get_NC_INT64_short(const void *xp, short *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
    get_ix_int64(xp, (ix_int64 *)ip);
#else
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > SHORT_MAX
    if (xx > SHORT_MAX || xx < SHORT_MIN) {
        *ip = NC_FILL_SHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (short) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_INT64_int(const void *xp, int *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
    get_ix_int64(xp, (ix_int64 *)ip);
#else
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > INT_MAX
    if (xx > INT_MAX || xx < INT_MIN) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (int) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_INT64_long(const void *xp, long *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
    get_ix_int64(xp, (ix_int64 *)ip);
#else
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > LONG_MAX
    if (xx > LONG_MAX || xx < LONG_MIN) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (long) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_INT64_ushort(const void *xp, ushort *ip)
{
    int err=NC_NOERR;
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > USHORT_MAX
    if (xx > USHORT_MAX) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (ushort) xx;
    return err;
}

static int
ncmpix_get_NC_INT64_uchar(const void *xp, uchar *ip)
{
    int err=NC_NOERR;
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > UCHAR_MAX
    if (xx > UCHAR_MAX) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (uchar) xx;
    return err;
}

static int
ncmpix_get_NC_INT64_uint(const void *xp, uint *ip)
{
    int err=NC_NOERR;
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > UINT_MAX
    if (xx > UINT_MAX) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (uint) xx;
    return err;
}

static int
ncmpix_get_NC_INT64_ulonglong(const void *xp, ulonglong *ip)
{
    int err=NC_NOERR;
    ix_int64 xx;
    get_ix_int64(xp, &xx);

#if IX_INT64_MAX > ULONGLONG_MAX
    if (xx > ULONGLONG_MAX) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif

    if (xx < 0) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE) /* because ip is unsigned */
    }
    *ip = (ulonglong) xx;
    return err;
}

static int
ncmpix_get_NC_INT64_float(const void *xp, float *ip)
{
	ix_int64 xx;
	get_ix_int64(xp, &xx);
	*ip = (float)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_INT64_double(const void *xp, double *ip)
{
	ix_int64 xx;
	get_ix_int64(xp, &xx);
	*ip = (double)xx;
	return NC_NOERR;
}


#if X_SIZEOF_INT64 != SIZEOF_LONGLONG
static int
ncmpix_put_NC_INT64_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_LONGLONG && IX_INT64_MAX == LONGLONG_MAX
    put_ix_int64(xp, (const ix_int64 *)ip);
#else
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < LONGLONG_MAX
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
#endif
    return err;
}

#endif
static int
ncmpix_put_NC_INT64_schar(void *xp, const schar *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < SCHAR_MAX
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT64_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_SHORT && IX_INT64_MAX == SHORT_MAX
    put_ix_int64(xp, (const ix_int64 *)ip);
#else
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < SHORT_MAX
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_INT64_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_INT && IX_INT64_MAX == INT_MAX
    put_ix_int64(xp, (const ix_int64 *)ip);
#else
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < INT_MAX
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_INT64_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_INT64 == SIZEOF_LONG && IX_INT64_MAX == LONG_MAX
    put_ix_int64(xp, (const ix_int64 *)ip);
#else
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < LONG_MAX
    if (*ip > IX_INT64_MAX || *ip < X_INT64_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_INT64_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < USHORT_MAX
    if (*ip > IX_INT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT64_uchar(void *xp, const uchar *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < UCHAR_MAX
    if (*ip > IX_INT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT64_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < UINT_MAX
    if (*ip > IX_INT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT64_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int64 xx = NC_FILL_INT64;

#if IX_INT64_MAX < ULONGLONG_MAX
    if (*ip > IX_INT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT64_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int64 xx = NC_FILL_INT64;

    if (*ip > (double)X_INT64_MAX || *ip < (double)X_INT64_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_INT64_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_int64 xx = NC_FILL_INT64;

    if (*ip > (double)X_INT64_MAX || *ip < X_INT64_MIN) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_int64)*ip;

    put_ix_int64(xp, &xx);
    return err;
}



/* external NC_UINT64 -------------------------------------------------------*/

#if USHORT_MAX == X_UINT64_MAX
typedef ushort ix_uint64;
#define SIZEOF_IX_UINT64 SIZEOF_USHORT
#define IX_UINT64_MAX USHORT_MAX
#elif ULONG_LONG_MAX  >= X_UINT64_MAX
typedef ulonglong ix_uint64;
#define SIZEOF_IX_UINT64 SIZEOF_ULONGLONG
#define IX_UINT64_MAX ULONG_LONG_MAX
#elif ULONG_MAX  >= X_UINT64_MAX
typedef ulong ix_uint64;
#define SIZEOF_IX_UINT64 SIZEOF_ULONG
#define IX_UINT64_MAX ULONG_MAX
#else
#error "ix_uint64 implementation"
#endif


static void
get_ix_uint64(const void *xp, ix_uint64 *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(ip, xp, 8);
#else
    ix_uint64 tmp;
    memcpy(&tmp, xp, 8);
    *ip = SWAP8(tmp);
#endif
}

static void
put_ix_uint64(void *xp, const ix_uint64 *ip)
{
#ifdef WORDS_BIGENDIAN
    memcpy(xp, ip, 8);
#else
    ix_uint64 xtmp, itmp = *ip;
    xtmp = SWAP8(itmp);
    memcpy(xp, &xtmp, 8);
#endif
}

#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
static int
ncmpix_get_NC_UINT64_ulonglong(const void *xp, ulonglong *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
    get_ix_uint64(xp, (ix_uint64 *)ip);
#else
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > ULONGLONG_MAX
    if (xx > ULONGLONG_MAX) {
        *ip = NC_FILL_UINT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (ulonglong) xx;
#endif
    return err;
}

#endif
static int
ncmpix_get_NC_UINT64_schar(const void *xp, schar *ip)
{
    int err=NC_NOERR;
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > SCHAR_MAX
    if (xx > SCHAR_MAX) {
        *ip = NC_FILL_BYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (schar) xx;
    return err;
}

static int
ncmpix_get_NC_UINT64_short(const void *xp, short *ip)
{
    int err=NC_NOERR;
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > SHORT_MAX
    if (xx > SHORT_MAX) {
        *ip = NC_FILL_SHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (short) xx;
    return err;
}

static int
ncmpix_get_NC_UINT64_int(const void *xp, int *ip)
{
    int err=NC_NOERR;
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > INT_MAX
    if (xx > INT_MAX) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (int) xx;
    return err;
}

static int
ncmpix_get_NC_UINT64_long(const void *xp, long *ip)
{
    int err=NC_NOERR;
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > LONG_MAX
    if (xx > LONG_MAX) {
        *ip = NC_FILL_INT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (long) xx;
    return err;
}

static int
ncmpix_get_NC_UINT64_longlong(const void *xp, longlong *ip)
{
    int err=NC_NOERR;
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > LONGLONG_MAX
    if (xx > LONGLONG_MAX) {
        *ip = NC_FILL_INT64;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (longlong) xx;
    return err;
}

static int
ncmpix_get_NC_UINT64_ushort(const void *xp, ushort *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
    get_ix_uint64(xp, (ix_uint64 *)ip);
#else
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > USHORT_MAX
    if (xx > USHORT_MAX) {
        *ip = NC_FILL_USHORT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (ushort) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_UINT64_uchar(const void *xp, uchar *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
    get_ix_uint64(xp, (ix_uint64 *)ip);
#else
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > UCHAR_MAX
    if (xx > UCHAR_MAX) {
        *ip = NC_FILL_UBYTE;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (uchar) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_UINT64_uint(const void *xp, uint *ip)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
    get_ix_uint64(xp, (ix_uint64 *)ip);
#else
    ix_uint64 xx;
    get_ix_uint64(xp, &xx);

#if IX_UINT64_MAX > UINT_MAX
    if (xx > UINT_MAX) {
        *ip = NC_FILL_UINT;
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }
#endif


    *ip = (uint) xx;
#endif
    return err;
}

static int
ncmpix_get_NC_UINT64_float(const void *xp, float *ip)
{
	ix_uint64 xx;
	get_ix_uint64(xp, &xx);
	*ip = (float)xx;
	return NC_NOERR;
}

static int
ncmpix_get_NC_UINT64_double(const void *xp, double *ip)
{
	ix_uint64 xx;
	get_ix_uint64(xp, &xx);
	*ip = (double)xx;
	return NC_NOERR;
}


#if X_SIZEOF_UINT64 != SIZEOF_ULONGLONG
static int
ncmpix_put_NC_UINT64_ulonglong(void *xp, const ulonglong *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_ULONGLONG && IX_UINT64_MAX == ULONGLONG_MAX
    put_ix_uint64(xp, (const ix_uint64 *)ip);
#else
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < ULONGLONG_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
#endif
    return err;
}

#endif
static int
ncmpix_put_NC_UINT64_schar(void *xp, const schar *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < SCHAR_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT64_short(void *xp, const short *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < SHORT_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT64_int(void *xp, const int *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < INT_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT64_long(void *xp, const long *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < LONG_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT64_longlong(void *xp, const longlong *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < LONGLONG_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
    if (*ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE) /* because xp is unsigned */
    } else
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT64_uchar(void *xp, const uchar *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_UCHAR && IX_UINT64_MAX == UCHAR_MAX
    put_ix_uint64(xp, (const ix_uint64 *)ip);
#else
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < UCHAR_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_UINT64_ushort(void *xp, const ushort *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_USHORT && IX_UINT64_MAX == USHORT_MAX
    put_ix_uint64(xp, (const ix_uint64 *)ip);
#else
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < USHORT_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_UINT64_uint(void *xp, const uint *ip, void *fillp)
{
    int err=NC_NOERR;
#if SIZEOF_IX_UINT64 == SIZEOF_UINT && IX_UINT64_MAX == UINT_MAX
    put_ix_uint64(xp, (const ix_uint64 *)ip);
#else
    ix_uint64 xx = NC_FILL_UINT64;

#if IX_UINT64_MAX < UINT_MAX
    if (*ip > IX_UINT64_MAX) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
#endif
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
#endif
    return err;
}

static int
ncmpix_put_NC_UINT64_float(void *xp, const float *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint64 xx = NC_FILL_UINT64;

    if (*ip > (double)X_UINT64_MAX || *ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
    return err;
}

static int
ncmpix_put_NC_UINT64_double(void *xp, const double *ip, void *fillp)
{
    int err=NC_NOERR;
    ix_uint64 xx = NC_FILL_UINT64;

    if (*ip > (double)X_UINT64_MAX || *ip < 0) {
        if (fillp != NULL) memcpy(&xx, fillp, 8);
        DEBUG_ASSIGN_ERROR(err, NC_ERANGE)
    } else
        xx = (ix_uint64)*ip;

    put_ix_uint64(xp, &xx);
    return err;
}



/* x_size_t */

#if SIZEOF_SIZE_T < X_SIZEOF_SIZE_T
#error "x_size_t implementation"
/* netcdf requires size_t which can hold a values from 0 to 2^32 -1 */
#endif

int
ncmpix_put_size_t(void **xpp, const size_t *ulp)
/* This subroutine is used only in NetCDF, not PnetCDF, and only used for
 * classic CDF-1 and 2 file formats where external int is 32-bit in files.
 * The name of this function is misleading, as size_t is an interanl memory
 * type whose size may be 4 or 8 byte, depending on the systems. The usage
 * of this function (i.e. in v1hpg.c) is actually to write a 32-bit unsigned
 * integer from ulp to xpp. Thus, more accurate function is to call
 * ncmpix_put_uint32()
 */
{
#ifdef WORDS_BIGENDIAN
    memcpy(*xpp, ulp, 4);
#else
    size_t xtmp, itmp = *ulp;
    xtmp = SWAP4(itmp);
    memcpy(*xpp, &xtmp, 4);
#endif

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

int
ncmpix_get_size_t(const void **xpp, size_t *ulp)
/* This subroutine is used only in NetCDF, not PnetCDF, and only used for
 * classic CDF-1 and 2 file formats where external int is 32-bit in files.
 * The name of this function is misleading, as size_t is an interanl memory
 * type whose size may be 4 or 8 byte, depending on the systems. The usage
 * of this function (i.e. in v1hpg.c) is actually to read a 32-bit unsigned
 * integer from xpp to ulp. Thus, more accurate function is to call
 * ncmpix_get_uint32()
 */
{
#ifdef WORDS_BIGENDIAN
    memcpy(ulp, *xpp, 4);
#else
    size_t tmp;
    memcpy(&tmp, *xpp, 4);
    *ulp = SWAP4(tmp);
#endif

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

/* x_off_t */

int
ncmpix_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
/* This subroutine is used only in NetCDF. not PnetCDF */
{
    /* No negative offsets stored in netcdf */
    if (*lp < 0) {
        /* Assume this is an overflow of a 32-bit int... */
        DEBUG_RETURN_ERROR(NC_ERANGE)
    }

    assert(sizeof_off_t == 4 || sizeof_off_t == 8);

    if (sizeof_off_t == 4) {
#ifdef WORDS_BIGENDIAN
        memcpy(*xpp, lp, 4);
#else
        if (*lp > X_INT_MAX)
            DEBUG_RETURN_ERROR(NC_EINTOVERFLOW)
        else {
            int xtmp, itmp;
            itmp = (int)*lp;
            xtmp = SWAP4(itmp);
            memcpy(*xpp, &xtmp, 4);
        }
#endif
    } else {
#ifdef WORDS_BIGENDIAN
        memcpy(*xpp, lp, 8);
#else
        off_t xtmp, itmp = *lp;
        xtmp = SWAP8(itmp);
        memcpy(*xpp, &xtmp, 8);
#endif
    }
    *xpp = (void *)((char *)(*xpp) + sizeof_off_t);
    return NC_NOERR;
}

int
ncmpix_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
/* This subroutine is used only in NetCDF. not PnetCDF */
{
    /* similar to get_ix_int() */
    assert(sizeof_off_t == 4 || sizeof_off_t == 8);

    if (sizeof_off_t == 4) {
#ifdef WORDS_BIGENDIAN
        memcpy(lp, *xpp, 4);
#else
        int tmp;
        memcpy(&tmp, *xpp, 4);
        *lp = (off_t) SWAP4(tmp);
#endif
    } else {
#ifdef WORDS_BIGENDIAN
        memcpy(lp, *xpp, 8);
#else
        long long tmp;
        memcpy(&tmp, *xpp, 8);
        *lp = (off_t) SWAP8(tmp);
#endif
    }
    *xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
    return NC_NOERR;
}

/*----< ncmpix_get_uint32() >------------------------------------------*/
int
ncmpix_get_uint32(const void **xpp, uint *ip)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(ip, *xpp, 4);
#else
    uint tmp;
    memcpy(&tmp, *xpp, 4);
    *ip = SWAP4(tmp);
#endif
    /* advance *xpp 4 bytes */
    *xpp = (void *)((const char *)(*xpp) + 4);

    return NC_NOERR;
}

/*----< ncmpix_getn_uint32() >-----------------------------------------*/
int
ncmpix_getn_uint32(const void **xpp, uint *ip, int nelems)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(ip, *xpp, (size_t)4 * nelems);
#else
    swapn4b(ip, *xpp, nelems);
#endif
    /* advance 4*nelems bytes for *xpp */
    *xpp = (void *)((const char *)(*xpp) + 4 * nelems);

    return NC_NOERR;
}

/*----< ncmpix_get_uint64() >------------------------------------------*/
int
ncmpix_get_uint64(const void **xpp, unsigned long long *ullp)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(ullp, *xpp, 8);
#else
    unsigned long long tmp;
    memcpy(&tmp, *xpp, 8);
    *ullp = SWAP8(tmp);
#endif
    /* advance *xpp 8 bytes */
    *xpp = (void *)((const char *)(*xpp) + 8);

    return NC_NOERR;
}

/*----< ncmpix_getn_uint64() >-----------------------------------------*/
int
ncmpix_getn_uint64(const void **xpp, unsigned long long *ullp, int nelems)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(ullp, *xpp, (size_t)8 * nelems);
#else
    swapn8b(ullp, *xpp, nelems);
#endif
    /* advance 8*nelems bytes for *xpp */
    *xpp = (void *)((const char *)(*xpp) + 8 * nelems);

    return NC_NOERR;
}

/*---< ncmpix_put_uint32() >-------------------------------------------*/
/* copy the contents of ip (an unsigned 32-bit integer) to xpp in Big Endian
 * form and advance *xpp 4 bytes
 */
int
ncmpix_put_uint32(void **xpp, unsigned int ip)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT);
#else
    /* bitwise shifts below are to produce an integer in Big Endian */
    unsigned int tmp;
    tmp = SWAP4(ip);
    memcpy(*xpp, &tmp, 4);
#endif
    /* advance *xpp 4 bytes */
    *xpp  = (void *)((char *)(*xpp) + 4);

    return NC_NOERR;
}

/*---< ncmpix_putn_uint32() >------------------------------------------*/
/* copy the contents of ip (nelems unsigned 32-bit integers) to xpp in Big
 * Endian form and advance (4*nelems) bytes for pointer *xpp
 */
int
ncmpix_putn_uint32(void **xpp, const unsigned int *ip, int nelems)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(*xpp, ip, (size_t)4 * nelems);
#else
    swapn4b(*xpp, ip, nelems);
#endif
    /* advance 4*nelems bytes for *xpp */
    *xpp  = (void *)((char *)(*xpp) + 4*nelems);

    return NC_NOERR;
}

/*---< ncmpix_put_uint64() >-------------------------------------------*/
/* copy the contents of ip (an unsigned 64-bit integer) to xpp in Big Endian
 * form and advance *xpp 8 bytes
 */
int
ncmpix_put_uint64(void **xpp, unsigned long long ip)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(*xpp, &ip, X_SIZEOF_UINT64);
#else
    unsigned long long tmp;
    tmp = SWAP8(ip);
    memcpy(*xpp, &tmp, 8);
#endif
    /* advance *xpp 8 bytes */
    *xpp  = (void *)((char *)(*xpp) + 8);

    return NC_NOERR;
}

/*---< ncmpix_putn_uint64() >------------------------------------------*/
/* copy the contents of ip (nelems unsigned 64-bit integers) to xpp in Big
 * Endian form and advance 8*nelems bytes for pointer *xpp
 */
int
ncmpix_putn_uint64(void **xpp, const unsigned long long *ip, int nelems)
{
#ifdef WORDS_BIGENDIAN
    /* use memcpy instead of assignment to avoid BUS_ADRALN alignment error on
     * some system, such as HPUX */
    (void) memcpy(*xpp, ip, (size_t)8 * nelems);
#else
    swapn8b(*xpp, ip, nelems);
#endif
    /* advance 8*nelems bytes for *xpp */
    *xpp  = (void *)((char *)(*xpp) + 8*nelems);

    return NC_NOERR;
}


/*
 * Aggregate numeric conversion functions.
 */



/* schar ---------------------------------------------------------------------*/

int
ncmpix_getn_NC_BYTE_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
		(void) memcpy(tp, *xpp, (size_t)nelems);
	*xpp = (void *)((char *)(*xpp) + nelems);
	return NC_NOERR;

}
int
ncmpix_getn_NC_BYTE_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_UBYTE;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
    }

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

int
ncmpix_getn_NC_BYTE_short(const void **xpp, MPI_Offset nelems, short *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
    }

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

int
ncmpix_getn_NC_BYTE_int(const void **xpp, MPI_Offset nelems, int *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
    }

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

int
ncmpix_getn_NC_BYTE_long(const void **xpp, MPI_Offset nelems, long *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
    }

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

int
ncmpix_getn_NC_BYTE_float(const void **xpp, MPI_Offset nelems, float *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
    }

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

int
ncmpix_getn_NC_BYTE_double(const void **xpp, MPI_Offset nelems, double *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
    }

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

int
ncmpix_getn_NC_BYTE_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
    }

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

int
ncmpix_getn_NC_BYTE_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_USHORT;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
    }

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

int
ncmpix_getn_NC_BYTE_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_UINT;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
    }

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

int
ncmpix_getn_NC_BYTE_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
    int status = NC_NOERR;
    schar *xp = (schar *)(*xpp);

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_UINT64;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
    }

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


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

	if (rndup)
		rndup = X_ALIGN - rndup;

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

	return NC_NOERR;

}
int
ncmpix_pad_getn_NC_BYTE_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_UBYTE;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (uchar) (signed) (*xp++);  /* type cast from schar to uchar */
    }

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

int
ncmpix_pad_getn_NC_BYTE_short(const void **xpp, MPI_Offset nelems, short *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (short)  (*xp++);  /* type cast from schar to short */
    }

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

int
ncmpix_pad_getn_NC_BYTE_int(const void **xpp, MPI_Offset nelems, int *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (int)  (*xp++);  /* type cast from schar to int */
    }

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

int
ncmpix_pad_getn_NC_BYTE_long(const void **xpp, MPI_Offset nelems, long *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (long)  (*xp++);  /* type cast from schar to long */
    }

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

int
ncmpix_pad_getn_NC_BYTE_float(const void **xpp, MPI_Offset nelems, float *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (float)  (*xp++);  /* type cast from schar to float */
    }

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

int
ncmpix_pad_getn_NC_BYTE_double(const void **xpp, MPI_Offset nelems, double *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (double)  (*xp++);  /* type cast from schar to double */
    }

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

int
ncmpix_pad_getn_NC_BYTE_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (longlong)  (*xp++);  /* type cast from schar to longlong */
    }

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

int
ncmpix_pad_getn_NC_BYTE_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_USHORT;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (ushort) (signed) (*xp++);  /* type cast from schar to ushort */
    }

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

int
ncmpix_pad_getn_NC_BYTE_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_UINT;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (uint) (signed) (*xp++);  /* type cast from schar to uint */
    }

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

int
ncmpix_pad_getn_NC_BYTE_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        if (*xp < 0) {
            *tp = NC_FILL_UINT64;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE) /* because tp is unsigned */
            xp++; tp++; continue;
        }
        *tp++ = (ulonglong) (signed) (*xp++);  /* type cast from schar to ulonglong */
    }

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


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

	return NC_NOERR;

}
int
ncmpix_putn_NC_BYTE_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (uchar)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
    }

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

int
ncmpix_putn_NC_BYTE_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
    }

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

int
ncmpix_putn_NC_BYTE_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
    }

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

int
ncmpix_putn_NC_BYTE_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
    }

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

int
ncmpix_putn_NC_BYTE_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
    }

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

int
ncmpix_putn_NC_BYTE_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
    }

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

int
ncmpix_putn_NC_BYTE_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
    }

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

int
ncmpix_putn_NC_BYTE_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (ushort)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
    }

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

int
ncmpix_putn_NC_BYTE_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (uint)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
    }

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

int
ncmpix_putn_NC_BYTE_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
    int status = NC_NOERR;
    schar *xp = (schar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
    }

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


int
ncmpix_pad_putn_NC_BYTE_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
		MPI_Offset rndup = nelems % X_ALIGN;

	if (rndup)
		rndup = X_ALIGN - rndup;

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

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

	return NC_NOERR;

}
int
ncmpix_pad_putn_NC_BYTE_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (uchar)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from uchar to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (short)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from short to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (int)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from int to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (long)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from long to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (float)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from float to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (double)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from double to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (longlong)X_SCHAR_MAX || *tp < X_SCHAR_MIN) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from longlong to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (ushort)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from ushort to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (uint)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from uint to schar */
    }


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

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

int
ncmpix_pad_putn_NC_BYTE_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    schar *xp = (schar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (ulonglong)X_SCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (schar)  *tp++; /* type cast from ulonglong to schar */
    }


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

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



/* uchar ---------------------------------------------------------------------*/
int
ncmpix_getn_NC_UBYTE_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        if (*xp > SCHAR_MAX) {
            *tp = NC_FILL_BYTE;
       	    DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
	*tp++ = (schar) *xp++; /* type cast from uchar to schar */
    }

    *xpp = (const void *)xp;
    return status;
}
int
ncmpix_getn_NC_UBYTE_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
		(void) memcpy(tp, *xpp, (size_t)nelems);
	*xpp = (void *)((char *)(*xpp) + nelems);
	return NC_NOERR;

}
int
ncmpix_getn_NC_UBYTE_short(const void **xpp, MPI_Offset nelems, short *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
    }

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

int
ncmpix_getn_NC_UBYTE_int(const void **xpp, MPI_Offset nelems, int *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
    }

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

int
ncmpix_getn_NC_UBYTE_long(const void **xpp, MPI_Offset nelems, long *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
    }

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

int
ncmpix_getn_NC_UBYTE_float(const void **xpp, MPI_Offset nelems, float *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
    }

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

int
ncmpix_getn_NC_UBYTE_double(const void **xpp, MPI_Offset nelems, double *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
    }

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

int
ncmpix_getn_NC_UBYTE_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
    }

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

int
ncmpix_getn_NC_UBYTE_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
    }

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

int
ncmpix_getn_NC_UBYTE_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
    }

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

int
ncmpix_getn_NC_UBYTE_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *)(*xpp);

    while (nelems-- != 0) {
        
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
    }

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


int
ncmpix_pad_getn_NC_UBYTE_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*xp > SCHAR_MAX) {
            *tp = NC_FILL_BYTE;
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *tp++ = (schar) *xp++; /* type cast from uchar to schar */
    }

    *xpp = (void *)(xp + rndup);
    return status;
}
int
ncmpix_pad_getn_NC_UBYTE_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
		MPI_Offset rndup = nelems % X_ALIGN;

	if (rndup)
		rndup = X_ALIGN - rndup;

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

	return NC_NOERR;

}
int
ncmpix_pad_getn_NC_UBYTE_short(const void **xpp, MPI_Offset nelems, short *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (short)  (*xp++);  /* type cast from uchar to short */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_int(const void **xpp, MPI_Offset nelems, int *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (int)  (*xp++);  /* type cast from uchar to int */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_long(const void **xpp, MPI_Offset nelems, long *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (long)  (*xp++);  /* type cast from uchar to long */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_float(const void **xpp, MPI_Offset nelems, float *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (float)  (*xp++);  /* type cast from uchar to float */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_double(const void **xpp, MPI_Offset nelems, double *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (double)  (*xp++);  /* type cast from uchar to double */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (longlong)  (*xp++);  /* type cast from uchar to longlong */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (ushort)  (*xp++);  /* type cast from uchar to ushort */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (uint)  (*xp++);  /* type cast from uchar to uint */
    }

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

int
ncmpix_pad_getn_NC_UBYTE_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup)
        rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        
        *tp++ = (ulonglong)  (*xp++);  /* type cast from uchar to ulonglong */
    }

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


int
ncmpix_putn_NC_UBYTE_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
    }

    *xpp = (void *)xp;
    return status;
}
int
ncmpix_putn_NC_UBYTE_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
		(void) memcpy(*xpp, tp, (size_t)nelems);
	*xpp = (void *)((char *)(*xpp) + nelems);

	return NC_NOERR;

}
int
ncmpix_putn_NC_UBYTE_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (ushort)X_UCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (uint)X_UCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
    }

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

int
ncmpix_putn_NC_UBYTE_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
    int status = NC_NOERR;
    uchar *xp = (uchar *) *xpp;

    while (nelems-- != 0) {
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
    }

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


int
ncmpix_pad_putn_NC_UBYTE_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from schar to uchar */
    }

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

    *xpp = (void *)xp;
    return status;
}
int
ncmpix_pad_putn_NC_UBYTE_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
		MPI_Offset rndup = nelems % X_ALIGN;

	if (rndup)
		rndup = X_ALIGN - rndup;

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

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

	return NC_NOERR;

}
int
ncmpix_pad_putn_NC_UBYTE_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (short)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from short to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (int)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from int to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (long)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from long to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (float)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from float to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (double)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from double to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (longlong)X_UCHAR_MAX || *tp < 0) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar) (signed) *tp++; /* type cast from longlong to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (ushort)X_UCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar)  *tp++; /* type cast from ushort to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (uint)X_UCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar)  *tp++; /* type cast from uint to uchar */
    }


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

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

int
ncmpix_pad_putn_NC_UBYTE_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
    int status = NC_NOERR;
    MPI_Offset rndup = nelems % X_ALIGN;
    uchar *xp = (uchar *) *xpp;

    if (rndup) rndup = X_ALIGN - rndup;

    while (nelems-- != 0) {
        if (*tp > (ulonglong)X_UCHAR_MAX ) {
            if (fillp != NULL) memcpy(xp, fillp, 1);
            DEBUG_ASSIGN_ERROR(status, NC_ERANGE)
            xp++; tp++; continue;
        }
        *xp++ = (uchar)  *tp++; /* type cast from ulonglong to uchar */
    }


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

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


/* short ---------------------------------------------------------------------*/

#if X_SIZEOF_SHORT == SIZEOF_SHORT
/* optimized version */
int
ncmpix_getn_NC_SHORT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_SHORT);
# else
	swapn2b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
	return NC_NOERR;
}
#else
int
ncmpix_getn_NC_SHORT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_getn_NC_SHORT_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_SHORT_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_SHORT));
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (short *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


int
ncmpix_pad_getn_NC_SHORT_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_long(const void **xpp, MPI_Offset nelems, long *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_double(const void **xpp, MPI_Offset nelems, double *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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

int
ncmpix_pad_getn_NC_SHORT_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_SHORT_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_SHORT;

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


#if X_SIZEOF_SHORT == SIZEOF_SHORT
/* optimized version */
int
ncmpix_putn_NC_SHORT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_SHORT);
# else
	swapn2b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
	return NC_NOERR;
}
#else
int
ncmpix_putn_NC_SHORT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_putn_NC_SHORT_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX || tp[i] < X_SHORT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_SHORT_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_SHORT == SIZEOF_SHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  short tmp[LOOPCNT];        /* in case input is misaligned */
  short *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_SHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (short *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (short) Max( X_SHORT_MIN, Min(X_SHORT_MAX, (short) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_SHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_SHORT);
      xp = (short *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


int
ncmpix_pad_putn_NC_SHORT_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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

int
ncmpix_pad_putn_NC_SHORT_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_SHORT_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_SHORT));
		xp += X_SIZEOF_SHORT;
	}

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



/* ushort --------------------------------------------------------------------*/

#if X_SIZEOF_USHORT == SIZEOF_USHORT
/* optimized version */
int
ncmpix_getn_NC_USHORT_ushort(const void **xpp, MPI_Offset nelems, unsigned short *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_USHORT);
# else
	swapn2b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
	return NC_NOERR;
}
#else
int
ncmpix_getn_NC_USHORT_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_getn_NC_USHORT_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > FLOAT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > DOUBLE_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_USHORT_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_USHORT));
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (ushort *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


int
ncmpix_pad_getn_NC_USHORT_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_long(const void **xpp, MPI_Offset nelems, long *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_double(const void **xpp, MPI_Offset nelems, double *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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

int
ncmpix_pad_getn_NC_USHORT_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		const int lstatus = ncmpix_get_NC_USHORT_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
		xp += X_SIZEOF_USHORT;

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


#if X_SIZEOF_USHORT == SIZEOF_USHORT
/* optimized version */
int
ncmpix_putn_NC_USHORT_ushort(void **xpp, MPI_Offset nelems, const unsigned short *tp, void *fillp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_USHORT);
# else
	swapn2b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
	return NC_NOERR;
}
#else
int
ncmpix_putn_NC_USHORT_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_putn_NC_USHORT_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_USHORT_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_USHORT == SIZEOF_USHORT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  ushort tmp[LOOPCNT];        /* in case input is misaligned */
  ushort *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_USHORT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (ushort *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (ushort) Max( X_USHORT_MIN, Min(X_USHORT_MAX, (ushort) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_USHORT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_USHORT);
      xp = (ushort *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


int
ncmpix_pad_putn_NC_USHORT_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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

int
ncmpix_pad_putn_NC_USHORT_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
	const MPI_Offset rndup = nelems % X_SIZEOF_SHORT;

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_USHORT, tp++)
	{
		int lstatus = ncmpix_put_NC_USHORT_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	if (rndup != 0)
	{
		(void) memcpy(xp, nada, (size_t)(X_SIZEOF_USHORT));
		xp += X_SIZEOF_USHORT;
	}

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



/* int -----------------------------------------------------------------------*/

#if X_SIZEOF_INT == SIZEOF_INT
/* optimized version */
int
ncmpix_getn_NC_INT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_INT);
# else
	swapn4b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
	return NC_NOERR;
}
#else
int
ncmpix_getn_NC_INT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_getn_NC_INT_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT));
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


#if X_SIZEOF_INT == SIZEOF_INT
/* optimized version */
int
ncmpix_putn_NC_INT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT);
# else
	swapn4b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
	return NC_NOERR;
}
#else
int
ncmpix_putn_NC_INT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_putn_NC_INT_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  double d;               /* special case for ncmpix_putn_int_float */
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* for some reason int to float, for putn, requires a special case */
      d = tp[i];
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) d));
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX || tp[i] < X_INT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT == SIZEOF_INT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int tmp[LOOPCNT];        /* in case input is misaligned */
  int *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int) Max( X_INT_MIN, Min(X_INT_MAX, (int) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT);
      xp = (int *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++)
	{
		int lstatus = ncmpix_put_NC_INT_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


/* uint ----------------------------------------------------------------------*/

#if X_SIZEOF_UINT == SIZEOF_UINT
/* optimized version */
int
ncmpix_getn_NC_UINT_uint(const void **xpp, MPI_Offset nelems, unsigned int *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UINT);
# else
	swapn4b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
	return NC_NOERR;
}
#else
int
ncmpix_getn_NC_UINT_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_getn_NC_UINT_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > FLOAT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > DOUBLE_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT));
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


#if X_SIZEOF_UINT == SIZEOF_UINT
/* optimized version */
int
ncmpix_putn_NC_UINT_uint(void **xpp, MPI_Offset nelems, const unsigned int *tp, void *fillp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT);
# else
	swapn4b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
	return NC_NOERR;
}
#else
int
ncmpix_putn_NC_UINT_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_putn_NC_UINT_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT == SIZEOF_UINT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint tmp[LOOPCNT];        /* in case input is misaligned */
  uint *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint) Max( X_UINT_MIN, Min(X_UINT_MAX, (uint) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT);
      xp = (uint *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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



/* float ---------------------------------------------------------------------*/

#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
/* optimized version */
int
ncmpix_getn_NC_FLOAT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_FLOAT);
# else
	swapn4b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
	return NC_NOERR;
}
#elif defined(vax) && vax != 0
int
ncmpix_getn_NC_FLOAT_float(const void **xpp, MPI_Offset nfloats, float *ip)
{
	float *const end = ip + nfloats;

	while (ip < end)
	{
		struct vax_single *const vsp = (struct vax_single *) ip;
		const struct ieee_single *const isp =
			 (const struct ieee_single *) (*xpp);
		unsigned exp = isp->exp_hi << 1 | isp->exp_lo;

		switch(exp) {
		case 0 :
			/* ieee subnormal */
			if (isp->mant_hi == min.ieee.mant_hi
				&& isp->mant_lo_hi == min.ieee.mant_lo_hi
				&& isp->mant_lo_lo == min.ieee.mant_lo_lo)
			{
				*vsp = min.s;
			}
			else
			{
				unsigned mantissa = (isp->mant_hi << 16)
					 | isp->mant_lo_hi << 8
					 | isp->mant_lo_lo;
				unsigned tmp = mantissa >> 20;
				if (tmp >= 4) {
					vsp->exp = 2;
				} else if (tmp >= 2) {
					vsp->exp = 1;
				} else {
					*vsp = min.s;
					break;
				} /* else */
				tmp = mantissa - (1 << (20 + vsp->exp ));
				tmp <<= 3 - vsp->exp;
				vsp->mantissa2 = tmp;
				vsp->mantissa1 = (tmp >> 16);
			}
			break;
		case 0xfe :
		case 0xff :
			*vsp = max.s;
			break;
		default :
			vsp->exp = exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
			vsp->mantissa2 = isp->mant_lo_hi << 8 | isp->mant_lo_lo;
			vsp->mantissa1 = isp->mant_hi;
		}

		vsp->sign = isp->sign;


		ip++;
		*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
	}
	return NC_NOERR;
}
#else
int
ncmpix_getn_NC_FLOAT_float(const void **xpp, MPI_Offset nelems, float *tp)
{
	const char *xp = *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_getn_NC_FLOAT_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_FLOAT_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_FLOAT));
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (float *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		const int lstatus = ncmpix_get_NC_FLOAT_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


int
ncmpix_putn_NC_FLOAT_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
/* optimized version */
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_FLOAT);
# else
	swapn4b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
	return NC_NOERR;
}
#elif defined(vax) && vax != 0
{
	const float *const end = tp + nelems;

	while (tp < end) {
				const struct vax_single *const vsp =
			 (const struct vax_single *)ip;
		struct ieee_single *const isp = (struct ieee_single *) (*xpp);

		switch(vsp->exp){
		case 0 :
			/* all vax float with zero exponent map to zero */
			*isp = min.ieee;
			break;
		case 2 :
		case 1 :
		{
			/* These will map to subnormals */
			unsigned mantissa = (vsp->mantissa1 << 16)
					 | vsp->mantissa2;
			mantissa >>= 3 - vsp->exp;
			mantissa += (1 << (20 + vsp->exp));
			isp->mant_lo_lo = mantissa;
			isp->mant_lo_hi = mantissa >> 8;
			isp->mant_hi = mantissa >> 16;
			isp->exp_lo = 0;
			isp->exp_hi = 0;
		}
			break;
		case 0xff : /* max.s.exp */
			if (vsp->mantissa2 == max.s.mantissa2 &&
			    vsp->mantissa1 == max.s.mantissa1)
			{
				/* map largest vax float to ieee infinity */
				*isp = max.ieee;
				break;
			} /* else, fall thru */
		default :
		{
			unsigned exp = vsp->exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
			isp->exp_hi = exp >> 1;
			isp->exp_lo = exp;
			isp->mant_lo_lo = vsp->mantissa2;
			isp->mant_lo_hi = vsp->mantissa2 >> 8;
			isp->mant_hi = vsp->mantissa1;
		}
		}

		isp->sign = vsp->sign;

		tp++;
		*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
	}
	return NC_NOERR;
}
#else
{
	char *xp = *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) {
		int lstatus = ncmpix_put_NC_FLOAT_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	*xpp = (void *)xp;
	return status;
}
#endif
int
ncmpix_putn_NC_FLOAT_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX || tp[i] < X_FLOAT_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_FLOAT_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_FLOAT == SIZEOF_FLOAT

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  float tmp[LOOPCNT];        /* in case input is misaligned */
  float *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_FLOAT;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (float *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (float) Max( X_FLOAT_MIN, Min(X_FLOAT_MAX, (float) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_FLOAT_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_FLOAT);
      xp = (float *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
	{
		int lstatus = ncmpix_put_NC_FLOAT_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


/* double --------------------------------------------------------------------*/

#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
/* optimized version */
int
ncmpix_getn_NC_DOUBLE_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_DOUBLE);
# else
	swapn8b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
	return NC_NOERR;
}
#elif defined(vax) && vax != 0
int
ncmpix_getn_NC_DOUBLE_double(const void **xpp, MPI_Offset ndoubles, double *ip)
{
	double *const end = ip + ndoubles;

	while (ip < end)
	{
	struct vax_double *const vdp =
			 (struct vax_double *)ip;
	const struct ieee_double *const idp =
			 (const struct ieee_double *) (*xpp);
	{
		const struct dbl_limits *lim;
		int ii;
		for (ii = 0, lim = dbl_limits;
			ii < sizeof(dbl_limits)/sizeof(struct dbl_limits);
			ii++, lim++)
		{
			if ((idp->mant_lo == lim->ieee.mant_lo)
				&& (idp->mant_4 == lim->ieee.mant_4)
				&& (idp->mant_5 == lim->ieee.mant_5)
				&& (idp->mant_6 == lim->ieee.mant_6)
				&& (idp->exp_lo == lim->ieee.exp_lo)
				&& (idp->exp_hi == lim->ieee.exp_hi)
				)
			{
				*vdp = lim->d;
				goto doneit;
			}
		}
	}
	{
		unsigned exp = idp->exp_hi << 4 | idp->exp_lo;
		vdp->exp = exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
	}
	{
		unsigned mant_hi = ((idp->mant_6 << 16)
				 | (idp->mant_5 << 8)
				 | idp->mant_4);
		unsigned mant_lo = SWAP4(idp->mant_lo);
		vdp->mantissa1 = (mant_hi >> 13);
		vdp->mantissa2 = ((mant_hi & MASK(13)) << 3)
				| (mant_lo >> 29);
		vdp->mantissa3 = (mant_lo >> 13);
		vdp->mantissa4 = (mant_lo << 3);
	}
	doneit:
		vdp->sign = idp->sign;

		ip++;
		*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
	}
	return NC_NOERR;
}
	/* vax */
#else
int
ncmpix_getn_NC_DOUBLE_double(const void **xpp, MPI_Offset nelems, double *tp)
{
	const char *xp = *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	*xpp = (const void *)xp;
	return status;
}
#endif
int
ncmpix_getn_NC_DOUBLE_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_DOUBLE_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_DOUBLE));
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (double *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		const int lstatus = ncmpix_get_NC_DOUBLE_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
/* optimized version */
int
ncmpix_putn_NC_DOUBLE_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_DOUBLE);
# else
	swapn8b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
	return NC_NOERR;
}
#elif defined(vax) && vax != 0
int
ncmpix_putn_NC_DOUBLE_double(void **xpp, MPI_Offset ndoubles, const double *ip, void *fillp)
{
	const double *const end = ip + ndoubles;

	while (ip < end)
	{
	const struct vax_double *const vdp =
			(const struct vax_double *)ip;
	struct ieee_double *const idp =
			 (struct ieee_double *) (*xpp);

	if ((vdp->mantissa4 > (dbl_limits[0].d.mantissa4 - 3)) &&
		(vdp->mantissa3 == dbl_limits[0].d.mantissa3) &&
		(vdp->mantissa2 == dbl_limits[0].d.mantissa2) &&
		(vdp->mantissa1 == dbl_limits[0].d.mantissa1) &&
		(vdp->exp == dbl_limits[0].d.exp))
	{
		*idp = dbl_limits[0].ieee;
		goto shipit;
	}
	if ((vdp->mantissa4 == dbl_limits[1].d.mantissa4) &&
		(vdp->mantissa3 == dbl_limits[1].d.mantissa3) &&
		(vdp->mantissa2 == dbl_limits[1].d.mantissa2) &&
		(vdp->mantissa1 == dbl_limits[1].d.mantissa1) &&
		(vdp->exp == dbl_limits[1].d.exp))
	{
		*idp = dbl_limits[1].ieee;
		goto shipit;
	}

	{
		unsigned exp = vdp->exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;

		unsigned mant_lo = ((vdp->mantissa2 & MASK(3)) << 29) |
			(vdp->mantissa3 << 13) |
			((vdp->mantissa4 >> 3) & MASK(13));

		unsigned mant_hi = (vdp->mantissa1 << 13)
				 | (vdp->mantissa2 >> 3);

		if ((vdp->mantissa4 & 7) > 4)
		{
			/* round up */
			mant_lo++;
			if (mant_lo == 0)
			{
				mant_hi++;
				if (mant_hi > 0xffffff)
				{
					mant_hi = 0;
					exp++;
				}
			}
		}

		idp->mant_lo = SWAP4(mant_lo);
		idp->mant_6 = mant_hi >> 16;
		idp->mant_5 = (mant_hi & 0xff00) >> 8;
		idp->mant_4 = mant_hi;
		idp->exp_hi = exp >> 4;
		idp->exp_lo = exp;
	}

	shipit:
		idp->sign = vdp->sign;

		ip++;
		*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
	}
	return NC_NOERR;
}
	/* vax */
#else
int
ncmpix_putn_NC_DOUBLE_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
	char *xp = *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

	*xpp = (void *)xp;
	return status;
}
#endif
int
ncmpix_putn_NC_DOUBLE_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX || tp[i] < X_DOUBLE_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_DOUBLE_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_DOUBLE == SIZEOF_DOUBLE

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  double tmp[LOOPCNT];        /* in case input is misaligned */
  double *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_DOUBLE;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (double *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (double) Max( X_DOUBLE_MIN, Min(X_DOUBLE_MAX, (double) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_DOUBLE_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_DOUBLE);
      xp = (double *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
	{
		int lstatus = ncmpix_put_NC_DOUBLE_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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



/* longlong ------------------------------------------------------------------*/

#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
/* optimized version */
int
ncmpix_getn_NC_INT64_longlong(const void **xpp, MPI_Offset nelems, long long *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_LONG_LONG);
# else
	swapn8b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT64);
	return NC_NOERR;
}
#else
int
ncmpix_getn_NC_INT64_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX || xp[i] < LONGLONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_getn_NC_INT64_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX || xp[i] < SCHAR_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX || xp[i] < SHORT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX || xp[i] < INT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX || xp[i] < LONG_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > FLOAT_MAX || xp[i] < FLOAT_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > DOUBLE_MAX || xp[i] < DOUBLE_MIN;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_INT64_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_INT64));
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX || xp[i] < 0;
    }
   /* update xpp and tp */
    if (realign) xp = (int64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_INT64_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


#if X_SIZEOF_INT64 == SIZEOF_LONGLONG
/* optimized version */
int
ncmpix_putn_NC_INT64_longlong(void **xpp, MPI_Offset nelems, const long long *tp, void *fillp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_INT64);
# else
	swapn8b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT64);
	return NC_NOERR;
}
#else
int
ncmpix_putn_NC_INT64_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_putn_NC_INT64_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX || tp[i] < X_INT64_MIN;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_INT64_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_INT64 == SIZEOF_INT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  int64 tmp[LOOPCNT];        /* in case input is misaligned */
  int64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_INT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (int64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (int64) Max( X_INT64_MIN, Min(X_INT64_MAX, (int64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_INT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_INT64);
      xp = (int64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT64, tp++)
	{
		int lstatus = ncmpix_put_NC_INT64_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


/* uint64 --------------------------------------------------------------------*/

#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
/* optimized version */
int
ncmpix_getn_NC_UINT64_ulonglong(const void **xpp, MPI_Offset nelems, unsigned long long *tp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(tp, *xpp, (size_t)nelems * SIZEOF_UNSIGNED_LONG_LONG);
# else
	swapn8b(tp, *xpp, nelems);
# endif
	*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT64);
	return NC_NOERR;
}
#else
int
ncmpix_getn_NC_UINT64_ulonglong(const void **xpp, MPI_Offset nelems, ulonglong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ulonglong) Max( ULONGLONG_MIN, Min(ULONGLONG_MAX, (ulonglong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > ULONGLONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_ulonglong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_getn_NC_UINT64_schar(const void **xpp, MPI_Offset nelems, schar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (schar) Max( SCHAR_MIN, Min(SCHAR_MAX, (schar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SCHAR_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_schar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_short(const void **xpp, MPI_Offset nelems, short *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (short) Max( SHORT_MIN, Min(SHORT_MAX, (short) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > SHORT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_short(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_int(const void **xpp, MPI_Offset nelems, int *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (int) Max( INT_MIN, Min(INT_MAX, (int) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > INT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_int(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_long(const void **xpp, MPI_Offset nelems, long *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (long) Max( LONG_MIN, Min(LONG_MAX, (long) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_long(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_float(const void **xpp, MPI_Offset nelems, float *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (float) Max( FLOAT_MIN, Min(FLOAT_MAX, (float) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > FLOAT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_float(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_double(const void **xpp, MPI_Offset nelems, double *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (double) Max( DOUBLE_MIN, Min(DOUBLE_MAX, (double) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > DOUBLE_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_double(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_longlong(const void **xpp, MPI_Offset nelems, longlong *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (longlong) Max( LONGLONG_MIN, Min(LONGLONG_MAX, (longlong) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > LONGLONG_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_longlong(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_uchar(const void **xpp, MPI_Offset nelems, uchar *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uchar) Max( UCHAR_MIN, Min(UCHAR_MAX, (uchar) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UCHAR_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_uchar(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_ushort(const void **xpp, MPI_Offset nelems, ushort *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (ushort) Max( USHORT_MIN, Min(USHORT_MAX, (ushort) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > USHORT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_ushort(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_getn_NC_UINT64_uint(const void **xpp, MPI_Offset nelems, uint *tp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of input data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update xpp to point at next unconverted input, and tp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      memcpy(tmp, *xpp, (size_t)(ni*SIZEOF_UINT64));
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      tp[i] = (uint) Max( UINT_MIN, Min(UINT_MAX, (uint) xp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned, we need not check if xp[i] < _MIN */
     /* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
      nrange += xp[i] > UINT_MAX ;
    }
   /* update xpp and tp */
    if (realign) xp = (uint64 *) *xpp;
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */
	const char *xp = (const char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		const int lstatus = ncmpix_get_NC_UINT64_uint(xp, tp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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


#if X_SIZEOF_UINT64 == SIZEOF_ULONGLONG
/* optimized version */
int
ncmpix_putn_NC_UINT64_ulonglong(void **xpp, MPI_Offset nelems, const unsigned long long *tp, void *fillp)
{
#ifdef WORDS_BIGENDIAN
	(void) memcpy(*xpp, tp, (size_t)nelems * X_SIZEOF_UINT64);
# else
	swapn8b(*xpp, tp, nelems);
# endif
	*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT64);
	return NC_NOERR;
}
#else
int
ncmpix_putn_NC_UINT64_ulonglong(void **xpp, MPI_Offset nelems, const ulonglong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_ulonglong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

#endif
int
ncmpix_putn_NC_UINT64_schar(void **xpp, MPI_Offset nelems, const schar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_schar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_short(void **xpp, MPI_Offset nelems, const short *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_short(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_int(void **xpp, MPI_Offset nelems, const int *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_int(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_long(void **xpp, MPI_Offset nelems, const long *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_long(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_float(void **xpp, MPI_Offset nelems, const float *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_float(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_double(void **xpp, MPI_Offset nelems, const double *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_double(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_longlong(void **xpp, MPI_Offset nelems, const longlong *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX || tp[i] < 0;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_longlong(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_uchar(void **xpp, MPI_Offset nelems, const uchar *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_uchar(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_ushort(void **xpp, MPI_Offset nelems, const ushort *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_ushort(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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

int
ncmpix_putn_NC_UINT64_uint(void **xpp, MPI_Offset nelems, const uint *tp, void *fillp)
{
#if defined(_SX) && _SX != 0 && X_SIZEOF_UINT64 == SIZEOF_UINT64

 /* basic algorithm is:
  *   - ensure sane alignment of output data
  *   - copy (conversion happens automatically) input data
  *     to output
  *   - update tp to point at next unconverted input, and xpp to point
  *     at next location for converted output
  */
  long i, j, ni;
  uint64 tmp[LOOPCNT];        /* in case input is misaligned */
  uint64 *xp;
  int nrange = 0;         /* number of range errors */
  int realign = 0;        /* "do we need to fix input data alignment?" */
  long cxp = (long) *((char**)xpp);

  realign = (cxp & 7) % SIZEOF_UINT64;
  /* sjl: manually stripmine so we can limit amount of
   * vector work space reserved to LOOPCNT elements. Also
   * makes vectorisation easy */
  for (j=0; j<nelems && nrange==0; j+=LOOPCNT) {
    ni=Min(nelems-j,LOOPCNT);
    if (realign) {
      xp = tmp;
    } else {
      xp = (uint64 *) *xpp;
    }
   /* copy the next block */
#pragma cdir loopcnt=LOOPCNT
#pragma cdir shortloop
    for (i=0; i<ni; i++) {
      /* the normal case: */
      xp[i] = (uint64) Max( X_UINT64_MIN, Min(X_UINT64_MAX, (uint64) tp[i]));
     /* test for range errors (not always needed but do it anyway) */
     /* if xpp is unsigned && tp is signed, we need check if tp[i] >= 0 */
     /* if tp is unsigned, we need not check if tp[i] < X__MIN */
      nrange += tp[i] > X_UINT64_MAX ;
    }
   /* copy workspace back if necessary */
    if (realign) {
      memcpy(*xpp, tmp, (size_t)*ni*X_SIZEOF_UINT64);
      xp = (uint64 *) *xpp;
    }
   /* update xpp and tp */
    xp += ni;
    tp += ni;
    *xpp = (void*)xp;
  }
  return nrange == 0 ? NC_NOERR : NC_ERANGE;

#else   /* not SX */

	char *xp = (char *) *xpp;
	int status = NC_NOERR;

	for( ; nelems != 0; nelems--, xp += X_SIZEOF_UINT64, tp++)
	{
		int lstatus = ncmpix_put_NC_UINT64_uint(xp, tp, fillp);
		if (status == NC_NOERR) /* report the first encountered error */
			status = lstatus;
	}

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



/*
 * Other aggregate conversion functions.
 */

/* text */

int
ncmpix_getn_text(const void **xpp, MPI_Offset nelems, char *tp)
{
	(void) memcpy(tp, *xpp, (size_t)nelems);
	*xpp = (void *)((char *)(*xpp) + nelems);
	return NC_NOERR;

}

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

	if (rndup)
		rndup = X_ALIGN - rndup;

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

	return NC_NOERR;

}

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

	return NC_NOERR;

}

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

	if (rndup)
		rndup = X_ALIGN - rndup;

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

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

	return NC_NOERR;

}


/* opaque */

int
ncmpix_getn_void(const void **xpp, MPI_Offset nelems, void *tp)
{
	(void) memcpy(tp, *xpp, (size_t)nelems);
	*xpp = (void *)((char *)(*xpp) + nelems);
	return NC_NOERR;

}

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

	if (rndup)
		rndup = X_ALIGN - rndup;

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

	return NC_NOERR;

}

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

	return NC_NOERR;

}

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

	if (rndup)
		rndup = X_ALIGN - rndup;

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

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

	return NC_NOERR;

}
