longdbl.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #ifndef _LDHACK_H
  2. #define _LDHACK_H
  3. #include <float.h>
  4. #include <stdint.h>
  5. #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
  6. #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
  7. union ldshape {
  8. long double value;
  9. struct {
  10. uint64_t m;
  11. uint16_t exp:15;
  12. uint16_t sign:1;
  13. uint16_t pad;
  14. } bits;
  15. };
  16. #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
  17. union ldshape {
  18. long double value;
  19. struct {
  20. uint64_t mlo;
  21. uint64_t mhi:48;
  22. uint16_t exp:15;
  23. uint16_t sign:1;
  24. } bits;
  25. };
  26. #else
  27. #error Unsupported long double representation
  28. #endif
  29. // FIXME: hacks to make freebsd+openbsd long double code happy
  30. // union and macros for freebsd
  31. #if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
  32. union IEEEl2bits {
  33. long double e;
  34. struct {
  35. uint32_t manl:32;
  36. uint32_t manh:32;
  37. uint32_t exp:15;
  38. uint32_t sign:1;
  39. uint32_t pad:16;
  40. } bits;
  41. struct {
  42. uint64_t man:64;
  43. uint32_t expsign:16;
  44. uint32_t pad:16;
  45. } xbits;
  46. };
  47. #define LDBL_MANL_SIZE 32
  48. #define LDBL_MANH_SIZE 32
  49. #define LDBL_NBIT (1ull << LDBL_MANH_SIZE-1)
  50. #undef LDBL_IMPLICIT_NBIT
  51. #define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
  52. #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
  53. /*
  54. // ld128 float.h
  55. //#define LDBL_MAX 1.189731495357231765085759326628007016E+4932L
  56. #define LDBL_MAX 0x1.ffffffffffffffffffffffffffffp+16383
  57. #define LDBL_MAX_EXP 16384
  58. #define LDBL_HAS_INFINITY 1
  59. //#define LDBL_MIN 3.362103143112093506262677817321752603E-4932L
  60. #define LDBL_MIN 0x1p-16382
  61. #define LDBL_HAS_QUIET_NAN 1
  62. #define LDBL_HAS_DENORM 1
  63. //#define LDBL_EPSILON 1.925929944387235853055977942584927319E-34L
  64. #define LDBL_EPSILON 0x1p-112
  65. #define LDBL_MANT_DIG 113
  66. #define LDBL_MIN_EXP (-16381)
  67. #define LDBL_MAX_10_EXP 4932
  68. #define LDBL_DENORM_MIN 0x0.0000000000000000000000000001p-16381
  69. #define LDBL_MIN_10_EXP (-4931)
  70. #define LDBL_DIG 33
  71. */
  72. union IEEEl2bits {
  73. long double e;
  74. struct {
  75. uint64_t manl:64;
  76. uint64_t manh:48;
  77. uint32_t exp:15;
  78. uint32_t sign:1;
  79. } bits;
  80. struct {
  81. uint64_t unused0:64;
  82. uint64_t unused1:48;
  83. uint32_t expsign:16;
  84. } xbits;
  85. };
  86. #define LDBL_MANL_SIZE 64
  87. #define LDBL_MANH_SIZE 48
  88. #define LDBL_NBIT (1ull << LDBL_MANH_SIZE)
  89. #define LDBL_IMPLICIT_NBIT 1
  90. #define mask_nbit_l(u)
  91. #endif
  92. // macros for openbsd
  93. #define GET_LDOUBLE_WORDS(se,mh,ml, f) do{ \
  94. union IEEEl2bits u; \
  95. u.e = (f); \
  96. (se) = u.xbits.expsign; \
  97. (mh) = u.bits.manh; \
  98. (ml) = u.bits.manl; \
  99. }while(0)
  100. #define SET_LDOUBLE_WORDS(f, se,mh,ml) do{ \
  101. union IEEEl2bits u; \
  102. u.xbits.expsign = (se); \
  103. u.bits.manh = (mh); \
  104. u.bits.manl = (ml); \
  105. (f) = u.e; \
  106. }while(0)
  107. #define GET_LDOUBLE_EXP(se, f) do{ \
  108. union IEEEl2bits u; \
  109. u.e = (f); \
  110. (se) = u.xbits.expsign; \
  111. }while(0)
  112. #define SET_LDOUBLE_EXP(f, se) do{ \
  113. union IEEEl2bits u; \
  114. u.e = (f); \
  115. u.xbits.expsign = (se); \
  116. (f) = u.e; \
  117. }while(0)
  118. #endif