Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
4.3 KiB

  1. /***
  2. *mantold.c - conversion of a decimal mantissa to _LDBL12
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Conversion of a decimal mantissa into _LDBL12 format (i.e. long
  8. * double with two additional bytes of significand)
  9. *
  10. *Revision History:
  11. * 7-17-91 GDP Initial version (ported from assembly)
  12. *
  13. *******************************************************************************/
  14. #include <cv.h>
  15. /***
  16. *int _CALLTYPE5 __addl(u_long x, u_long y, u_long *sum) - u_long addition
  17. *
  18. *Purpose: add two u_long numbers and return carry
  19. *
  20. *Entry: u_long x, u_long y : the numbers to be added
  21. * u_long *sum : where to store the result
  22. *
  23. *Exit: *sum receives the value of x+y
  24. * the value of the carry is returned
  25. *
  26. *Exceptions:
  27. *
  28. *******************************************************************************/
  29. int _CALLTYPE5 __addl(u_long x, u_long y, u_long *sum)
  30. {
  31. u_long r;
  32. int carry=0;
  33. r = x+y;
  34. if (r < x || r < y)
  35. carry++;
  36. *sum = r;
  37. return carry;
  38. }
  39. /***
  40. *void _CALLTYPE5 __add_12(_LDBL12 *x, _LDBL12 *y) - _LDBL12 addition
  41. *
  42. *Purpose: add two _LDBL12 numbers. The numbers are added
  43. * as 12-byte integers. Overflow is ignored.
  44. *
  45. *Entry: x,y: pointers to the operands
  46. *
  47. *Exit: *x receives the sum
  48. *
  49. *Exceptions:
  50. *
  51. *******************************************************************************/
  52. void _CALLTYPE5 __add_12(_LDBL12 *x, _LDBL12 *y)
  53. {
  54. int c0,c1,c2;
  55. c0 = __addl(*UL_LO_12(x),*UL_LO_12(y),UL_LO_12(x));
  56. if (c0) {
  57. c1 = __addl(*UL_MED_12(x),(u_long)1,UL_MED_12(x));
  58. if (c1) {
  59. (*UL_HI_12(x))++;
  60. }
  61. }
  62. c2 = __addl(*UL_MED_12(x),*UL_MED_12(y),UL_MED_12(x));
  63. if (c2) {
  64. (*UL_HI_12(x))++;
  65. }
  66. /* ignore next carry -- assume no overflow will occur */
  67. (void) __addl(*UL_HI_12(x),*UL_HI_12(y),UL_HI_12(x));
  68. }
  69. /***
  70. *void _CALLTYPE5 __shl_12(_LDBL12 *x) - _LDBL12 shift left
  71. *void _CALLTYPE5 __shr_12(_LDBL12 *x) - _LDBL12 shift right
  72. *
  73. *Purpose: Shift a _LDBL12 number one bit to the left (right). The number
  74. * is shifted as a 12-byte integer. The MSB is lost.
  75. *
  76. *Entry: x: a pointer to the operand
  77. *
  78. *Exit: *x is shifted one bit to the left (or right)
  79. *
  80. *Exceptions:
  81. *
  82. *******************************************************************************/
  83. void _CALLTYPE5 __shl_12(_LDBL12 *p)
  84. {
  85. u_long c0,c1;
  86. c0 = *UL_LO_12(p) & MSB_ULONG ? 1: 0;
  87. c1 = *UL_MED_12(p) & MSB_ULONG ? 1: 0;
  88. *UL_LO_12(p) <<= 1;
  89. *UL_MED_12(p) = *UL_MED_12(p)<<1 | c0;
  90. *UL_HI_12(p) = *UL_HI_12(p)<<1 | c1;
  91. }
  92. void _CALLTYPE5 __shr_12(_LDBL12 *p)
  93. {
  94. u_long c2,c1;
  95. c2 = *UL_HI_12(p) & 0x1 ? MSB_ULONG: 0;
  96. c1 = *UL_MED_12(p) & 0x1 ? MSB_ULONG: 0;
  97. *UL_HI_12(p) >>= 1;
  98. *UL_MED_12(p) = *UL_MED_12(p)>>1 | c2;
  99. *UL_LO_12(p) = *UL_LO_12(p)>>1 | c1;
  100. }
  101. /***
  102. *void _CALLTYPE5 __mtold12(char *manptr,unsigned manlen,_LDBL12 *ld12) -
  103. * convert a mantissa into a _LDBL12
  104. *
  105. *Purpose: convert a mantissa into a _LDBL12. The mantissa is
  106. * in the form of an array of manlen BCD digits and is
  107. * considered to be an integer.
  108. *
  109. *Entry: manptr: the array containing the packed BCD digits of the mantissa
  110. * manlen: the size of the array
  111. * ld12: a pointer to the long double where the result will be stored
  112. *
  113. *Exit:
  114. * ld12 gets the result of the conversion
  115. *
  116. *Exceptions:
  117. *
  118. *******************************************************************************/
  119. void _CALLTYPE5 __mtold12(char *manptr,
  120. unsigned manlen,
  121. _LDBL12 *ld12)
  122. {
  123. _LDBL12 tmp;
  124. u_short expn = LD_BIASM1+80;
  125. *UL_LO_12(ld12) = 0;
  126. *UL_MED_12(ld12) = 0;
  127. *UL_HI_12(ld12) = 0;
  128. for (;manlen>0;manlen--,manptr++){
  129. tmp = *ld12;
  130. __shl_12(ld12);
  131. __shl_12(ld12);
  132. __add_12(ld12,&tmp);
  133. __shl_12(ld12); /* multiply by 10 */
  134. *UL_LO_12(&tmp) = (u_long)*manptr;
  135. *UL_MED_12(&tmp) = 0;
  136. *UL_HI_12(&tmp) = 0;
  137. __add_12(ld12,&tmp);
  138. }
  139. /* normalize mantissa -- first shift word by word */
  140. while (*UL_HI_12(ld12) == 0) {
  141. *UL_HI_12(ld12) = *UL_MED_12(ld12) >> 16;
  142. *UL_MED_12(ld12) = *UL_MED_12(ld12) << 16 | *UL_LO_12(ld12) >> 16;
  143. (*UL_LO_12(ld12)) <<= 16;
  144. expn -= 16;
  145. }
  146. while ((*UL_HI_12(ld12) & 0x8000) == 0) {
  147. __shl_12(ld12);
  148. expn--;
  149. }
  150. *U_EXP_12(ld12) = expn;
  151. }