pastebin - collaborative debugging tool
rovema.kpaste.net RSS


nan_payload_probe code
Posted by Anonymous on Mon 12th Jun 2023 18:41
raw | new post

  1. + for i in *
  2. + cat Makefile
  3. #
  4. # Makefile for nan_payload_probe code
  5. #
  6.  
  7. SHELL=/usr/bin/ksh93
  8.  
  9. nanpayload.h: nanpayload.sh
  10.         ksh93 nanpayload.sh
  11.         rm tmp_nanpayload_sh_generator tmp_nanpayload_sh_generator.c
  12.  
  13. nan_payload_test1: nan_payload_test1.c nan_payload_probe.c nan_payload_probe.h nanpayload.h
  14.         gcc nan_payload_probe.c -Wall -g nan_payload_test1.c -lm -o nan_payload_test1
  15.  
  16. tests: nan_payload_test1
  17.         diff -u nan_payload_test1_expected_output_x86_64bit.out <( ./nan_payload_test1 ) && echo "test OK"
  18.        
  19. clean:
  20.         rm -f \
  21.                 nanpayload.h \
  22.                 nan_payload_test1
  23.  
  24. # EOF.
  25. + for i in *
  26. + cat nan_payload_probe.c
  27. /***********************************************************************
  28. *                                                                      *
  29. *               This software is part of the ast package               *
  30. *            Copyright (c) 2013 AT&T Intellectual Property             *
  31. *                      and is licensed under the                       *
  32. *                  Common Public License, Version 1.0                  *
  33. *                    by AT&T Intellectual Property                     *
  34. *                                                                      *
  35. *                A copy of the License is available at                 *
  36. *            http://www.opensource.org/licenses/cpl1.0.txt             *
  37. *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
  38. *                                                                      *
  39. *              Information and Software Systems Research               *
  40. *                            AT&T Research                             *
  41. *                           Florham Park NJ                            *
  42. *                                                                      *
  43. *              Roland Mainz <roland.mainz@nrubsig.org>                 *
  44. *                                                                      *
  45. ***********************************************************************/
  46.  
  47. #include <stdlib.h>
  48. #include <stdio.h>
  49. #include <string.h>
  50.  
  51. #include "nan_payload_probe.h"
  52.  
  53. void set_nan_payload_binary32(flt_binary32 *val, uint32_t payload)
  54. {
  55.         if (payload == 0)
  56.                 return;
  57.         if (!isnanf(*val))
  58.                 return;
  59.  
  60.         uint32_t bitval;
  61.         (void)memcpy(&bitval, val, sizeof(bitval));
  62.  
  63.         bitval &= ~NANPAYLOAD_FLT_PAYLOAD_MASK;
  64.         bitval |= (payload & NANPAYLOAD_FLT_PAYLOAD_MASK);
  65.        
  66.         (void)memcpy(val, &bitval, sizeof(*val));
  67. }
  68.  
  69.  
  70. uint32_t get_nan_payload_binary32(flt_binary32 x)
  71. {
  72.         uint32_t payload;
  73.  
  74.         if (!isnanf(x))
  75.                 return(0);
  76.  
  77.         uint32_t bitval;
  78.         (void)memcpy(&bitval, &x, sizeof(bitval));
  79.  
  80.         payload = bitval & NANPAYLOAD_FLT_PAYLOAD_MASK;
  81.  
  82.         return(payload);
  83. }
  84.  
  85.  
  86. void set_nan_payload_binary64(flt_binary64 *val, uint64_t payload)
  87. {
  88.         if (payload == 0)
  89.                 return;
  90.         if (!isnan(*val))
  91.                 return;
  92.  
  93.         uint64_t bitval;
  94.         (void)memcpy(&bitval, val, sizeof(bitval));
  95.  
  96.         bitval &= ~NANPAYLOAD_DBL_PAYLOAD_MASK;
  97.         bitval |= (payload & NANPAYLOAD_DBL_PAYLOAD_MASK);
  98.  
  99.         (void)memcpy(val, &bitval, sizeof(*val));
  100. }
  101.  
  102.  
  103. uint64_t get_nan_payload_binary64(flt_binary64 x)
  104. {
  105.         uint64_t payload;
  106.  
  107.         if (!isnan(x))
  108.                 return(0ULL);
  109.  
  110.         uint64_t bitval;
  111.         (void)memcpy(&bitval, &x, sizeof(bitval));
  112.  
  113.         payload = bitval & NANPAYLOAD_DBL_PAYLOAD_MASK;
  114.  
  115.         return(payload);
  116. }
  117.  
  118.  
  119. #ifdef _typ___int128_t
  120. #if NAN_PAYLOAD_LDBL_BITS == 128
  121. void set_nan_payload_binary128(flt_binary128 *val, __int128_t payload)
  122. #elif NAN_PAYLOAD_LDBL_BITS == 80
  123. void set_nan_payload_binary80(flt_binary80 *val, uint64_t payload)
  124. #endif
  125. {
  126.         if (payload == 0)
  127.                 return;
  128.         if (!isnanl(*val))
  129.                 return;
  130.  
  131.         __int128_t bitval;
  132.         (void)memcpy(&bitval, val, sizeof(bitval));
  133.  
  134.         /*
  135.          * The i387 FPU extended precision format defines one extra
  136.          * magic bit between exponent and fraction.
  137.          * The layout looks like this:
  138.          * <sign(1bit)><exponent(15bit)><magic(1bit)><fraction(63bit)>
  139.          */
  140.         bitval &= ~NANPAYLOAD_LDBL_PAYLOAD_MASK;
  141.         bitval |= (payload & NANPAYLOAD_LDBL_PAYLOAD_MASK);
  142.  
  143.         (void)memcpy(val, &bitval, sizeof(*val));
  144. }
  145.  
  146.  
  147. #if NAN_PAYLOAD_LDBL_BITS == 128
  148. __int128_t get_nan_payload_binary128(flt_binary128 x)
  149. #elif NAN_PAYLOAD_LDBL_BITS == 80
  150. uint64_t get_nan_payload_binary80(flt_binary80 x)
  151. #endif
  152. {
  153. #if NAN_PAYLOAD_LDBL_BITS == 128
  154.         __int128_t payload;
  155. #else
  156.         uint64_t payload;
  157. #endif
  158.         if (!isnanl(x))
  159.                 return(0);
  160.  
  161.         __int128_t bitval;
  162.         (void)memcpy(&bitval, &x, sizeof(bitval));
  163.  
  164.         payload = bitval & NANPAYLOAD_LDBL_PAYLOAD_MASK;
  165.  
  166.         return(payload);
  167. }
  168. #endif /* _typ___int128_t */
  169.  
  170.  
  171. #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
  172. void set_nan_payload_binary80_i387(flt_binary80 *val, uint64_t payload)
  173. {
  174.         if (payload == 0)
  175.                 return;
  176.         if (!isnanl(*val))
  177.                 return;
  178.  
  179.         /*
  180.          * This is a bit of a hack, we access only the first 64bit data
  181.          * of a 64bit data type
  182.          */
  183.         uint64_t bitval;
  184.         (void)memcpy(&bitval, val, sizeof(bitval));
  185.  
  186.         bitval &= ~NANPAYLOAD_LDBL_PAYLOAD_MASK;
  187.         bitval |= (payload & NANPAYLOAD_LDBL_PAYLOAD_MASK);
  188.  
  189.         (void)memcpy(val, &bitval, sizeof(uint64_t));
  190. }
  191.  
  192.  
  193. uint64_t get_nan_payload_binary80_i387(flt_binary80 x)
  194. {
  195.         uint64_t payload;
  196.  
  197.         if (!isnanl(x))
  198.                 return(0);
  199.  
  200.         uint64_t bitval;
  201.         (void)memcpy(&bitval, &x, sizeof(bitval));
  202.  
  203.         payload = bitval & NANPAYLOAD_LDBL_PAYLOAD_MASK;
  204.  
  205.         return(payload);
  206. }
  207. #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
  208.  
  209.  
  210. flt_binary32 cast_binary64_to_binary32(flt_binary64 d)
  211. {
  212.         flt_binary32 f;
  213.  
  214.         if (isnan(d))
  215.         {
  216.                 uint64_t payload;
  217.  
  218.                 payload = get_nan_payload_binary64(d);
  219.                 f = (flt_binary32)d;
  220.  
  221.                 set_nan_payload_binary32(&f, payload);
  222.         }
  223.         else
  224.         {
  225.                 f = (flt_binary32)d;
  226.         }
  227.  
  228.         return(f);
  229. }
  230.  
  231. #if NAN_PAYLOAD_LDBL_BITS == 128
  232. flt_binary128 cast_binary64_to_binary128(flt_binary64 d)
  233. {
  234.         flt_binary128 ld;
  235.  
  236.         if (isnan(d))
  237.         {
  238.                 __int128_t payload;
  239.  
  240.                 payload = get_nan_payload_binary64(d);
  241.                 ld = (flt_binary128)d;
  242.  
  243.                 set_nan_payload_binary128(&ld, payload);
  244.         }
  245.         else
  246.         {
  247.                 ld = (flt_binary128)d;
  248.         }
  249.  
  250.         return(ld);
  251. }
  252.  
  253.  
  254. #elif NAN_PAYLOAD_LDBL_BITS == 80
  255.  
  256.  
  257. flt_binary80 cast_binary64_to_binary80(flt_binary64 d)
  258. {
  259.         flt_binary80 ld;
  260.  
  261.         if (isnan(d))
  262.         {
  263.                 uint64_t payload;
  264.  
  265.                 payload = get_nan_payload_binary64(d);
  266.                 ld = (flt_binary80)d;
  267.  
  268.                 set_nan_payload_binary80(&ld, payload);
  269.         }
  270.         else
  271.         {
  272.                 ld = (flt_binary80)d;
  273.         }
  274.  
  275.         return(ld);
  276. }
  277. #endif /* NAN_PAYLOAD_LDBL_BITS == 80 */
  278.  
  279.  
  280. flt_binary64 cast_binary32_to_binary64(flt_binary32 f)
  281. {
  282.         flt_binary64 d;
  283.  
  284.         if (isnanf(f))
  285.         {
  286.                 uint32_t payload;
  287.  
  288.                 payload = get_nan_payload_binary32(f);
  289.                 d = (flt_binary64)f;
  290.  
  291.                 set_nan_payload_binary64(&d, payload);
  292.         }
  293.         else
  294.         {
  295.                 d = (flt_binary64)f;
  296.         }
  297.  
  298.         return(d);
  299. }
  300.  
  301.  
  302. #if NAN_PAYLOAD_LDBL_BITS == 128
  303. flt_binary128 cast_binary32_to_binary128(flt_binary32 f)
  304. {
  305.         flt_binary128 ld;
  306.  
  307.         if (isnanf(f))
  308.         {
  309.                 uint32_t payload;
  310.  
  311.                 payload = get_nan_payload_binary32(f);
  312.                 ld = (flt_binary128)f;
  313.  
  314.                 set_nan_payload_binary128(&ld, payload);
  315.         }
  316.         else
  317.         {
  318.                 ld = (flt_binary128)f;
  319.         }
  320.  
  321.         return(ld);
  322. }
  323.  
  324.  
  325. flt_binary32 cast_binary128_to_binary32(flt_binary128 ld)
  326. {
  327.         flt_binary32 f;
  328.  
  329.         if (isnanl(ld))
  330.         {
  331.                 __int128_t payload;
  332.  
  333.                 payload = get_nan_payload_binary128(ld);
  334.                 f = (flt_binary32)ld;
  335.  
  336.                 set_nan_payload_binary32(&f, payload);
  337.         }
  338.         else
  339.         {
  340.                 f = (flt_binary32)ld;
  341.         }
  342.  
  343.         return(f);
  344. }
  345.  
  346.  
  347. flt_binary64 cast_binary128_to_binary64(flt_binary128 ld)
  348. {
  349.         flt_binary64 d;
  350.  
  351.         if (isnanl(ld))
  352.         {
  353.                 __int128_t payload;
  354.  
  355.                 payload = get_nan_payload_binary128(ld);
  356.                 d = (flt_binary64)ld;
  357.  
  358.                 set_nan_payload_binary64(&d, payload);
  359.         }
  360.         else
  361.         {
  362.                 d = (flt_binary64)ld;
  363.         }
  364.  
  365.         return(d);
  366. }
  367.  
  368.  
  369. #elif NAN_PAYLOAD_LDBL_BITS == 80
  370.  
  371.  
  372. flt_binary80 cast_binary32_to_binary80(flt_binary32 f)
  373. {
  374.         flt_binary80 ld;
  375.  
  376.         if (isnanf(f))
  377.         {
  378.                 uint32_t payload;
  379.  
  380.                 payload = get_nan_payload_binary32(f);
  381.                 ld = (flt_binary80)f;
  382.  
  383.                 set_nan_payload_binary80(&ld, payload);
  384.         }
  385.         else
  386.         {
  387.                 ld = (flt_binary80)f;
  388.         }
  389.  
  390.         return(ld);
  391. }
  392.  
  393.  
  394. flt_binary32 cast_binary80_to_binary32(flt_binary80 ld)
  395. {
  396.         flt_binary32 f;
  397.  
  398.         if (isnanl(ld))
  399.         {
  400.                 uint64_t payload;
  401.  
  402.                 payload = get_nan_payload_binary80(ld);
  403.                 f = (flt_binary32)ld;
  404.  
  405.                 set_nan_payload_binary32(&f, payload);
  406.         }
  407.         else
  408.         {
  409.                 f = (flt_binary32)ld;
  410.         }
  411.  
  412.         return(f);
  413. }
  414.  
  415.  
  416. flt_binary64 cast_binary80_to_binary64(flt_binary80 ld)
  417. {
  418.         flt_binary64 d;
  419.  
  420.         if (isnanl(ld))
  421.         {
  422.                 uint64_t payload;
  423.  
  424.                 payload = get_nan_payload_binary80(ld);
  425.                 d = (flt_binary64)ld;
  426.  
  427.                 set_nan_payload_binary64(&d, payload);
  428.         }
  429.         else
  430.         {
  431.                 d = (flt_binary64)ld;
  432.         }
  433.  
  434.         return(d);
  435. }
  436. #endif /* NAN_PAYLOAD_LDBL_BITS == 80 */
  437. + for i in *
  438. + cat nan_payload_probe.h
  439. /***********************************************************************
  440. *                                                                      *
  441. *               This software is part of the ast package               *
  442. *            Copyright (c) 2013 AT&T Intellectual Property             *
  443. *                      and is licensed under the                       *
  444. *                  Common Public License, Version 1.0                  *
  445. *                    by AT&T Intellectual Property                     *
  446. *                                                                      *
  447. *                A copy of the License is available at                 *
  448. *            http://www.opensource.org/licenses/cpl1.0.txt             *
  449. *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
  450. *                                                                      *
  451. *              Information and Software Systems Research               *
  452. *                            AT&T Research                             *
  453. *                           Florham Park NJ                            *
  454. *                                                                      *
  455. *              Roland Mainz <roland.mainz@nrubsig.org>                 *
  456. *                                                                      *
  457. ***********************************************************************/
  458.  
  459. #ifndef NAN_PAYLOAD_PROBE_H
  460. #define NAN_PAYLOAD_PROBE_H 1
  461.  
  462. #include <stdint.h>
  463. #include <math.h>
  464. #include <float.h>
  465. #include <limits.h>
  466.  
  467. #if (__STDC_VERSION__ - 0) < 199901L
  468. #error Requires ISO C99 or gcc GNU99 mode
  469. #endif
  470.  
  471. #ifndef _typ___int128_t
  472. #ifdef __SIZEOF_INT128__
  473. #define _typ___int128_t 1
  474. #endif
  475. #endif
  476.  
  477. /* use |__float128| on gcc/x86 for testing */
  478. #if defined(__amd64)
  479. //#define GCC__FLOAT128 1
  480. #endif
  481.  
  482. #include "nanpayload.h"
  483.  
  484. /*
  485.  * map C types to aliases which define their physical layout
  486.  * The mapping type names are derived from IEEE754-2008 with
  487.  * |flt_| as prefix to avoid collisions with other software
  488.  */
  489. typedef float           flt_binary32;
  490. typedef double          flt_binary64;
  491. #if defined(__i386) || defined(__amd64)
  492. #if (NAN_PAYLOAD_LDBL_BITS == 128)
  493. typedef __float128      flt_binary128;
  494. #else
  495. typedef long double     flt_binary80;
  496. #endif
  497. #else
  498. #if (NAN_PAYLOAD_LDBL_BITS == 128)
  499. typedef long double     flt_binary128;
  500. #elif (NAN_PAYLOAD_LDBL_BITS == 64)
  501. #error |long double| == |double| not implemented yet
  502. #else
  503. #error Unsupported NAN_PAYLOAD_LDBL_BITS
  504. #endif
  505. #endif
  506.  
  507.  
  508.  
  509. #if 1 /* prototypes */
  510. void            set_nan_payload_binary32(flt_binary32 *val, uint32_t payload);
  511. uint32_t        get_nan_payload_binary32(flt_binary32 x);
  512. void            set_nan_payload_binary64(flt_binary64 *val, uint64_t payload);
  513. uint64_t        get_nan_payload_binary64(flt_binary64 x);
  514. #if NAN_PAYLOAD_LDBL_BITS == 128
  515. void            set_nan_payload_binary128(flt_binary128 *val, __int128_t payload);
  516. __int128_t      get_nan_payload_binary128(flt_binary128 x);
  517. #elif NAN_PAYLOAD_LDBL_BITS == 80
  518. #ifdef _typ___int128_t
  519. void            set_nan_payload_binary80(flt_binary80 *val, uint64_t payload);
  520. uint64_t        get_nan_payload_binary80(flt_binary80 x);
  521. #else
  522. #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
  523. #define set_nan_payload_binary80(v, p)  set_nan_payload_binary80_i387((v), (p))
  524. #define get_nan_payload_binary80(v)     get_nan_payload_binary80_i387(v)
  525. #endif
  526. #endif /* _typ___int128_t */
  527. #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
  528. void            set_nan_payload_binary80_i387(flt_binary80 *val, uint64_t payload);
  529. uint64_t        get_nan_payload_binary80_i387(flt_binary80 x);
  530. #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
  531. #endif
  532.  
  533. flt_binary32    cast_binary64_to_binary32(flt_binary64 d);
  534. #if NAN_PAYLOAD_LDBL_BITS == 128
  535. flt_binary128   cast_binary64_to_binary128(flt_binary64 d);
  536. #elif NAN_PAYLOAD_LDBL_BITS == 80
  537. flt_binary80    cast_binary64_to_binary80(flt_binary64 d);
  538. #endif /* NAN_PAYLOAD_LDBL_BITS == 128 */
  539. flt_binary64    cast_binary32_to_binary64(flt_binary32 f);
  540. #if NAN_PAYLOAD_LDBL_BITS == 128
  541. flt_binary128   cast_binary32_to_binary128(flt_binary32 f);
  542. flt_binary32    cast_binary128_to_binary32(flt_binary128 ld);
  543. flt_binary64    cast_binary128_to_binary64(flt_binary128 ld);
  544. #elif NAN_PAYLOAD_LDBL_BITS == 80
  545. flt_binary80    cast_binary32_to_binary80(flt_binary32 f);
  546. flt_binary32    cast_binary80_to_binary32(flt_binary80 ld);
  547. flt_binary64    cast_binary80_to_binary64(flt_binary80 ld);
  548. #endif /* NAN_PAYLOAD_LDBL_BITS == 128 */
  549. #endif /* prototypes */
  550.  
  551.  
  552. /*
  553.  * External API:
  554.  *
  555.  * |flt_binary@(32|64|80|128)| to ISO C type mappings
  556.  */
  557. #define CAST_FLT2DBL(f)         cast_binary32_to_binary64(f)
  558. #define CAST_DBL2FLT(f)         cast_binary64_to_binary32(f)
  559. #if (NAN_PAYLOAD_LDBL_BITS == 128)
  560. #define CAST_FLT2LDBL(f)        cast_binary32_to_binary128(f)
  561. #define CAST_DBL2LDBL(f)        cast_binary64_to_binary128(f)
  562. #define CAST_LDBL2FLT(f)        cast_binary128_to_binary32(f)
  563. #define CAST_LDBL2DBL(f)        cast_binary128_to_binary64(f)
  564. #elif (NAN_PAYLOAD_LDBL_BITS == 80)
  565. #define CAST_FLT2LDBL(f)        cast_binary32_to_binary80(f)
  566. #define CAST_DBL2LDBL(f)        cast_binary64_to_binary80(f)
  567. #define CAST_LDBL2FLT(f)        cast_binary80_to_binary32(f)
  568. #define CAST_LDBL2DBL(f)        cast_binary80_to_binary64(f)
  569. #else
  570. #error Unsupported NAN_PAYLOAD_LDBL_BITS value
  571. #endif
  572.  
  573. /*
  574.  * get payload
  575.  */
  576. #define GET_NAN_PAYLOAD_FLOAT(f)        get_nan_payload_binary32(f)
  577. #define GET_NAN_PAYLOAD_DOUBLE(d)       get_nan_payload_binary64(d)
  578. #if (NAN_PAYLOAD_LDBL_BITS == 128)
  579. #define GET_NAN_PAYLOAD_LONGDOUBLE(ld)  get_nan_payload_binary128(ld)
  580. #elif (NAN_PAYLOAD_LDBL_BITS == 80)
  581. #define GET_NAN_PAYLOAD_LONGDOUBLE(ld)  get_nan_payload_binary80(ld)
  582. #endif
  583.  
  584. /*
  585.  * set payload
  586.  */
  587. #define SET_NAN_PAYLOAD_FLOAT(val, payload) set_nan_payload_binary32((val), (payload))
  588. #define SET_NAN_PAYLOAD_DOUBLE(val, payload) set_nan_payload_binary64((val), (payload))
  589. #if (NAN_PAYLOAD_LDBL_BITS == 128)
  590. #define SET_NAN_PAYLOAD_LONGDOUBLE(val, payload) set_nan_payload_binary128((val), (payload))
  591. #elif (NAN_PAYLOAD_LDBL_BITS == 80)
  592. #define SET_NAN_PAYLOAD_LONGDOUBLE(val, payload) set_nan_payload_binary80((val), (payload))
  593. #endif
  594.  
  595.  
  596.  
  597. /*
  598.  * Notes about portablity:
  599.  * - The ISO C99 standards supports a portable way to write the
  600.  *   payload of a quiet NaN in ISO C.
  601.  *
  602.  * - The |nan()|/|nanf()|/|nanl()| functions (from <math.h>, see
  603.  *   section 7.12.11.2 in the ISO C99 spec) accept strings as
  604.  *   arguments.
  605.  *
  606.  * - |strtof()|/|strtod()|/|strtold()| functions (from <stdlib.h>,
  607.  *   see section 7.20.1.3) accept strings in the form
  608.  *   "NAN(character sequence)".
  609.  *
  610.  * - |fscanf()|+|sscanf()| follow |strtod()|
  611.  *
  612.  * - the character sequence in "NAN(character sequence)" is
  613.  *   interpreted in an (libc+compiler) implementation-specific
  614.  *   way (=not portable).
  615.  *
  616.  * - The actual bit layout can differ from the recommended IEEE754-2008
  617.  *   layout. For now we do not care about these special cases except
  618.  *   the 80bit i387 FPU format (mc68881/2 *may* require similar
  619.  *   attention) - see below...
  620.  *
  621.  * - The i387 FPU extended precision format defines one extra
  622.  *   magic bit between exponent and fraction.
  623.  *   The layout looks like this:
  624.  *   <sign(1bit)><exponent(15bit)><magic(1bit)><fraction(63bit)>
  625.  *
  626.  * - The |long double| code relies on |__int128_t| which is a
  627.  *   gcc+clang extension. It seems |__SIZEOF_INT128__| can be
  628.  *   reliably used (since gcc4.x; some platforms have more or less
  629.  *   working |__int128_t| since gcc 3.4 but there is no way to test
  630.  *   the completeness) to test whether the type is available:
  631.  *   -- snip --
  632.  *   $ gcc -E -dM -x c '/dev/null' | fgrep '128'
  633.  *   #define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
  634.  *   #define __DEC128_EPSILON__ 1E-33DL
  635.  *   #define __DEC128_MIN__ 1E-6143DL
  636.  *   #define __DEC128_MIN_EXP__ (-6142)
  637.  *   #define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
  638.  *   #define __FLT_MAX_EXP__ 128
  639.  *   #define __SIZEOF_INT128__ 16
  640.  *   #define __DEC128_MAX_EXP__ 6145
  641.  *   #define __DEC128_MANT_DIG__ 34
  642.  *   $ clang -E -dM -x c /dev/null | fgrep 128
  643.  *   #define __FLT_MAX_EXP__ 128
  644.  *   #define __SIZEOF_INT128__ 16
  645.  *   -- snip --
  646.  *
  647.  */
  648.  
  649. #endif /* NAN_PAYLOAD_PROBE_H */
  650. + for i in *
  651. + cat nanpayload.sh
  652. ########################################################################
  653. #                                                                      #
  654. #               This software is part of the ast package               #
  655. #                   Copyright (c) 2013 Roland Mainz                    #
  656. #                      and is licensed under the                       #
  657. #                 Eclipse Public License, Version 1.0                  #
  658. #                    by AT&T Intellectual Property                     #
  659. #                                                                      #
  660. #                A copy of the License is available at                 #
  661. #          http://www.eclipse.org/org/documents/epl-v10.html           #
  662. #         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
  663. #                                                                      #
  664. #                                                                      #
  665. #                 Roland Mainz <roland.mainz@nrubsig.org>              #
  666. #                                                                      #
  667. ########################################################################
  668.  
  669. #
  670. # Copyright (c) 2013, Roland Mainz. All rights reserved.
  671. #
  672.  
  673. #
  674. # nanpayload.sh - generate nanpayload.h
  675. #
  676.  
  677. cat >'tmp_nanpayload_sh_generator.c' <<ENDOFTEXT
  678.  
  679. /* Generated from nanpayload.sh - DO NOT EDIT */
  680.  
  681. #include <stdio.h>
  682. #include <stdint.h>
  683. #include <math.h>
  684. #include <float.h>
  685. #include <limits.h>
  686.  
  687. /*
  688.  * NAN_PAYLOAD_LDBL_BITS:
  689.  * 80 for AMD64, 128 on SPARC, xxx on other platforms
  690.  */
  691. #ifndef LDBL_MAX_EXP
  692. #error LDBL_MAX_EXP not available
  693. #endif
  694.  
  695. #if LDBL_MAX_EXP == 1024
  696. #define NAN_PAYLOAD_LDBL_BITS 64 /* this happens if |long double| is the same as |double| */
  697. #elif LDBL_MAX_EXP == 16384
  698. #define NAN_PAYLOAD_LDBL_BITS 80
  699. #elif LDBL_MAX_EXP > 16384
  700. #define NAN_PAYLOAD_LDBL_BITS 128
  701. #else
  702. #error Unsupported LDBL_MAX_EXP (cannot calculate |long double| bit size)
  703. #endif
  704.  
  705. int main(int ac, char *av[])
  706. {
  707.         (void)printf("#ifndef NANPAYLOAD_H\n");
  708.         (void)printf("#define NANPAYLOAD_H 1\n");
  709.         (void)printf("\n");
  710.  
  711.         (void)printf("/* Generated from nanpayload.sh - DO NOT EDIT */\n\n");
  712.  
  713.         (void)printf("#define NAN_PAYLOAD_LDBL_BITS %lu\n\n", (long)NAN_PAYLOAD_LDBL_BITS);
  714.  
  715.         {
  716.                 const uint32_t exp_bits         = (uint32_t)log2f(FLT_MAX_EXP)+1;
  717.                 const uint32_t frac_bits        = 32-1-exp_bits;
  718.                 const uint32_t payload_bits     = frac_bits-1; /* one bit for quiet/signaling nan */
  719.                 const uint32_t payload_mask     = ((uint32_t)powf(2, payload_bits))-1;
  720.  
  721.                 (void)printf("#define NANPAYLOAD_FLT_EXP_BITS\t%lu\n",          (unsigned long)exp_bits);
  722.                 (void)printf("#define NANPAYLOAD_FLT_FRAC_BITS\t%lu\n",         (unsigned long)frac_bits);
  723.                 (void)printf("#define NANPAYLOAD_FLT_PAYLOAD_BITS\t%lu\n",      (unsigned long)payload_bits);
  724.                 (void)printf("#define NANPAYLOAD_FLT_PAYLOAD_MASK\t0x%lx\n",    (unsigned long)payload_mask);
  725.                 (void)printf("\n");
  726.         }
  727.  
  728.         {
  729.                 const uint64_t exp_bits         = (uint64_t)log2(DBL_MAX_EXP)+1;
  730.                 const uint64_t frac_bits        = 64-1-exp_bits;
  731.                 const uint64_t payload_bits     = frac_bits-1; /* one bit for quiet/signaling nan */
  732.                 const uint64_t payload_mask     = ((uint64_t)pow(2, payload_bits))-1;
  733.  
  734.                 (void)printf("#define NANPAYLOAD_DBL_EXP_BITS\t%llu\n",         (unsigned long long)exp_bits);
  735.                 (void)printf("#define NANPAYLOAD_DBL_FRAC_BITS\t%llu\n",        (unsigned long long)frac_bits);
  736.                 (void)printf("#define NANPAYLOAD_DBL_PAYLOAD_BITS\t%llu\n",     (unsigned long long)payload_bits);
  737.                 (void)printf("#define NANPAYLOAD_DBL_PAYLOAD_MASK\t0x%llx\n",   (unsigned long long)payload_mask);
  738.                 (void)printf("\n");
  739.         }
  740.  
  741.         {
  742. #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) && (!_typ___int128_t)
  743.                 const uint64_t exp_bits         = log2l(LDBL_MAX_EXP)+1;
  744.                 const uint64_t frac_bits        = 63;
  745.                 const uint64_t payload_bits     = frac_bits-1;
  746.                 const uint64_t payload_mask     = ((uint64_t)powl(2, payload_bits))-1;
  747.  
  748.                 (void)printf("#define NANPAYLOAD_LDBL_EXP_BITS\t%llu\n",        (unsigned long long)exp_bits);
  749.                 (void)printf("#define NANPAYLOAD_LDBL_FRAC_BITS\t%llu\n",       (unsigned long long)frac_bits);
  750.                 (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_BITS\t%llu\n",    (unsigned long long)payload_bits);
  751.                 (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_MASK\t0x%llx\n",  (unsigned long long)payload_mask);
  752.                 (void)printf("\n");
  753. #else
  754.                 const __int128_t exp_bits       = (__int128_t)log2l(LDBL_MAX_EXP)+1;
  755. #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
  756.                 /*
  757.                  * The i387 FPU extended precision format defines one extra
  758.                  * magic bit between exponent and fraction.
  759.                  * The layout looks like this:
  760.                  * <sign(1bit)><exponent(15bit)><magic(1bit)><fraction(63bit)>
  761.                  */
  762.                 const __int128_t frac_bits      = NAN_PAYLOAD_LDBL_BITS-1-1-exp_bits;
  763. #else
  764.                 const __int128_t frac_bits      = NAN_PAYLOAD_LDBL_BITS-1-exp_bits;
  765. #endif
  766.                 const __int128_t payload_bits   = frac_bits-1; /* one bit for quiet/signaling nan */
  767.                 const __int128_t payload_mask   = ((__int128_t)powl(2, payload_bits))-1;
  768.  
  769.                 /* fixme: How do we print |__int128_t| ? */
  770.                 (void)printf("#define NANPAYLOAD_LDBL_EXP_BITS\t%llu\n",        (unsigned long long)exp_bits);
  771.                 (void)printf("#define NANPAYLOAD_LDBL_FRAC_BITS\t%llu\n",       (unsigned long long)frac_bits);
  772.                 (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_BITS\t%llu\n",    (unsigned long long)payload_bits);
  773.                 (void)printf("#define NANPAYLOAD_LDBL_PAYLOAD_MASK\t0x%llx\n",  (unsigned long long)payload_mask);
  774.                 (void)printf("\n");
  775. #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
  776.         }
  777.  
  778.         (void)printf("\n#endif /* NANPAYLOAD_H */\n");
  779.         return (0);
  780. }
  781. ENDOFTEXT
  782.  
  783. rm -f ./tmp_nanpayload_sh_generator
  784. gcc -std=gnu99 -m64 -Wall tmp_nanpayload_sh_generator.c -o tmp_nanpayload_sh_generator -lm
  785. ./tmp_nanpayload_sh_generator >'nanpayload.h'
  786.  
  787. # EOF.
  788. + for i in *
  789. + cat nan_payload_test1.c
  790. /***********************************************************************
  791. *                                                                      *
  792. *               This software is part of the ast package               *
  793. *            Copyright (c) 2013 AT&T Intellectual Property             *
  794. *                      and is licensed under the                       *
  795. *                  Common Public License, Version 1.0                  *
  796. *                    by AT&T Intellectual Property                     *
  797. *                                                                      *
  798. *                A copy of the License is available at                 *
  799. *            http://www.opensource.org/licenses/cpl1.0.txt             *
  800. *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
  801. *                                                                      *
  802. *              Information and Software Systems Research               *
  803. *                            AT&T Research                             *
  804. *                           Florham Park NJ                            *
  805. *                                                                      *
  806. *              Roland Mainz <roland.mainz@nrubsig.org>                 *
  807. *                                                                      *
  808. ***********************************************************************/
  809.  
  810. #include <stdlib.h>
  811. #include <stdio.h>
  812.  
  813. #include "nan_payload_probe.h"
  814.  
  815.  
  816. #ifdef GCC__FLOAT128
  817. #define FLT1282LDBL(flt128) ((long double)(flt128))
  818. #else
  819. #define FLT1282LDBL(flt128) (flt128)
  820. #endif
  821.  
  822. void print_bits_32(uint32_t x)
  823. {
  824.         int i;
  825.         for (i=0 ; i < 32 ; i++)
  826.         {
  827.                 /* fixme: endian! */
  828.                 (void)printf("%d", (x & (1UL<<31))?1:0);
  829.                 x = x << 1;
  830.         }
  831. }
  832.  
  833.  
  834. void print_bits_64(uint64_t x)
  835. {
  836.         int i;
  837.         for (i=0 ; i < 64 ; i++)
  838.         {
  839.                 /* fixme: endian! */
  840.                 (void)printf("%d", (x & (1ULL<<63))?1:0);
  841.                 x = x << 1;
  842.         }
  843. }
  844.  
  845.  
  846. #ifdef _typ___int128_t
  847. void print_bits_128(__int128_t x)
  848. {
  849.         int i;
  850.         for (i=0 ; i < 128 ; i++)
  851.         {
  852.                 /* fixme: endian! */
  853.                 (void)printf("%d", (x & (((__int128_t)1)<<127))?1:0);
  854.                 x = x << 1;
  855.         }
  856. }
  857. #endif /* _typ___int128_t */
  858.  
  859.  
  860. int main(int ac, char *av[])
  861. {
  862.         volatile flt_binary32   val = NAN;
  863.         long                    i;
  864.         volatile uint32_t       *xp=(volatile uint32_t *)&val;
  865.  
  866.         (void)printf("orig:\t" ); print_bits_32(*xp); (void)printf("\tval=%f\n", val);
  867.  
  868.         const uint32_t exp_bits         = ((uint32_t)log2(FLT_MAX_EXP))+1;
  869.         const uint32_t frac_bits        = 32-1-exp_bits;
  870.         const uint32_t payload_bits     = frac_bits-1;
  871.         const uint32_t frac_mask        = ((uint32_t)pow(2, frac_bits))-1; /* upper bit is for quiet/signaning nans */
  872.         const uint32_t payload_mask     = ((uint32_t)pow(2, payload_bits))-1; /* upper bit is for quiet/signaning nans */
  873.  
  874.         (void)printf("exp_bits=%d, frac_bits=%d, frac_mask=%lx, payload_bits=%d, payload_mask=%lx\n",
  875.                 exp_bits,
  876.                 frac_bits,
  877.                 (unsigned long)frac_mask,
  878.                 payload_bits,
  879.                 (unsigned long)payload_mask);
  880.  
  881.         (void)printf("frcmsk:\t" ); print_bits_32(frac_mask);   (void)printf("\n");
  882.         (void)printf("paymsk:\t" ); print_bits_32(payload_mask);(void)printf("\n");
  883.  
  884.         val = +NAN;
  885.         *xp |= 0x01;
  886.         (void)printf("+NAN/0x01:\t" ); print_bits_32(*xp); (void)printf("\tval=%f\n", val);
  887.  
  888.         val = -NAN;
  889.         *xp |= 0x01;
  890.         (void)printf("-NAN/0x01:\t" ); print_bits_32(*xp); (void)printf("\tval=%f\n", val);
  891.  
  892.         /*
  893.          * basic test
  894.          * IEEE 764-2008 floating-point types must have a non-zero
  895.          * payload, otherwise they turn into an |inf|
  896.          */
  897.         for (i=0 ; i <= frac_mask ; i++)
  898.         {
  899.                 volatile uint32_t *bitval_ptr = ((volatile uint32_t *)&val);
  900.  
  901.                 val = NAN;
  902.                 *bitval_ptr &= ~payload_mask;
  903.                 *bitval_ptr |= (i & payload_mask);
  904.                 if (!isnan(val))
  905.                         (void)printf("FAIL: %f not a nan for %ld\n", val, (long)i);
  906.                 if (isinf(val))
  907.                         (void)printf("FAIL: %f is a inf for %ld\n", val, (long)i);
  908.         }
  909.  
  910.         /* tests for type casting */
  911.         {
  912.                 flt_binary32 fval;
  913.                 fval = -NAN;
  914.                 SET_NAN_PAYLOAD_FLOAT(&fval, 667);
  915.                 (void)printf("flt: val with -NAN667=%f\n", fval);
  916.                 (void)printf("flt: payload of -NAN667=%d\n", (int)GET_NAN_PAYLOAD_FLOAT(fval));
  917.         }
  918.  
  919.         {
  920.                 flt_binary64 dval;
  921.                 dval = -NAN;
  922.                 SET_NAN_PAYLOAD_DOUBLE(&dval, 667);
  923.                 (void)printf("dbl: val with -NAN667=%f\n", dval);
  924.                 (void)printf("dbl: payload of -NAN667=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE(dval));
  925.                 (void)printf("dbl: payload of sys_cast float(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_FLOAT((flt_binary32)dval));
  926.                 (void)printf("dbl: payload of own_cast float(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_FLOAT(CAST_DBL2FLT(dval)));
  927.         }
  928.  
  929.         {
  930. #if GCC__FLOAT128
  931.                 __float128 ldval;
  932. #else
  933.                 long double ldval;
  934. #endif
  935.  
  936.                 ldval = -NAN;
  937.                 SET_NAN_PAYLOAD_LONGDOUBLE(&ldval, 667);
  938.                 (void)printf("ldbl: val with -NAN667=%Lf\n", FLT1282LDBL(ldval));
  939.                 (void)printf("ldbl: payload of -NAN667=%lu\n", (unsigned long)GET_NAN_PAYLOAD_LONGDOUBLE(ldval));
  940.                 (void)printf("ldbl: payload of sys_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE((flt_binary64)ldval));
  941.                 (void)printf("ldbl: payload of own_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE(CAST_LDBL2DBL(ldval)));
  942.         }
  943.  
  944. #if (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80)
  945.         /* special version of i387 */
  946.         {
  947.                 flt_binary80 ldval;
  948.                 ldval = -NAN;
  949.                 set_nan_payload_binary80_i387(&ldval, 667);
  950.                 (void)printf("ldbl(i387): val with -NAN667=%Lf\n", ldval);
  951.                 (void)printf("ldbl(i387): payload of -NAN667=%lu\n", (unsigned long)get_nan_payload_binary80(ldval));
  952.                 (void)printf("ldbl(i387): payload of -NAN667=%lu (i387)\n", (unsigned long)get_nan_payload_binary80_i387(ldval));
  953.                 (void)printf("ldbl(i387): payload of sys_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE((flt_binary64)ldval));
  954.                 (void)printf("ldbl(i387): payload of own_cast double(-NAN667)=%lu\n", (unsigned long)GET_NAN_PAYLOAD_DOUBLE(cast_binary80_to_binary64(ldval)));
  955.         }
  956. #endif /* (defined(__i386) || defined(__amd64)) && (NAN_PAYLOAD_LDBL_BITS == 80) */
  957.  
  958.         {
  959.                 float           f;
  960.                 double          d;
  961.                 long double     ld;
  962.                 f  = NAN;               (void)printf("flt:  payload of plain NAN=%ld\n", (long)GET_NAN_PAYLOAD_FLOAT(f));
  963.                 d  = NAN;               (void)printf("dbl:  payload of plain NAN=%ld\n", (long)GET_NAN_PAYLOAD_DOUBLE(d));
  964.                 ld = NAN;               (void)printf("ldbl: payload of plain NAN=%ld\n", (long)GET_NAN_PAYLOAD_LONGDOUBLE(ld));
  965.                 f  = nanf("");          (void)printf("flt:  payload of plain nanf("")=%lx\n",   (long)GET_NAN_PAYLOAD_FLOAT(f));
  966.                 d  = nan("");           (void)printf("dbl:  payload of plain nan("")=%lx\n",    (long)GET_NAN_PAYLOAD_DOUBLE(d));
  967.                 ld = nanl("");          (void)printf("ldbl: payload of plain nanl("")=%lx\n",   (long)GET_NAN_PAYLOAD_LONGDOUBLE(ld));
  968.                 f  = sinf(INFINITY);    (void)printf("flt:  payload of nan=%f from sinf(inf)=%lx\n",  f,  (long)GET_NAN_PAYLOAD_FLOAT(f));
  969.                 d  = sin(INFINITY);     (void)printf("dbl:  payload of nan=%f from sin(inf)=%lx\n",   d,  (long)GET_NAN_PAYLOAD_DOUBLE(d));
  970.                 ld = sinl(INFINITY);    (void)printf("ldbl: payload of nan=%Lf from sinl(inf)=%lx\n", FLT1282LDBL(ld), (long)GET_NAN_PAYLOAD_LONGDOUBLE(ld));
  971.         }
  972.  
  973.         return(EXIT_SUCCESS);
  974. }
  975. + for i in *
  976. + cat nan_payload_test1_expected_output_x86_64bit.out
  977. orig:   01111111110000000000000000000000        val=nan
  978. exp_bits=8, frac_bits=23, frac_mask=7fffff, payload_bits=22, payload_mask=3fffff
  979. frcmsk: 00000000011111111111111111111111
  980. paymsk: 00000000001111111111111111111111
  981. +NAN/0x01:      01111111110000000000000000000001        val=nan
  982. -NAN/0x01:      11111111110000000000000000000001        val=-nan
  983. flt: val with -NAN667=-nan
  984. flt: payload of -NAN667=667
  985. dbl: val with -NAN667=-nan
  986. dbl: payload of -NAN667=667
  987. dbl: payload of sys_cast float(-NAN667)=0
  988. dbl: payload of own_cast float(-NAN667)=667
  989. ldbl: val with -NAN667=-nan
  990. ldbl: payload of -NAN667=667
  991. ldbl: payload of sys_cast double(-NAN667)=0
  992. ldbl: payload of own_cast double(-NAN667)=667
  993. ldbl(i387): val with -NAN667=-nan
  994. ldbl(i387): payload of -NAN667=667
  995. ldbl(i387): payload of -NAN667=667 (i387)
  996. ldbl(i387): payload of sys_cast double(-NAN667)=0
  997. ldbl(i387): payload of own_cast double(-NAN667)=667
  998. flt:  payload of plain NAN=0
  999. dbl:  payload of plain NAN=0
  1000. ldbl: payload of plain NAN=0
  1001. flt:  payload of plain nanf()=0
  1002. dbl:  payload of plain nan()=0
  1003. ldbl: payload of plain nanl()=0
  1004. flt:  payload of nan=-nan from sinf(inf)=0
  1005. dbl:  payload of nan=-nan from sin(inf)=0
  1006. ldbl: payload of nan=-nan from sinl(inf)=0

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at