compact.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Id$ */
  6. /*
  7. COMPACT EXTEND FORMAT INTO FLOAT OF PROPER SIZE
  8. */
  9. # include "FP_bias.h"
  10. # include "FP_shift.h"
  11. # include "FP_trap.h"
  12. # include "FP_types.h"
  13. # include "get_put.h"
  14. void
  15. compact(f,to,size)
  16. EXTEND *f;
  17. unsigned long *to;
  18. int size;
  19. {
  20. int error = 0;
  21. if (size == sizeof(DOUBLE)) {
  22. /*
  23. * COMPACT EXTENDED INTO DOUBLE
  24. */
  25. DOUBLE *DBL = (DOUBLE *) (void *) to;
  26. if ((f->m1|(f->m2 & DBL_ZERO)) == 0L) {
  27. zrf8(DBL);
  28. return;
  29. }
  30. f->exp += DBL_BIAS; /* restore proper bias */
  31. if (f->exp > DBL_MAX) {
  32. dbl_over: trap(EFOVFL);
  33. f->exp = DBL_MAX+1;
  34. f->m1 = 0;
  35. f->m2 = 0;
  36. if (error++)
  37. return;
  38. }
  39. else if (f->exp < DBL_MIN) {
  40. b64_rsft(&(f->mantissa));
  41. if (f->exp < 0) {
  42. b64_sft(&(f->mantissa), -f->exp);
  43. f->exp = 0;
  44. }
  45. /* underflow ??? */
  46. }
  47. /* local CAST conversion */
  48. /* because of special format shift only 10 bits */
  49. /* bit shift mantissa 10 bits */
  50. /* first align within words, then do store operation */
  51. DBL->d[0] = f->m1 >> DBL_RUNPACK; /* plus 22 == 32 */
  52. DBL->d[1] = f->m2 >> DBL_RUNPACK; /* plus 22 == 32 */
  53. DBL->d[1] |= (f->m1 << DBL_LUNPACK); /* plus 10 == 32 */
  54. /* if not exact then round to nearest */
  55. /* on a tie, round to even */
  56. #ifdef EXCEPTION_INEXACT
  57. if ((f->m2 & DBL_EXACT) != 0) {
  58. INEXACT();
  59. #endif
  60. if (((f->m2 & DBL_EXACT) > DBL_ROUNDUP)
  61. || ((f->m2 & DBL_EXACT) == DBL_ROUNDUP
  62. && (f->m2 & (DBL_ROUNDUP << 1)))) {
  63. DBL->d[1]++; /* rounding up */
  64. if (DBL->d[1] == 0L) { /* carry out */
  65. DBL->d[0]++;
  66. if (f->exp == 0 && (DBL->d[0] & ~DBL_MASK)) {
  67. f->exp++;
  68. }
  69. if (DBL->d[0] & DBL_CARRYOUT) { /* carry out */
  70. if (DBL->d[0] & 01)
  71. DBL->d[1] = CARRYBIT;
  72. DBL->d[0] >>= 1;
  73. f->exp++;
  74. }
  75. }
  76. /* check for overflow */
  77. if (f->exp > DBL_MAX)
  78. goto dbl_over;
  79. }
  80. #ifdef EXCEPTION_INEXACT
  81. }
  82. #endif
  83. /*
  84. * STORE EXPONENT AND SIGN:
  85. *
  86. * 1) clear leading bits (B4-B15)
  87. * 2) shift and store exponent
  88. */
  89. DBL->d[0] &= DBL_MASK;
  90. DBL->d[0] |=
  91. ((long) (f->exp << DBL_EXPSHIFT) << EXP_STORE);
  92. if (f->sign)
  93. DBL->d[0] |= CARRYBIT;
  94. /*
  95. * STORE MANTISSA
  96. */
  97. #if FL_MSL_AT_LOW_ADDRESS
  98. put4(DBL->d[0], (char *) &DBL->d[0]);
  99. put4(DBL->d[1], (char *) &DBL->d[1]);
  100. #else
  101. { unsigned long l;
  102. put4(DBL->d[1], (char *) &l);
  103. put4(DBL->d[0], (char *) &DBL->d[1]);
  104. DBL->d[0] = l;
  105. }
  106. #endif
  107. }
  108. else {
  109. /*
  110. * COMPACT EXTENDED INTO FLOAT
  111. */
  112. SINGLE *SGL;
  113. /* local CAST conversion */
  114. SGL = (SINGLE *) (void *) to;
  115. if ((f->m1 & SGL_ZERO) == 0L) {
  116. *SGL = 0L;
  117. return;
  118. }
  119. f->exp += SGL_BIAS; /* restore bias */
  120. if (f->exp > SGL_MAX) {
  121. sgl_over: trap(EFOVFL);
  122. f->exp = SGL_MAX+1;
  123. f->m1 = 0L;
  124. f->m2 = 0L;
  125. if (error++)
  126. return;
  127. }
  128. else if (f->exp < SGL_MIN) {
  129. b64_rsft(&(f->mantissa));
  130. if (f->exp < 0) {
  131. b64_sft(&(f->mantissa), -f->exp);
  132. f->exp = 0;
  133. }
  134. /* underflow ??? */
  135. }
  136. /* shift mantissa and store */
  137. *SGL = (f->m1 >> SGL_RUNPACK);
  138. /* check for rounding to nearest */
  139. /* on a tie, round to even */
  140. #ifdef EXCEPTION_INEXACT
  141. if (f->m2 != 0 ||
  142. (f->m1 & SGL_EXACT) != 0L) {
  143. INEXACT();
  144. #endif
  145. if (((f->m1 & SGL_EXACT) > SGL_ROUNDUP)
  146. || ((f->m1 & SGL_EXACT) == SGL_ROUNDUP
  147. && (f->m1 & (SGL_ROUNDUP << 1)))) {
  148. (*SGL)++;
  149. if (f->exp == 0 && (*SGL & ~SGL_MASK)) {
  150. f->exp++;
  151. }
  152. /* check normal */
  153. if (*SGL & SGL_CARRYOUT) {
  154. *SGL >>= 1;
  155. f->exp++;
  156. }
  157. if (f->exp > SGL_MAX)
  158. goto sgl_over;
  159. }
  160. #ifdef EXCEPTION_INEXACT
  161. }
  162. #endif
  163. /*
  164. * STORE EXPONENT AND SIGN:
  165. *
  166. * 1) clear leading bit of fraction
  167. * 2) shift and store exponent
  168. */
  169. *SGL &= SGL_MASK; /* B23-B31 are 0 */
  170. *SGL |= ((long) (f->exp << SGL_EXPSHIFT) << EXP_STORE);
  171. if (f->sign)
  172. *SGL |= CARRYBIT;
  173. /*
  174. * STORE MANTISSA
  175. */
  176. put4(*SGL, (char *) &SGL);
  177. }
  178. }