mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
3377 lines
75 KiB
Plaintext
3377 lines
75 KiB
Plaintext
dnl
|
|
dnl sjl: this version of ncx.m4 has SX-specific optimisations as per
|
|
dnl Harveys mods to earlier versions. However, I have removed
|
|
dnl support for FLOAT2 and attempted to tidy up the mods to
|
|
dnl reduce the complexity a bit
|
|
dnl
|
|
dnl This is m4 source.
|
|
dnl Process using m4 to produce 'C' language file.
|
|
dnl
|
|
dnl If you see this line, you can ignore the next one.
|
|
/* Do not edit this file. It is produced from the corresponding .m4 source */
|
|
dnl
|
|
/*
|
|
* Copyright 1996, University Corporation for Atmospheric Research
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*
|
|
* This file contains some routines derived from code
|
|
* which is copyrighted by Sun Microsystems, Inc.
|
|
* The "#ifdef vax" versions of
|
|
* ncx_put_float_float()
|
|
* ncx_get_float_float()
|
|
* ncx_put_double_double()
|
|
* ncx_get_double_double()
|
|
* ncx_putn_float_float()
|
|
* ncx_getn_float_float()
|
|
* ncx_putn_double_double()
|
|
* ncx_getn_double_double()
|
|
* are derived from xdr_float() and xdr_double() routines
|
|
* in the freely available, copyrighted Sun RPCSRC 3.9
|
|
* distribution, xdr_float.c.
|
|
* Our "value added" is that these are always memory to memory,
|
|
* they handle IEEE subnormals properly, and their "n" versions
|
|
* operate speedily on arrays.
|
|
*/
|
|
/* $Id: ncx.m4 2795 2014-10-27 23:12:51Z wkliao $ */
|
|
|
|
/*
|
|
* An external data representation interface.
|
|
*/
|
|
|
|
#pragma GCC diagnostic ignored "-Wdeprecated"
|
|
|
|
#include "ncx.h"
|
|
#include "nc3dispatch.h"
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
|
|
/* alias poorly named limits.h macros */
|
|
#define SHORT_MAX SHRT_MAX
|
|
#define SHORT_MIN SHRT_MIN
|
|
#define USHORT_MAX USHRT_MAX
|
|
#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_USHORT
|
|
#define SIZEOF_USHORT SIZEOF_UNSIGNED_SHORT_INT
|
|
#endif
|
|
#ifndef SIZEOF_UINT
|
|
#define SIZEOF_UINT SIZEOF_UNSIGNED_INT
|
|
#endif
|
|
#ifndef SIZEOF_ULONG_LONG
|
|
#define SIZEOF_ULONG_LONG SIZEOF_UNSIGNED_LONG_LONG
|
|
#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 _SX /* 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 */
|
|
|
|
static const char nada[X_ALIGN] = {0, 0, 0, 0};
|
|
|
|
#ifndef WORDS_BIGENDIAN
|
|
/* LITTLE_ENDIAN: DEC and intel */
|
|
/*
|
|
* Routines to convert to BIGENDIAN.
|
|
* Optimize the swapn?b() and swap?b() routines aggressivly.
|
|
*/
|
|
|
|
#define SWAP2(a) ( (((a) & 0xff) << 8) | \
|
|
(((a) >> 8) & 0xff) )
|
|
|
|
#define SWAP4(a) ( ((a) << 24) | \
|
|
(((a) << 8) & 0x00ff0000) | \
|
|
(((a) >> 8) & 0x0000ff00) | \
|
|
(((a) >> 24) & 0x000000ff) )
|
|
|
|
|
|
static void
|
|
swapn2b(void *dst, const void *src, size_t nn)
|
|
{
|
|
char *op = dst;
|
|
const char *ip = src;
|
|
|
|
/* unroll the following to reduce loop overhead
|
|
*
|
|
* while(nn-- != 0)
|
|
* {
|
|
* *op++ = *(++ip);
|
|
* *op++ = *(ip++ -1);
|
|
* }
|
|
*/
|
|
while(nn > 3)
|
|
{
|
|
*op++ = *(++ip);
|
|
*op++ = *(ip++ -1);
|
|
*op++ = *(++ip);
|
|
*op++ = *(ip++ -1);
|
|
*op++ = *(++ip);
|
|
*op++ = *(ip++ -1);
|
|
*op++ = *(++ip);
|
|
*op++ = *(ip++ -1);
|
|
nn -= 4;
|
|
}
|
|
while(nn-- > 0)
|
|
{
|
|
*op++ = *(++ip);
|
|
*op++ = *(ip++ -1);
|
|
}
|
|
}
|
|
|
|
# ifndef vax
|
|
void
|
|
swap4b(void *dst, const void *src)
|
|
{
|
|
unsigned int *op = dst;
|
|
const char *ip = src;
|
|
unsigned int tempIn;
|
|
unsigned int tempOut;
|
|
|
|
tempIn = *(unsigned int *)(ip+0);
|
|
tempOut =
|
|
( tempIn << 24) |
|
|
((tempIn & 0x0000ff00) << 8) |
|
|
((tempIn & 0x00ff0000) >> 8) |
|
|
( tempIn >> 24);
|
|
|
|
*(float *)op = *(float *)(&tempOut);
|
|
}
|
|
# endif /* !vax */
|
|
|
|
static void
|
|
swapn4b(void *dst, const void *src, size_t nn)
|
|
{
|
|
char *op = dst;
|
|
const char *ip = src;
|
|
|
|
/* unroll the following to reduce loop overhead
|
|
* while(nn-- != 0)
|
|
* {
|
|
* op[0] = ip[3];
|
|
* op[1] = ip[2];
|
|
* op[2] = ip[1];
|
|
* op[3] = ip[0];
|
|
* op += 4;
|
|
* ip += 4;
|
|
* }
|
|
*/
|
|
while(nn > 3)
|
|
{
|
|
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[11];
|
|
op[9] = ip[10];
|
|
op[10] = ip[9];
|
|
op[11] = ip[8];
|
|
op[12] = ip[15];
|
|
op[13] = ip[14];
|
|
op[14] = ip[13];
|
|
op[15] = ip[12];
|
|
op += 16;
|
|
ip += 16;
|
|
nn -= 4;
|
|
}
|
|
while(nn-- > 0)
|
|
{
|
|
op[0] = ip[3];
|
|
op[1] = ip[2];
|
|
op[2] = ip[1];
|
|
op[3] = ip[0];
|
|
op += 4;
|
|
ip += 4;
|
|
}
|
|
}
|
|
|
|
# ifndef vax
|
|
static void
|
|
swap8b(void *dst, const void *src)
|
|
{
|
|
char *op = dst;
|
|
const char *ip = src;
|
|
# ifndef FLOAT_WORDS_BIGENDIAN
|
|
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];
|
|
# else
|
|
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];
|
|
# endif
|
|
}
|
|
# endif /* !vax */
|
|
|
|
# ifndef vax
|
|
static void
|
|
swapn8b(void *dst, const void *src, size_t nn)
|
|
{
|
|
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 /* !vax */
|
|
|
|
#endif /* LITTLE_ENDIAN */
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl Upcase(str)
|
|
dnl
|
|
define(`Upcase',dnl
|
|
`dnl
|
|
translit($1, abcdefghijklmnopqrstuvwxyz, ABCDEFGHIJKLMNOPQRSTUVWXYZ)')dnl
|
|
dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
define(`Isizeof', ``SIZEOF_'Upcase($1)')dnl
|
|
define(`Xsizeof', ``X_SIZEOF_'Upcase($1)')dnl
|
|
define(`IXsizeof', ``SIZEOF_IX_'Upcase($1)')dnl
|
|
define(`Imax', `Upcase($1)`_MAX'')dnl
|
|
define(`Imin', `Upcase($1)`_MIN'')dnl
|
|
define(`Xmax', ``X_'Upcase($1)`_MAX'')dnl
|
|
define(`Xmin', ``X_'Upcase($1)`_MIN'')dnl
|
|
define(`IXmax', ``IX_'Upcase($1)`_MAX'')dnl
|
|
dnl
|
|
define(`Fmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Imin($1)')')dnl
|
|
define(`Dmin', `ifelse(index(`$1',`u'), 0, `0', `Imin($1)')')dnl
|
|
define(`FXmin', `ifelse(index(`$1',`u'), 0, `0', `(double)Xmin($1)')')dnl
|
|
define(`DXmin', `ifelse(index(`$1',`u'), 0, `0', `Xmin($1)')')dnl
|
|
|
|
dnl
|
|
dnl For GET APIs:
|
|
dnl check for negative xx if xp is signed && ip is unsigned
|
|
dnl Don't check for negative xx if xp is signed && ip is signed
|
|
dnl Don't check for negative xx if xp is unsigned
|
|
dnl
|
|
define(`GETI_CheckNeg', `ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, ` if (xx < 0) return NC_ERANGE; /* because ip is unsigned */')')')dnl
|
|
|
|
dnl
|
|
dnl For PUT APIs:
|
|
dnl check for negative ip if xp is unsigned && ip is signed
|
|
dnl Don't check for negative ip if xp is unsigned && ip is unsigned
|
|
dnl Don't check for negative ip if xp is signed
|
|
dnl
|
|
define(`PUTI_CheckNeg', `ifelse(index(`$1',`u'), 0, `ifelse(index(`$2',`u'), 0, , ` if (*ip < 0) return NC_ERANGE; /* because xp is unsigned */')')')dnl
|
|
|
|
dnl
|
|
dnl For GET APIs and either $1 and $2 is float or double:
|
|
dnl
|
|
define(`GETF_CheckBND',
|
|
`ifelse(`$1', `double', ` if(xx > Upcase($2)_MAX || xx < Dmin($2)) return NC_ERANGE;',
|
|
`ifelse(`$1', `float', `ifelse(`$2', `double',,` if(xx > (double)Upcase($2)_MAX || xx < Fmin($2)) return NC_ERANGE;')')'dnl
|
|
)')
|
|
|
|
dnl
|
|
dnl For PUT APIs and either $1 and $2 is float or double:
|
|
dnl
|
|
define(`PUTF_CheckBND',
|
|
`ifelse(`$2', `double', ` if(*ip > Xmax($1) || *ip < DXmin($1)) return NC_ERANGE;',
|
|
`ifelse(`$2', `float', ` if(*ip > (double)Xmax($1) || *ip < FXmin($1)) return NC_ERANGE;')'dnl
|
|
)')
|
|
|
|
dnl
|
|
dnl For GET APIs and $1 and $2 are not float or double
|
|
dnl
|
|
define(`GETI_CheckBND',
|
|
``#'if IXmax($1) > Imax($2)
|
|
if (xx > Imax($2)'`ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, , ` || xx < Imin($2)')')'`) return NC_ERANGE;'
|
|
`#'endif)
|
|
|
|
dnl
|
|
dnl For PUT APIs and $1 and $2 are not float or double
|
|
dnl
|
|
define(`PUTI_CheckBND',
|
|
``#'if IXmax($1) < Imax($2)
|
|
if (*ip > IXmax($1)'`ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, , ` || *ip < Xmin($1)')')'`) return NC_ERANGE;'
|
|
`#'endif)
|
|
|
|
/*
|
|
* Primitive numeric conversion functions.
|
|
*/
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_GET1F(xtype, itype) for floating-point types
|
|
dnl
|
|
define(`NCX_GET1F',dnl
|
|
`dnl
|
|
int
|
|
ncx_get_$1_$2(const void *xp, $2 *ip)
|
|
{
|
|
ix_$1 xx;
|
|
get_ix_$1(xp, &xx);
|
|
*ip = ($2) xx;
|
|
GETF_CheckBND($1, $2)
|
|
return ENOERR;
|
|
}
|
|
')dnl
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_GET1I(xtype, itype, isComptable) for integral types
|
|
dnl
|
|
define(`NCX_GET1I',dnl
|
|
`dnl
|
|
int
|
|
ncx_get_$1_$2(const void *xp, $2 *ip)
|
|
{
|
|
ifelse(`$3', `1',
|
|
``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX
|
|
get_ix_$1(xp, (ix_$1 *)ip);
|
|
return ENOERR;
|
|
`#'else
|
|
')dnl
|
|
ix_$1 xx;
|
|
get_ix_$1(xp, &xx);
|
|
*ip = ($2) xx;
|
|
GETI_CheckBND($1, $2)
|
|
GETI_CheckNeg($1, $2)
|
|
ifelse(`$3', `1', ``#'endif
|
|
')dnl
|
|
return ENOERR;
|
|
}
|
|
')dnl
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PUT1F(xtype, itype) for floating-point types
|
|
dnl
|
|
define(`NCX_PUT1F',dnl
|
|
`dnl
|
|
int
|
|
ncx_put_$1_$2(void *xp, const $2 *ip)
|
|
{
|
|
ix_$1 xx = (ix_$1)*ip;
|
|
put_ix_$1(xp, &xx);
|
|
PUTF_CheckBND($1, $2)
|
|
return ENOERR;
|
|
}
|
|
')dnl
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PUT1I(xtype, itype, isComptable) for integral types
|
|
dnl
|
|
define(`NCX_PUT1I',dnl
|
|
`dnl
|
|
int
|
|
ncx_put_$1_$2(void *xp, const $2 *ip)
|
|
{
|
|
ifelse(`$3', `1',
|
|
``#'if IXsizeof($1) == Isizeof($2) && IXmax($1) == Upcase($2)_MAX
|
|
put_ix_$1(xp, (const ix_$1 *)ip);
|
|
return ENOERR;
|
|
`#'else
|
|
')dnl
|
|
ix_$1 xx = (ix_$1)*ip;
|
|
put_ix_$1(xp, &xx);
|
|
PUTI_CheckBND($1, $2)
|
|
PUTI_CheckNeg($1, $2)
|
|
ifelse(`$3', `1', ``#'endif
|
|
')dnl
|
|
return ENOERR;
|
|
}
|
|
')dnl
|
|
|
|
/* x_schar */
|
|
/* x_uchar */
|
|
|
|
/* We don't implement any x_schar and x_uchar primitives. */
|
|
|
|
|
|
/* x_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_LONG_LONG
|
|
#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 = *cp++ << 8;
|
|
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
|
|
if(*ip & 0x8000)
|
|
{
|
|
/* extern is negative */
|
|
*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
|
|
}
|
|
#endif
|
|
*ip |= *cp;
|
|
}
|
|
|
|
static void
|
|
put_ix_short(void *xp, const ix_short *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
*cp++ = (*ip) >> 8;
|
|
*cp = (*ip) & 0xff;
|
|
}
|
|
|
|
static NCX_GET1I(short, schar, 0)
|
|
static NCX_GET1I(short, short, 1)
|
|
static NCX_GET1I(short, int, 1)
|
|
static NCX_GET1I(short, longlong, 1)
|
|
static NCX_GET1I(short, ushort, 0)
|
|
static NCX_GET1I(short, uchar, 0)
|
|
static NCX_GET1I(short, uint, 0)
|
|
static NCX_GET1I(short, ulonglong, 0)
|
|
static NCX_GET1F(short, float)
|
|
static NCX_GET1F(short, double)
|
|
|
|
static int
|
|
ncx_put_short_schar(void *xp, const schar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
if(*ip & 0x80)
|
|
*cp++ = 0xff;
|
|
else
|
|
*cp++ = 0;
|
|
*cp = (uchar)*ip;
|
|
return ENOERR;
|
|
}
|
|
|
|
static int
|
|
ncx_put_short_uchar(void *xp, const uchar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
*cp++ = 0;
|
|
*cp = *ip;
|
|
return ENOERR;
|
|
}
|
|
|
|
static NCX_PUT1I(short, short, 1)
|
|
static NCX_PUT1I(short, int, 1)
|
|
static NCX_PUT1I(short, longlong, 1)
|
|
static NCX_PUT1I(short, ushort, 0)
|
|
static NCX_PUT1I(short, uint, 0)
|
|
static NCX_PUT1I(short, ulonglong, 0)
|
|
static NCX_PUT1F(short, float)
|
|
static NCX_PUT1F(short, double)
|
|
|
|
/* x_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_ULONG_LONG
|
|
#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 = *cp++ << 8;
|
|
#if SIZEOF_IX_SHORT > X_SIZEOF_SHORT
|
|
if(*ip & 0x8000)
|
|
{
|
|
/* extern is negative */
|
|
*ip |= (~(0xffff)); /* N.B. Assumes "twos complement" */
|
|
}
|
|
#endif
|
|
*ip |= *cp;
|
|
}
|
|
|
|
static void
|
|
put_ix_ushort(void *xp, const ix_ushort *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
*cp++ = (*ip) >> 8;
|
|
*cp = (*ip) & 0xff;
|
|
}
|
|
|
|
static NCX_GET1I(ushort, schar, 0)
|
|
static NCX_GET1I(ushort, short, 0)
|
|
static NCX_GET1I(ushort, int, 0)
|
|
static NCX_GET1I(ushort, longlong, 0)
|
|
static NCX_GET1I(ushort, ushort, 1)
|
|
static NCX_GET1I(ushort, uchar, 1)
|
|
static NCX_GET1I(ushort, uint, 1)
|
|
static NCX_GET1I(ushort, ulonglong, 1)
|
|
static NCX_GET1F(ushort, float)
|
|
static NCX_GET1F(ushort, double)
|
|
|
|
static int
|
|
ncx_put_ushort_schar(void *xp, const schar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
if(*ip & 0x80)
|
|
*cp++ = 0xff;
|
|
else
|
|
*cp++ = 0;
|
|
*cp = (uchar)*ip;
|
|
if (*ip < 0) return NC_ERANGE;
|
|
|
|
return ENOERR;
|
|
}
|
|
|
|
static int
|
|
ncx_put_ushort_uchar(void *xp, const uchar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
*cp++ = 0;
|
|
*cp = *ip;
|
|
return ENOERR;
|
|
}
|
|
|
|
static NCX_PUT1I(ushort, short, 0)
|
|
static NCX_PUT1I(ushort, int, 0)
|
|
static NCX_PUT1I(ushort, longlong, 0)
|
|
static NCX_PUT1I(ushort, ushort, 1)
|
|
static NCX_PUT1I(ushort, uint, 1)
|
|
static NCX_PUT1I(ushort, ulonglong, 1)
|
|
static NCX_PUT1F(ushort, float)
|
|
static NCX_PUT1F(ushort, double)
|
|
|
|
/* x_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
|
|
|
|
|
|
static void
|
|
get_ix_int(const void *xp, ix_int *ip)
|
|
{
|
|
const uchar *cp = (const uchar *) xp;
|
|
|
|
*ip = *cp++ << 24;
|
|
#if SIZEOF_IX_INT > X_SIZEOF_INT
|
|
if(*ip & 0x80000000)
|
|
{
|
|
/* extern is negative */
|
|
*ip |= (~(0xffffffff)); /* N.B. Assumes "twos complement" */
|
|
}
|
|
#endif
|
|
*ip |= (*cp++ << 16);
|
|
*ip |= (*cp++ << 8);
|
|
*ip |= *cp;
|
|
}
|
|
|
|
static void
|
|
put_ix_int(void *xp, const ix_int *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
|
|
*cp++ = (*ip) >> 24;
|
|
*cp++ = ((*ip) & 0x00ff0000) >> 16;
|
|
*cp++ = ((*ip) & 0x0000ff00) >> 8;
|
|
*cp = ((*ip) & 0x000000ff);
|
|
}
|
|
|
|
static NCX_GET1I(int, schar, 0)
|
|
static NCX_GET1I(int, short, 1)
|
|
NCX_GET1I(int, int, 1)
|
|
static NCX_GET1I(int, longlong, 1)
|
|
static NCX_GET1I(int, ushort, 0)
|
|
static NCX_GET1I(int, uchar, 0)
|
|
static NCX_GET1I(int, uint, 0)
|
|
static NCX_GET1I(int, ulonglong, 0)
|
|
static NCX_GET1F(int, float)
|
|
static NCX_GET1F(int, double)
|
|
|
|
static int
|
|
ncx_put_int_schar(void *xp, const schar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
if(*ip & 0x80)
|
|
{
|
|
*cp++ = 0xff;
|
|
*cp++ = 0xff;
|
|
*cp++ = 0xff;
|
|
}
|
|
else
|
|
{
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
}
|
|
*cp = (uchar)*ip;
|
|
return ENOERR;
|
|
}
|
|
|
|
static int
|
|
ncx_put_int_uchar(void *xp, const uchar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
*cp = *ip;
|
|
return ENOERR;
|
|
}
|
|
|
|
static NCX_PUT1I(int, short, 1)
|
|
NCX_PUT1I(int, int, 1)
|
|
static NCX_PUT1I(int, longlong, 1)
|
|
static NCX_PUT1I(int, ushort, 0)
|
|
static NCX_PUT1I(int, uint, 0)
|
|
static NCX_PUT1I(int, ulonglong, 0)
|
|
static NCX_PUT1F(int, float)
|
|
static NCX_PUT1F(int, double)
|
|
|
|
|
|
/* x_uint --------------------------------------------------------------------*/
|
|
|
|
#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_uint(const void *xp, ix_uint *ip)
|
|
{
|
|
const uchar *cp = (const uchar *) xp;
|
|
|
|
*ip = *cp++ << 24;
|
|
*ip |= (*cp++ << 16);
|
|
*ip |= (*cp++ << 8);
|
|
*ip |= *cp;
|
|
}
|
|
|
|
static void
|
|
put_ix_uint(void *xp, const ix_uint *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
|
|
*cp++ = (*ip) >> 24;
|
|
*cp++ = ((*ip) & 0x00ff0000) >> 16;
|
|
*cp++ = ((*ip) & 0x0000ff00) >> 8;
|
|
*cp = ((*ip) & 0x000000ff);
|
|
}
|
|
|
|
#if X_SIZEOF_UINT != SIZEOF_UINT
|
|
static NCX_GET1I(uint, uint, 1)
|
|
#endif
|
|
|
|
static NCX_GET1I(uint, schar, 0)
|
|
static NCX_GET1I(uint, short, 0)
|
|
static NCX_GET1I(uint, int, 0)
|
|
static NCX_GET1I(uint, longlong, 0)
|
|
static NCX_GET1I(uint, ushort, 1)
|
|
static NCX_GET1I(uint, uchar, 1)
|
|
static NCX_GET1I(uint, ulonglong, 1)
|
|
static NCX_GET1F(uint, float)
|
|
static NCX_GET1F(uint, double)
|
|
|
|
static int
|
|
ncx_put_uint_schar(void *xp, const schar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
*cp = (uchar)*ip;
|
|
|
|
if (*ip < 0) return NC_ERANGE;
|
|
|
|
return ENOERR;
|
|
}
|
|
|
|
static int
|
|
ncx_put_uint_uchar(void *xp, const uchar *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
*cp++ = 0x00;
|
|
*cp = *ip;
|
|
return ENOERR;
|
|
}
|
|
|
|
#if X_SIZEOF_UINT != SIZEOF_UINT
|
|
static NCX_PUT1I(uint, uint, 1)
|
|
#endif
|
|
|
|
static NCX_PUT1I(uint, short, 0)
|
|
static NCX_PUT1I(uint, int, 0)
|
|
static NCX_PUT1I(uint, longlong, 0)
|
|
static NCX_PUT1I(uint, ushort, 1)
|
|
static NCX_PUT1I(uint, ulonglong, 1)
|
|
static NCX_PUT1F(uint, float)
|
|
static NCX_PUT1F(uint, double)
|
|
|
|
/* x_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 vax
|
|
|
|
/* 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 */
|
|
};
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl GET_VAX_DFLOAT_Body(xp) (body for get_ix_float)
|
|
dnl
|
|
define(`GET_VAX_DFLOAT_Body',dnl
|
|
`dnl
|
|
struct vax_single *const vsp = (struct vax_single *) ip;
|
|
const struct ieee_single *const isp =
|
|
(const struct ieee_single *) $1;
|
|
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;
|
|
')dnl
|
|
static void
|
|
get_ix_float(const void *xp, float *ip)
|
|
{
|
|
GET_VAX_DFLOAT_Body(xp)
|
|
}
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl PUT_VAX_DFLOAT_Body(xp) (body for get_ix_float)
|
|
dnl
|
|
define(`PUT_VAX_DFLOAT_Body',dnl
|
|
`dnl
|
|
const struct vax_single *const vsp =
|
|
(const struct vax_single *)ip;
|
|
struct ieee_single *const isp = (struct ieee_single *) $1;
|
|
|
|
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;
|
|
')dnl
|
|
|
|
static void
|
|
put_ix_float(void *xp, const float *ip)
|
|
{
|
|
PUT_VAX_DFLOAT_Body(xp)
|
|
}
|
|
|
|
/* 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)
|
|
{
|
|
const 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;
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl GET_IX_FLOAT_Body (body for get_ix_float)
|
|
dnl
|
|
define(`GET_IX_FLOAT_Body',dnl
|
|
`dnl
|
|
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;
|
|
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl PUT_IX_FLOAT_Body (body for put_ix_float)
|
|
dnl
|
|
define(`PUT_IX_FLOAT_Body',dnl
|
|
`dnl
|
|
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;
|
|
}
|
|
')dnl
|
|
|
|
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;
|
|
GET_IX_FLOAT_Body
|
|
}
|
|
else
|
|
{
|
|
const ieee_single_lo *isp = (const ieee_single_lo *) xp;
|
|
GET_IX_FLOAT_Body
|
|
}
|
|
}
|
|
|
|
static void
|
|
put_ix_float(void *xp, const float *ip)
|
|
{
|
|
if(word_align(xp) == 0)
|
|
{
|
|
ieee_single_hi *isp = (ieee_single_hi*)xp;
|
|
PUT_IX_FLOAT_Body
|
|
}
|
|
else
|
|
{
|
|
ieee_single_lo *isp = (ieee_single_lo*)xp;
|
|
PUT_IX_FLOAT_Body
|
|
}
|
|
}
|
|
|
|
#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
|
|
ncx_get_float_float(const void *xp, float *ip)
|
|
{
|
|
/* TODO */
|
|
get_ix_float(xp, ip);
|
|
return ENOERR;
|
|
}
|
|
#endif
|
|
|
|
#define ix_float float
|
|
|
|
static NCX_GET1F(float, schar)
|
|
static NCX_GET1F(float, short)
|
|
static NCX_GET1F(float, int)
|
|
static NCX_GET1F(float, double)
|
|
static NCX_GET1F(float, longlong)
|
|
static NCX_GET1F(float, uchar)
|
|
static NCX_GET1F(float, ushort)
|
|
static NCX_GET1F(float, uint)
|
|
static NCX_GET1F(float, ulonglong)
|
|
|
|
#if X_SIZEOF_FLOAT != SIZEOF_FLOAT || defined(NO_IEEE_FLOAT)
|
|
static int
|
|
ncx_put_float_float(void *xp, const float *ip)
|
|
{
|
|
put_ix_float(xp, ip);
|
|
#ifdef NO_IEEE_FLOAT
|
|
if(*ip > X_FLOAT_MAX || *ip < X_FLOAT_MIN)
|
|
return NC_ERANGE;
|
|
#endif
|
|
return ENOERR;
|
|
}
|
|
#endif
|
|
|
|
static NCX_PUT1F(float, schar)
|
|
static NCX_PUT1F(float, short)
|
|
static NCX_PUT1F(float, int)
|
|
static NCX_PUT1F(float, double)
|
|
static NCX_PUT1F(float, longlong)
|
|
static NCX_PUT1F(float, uchar)
|
|
static NCX_PUT1F(float, ushort)
|
|
static NCX_PUT1F(float, uint)
|
|
static NCX_PUT1F(float, ulonglong)
|
|
|
|
|
|
/* x_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 vax
|
|
|
|
/* 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 */
|
|
};
|
|
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl GET_VAX_DDOUBLE_Body(xp) (body for get_ix_double)
|
|
dnl
|
|
define(`GET_VAX_DDOUBLE_Body',dnl
|
|
`dnl
|
|
struct vax_double *const vdp =
|
|
(struct vax_double *)ip;
|
|
const struct ieee_double *const idp =
|
|
(const struct ieee_double *) $1;
|
|
{
|
|
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;
|
|
')dnl
|
|
static void
|
|
get_ix_double(const void *xp, double *ip)
|
|
{
|
|
GET_VAX_DDOUBLE_Body(xp)
|
|
}
|
|
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl PUT_VAX_DDOUBLE_Body(xp) (body for put_ix_double)
|
|
dnl
|
|
define(`PUT_VAX_DDOUBLE_Body',dnl
|
|
`dnl
|
|
const struct vax_double *const vdp =
|
|
(const struct vax_double *)ip;
|
|
struct ieee_double *const idp =
|
|
(struct ieee_double *) $1;
|
|
|
|
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;
|
|
')dnl
|
|
static void
|
|
put_ix_double(void *xp, const double *ip)
|
|
{
|
|
PUT_VAX_DDOUBLE_Body(xp)
|
|
}
|
|
|
|
/* 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 NCX_GET1F(double, schar)
|
|
static NCX_GET1F(double, short)
|
|
static NCX_GET1F(double, int)
|
|
static NCX_GET1F(double, longlong)
|
|
static NCX_GET1F(double, uchar)
|
|
static NCX_GET1F(double, ushort)
|
|
static NCX_GET1F(double, uint)
|
|
|
|
int
|
|
ncx_get_double_ulonglong(const void *xp, unsigned long long *ip)
|
|
{
|
|
double xx;
|
|
get_ix_double(xp, &xx);
|
|
*ip = (unsigned long long) xx;
|
|
if(xx > ULONG_LONG_MAX || xx < 0)
|
|
return NC_ERANGE;
|
|
return ENOERR;
|
|
}
|
|
|
|
static int
|
|
ncx_get_double_float(const void *xp, float *ip)
|
|
{
|
|
double xx;
|
|
get_ix_double(xp, &xx);
|
|
if(xx > FLT_MAX)
|
|
{
|
|
*ip = FLT_MAX;
|
|
return NC_ERANGE;
|
|
}
|
|
if(xx < (-FLT_MAX))
|
|
{
|
|
*ip = (-FLT_MAX);
|
|
return NC_ERANGE;
|
|
}
|
|
*ip = (float) xx;
|
|
return ENOERR;
|
|
}
|
|
|
|
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT)
|
|
static int
|
|
ncx_get_double_double(const void *xp, double *ip)
|
|
{
|
|
/* TODO */
|
|
get_ix_double(xp, ip);
|
|
return ENOERR;
|
|
}
|
|
#endif
|
|
|
|
static NCX_PUT1F(double, schar)
|
|
static NCX_PUT1F(double, uchar)
|
|
static NCX_PUT1F(double, short)
|
|
static NCX_PUT1F(double, ushort)
|
|
static NCX_PUT1F(double, int)
|
|
static NCX_PUT1F(double, uint)
|
|
static NCX_PUT1F(double, longlong)
|
|
static NCX_PUT1F(double, ulonglong)
|
|
|
|
static int
|
|
ncx_put_double_float(void *xp, const float *ip)
|
|
{
|
|
double xx = (double) *ip;
|
|
put_ix_double(xp, &xx);
|
|
#if 1 /* TODO: figure this out */
|
|
if((double)(*ip) > X_DOUBLE_MAX || (double)(*ip) < X_DOUBLE_MIN)
|
|
return NC_ERANGE;
|
|
#endif
|
|
return ENOERR;
|
|
}
|
|
|
|
#if X_SIZEOF_DOUBLE != SIZEOF_DOUBLE || defined(NO_IEEE_FLOAT)
|
|
static int
|
|
ncx_put_double_double(void *xp, const double *ip)
|
|
{
|
|
put_ix_double(xp, ip);
|
|
#ifdef NO_IEEE_FLOAT
|
|
if(*ip > X_DOUBLE_MAX || *ip < X_DOUBLE_MIN)
|
|
return NC_ERANGE;
|
|
#endif
|
|
return ENOERR;
|
|
}
|
|
#endif
|
|
|
|
|
|
/* x_longlong ---------------------------------------------------------------------*/
|
|
|
|
#if SHORT_MAX == X_LONGLONG_MAX
|
|
typedef short ix_longlong;
|
|
#define SIZEOF_IX_LONGLONG SIZEOF_SHORT
|
|
#define IX_LONGLONG_MAX SHORT_MAX
|
|
#elif LONG_LONG_MAX >= X_LONGLONG_MAX
|
|
typedef longlong ix_longlong;
|
|
#define SIZEOF_IX_LONGLONG SIZEOF_LONGLONG
|
|
#define IX_LONGLONG_MAX LONG_LONG_MAX
|
|
#elif LONG_MAX >= X_LONGLONG_MAX
|
|
typedef long ix_longlong;
|
|
#define SIZEOF_IX_LONGLONG SIZEOF_LONG
|
|
#define IX_LONGLONG_MAX LONG_MAX
|
|
#else
|
|
#error "ix_longlong implementation"
|
|
#endif
|
|
|
|
|
|
static void
|
|
get_ix_longlong(const void *xp, ix_longlong *ip)
|
|
{
|
|
const uchar *cp = (const uchar *) xp;
|
|
|
|
*ip = ((long long)(*cp++) << 56);
|
|
*ip |= ((long long)(*cp++) << 48);
|
|
*ip |= ((long long)(*cp++) << 40);
|
|
*ip |= ((long long)(*cp++) << 32);
|
|
*ip |= ((long long)(*cp++) << 24);
|
|
*ip |= ((long long)(*cp++) << 16);
|
|
*ip |= ((long long)(*cp++) << 8);
|
|
*ip |= (long long)*cp;
|
|
}
|
|
|
|
static void
|
|
put_ix_longlong(void *xp, const ix_longlong *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
|
|
*cp++ = (*ip) >> 56;
|
|
*cp++ = ((*ip) & 0x00ff000000000000LL) >> 48;
|
|
*cp++ = ((*ip) & 0x0000ff0000000000LL) >> 40;
|
|
*cp++ = ((*ip) & 0x000000ff00000000LL) >> 32;
|
|
*cp++ = ((*ip) & 0x00000000ff000000LL) >> 24;
|
|
*cp++ = ((*ip) & 0x0000000000ff0000LL) >> 16;
|
|
*cp++ = ((*ip) & 0x000000000000ff00LL) >> 8;
|
|
*cp = ((*ip) & 0x00000000000000ffLL);
|
|
}
|
|
|
|
static NCX_GET1I(longlong, schar, 0)
|
|
static NCX_GET1I(longlong, short, 1)
|
|
static NCX_GET1I(longlong, int, 1)
|
|
static NCX_GET1I(longlong, longlong, 1)
|
|
static NCX_GET1I(longlong, ushort, 0)
|
|
static NCX_GET1I(longlong, uchar, 0)
|
|
static NCX_GET1I(longlong, uint, 0)
|
|
static NCX_GET1I(longlong, ulonglong, 0)
|
|
static NCX_GET1F(longlong, float)
|
|
static NCX_GET1F(longlong, double)
|
|
|
|
static NCX_PUT1I(longlong, schar, 0)
|
|
static NCX_PUT1I(longlong, short, 1)
|
|
static NCX_PUT1I(longlong, int, 1)
|
|
static NCX_PUT1I(longlong, longlong, 1)
|
|
static NCX_PUT1I(longlong, ushort, 0)
|
|
static NCX_PUT1I(longlong, uchar, 0)
|
|
static NCX_PUT1I(longlong, uint, 0)
|
|
static NCX_PUT1I(longlong, ulonglong, 0)
|
|
static NCX_PUT1F(longlong, float)
|
|
static NCX_PUT1F(longlong, double)
|
|
|
|
/* x_ulonglong --------------------------------------------------------------------*/
|
|
|
|
#if USHORT_MAX == X_ULONGLONG_MAX
|
|
typedef ushort ix_ulonglong;
|
|
#define SIZEOF_IX_ULONGLONG SIZEOF_USHORT
|
|
#define IX_ULONGLONG_MAX USHORT_MAX
|
|
#elif ULONG_LONG_MAX >= X_ULONGLONG_MAX
|
|
typedef ulonglong ix_ulonglong;
|
|
#define SIZEOF_IX_ULONGLONG SIZEOF_ULONGLONG
|
|
#define IX_ULONGLONG_MAX ULONG_LONG_MAX
|
|
#elif ULONG_MAX >= X_ULONGLONG_MAX
|
|
typedef ulong ix_ulonglong;
|
|
#define SIZEOF_IX_ULONGLONG SIZEOF_ULONG
|
|
#define IX_ULONGLONG_MAX ULONG_MAX
|
|
#else
|
|
#error "ix_ulonglong implementation"
|
|
#endif
|
|
|
|
|
|
static void
|
|
get_ix_ulonglong(const void *xp, ix_ulonglong *ip)
|
|
{
|
|
const uchar *cp = (const uchar *) xp;
|
|
|
|
*ip = ((unsigned long long)(*cp++) << 56);
|
|
*ip |= ((unsigned long long)(*cp++) << 48);
|
|
*ip |= ((unsigned long long)(*cp++) << 40);
|
|
*ip |= ((unsigned long long)(*cp++) << 32);
|
|
*ip |= ((unsigned long long)(*cp++) << 24);
|
|
*ip |= ((unsigned long long)(*cp++) << 16);
|
|
*ip |= ((unsigned long long)(*cp++) << 8);
|
|
*ip |= (unsigned long long)*cp;
|
|
}
|
|
|
|
static void
|
|
put_ix_ulonglong(void *xp, const ix_ulonglong *ip)
|
|
{
|
|
uchar *cp = (uchar *) xp;
|
|
|
|
*cp++ = (*ip) >> 56;
|
|
*cp++ = ((*ip) & 0x00ff000000000000ULL) >> 48;
|
|
*cp++ = ((*ip) & 0x0000ff0000000000ULL) >> 40;
|
|
*cp++ = ((*ip) & 0x000000ff00000000ULL) >> 32;
|
|
*cp++ = ((*ip) & 0x00000000ff000000ULL) >> 24;
|
|
*cp++ = ((*ip) & 0x0000000000ff0000ULL) >> 16;
|
|
*cp++ = ((*ip) & 0x000000000000ff00ULL) >> 8;
|
|
*cp = ((*ip) & 0x00000000000000ffULL);
|
|
}
|
|
|
|
static NCX_GET1I(ulonglong, schar, 0)
|
|
static NCX_GET1I(ulonglong, short, 0)
|
|
static NCX_GET1I(ulonglong, int, 0)
|
|
static NCX_GET1I(ulonglong, longlong, 0)
|
|
static NCX_GET1I(ulonglong, ushort, 1)
|
|
static NCX_GET1I(ulonglong, uchar, 1)
|
|
static NCX_GET1I(ulonglong, uint, 1)
|
|
static NCX_GET1I(ulonglong, ulonglong, 1)
|
|
static NCX_GET1F(ulonglong, float)
|
|
static NCX_GET1F(ulonglong, double)
|
|
|
|
static NCX_PUT1I(ulonglong, schar, 0)
|
|
static NCX_PUT1I(ulonglong, short, 0)
|
|
static NCX_PUT1I(ulonglong, int, 0)
|
|
static NCX_PUT1I(ulonglong, longlong, 0)
|
|
static NCX_PUT1I(ulonglong, uchar, 1)
|
|
static NCX_PUT1I(ulonglong, ushort, 1)
|
|
static NCX_PUT1I(ulonglong, uint, 1)
|
|
static NCX_PUT1I(ulonglong, ulonglong, 1)
|
|
static NCX_PUT1F(ulonglong, float)
|
|
static NCX_PUT1F(ulonglong, double)
|
|
|
|
/* 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
|
|
ncx_put_size_t(void **xpp, const size_t *ulp)
|
|
{
|
|
/* similar to put_ix_int() */
|
|
uchar *cp = (uchar *) *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 ENOERR;
|
|
}
|
|
|
|
int
|
|
ncx_get_size_t(const void **xpp, size_t *ulp)
|
|
{
|
|
/* similar to get_ix_int */
|
|
const uchar *cp = (const uchar *) *xpp;
|
|
|
|
*ulp = (unsigned)(*cp++ << 24);
|
|
*ulp |= (*cp++ << 16);
|
|
*ulp |= (*cp++ << 8);
|
|
*ulp |= *cp;
|
|
|
|
*xpp = (const void *)((const char *)(*xpp) + X_SIZEOF_SIZE_T);
|
|
return ENOERR;
|
|
}
|
|
|
|
/* x_off_t */
|
|
|
|
int
|
|
ncx_put_off_t(void **xpp, const off_t *lp, size_t sizeof_off_t)
|
|
{
|
|
/* similar to put_ix_int() */
|
|
uchar *cp = (uchar *) *xpp;
|
|
/* No negative offsets stored in netcdf */
|
|
if (*lp < 0) {
|
|
/* Assume this is an overflow of a 32-bit int... */
|
|
return NC_ERANGE;
|
|
}
|
|
|
|
assert(sizeof_off_t == 4 || sizeof_off_t == 8);
|
|
|
|
if (sizeof_off_t == 4) {
|
|
*cp++ = (uchar) ((*lp) >> 24);
|
|
*cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
|
|
*cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8);
|
|
*cp = (uchar)( (*lp) & 0x000000ff);
|
|
} else {
|
|
#if SIZEOF_OFF_T == 4
|
|
/* Write a 64-bit offset on a system with only a 32-bit offset */
|
|
*cp++ = (uchar)0;
|
|
*cp++ = (uchar)0;
|
|
*cp++ = (uchar)0;
|
|
*cp++ = (uchar)0;
|
|
|
|
*cp++ = (uchar)(((*lp) & 0xff000000) >> 24);
|
|
*cp++ = (uchar)(((*lp) & 0x00ff0000) >> 16);
|
|
*cp++ = (uchar)(((*lp) & 0x0000ff00) >> 8);
|
|
*cp = (uchar)( (*lp) & 0x000000ff);
|
|
#else
|
|
*cp++ = (uchar) ((*lp) >> 56);
|
|
*cp++ = (uchar)(((*lp) & 0x00ff000000000000ULL) >> 48);
|
|
*cp++ = (uchar)(((*lp) & 0x0000ff0000000000ULL) >> 40);
|
|
*cp++ = (uchar)(((*lp) & 0x000000ff00000000ULL) >> 32);
|
|
*cp++ = (uchar)(((*lp) & 0x00000000ff000000ULL) >> 24);
|
|
*cp++ = (uchar)(((*lp) & 0x0000000000ff0000ULL) >> 16);
|
|
*cp++ = (uchar)(((*lp) & 0x000000000000ff00ULL) >> 8);
|
|
*cp = (uchar)( (*lp) & 0x00000000000000ffULL);
|
|
#endif
|
|
}
|
|
*xpp = (void *)((char *)(*xpp) + sizeof_off_t);
|
|
return ENOERR;
|
|
}
|
|
|
|
int
|
|
ncx_get_off_t(const void **xpp, off_t *lp, size_t sizeof_off_t)
|
|
{
|
|
/* similar to get_ix_int() */
|
|
const uchar *cp = (const uchar *) *xpp;
|
|
assert(sizeof_off_t == 4 || sizeof_off_t == 8);
|
|
|
|
if (sizeof_off_t == 4) {
|
|
*lp = (off_t)(*cp++ << 24);
|
|
*lp |= (off_t)(*cp++ << 16);
|
|
*lp |= (off_t)(*cp++ << 8);
|
|
*lp |= (off_t)*cp;
|
|
} else {
|
|
#if SIZEOF_OFF_T == 4
|
|
/* Read a 64-bit offset on a system with only a 32-bit offset */
|
|
/* If the offset overflows, set an error code and return */
|
|
*lp = ((off_t)(*cp++) << 24);
|
|
*lp |= ((off_t)(*cp++) << 16);
|
|
*lp |= ((off_t)(*cp++) << 8);
|
|
*lp |= ((off_t)(*cp++));
|
|
/*
|
|
* lp now contains the upper 32-bits of the 64-bit offset. if lp is
|
|
* not zero, then the dataset is larger than can be represented
|
|
* on this system. Set an error code and return.
|
|
*/
|
|
if (*lp != 0) {
|
|
return NC_ERANGE;
|
|
}
|
|
|
|
*lp = ((off_t)(*cp++) << 24);
|
|
*lp |= ((off_t)(*cp++) << 16);
|
|
*lp |= ((off_t)(*cp++) << 8);
|
|
*lp |= (off_t)*cp;
|
|
|
|
if (*lp < 0) {
|
|
/*
|
|
* If this fails, then the offset is >2^31, but less
|
|
* than 2^32 which is not allowed, but is not caught
|
|
* by the previous check
|
|
*/
|
|
return NC_ERANGE;
|
|
}
|
|
#else
|
|
*lp = ((off_t)(*cp++) << 56);
|
|
*lp |= ((off_t)(*cp++) << 48);
|
|
*lp |= ((off_t)(*cp++) << 40);
|
|
*lp |= ((off_t)(*cp++) << 32);
|
|
*lp |= ((off_t)(*cp++) << 24);
|
|
*lp |= ((off_t)(*cp++) << 16);
|
|
*lp |= ((off_t)(*cp++) << 8);
|
|
*lp |= (off_t)*cp;
|
|
#endif
|
|
}
|
|
*xpp = (const void *)((const char *)(*xpp) + sizeof_off_t);
|
|
return ENOERR;
|
|
}
|
|
|
|
/*----< ncx_get_int32() >--------------------------------------------------*/
|
|
int
|
|
ncx_get_int32(const void **xpp,
|
|
int *ip)
|
|
{
|
|
const uchar *cp = (const uchar *) *xpp;
|
|
|
|
/* cannot call swap4b(), as lp is 8-byte */
|
|
*ip = (*cp++ << 24);
|
|
*ip |= (*cp++ << 16);
|
|
*ip |= (*cp++ << 8);
|
|
*ip |= *cp;
|
|
|
|
/* advance *xpp 4 bytes */
|
|
*xpp = (void *)((const char *)(*xpp) + 4);
|
|
|
|
return NC_NOERR;
|
|
}
|
|
|
|
/*----< ncx_get_int64() >-------------------------------------------------*/
|
|
int
|
|
ncx_get_int64(const void **xpp,
|
|
long long *llp)
|
|
{
|
|
const uchar *cp = (const uchar *) *xpp;
|
|
|
|
/* below is the same as calling swap8b(llp, *xpp) */
|
|
*llp = ((long long)(*cp++) << 56);
|
|
*llp |= ((long long)(*cp++) << 48);
|
|
*llp |= ((long long)(*cp++) << 40);
|
|
*llp |= ((long long)(*cp++) << 32);
|
|
*llp |= ((long long)(*cp++) << 24);
|
|
*llp |= ((long long)(*cp++) << 16);
|
|
*llp |= ((long long)(*cp++) << 8);
|
|
*llp |= (long long)*cp;
|
|
|
|
/* advance *xpp 8 bytes */
|
|
*xpp = (void *)((const char *)(*xpp) + 8);
|
|
|
|
return NC_NOERR;
|
|
}
|
|
|
|
/*---< ncx_put_int32() >-----------------------------------------------------*/
|
|
/* copy the contents of lp (a signed 32-bit integer) to xpp in Big Endian
|
|
* form and advance *xpp 4 bytes
|
|
*/
|
|
int
|
|
ncx_put_int32(void **xpp,
|
|
const int ip)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
int *ptr = (int*) (*xpp); /* typecast to 4-byte integer */
|
|
*ptr = ip;
|
|
#else
|
|
/* bitwise shifts below are to produce an integer in Big Endian */
|
|
/* cannot call swap4b(), as lp is 8-byte */
|
|
uchar *cp = (uchar *) *xpp;
|
|
*cp++ = (uchar)((ip & 0xff000000) >> 24);
|
|
*cp++ = (uchar)((ip & 0x00ff0000) >> 16);
|
|
*cp++ = (uchar)((ip & 0x0000ff00) >> 8);
|
|
*cp = (uchar)( ip & 0x000000ff);
|
|
#endif
|
|
/* advance *xpp 4 bytes */
|
|
*xpp = (void *)((char *)(*xpp) + 4);
|
|
|
|
return NC_NOERR;
|
|
}
|
|
|
|
/*---< ncx_put_int64() >-----------------------------------------------------*/
|
|
/* copy the contents of lp (a signed 64-bit integer) to xpp in Big Endian
|
|
* form and advance *xpp 8 bytes
|
|
*/
|
|
int
|
|
ncx_put_int64(void **xpp,
|
|
const long long ip)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
long long *ptr = (long long*) (*xpp); /* typecast to 8-byte integer */
|
|
*ptr = ip;
|
|
#else
|
|
uchar *cp = (uchar *) *xpp;
|
|
/* below is the same as calling swap8b(*xpp, &ip) */
|
|
*cp++ = (uchar)((ip & 0xff00000000000000ULL) >> 56);
|
|
*cp++ = (uchar)((ip & 0x00ff000000000000ULL) >> 48);
|
|
*cp++ = (uchar)((ip & 0x0000ff0000000000ULL) >> 40);
|
|
*cp++ = (uchar)((ip & 0x000000ff00000000ULL) >> 32);
|
|
*cp++ = (uchar)((ip & 0x00000000ff000000ULL) >> 24);
|
|
*cp++ = (uchar)((ip & 0x0000000000ff0000ULL) >> 16);
|
|
*cp++ = (uchar)((ip & 0x000000000000ff00ULL) >> 8);
|
|
*cp = (uchar)( ip & 0x00000000000000ffULL);
|
|
#endif
|
|
/* advance *xpp 8 bytes */
|
|
*xpp = (void *)((char *)(*xpp) + 8);
|
|
|
|
return NC_NOERR;
|
|
}
|
|
|
|
|
|
/*
|
|
* Aggregate numeric conversion functions.
|
|
*/
|
|
dnl
|
|
define(`GETN_CheckBND', `ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, `|| xp[i] < 0', `|| xp[i] < Imin($2)')')')dnl
|
|
define(`PUTN_CheckBND', `ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| tp[i] < 0', `|| tp[i] < Xmin($1)')')')dnl
|
|
|
|
dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_GETN_Byte_Body (body for one byte types on diagonal)
|
|
dnl
|
|
define(`NCX_GETN_Byte_Body',dnl
|
|
`dnl
|
|
(void) memcpy(tp, *xpp, nelems);
|
|
*xpp = (void *)((char *)(*xpp) + nelems);
|
|
return ENOERR;
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PAD_GETN_Byte_body (body for one byte types on diagonal)
|
|
dnl
|
|
define(`NCX_PAD_GETN_Byte_Body',dnl
|
|
`dnl
|
|
size_t rndup = nelems % X_ALIGN;
|
|
|
|
if(rndup)
|
|
rndup = X_ALIGN - rndup;
|
|
|
|
(void) memcpy(tp, *xpp, nelems);
|
|
*xpp = (void *)((char *)(*xpp) + nelems + rndup);
|
|
|
|
return ENOERR;
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_GETN_CHAR(Type)
|
|
dnl
|
|
define(`NCX_GETN_CHAR',dnl
|
|
`dnl
|
|
int
|
|
ncx_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp)
|
|
{
|
|
int status = ENOERR;
|
|
$1 *xp = ($1 *)(*xpp);
|
|
|
|
while(nelems-- != 0)
|
|
{
|
|
ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, ` if (*xp < 0) status = NC_ERANGE;')')
|
|
*tp++ = *xp++;
|
|
}
|
|
|
|
*xpp = (const void *)xp;
|
|
return status;
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PAD_GETN_CHAR(Type)
|
|
dnl
|
|
define(`NCX_PAD_GETN_CHAR',dnl
|
|
`dnl
|
|
int
|
|
ncx_pad_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp)
|
|
{
|
|
int status = ENOERR;
|
|
size_t rndup = nelems % X_ALIGN;
|
|
$1 *xp = ($1 *) *xpp;
|
|
|
|
if(rndup)
|
|
rndup = X_ALIGN - rndup;
|
|
|
|
while(nelems-- != 0)
|
|
{
|
|
ifelse(index(`$1',`u'), 0, , `ifelse(index(`$2',`u'), 0, ` if (*xp < 0) status = NC_ERANGE;')')
|
|
*tp++ = *xp++;
|
|
}
|
|
|
|
*xpp = (void *)(xp + rndup);
|
|
return status;
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_GETNo(XType, Type) deprecated
|
|
dnl
|
|
define(`NCX_GETNo',dnl
|
|
`dnl
|
|
int
|
|
ncx_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp)
|
|
{
|
|
const char *xp = (const char *) *xpp;
|
|
int status = ENOERR;
|
|
$1 xx;
|
|
|
|
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
|
|
{
|
|
const int lstatus = ncx_get_$1_$1(xp, &xx);
|
|
*tp = ($2)xx;
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
*xpp = (const void *)xp;
|
|
return status;
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_GETN(XType, Type, condition)
|
|
dnl
|
|
define(`NCX_GETN',dnl
|
|
`dnl
|
|
int
|
|
ncx_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp)
|
|
{
|
|
`#'if _SX && Xsizeof($1) == Isizeof($1)
|
|
|
|
/* 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;
|
|
$1 tmp[LOOPCNT]; /* in case input is misaligned */
|
|
$1 *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) % Isizeof($1);
|
|
/* 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, ni*Isizeof($1));
|
|
xp = tmp;
|
|
} else {
|
|
xp = ($1 *) *xpp;
|
|
}
|
|
/* copy the next block */
|
|
#pragma cdir loopcnt=LOOPCNT
|
|
#pragma cdir shortloop
|
|
for (i=0; i<ni; i++) {
|
|
tp[i] = ($2) Max( Imin($2), Min(Imax($2), ($2) xp[i]));
|
|
/* test for range errors (not always needed but do it anyway) */
|
|
/* if xpp is unsigned, we need not check if xp[i] < Imin */
|
|
/* if xpp is signed && tp is unsigned, we need check if xp[i] >= 0 */
|
|
nrange += xp[i] > Imax($2) GETN_CheckBND($1, $2);
|
|
}
|
|
/* update xpp and tp */
|
|
if (realign) xp = ($1 *) *xpp;
|
|
xp += ni;
|
|
tp += ni;
|
|
*xpp = (void*)xp;
|
|
}
|
|
return nrange == 0 ? ENOERR : NC_ERANGE;
|
|
|
|
#else /* not SX */
|
|
const char *xp = (const char *) *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
|
|
{
|
|
const int lstatus = ncx_get_$1_$2(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
*xpp = (const void *)xp;
|
|
return status;
|
|
# endif
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PAD_GETN_SHORT(xtype ttype)
|
|
dnl
|
|
define(`NCX_PAD_GETN_SHORT',dnl
|
|
`dnl
|
|
int
|
|
ncx_pad_getn_$1_$2(const void **xpp, size_t nelems, $2 *tp)
|
|
{
|
|
const size_t rndup = nelems % 2;
|
|
|
|
const char *xp = (const char *) *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
|
|
{
|
|
const int lstatus = ncx_get_$1_$2(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
if(rndup != 0)
|
|
xp += Xsizeof($1);
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PUTN_Byte_Body(Type) (body for one byte types)
|
|
dnl
|
|
define(`NCX_PUTN_Byte_Body',dnl
|
|
`dnl
|
|
(void) memcpy(*xpp, tp, nelems);
|
|
*xpp = (void *)((char *)(*xpp) + nelems);
|
|
|
|
return ENOERR;
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PAD_PUTN_Byte_Body(Type) (body for one byte types)
|
|
dnl
|
|
define(`NCX_PAD_PUTN_Byte_Body',dnl
|
|
size_t rndup = nelems % X_ALIGN;
|
|
|
|
if(rndup)
|
|
rndup = X_ALIGN - rndup;
|
|
|
|
(void) memcpy(*xpp, tp, nelems);
|
|
*xpp = (void *)((char *)(*xpp) + nelems);
|
|
|
|
if(rndup)
|
|
{
|
|
(void) memcpy(*xpp, nada, rndup);
|
|
*xpp = (void *)((char *)(*xpp) + rndup);
|
|
}
|
|
|
|
return ENOERR;
|
|
`dnl
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PUTN_CHAR(Type)
|
|
dnl
|
|
define(`NCX_PUTN_CHAR',dnl
|
|
`dnl
|
|
int
|
|
ncx_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp)
|
|
{
|
|
int status = ENOERR;
|
|
$1 *xp = ($1 *) *xpp;
|
|
|
|
while(nelems-- != 0)
|
|
{
|
|
if(*tp > Xmax($1) ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')'))
|
|
status = NC_ERANGE;
|
|
*xp++ = ($1) *tp++;
|
|
}
|
|
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PAD_PUTN_CHAR(xtype, ttype)
|
|
dnl
|
|
define(`NCX_PAD_PUTN_CHAR',dnl
|
|
`dnl
|
|
int
|
|
ncx_pad_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp)
|
|
{
|
|
int status = ENOERR;
|
|
size_t rndup = nelems % X_ALIGN;
|
|
$1 *xp = ($1 *) *xpp;
|
|
|
|
if(rndup)
|
|
rndup = X_ALIGN - rndup;
|
|
|
|
while(nelems-- != 0)
|
|
{
|
|
if(*tp > Xmax($1) ifelse(index(`$2',`u'), 0, , `ifelse(index(`$1',`u'), 0, `|| *tp < 0',`|| *tp < Xmin(schar)')'))
|
|
status = NC_ERANGE;
|
|
*xp++ = ($1) *tp++;
|
|
}
|
|
|
|
|
|
if(rndup)
|
|
{
|
|
(void) memcpy(xp, nada, rndup);
|
|
xp += rndup;
|
|
}
|
|
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PUTNo(XType, Type) deprecated
|
|
dnl
|
|
define(`NCX_PUTNo',dnl
|
|
`dnl
|
|
int
|
|
ncx_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp)
|
|
{
|
|
char *xp = (char *) *xpp;
|
|
int status = ENOERR;
|
|
$1 xx;
|
|
|
|
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
|
|
{
|
|
xx = ($1) *tp;
|
|
{
|
|
int lstatus = ncx_put_$1_$1(xp, &xx);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
}
|
|
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PUTN(XType, Type, condition)
|
|
dnl
|
|
define(`NCX_PUTN',dnl
|
|
`dnl
|
|
int
|
|
ncx_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp)
|
|
{
|
|
`#'if _SX && Xsizeof($1) == Isizeof($1)
|
|
|
|
/* 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;
|
|
$1 tmp[LOOPCNT]; /* in case input is misaligned */
|
|
$1 *xp;
|
|
ifelse( $1$2, intfloat,dnl
|
|
`dnl
|
|
double d; /* special case for ncx_putn_int_float */
|
|
')dnl
|
|
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) % Isizeof($1);
|
|
/* 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 = ($1 *) *xpp;
|
|
}
|
|
/* copy the next block */
|
|
#pragma cdir loopcnt=LOOPCNT
|
|
#pragma cdir shortloop
|
|
for (i=0; i<ni; i++) {
|
|
ifelse( $1$2, intfloat,dnl
|
|
`dnl
|
|
/* for some reason int to float, for putn, requires a special case */
|
|
d = tp[i];
|
|
xp[i] = ($1) Max( Xmin($1), Min(Xmax($1), ($1) d));
|
|
nrange += tp[i] > Xmax($1) PUTN_CheckBND($1, $2);
|
|
',dnl
|
|
`dnl
|
|
/* the normal case: */
|
|
xp[i] = ($1) Max( Xmin($1), Min(Xmax($1), ($1) 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] < Xmin */
|
|
nrange += tp[i] > Xmax($1) PUTN_CheckBND($1, $2);
|
|
')dnl
|
|
}
|
|
/* copy workspace back if necessary */
|
|
if (realign) {
|
|
memcpy(*xpp, tmp, ni*Xsizeof($1));
|
|
xp = ($1 *) *xpp;
|
|
}
|
|
/* update xpp and tp */
|
|
xp += ni;
|
|
tp += ni;
|
|
*xpp = (void*)xp;
|
|
}
|
|
return nrange == 0 ? ENOERR : NC_ERANGE;
|
|
|
|
#else /* not SX */
|
|
|
|
char *xp = (char *) *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
|
|
{
|
|
int lstatus = ncx_put_$1_$2(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
#endif
|
|
}
|
|
')dnl
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl NCX_PAD_PUTN_SHORT(xtype, ttype)
|
|
dnl
|
|
define(`NCX_PAD_PUTN_SHORT',dnl
|
|
`dnl
|
|
int
|
|
ncx_pad_putn_$1_$2(void **xpp, size_t nelems, const $2 *tp)
|
|
{
|
|
const size_t rndup = nelems % 2;
|
|
|
|
char *xp = (char *) *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += Xsizeof($1), tp++)
|
|
{
|
|
int lstatus = ncx_put_$1_$2(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
if(rndup != 0)
|
|
{
|
|
(void) memcpy(xp, nada, Xsizeof($1));
|
|
xp += Xsizeof($1);
|
|
}
|
|
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
}
|
|
')dnl
|
|
|
|
dnl dnl dnl
|
|
dnl
|
|
dnl Declare & define routines
|
|
dnl
|
|
dnl dnl dnl
|
|
|
|
/* schar ---------------------------------------------------------------------*/
|
|
|
|
dnl NCX_GETN_CHAR(schar, schar)
|
|
int
|
|
ncx_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
|
|
{
|
|
NCX_GETN_Byte_Body
|
|
}
|
|
dnl NCX_GETN_CHAR(schar, uchar)
|
|
int
|
|
ncx_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
|
|
{
|
|
NCX_GETN_Byte_Body
|
|
}
|
|
NCX_GETN_CHAR(schar, short)
|
|
NCX_GETN_CHAR(schar, int)
|
|
NCX_GETN_CHAR(schar, float)
|
|
NCX_GETN_CHAR(schar, double)
|
|
NCX_GETN_CHAR(schar, longlong)
|
|
NCX_GETN_CHAR(schar, ushort)
|
|
NCX_GETN_CHAR(schar, uint)
|
|
NCX_GETN_CHAR(schar, ulonglong)
|
|
|
|
dnl NCX_PAD_GETN_CHAR(schar, schar)
|
|
int
|
|
ncx_pad_getn_schar_schar(const void **xpp, size_t nelems, schar *tp)
|
|
{
|
|
NCX_PAD_GETN_Byte_Body
|
|
}
|
|
dnl NCX_PAD_GETN_CHAR(schar, uchar)
|
|
int
|
|
ncx_pad_getn_schar_uchar(const void **xpp, size_t nelems, uchar *tp)
|
|
{
|
|
NCX_PAD_GETN_Byte_Body
|
|
}
|
|
NCX_PAD_GETN_CHAR(schar, short)
|
|
NCX_PAD_GETN_CHAR(schar, int)
|
|
NCX_PAD_GETN_CHAR(schar, float)
|
|
NCX_PAD_GETN_CHAR(schar, double)
|
|
NCX_PAD_GETN_CHAR(schar, longlong)
|
|
NCX_PAD_GETN_CHAR(schar, ushort)
|
|
NCX_PAD_GETN_CHAR(schar, uint)
|
|
NCX_PAD_GETN_CHAR(schar, ulonglong)
|
|
|
|
dnl NCX_PUTN_CHAR(schar, schar)
|
|
int
|
|
ncx_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
|
|
{
|
|
NCX_PUTN_Byte_Body
|
|
}
|
|
dnl NCX_PUTN_CHAR(schar, uchar)
|
|
int
|
|
ncx_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
|
|
{
|
|
NCX_PUTN_Byte_Body
|
|
}
|
|
NCX_PUTN_CHAR(schar, short)
|
|
NCX_PUTN_CHAR(schar, int)
|
|
NCX_PUTN_CHAR(schar, float)
|
|
NCX_PUTN_CHAR(schar, double)
|
|
NCX_PUTN_CHAR(schar, longlong)
|
|
NCX_PUTN_CHAR(schar, ushort)
|
|
NCX_PUTN_CHAR(schar, uint)
|
|
NCX_PUTN_CHAR(schar, ulonglong)
|
|
|
|
dnl NCX_PAD_PUTN_CHAR(schar, schar)
|
|
int
|
|
ncx_pad_putn_schar_schar(void **xpp, size_t nelems, const schar *tp)
|
|
{
|
|
NCX_PAD_PUTN_Byte_Body
|
|
}
|
|
dnl NCX_PAD_PUTN_CHAR(schar, uchar)
|
|
int
|
|
ncx_pad_putn_schar_uchar(void **xpp, size_t nelems, const uchar *tp)
|
|
{
|
|
NCX_PAD_PUTN_Byte_Body
|
|
}
|
|
NCX_PAD_PUTN_CHAR(schar, short)
|
|
NCX_PAD_PUTN_CHAR(schar, int)
|
|
NCX_PAD_PUTN_CHAR(schar, float)
|
|
NCX_PAD_PUTN_CHAR(schar, double)
|
|
NCX_PAD_PUTN_CHAR(schar, longlong)
|
|
NCX_PAD_PUTN_CHAR(schar, ushort)
|
|
NCX_PAD_PUTN_CHAR(schar, uint)
|
|
NCX_PAD_PUTN_CHAR(schar, ulonglong)
|
|
|
|
|
|
/* uchar ---------------------------------------------------------------------*/
|
|
dnl
|
|
dnl NCX_GETN_CHAR(uchar, schar)
|
|
int
|
|
ncx_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
|
|
{
|
|
NCX_GETN_Byte_Body
|
|
}
|
|
dnl NCX_GETN_CHAR(uchar, uchar)
|
|
int
|
|
ncx_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
|
|
{
|
|
NCX_GETN_Byte_Body
|
|
}
|
|
NCX_GETN_CHAR(uchar, short)
|
|
NCX_GETN_CHAR(uchar, int)
|
|
NCX_GETN_CHAR(uchar, float)
|
|
NCX_GETN_CHAR(uchar, double)
|
|
NCX_GETN_CHAR(uchar, longlong)
|
|
NCX_GETN_CHAR(uchar, ushort)
|
|
NCX_GETN_CHAR(uchar, uint)
|
|
NCX_GETN_CHAR(uchar, ulonglong)
|
|
|
|
dnl NCX_PAD_GETN_CHAR(uchar, schar)
|
|
int
|
|
ncx_pad_getn_uchar_schar(const void **xpp, size_t nelems, schar *tp)
|
|
{
|
|
NCX_PAD_GETN_Byte_Body
|
|
}
|
|
dnl NCX_PAD_GETN_CHAR(uchar, uchar)
|
|
int
|
|
ncx_pad_getn_uchar_uchar(const void **xpp, size_t nelems, uchar *tp)
|
|
{
|
|
NCX_PAD_GETN_Byte_Body
|
|
}
|
|
NCX_PAD_GETN_CHAR(uchar, short)
|
|
NCX_PAD_GETN_CHAR(uchar, int)
|
|
NCX_PAD_GETN_CHAR(uchar, float)
|
|
NCX_PAD_GETN_CHAR(uchar, double)
|
|
NCX_PAD_GETN_CHAR(uchar, longlong)
|
|
NCX_PAD_GETN_CHAR(uchar, ushort)
|
|
NCX_PAD_GETN_CHAR(uchar, uint)
|
|
NCX_PAD_GETN_CHAR(uchar, ulonglong)
|
|
|
|
dnl NCX_PUTN_CHAR(uchar, schar)
|
|
int
|
|
ncx_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp)
|
|
{
|
|
NCX_PUTN_Byte_Body
|
|
}
|
|
dnl NCX_PUTN_CHAR(uchar, uchar)
|
|
int
|
|
ncx_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp)
|
|
{
|
|
NCX_PUTN_Byte_Body
|
|
}
|
|
NCX_PUTN_CHAR(uchar, short)
|
|
NCX_PUTN_CHAR(uchar, int)
|
|
NCX_PUTN_CHAR(uchar, float)
|
|
NCX_PUTN_CHAR(uchar, double)
|
|
NCX_PUTN_CHAR(uchar, longlong)
|
|
NCX_PUTN_CHAR(uchar, ushort)
|
|
NCX_PUTN_CHAR(uchar, uint)
|
|
NCX_PUTN_CHAR(uchar, ulonglong)
|
|
|
|
dnl NCX_PAD_PUTN_UCHAR(uchar, schar)
|
|
int
|
|
ncx_pad_putn_uchar_schar(void **xpp, size_t nelems, const schar *tp)
|
|
{
|
|
NCX_PAD_PUTN_Byte_Body
|
|
}
|
|
dnl NCX_PAD_PUTN_UCHAR(uchar, uchar)
|
|
int
|
|
ncx_pad_putn_uchar_uchar(void **xpp, size_t nelems, const uchar *tp)
|
|
{
|
|
NCX_PAD_PUTN_Byte_Body
|
|
}
|
|
NCX_PAD_PUTN_CHAR(uchar, short)
|
|
NCX_PAD_PUTN_CHAR(uchar, int)
|
|
NCX_PAD_PUTN_CHAR(uchar, float)
|
|
NCX_PAD_PUTN_CHAR(uchar, double)
|
|
NCX_PAD_PUTN_CHAR(uchar, longlong)
|
|
NCX_PAD_PUTN_CHAR(uchar, ushort)
|
|
NCX_PAD_PUTN_CHAR(uchar, uint)
|
|
NCX_PAD_PUTN_CHAR(uchar, ulonglong)
|
|
|
|
/* short ---------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_SHORT == SIZEOF_SHORT
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_short_short(const void **xpp, size_t nelems, short *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(short));
|
|
# else
|
|
swapn2b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_SHORT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_GETN(short, short)
|
|
#endif
|
|
NCX_GETN(short, schar)
|
|
NCX_GETN(short, int)
|
|
NCX_GETN(short, float)
|
|
NCX_GETN(short, double)
|
|
NCX_GETN(short, longlong)
|
|
NCX_GETN(short, uchar)
|
|
NCX_GETN(short, ushort)
|
|
NCX_GETN(short, uint)
|
|
NCX_GETN(short, ulonglong)
|
|
|
|
NCX_PAD_GETN_SHORT(short, schar)
|
|
NCX_PAD_GETN_SHORT(short, uchar)
|
|
NCX_PAD_GETN_SHORT(short, short)
|
|
NCX_PAD_GETN_SHORT(short, int)
|
|
NCX_PAD_GETN_SHORT(short, float)
|
|
NCX_PAD_GETN_SHORT(short, double)
|
|
NCX_PAD_GETN_SHORT(short, uint)
|
|
NCX_PAD_GETN_SHORT(short, longlong)
|
|
NCX_PAD_GETN_SHORT(short, ulonglong)
|
|
NCX_PAD_GETN_SHORT(short, ushort)
|
|
|
|
#if X_SIZEOF_SHORT == SIZEOF_SHORT
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_short_short(void **xpp, size_t nelems, const short *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_SHORT);
|
|
# else
|
|
swapn2b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_SHORT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_PUTN(short, short)
|
|
#endif
|
|
NCX_PUTN(short, schar)
|
|
NCX_PUTN(short, int)
|
|
NCX_PUTN(short, float)
|
|
NCX_PUTN(short, double)
|
|
NCX_PUTN(short, longlong)
|
|
NCX_PUTN(short, uchar)
|
|
NCX_PUTN(short, uint)
|
|
NCX_PUTN(short, ulonglong)
|
|
NCX_PUTN(short, ushort)
|
|
|
|
NCX_PAD_PUTN_SHORT(short, schar)
|
|
NCX_PAD_PUTN_SHORT(short, uchar)
|
|
NCX_PAD_PUTN_SHORT(short, short)
|
|
NCX_PAD_PUTN_SHORT(short, int)
|
|
NCX_PAD_PUTN_SHORT(short, float)
|
|
NCX_PAD_PUTN_SHORT(short, double)
|
|
NCX_PAD_PUTN_SHORT(short, uint)
|
|
NCX_PAD_PUTN_SHORT(short, longlong)
|
|
NCX_PAD_PUTN_SHORT(short, ulonglong)
|
|
NCX_PAD_PUTN_SHORT(short, ushort)
|
|
|
|
|
|
/* ushort --------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_USHORT == SIZEOF_USHORT
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_ushort_ushort(const void **xpp, size_t nelems, unsigned short *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(unsigned short));
|
|
# else
|
|
swapn2b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_USHORT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_GETN(ushort, ushort)
|
|
#endif
|
|
NCX_GETN(ushort, schar)
|
|
NCX_GETN(ushort, short)
|
|
NCX_GETN(ushort, int)
|
|
NCX_GETN(ushort, float)
|
|
NCX_GETN(ushort, double)
|
|
NCX_GETN(ushort, longlong)
|
|
NCX_GETN(ushort, uchar)
|
|
NCX_GETN(ushort, uint)
|
|
NCX_GETN(ushort, ulonglong)
|
|
|
|
NCX_PAD_GETN_SHORT(ushort, schar)
|
|
NCX_PAD_GETN_SHORT(ushort, uchar)
|
|
NCX_PAD_GETN_SHORT(ushort, short)
|
|
NCX_PAD_GETN_SHORT(ushort, ushort)
|
|
NCX_PAD_GETN_SHORT(ushort, int)
|
|
NCX_PAD_GETN_SHORT(ushort, uint)
|
|
NCX_PAD_GETN_SHORT(ushort, float)
|
|
NCX_PAD_GETN_SHORT(ushort, double)
|
|
NCX_PAD_GETN_SHORT(ushort, longlong)
|
|
NCX_PAD_GETN_SHORT(ushort, ulonglong)
|
|
|
|
#if X_SIZEOF_USHORT == SIZEOF_USHORT
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_ushort_ushort(void **xpp, size_t nelems, const unsigned short *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_USHORT);
|
|
# else
|
|
swapn2b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_USHORT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_PUTN(ushort, ushort)
|
|
#endif
|
|
NCX_PUTN(ushort, schar)
|
|
NCX_PUTN(ushort, short)
|
|
NCX_PUTN(ushort, int)
|
|
NCX_PUTN(ushort, float)
|
|
NCX_PUTN(ushort, double)
|
|
NCX_PUTN(ushort, longlong)
|
|
NCX_PUTN(ushort, uchar)
|
|
NCX_PUTN(ushort, uint)
|
|
NCX_PUTN(ushort, ulonglong)
|
|
|
|
NCX_PAD_PUTN_SHORT(ushort, schar)
|
|
NCX_PAD_PUTN_SHORT(ushort, uchar)
|
|
NCX_PAD_PUTN_SHORT(ushort, short)
|
|
NCX_PAD_PUTN_SHORT(ushort, int)
|
|
NCX_PAD_PUTN_SHORT(ushort, float)
|
|
NCX_PAD_PUTN_SHORT(ushort, double)
|
|
NCX_PAD_PUTN_SHORT(ushort, uint)
|
|
NCX_PAD_PUTN_SHORT(ushort, longlong)
|
|
NCX_PAD_PUTN_SHORT(ushort, ulonglong)
|
|
NCX_PAD_PUTN_SHORT(ushort, ushort)
|
|
|
|
|
|
/* int -----------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_INT == SIZEOF_INT
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_int_int(const void **xpp, size_t nelems, int *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(int));
|
|
# else
|
|
swapn4b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_INT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_GETN(int, int)
|
|
#endif
|
|
NCX_GETN(int, schar)
|
|
NCX_GETN(int, short)
|
|
NCX_GETN(int, float)
|
|
NCX_GETN(int, double)
|
|
NCX_GETN(int, longlong)
|
|
NCX_GETN(int, uchar)
|
|
NCX_GETN(int, ushort)
|
|
NCX_GETN(int, uint)
|
|
NCX_GETN(int, ulonglong)
|
|
|
|
#if X_SIZEOF_INT == SIZEOF_INT
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_int_int(void **xpp, size_t nelems, const int *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_INT);
|
|
# else
|
|
swapn4b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_INT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_PUTN(int, int)
|
|
#endif
|
|
NCX_PUTN(int, schar)
|
|
NCX_PUTN(int, short)
|
|
NCX_PUTN(int, float)
|
|
NCX_PUTN(int, double)
|
|
NCX_PUTN(int, longlong)
|
|
NCX_PUTN(int, uchar)
|
|
NCX_PUTN(int, ushort)
|
|
NCX_PUTN(int, uint)
|
|
NCX_PUTN(int, ulonglong)
|
|
|
|
/* uint ----------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_UINT == SIZEOF_UINT
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_uint_uint(const void **xpp, size_t nelems, unsigned int *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(uint));
|
|
# else
|
|
swapn4b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_UINT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_GETN(uint, uint)
|
|
#endif
|
|
NCX_GETN(uint, schar)
|
|
NCX_GETN(uint, short)
|
|
NCX_GETN(uint, int)
|
|
NCX_GETN(uint, float)
|
|
NCX_GETN(uint, double)
|
|
NCX_GETN(uint, longlong)
|
|
NCX_GETN(uint, uchar)
|
|
NCX_GETN(uint, ushort)
|
|
NCX_GETN(uint, ulonglong)
|
|
|
|
#if X_SIZEOF_UINT == SIZEOF_UINT
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_uint_uint(void **xpp, size_t nelems, const unsigned int *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_UINT);
|
|
# else
|
|
swapn4b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_UINT);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_PUTN(uint, uint)
|
|
#endif
|
|
NCX_PUTN(uint, schar)
|
|
NCX_PUTN(uint, short)
|
|
NCX_PUTN(uint, int)
|
|
NCX_PUTN(uint, float)
|
|
NCX_PUTN(uint, double)
|
|
NCX_PUTN(uint, longlong)
|
|
NCX_PUTN(uint, uchar)
|
|
NCX_PUTN(uint, ushort)
|
|
NCX_PUTN(uint, ulonglong)
|
|
|
|
|
|
/* float ---------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(float));
|
|
# else
|
|
swapn4b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
|
|
return ENOERR;
|
|
}
|
|
#elif vax
|
|
int
|
|
ncx_getn_float_float(const void **xpp, size_t nfloats, float *ip)
|
|
{
|
|
float *const end = ip + nfloats;
|
|
|
|
while(ip < end)
|
|
{
|
|
GET_VAX_DFLOAT_Body(`(*xpp)')
|
|
|
|
ip++;
|
|
*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
|
|
}
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
int
|
|
ncx_getn_float_float(const void **xpp, size_t nelems, float *tp)
|
|
{
|
|
const char *xp = *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
|
|
{
|
|
const int lstatus = ncx_get_float_float(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
*xpp = (const void *)xp;
|
|
return status;
|
|
}
|
|
|
|
#endif
|
|
NCX_GETN(float, schar)
|
|
NCX_GETN(float, short)
|
|
NCX_GETN(float, int)
|
|
NCX_GETN(float, double)
|
|
NCX_GETN(float, longlong)
|
|
NCX_GETN(float, ushort)
|
|
NCX_GETN(float, uchar)
|
|
NCX_GETN(float, uint)
|
|
NCX_GETN(float, ulonglong)
|
|
|
|
#if X_SIZEOF_FLOAT == SIZEOF_FLOAT && !defined(NO_IEEE_FLOAT)
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_FLOAT);
|
|
# else
|
|
swapn4b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_FLOAT);
|
|
return ENOERR;
|
|
}
|
|
#elif vax
|
|
int
|
|
ncx_putn_float_float(void **xpp, size_t nfloats, const float *ip)
|
|
{
|
|
const float *const end = ip + nfloats;
|
|
|
|
while(ip < end)
|
|
{
|
|
PUT_VAX_DFLOAT_Body(`(*xpp)')
|
|
|
|
ip++;
|
|
*xpp = (char *)(*xpp) + X_SIZEOF_FLOAT;
|
|
}
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
int
|
|
ncx_putn_float_float(void **xpp, size_t nelems, const float *tp)
|
|
{
|
|
char *xp = *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += X_SIZEOF_FLOAT, tp++)
|
|
{
|
|
int lstatus = ncx_put_float_float(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
}
|
|
#endif
|
|
NCX_PUTN(float, schar)
|
|
NCX_PUTN(float, short)
|
|
NCX_PUTN(float, int)
|
|
NCX_PUTN(float, double)
|
|
NCX_PUTN(float, longlong)
|
|
NCX_PUTN(float, uchar)
|
|
NCX_PUTN(float, ushort)
|
|
NCX_PUTN(float, uint)
|
|
NCX_PUTN(float, ulonglong)
|
|
|
|
/* double --------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(double));
|
|
# else
|
|
swapn8b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
|
|
return ENOERR;
|
|
}
|
|
#elif vax
|
|
int
|
|
ncx_getn_double_double(const void **xpp, size_t ndoubles, double *ip)
|
|
{
|
|
double *const end = ip + ndoubles;
|
|
|
|
while(ip < end)
|
|
{
|
|
GET_VAX_DDOUBLE_Body(`(*xpp)')
|
|
ip++;
|
|
*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
|
|
}
|
|
return ENOERR;
|
|
}
|
|
/* vax */
|
|
#else
|
|
int
|
|
ncx_getn_double_double(const void **xpp, size_t nelems, double *tp)
|
|
{
|
|
const char *xp = *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
|
|
{
|
|
const int lstatus = ncx_get_double_double(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
*xpp = (const void *)xp;
|
|
return status;
|
|
}
|
|
#endif
|
|
NCX_GETN(double, schar)
|
|
NCX_GETN(double, short)
|
|
NCX_GETN(double, int)
|
|
NCX_GETN(double, float)
|
|
NCX_GETN(double, longlong)
|
|
NCX_GETN(double, uchar)
|
|
NCX_GETN(double, ushort)
|
|
NCX_GETN(double, uint)
|
|
NCX_GETN(double, ulonglong)
|
|
|
|
#if X_SIZEOF_DOUBLE == SIZEOF_DOUBLE && !defined(NO_IEEE_FLOAT)
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_DOUBLE);
|
|
# else
|
|
swapn8b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_DOUBLE);
|
|
return ENOERR;
|
|
}
|
|
#elif vax
|
|
int
|
|
ncx_putn_double_double(void **xpp, size_t ndoubles, const double *ip)
|
|
{
|
|
const double *const end = ip + ndoubles;
|
|
|
|
while(ip < end)
|
|
{
|
|
PUT_VAX_DDOUBLE_Body(`(*xpp)')
|
|
ip++;
|
|
*xpp = (char *)(*xpp) + X_SIZEOF_DOUBLE;
|
|
}
|
|
return ENOERR;
|
|
}
|
|
/* vax */
|
|
#else
|
|
int
|
|
ncx_putn_double_double(void **xpp, size_t nelems, const double *tp)
|
|
{
|
|
char *xp = *xpp;
|
|
int status = ENOERR;
|
|
|
|
for( ; nelems != 0; nelems--, xp += X_SIZEOF_DOUBLE, tp++)
|
|
{
|
|
int lstatus = ncx_put_double_double(xp, tp);
|
|
if(lstatus != ENOERR)
|
|
status = lstatus;
|
|
}
|
|
|
|
*xpp = (void *)xp;
|
|
return status;
|
|
}
|
|
#endif
|
|
NCX_PUTN(double, schar)
|
|
NCX_PUTN(double, short)
|
|
NCX_PUTN(double, int)
|
|
NCX_PUTN(double, float)
|
|
NCX_PUTN(double, longlong)
|
|
NCX_PUTN(double, uchar)
|
|
NCX_PUTN(double, ushort)
|
|
NCX_PUTN(double, uint)
|
|
NCX_PUTN(double, ulonglong)
|
|
|
|
|
|
/* longlong -----------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_LONGLONG == SIZEOF_LONGLONG
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_longlong_longlong(const void **xpp, size_t nelems, long long *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(long long));
|
|
# else
|
|
swapn8b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_LONGLONG);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_GETN(longlong, longlong)
|
|
#endif
|
|
NCX_GETN(longlong, schar)
|
|
NCX_GETN(longlong, short)
|
|
NCX_GETN(longlong, int)
|
|
NCX_GETN(longlong, float)
|
|
NCX_GETN(longlong, double)
|
|
NCX_GETN(longlong, uchar)
|
|
NCX_GETN(longlong, ushort)
|
|
NCX_GETN(longlong, uint)
|
|
NCX_GETN(longlong, ulonglong)
|
|
|
|
#if X_SIZEOF_LONGLONG == SIZEOF_LONGLONG
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_longlong_longlong(void **xpp, size_t nelems, const long long *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_LONGLONG);
|
|
# else
|
|
swapn8b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_LONGLONG);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_PUTN(longlong, longlong)
|
|
#endif
|
|
NCX_PUTN(longlong, schar)
|
|
NCX_PUTN(longlong, short)
|
|
NCX_PUTN(longlong, int)
|
|
NCX_PUTN(longlong, float)
|
|
NCX_PUTN(longlong, double)
|
|
NCX_PUTN(longlong, uchar)
|
|
NCX_PUTN(longlong, ushort)
|
|
NCX_PUTN(longlong, uint)
|
|
NCX_PUTN(longlong, ulonglong)
|
|
|
|
/* ulonglong ----------------------------------------------------------------------*/
|
|
|
|
#if X_SIZEOF_ULONGLONG == SIZEOF_ULONGLONG
|
|
/* optimized version */
|
|
int
|
|
ncx_getn_ulonglong_ulonglong(const void **xpp, size_t nelems, unsigned long long *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(tp, *xpp, nelems * sizeof(unsigned long long));
|
|
# else
|
|
swapn8b(tp, *xpp, nelems);
|
|
# endif
|
|
*xpp = (const void *)((const char *)(*xpp) + nelems * X_SIZEOF_ULONGLONG);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_GETN(ulonglong, ulonglong)
|
|
#endif
|
|
NCX_GETN(ulonglong, schar)
|
|
NCX_GETN(ulonglong, short)
|
|
NCX_GETN(ulonglong, int)
|
|
NCX_GETN(ulonglong, float)
|
|
NCX_GETN(ulonglong, double)
|
|
NCX_GETN(ulonglong, longlong)
|
|
NCX_GETN(ulonglong, uchar)
|
|
NCX_GETN(ulonglong, ushort)
|
|
NCX_GETN(ulonglong, uint)
|
|
|
|
#if X_SIZEOF_ULONGLONG == SIZEOF_ULONGLONG
|
|
/* optimized version */
|
|
int
|
|
ncx_putn_ulonglong_ulonglong(void **xpp, size_t nelems, const unsigned long long *tp)
|
|
{
|
|
#ifdef WORDS_BIGENDIAN
|
|
(void) memcpy(*xpp, tp, nelems * X_SIZEOF_ULONGLONG);
|
|
# else
|
|
swapn8b(*xpp, tp, nelems);
|
|
# endif
|
|
*xpp = (void *)((char *)(*xpp) + nelems * X_SIZEOF_ULONGLONG);
|
|
return ENOERR;
|
|
}
|
|
#else
|
|
NCX_PUTN(ulonglong, ulonglong)
|
|
#endif
|
|
NCX_PUTN(ulonglong, schar)
|
|
NCX_PUTN(ulonglong, short)
|
|
NCX_PUTN(ulonglong, int)
|
|
NCX_PUTN(ulonglong, float)
|
|
NCX_PUTN(ulonglong, double)
|
|
NCX_PUTN(ulonglong, longlong)
|
|
NCX_PUTN(ulonglong, uchar)
|
|
NCX_PUTN(ulonglong, ushort)
|
|
NCX_PUTN(ulonglong, uint)
|
|
|
|
|
|
/*
|
|
* Other aggregate conversion functions.
|
|
*/
|
|
|
|
/* text */
|
|
|
|
int
|
|
ncx_getn_text(const void **xpp, size_t nelems, char *tp)
|
|
{
|
|
NCX_GETN_Byte_Body
|
|
}
|
|
|
|
int
|
|
ncx_pad_getn_text(const void **xpp, size_t nelems, char *tp)
|
|
{
|
|
NCX_PAD_GETN_Byte_Body
|
|
}
|
|
|
|
int
|
|
ncx_putn_text(void **xpp, size_t nelems, const char *tp)
|
|
{
|
|
NCX_PUTN_Byte_Body
|
|
}
|
|
|
|
int
|
|
ncx_pad_putn_text(void **xpp, size_t nelems, const char *tp)
|
|
{
|
|
NCX_PAD_PUTN_Byte_Body
|
|
}
|
|
|
|
|
|
/* opaque */
|
|
|
|
int
|
|
ncx_getn_void(const void **xpp, size_t nelems, void *tp)
|
|
{
|
|
NCX_GETN_Byte_Body
|
|
}
|
|
|
|
int
|
|
ncx_pad_getn_void(const void **xpp, size_t nelems, void *tp)
|
|
{
|
|
NCX_PAD_GETN_Byte_Body
|
|
}
|
|
|
|
int
|
|
ncx_putn_void(void **xpp, size_t nelems, const void *tp)
|
|
{
|
|
NCX_PUTN_Byte_Body
|
|
}
|
|
|
|
int
|
|
ncx_pad_putn_void(void **xpp, size_t nelems, const void *tp)
|
|
{
|
|
NCX_PAD_PUTN_Byte_Body
|
|
}
|