- + for i in *
- + cat Makefile
- #
- # Makefile for nan_payload_probe code
- #
- SHELL=/usr/bin/ksh93
- nanpayload.h: nanpayload.sh
- ksh93 nanpayload.sh
- rm tmp_nanpayload_sh_generator tmp_nanpayload_sh_generator.c
- nan_payload_test1: nan_payload_test1.c nan_payload_probe.c nan_payload_probe.h nanpayload.h
- gcc nan_payload_probe.c -Wall -g nan_payload_test1.c -lm -o nan_payload_test1
- tests: nan_payload_test1
- diff -u nan_payload_test1_expected_output_x86_64bit.out <( ./nan_payload_test1 ) && echo "test OK"
- clean:
- rm -f \
- nanpayload.h \
- nan_payload_test1
- # EOF.
- + for i in *
- + cat nan_payload_probe.c
- /***********************************************************************
- * *
- * This software is part of the ast package *
- * Copyright (c) 2013 AT&T Intellectual Property *
- * and is licensed under the *
- * Common Public License, Version 1.0 *
- * by AT&T Intellectual Property *
- * *
- * A copy of the License is available at *
- * http://www.opensource.org/licenses/cpl1.0.txt *
- * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
- * *
- * Information and Software Systems Research *
- * AT&T Research *
- * Florham Park NJ *
- * *
- * Roland Mainz <roland.mainz@nrubsig.org> *
- * *
- ***********************************************************************/
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "nan_payload_probe.h"
- void set_nan_payload_binary32(flt_binary32 *val, uint32_t payload)
- {
- if (payload == 0)
- return;
- if (!isnanf(*val))
- return;
- uint32_t bitval;
- (void)memcpy(&bitval, val, sizeof(bitval));
- bitval &= ~NANPAYLOAD_FLT_PAYLOAD_MASK;
- bitval |= (payload & NANPAYLOAD_FLT_PAYLOAD_MASK);
- (void)memcpy(val, &bitval, sizeof(*val));
- }
- uint32_t get_nan_payload_binary32(flt_binary32 x)
- {
- uint32_t payload;
- if (!isnanf(x))
- return(0);
- uint32_t bitval;
- (void)memcpy(&bitval, &x, sizeof(bitval));
- payload = bitval & NANPAYLOAD_FLT_PAYLOAD_MASK;
- return(payload);
- }
- void set_nan_payload_binary64(flt_binary64 *val, uint64_t payload)
- {
- if (payload == 0)
- return;
- if (!isnan(*val))
- return;
- uint64_t bitval;
- (void)memcpy(&bitval, val, sizeof(bitval));
- bitval &= ~NANPAYLOAD_DBL_PAYLOAD_MASK;
- bitval |= (payload & NANPAYLOAD_DBL_PAYLOAD_MASK);
- (void)memcpy(val, &bitval, sizeof(*val));
- }
- uint64_t get_nan_payload_binary64(flt_binary64 x)
- {
- uint64_t payload;
- if (!isnan(x))
- return(0ULL);
- uint64_t bitval;
- (void)memcpy(&bitval, &x, sizeof(bitval));
- payload = bitval & NANPAYLOAD_DBL_PAYLOAD_MASK;
- return(payload);
- }
- #ifdef _typ___int128_t
- #if NAN_PAYLOAD_LDBL_BITS == 128
- void set_nan_payload_binary128(flt_binary128 *val, __int128_t payload)
- #elif NAN_PAYLOAD_LDBL_BITS == 80
- void set_nan_payload_binary80(flt_binary80 *val, uint64_t payload)
- #endif
- {
- if (payload == 0)
- return;
- if (!isnanl(*val))
- return;
- __int128_t bitval;
- (void)memcpy(&bitval, val, sizeof(bitval));
- /*
- * The i387 FPU extended precision format defines one extra
- * magic bit between exponent and fraction.
- * The layout looks like this:
- * <sign(1bit)><exponent(15bit)><magic(1bit)><fraction(63bit)>
- */
- bitval &= ~NANPAYLOAD_LDBL_PAYLOAD_MASK;
- bitval |= (payload & NANPAYLOAD_LDBL_PAYLOAD_MASK);
- (void)memcpy(val, &bitval, sizeof(*val));
- }
- #if NAN_PAYLOAD_LDBL_BITS == 128
- __int128_t get_nan_payload_binary128(flt_binary128 x)
- #elif NAN_PAYLOAD_LDBL_BITS == 80
- uint64_t get_nan_payload_binary80(flt_binary80 x)
- #endif
- {
- #if NAN_PAYLOAD_LDBL_BITS == 128
- __int128_t payload;
- #else
- uint64_t payload;
- #endif
- if (!isnanl(x))
- return(0);
- __int128_t bitval;
- (void)memcpy(&bitval, &x, sizeof(bitval));
- payload = bitval & NANPAYLOAD_LDBL_PAYLOAD_MASK;
- return(payload);
- }
- #endif /* _typ___int128_t */
- #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
- void set_nan_payload_binary80_i387(flt_binary80 *val, uint64_t payload)
- {
- if (payload == 0)
- return;
- if (!isnanl(*val))
- return;
- /*
- * This is a bit of a hack, we access only the first 64bit data
- * of a 64bit data type
- */
- uint64_t bitval;
- (void)memcpy(&bitval, val, sizeof(bitval));
- bitval &= ~NANPAYLOAD_LDBL_PAYLOAD_MASK;
- bitval |= (payload & NANPAYLOAD_LDBL_PAYLOAD_MASK);
- (void)memcpy(val, &bitval, sizeof(uint64_t));
- }
- uint64_t get_nan_payload_binary80_i387(flt_binary80 x)
- {
- uint64_t payload;
- if (!isnanl(x))
- return(0);
- uint64_t bitval;
- (void)memcpy(&bitval, &x, sizeof(bitval));
- payload = bitval & NANPAYLOAD_LDBL_PAYLOAD_MASK;
- return(payload);
- }
- #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
- flt_binary32 cast_binary64_to_binary32(flt_binary64 d)
- {
- flt_binary32 f;
- if (isnan(d))
- {
- uint64_t payload;
- payload = get_nan_payload_binary64(d);
- f = (flt_binary32)d;
- set_nan_payload_binary32(&f, payload);
- }
- else
- {
- f = (flt_binary32)d;
- }
- return(f);
- }
- #if NAN_PAYLOAD_LDBL_BITS == 128
- flt_binary128 cast_binary64_to_binary128(flt_binary64 d)
- {
- flt_binary128 ld;
- if (isnan(d))
- {
- __int128_t payload;
- payload = get_nan_payload_binary64(d);
- ld = (flt_binary128)d;
- set_nan_payload_binary128(&ld, payload);
- }
- else
- {
- ld = (flt_binary128)d;
- }
- return(ld);
- }
- #elif NAN_PAYLOAD_LDBL_BITS == 80
- flt_binary80 cast_binary64_to_binary80(flt_binary64 d)
- {
- flt_binary80 ld;
- if (isnan(d))
- {
- uint64_t payload;
- payload = get_nan_payload_binary64(d);
- ld = (flt_binary80)d;
- set_nan_payload_binary80(&ld, payload);
- }
- else
- {
- ld = (flt_binary80)d;
- }
- return(ld);
- }
- #endif /* NAN_PAYLOAD_LDBL_BITS == 80 */
- flt_binary64 cast_binary32_to_binary64(flt_binary32 f)
- {
- flt_binary64 d;
- if (isnanf(f))
- {
- uint32_t payload;
- payload = get_nan_payload_binary32(f);
- d = (flt_binary64)f;
- set_nan_payload_binary64(&d, payload);
- }
- else
- {
- d = (flt_binary64)f;
- }
- return(d);
- }
- #if NAN_PAYLOAD_LDBL_BITS == 128
- flt_binary128 cast_binary32_to_binary128(flt_binary32 f)
- {
- flt_binary128 ld;
- if (isnanf(f))
- {
- uint32_t payload;
- payload = get_nan_payload_binary32(f);
- ld = (flt_binary128)f;
- set_nan_payload_binary128(&ld, payload);
- }
- else
- {
- ld = (flt_binary128)f;
- }
- return(ld);
- }
- flt_binary32 cast_binary128_to_binary32(flt_binary128 ld)
- {
- flt_binary32 f;
- if (isnanl(ld))
- {
- __int128_t payload;
- payload = get_nan_payload_binary128(ld);
- f = (flt_binary32)ld;
- set_nan_payload_binary32(&f, payload);
- }
- else
- {
- f = (flt_binary32)ld;
- }
- return(f);
- }
- flt_binary64 cast_binary128_to_binary64(flt_binary128 ld)
- {
- flt_binary64 d;
- if (isnanl(ld))
- {
- __int128_t payload;
- payload = get_nan_payload_binary128(ld);
- d = (flt_binary64)ld;
- set_nan_payload_binary64(&d, payload);
- }
- else
- {
- d = (flt_binary64)ld;
- }
- return(d);
- }
- #elif NAN_PAYLOAD_LDBL_BITS == 80
- flt_binary80 cast_binary32_to_binary80(flt_binary32 f)
- {
- flt_binary80 ld;
- if (isnanf(f))
- {
- uint32_t payload;
- payload = get_nan_payload_binary32(f);
- ld = (flt_binary80)f;
- set_nan_payload_binary80(&ld, payload);
- }
- else
- {
- ld = (flt_binary80)f;
- }
- return(ld);
- }
- flt_binary32 cast_binary80_to_binary32(flt_binary80 ld)
- {
- flt_binary32 f;
- if (isnanl(ld))
- {
- uint64_t payload;
- payload = get_nan_payload_binary80(ld);
- f = (flt_binary32)ld;
- set_nan_payload_binary32(&f, payload);
- }
- else
- {
- f = (flt_binary32)ld;
- }
- return(f);
- }
- flt_binary64 cast_binary80_to_binary64(flt_binary80 ld)
- {
- flt_binary64 d;
- if (isnanl(ld))
- {
- uint64_t payload;
- payload = get_nan_payload_binary80(ld);
- d = (flt_binary64)ld;
- set_nan_payload_binary64(&d, payload);
- }
- else
- {
- d = (flt_binary64)ld;
- }
- return(d);
- }
- #endif /* NAN_PAYLOAD_LDBL_BITS == 80 */
- + for i in *
- + cat nan_payload_probe.h
- /***********************************************************************
- * *
- * This software is part of the ast package *
- * Copyright (c) 2013 AT&T Intellectual Property *
- * and is licensed under the *
- * Common Public License, Version 1.0 *
- * by AT&T Intellectual Property *
- * *
- * A copy of the License is available at *
- * http://www.opensource.org/licenses/cpl1.0.txt *
- * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
- * *
- * Information and Software Systems Research *
- * AT&T Research *
- * Florham Park NJ *
- * *
- * Roland Mainz <roland.mainz@nrubsig.org> *
- * *
- ***********************************************************************/
- #ifndef NAN_PAYLOAD_PROBE_H
- #define NAN_PAYLOAD_PROBE_H 1
- #include <stdint.h>
- #include <math.h>
- #include <float.h>
- #include <limits.h>
- #if (__STDC_VERSION__ - 0) < 199901L
- #error Requires ISO C99 or gcc GNU99 mode
- #endif
- #ifndef _typ___int128_t
- #ifdef __SIZEOF_INT128__
- #define _typ___int128_t 1
- #endif
- #endif
- /* use |__float128| on gcc/x86 for testing */
- #if defined(__amd64)
- //#define GCC__FLOAT128 1
- #endif
- #include "nanpayload.h"
- /*
- * map C types to aliases which define their physical layout
- * The mapping type names are derived from IEEE754-2008 with
- * |flt_| as prefix to avoid collisions with other software
- */
- typedef float flt_binary32;
- typedef double flt_binary64;
- #if defined(__i386) || defined(__amd64)
- #if (NAN_PAYLOAD_LDBL_BITS == 128)
- typedef __float128 flt_binary128;
- #else
- typedef long double flt_binary80;
- #endif
- #else
- #if (NAN_PAYLOAD_LDBL_BITS == 128)
- typedef long double flt_binary128;
- #elif (NAN_PAYLOAD_LDBL_BITS == 64)
- #error |long double| == |double| not implemented yet
- #else
- #error Unsupported NAN_PAYLOAD_LDBL_BITS
- #endif
- #endif
- #if 1 /* prototypes */
- void set_nan_payload_binary32(flt_binary32 *val, uint32_t payload);
- uint32_t get_nan_payload_binary32(flt_binary32 x);
- void set_nan_payload_binary64(flt_binary64 *val, uint64_t payload);
- uint64_t get_nan_payload_binary64(flt_binary64 x);
- #if NAN_PAYLOAD_LDBL_BITS == 128
- void set_nan_payload_binary128(flt_binary128 *val, __int128_t payload);
- __int128_t get_nan_payload_binary128(flt_binary128 x);
- #elif NAN_PAYLOAD_LDBL_BITS == 80
- #ifdef _typ___int128_t
- void set_nan_payload_binary80(flt_binary80 *val, uint64_t payload);
- uint64_t get_nan_payload_binary80(flt_binary80 x);
- #else
- #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
- #define set_nan_payload_binary80(v, p) set_nan_payload_binary80_i387((v), (p))
- #define get_nan_payload_binary80(v) get_nan_payload_binary80_i387(v)
- #endif
- #endif /* _typ___int128_t */
- #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
- void set_nan_payload_binary80_i387(flt_binary80 *val, uint64_t payload);
- uint64_t get_nan_payload_binary80_i387(flt_binary80 x);
- #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
- #endif
- flt_binary32 cast_binary64_to_binary32(flt_binary64 d);
- #if NAN_PAYLOAD_LDBL_BITS == 128
- flt_binary128 cast_binary64_to_binary128(flt_binary64 d);
- #elif NAN_PAYLOAD_LDBL_BITS == 80
- flt_binary80 cast_binary64_to_binary80(flt_binary64 d);
- #endif /* NAN_PAYLOAD_LDBL_BITS == 128 */
- flt_binary64 cast_binary32_to_binary64(flt_binary32 f);
- #if NAN_PAYLOAD_LDBL_BITS == 128
- flt_binary128 cast_binary32_to_binary128(flt_binary32 f);
- flt_binary32 cast_binary128_to_binary32(flt_binary128 ld);
- flt_binary64 cast_binary128_to_binary64(flt_binary128 ld);
- #elif NAN_PAYLOAD_LDBL_BITS == 80
- flt_binary80 cast_binary32_to_binary80(flt_binary32 f);
- flt_binary32 cast_binary80_to_binary32(flt_binary80 ld);
- flt_binary64 cast_binary80_to_binary64(flt_binary80 ld);
- #endif /* NAN_PAYLOAD_LDBL_BITS == 128 */
- #endif /* prototypes */
- /*
- * External API:
- *
- * |flt_binary@(32|64|80|128)| to ISO C type mappings
- */
- #define CAST_FLT2DBL(f) cast_binary32_to_binary64(f)
- #define CAST_DBL2FLT(f) cast_binary64_to_binary32(f)
- #if (NAN_PAYLOAD_LDBL_BITS == 128)
- #define CAST_FLT2LDBL(f) cast_binary32_to_binary128(f)
- #define CAST_DBL2LDBL(f) cast_binary64_to_binary128(f)
- #define CAST_LDBL2FLT(f) cast_binary128_to_binary32(f)
- #define CAST_LDBL2DBL(f) cast_binary128_to_binary64(f)
- #elif (NAN_PAYLOAD_LDBL_BITS == 80)
- #define CAST_FLT2LDBL(f) cast_binary32_to_binary80(f)
- #define CAST_DBL2LDBL(f) cast_binary64_to_binary80(f)
- #define CAST_LDBL2FLT(f) cast_binary80_to_binary32(f)
- #define CAST_LDBL2DBL(f) cast_binary80_to_binary64(f)
- #else
- #error Unsupported NAN_PAYLOAD_LDBL_BITS value
- #endif
- /*
- * get payload
- */
- #define GET_NAN_PAYLOAD_FLOAT(f) get_nan_payload_binary32(f)
- #define GET_NAN_PAYLOAD_DOUBLE(d) get_nan_payload_binary64(d)
- #if (NAN_PAYLOAD_LDBL_BITS == 128)
- #define GET_NAN_PAYLOAD_LONGDOUBLE(ld) get_nan_payload_binary128(ld)
- #elif (NAN_PAYLOAD_LDBL_BITS == 80)
- #define GET_NAN_PAYLOAD_LONGDOUBLE(ld) get_nan_payload_binary80(ld)
- #endif
- /*
- * set payload
- */
- #define SET_NAN_PAYLOAD_FLOAT(val, payload) set_nan_payload_binary32((val), (payload))
- #define SET_NAN_PAYLOAD_DOUBLE(val, payload) set_nan_payload_binary64((val), (payload))
- #if (NAN_PAYLOAD_LDBL_BITS == 128)
- #define SET_NAN_PAYLOAD_LONGDOUBLE(val, payload) set_nan_payload_binary128((val), (payload))
- #elif (NAN_PAYLOAD_LDBL_BITS == 80)
- #define SET_NAN_PAYLOAD_LONGDOUBLE(val, payload) set_nan_payload_binary80((val), (payload))
- #endif
- /*
- * Notes about portablity:
- * - The ISO C99 standards supports a portable way to write the
- * payload of a quiet NaN in ISO C.
- *
- * - The |nan()|/|nanf()|/|nanl()| functions (from <math.h>, see
- * section 7.12.11.2 in the ISO C99 spec) accept strings as
- * arguments.
- *
- * - |strtof()|/|strtod()|/|strtold()| functions (from <stdlib.h>,
- * see section 7.20.1.3) accept strings in the form
- * "NAN(character sequence)".
- *
- * - |fscanf()|+|sscanf()| follow |strtod()|
- *
- * - the character sequence in "NAN(character sequence)" is
- * interpreted in an (libc+compiler) implementation-specific
- * way (=not portable).
- *
- * - The actual bit layout can differ from the recommended IEEE754-2008
- * layout. For now we do not care about these special cases except
- * the 80bit i387 FPU format (mc68881/2 *may* require similar
- * attention) - see below...
- *
- * - The i387 FPU extended precision format defines one extra
- * magic bit between exponent and fraction.
- * The layout looks like this:
- * <sign(1bit)><exponent(15bit)><magic(1bit)><fraction(63bit)>
- *
- * - The |long double| code relies on |__int128_t| which is a
- * gcc+clang extension. It seems |__SIZEOF_INT128__| can be
- * reliably used (since gcc4.x; some platforms have more or less
- * working |__int128_t| since gcc 3.4 but there is no way to test
- * the completeness) to test whether the type is available:
- * -- snip --
- * $ gcc -E -dM -x c '/dev/null' | fgrep '128'
- * #define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
- * #define __DEC128_EPSILON__ 1E-33DL
- * #define __DEC128_MIN__ 1E-6143DL
- * #define __DEC128_MIN_EXP__ (-6142)
- * #define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
- * #define __FLT_MAX_EXP__ 128
- * #define __SIZEOF_INT128__ 16
- * #define __DEC128_MAX_EXP__ 6145
- * #define __DEC128_MANT_DIG__ 34
- * $ clang -E -dM -x c /dev/null | fgrep 128
- * #define __FLT_MAX_EXP__ 128
- * #define __SIZEOF_INT128__ 16
- * -- snip --
- *
- */
- #endif /* NAN_PAYLOAD_PROBE_H */
- + for i in *
- + cat nanpayload.sh
- ########################################################################
- # #
- # This software is part of the ast package #
- # Copyright (c) 2013 Roland Mainz #
- # and is licensed under the #
- # Eclipse Public License, Version 1.0 #
- # by AT&T Intellectual Property #
- # #
- # A copy of the License is available at #
- # http://www.eclipse.org/org/documents/epl-v10.html #
- # (with md5 checksum b35adb5213ca9657e911e9befb180842) #
- # #
- # #
- # Roland Mainz <roland.mainz@nrubsig.org> #
- # #
- ########################################################################
- #
- # Copyright (c) 2013, Roland Mainz. All rights reserved.
- #
- #
- # nanpayload.sh - generate nanpayload.h
- #
- cat >'tmp_nanpayload_sh_generator.c' <<ENDOFTEXT
- /* Generated from nanpayload.sh - DO NOT EDIT */
- #include <stdio.h>
- #include <stdint.h>
- #include <math.h>
- #include <float.h>
- #include <limits.h>
- /*
- * NAN_PAYLOAD_LDBL_BITS:
- * 80 for AMD64, 128 on SPARC, xxx on other platforms
- */
- #ifndef LDBL_MAX_EXP
- #error LDBL_MAX_EXP not available
- #endif
- #if LDBL_MAX_EXP == 1024
- #define NAN_PAYLOAD_LDBL_BITS 64 /* this happens if |long double| is the same as |double| */
- #elif LDBL_MAX_EXP == 16384
- #define NAN_PAYLOAD_LDBL_BITS 80
- #elif LDBL_MAX_EXP > 16384
- #define NAN_PAYLOAD_LDBL_BITS 128
- #else
- #error Unsupported LDBL_MAX_EXP (cannot calculate |long double| bit size)
- #endif
- int main(int ac, char *av[])
- {
- (void)printf("#ifndef NANPAYLOAD_H\n");
- (void)printf("#define NANPAYLOAD_H 1\n");
- (void)printf("\n");
- (void)printf("/* Generated from nanpayload.sh - DO NOT EDIT */\n\n");
- (void)printf("#define NAN_PAYLOAD_LDBL_BITS %lu\n\n", (long)NAN_PAYLOAD_LDBL_BITS);
- {
- const uint32_t exp_bits = (uint32_t)log2f(FLT_MAX_EXP)+1;
- const uint32_t frac_bits = 32-1-exp_bits;
- const uint32_t payload_bits = frac_bits-1; /* one bit for quiet/signaling nan */
- const uint32_t payload_mask = ((uint32_t)powf(2, payload_bits))-1;
- (void)printf("#define NANPAYLOAD_FLT_EXP_BITS\t%lu\n", (unsigned long)exp_bits);
- (void)printf("#define NANPAYLOAD_FLT_FRAC_BITS\t%lu\n", (unsigned long)frac_bits);
- (void)printf("#define NANPAYLOAD_FLT_PAYLOAD_BITS\t%lu\n", (unsigned long)payload_bits);
- (void)printf("#define NANPAYLOAD_FLT_PAYLOAD_MASK\t0x%lx\n", (unsigned long)payload_mask);
- (void)printf("\n");
- }
- {
- const uint64_t exp_bits = (uint64_t)log2(DBL_MAX_EXP)+1;
- const uint64_t frac_bits = 64-1-exp_bits;
- const uint64_t payload_bits = frac_bits-1; /* one bit for quiet/signaling nan */
- const uint64_t payload_mask = ((uint64_t)pow(2, payload_bits))-1;
- (void)printf("#define NANPAYLOAD_DBL_EXP_BITS\t%llu\n", (unsigned long long)exp_bits);
- (void)printf("#define NANPAYLOAD_DBL_FRAC_BITS\t%llu\n", (unsigned long long)frac_bits);
- (void)printf("#define NANPAYLOAD_DBL_PAYLOAD_BITS\t%llu\n", (unsigned long long)payload_bits);
- (void)printf("#define NANPAYLOAD_DBL_PAYLOAD_MASK\t0x%llx\n", (unsigned long long)payload_mask);
- (void)printf("\n");
- }
- {
- #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) && (!_typ___int128_t)
- const uint64_t exp_bits = log2l(LDBL_MAX_EXP)+1;
- const uint64_t frac_bits = 63;
- const uint64_t payload_bits = frac_bits-1;
- const uint64_t payload_mask = ((uint64_t)powl(2, payload_bits))-1;
- (void)printf("#define NANPAYLOAD_LDBL_EXP_BITS\t%llu\n", (unsigned long long)exp_bits);
- (void)printf("#define NANPAYLOAD_LDBL_FRAC_BITS\t%llu\n", (unsigned long long)frac_bits);
- (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_BITS\t%llu\n", (unsigned long long)payload_bits);
- (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_MASK\t0x%llx\n", (unsigned long long)payload_mask);
- (void)printf("\n");
- #else
- const __int128_t exp_bits = (__int128_t)log2l(LDBL_MAX_EXP)+1;
- #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
- /*
- * The i387 FPU extended precision format defines one extra
- * magic bit between exponent and fraction.
- * The layout looks like this:
- * <sign(1bit)><exponent(15bit)><magic(1bit)><fraction(63bit)>
- */
- const __int128_t frac_bits = NAN_PAYLOAD_LDBL_BITS-1-1-exp_bits;
- #else
- const __int128_t frac_bits = NAN_PAYLOAD_LDBL_BITS-1-exp_bits;
- #endif
- const __int128_t payload_bits = frac_bits-1; /* one bit for quiet/signaling nan */
- const __int128_t payload_mask = ((__int128_t)powl(2, payload_bits))-1;
- /* fixme: How do we print |__int128_t| ? */
- (void)printf("#define NANPAYLOAD_LDBL_EXP_BITS\t%llu\n", (unsigned long long)exp_bits);
- (void)printf("#define NANPAYLOAD_LDBL_FRAC_BITS\t%llu\n", (unsigned long long)frac_bits);
- (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_BITS\t%llu\n", (unsigned long long)payload_bits);
- (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_MASK\t0x%llx\n", (unsigned long long)payload_mask);
- (void)printf("\n");
- #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
- }
- (void)printf("\n#endif /* NANPAYLOAD_H */\n");
- return (0);
- }
- ENDOFTEXT
- rm -f ./tmp_nanpayload_sh_generator
- gcc -std=gnu99 -m64 -Wall tmp_nanpayload_sh_generator.c -o tmp_nanpayload_sh_generator -lm
- ./tmp_nanpayload_sh_generator >'nanpayload.h'
- # EOF.
- + for i in *
- + cat nan_payload_test1.c
- /***********************************************************************
- * *
- * This software is part of the ast package *
- * Copyright (c) 2013 AT&T Intellectual Property *
- * and is licensed under the *
- * Common Public License, Version 1.0 *
- * by AT&T Intellectual Property *
- * *
- * A copy of the License is available at *
- * http://www.opensource.org/licenses/cpl1.0.txt *
- * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
- * *
- * Information and Software Systems Research *
- * AT&T Research *
- * Florham Park NJ *
- * *
- * Roland Mainz <roland.mainz@nrubsig.org> *
- * *
- ***********************************************************************/
- #include <stdlib.h>
- #include <stdio.h>
- #include "nan_payload_probe.h"
- #ifdef GCC__FLOAT128
- #define FLT1282LDBL(flt128) ((long double)(flt128))
- #else
- #define FLT1282LDBL(flt128) (flt128)
- #endif
- void print_bits_32(uint32_t x)
- {
- int i;
- for (i=0 ; i < 32 ; i++)
- {
- /* fixme: endian! */
- (void)printf("%d", (x & (1UL<<31))?1:0);
- x = x << 1;
- }
- }
- void print_bits_64(uint64_t x)
- {
- int i;
- for (i=0 ; i < 64 ; i++)
- {
- /* fixme: endian! */
- (void)printf("%d", (x & (1ULL<<63))?1:0);
- x = x << 1;
- }
- }
- #ifdef _typ___int128_t
- void print_bits_128(__int128_t x)
- {
- int i;
- for (i=0 ; i < 128 ; i++)
- {
- /* fixme: endian! */
- (void)printf("%d", (x & (((__int128_t)1)<<127))?1:0);
- x = x << 1;
- }
- }
- #endif /* _typ___int128_t */
- int main(int ac, char *av[])
- {
- volatile flt_binary32 val = NAN;
- long i;
- volatile uint32_t *xp=(volatile uint32_t *)&val;
- (void)printf("orig:\t" ); print_bits_32(*xp); (void)printf("\tval=%f\n", val);
- const uint32_t exp_bits = ((uint32_t)log2(FLT_MAX_EXP))+1;
- const uint32_t frac_bits = 32-1-exp_bits;
- const uint32_t payload_bits = frac_bits-1;
- const uint32_t frac_mask = ((uint32_t)pow(2, frac_bits))-1; /* upper bit is for quiet/signaning nans */
- const uint32_t payload_mask = ((uint32_t)pow(2, payload_bits))-1; /* upper bit is for quiet/signaning nans */
- (void)printf("exp_bits=%d, frac_bits=%d, frac_mask=%lx, payload_bits=%d, payload_mask=%lx\n",
- exp_bits,
- frac_bits,
- (unsigned long)frac_mask,
- payload_bits,
- (unsigned long)payload_mask);
- (void)printf("frcmsk:\t" ); print_bits_32(frac_mask); (void)printf("\n");
- (void)printf("paymsk:\t" ); print_bits_32(payload_mask);(void)printf("\n");
- val = +NAN;
- *xp |= 0x01;
- (void)printf("+NAN/0x01:\t" ); print_bits_32(*xp); (void)printf("\tval=%f\n", val);
- val = -NAN;
- *xp |= 0x01;
- (void)printf("-NAN/0x01:\t" ); print_bits_32(*xp); (void)printf("\tval=%f\n", val);
- /*
- * basic test
- * IEEE 764-2008 floating-point types must have a non-zero
- * payload, otherwise they turn into an |inf|
- */
- for (i=0 ; i <= frac_mask ; i++)
- {
- volatile uint32_t *bitval_ptr = ((volatile uint32_t *)&val);
- val = NAN;
- *bitval_ptr &= ~payload_mask;
- *bitval_ptr |= (i & payload_mask);
- if (!isnan(val))
- (void)printf("FAIL: %f not a nan for %ld\n", val, (long)i);
- if (isinf(val))
- (void)printf("FAIL: %f is a inf for %ld\n", val, (long)i);
- }
- /* tests for type casting */
- {
- flt_binary32 fval;
- fval = -NAN;
- SET_NAN_PAYLOAD_FLOAT(&fval, 667);
- (void)printf("flt: val with -NAN667=%f\n", fval);
- (void)printf("flt: payload of -NAN667=%d\n", (int)GET_NAN_PAYLOAD_FLOAT(fval));
- }
- {
- flt_binary64 dval;
- dval = -NAN;
- SET_NAN_PAYLOAD_DOUBLE(&dval, 667);
- (void)printf("dbl: val with -NAN667=%f\n", dval);
- (void)printf("dbl: payload of -NAN667=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE(dval));
- (void)printf("dbl: payload of sys_cast float(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_FLOAT((flt_binary32)dval));
- (void)printf("dbl: payload of own_cast float(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_FLOAT(CAST_DBL2FLT(dval)));
- }
- {
- #if GCC__FLOAT128
- __float128 ldval;
- #else
- long double ldval;
- #endif
- ldval = -NAN;
- SET_NAN_PAYLOAD_LONGDOUBLE(&ldval, 667);
- (void)printf("ldbl: val with -NAN667=%Lf\n", FLT1282LDBL(ldval));
- (void)printf("ldbl: payload of -NAN667=%lu\n", (unsigned long)GET_NAN_PAYLOAD_LONGDOUBLE(ldval));
- (void)printf("ldbl: payload of sys_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE((flt_binary64)ldval));
- (void)printf("ldbl: payload of own_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE(CAST_LDBL2DBL(ldval)));
- }
- #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
- /* special version of i387 */
- {
- flt_binary80 ldval;
- ldval = -NAN;
- set_nan_payload_binary80_i387(&ldval, 667);
- (void)printf("ldbl(i387): val with -NAN667=%Lf\n", ldval);
- (void)printf("ldbl(i387): payload of -NAN667=%lu\n", (unsigned long)get_nan_payload_binary80(ldval));
- (void)printf("ldbl(i387): payload of -NAN667=%lu (i387)\n", (unsigned long)get_nan_payload_binary80_i387(ldval));
- (void)printf("ldbl(i387): payload of sys_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE((flt_binary64)ldval));
- (void)printf("ldbl(i387): payload of own_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE(cast_binary80_to_binary64(ldval)));
- }
- #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
- {
- float f;
- double d;
- long double ld;
- f = NAN; (void)printf("flt: payload of plain NAN=%ld\n", (long)GET_NAN_PAYLOAD_FLOAT(f));
- d = NAN; (void)printf("dbl: payload of plain NAN=%ld\n", (long)GET_NAN_PAYLOAD_DOUBLE(d));
- ld = NAN; (void)printf("ldbl: payload of plain NAN=%ld\n", (long)GET_NAN_PAYLOAD_LONGDOUBLE(ld));
- f = nanf(""); (void)printf("flt: payload of plain nanf("")=%lx\n", (long)GET_NAN_PAYLOAD_FLOAT(f));
- d = nan(""); (void)printf("dbl: payload of plain nan("")=%lx\n", (long)GET_NAN_PAYLOAD_DOUBLE(d));
- ld = nanl(""); (void)printf("ldbl: payload of plain nanl("")=%lx\n", (long)GET_NAN_PAYLOAD_LONGDOUBLE(ld));
- f = sinf(INFINITY); (void)printf("flt: payload of nan=%f from sinf(inf)=%lx\n", f, (long)GET_NAN_PAYLOAD_FLOAT(f));
- d = sin(INFINITY); (void)printf("dbl: payload of nan=%f from sin(inf)=%lx\n", d, (long)GET_NAN_PAYLOAD_DOUBLE(d));
- ld = sinl(INFINITY); (void)printf("ldbl: payload of nan=%Lf from sinl(inf)=%lx\n", FLT1282LDBL(ld), (long)GET_NAN_PAYLOAD_LONGDOUBLE(ld));
- }
- return(EXIT_SUCCESS);
- }
- + for i in *
- + cat nan_payload_test1_expected_output_x86_64bit.out
- orig: 01111111110000000000000000000000 val=nan
- exp_bits=8, frac_bits=23, frac_mask=7fffff, payload_bits=22, payload_mask=3fffff
- frcmsk: 00000000011111111111111111111111
- paymsk: 00000000001111111111111111111111
- +NAN/0x01: 01111111110000000000000000000001 val=nan
- -NAN/0x01: 11111111110000000000000000000001 val=-nan
- flt: val with -NAN667=-nan
- flt: payload of -NAN667=667
- dbl: val with -NAN667=-nan
- dbl: payload of -NAN667=667
- dbl: payload of sys_cast float(-NAN667)=0
- dbl: payload of own_cast float(-NAN667)=667
- ldbl: val with -NAN667=-nan
- ldbl: payload of -NAN667=667
- ldbl: payload of sys_cast double(-NAN667)=0
- ldbl: payload of own_cast double(-NAN667)=667
- ldbl(i387): val with -NAN667=-nan
- ldbl(i387): payload of -NAN667=667
- ldbl(i387): payload of -NAN667=667 (i387)
- ldbl(i387): payload of sys_cast double(-NAN667)=0
- ldbl(i387): payload of own_cast double(-NAN667)=667
- flt: payload of plain NAN=0
- dbl: payload of plain NAN=0
- ldbl: payload of plain NAN=0
- flt: payload of plain nanf()=0
- dbl: payload of plain nan()=0
- ldbl: payload of plain nanl()=0
- flt: payload of nan=-nan from sinf(inf)=0
- dbl: payload of nan=-nan from sin(inf)=0
- ldbl: payload of nan=-nan from sinl(inf)=0
nan_payload_probe code
Posted by Anonymous on Mon 12th Jun 2023 18:41
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.