1a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 2a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * ==================================================== 3a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 4a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * 5a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Developed at SunPro, a Sun Microsystems, Inc. business. 6a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Permission to use, copy, modify, and distribute this 7a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * software is freely granted, provided that this notice 8a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * is preserved. 9a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * ==================================================== 10a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 11a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 12a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 13a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * from: @(#)fdlibm.h 5.1 93/09/24 148cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes * $FreeBSD: head/lib/msun/src/math_private.h 276176 2014-12-24 10:13:53Z ed $ 15a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 16a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 17a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifndef _MATH_PRIVATE_H_ 18a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define _MATH_PRIVATE_H_ 19a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 20a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <sys/types.h> 21a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <machine/endian.h> 22a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 23a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 24a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * The original fdlibm code used statements like: 25a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * n0 = ((*(int*)&one)>>29)^1; * index of high word * 26a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * ix0 = *(n0+(int*)&x); * high word of x * 27a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * ix1 = *((1-n0)+(int*)&x); * low word of x * 28a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * to dig two 32 bit words out of the 64 bit IEEE floating point 29a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * value. That is non-ANSI, and, moreover, the gcc instruction 30a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * scheduler gets it wrong. We instead use the following macros. 31a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Unlike the original code, we determine the endianness at compile 32a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * time, not at run time; I don't see much benefit to selecting 33a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * endianness at run time. 34a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 35a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 36a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 37a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * A union which permits us to convert between a double and two 32 bit 38a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * ints. 39a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 40a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 41a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef __arm__ 42bd3155dc5ddf09647388ad7f8fdbe6df123fbd6aCalin Juravle#if defined(__VFP_FP__) || defined(__ARM_EABI__) 43a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define IEEE_WORD_ORDER BYTE_ORDER 44a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#else 45a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define IEEE_WORD_ORDER BIG_ENDIAN 46a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 47a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#else /* __arm__ */ 48a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define IEEE_WORD_ORDER BYTE_ORDER 49a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 50a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 51a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#if IEEE_WORD_ORDER == BIG_ENDIAN 52a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 53a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughestypedef union 54a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 55a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes double value; 56a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes struct 57a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes { 58a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes u_int32_t msw; 59a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes u_int32_t lsw; 60a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes } parts; 61a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes struct 62a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes { 63a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes u_int64_t w; 64a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes } xparts; 65a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} ieee_double_shape_type; 66a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 67a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 68a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 69a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#if IEEE_WORD_ORDER == LITTLE_ENDIAN 70a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 71a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughestypedef union 72a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 73a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes double value; 74a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes struct 75a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes { 76a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes u_int32_t lsw; 77a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes u_int32_t msw; 78a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes } parts; 79a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes struct 80a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes { 81a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes u_int64_t w; 82a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes } xparts; 83a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} ieee_double_shape_type; 84a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 85a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 86a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 87a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Get two 32 bit ints from a double. */ 88a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 89a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define EXTRACT_WORDS(ix0,ix1,d) \ 90a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 91a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type ew_u; \ 92a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ew_u.value = (d); \ 93a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (ix0) = ew_u.parts.msw; \ 94a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (ix1) = ew_u.parts.lsw; \ 95a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 96a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 97a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Get a 64-bit int from a double. */ 98a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define EXTRACT_WORD64(ix,d) \ 99a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 100a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type ew_u; \ 101a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ew_u.value = (d); \ 102a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (ix) = ew_u.xparts.w; \ 103a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 104a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 105a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Get the more significant 32 bit int from a double. */ 106a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 107a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define GET_HIGH_WORD(i,d) \ 108a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 109a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type gh_u; \ 110a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes gh_u.value = (d); \ 111a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (i) = gh_u.parts.msw; \ 112a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 113a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 114a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Get the less significant 32 bit int from a double. */ 115a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 116a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define GET_LOW_WORD(i,d) \ 117a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 118a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type gl_u; \ 119a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes gl_u.value = (d); \ 120a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (i) = gl_u.parts.lsw; \ 121a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 122a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 123a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Set a double from two 32 bit ints. */ 124a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 125a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define INSERT_WORDS(d,ix0,ix1) \ 126a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 127a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type iw_u; \ 128a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes iw_u.parts.msw = (ix0); \ 129a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes iw_u.parts.lsw = (ix1); \ 130a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (d) = iw_u.value; \ 131a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 132a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 133a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Set a double from a 64-bit int. */ 134a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define INSERT_WORD64(d,ix) \ 135a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 136a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type iw_u; \ 137a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes iw_u.xparts.w = (ix); \ 138a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (d) = iw_u.value; \ 139a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 140a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 141a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Set the more significant 32 bits of a double from an int. */ 142a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 143a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define SET_HIGH_WORD(d,v) \ 144a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 145a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type sh_u; \ 146a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes sh_u.value = (d); \ 147a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes sh_u.parts.msw = (v); \ 148a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (d) = sh_u.value; \ 149a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 150a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 151a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Set the less significant 32 bits of a double from an int. */ 152a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 153a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define SET_LOW_WORD(d,v) \ 154a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 155a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_double_shape_type sl_u; \ 156a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes sl_u.value = (d); \ 157a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes sl_u.parts.lsw = (v); \ 158a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (d) = sl_u.value; \ 159a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 160a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 161a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 162a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * A union which permits us to convert between a float and a 32 bit 163a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * int. 164a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 165a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 166a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughestypedef union 167a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 168a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes float value; 169a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes /* FIXME: Assumes 32 bit int. */ 170a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes unsigned int word; 171a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} ieee_float_shape_type; 172a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 173a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Get a 32 bit int from a float. */ 174a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 175a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define GET_FLOAT_WORD(i,d) \ 176a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 177a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_float_shape_type gf_u; \ 178a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes gf_u.value = (d); \ 179a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (i) = gf_u.word; \ 180a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 181a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 182a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Set a float from a 32 bit int. */ 183a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 184a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define SET_FLOAT_WORD(d,i) \ 185a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 186a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ieee_float_shape_type sf_u; \ 187a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes sf_u.word = (i); \ 188a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (d) = sf_u.value; \ 189a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 190a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 19178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* 19278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Get expsign and mantissa as 16 bit and 64 bit ints from an 80 bit long 19378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * double. 19478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes */ 19578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 19678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define EXTRACT_LDBL80_WORDS(ix0,ix1,d) \ 19778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughesdo { \ 19878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes union IEEEl2bits ew_u; \ 19978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes ew_u.e = (d); \ 20078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (ix0) = ew_u.xbits.expsign; \ 20178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (ix1) = ew_u.xbits.man; \ 20278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 20378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 20478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* 20578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Get expsign and mantissa as one 16 bit and two 64 bit ints from a 128 bit 20678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * long double. 20778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes */ 20878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 20978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define EXTRACT_LDBL128_WORDS(ix0,ix1,ix2,d) \ 21078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughesdo { \ 21178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes union IEEEl2bits ew_u; \ 21278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes ew_u.e = (d); \ 21378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (ix0) = ew_u.xbits.expsign; \ 21478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (ix1) = ew_u.xbits.manh; \ 21578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (ix2) = ew_u.xbits.manl; \ 21678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 21778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 218a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Get expsign as a 16 bit int from a long double. */ 219a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 220a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define GET_LDBL_EXPSIGN(i,d) \ 221a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 222a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes union IEEEl2bits ge_u; \ 223a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes ge_u.e = (d); \ 224a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (i) = ge_u.xbits.expsign; \ 225a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 226a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 22778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* 22878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Set an 80 bit long double from a 16 bit int expsign and a 64 bit int 22978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * mantissa. 23078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes */ 23178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 23278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define INSERT_LDBL80_WORDS(d,ix0,ix1) \ 23378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughesdo { \ 23478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes union IEEEl2bits iw_u; \ 23578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes iw_u.xbits.expsign = (ix0); \ 23678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes iw_u.xbits.man = (ix1); \ 23778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (d) = iw_u.e; \ 23878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 23978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 24078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* 24178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Set a 128 bit long double from a 16 bit int expsign and two 64 bit ints 24278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * comprising the mantissa. 24378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes */ 24478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 24578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define INSERT_LDBL128_WORDS(d,ix0,ix1,ix2) \ 24678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughesdo { \ 24778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes union IEEEl2bits iw_u; \ 24878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes iw_u.xbits.expsign = (ix0); \ 24978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes iw_u.xbits.manh = (ix1); \ 25078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes iw_u.xbits.manl = (ix2); \ 25178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (d) = iw_u.e; \ 25278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 25378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 254a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Set expsign of a long double from a 16 bit int. */ 255a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 256a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define SET_LDBL_EXPSIGN(d,v) \ 257a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdo { \ 258a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes union IEEEl2bits se_u; \ 259a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes se_u.e = (d); \ 260a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes se_u.xbits.expsign = (v); \ 261a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (d) = se_u.e; \ 262a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 263a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 264a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef __i386__ 265a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Long double constants are broken on i386. */ 266a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define LD80C(m, ex, v) { \ 267a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes .xbits.man = __CONCAT(m, ULL), \ 268a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes .xbits.expsign = (0x3fff + (ex)) | ((v) < 0 ? 0x8000 : 0), \ 269a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 270a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#else 271a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* The above works on non-i386 too, but we use this to check v. */ 272a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define LD80C(m, ex, v) { .e = (v), } 273a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 274a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 275a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef FLT_EVAL_METHOD 276a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 277a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Attempt to get strict C99 semantics for assignment with non-C99 compilers. 278a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 279a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 280a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) 281a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#else 282a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define STRICT_ASSIGN(type, lval, rval) do { \ 283a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes volatile type __lval; \ 284a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes \ 285a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if (sizeof(type) >= sizeof(long double)) \ 286a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (lval) = (rval); \ 287a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes else { \ 288a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes __lval = (rval); \ 289a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes (lval) = __lval; \ 290a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes } \ 291a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 292a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 293a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif /* FLT_EVAL_METHOD */ 294a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 295a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Support switching the mode to FP_PE if necessary. */ 296a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#if defined(__i386__) && !defined(NO_FPSETPREC) 297a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define ENTERI() \ 298a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes long double __retval; \ 299a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes fp_prec_t __oprec; \ 300a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes \ 301a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if ((__oprec = fpgetprec()) != FP_PE) \ 302a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes fpsetprec(FP_PE) 303a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define RETURNI(x) do { \ 304a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes __retval = (x); \ 305a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes if (__oprec != FP_PE) \ 306a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes fpsetprec(__oprec); \ 307a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes RETURNF(__retval); \ 308a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} while (0) 309a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#else 310a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define ENTERI(x) 311a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define RETURNI(x) RETURNF(x) 312a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 313a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 314a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Default return statement if hack*_t() is not used. */ 315a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define RETURNF(v) return (v) 316a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 317a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 31878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 2sum gives the same result as 2sumF without requiring |a| >= |b| or 31978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * a == 0, but is slower. 32078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes */ 32178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define _2sum(a, b) do { \ 32278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __typeof(a) __s, __w; \ 32378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 32478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __w = (a) + (b); \ 32578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __s = __w - (a); \ 32678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (b) = ((a) - (__w - __s)) + ((b) - __s); \ 32778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (a) = __w; \ 32878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 32978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 33078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* 33178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 2sumF algorithm. 33278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 33378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * "Normalize" the terms in the infinite-precision expression a + b for 33478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * the sum of 2 floating point values so that b is as small as possible 33578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * relative to 'a'. (The resulting 'a' is the value of the expression in 33678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * the same precision as 'a' and the resulting b is the rounding error.) 33778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * |a| must be >= |b| or 0, b's type must be no larger than 'a's type, and 33878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * exponent overflow or underflow must not occur. This uses a Theorem of 33978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Dekker (1971). See Knuth (1981) 4.2.2 Theorem C. The name "TwoSum" 34078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * is apparently due to Skewchuk (1997). 34178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 34278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * For this to always work, assignment of a + b to 'a' must not retain any 34378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * extra precision in a + b. This is required by C standards but broken 34478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * in many compilers. The brokenness cannot be worked around using 34578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * STRICT_ASSIGN() like we do elsewhere, since the efficiency of this 34678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * algorithm would be destroyed by non-null strict assignments. (The 34778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * compilers are correct to be broken -- the efficiency of all floating 34878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * point code calculations would be destroyed similarly if they forced the 34978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * conversions.) 35078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 35178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Fortunately, a case that works well can usually be arranged by building 35278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * any extra precision into the type of 'a' -- 'a' should have type float_t, 35378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * double_t or long double. b's type should be no larger than 'a's type. 35478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Callers should use these types with scopes as large as possible, to 35578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * reduce their own extra-precision and efficiciency problems. In 35678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * particular, they shouldn't convert back and forth just to call here. 35778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes */ 35878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#ifdef DEBUG 35978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define _2sumF(a, b) do { \ 36078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __typeof(a) __w; \ 36178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes volatile __typeof(a) __ia, __ib, __r, __vw; \ 36278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 36378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __ia = (a); \ 36478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __ib = (b); \ 36578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes assert(__ia == 0 || fabsl(__ia) >= fabsl(__ib)); \ 36678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 36778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __w = (a) + (b); \ 36878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (b) = ((a) - __w) + (b); \ 36978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (a) = __w; \ 37078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 37178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes /* The next 2 assertions are weak if (a) is already long double. */ \ 37278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes assert((long double)__ia + __ib == (long double)(a) + (b)); \ 37378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __vw = __ia + __ib; \ 37478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __r = __ia - __vw; \ 37578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __r += __ib; \ 37678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes assert(__vw == (a) && __r == (b)); \ 37778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 37878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#else /* !DEBUG */ 37978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define _2sumF(a, b) do { \ 38078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __typeof(a) __w; \ 38178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 38278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __w = (a) + (b); \ 38378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (b) = ((a) - __w) + (b); \ 38478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (a) = __w; \ 38578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 38678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif /* DEBUG */ 38778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 38878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* 38978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Set x += c, where x is represented in extra precision as a + b. 39078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * x must be sufficiently normalized and sufficiently larger than c, 39178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * and the result is then sufficiently normalized. 39278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 39378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * The details of ordering are that |a| must be >= |c| (so that (a, c) 39478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * can be normalized without extra work to swap 'a' with c). The details of 39578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * the normalization are that b must be small relative to the normalized 'a'. 39678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * Normalization of (a, c) makes the normalized c tiny relative to the 39778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * normalized a, so b remains small relative to 'a' in the result. However, 39878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * b need not ever be tiny relative to 'a'. For example, b might be about 39978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 2**20 times smaller than 'a' to give about 20 extra bits of precision. 40078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * That is usually enough, and adding c (which by normalization is about 40178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 2**53 times smaller than a) cannot change b significantly. However, 40278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * cancellation of 'a' with c in normalization of (a, c) may reduce 'a' 40378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * significantly relative to b. The caller must ensure that significant 40478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * cancellation doesn't occur, either by having c of the same sign as 'a', 40578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * or by having |c| a few percent smaller than |a|. Pre-normalization of 40678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * (a, b) may help. 40778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * 40878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * This is is a variant of an algorithm of Kahan (see Knuth (1981) 4.2.2 40978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * exercise 19). We gain considerable efficiency by requiring the terms to 41078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes * be sufficiently normalized and sufficiently increasing. 41178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes */ 41278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define _3sumF(a, b, c) do { \ 41378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __typeof(a) __tmp; \ 41478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 41578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __tmp = (c); \ 41678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes _2sumF(__tmp, (a)); \ 41778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (b) += (a); \ 41878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (a) = __tmp; \ 41978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 42078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 42178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* 422a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Common routine to process the arguments to nan(), nanf(), and nanl(). 423a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 424a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesvoid _scan_nan(uint32_t *__words, int __num_words, const char *__s); 425a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 426a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef _COMPLEX_H 427a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 428a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 429a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * C99 specifies that complex numbers have the same representation as 430a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * an array of two elements, where the first element is the real part 431a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * and the second element is the imaginary part. 432a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 433a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughestypedef union { 434a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes float complex f; 435a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes float a[2]; 436a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} float_complex; 437a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughestypedef union { 438a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes double complex f; 439a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes double a[2]; 440a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} double_complex; 441a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughestypedef union { 442a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes long double complex f; 443a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes long double a[2]; 444a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} long_double_complex; 445a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define REALPART(z) ((z).a[0]) 446a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define IMAGPART(z) ((z).a[1]) 447a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 448a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 449a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * Inline functions that can be used to construct complex values. 450a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * 451a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * The C99 standard intends x+I*y to be used for this, but x+I*y is 452a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * currently unusable in general since gcc introduces many overflow, 453a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * underflow, sign and efficiency bugs by rewriting I*y as 454a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. 455a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted 456a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * to -0.0+I*0.0. 4578cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes * 4588cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL() 4598cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes * to construct complex values. Compilers that conform to the C99 4608cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes * standard require the following functions to avoid the above issues. 461a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 4628cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes 4638cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes#ifndef CMPLXF 464a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesstatic __inline float complex 4658cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott HughesCMPLXF(float x, float y) 466a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 467a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes float_complex z; 468a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 469a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes REALPART(z) = x; 470a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes IMAGPART(z) = y; 471a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return (z.f); 472a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 4738cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes#endif 474a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 4758cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes#ifndef CMPLX 476a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesstatic __inline double complex 4778cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott HughesCMPLX(double x, double y) 478a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 479a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes double_complex z; 480a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 481a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes REALPART(z) = x; 482a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes IMAGPART(z) = y; 483a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return (z.f); 484a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 4858cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes#endif 486a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 4878cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes#ifndef CMPLXL 488a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesstatic __inline long double complex 4898cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott HughesCMPLXL(long double x, long double y) 490a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 491a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes long_double_complex z; 492a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 493a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes REALPART(z) = x; 494a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes IMAGPART(z) = y; 495a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return (z.f); 496a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 4978cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes#endif 4988cff2f95d8673b4b9002292d50ce8caa6efb98b6Elliott Hughes 499a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif /* _COMPLEX_H */ 500a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 501a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef __GNUCLIKE_ASM 502a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 503a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* Asm versions of some functions. */ 504a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 505a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef __amd64__ 506a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesstatic __inline int 507a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesirint(double x) 508a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 509a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes int n; 510a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 511a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes asm("cvtsd2si %1,%0" : "=r" (n) : "x" (x)); 512a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return (n); 513a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 514a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define HAVE_EFFICIENT_IRINT 515a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 516a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 517a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef __i386__ 518a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesstatic __inline int 519a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesirint(double x) 520a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 521a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes int n; 522a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 523a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes asm("fistl %0" : "=m" (n) : "t" (x)); 524a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return (n); 525a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 526a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define HAVE_EFFICIENT_IRINT 527a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 528a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 529a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#if defined(__amd64__) || defined(__i386__) 530a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesstatic __inline int 531a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesirintl(long double x) 532a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes{ 533a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes int n; 534a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 535a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes asm("fistl %0" : "=m" (n) : "t" (x)); 536a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes return (n); 537a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes} 538a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define HAVE_EFFICIENT_IRINTL 539a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 540a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 541a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif /* __GNUCLIKE_ASM */ 542a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 54378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#ifdef DEBUG 54478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#if defined(__amd64__) || defined(__i386__) 54578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define breakpoint() asm("int $3") 54678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#else 54778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#include <signal.h> 54878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 54978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define breakpoint() raise(SIGTRAP) 55078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif 55178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif 55278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 55378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes/* Write a pari script to test things externally. */ 55478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#ifdef DOPRINT 55578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#include <stdio.h> 55678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 55778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#ifndef DOPRINT_SWIZZLE 55878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_SWIZZLE 0 55978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif 56078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 56178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#ifdef DOPRINT_LD80 56278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 56378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_START(xp) do { \ 56478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes uint64_t __lx; \ 56578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes uint16_t __hx; \ 56678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 56778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes /* Hack to give more-problematic args. */ \ 56878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes EXTRACT_LDBL80_WORDS(__hx, __lx, *xp); \ 56978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __lx ^= DOPRINT_SWIZZLE; \ 57078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes INSERT_LDBL80_WORDS(*xp, __hx, __lx); \ 57178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("x = %.21Lg; ", (long double)*xp); \ 57278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 57378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END1(v) \ 57478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 57578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END2(hi, lo) \ 57678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 57778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (long double)(hi), (long double)(lo)) 57878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 57978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#elif defined(DOPRINT_D64) 58078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 58178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_START(xp) do { \ 58278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes uint32_t __hx, __lx; \ 58378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 58478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes EXTRACT_WORDS(__hx, __lx, *xp); \ 58578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __lx ^= DOPRINT_SWIZZLE; \ 58678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes INSERT_WORDS(*xp, __hx, __lx); \ 58778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("x = %.21Lg; ", (long double)*xp); \ 58878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 58978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END1(v) \ 59078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 59178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END2(hi, lo) \ 59278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 59378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (long double)(hi), (long double)(lo)) 59478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 59578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#elif defined(DOPRINT_F32) 59678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 59778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_START(xp) do { \ 59878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes uint32_t __hx; \ 59978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 60078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes GET_FLOAT_WORD(__hx, *xp); \ 60178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __hx ^= DOPRINT_SWIZZLE; \ 60278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes SET_FLOAT_WORD(*xp, __hx); \ 60378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("x = %.21Lg; ", (long double)*xp); \ 60478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 60578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END1(v) \ 60678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.21Lg; z = 0; show(x, y, z);\n", (long double)(v)) 60778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END2(hi, lo) \ 60878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.21Lg; z = %.21Lg; show(x, y, z);\n", \ 60978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (long double)(hi), (long double)(lo)) 61078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 61178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#else /* !DOPRINT_LD80 && !DOPRINT_D64 (LD128 only) */ 61278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 61378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#ifndef DOPRINT_SWIZZLE_HIGH 61478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_SWIZZLE_HIGH 0 61578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif 61678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 61778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_START(xp) do { \ 61878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes uint64_t __lx, __llx; \ 61978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes uint16_t __hx; \ 62078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 62178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes EXTRACT_LDBL128_WORDS(__hx, __lx, __llx, *xp); \ 62278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __llx ^= DOPRINT_SWIZZLE; \ 62378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __lx ^= DOPRINT_SWIZZLE_HIGH; \ 62478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes INSERT_LDBL128_WORDS(*xp, __hx, __lx, __llx); \ 62578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("x = %.36Lg; ", (long double)*xp); \ 62678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 62778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END1(v) \ 62878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.36Lg; z = 0; show(x, y, z);\n", (long double)(v)) 62978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END2(hi, lo) \ 63078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes printf("y = %.36Lg; z = %.36Lg; show(x, y, z);\n", \ 63178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes (long double)(hi), (long double)(lo)) 63278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 63378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif /* DOPRINT_LD80 */ 63478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 63578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#else /* !DOPRINT */ 63678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_START(xp) 63778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END1(v) 63878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define DOPRINT_END2(hi, lo) 63978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif /* DOPRINT */ 64078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 64178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define RETURNP(x) do { \ 64278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes DOPRINT_END1(x); \ 64378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURNF(x); \ 64478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 64578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define RETURNPI(x) do { \ 64678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes DOPRINT_END1(x); \ 64778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURNI(x); \ 64878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 64978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define RETURN2P(x, y) do { \ 65078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes DOPRINT_END2((x), (y)); \ 65178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURNF((x) + (y)); \ 65278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 65378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define RETURN2PI(x, y) do { \ 65478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes DOPRINT_END2((x), (y)); \ 65578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURNI((x) + (y)); \ 65678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 65778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#ifdef STRUCT_RETURN 65878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define RETURNSP(rp) do { \ 65978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes if (!(rp)->lo_set) \ 66078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURNP((rp)->hi); \ 66178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURN2P((rp)->hi, (rp)->lo); \ 66278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 66378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define RETURNSPI(rp) do { \ 66478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes if (!(rp)->lo_set) \ 66578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURNPI((rp)->hi); \ 66678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes RETURN2PI((rp)->hi, (rp)->lo); \ 66778419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes} while (0) 66878419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#endif 66978419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes#define SUM2P(x, y) ({ \ 67078419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes const __typeof (x) __x = (x); \ 67178419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes const __typeof (y) __y = (y); \ 67278419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes \ 67378419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes DOPRINT_END2(__x, __y); \ 67478419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes __x + __y; \ 67578419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes}) 67678419467a2f88744ae2445fca5eb442877ebb1b0Elliott Hughes 677a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* 678a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * ieee style elementary functions 679a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * 680a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * We rename functions here to improve other sources' diffability 681a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes * against fdlibm. 682a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes */ 683a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_sqrt sqrt 684a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_acos acos 685a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_acosh acosh 686a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_log log 687a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_log2 log2 688a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_atanh atanh 689a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_asin asin 690a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_atan2 atan2 691a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_exp exp 692a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_cosh cosh 693a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_fmod fmod 694a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_pow pow 695a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_lgamma lgamma 696a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_gamma gamma 697a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_lgamma_r lgamma_r 698a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_gamma_r gamma_r 699a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_log10 log10 700a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_sinh sinh 701a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_hypot hypot 702a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_j0 j0 703a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_j1 j1 704a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_y0 y0 705a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_y1 y1 706a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_jn jn 707a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_yn yn 708a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_remainder remainder 709a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_scalb scalb 710a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_sqrtf sqrtf 711a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_acosf acosf 712a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_acoshf acoshf 713a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_logf logf 714a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_atanhf atanhf 715a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_asinf asinf 716a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_atan2f atan2f 717a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_expf expf 718a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_coshf coshf 719a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_fmodf fmodf 720a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_powf powf 721a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_lgammaf lgammaf 722a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_gammaf gammaf 723a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_lgammaf_r lgammaf_r 724a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_gammaf_r gammaf_r 725a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_log10f log10f 726a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_log2f log2f 727a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_sinhf sinhf 728a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_hypotf hypotf 729a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_j0f j0f 730a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_j1f j1f 731a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_y0f y0f 732a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_y1f y1f 733a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_jnf jnf 734a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_ynf ynf 735a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_remainderf remainderf 736a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#define __ieee754_scalbf scalbf 737a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 738a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* fdlibm kernel function */ 739a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesint __kernel_rem_pio2(double*,double*,int,int,int); 740a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 741a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* double precision kernel functions */ 742a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifndef INLINE_REM_PIO2 743a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesint __ieee754_rem_pio2(double,double*); 744a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 745a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdouble __kernel_sin(double,double,int); 746a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdouble __kernel_cos(double,double); 747a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdouble __kernel_tan(double,double,int); 748a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdouble __ldexp_exp(double,int); 749a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef _COMPLEX_H 750a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesdouble complex __ldexp_cexp(double complex,int); 751a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 752a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 753a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* float precision kernel functions */ 754a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifndef INLINE_REM_PIO2F 755a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesint __ieee754_rem_pio2f(float,double*); 756a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 757a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifndef INLINE_KERNEL_SINDF 758a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesfloat __kernel_sindf(double); 759a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 760a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifndef INLINE_KERNEL_COSDF 761a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesfloat __kernel_cosdf(double); 762a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 763a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifndef INLINE_KERNEL_TANDF 764a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesfloat __kernel_tandf(double,int); 765a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 766a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesfloat __ldexp_expf(float,int); 767a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#ifdef _COMPLEX_H 768a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughesfloat complex __ldexp_cexpf(float complex,int); 769a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 770a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 771a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes/* long double precision kernel functions */ 772a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hugheslong double __kernel_sinl(long double, long double, int); 773a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hugheslong double __kernel_cosl(long double, long double); 774a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hugheslong double __kernel_tanl(long double, long double, int); 775a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 776a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif /* !_MATH_PRIVATE_H_ */ 777