ieee754.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* single and double precision fp ops
  2.  * missing extended precision.
  3. */
  4. /*
  5.  * MIPS floating point support
  6.  * Copyright (C) 1994-2000 Algorithmics Ltd.  All rights reserved.
  7.  * http://www.algor.co.uk
  8.  *
  9.  * ########################################################################
  10.  *
  11.  *  This program is free software; you can distribute it and/or modify it
  12.  *  under the terms of the GNU General Public License (Version 2) as
  13.  *  published by the Free Software Foundation.
  14.  *
  15.  *  This program is distributed in the hope it will be useful, but WITHOUT
  16.  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17.  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  18.  *  for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License along
  21.  *  with this program; if not, write to the Free Software Foundation, Inc.,
  22.  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  23.  *
  24.  * ########################################################################
  25.  */
  26. /**************************************************************************
  27.  *  Nov 7, 2000
  28.  *  Modification to allow integration with Linux kernel
  29.  *
  30.  *  Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com
  31.  *  Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
  32.  *************************************************************************/
  33. #ifdef __KERNEL__
  34. /* Going from Algorithmics to Linux native environment, add this */
  35. #include <linux/types.h>
  36. /*
  37.  * Not very pretty, but the Linux kernel's normal va_list definition
  38.  * does not allow it to be used as a structure element, as it is here.
  39.  */
  40. #ifndef _STDARG_H
  41. #include <stdarg.h>
  42. #endif
  43. #else
  44. /* Note that __KERNEL__ is taken to mean Linux kernel */
  45. #if #system(OpenBSD)
  46. #include <machine/types.h>
  47. #endif
  48. #include <machine/endian.h>
  49. #endif /* __KERNEL__ */
  50. #if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__MIPSEL__)
  51. struct ieee754dp_konst {
  52. unsigned mantlo:32;
  53. unsigned manthi:20;
  54. unsigned bexp:11;
  55. unsigned sign:1;
  56. };
  57. struct ieee754sp_konst {
  58. unsigned mant:23;
  59. unsigned bexp:8;
  60. unsigned sign:1;
  61. };
  62. typedef union _ieee754dp {
  63. struct ieee754dp_konst oparts;
  64. struct {
  65. u64 mant:52;
  66. unsigned int bexp:11;
  67. unsigned int sign:1;
  68. } parts;
  69. u64 bits;
  70. double d;
  71. } ieee754dp;
  72. typedef union _ieee754sp {
  73. struct ieee754sp_konst parts;
  74. float f;
  75. u32 bits;
  76. } ieee754sp;
  77. #endif
  78. #if (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) || defined(__MIPSEB__)
  79. struct ieee754dp_konst {
  80. unsigned sign:1;
  81. unsigned bexp:11;
  82. unsigned manthi:20;
  83. unsigned mantlo:32;
  84. };
  85. typedef union _ieee754dp {
  86. struct ieee754dp_konst oparts;
  87. struct {
  88. unsigned int sign:1;
  89. unsigned int bexp:11;
  90. u64 mant:52;
  91. } parts;
  92. double d;
  93. u64 bits;
  94. } ieee754dp;
  95. struct ieee754sp_konst {
  96. unsigned sign:1;
  97. unsigned bexp:8;
  98. unsigned mant:23;
  99. };
  100. typedef union _ieee754sp {
  101. struct ieee754sp_konst parts;
  102. float f;
  103. u32 bits;
  104. } ieee754sp;
  105. #endif
  106. /*
  107.  * single precision (often aka float)
  108. */
  109. int ieee754sp_finite(ieee754sp x);
  110. int ieee754sp_class(ieee754sp x);
  111. ieee754sp ieee754sp_abs(ieee754sp x);
  112. ieee754sp ieee754sp_neg(ieee754sp x);
  113. ieee754sp ieee754sp_scalb(ieee754sp x, int);
  114. ieee754sp ieee754sp_logb(ieee754sp x);
  115. /* x with sign of y */
  116. ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y);
  117. ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y);
  118. ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y);
  119. ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y);
  120. ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y);
  121. ieee754sp ieee754sp_fint(int x);
  122. ieee754sp ieee754sp_funs(unsigned x);
  123. ieee754sp ieee754sp_flong(s64 x);
  124. ieee754sp ieee754sp_fulong(u64 x);
  125. ieee754sp ieee754sp_fdp(ieee754dp x);
  126. int ieee754sp_tint(ieee754sp x);
  127. unsigned int ieee754sp_tuns(ieee754sp x);
  128. s64 ieee754sp_tlong(ieee754sp x);
  129. u64 ieee754sp_tulong(ieee754sp x);
  130. int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig);
  131. /*
  132.  * basic sp math
  133.  */
  134. ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip);
  135. ieee754sp ieee754sp_frexp(ieee754sp x, int *exp);
  136. ieee754sp ieee754sp_ldexp(ieee754sp x, int exp);
  137. ieee754sp ieee754sp_ceil(ieee754sp x);
  138. ieee754sp ieee754sp_floor(ieee754sp x);
  139. ieee754sp ieee754sp_trunc(ieee754sp x);
  140. ieee754sp ieee754sp_sqrt(ieee754sp x);
  141. /*
  142.  * double precision (often aka double)
  143. */
  144. int ieee754dp_finite(ieee754dp x);
  145. int ieee754dp_class(ieee754dp x);
  146. /* x with sign of y */
  147. ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y);
  148. ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y);
  149. ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y);
  150. ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y);
  151. ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y);
  152. ieee754dp ieee754dp_abs(ieee754dp x);
  153. ieee754dp ieee754dp_neg(ieee754dp x);
  154. ieee754dp ieee754dp_scalb(ieee754dp x, int);
  155. /* return exponent as integer in floating point format
  156.  */
  157. ieee754dp ieee754dp_logb(ieee754dp x);
  158. ieee754dp ieee754dp_fint(int x);
  159. ieee754dp ieee754dp_funs(unsigned x);
  160. ieee754dp ieee754dp_flong(s64 x);
  161. ieee754dp ieee754dp_fulong(u64 x);
  162. ieee754dp ieee754dp_fsp(ieee754sp x);
  163. ieee754dp ieee754dp_ceil(ieee754dp x);
  164. ieee754dp ieee754dp_floor(ieee754dp x);
  165. ieee754dp ieee754dp_trunc(ieee754dp x);
  166. int ieee754dp_tint(ieee754dp x);
  167. unsigned int ieee754dp_tuns(ieee754dp x);
  168. s64 ieee754dp_tlong(ieee754dp x);
  169. u64 ieee754dp_tulong(ieee754dp x);
  170. int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig);
  171. /*
  172.  * basic sp math
  173.  */
  174. ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip);
  175. ieee754dp ieee754dp_frexp(ieee754dp x, int *exp);
  176. ieee754dp ieee754dp_ldexp(ieee754dp x, int exp);
  177. ieee754dp ieee754dp_ceil(ieee754dp x);
  178. ieee754dp ieee754dp_floor(ieee754dp x);
  179. ieee754dp ieee754dp_trunc(ieee754dp x);
  180. ieee754dp ieee754dp_sqrt(ieee754dp x);
  181. /* 5 types of floating point number
  182. */
  183. #define IEEE754_CLASS_NORM 0x00
  184. #define IEEE754_CLASS_ZERO 0x01
  185. #define IEEE754_CLASS_DNORM 0x02
  186. #define IEEE754_CLASS_INF 0x03
  187. #define IEEE754_CLASS_SNAN 0x04
  188. #define IEEE754_CLASS_QNAN 0x05
  189. extern const char *const ieee754_cname[];
  190. /* exception numbers */
  191. #define IEEE754_INEXACT 0x01
  192. #define IEEE754_UNDERFLOW 0x02
  193. #define IEEE754_OVERFLOW 0x04
  194. #define IEEE754_ZERO_DIVIDE 0x08
  195. #define IEEE754_INVALID_OPERATION 0x10
  196. /* cmp operators
  197. */
  198. #define IEEE754_CLT 0x01
  199. #define IEEE754_CEQ 0x02
  200. #define IEEE754_CGT 0x04
  201. #define IEEE754_CUN 0x08
  202. /* rounding mode
  203. */
  204. #define IEEE754_RN 0 /* round to nearest */
  205. #define IEEE754_RZ 1 /* round toward zero  */
  206. #define IEEE754_RD 2 /* round toward -Infinity */
  207. #define IEEE754_RU 3 /* round toward +Infinity */
  208. /* other naming */
  209. #define IEEE754_RM IEEE754_RD
  210. #define IEEE754_RP IEEE754_RU
  211. /* "normal" comparisons
  212. */
  213. static __inline int ieee754sp_eq(ieee754sp x, ieee754sp y)
  214. {
  215. return ieee754sp_cmp(x, y, IEEE754_CEQ, 0);
  216. }
  217. static __inline int ieee754sp_ne(ieee754sp x, ieee754sp y)
  218. {
  219. return ieee754sp_cmp(x, y,
  220.      IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
  221. }
  222. static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
  223. {
  224. return ieee754sp_cmp(x, y, IEEE754_CLT, 0);
  225. }
  226. static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
  227. {
  228. return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
  229. }
  230. static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
  231. {
  232. return ieee754sp_cmp(x, y, IEEE754_CGT, 0);
  233. }
  234. static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
  235. {
  236. return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
  237. }
  238. static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
  239. {
  240. return ieee754dp_cmp(x, y, IEEE754_CEQ, 0);
  241. }
  242. static __inline int ieee754dp_ne(ieee754dp x, ieee754dp y)
  243. {
  244. return ieee754dp_cmp(x, y,
  245.      IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0);
  246. }
  247. static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
  248. {
  249. return ieee754dp_cmp(x, y, IEEE754_CLT, 0);
  250. }
  251. static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
  252. {
  253. return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0);
  254. }
  255. static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
  256. {
  257. return ieee754dp_cmp(x, y, IEEE754_CGT, 0);
  258. }
  259. static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
  260. {
  261. return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0);
  262. }
  263. /* like strtod
  264. */
  265. ieee754dp ieee754dp_fstr(const char *s, char **endp);
  266. char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af);
  267. /* the control status register
  268. */
  269. struct ieee754_csr {
  270. unsigned pad:13;
  271. unsigned nod:1; /* set 1 for no denormalised numbers */
  272. unsigned cx:5; /* exceptions this operation */
  273. unsigned mx:5; /* exception enable  mask */
  274. unsigned sx:5; /* exceptions total */
  275. unsigned rm:2; /* current rounding mode */
  276. };
  277. extern struct ieee754_csr ieee754_csr;
  278. static __inline unsigned ieee754_getrm(void)
  279. {
  280. return (ieee754_csr.rm);
  281. }
  282. static __inline unsigned ieee754_setrm(unsigned rm)
  283. {
  284. return (ieee754_csr.rm = rm);
  285. }
  286. /*
  287.  * get current exceptions
  288.  */
  289. static __inline unsigned ieee754_getcx(void)
  290. {
  291. return (ieee754_csr.cx);
  292. }
  293. /* test for current exception condition
  294.  */
  295. static __inline int ieee754_cxtest(unsigned n)
  296. {
  297. return (ieee754_csr.cx & n);
  298. }
  299. /*
  300.  * get sticky exceptions
  301.  */
  302. static __inline unsigned ieee754_getsx(void)
  303. {
  304. return (ieee754_csr.sx);
  305. }
  306. /* clear sticky conditions
  307. */
  308. static __inline unsigned ieee754_clrsx(void)
  309. {
  310. return (ieee754_csr.sx = 0);
  311. }
  312. /* test for sticky exception condition
  313.  */
  314. static __inline int ieee754_sxtest(unsigned n)
  315. {
  316. return (ieee754_csr.sx & n);
  317. }
  318. /* debugging */
  319. ieee754sp ieee754sp_dump(char *s, ieee754sp x);
  320. ieee754dp ieee754dp_dump(char *s, ieee754dp x);
  321. #define IEEE754_SPCVAL_PZERO 0
  322. #define IEEE754_SPCVAL_NZERO 1
  323. #define IEEE754_SPCVAL_PONE 2
  324. #define IEEE754_SPCVAL_NONE 3
  325. #define IEEE754_SPCVAL_PTEN 4
  326. #define IEEE754_SPCVAL_NTEN 5
  327. #define IEEE754_SPCVAL_PINFINITY 6
  328. #define IEEE754_SPCVAL_NINFINITY 7
  329. #define IEEE754_SPCVAL_INDEF 8
  330. #define IEEE754_SPCVAL_PMAX 9 /* +max norm */
  331. #define IEEE754_SPCVAL_NMAX 10 /* -max norm */
  332. #define IEEE754_SPCVAL_PMIN 11 /* +min norm */
  333. #define IEEE754_SPCVAL_NMIN 12 /* +min norm */
  334. #define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
  335. #define IEEE754_SPCVAL_NMIND 14 /* +min denorm */
  336. #define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
  337. #define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
  338. extern const struct ieee754dp_konst __ieee754dp_spcvals[];
  339. extern const struct ieee754sp_konst __ieee754sp_spcvals[];
  340. #define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
  341. #define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
  342. /* return infinity with given sign
  343. */
  344. #define ieee754dp_inf(sn)
  345.   (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
  346. #define ieee754dp_zero(sn) 
  347.   (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
  348. #define ieee754dp_one(sn) 
  349.   (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
  350. #define ieee754dp_ten(sn) 
  351.   (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
  352. #define ieee754dp_indef() 
  353.   (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
  354. #define ieee754dp_max(sn) 
  355.   (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
  356. #define ieee754dp_min(sn) 
  357.   (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
  358. #define ieee754dp_mind(sn) 
  359.   (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
  360. #define ieee754dp_1e31() 
  361.   (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
  362. #define ieee754dp_1e63() 
  363.   (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
  364. #define ieee754sp_inf(sn) 
  365.   (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
  366. #define ieee754sp_zero(sn) 
  367.   (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
  368. #define ieee754sp_one(sn) 
  369.   (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
  370. #define ieee754sp_ten(sn) 
  371.   (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
  372. #define ieee754sp_indef() 
  373.   (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
  374. #define ieee754sp_max(sn) 
  375.   (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
  376. #define ieee754sp_min(sn) 
  377.   (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
  378. #define ieee754sp_mind(sn) 
  379.   (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
  380. #define ieee754sp_1e31() 
  381.   (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
  382. #define ieee754sp_1e63() 
  383.   (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
  384. /* indefinite integer value
  385. */
  386. #define ieee754si_indef() INT_MAX
  387. #ifdef LONG_LONG_MAX
  388. #define ieee754di_indef() LONG_LONG_MAX
  389. #else
  390. #define ieee754di_indef() ((s64)(~0ULL>>1))
  391. #endif
  392. /* IEEE exception context, passed to handler */
  393. struct ieee754xctx {
  394. const char *op; /* operation name */
  395. int rt; /* result type */
  396. union {
  397. ieee754sp sp; /* single precision */
  398. ieee754dp dp; /* double precision */
  399. #ifdef IEEE854_XP
  400. ieee754xp xp; /* extended precision */
  401. #endif
  402. int si; /* standard signed integer (32bits) */
  403. s64 di; /* extended signed integer (64bits) */
  404. } rv; /* default result format implied by op */
  405. va_list ap;
  406. };
  407. /* result types for xctx.rt */
  408. #define IEEE754_RT_SP 0
  409. #define IEEE754_RT_DP 1
  410. #define IEEE754_RT_XP 2
  411. #define IEEE754_RT_SI 3
  412. #define IEEE754_RT_DI 4
  413. extern void ieee754_xcpt(struct ieee754xctx *xcp);
  414. /* compat */
  415. #define ieee754dp_fix(x) ieee754dp_tint(x)
  416. #define ieee754sp_fix(x) ieee754sp_tint(x)