ieee754.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:13k
源码类别:

嵌入式Linux

开发平台:

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. unsigned long long mant:52;
  66. unsigned int bexp:11;
  67. unsigned int sign:1;
  68. } parts;
  69. unsigned long long bits;
  70. double d;
  71. } ieee754dp;
  72. typedef union _ieee754sp {
  73. struct ieee754sp_konst parts;
  74. float f;
  75. unsigned long 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. unsigned long long mant:52;
  91. } parts;
  92. double d;
  93. unsigned long long 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. unsigned long 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(long long x);
  124. ieee754sp ieee754sp_fulong(unsigned long long x);
  125. ieee754sp ieee754sp_fdp(ieee754dp x);
  126. int ieee754sp_tint(ieee754sp x);
  127. unsigned int ieee754sp_tuns(ieee754sp x);
  128. long long ieee754sp_tlong(ieee754sp x);
  129. unsigned long long ieee754sp_tulong(ieee754sp x);
  130. int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop);
  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(long long x);
  161. ieee754dp ieee754dp_fulong(unsigned long long 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. long long ieee754dp_tlong(ieee754dp x);
  169. unsigned long long ieee754dp_tulong(ieee754dp x);
  170. int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop);
  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);
  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);
  221. }
  222. static __inline int ieee754sp_lt(ieee754sp x, ieee754sp y)
  223. {
  224. return ieee754sp_cmp(x, y, IEEE754_CLT);
  225. }
  226. static __inline int ieee754sp_le(ieee754sp x, ieee754sp y)
  227. {
  228. return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
  229. }
  230. static __inline int ieee754sp_gt(ieee754sp x, ieee754sp y)
  231. {
  232. return ieee754sp_cmp(x, y, IEEE754_CGT);
  233. }
  234. static __inline int ieee754sp_ge(ieee754sp x, ieee754sp y)
  235. {
  236. return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
  237. }
  238. static __inline int ieee754dp_eq(ieee754dp x, ieee754dp y)
  239. {
  240. return ieee754dp_cmp(x, y, IEEE754_CEQ);
  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);
  246. }
  247. static __inline int ieee754dp_lt(ieee754dp x, ieee754dp y)
  248. {
  249. return ieee754dp_cmp(x, y, IEEE754_CLT);
  250. }
  251. static __inline int ieee754dp_le(ieee754dp x, ieee754dp y)
  252. {
  253. return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ);
  254. }
  255. static __inline int ieee754dp_gt(ieee754dp x, ieee754dp y)
  256. {
  257. return ieee754dp_cmp(x, y, IEEE754_CGT);
  258. }
  259. static __inline int ieee754dp_ge(ieee754dp x, ieee754dp y)
  260. {
  261. return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ);
  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 noq:1; /* set 1 for no quiet NaN's */
  272. unsigned nod:1; /* set 1 for no denormalised numbers */
  273. unsigned cx:5; /* exceptions this operation */
  274. unsigned mx:5; /* exception enable  mask */
  275. unsigned sx:5; /* exceptions total */
  276. unsigned rm:2; /* current rounding mode */
  277. };
  278. extern struct ieee754_csr ieee754_csr;
  279. static __inline unsigned ieee754_getrm(void)
  280. {
  281. return (ieee754_csr.rm);
  282. }
  283. static __inline unsigned ieee754_setrm(unsigned rm)
  284. {
  285. return (ieee754_csr.rm = rm);
  286. }
  287. /*
  288.  * get current exceptions
  289.  */
  290. static __inline unsigned ieee754_getcx(void)
  291. {
  292. return (ieee754_csr.cx);
  293. }
  294. /* test for current exception condition 
  295.  */
  296. static __inline int ieee754_cxtest(unsigned n)
  297. {
  298. return (ieee754_csr.cx & n);
  299. }
  300. /*
  301.  * get sticky exceptions
  302.  */
  303. static __inline unsigned ieee754_getsx(void)
  304. {
  305. return (ieee754_csr.sx);
  306. }
  307. /* clear sticky conditions
  308. */
  309. static __inline unsigned ieee754_clrsx(void)
  310. {
  311. return (ieee754_csr.sx = 0);
  312. }
  313. /* test for sticky exception condition 
  314.  */
  315. static __inline int ieee754_sxtest(unsigned n)
  316. {
  317. return (ieee754_csr.sx & n);
  318. }
  319. /* debugging */
  320. ieee754sp ieee754sp_dump(char *s, ieee754sp x);
  321. ieee754dp ieee754dp_dump(char *s, ieee754dp x);
  322. #define IEEE754_SPCVAL_PZERO 0
  323. #define IEEE754_SPCVAL_NZERO 1
  324. #define IEEE754_SPCVAL_PONE 2
  325. #define IEEE754_SPCVAL_NONE 3
  326. #define IEEE754_SPCVAL_PTEN 4
  327. #define IEEE754_SPCVAL_NTEN 5
  328. #define IEEE754_SPCVAL_PINFINITY 6
  329. #define IEEE754_SPCVAL_NINFINITY 7
  330. #define IEEE754_SPCVAL_INDEF 8
  331. #define IEEE754_SPCVAL_PMAX 9 /* +max norm */
  332. #define IEEE754_SPCVAL_NMAX 10 /* -max norm */
  333. #define IEEE754_SPCVAL_PMIN 11 /* +min norm */
  334. #define IEEE754_SPCVAL_NMIN 12 /* +min norm */
  335. #define IEEE754_SPCVAL_PMIND 13 /* +min denorm */
  336. #define IEEE754_SPCVAL_NMIND 14 /* +min denorm */
  337. #define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */
  338. #define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */
  339. extern const struct ieee754dp_konst __ieee754dp_spcvals[];
  340. extern const struct ieee754sp_konst __ieee754sp_spcvals[];
  341. #define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals)
  342. #define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals)
  343. /* return infinity with given sign
  344. */
  345. #define ieee754dp_inf(sn)
  346.   (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
  347. #define ieee754dp_zero(sn) 
  348.   (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
  349. #define ieee754dp_one(sn) 
  350.   (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
  351. #define ieee754dp_ten(sn) 
  352.   (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
  353. #define ieee754dp_indef() 
  354.   (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF])
  355. #define ieee754dp_max(sn) 
  356.   (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
  357. #define ieee754dp_min(sn) 
  358.   (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
  359. #define ieee754dp_mind(sn) 
  360.   (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
  361. #define ieee754dp_1e31() 
  362.   (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31])
  363. #define ieee754dp_1e63() 
  364.   (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63])
  365. #define ieee754sp_inf(sn) 
  366.   (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)])
  367. #define ieee754sp_zero(sn) 
  368.   (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)])
  369. #define ieee754sp_one(sn) 
  370.   (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)])
  371. #define ieee754sp_ten(sn) 
  372.   (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)])
  373. #define ieee754sp_indef() 
  374.   (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF])
  375. #define ieee754sp_max(sn) 
  376.   (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)])
  377. #define ieee754sp_min(sn) 
  378.   (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)])
  379. #define ieee754sp_mind(sn) 
  380.   (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)])
  381. #define ieee754sp_1e31() 
  382.   (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31])
  383. #define ieee754sp_1e63() 
  384.   (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63])
  385. /* indefinite integer value 
  386. */
  387. #define ieee754si_indef() INT_MIN
  388. #ifdef LONG_LONG_MIN
  389. #define ieee754di_indef() LONG_LONG_MIN
  390. #else
  391. #define ieee754di_indef() (-9223372036854775807LL-1)
  392. #endif
  393. /* IEEE exception context, passed to handler */
  394. struct ieee754xctx {
  395. const char *op; /* operation name */
  396. int rt; /* result type */
  397. union {
  398. ieee754sp sp; /* single precision */
  399. ieee754dp dp; /* double precision */
  400. #ifdef IEEE854_XP
  401. ieee754xp xp; /* extended precision */
  402. #endif
  403. int si; /* standard signed integer (32bits) */
  404. long long di; /* extended signed integer (64bits) */
  405. } rv; /* default result format implied by op */
  406. va_list ap;
  407. };
  408. /* result types for xctx.rt */
  409. #define IEEE754_RT_SP 0
  410. #define IEEE754_RT_DP 1
  411. #define IEEE754_RT_XP 2
  412. #define IEEE754_RT_SI 3
  413. #define IEEE754_RT_DI 4
  414. extern void ieee754_xcpt(struct ieee754xctx *xcp);
  415. /* compat */
  416. #define ieee754dp_fix(x) ieee754dp_tint(x)
  417. #define ieee754sp_fix(x) ieee754sp_tint(x)