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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* IEEE754 floating point arithmetic
  2.  * single 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. #include <linux/kernel.h>
  27. #include "ieee754sp.h"
  28. int ieee754sp_tint(ieee754sp x)
  29. {
  30. COMPXSP;
  31. CLEARCX;
  32. EXPLODEXSP;
  33. FLUSHXSP;
  34. switch (xc) {
  35. case IEEE754_CLASS_SNAN:
  36. case IEEE754_CLASS_QNAN:
  37. case IEEE754_CLASS_INF:
  38. SETCX(IEEE754_INVALID_OPERATION);
  39. return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
  40. case IEEE754_CLASS_ZERO:
  41. return 0;
  42. case IEEE754_CLASS_DNORM:
  43. case IEEE754_CLASS_NORM:
  44. break;
  45. }
  46. if (xe >= 31) {
  47. /* look for valid corner case */
  48. if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
  49. return -0x80000000;
  50. /* Set invalid. We will only use overflow for floating
  51.    point overflow */
  52. SETCX(IEEE754_INVALID_OPERATION);
  53. return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
  54. }
  55. /* oh gawd */
  56. if (xe > SP_MBITS) {
  57. xm <<= xe - SP_MBITS;
  58. } else {
  59. u32 residue;
  60. int round;
  61. int sticky;
  62. int odd;
  63. if (xe < -1) {
  64. residue = xm;
  65. round = 0;
  66. sticky = residue != 0;
  67. xm = 0;
  68. }
  69. else {
  70. /* Shifting a u32 32 times does not work,
  71. * so we do it in two steps. Be aware that xe
  72. * may be -1 */
  73. residue = xm << (xe + 1);
  74. residue <<= 31 - SP_MBITS;
  75. round = (residue >> 31) != 0;
  76. sticky = (residue << 1) != 0;
  77. xm >>= SP_MBITS - xe;
  78. }
  79. odd = (xm & 0x1) != 0x0;
  80. switch (ieee754_csr.rm) {
  81. case IEEE754_RN:
  82. if (round && (sticky || odd))
  83. xm++;
  84. break;
  85. case IEEE754_RZ:
  86. break;
  87. case IEEE754_RU: /* toward +Infinity */
  88. if ((round || sticky) && !xs)
  89. xm++;
  90. break;
  91. case IEEE754_RD: /* toward -Infinity */
  92. if ((round || sticky) && xs)
  93. xm++;
  94. break;
  95. }
  96. if ((xm >> 31) != 0) {
  97. /* This can happen after rounding */
  98. SETCX(IEEE754_INVALID_OPERATION);
  99. return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x);
  100. }
  101. if (round || sticky)
  102. SETCX(IEEE754_INEXACT);
  103. }
  104. if (xs)
  105. return -xm;
  106. else
  107. return xm;
  108. }
  109. unsigned int ieee754sp_tuns(ieee754sp x)
  110. {
  111. ieee754sp hb = ieee754sp_1e31();
  112. /* what if x < 0 ?? */
  113. if (ieee754sp_lt(x, hb))
  114. return (unsigned) ieee754sp_tint(x);
  115. return (unsigned) ieee754sp_tint(ieee754sp_sub(x, hb)) |
  116.     ((unsigned) 1 << 31);
  117. }