/* * Copyright 1996, University Corporation for Atmospheric Research * See netcdf/COPYRIGHT file for copying and redistribution conditions. * */ /* $Id: ncx_cray.c,v 1.60 2004/09/30 18:47:12 russ Exp $ */ #ifndef _CRAY #error "ncx_cray.c is a cray specific implementation" #endif #if HAVE_CONFIG_H #include #endif /* * An external data representation interface. */ /* * TODO: Fix "off diagonal" functions (ncx_{put,get}[n]_t1_t2() s.t. t1 != t2) * to be use IEG functions when diagonals are. * * Whine to cray about IEG function limiting behavior. */ #include #include /* alias poorly named limits.h macros */ #define SHORT_MAX SHRT_MAX #define SHORT_MIN SHRT_MIN #define USHORT_MAX USHRT_MAX #include #include #include "ncx.h" /**/ #if USE_IEG #define C_SIZE_T size_t extern int CRAY2IEG( const int *typep, const C_SIZE_T *nump, word *foreignp, const int *bitoffp, const void *local, const int *stride ); extern int IEG2CRAY( const int *typep, const C_SIZE_T *nump, const word *foreignp, const int *bitoffp, void *local, const int *stride ); static const int Zero = 0; static const C_SIZE_T One = 1; static const int ThirtyTwo = 32; static const int UnitStride = 1; static const int Cray2_I32 = 1; /* 32 bit two complement */ static const int Cray2_F32 = 2; /* IEEE single precision */ static const int Cray2_I16 = 7; /* 16 bit twos complement */ static const int Cray2_F64 = 8; /* CRAY float to IEEE double */ #define SHORT_USE_IEG 1 #define INT_USE_IEG 1 #define FLOAT_USE_IEG 1 #define DOUBLE_USE_IEG 1 #if _CRAY1 /* * Return the number of bits "into" a word that (void *) is. * N.B. This is based on the CRAY1 (PVP) address structure, * which puts the address within a word in the leftmost 3 bits * of the address. */ static size_t bitoff(const void *vp) { const size_t bitoffset = ((size_t)vp >> (64 - 6)) & 0x3f; return bitoffset; } # else #error "Don't use IEG2CRAY, CRAY2IEG except on CRAY1 (MPP) platforms" #define bitoff(vp) ((size_t)(vp) % 64) /* N.B. Assumes 64 bit word */ # endif /* _CRAY1 */ #endif /* USE_IEG */ #if _CRAY1 /* * Return the number of bytes "into" a word that (void *) is. * N.B. This is based on the CRAY1 (PVP) address structure, * which puts the address within a word in the leftmost 3 bits * of the address. */ static size_t byteoff(const void *vp) { const size_t byteoffset = ((size_t)vp >> (64 - 3)) & 0x7; return byteoffset; } #else #define byteoff(vp) ((size_t)(vp) % 8) /* N.B. Assumes 64 bit word */ #endif /* _CRAY1 */ /* * Return the number of bytes until the next "word" boundary */ static size_t word_align(const void *vp) { const size_t rem = byteoff(vp); if(rem == 0) return 0; return sizeof(word) - rem; } static const char nada[X_ALIGN] = {0, 0, 0, 0}; /* * Primitive numeric conversion functions. */ /* x_schar */ /* We don't implement and x_schar primitives. */ /* x_short */ typedef short ix_short; #define SIZEOF_IX_SHORT SIZEOF_SHORT #define IX_SHORT_MAX SHORT_MAX static void cget_short_short(const void *xp, short *ip, int which) { const long *wp = xp; switch(which) { case 0: *ip = (short)(*wp >> 48); break; case 1: *ip = (short)((*wp >> 32) & 0xffff); break; case 2: *ip = (short)((*wp >> 16) & 0xffff); break; case 3: *ip = (short)(*wp & 0xffff); break; } if(*ip & 0x8000) { /* extern is negative */ *ip |= (~(0xffff)); } } #define get_ix_short(xp, ip) cget_short_short((xp), (ip), byteoff(xp)/X_SIZEOF_SHORT) static int cput_short_short(void *xp, const short *ip, int which) { word *wp = xp; switch(which) { case 0: *wp = (*ip << 48) | (*wp & 0x0000ffffffffffff); break; case 1: *wp = ((*ip << 32) & 0x0000ffff00000000) | (*wp & 0xffff0000ffffffff); break; case 2: *wp = ((*ip << 16) & 0x00000000ffff0000) | (*wp & 0xffffffff0000ffff); break; case 3: *wp = (*ip & 0x000000000000ffff) | (*wp & 0xffffffffffff0000); break; } if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_short_schar(const void *xp, schar *ip) { ix_short xx; get_ix_short(xp, &xx); *ip = xx; if(xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_short_uchar(const void *xp, uchar *ip) { ix_short xx; get_ix_short(xp, &xx); *ip = xx; if(xx > UCHAR_MAX || xx < 0) return NC_ERANGE; return NC_NOERR; } int ncx_get_short_short(const void *xp, short *ip) { get_ix_short(xp, ip); return NC_NOERR; } int ncx_get_short_int(const void *xp, int *ip) { ix_short xx; get_ix_short(xp, &xx); *ip = xx; return NC_NOERR; } int ncx_get_short_long(const void *xp, long *ip) { ix_short xx; get_ix_short(xp, &xx); *ip = xx; return NC_NOERR; } int ncx_get_short_float(const void *xp, float *ip) { ix_short xx; get_ix_short(xp, &xx); *ip = xx; return NC_NOERR; } int ncx_get_short_double(const void *xp, double *ip) { ix_short xx; get_ix_short(xp, &xx); *ip = xx; return NC_NOERR; } int ncx_put_short_schar(void *xp, const schar *ip) { uchar *cp = xp; if(*ip & 0x80) *cp++ = 0xff; else *cp++ = 0; *cp = (uchar)*ip; return NC_NOERR; } int ncx_put_short_uchar(void *xp, const uchar *ip) { uchar *cp = xp; *cp++ = 0; *cp = *ip; return NC_NOERR; } int ncx_put_short_short(void *xp, const short *ip) { return cput_short_short(xp, ip, byteoff(xp)/X_SIZEOF_SHORT); } int ncx_put_short_int(void *xp, const int *ip) { ix_short xx = (ix_short)*ip; return cput_short_short(xp, &xx, byteoff(xp)/X_SIZEOF_SHORT); } int ncx_put_short_long(void *xp, const long *ip) { ix_short xx = (ix_short)*ip; return cput_short_short(xp, &xx, byteoff(xp)/X_SIZEOF_SHORT); } int ncx_put_short_float(void *xp, const float *ip) { ix_short xx = (ix_short)*ip; const int status = cput_short_short(xp, &xx, byteoff(xp)/X_SIZEOF_SHORT); if(status != NC_NOERR) return status; if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_put_short_double(void *xp, const double *ip) { ix_short xx = (ix_short)*ip; const int status = cput_short_short(xp, &xx, byteoff(xp)/X_SIZEOF_SHORT); if(status != NC_NOERR) return status; if(*ip > X_SHORT_MAX || *ip < X_SHORT_MIN) return NC_ERANGE; return NC_NOERR; } /* x_int */ typedef int ix_int; #define SIZEOF_IX_INT SIZEOF_INT #define IX_INT_MAX INT_MAX static void cget_int_int(const void *xp, int *ip, int which) { const long *wp = xp; if(which == 0) { *ip = (int)(*wp >> 32); } else { *ip = (int)(*wp & 0xffffffff); } if(*ip & 0x80000000) { /* extern is negative */ *ip |= (~(0xffffffff)); } } #define get_ix_int(xp, ip) cget_int_int((xp), (ip), byteoff(xp)) static int cput_int_int(void *xp, const int *ip, int which) { word *wp = xp; if(which == 0) { *wp = (*ip << 32) | (*wp & 0xffffffff); } else { *wp = (*wp & ~0xffffffff) | (*ip & 0xffffffff); } if(*ip > X_INT_MAX || *ip < X_INT_MIN) return NC_ERANGE; return NC_NOERR; } #define put_ix_int(xp, ip) cput_int_int((xp), (ip), byteoff(xp)) int ncx_get_int_schar(const void *xp, schar *ip) { ix_int xx; get_ix_int(xp, &xx); *ip = xx; if(xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_int_uchar(const void *xp, uchar *ip) { ix_int xx; get_ix_int(xp, &xx); *ip = xx; if(xx > UCHAR_MAX || xx < 0) return NC_ERANGE; return NC_NOERR; } int ncx_get_int_short(const void *xp, short *ip) { ix_int xx; get_ix_int(xp, &xx); *ip = xx; if(xx > SHORT_MAX || xx < SHORT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_int_int(const void *xp, int *ip) { ix_int xx; get_ix_int(xp, &xx); *ip = xx; return NC_NOERR; } static void cget_int_long(const void *xp, long *ip, int which) { const long *wp = xp; if(which == 0) { *ip = (int)(*wp >> 32); } else { *ip = (int)(*wp & 0xffffffff); } if(*ip & 0x80000000) { /* extern is negative */ *ip |= (~(0xffffffff)); } } int ncx_get_int_long(const void *xp, long *ip) { cget_int_long(xp, ip, byteoff(xp)); return NC_NOERR; } int ncx_get_int_float(const void *xp, float *ip) { ix_int xx; get_ix_int(xp, &xx); *ip = xx; if(xx > FLT_MAX || xx < (-FLT_MAX)) return NC_ERANGE; return NC_NOERR; } int ncx_get_int_double(const void *xp, double *ip) { ix_int xx; get_ix_int(xp, &xx); *ip = xx; return NC_NOERR; } int ncx_put_int_schar(void *xp, const schar *ip) { uchar *cp = xp; if(*ip & 0x80) { *cp++ = 0xff; *cp++ = 0xff; *cp++ = 0xff; } else { *cp++ = 0x00; *cp++ = 0x00; *cp++ = 0x00; } *cp = (uchar)*ip; return NC_NOERR; } int ncx_put_int_uchar(void *xp, const uchar *ip) { uchar *cp = xp; *cp++ = 0x00; *cp++ = 0x00; *cp++ = 0x00; *cp = *ip; return NC_NOERR; } int ncx_put_int_short(void *xp, const short *ip) { ix_int xx = (ix_int)(*ip); return put_ix_int(xp, &xx); } int ncx_put_int_int(void *xp, const int *ip) { return put_ix_int(xp, ip); } static int cput_int_long(void *xp, const long *ip, int which) { long *wp = xp; if(which == 0) { *wp = (*ip << 32) | (*wp & 0xffffffff); } else { *wp = (*wp & ~0xffffffff) | (*ip & 0xffffffff); } if(*ip > X_INT_MAX || *ip < X_INT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_put_int_long(void *xp, const long *ip) { return cput_int_long(xp, ip, byteoff(xp)); } int ncx_put_int_float(void *xp, const float *ip) { ix_int xx = (ix_int)(*ip); const int status = put_ix_int(xp, &xx); if(status != NC_NOERR) return status; if(*ip > (double)X_INT_MAX || *ip < (double)X_INT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_put_int_double(void *xp, const double *ip) { ix_int xx = (ix_int)(*ip); const int status = put_ix_int(xp, &xx); if(status != NC_NOERR) return status; if(*ip > X_INT_MAX || *ip < X_INT_MIN) return NC_ERANGE; return NC_NOERR; } /* x_float */ #if defined(NO_IEEE_FLOAT) struct cray_single { unsigned int sign : 1; unsigned int exp :15; unsigned int mant :48; }; typedef struct cray_single cray_single; static const int cs_ieis_bias = 0x4000 - 0x7f; static const int cs_id_bias = 0x4000 - 0x3ff; #endif struct ieee_single_hi { unsigned int sign : 1; unsigned int exp : 8; unsigned int mant :23; unsigned int pad :32; }; typedef struct ieee_single_hi ieee_single_hi; struct ieee_single_lo { unsigned int pad :32; unsigned int sign : 1; unsigned int exp : 8; unsigned int mant :23; }; typedef struct ieee_single_lo ieee_single_lo; static const int ieee_single_bias = 0x7f; struct ieee_double { unsigned int sign : 1; unsigned int exp :11; unsigned int mant :52; }; typedef struct ieee_double ieee_double; static const int ieee_double_bias = 0x3ff; #if FLOAT_USE_IEG static void get_ix_float(const void *xp, float *ip) { const int bo = bitoff(xp); (void) IEG2CRAY(&Cray2_F32, &One, (word *)xp, &bo, ip, &UnitStride); } static int put_ix_float(void *xp, const float *ip) { const int bo = bitoff(xp); int status = CRAY2IEG(&Cray2_F32, &One, (word *)xp, &bo, ip, &UnitStride); if(status != 0) status = NC_ERANGE; /* else, status == 0 == NC_NOERR */ return status; } #else /* !FLOAT_USE_IEG */ #if defined(NO_IEEE_FLOAT) static void cget_float_float(const void *xp, float *ip, int which) { if(which == 0) { const ieee_single_hi *isp = (const ieee_single_hi *) xp; cray_single *csp = (cray_single *) ip; if(isp->exp == 0) { /* ieee subnormal */ *ip = (double)isp->mant; if(isp->mant != 0) { csp->exp -= (ieee_single_bias + 22); } } else { csp->exp = isp->exp + cs_ieis_bias + 1; csp->mant = isp->mant << (48 - 1 - 23); csp->mant |= (1 << (48 - 1)); } csp->sign = isp->sign; } else { const ieee_single_lo *isp = (const ieee_single_lo *) xp; cray_single *csp = (cray_single *) ip; if(isp->exp == 0) { /* ieee subnormal */ *ip = (double)isp->mant; if(isp->mant != 0) { csp->exp -= (ieee_single_bias + 22); } } else { csp->exp = isp->exp + cs_ieis_bias + 1; csp->mant = isp->mant << (48 - 1 - 23); csp->mant |= (1 << (48 - 1)); } csp->sign = isp->sign; } } static int cput_float_float(void *xp, const float *ip, int which) { int status = NC_NOERR; if(which == 0) { ieee_single_hi *isp = (ieee_single_hi*)xp; const cray_single *csp = (const cray_single *) ip; int ieee_exp = csp->exp - cs_ieis_bias -1; isp->sign = csp->sign; if(ieee_exp >= 0xff || *ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) { /* NC_ERANGE => ieee Inf */ isp->exp = 0xff; isp->mant = 0x0; return NC_ERANGE; } /* else */ if(ieee_exp > 0) { /* normal ieee representation */ isp->exp = ieee_exp; /* assumes cray rep is in normal form */ /* assert(csp->mant & 0x800000000000); */ isp->mant = (((csp->mant << 1) & 0xffffffffffff) >> (48 - 23)); } else if(ieee_exp > -23) { /* ieee subnormal, right */ const int rshift = (48 - 23 - ieee_exp); isp->mant = csp->mant >> rshift; isp->exp = 0; } else { /* smaller than ieee can represent */ isp->exp = 0; isp->mant = 0; } } else { ieee_single_lo *isp = (ieee_single_lo*)xp; const cray_single *csp = (const cray_single *) ip; int ieee_exp = csp->exp - cs_ieis_bias -1; isp->sign = csp->sign; if(ieee_exp >= 0xff || *ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) { /* NC_ERANGE => ieee Inf */ isp->exp = 0xff; isp->mant = 0x0; return NC_ERANGE; } /* else */ if(ieee_exp > 0) { /* normal ieee representation */ isp->exp = ieee_exp; /* assumes cray rep is in normal form */ /* assert(csp->mant & 0x800000000000); */ isp->mant = (((csp->mant << 1) & 0xffffffffffff) >> (48 - 23)); } else if(ieee_exp > -23) { /* ieee subnormal, right */ const int rshift = (48 - 23 - ieee_exp); isp->mant = csp->mant >> rshift; isp->exp = 0; } else { /* smaller than ieee can represent */ isp->exp = 0; isp->mant = 0; } } return NC_NOERR; } #define get_ix_float(xp, ip) cget_float_float((xp), (ip), byteoff(xp)) #define put_ix_float(xp, ip) cput_float_float((xp), (ip), byteoff(xp)) #else /* IEEE Cray with only doubles */ static void cget_float_float(const void *xp, float *ip, int which) { ieee_double *idp = (ieee_double *) ip; if(which == 0) { const ieee_single_hi *isp = (const ieee_single_hi *) xp; if(isp->exp == 0 && isp->mant == 0) { idp->exp = 0; idp->mant = 0; } else { idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias); idp->mant = isp->mant << (52 - 23); } idp->sign = isp->sign; } else { const ieee_single_lo *isp = (const ieee_single_lo *) xp; if(isp->exp == 0 && isp->mant == 0) { idp->exp = 0; idp->mant = 0; } else { idp->exp = isp->exp + (ieee_double_bias - ieee_single_bias); idp->mant = isp->mant << (52 - 23); } idp->sign = isp->sign; } } static int cput_float_float(void *xp, const float *ip, int which) { const ieee_double *idp = (const ieee_double *) ip; if(which == 0) { ieee_single_hi *isp = (ieee_single_hi*)xp; if(idp->exp > (ieee_double_bias - ieee_single_bias)) isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); else isp->exp = 0; isp->mant = idp->mant >> (52 - 23); isp->sign = idp->sign; } else { ieee_single_lo *isp = (ieee_single_lo*)xp; if(idp->exp > (ieee_double_bias - ieee_single_bias)) isp->exp = idp->exp - (ieee_double_bias - ieee_single_bias); else isp->exp = 0; isp->mant = idp->mant >> (52 - 23); isp->sign = idp->sign; } if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) return NC_ERANGE; return NC_NOERR; } #define get_ix_float(xp, ip) cget_float_float((xp), (ip), byteoff(xp)) #define put_ix_float(xp, ip) cput_float_float((xp), (ip), byteoff(xp)) #endif /* NO_IEEE_FLOAT */ #endif /* FLOAT_USE_IEG */ int ncx_get_float_schar(const void *xp, schar *ip) { float xx; get_ix_float(xp, &xx); *ip = (schar) xx; if(xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_float_uchar(const void *xp, uchar *ip) { float xx; get_ix_float(xp, &xx); *ip = (uchar) xx; if(xx > UCHAR_MAX || xx < 0) return NC_ERANGE; return NC_NOERR; } int ncx_get_float_short(const void *xp, short *ip) { float xx; get_ix_float(xp, &xx); *ip = (short) xx; if(xx > SHORT_MAX || xx < SHORT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_float_int(const void *xp, int *ip) { float xx; get_ix_float(xp, &xx); *ip = (int) xx; if(xx > (double)INT_MAX || xx < (double)INT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_float_long(const void *xp, long *ip) { float xx; get_ix_float(xp, &xx); *ip = (long) xx; if(xx > LONG_MAX || xx < LONG_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_float_float(const void *xp, float *ip) { get_ix_float(xp, ip); return NC_NOERR; } int ncx_get_float_double(const void *xp, double *ip) { #if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG return ncx_get_float_float(xp, (float *)ip); #else float xx; get_ix_float(xp, &xx); *ip = xx; return NC_NOERR; #endif } int ncx_put_float_schar(void *xp, const schar *ip) { float xx = (float) *ip; return put_ix_float(xp, &xx); } int ncx_put_float_uchar(void *xp, const uchar *ip) { float xx = (float) *ip; return put_ix_float(xp, &xx); } int ncx_put_float_short(void *xp, const short *ip) { float xx = (float) *ip; return put_ix_float(xp, &xx); } int ncx_put_float_int(void *xp, const int *ip) { float xx = (float) *ip; return put_ix_float(xp, &xx); } int ncx_put_float_long(void *xp, const long *ip) { float xx = (float) *ip; return put_ix_float(xp, &xx); } int ncx_put_float_float(void *xp, const float *ip) { return put_ix_float(xp, ip); } int ncx_put_float_double(void *xp, const double *ip) { #if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG return put_ix_float(xp, (float *)ip); #else float xx = (float) *ip; int status = put_ix_float(xp, &xx); if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN) return NC_ERANGE; return status; #endif } /* x_double */ #if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) static void get_ix_double(const void *xp, double *ip) { (void) memcpy(ip, xp, sizeof(double)); } static int put_ix_double(void *xp, const double *ip) { (void) memcpy(xp, ip, X_SIZEOF_DOUBLE); return NC_NOERR; } #else static void cget_double_double(const void *xp, double *ip) { const ieee_double *idp = (const ieee_double *) xp; cray_single *csp = (cray_single *) ip; if(idp->exp == 0) { /* ieee subnormal */ *ip = (double)idp->mant; if(idp->mant != 0) { csp->exp -= (ieee_double_bias + 51); } } else { csp->exp = idp->exp + cs_id_bias + 1; csp->mant = idp->mant >> (52 - 48 + 1); csp->mant |= (1 << (48 - 1)); } csp->sign = idp->sign; } static int cput_double_double(void *xp, const double *ip) { ieee_double *idp = (ieee_double *) xp; const cray_single *csp = (const cray_single *) ip; int ieee_exp = csp->exp - cs_id_bias -1; idp->sign = csp->sign; if(ieee_exp >= 0x7ff) { /* NC_ERANGE => ieee Inf */ idp->exp = 0x7ff; idp->mant = 0x0; return NC_ERANGE; } /* else */ if(ieee_exp > 0) { /* normal ieee representation */ idp->exp = ieee_exp; /* assumes cray rep is in normal form */ assert(csp->mant & 0x800000000000); idp->mant = (((csp->mant << 1) & 0xffffffffffff) << (52 - 48)); } else if(ieee_exp >= (-(52 -48))) { /* ieee subnormal, left */ const int lshift = (52 - 48) + ieee_exp; idp->mant = csp->mant << lshift; idp->exp = 0; } else if(ieee_exp >= -52) { /* ieee subnormal, right */ const int rshift = (- (52 - 48) - ieee_exp); idp->mant = csp->mant >> rshift; idp->exp = 0; } else { /* smaller than ieee can represent */ idp->exp = 0; idp->mant = 0; } return NC_NOERR; } #define get_ix_double(xp, ip) cget_double_double((xp), (ip)) #define put_ix_double(xp, ip) cput_double_double((xp), (ip)) #endif /* NO_IEEE_FLOAT */ int ncx_get_double_schar(const void *xp, schar *ip) { double xx; get_ix_double(xp, &xx); *ip = (schar) xx; if(xx > SCHAR_MAX || xx < SCHAR_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_double_uchar(const void *xp, uchar *ip) { double xx; get_ix_double(xp, &xx); *ip = (uchar) xx; if(xx > UCHAR_MAX || xx < 0) return NC_ERANGE; return NC_NOERR; } int ncx_get_double_short(const void *xp, short *ip) { double xx; get_ix_double(xp, &xx); *ip = (short) xx; if(xx > SHORT_MAX || xx < SHORT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_double_int(const void *xp, int *ip) { double xx; get_ix_double(xp, &xx); *ip = (int) xx; if(xx > INT_MAX || xx < INT_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_double_long(const void *xp, long *ip) { double xx; get_ix_double(xp, &xx); *ip = (long) xx; if(xx > LONG_MAX || xx < LONG_MIN) return NC_ERANGE; return NC_NOERR; } int ncx_get_double_float(const void *xp, float *ip) { #if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG get_ix_double(xp, (double *)ip); return NC_NOERR; #else double xx; get_ix_double(xp, &xx); if(xx > FLT_MAX || xx < (-FLT_MAX)) { *ip = FLT_MAX; return NC_ERANGE; } if(xx < (-FLT_MAX)) { *ip = (-FLT_MAX); return NC_ERANGE; } *ip = (float) xx; return NC_NOERR; #endif } int ncx_get_double_double(const void *xp, double *ip) { get_ix_double(xp, ip); return NC_NOERR; } int ncx_put_double_schar(void *xp, const schar *ip) { double xx = (double) *ip; put_ix_double(xp, &xx); return NC_NOERR; } int ncx_put_double_uchar(void *xp, const uchar *ip) { double xx = (double) *ip; put_ix_double(xp, &xx); return NC_NOERR; } int ncx_put_double_short(void *xp, const short *ip) { double xx = (double) *ip; put_ix_double(xp, &xx); return NC_NOERR; } int ncx_put_double_int(void *xp, const int *ip) { double xx = (double) *ip; put_ix_double(xp, &xx); return NC_NOERR; } int ncx_put_double_long(void *xp, const long *ip) { double xx = (double) *ip; put_ix_double(xp, &xx); /* TODO: Deal with big guys */ return NC_NOERR; } int ncx_put_double_float(void *xp, const float *ip) { #if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG put_ix_double(xp, (double *)ip); return NC_NOERR; #else double xx = (double) *ip; return put_ix_double(xp, &xx); #endif } int ncx_put_double_double(void *xp, const double *ip) { #if !defined(NO_IEEE_FLOAT) put_ix_double(xp, ip); return NC_NOERR; #else return put_ix_double(xp, ip); #endif } /* x_size_t */ int ncx_put_size_t(void **xpp, const size_t *ulp) { /* similar to put_ix_int() */ uchar *cp = *xpp; assert(*ulp <= X_SIZE_MAX); *cp++ = (uchar)((*ulp) >> 24); *cp++ = (uchar)(((*ulp) & 0x00ff0000) >> 16); *cp++ = (uchar)(((*ulp) & 0x0000ff00) >> 8); *cp = (uchar)((*ulp) & 0x000000ff); *xpp = (void *)((char *)(*xpp) + X_SIZEOF_SIZE_T); return NC_NOERR; } int ncx_get_size_t(const void **xpp, size_t *ulp) { /* similar to get_ix_int */ const uchar *cp = *xpp; assert((*cp & 0x80) == 0); /* sizes limited to 2^31 -1 in netcdf */ *ulp = *cp++ << 24; *ulp |= (*cp++ << 16); *ulp |= (*cp++ << 8); *ulp |= *cp; *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T); return NC_NOERR; } /* x_off_t */ int ncx_put_off_t(void **xpp, const off_t *lp) { /* similar to put_ix_int() */ uchar *cp = *xpp; /* No negative offsets stored in netcdf */ assert(*lp >= 0 && *lp <= X_OFF_MAX); *cp++ = (uchar)((*lp) >> 24); *cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16); *cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8); *cp = (uchar)((*lp) & 0x000000ff); *xpp = (void *)((char *)(*xpp) + X_SIZEOF_OFF_T); return NC_NOERR; } int ncx_get_off_t(const void **xpp, off_t *lp) { /* similar to get_ix_int() */ const uchar *cp = *xpp; assert((*cp & 0x80) == 0); /* No negative offsets stored in netcdf */ *lp = *cp++ << 24; *lp |= (*cp++ << 16); *lp |= (*cp++ << 8); *lp |= *cp; *xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_OFF_T); return NC_NOERR; } /* * Aggregate numeric conversion functions. */ /* schar */ int ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp) { (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp) { (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_getn_schar_short(const void **xpp, size_t nelems, short *tp) { schar *xp = (schar *)(*xpp); while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (const void *)xp; return NC_NOERR; } int ncx_getn_schar_int(const void **xpp, size_t nelems, int *tp) { schar *xp = (schar *)(*xpp); while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (const void *)xp; return NC_NOERR; } int ncx_getn_schar_long(const void **xpp, size_t nelems, long *tp) { schar *xp = (schar *)(*xpp); while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (const void *)xp; return NC_NOERR; } int ncx_getn_schar_float(const void **xpp, size_t nelems, float *tp) { schar *xp = (schar *)(*xpp); while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (const void *)xp; return NC_NOERR; } int ncx_getn_schar_double(const void **xpp, size_t nelems, double *tp) { schar *xp = (schar *)(*xpp); while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (const void *)xp; return NC_NOERR; } int ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems + rndup); return NC_NOERR; } int ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems + rndup); return NC_NOERR; } int ncx_pad_getn_schar_short(const void **xpp, size_t nelems, short *tp) { size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (void *)(xp + rndup); return NC_NOERR; } int ncx_pad_getn_schar_int(const void **xpp, size_t nelems, int *tp) { size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (void *)(xp + rndup); return NC_NOERR; } int ncx_pad_getn_schar_long(const void **xpp, size_t nelems, long *tp) { size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (void *)(xp + rndup); return NC_NOERR; } int ncx_pad_getn_schar_float(const void **xpp, size_t nelems, float *tp) { size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (void *)(xp + rndup); return NC_NOERR; } int ncx_pad_getn_schar_double(const void **xpp, size_t nelems, double *tp) { size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { *tp++ = *xp++; } *xpp = (void *)(xp + rndup); return NC_NOERR; } int ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp) { (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp) { (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_putn_schar_short(void **xpp, size_t nelems, const short *tp) { int status = NC_NOERR; schar *xp = (schar *)(*xpp); while(nelems-- != 0) { if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } *xpp = (void *)xp; return status; } int ncx_putn_schar_int(void **xpp, size_t nelems, const int *tp) { int status = NC_NOERR; schar *xp = (schar *)(*xpp); while(nelems-- != 0) { if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } *xpp = (void *)xp; return status; } int ncx_putn_schar_long(void **xpp, size_t nelems, const long *tp) { int status = NC_NOERR; schar *xp = (schar *)(*xpp); while(nelems-- != 0) { if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } *xpp = (void *)xp; return status; } int ncx_putn_schar_float(void **xpp, size_t nelems, const float *tp) { int status = NC_NOERR; schar *xp = (schar *)(*xpp); while(nelems-- != 0) { if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } *xpp = (void *)xp; return status; } int ncx_putn_schar_double(void **xpp, size_t nelems, const double *tp) { int status = NC_NOERR; schar *xp = (schar *)(*xpp); while(nelems-- != 0) { if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } *xpp = (void *)xp; return status; } int ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); if(rndup) { (void) memcpy(*xpp, nada, rndup); *xpp = (void *)((char *)(*xpp) + rndup); } return NC_NOERR; } int ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); if(rndup) { (void) memcpy(*xpp, nada, rndup); *xpp = (void *)((char *)(*xpp) + rndup); } return NC_NOERR; } int ncx_pad_putn_schar_short(void **xpp, size_t nelems, const short *tp) { int status = NC_NOERR; size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { /* N.B. schar as signed */ if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } if(rndup) { (void) memcpy(xp, nada, rndup); xp += rndup; } *xpp = (void *)xp; return status; } int ncx_pad_putn_schar_int(void **xpp, size_t nelems, const int *tp) { int status = NC_NOERR; size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { /* N.B. schar as signed */ if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } if(rndup) { (void) memcpy(xp, nada, rndup); xp += rndup; } *xpp = (void *)xp; return status; } int ncx_pad_putn_schar_long(void **xpp, size_t nelems, const long *tp) { int status = NC_NOERR; size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { /* N.B. schar as signed */ if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } if(rndup) { (void) memcpy(xp, nada, rndup); xp += rndup; } *xpp = (void *)xp; return status; } int ncx_pad_putn_schar_float(void **xpp, size_t nelems, const float *tp) { int status = NC_NOERR; size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { /* N.B. schar as signed */ if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } if(rndup) { (void) memcpy(xp, nada, rndup); xp += rndup; } *xpp = (void *)xp; return status; } int ncx_pad_putn_schar_double(void **xpp, size_t nelems, const double *tp) { int status = NC_NOERR; size_t rndup = nelems % X_ALIGN; schar *xp = (schar *)(*xpp); if(rndup) rndup = X_ALIGN - rndup; while(nelems-- != 0) { /* N.B. schar as signed */ if(*tp > X_SCHAR_MAX || *tp < X_SCHAR_MIN) status = NC_ERANGE; *xp++ = (schar) *tp++; } if(rndup) { (void) memcpy(xp, nada, rndup); xp += rndup; } *xpp = (void *)xp; return status; } /* short */ int ncx_getn_short_schar(const void **xpp, size_t nelems, schar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } #if SHORT_USE_IEG int ncx_getn_short_short(const void **xpp, size_t nelems, short *tp) { if(nelems > 0) { const int bo = bitoff(*xpp); const word *wp = *xpp; int ierr; *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_SHORT); ierr = IEG2CRAY(&Cray2_I16, &nelems, wp, &bo, tp, &UnitStride); assert(ierr >= 0); if(ierr > 0) return NC_ERANGE; } return NC_NOERR; } #else int ncx_getn_short_short(const void **xpp, const size_t nelems, short *tp) { if(nelems > 0) { const word *wp = *xpp; const short *const last = &tp[nelems -1]; const int rem = word_align(*xpp)/X_SIZEOF_SHORT; *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_SHORT); switch(rem) { case 3: *tp = (short)((*wp >> 32) & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); if(tp == last) return NC_NOERR; tp++; /*FALLTHRU*/ case 2: *tp = (short)((*wp >> 16) & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); if(tp == last) return NC_NOERR; tp++; /*FALLTHRU*/ case 1: *tp = (short)(*wp & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); if(tp == last) return NC_NOERR; tp++; wp++; /* Note Bene */ /*FALLTHRU*/ } assert((nelems - rem) != 0); { const int nwords = ((nelems - rem) * X_SIZEOF_SHORT) / sizeof(word); const word *const endw = &wp[nwords]; #pragma _CRI ivdep for( ; wp < endw; wp++) { *tp = (short)(*wp >> 48); if(*tp & 0x8000) *tp |= (~(0xffff)); tp++; *tp = (short)((*wp >> 32) & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); tp++; *tp = (short)((*wp >> 16) & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); tp++; *tp = (short)(*wp & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); tp++; } } if(tp <= last) { *tp = (short)(*wp >> 48); if(*tp & 0x8000) *tp |= (~(0xffff)); tp++; } if(tp <= last) { *tp = (short)((*wp >> 32) & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); tp++; } if(tp <= last) { *tp = (short)((*wp >> 16) & 0xffff); if(*tp & 0x8000) *tp |= (~(0xffff)); tp++; } } return NC_NOERR; } #endif int ncx_getn_short_int(const void **xpp, size_t nelems, int *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_short_long(const void **xpp, size_t nelems, long *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_short_float(const void **xpp, size_t nelems, float *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_short_double(const void **xpp, size_t nelems, double *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_pad_getn_short_schar(const void **xpp, size_t nelems, schar *tp) { const size_t rndup = nelems % 2; const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) xp += X_SIZEOF_SHORT; *xpp = (void *)xp; return status; } int ncx_pad_getn_short_uchar(const void **xpp, size_t nelems, uchar *tp) { const size_t rndup = nelems % 2; const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) xp += X_SIZEOF_SHORT; *xpp = (void *)xp; return status; } int ncx_pad_getn_short_short(const void **xpp, size_t nelems, short *tp) { const size_t rndup = nelems % 2; const int status = ncx_getn_short_short(xpp, nelems, tp); if(rndup != 0) { *xpp = ((char *) (*xpp) + X_SIZEOF_SHORT); } return status; } int ncx_pad_getn_short_int(const void **xpp, size_t nelems, int *tp) { const size_t rndup = nelems % 2; const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) xp += X_SIZEOF_SHORT; *xpp = (void *)xp; return status; } int ncx_pad_getn_short_long(const void **xpp, size_t nelems, long *tp) { const size_t rndup = nelems % 2; const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) xp += X_SIZEOF_SHORT; *xpp = (void *)xp; return status; } int ncx_pad_getn_short_float(const void **xpp, size_t nelems, float *tp) { const size_t rndup = nelems % 2; const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) xp += X_SIZEOF_SHORT; *xpp = (void *)xp; return status; } int ncx_pad_getn_short_double(const void **xpp, size_t nelems, double *tp) { const size_t rndup = nelems % 2; const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_get_short_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) xp += X_SIZEOF_SHORT; *xpp = (void *)xp; return status; } int ncx_putn_short_schar(void **xpp, size_t nelems, const schar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } #if SHORT_USE_IEG int ncx_putn_short_short(void **xpp, size_t nelems, const short *tp) { if(nelems > 0) { word *wp = *xpp; const int bo = bitoff(*xpp); int ierr; *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_SHORT); ierr = CRAY2IEG(&Cray2_I16, &nelems, wp, &bo, tp, &UnitStride); assert(ierr >= 0); if(ierr > 0) return NC_ERANGE; } return NC_NOERR; } #else int ncx_putn_short_short(void **xpp, const size_t nelems, const short *tp) { int status = NC_NOERR; if(nelems == 0) return status; { word *wp = *xpp; const short *const last = &tp[nelems -1]; const int rem = word_align(*xpp)/X_SIZEOF_SHORT; *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_SHORT); switch(rem) { case 3: *wp = ((*tp << 32) & 0x0000ffff00000000) | (*wp & 0xffff0000ffffffff); if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN) status = NC_ERANGE; if(tp == last) return status; tp++; /*FALLTHRU*/ case 2: *wp = ((*tp << 16) & 0x00000000ffff0000) | (*wp & 0xffffffff0000ffff); if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN) status = NC_ERANGE; if(tp == last) return status; tp++; /*FALLTHRU*/ case 1: *wp = (*tp & 0x000000000000ffff) | (*wp & 0xffffffffffff0000); if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN) status = NC_ERANGE; if(tp == last) return status; tp++; wp++; /* Note Bene */ /*FALLTHRU*/ } assert((nelems - rem) != 0); { const int nwords = ((nelems - rem) * X_SIZEOF_SHORT) / sizeof(word); const word *const endw = &wp[nwords]; #pragma _CRI ivdep for( ; wp < endw; wp++) { *wp = (*tp << 48) | ((*(tp +1) << 32) & 0x0000ffff00000000) | ((*(tp +2) << 16) & 0x00000000ffff0000) | ((*(tp +3) ) & 0x000000000000ffff); { int ii = 0; for(; ii < 4; ii++, tp++) if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN) status = NC_ERANGE; } } } if(tp <= last) { *wp = (*tp << 48) | (*wp & 0x0000ffffffffffff); if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN) status = NC_ERANGE; tp++; } if(tp <= last) { *wp = ((*tp << 32) & 0x0000ffff00000000) | (*wp & 0xffff0000ffffffff); if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN) status = NC_ERANGE; tp++; } if(tp <= last) { *wp = ((*tp << 16) & 0x00000000ffff0000) | (*wp & 0xffffffff0000ffff); if(*tp > X_SHORT_MAX || *tp < X_SHORT_MIN) status = NC_ERANGE; } return status; } } #endif int ncx_putn_short_int(void **xpp, size_t nelems, const int *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_short_long(void **xpp, size_t nelems, const long *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_short_float(void **xpp, size_t nelems, const float *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_short_double(void **xpp, size_t nelems, const double *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_pad_putn_short_schar(void **xpp, size_t nelems, const schar *tp) { const size_t rndup = nelems % 2; char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) { (void) memcpy(xp, nada, X_SIZEOF_SHORT); xp += X_SIZEOF_SHORT; } *xpp = (void *)xp; return status; } int ncx_pad_putn_short_uchar(void **xpp, size_t nelems, const uchar *tp) { const size_t rndup = nelems % 2; char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) { (void) memcpy(xp, nada, X_SIZEOF_SHORT); xp += X_SIZEOF_SHORT; } *xpp = (void *)xp; return status; } int ncx_pad_putn_short_short(void **xpp, size_t nelems, const short *tp) { const size_t rndup = nelems % 2; const int status = ncx_putn_short_short(xpp, nelems, tp); if(rndup != 0) { *xpp = ((char *) (*xpp) + X_SIZEOF_SHORT); } return status; } int ncx_pad_putn_short_int(void **xpp, size_t nelems, const int *tp) { const size_t rndup = nelems % 2; char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) { (void) memcpy(xp, nada, X_SIZEOF_SHORT); xp += X_SIZEOF_SHORT; } *xpp = (void *)xp; return status; } int ncx_pad_putn_short_long(void **xpp, size_t nelems, const long *tp) { const size_t rndup = nelems % 2; char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) { (void) memcpy(xp, nada, X_SIZEOF_SHORT); xp += X_SIZEOF_SHORT; } *xpp = (void *)xp; return status; } int ncx_pad_putn_short_float(void **xpp, size_t nelems, const float *tp) { const size_t rndup = nelems % 2; char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) { (void) memcpy(xp, nada, X_SIZEOF_SHORT); xp += X_SIZEOF_SHORT; } *xpp = (void *)xp; return status; } int ncx_pad_putn_short_double(void **xpp, size_t nelems, const double *tp) { const size_t rndup = nelems % 2; char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_SHORT, tp++) { const int lstatus = ncx_put_short_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } if(rndup != 0) { (void) memcpy(xp, nada, X_SIZEOF_SHORT); xp += X_SIZEOF_SHORT; } *xpp = (void *)xp; return status; } /* int */ int ncx_getn_int_schar(const void **xpp, size_t nelems, schar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_get_int_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_int_uchar(const void **xpp, size_t nelems, uchar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_get_int_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_int_short(const void **xpp, size_t nelems, short *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_get_int_short(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } #if INT_USE_IEG int ncx_getn_int_int(const void **xpp, size_t nelems, int *tp) { if(nelems > 0) { const int bo = bitoff(*xpp); const word *wp = *xpp; int ierr; *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_INT); ierr = IEG2CRAY(&Cray2_I32, &nelems, wp, &bo, tp, &UnitStride); assert(ierr >= 0); if(ierr > 0) return NC_ERANGE; } return NC_NOERR; } #else int ncx_getn_int_int(const void **xpp, size_t nelems, int *tp) { const int bo = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(bo != 0) { cget_int_int(*xpp, tp, bo); *xpp = ((char *) (*xpp) + X_SIZEOF_INT); nelems--; if(nelems == 0) return NC_NOERR; tp++; } assert(byteoff(*xpp) == 0); { const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word); const word *wp = *xpp; const word *const end = &wp[nwords]; #pragma _CRI ivdep for( ; wp < end; wp++, tp += 2) { cget_int_int(wp, tp, 0); cget_int_int(wp, tp + 1, 1); } *xpp = ((char *) (*xpp) + nwords * sizeof(word)); nelems -= (nwords * sizeof(word)/X_SIZEOF_INT); if(nelems != 0) { cget_int_int(wp, tp, 0); *xpp = ((char *) (*xpp) + X_SIZEOF_INT); } } return NC_NOERR; } #endif int ncx_getn_int_long(const void **xpp, size_t nelems, long *tp) { const int bo = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(bo != 0) { cget_int_long(*xpp, tp, bo); *xpp = ((char *) (*xpp) + X_SIZEOF_INT); nelems--; if(nelems == 0) return NC_NOERR; tp++; } assert(byteoff(*xpp) == 0); { const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word); const word *wp = *xpp; const word *const end = &wp[nwords]; #pragma _CRI ivdep for( ; wp < end; wp++, tp += 2) { cget_int_long(wp, tp, 0); cget_int_long(wp, tp + 1, 1); } *xpp = ((char *) (*xpp) + nwords * sizeof(word)); nelems -= (nwords * sizeof(word)/X_SIZEOF_INT); if(nelems != 0) { cget_int_long(wp, tp, 0); *xpp = ((char *) (*xpp) + X_SIZEOF_INT); } } return NC_NOERR; } int ncx_getn_int_float(const void **xpp, size_t nelems, float *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_get_int_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_int_double(const void **xpp, size_t nelems, double *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_get_int_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_putn_int_schar(void **xpp, size_t nelems, const schar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_put_int_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_int_uchar(void **xpp, size_t nelems, const uchar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_put_int_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_int_short(void **xpp, size_t nelems, const short *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_put_int_short(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } #if INT_USE_IEG int ncx_putn_int_int(void **xpp, size_t nelems, const int *tp) { if(nelems > 0) { word *wp = *xpp; const int bo = bitoff(*xpp); int ierr; *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_INT); ierr = CRAY2IEG(&Cray2_I32, &nelems, wp, &bo, tp, &UnitStride); assert(ierr >= 0); if(ierr > 0) return NC_ERANGE; } return NC_NOERR; } #else int ncx_putn_int_int(void **xpp, size_t nelems, const int *tp) { int status = NC_NOERR; const int bo = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(bo != 0) { status = cput_int_int(*xpp, tp, bo); *xpp = ((char *) (*xpp) + X_SIZEOF_INT); nelems--; if(nelems == 0) return status; tp++; } assert(byteoff(*xpp) == 0); { const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word); word *wp = *xpp; const word *const end = &wp[nwords]; #pragma _CRI ivdep for( ; wp < end; wp++, tp += 2) { int lstatus = cput_int_int(wp, tp, 0); if(lstatus != NC_NOERR) status = lstatus; lstatus = cput_int_int(wp, tp + 1, 1); if(lstatus != NC_NOERR) status = lstatus; } *xpp = ((char *) (*xpp) + nwords * sizeof(word)); nelems -= (nwords * sizeof(word)/X_SIZEOF_INT); if(nelems != 0) { const int lstatus = cput_int_int(wp, tp, 0); if(lstatus != NC_NOERR) status = lstatus; *xpp = ((char *) (*xpp) + X_SIZEOF_INT); } } return status; } #endif int ncx_putn_int_long(void **xpp, size_t nelems, const long *tp) { int status = NC_NOERR; const int bo = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(bo != 0) { status = cput_int_long(*xpp, tp, bo); *xpp = ((char *) (*xpp) + X_SIZEOF_INT); nelems--; if(nelems == 0) return status; tp++; } assert(byteoff(*xpp) == 0); { const int nwords = (nelems * X_SIZEOF_INT)/sizeof(word); word *wp = *xpp; const word *const end = &wp[nwords]; #pragma _CRI ivdep for( ; wp < end; wp++, tp += 2) { int lstatus = cput_int_long(wp, tp, 0); if(lstatus != NC_NOERR) status = lstatus; lstatus = cput_int_long(wp, tp + 1, 1); if(lstatus != NC_NOERR) status = lstatus; } *xpp = ((char *) (*xpp) + nwords * sizeof(word)); nelems -= (nwords * sizeof(word)/X_SIZEOF_INT); if(nelems != 0) { const int lstatus = cput_int_long(wp, tp, 0); if(lstatus != NC_NOERR) status = lstatus; *xpp = ((char *) (*xpp) + X_SIZEOF_INT); } } return status; } int ncx_putn_int_float(void **xpp, size_t nelems, const float *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_put_int_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_int_double(void **xpp, size_t nelems, const double *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_INT, tp++) { const int lstatus = ncx_put_int_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } /* float */ int ncx_getn_float_schar(const void **xpp, size_t nelems, schar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_get_float_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_float_uchar(const void **xpp, size_t nelems, uchar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_get_float_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_float_short(const void **xpp, size_t nelems, short *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_get_float_short(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_float_int(const void **xpp, size_t nelems, int *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_get_float_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_float_long(const void **xpp, size_t nelems, long *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_get_float_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } #if FLOAT_USE_IEG int ncx_getn_float_float(const void **xpp, size_t nelems, float *tp) { if(nelems > 0) { const int bo = bitoff(*xpp); const word *wp = *xpp; int ierr; *xpp = ((const char *) (*xpp) + nelems * X_SIZEOF_FLOAT); ierr = IEG2CRAY(&Cray2_F32, &nelems, wp, &bo, tp, &UnitStride); assert(ierr >= 0); if(ierr > 0) return NC_ERANGE; } return NC_NOERR; } #else int ncx_getn_float_float(const void **xpp, size_t nelems, float *tp) { const int bo = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(bo != 0) { cget_float_float(*xpp, tp, bo); *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT); nelems--; if(nelems == 0) return NC_NOERR; tp++; } assert(byteoff(*xpp) == 0); { const int nwords = (nelems * X_SIZEOF_FLOAT)/sizeof(word); const word *wp = *xpp; const word *const end = &wp[nwords]; #pragma _CRI ivdep for( ; wp < end; wp++, tp += 2) { cget_float_float(wp, tp, 0); cget_float_float(wp, tp + 1, 1); } *xpp = ((char *) (*xpp) + nwords * sizeof(word)); nelems -= (nwords * sizeof(word)/X_SIZEOF_FLOAT); if(nelems != 0) { cget_float_float(wp, tp, 0); *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT); } } return NC_NOERR; } #endif int ncx_getn_float_double(const void **xpp, size_t nelems, double *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_get_float_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_putn_float_schar(void **xpp, size_t nelems, const schar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_put_float_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_float_uchar(void **xpp, size_t nelems, const uchar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_put_float_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_float_short(void **xpp, size_t nelems, const short *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_put_float_short(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_float_int(void **xpp, size_t nelems, const int *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_put_float_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_float_long(void **xpp, size_t nelems, const long *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_put_float_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } #if FLOAT_USE_IEG int ncx_putn_float_float(void **xpp, size_t nelems, const float *tp) { if(nelems > 0) { word *wp = *xpp; const int bo = bitoff(*xpp); int ierr; *xpp = ((char *) (*xpp) + nelems * X_SIZEOF_FLOAT); ierr = CRAY2IEG(&Cray2_F32, &nelems, wp, &bo, tp, &UnitStride); assert(ierr >= 0); if(ierr > 0) return NC_ERANGE; } return NC_NOERR; } #else int ncx_putn_float_float(void **xpp, size_t nelems, const float *tp) { int status = NC_NOERR; const int bo = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(bo != 0) { status = cput_float_float(*xpp, tp, bo); *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT); nelems--; if(nelems == 0) return status; tp++; } assert(byteoff(*xpp) == 0); { const int nwords = (nelems * X_SIZEOF_FLOAT)/sizeof(word); word *wp = *xpp; const word *const end = &wp[nwords]; #pragma _CRI ivdep for( ; wp < end; wp++, tp += 2) { int lstatus = cput_float_float(wp, tp, 0); if(lstatus != NC_NOERR) status = lstatus; lstatus = cput_float_float(wp, tp + 1, 1); if(lstatus != NC_NOERR) status = lstatus; } *xpp = ((char *) (*xpp) + nwords * sizeof(word)); nelems -= (nwords * sizeof(word)/X_SIZEOF_FLOAT); if(nelems != 0) { const int lstatus = cput_float_float(wp, tp, 0); if(lstatus != NC_NOERR) status = lstatus; *xpp = ((char *) (*xpp) + X_SIZEOF_FLOAT); } } return status; } #endif int ncx_putn_float_double(void **xpp, size_t nelems, const double *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++) { const int lstatus = ncx_put_float_double(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } /* double */ int ncx_getn_double_schar(const void **xpp, size_t nelems, schar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_get_double_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_double_uchar(const void **xpp, size_t nelems, uchar *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_get_double_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_double_short(const void **xpp, size_t nelems, short *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_get_double_short(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_double_int(const void **xpp, size_t nelems, int *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_get_double_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } int ncx_getn_double_long(const void **xpp, size_t nelems, long *tp) { const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_get_double_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; } #if DOUBLE_USE_IEG int ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) { const size_t noff = byteoff(*xpp); int ierr; if(nelems == 0) return NC_NOERR; if(noff != 0) { /* (*xpp) not word aligned, forced to make a copy */ word *xbuf = (word*)malloc(nelems*sizeof(word)); if (xbuf == NULL) return NC_ENOMEM; (void) memcpy(xbuf, *xpp, nelems * X_SIZEOF_DOUBLE); ierr = IEG2CRAY(&Cray2_F64, &nelems, xbuf, &Zero, tp, &UnitStride); (void)free(xbuf); } else { ierr = IEG2CRAY(&Cray2_F64, &nelems, *xpp, &Zero, tp, &UnitStride); } *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); assert(ierr >= 0); return ierr > 0 ? NC_ERANGE : NC_NOERR; } #elif X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) int ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) { (void) memcpy(tp, *xpp, nelems * X_SIZEOF_DOUBLE); *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return NC_NOERR; } #else int ncx_getn_double_double(const void **xpp, size_t nelems, double *tp) { const size_t noff = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(noff != 0) { /* (*xpp) not word aligned, forced to make a copy */ word *xbuf = (word*)malloc(nelems*sizeof(word)); if (xbuf == NULL) { return NC_ENOMEM; } else { const word *wp = xbuf; const word *const end = &wp[nelems]; (void) memcpy( (void*)xbuf, *xpp, nelems * X_SIZEOF_DOUBLE); #pragma _CRI ivdep for( ; wp < end; wp++, tp++) { cget_double_double(wp, tp); } (void)free(xbuf); } } else { const word *wp = *xpp; const word *const end = &wp[nelems]; #pragma _CRI ivdep for( ; wp < end; wp++, tp++) { cget_double_double(wp, tp); } } *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return NC_NOERR; } #endif int ncx_getn_double_float(const void **xpp, size_t nelems, float *tp) { #if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG return ncx_getn_double_double(xpp, nelems, (double *)tp); #else const char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_get_double_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (const void *)xp; return status; #endif } int ncx_putn_double_schar(void **xpp, size_t nelems, const schar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_put_double_schar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_double_uchar(void **xpp, size_t nelems, const uchar *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_put_double_uchar(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_double_short(void **xpp, size_t nelems, const short *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_put_double_short(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_double_int(void **xpp, size_t nelems, const int *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_put_double_int(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } int ncx_putn_double_long(void **xpp, size_t nelems, const long *tp) { char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_put_double_long(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; } #if DOUBLE_USE_IEG int ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) { const size_t noff = byteoff(*xpp); int ierr; if(nelems == 0) return NC_NOERR; if(noff != 0) { /* (*xpp) not word aligned, forced to make a copy */ word *xbuf = (word*)malloc(nelems*sizeof(word)); if (xbuf == NULL) return NC_ENOMEM; ierr = CRAY2IEG(&Cray2_F64, &nelems, xbuf, &Zero, tp, &UnitStride); assert(ierr >= 0); (void) memcpy(*xpp, xbuf, nelems * X_SIZEOF_DOUBLE); (void)free(xbuf); } else { ierr = CRAY2IEG(&Cray2_F64, &nelems, *xpp, &Zero, tp, &UnitStride); assert(ierr >= 0); } *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return ierr > 0 ? NC_ERANGE : NC_NOERR; } #elif X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT) int ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) { const size_t noff = byteoff(*xpp); (void) memcpy(*xpp, tp, nelems * X_SIZEOF_DOUBLE); *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return NC_NOERR; } #else int ncx_putn_double_double(void **xpp, size_t nelems, const double *tp) { int status = NC_NOERR; const size_t noff = byteoff(*xpp); if(nelems == 0) return NC_NOERR; if(noff != 0) { /* (*xpp) not word aligned, forced to make a copy */ word *xbuf = (word*)malloc(nelems*sizeof(word)); if (xbuf == NULL) { return NC_ENOMEM; } else { word *wp = xbuf; const word *const end = &wp[nelems]; #pragma _CRI ivdep for( ; wp < end; wp++, tp++) { const int lstatus = cput_double_double(wp, tp); if(lstatus != NC_NOERR) status = lstatus; } (void) memcpy( *xpp, (void*)xbuf, nelems * X_SIZEOF_DOUBLE); (void)free(xbuf); } } else { word *wp = *xpp; const word *const end = &wp[nelems]; #pragma _CRI ivdep for( ; wp < end; wp++, tp++) { const int lstatus = cput_double_double(wp, tp); if(lstatus != NC_NOERR) status = lstatus; } } *xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE); return status; } #endif int ncx_putn_double_float(void **xpp, size_t nelems, const float *tp) { #if SIZEOF_FLOAT == SIZEOF_DOUBLE && FLT_MANT_DIG == DBL_MANT_DIG return ncx_putn_double_double(xpp, nelems, (double *)tp); #else char *xp = *xpp; int status = NC_NOERR; for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++) { const int lstatus = ncx_put_double_float(xp, tp); if(lstatus != NC_NOERR) status = lstatus; } *xpp = (void *)xp; return status; #endif } /* * Other aggregate conversion functions. */ /* text */ int ncx_getn_text(const void **xpp, size_t nelems, char *tp) { (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems + rndup); return NC_NOERR; } int ncx_putn_text(void **xpp, size_t nelems, const char *tp) { (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); if(rndup) { (void) memcpy(*xpp, nada, rndup); *xpp = (void *)((char *)(*xpp) + rndup); } return NC_NOERR; } /* opaque */ int ncx_getn_void(const void **xpp, size_t nelems, void *tp) { (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(tp, *xpp, nelems); *xpp = (void *)((char *)(*xpp) + nelems + rndup); return NC_NOERR; } int ncx_putn_void(void **xpp, size_t nelems, const void *tp) { (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); return NC_NOERR; } int ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp) { size_t rndup = nelems % X_ALIGN; if(rndup) rndup = X_ALIGN - rndup; (void) memcpy(*xpp, tp, nelems); *xpp = (void *)((char *)(*xpp) + nelems); if(rndup) { (void) memcpy(*xpp, nada, rndup); *xpp = (void *)((char *)(*xpp) + rndup); } return NC_NOERR; }