ieeefp.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #ifndef _IEEE_FP_H_
  2. #define _IEEE_FP_H_
  3. #include "_ansi.h"
  4. #include <machine/ieeefp.h>
  5. #include <float.h>
  6. _BEGIN_STD_C
  7. /* FIXME FIXME FIXME:
  8. Neither of __ieee_{float,double}_shape_type seem to be used anywhere
  9. except in libm/test. If that is the case, please delete these from here.
  10. If that is not the case, please insert documentation here describing why
  11. they're needed. */
  12. #ifdef __IEEE_BIG_ENDIAN
  13. typedef union
  14. {
  15. double value;
  16. struct
  17. {
  18. unsigned int sign : 1;
  19. unsigned int exponent: 11;
  20. unsigned int fraction0:4;
  21. unsigned int fraction1:16;
  22. unsigned int fraction2:16;
  23. unsigned int fraction3:16;
  24. } number;
  25. struct
  26. {
  27. unsigned int sign : 1;
  28. unsigned int exponent: 11;
  29. unsigned int quiet:1;
  30. unsigned int function0:3;
  31. unsigned int function1:16;
  32. unsigned int function2:16;
  33. unsigned int function3:16;
  34. } nan;
  35. struct
  36. {
  37. unsigned long msw;
  38. unsigned long lsw;
  39. } parts;
  40. long aslong[2];
  41. } __ieee_double_shape_type;
  42. #elif defined __IEEE_LITTLE_ENDIAN
  43. typedef union
  44. {
  45. double value;
  46. struct
  47. {
  48. #ifdef __SMALL_BITFIELDS
  49. unsigned int fraction3:16;
  50. unsigned int fraction2:16;
  51. unsigned int fraction1:16;
  52. unsigned int fraction0: 4;
  53. #else
  54. unsigned int fraction1:32;
  55. unsigned int fraction0:20;
  56. #endif
  57. unsigned int exponent :11;
  58. unsigned int sign : 1;
  59. } number;
  60. struct
  61. {
  62. #ifdef __SMALL_BITFIELDS
  63. unsigned int function3:16;
  64. unsigned int function2:16;
  65. unsigned int function1:16;
  66. unsigned int function0:3;
  67. #else
  68. unsigned int function1:32;
  69. unsigned int function0:19;
  70. #endif
  71. unsigned int quiet:1;
  72. unsigned int exponent: 11;
  73. unsigned int sign : 1;
  74. } nan;
  75. struct
  76. {
  77. unsigned long lsw;
  78. unsigned long msw;
  79. } parts;
  80. long aslong[2];
  81. } __ieee_double_shape_type;
  82. #endif /* __IEEE_LITTLE_ENDIAN */
  83. #ifdef __IEEE_BIG_ENDIAN
  84. typedef union
  85. {
  86. float value;
  87. struct
  88. {
  89. unsigned int sign : 1;
  90. unsigned int exponent: 8;
  91. unsigned int fraction0: 7;
  92. unsigned int fraction1: 16;
  93. } number;
  94. struct
  95. {
  96. unsigned int sign:1;
  97. unsigned int exponent:8;
  98. unsigned int quiet:1;
  99. unsigned int function0:6;
  100. unsigned int function1:16;
  101. } nan;
  102. long p1;
  103. } __ieee_float_shape_type;
  104. #elif defined __IEEE_LITTLE_ENDIAN
  105. typedef union
  106. {
  107. float value;
  108. struct
  109. {
  110. unsigned int fraction0: 7;
  111. unsigned int fraction1: 16;
  112. unsigned int exponent: 8;
  113. unsigned int sign : 1;
  114. } number;
  115. struct
  116. {
  117. unsigned int function1:16;
  118. unsigned int function0:6;
  119. unsigned int quiet:1;
  120. unsigned int exponent:8;
  121. unsigned int sign:1;
  122. } nan;
  123. long p1;
  124. } __ieee_float_shape_type;
  125. #endif /* __IEEE_LITTLE_ENDIAN */
  126. #ifndef _LDBL_EQ_DBL
  127. #ifndef LDBL_MANT_DIG
  128. #error "LDBL_MANT_DIG not defined - should be found in float.h"
  129. #elif LDBL_MANT_DIG == DBL_MANT_DIG
  130. #error "double and long double are the same size but LDBL_EQ_DBL is not defined"
  131. #elif LDBL_MANT_DIG == 53
  132. /* This happens when doubles are 32-bits and long doubles are 64-bits. */
  133. #define EXT_EXPBITS 11
  134. #define EXT_FRACHBITS 20
  135. #define EXT_FRACLBITS 32
  136. #define __ieee_ext_field_type unsigned long
  137. #elif LDBL_MANT_DIG == 64
  138. #define EXT_EXPBITS 15
  139. #define EXT_FRACHBITS 32
  140. #define EXT_FRACLBITS 32
  141. #define __ieee_ext_field_type unsigned int
  142. #elif LDBL_MANT_DIG == 65
  143. #define EXT_EXPBITS 15
  144. #define EXT_FRACHBITS 32
  145. #define EXT_FRACLBITS 32
  146. #define __ieee_ext_field_type unsigned int
  147. #elif LDBL_MANT_DIG == 112
  148. #define EXT_EXPBITS 15
  149. #define EXT_FRACHBITS 48
  150. #define EXT_FRACLBITS 64
  151. #define __ieee_ext_field_type unsigned long long
  152. #elif LDBL_MANT_DIG == 113
  153. #define EXT_EXPBITS 15
  154. #define EXT_FRACHBITS 48
  155. #define EXT_FRACLBITS 64
  156. #define __ieee_ext_field_type unsigned long long
  157. #else
  158. #error Unsupported value for LDBL_MANT_DIG
  159. #endif
  160. #define EXT_EXP_INFNAN ((1 << EXT_EXPBITS) - 1) /* 32767 */
  161. #define EXT_EXP_BIAS ((1 << (EXT_EXPBITS - 1)) - 1) /* 16383 */
  162. #define EXT_FRACBITS (EXT_FRACLBITS + EXT_FRACHBITS)
  163. typedef struct ieee_ext
  164. {
  165. __ieee_ext_field_type ext_fracl : EXT_FRACLBITS;
  166. __ieee_ext_field_type ext_frach : EXT_FRACHBITS;
  167. __ieee_ext_field_type ext_exp : EXT_EXPBITS;
  168. __ieee_ext_field_type ext_sign : 1;
  169. } ieee_ext;
  170. typedef union ieee_ext_u
  171. {
  172. long double extu_ld;
  173. struct ieee_ext extu_ext;
  174. } ieee_ext_u;
  175. #endif /* ! _LDBL_EQ_DBL */
  176. /* FLOATING ROUNDING */
  177. typedef int fp_rnd;
  178. #define FP_RN 0 /* Round to nearest */
  179. #define FP_RM 1 /* Round down */
  180. #define FP_RP 2 /* Round up */
  181. #define FP_RZ 3 /* Round to zero (trunate) */
  182. fp_rnd fpgetround (void);
  183. fp_rnd fpsetround (fp_rnd);
  184. /* EXCEPTIONS */
  185. typedef int fp_except;
  186. #define FP_X_INV 0x10 /* Invalid operation */
  187. #define FP_X_DX 0x80 /* Divide by zero */
  188. #define FP_X_OFL 0x04 /* Overflow exception */
  189. #define FP_X_UFL 0x02 /* Underflow exception */
  190. #define FP_X_IMP 0x01 /* imprecise exception */
  191. fp_except fpgetmask (void);
  192. fp_except fpsetmask (fp_except);
  193. fp_except fpgetsticky (void);
  194. fp_except fpsetsticky (fp_except);
  195. /* INTEGER ROUNDING */
  196. typedef int fp_rdi;
  197. #define FP_RDI_TOZ 0 /* Round to Zero */
  198. #define FP_RDI_RD 1 /* Follow float mode */
  199. fp_rdi fpgetroundtoi (void);
  200. fp_rdi fpsetroundtoi (fp_rdi);
  201. #define __IEEE_DBL_EXPBIAS 1023
  202. #define __IEEE_FLT_EXPBIAS 127
  203. #define __IEEE_DBL_EXPLEN 11
  204. #define __IEEE_FLT_EXPLEN 8
  205. #define __IEEE_DBL_FRACLEN (64 - (__IEEE_DBL_EXPLEN + 1))
  206. #define __IEEE_FLT_FRACLEN (32 - (__IEEE_FLT_EXPLEN + 1))
  207. #define __IEEE_DBL_MAXPOWTWO ((double)(1L << 32 - 2) * (1L << (32-11) - 32 + 1))
  208. #define __IEEE_FLT_MAXPOWTWO ((float)(1L << (32-8) - 1))
  209. #define __IEEE_DBL_NAN_EXP 0x7ff
  210. #define __IEEE_FLT_NAN_EXP 0xff
  211. #ifdef __ieeefp_isnanf
  212. #define isnanf(x) __ieeefp_isnanf(x)
  213. #endif
  214. #ifdef __ieeefp_isinff
  215. #define isinff(x) __ieeefp_isinff(x)
  216. #endif
  217. #ifdef __ieeefp_finitef
  218. #define finitef(x) __ieeefp_finitef(x)
  219. #endif
  220. #ifdef _DOUBLE_IS_32BITS
  221. #undef __IEEE_DBL_EXPBIAS
  222. #define __IEEE_DBL_EXPBIAS __IEEE_FLT_EXPBIAS
  223. #undef __IEEE_DBL_EXPLEN
  224. #define __IEEE_DBL_EXPLEN __IEEE_FLT_EXPLEN
  225. #undef __IEEE_DBL_FRACLEN
  226. #define __IEEE_DBL_FRACLEN __IEEE_FLT_FRACLEN
  227. #undef __IEEE_DBL_MAXPOWTWO
  228. #define __IEEE_DBL_MAXPOWTWO __IEEE_FLT_MAXPOWTWO
  229. #undef __IEEE_DBL_NAN_EXP
  230. #define __IEEE_DBL_NAN_EXP __IEEE_FLT_NAN_EXP
  231. #undef __ieee_double_shape_type
  232. #define __ieee_double_shape_type __ieee_float_shape_type
  233. #endif /* _DOUBLE_IS_32BITS */
  234. _END_STD_C
  235. #endif /* _IEEE_FP_H_ */