Windows2000/private/windbg64/lib/mantold.c
2020-09-30 17:12:32 +02:00

185 lines
3.8 KiB
C

/*
*mantold.c - conversion of a decimal mantissa to _ULDBL12
* Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
*Purpose:
* Conversion of a decimal mantissa into _ULDBL12 format (i.e. long
* double with two additional bytes of significand)
*Revision History:
* 7-17-91 GDP Initial version (ported from assembly)
* 05-26-92 GWK Windbg srcs
*/
#include "mathsup.h"
/*
*int __addl(u_long x, u_long y, u_long *sum) - u_long addition
*Purpose: add two u_long numbers and return carry
*Entry: u_long x, u_long y : the numbers to be added
* u_long *sum : where to store the result
*Exit: *sum receives the value of x+y
* the value of the carry is returned
*Exceptions:
*/
int __addl(u_long x, u_long y, u_long *sum)
{
u_long r;
int carry=0;
r = x+y;
if (r < x || r < y)
carry++;
*sum = r;
return carry;
}
/*
*void __add_12(_ULDBL12 *x, _ULDBL12 *y) - _ULDBL12 addition
*Purpose: add two _ULDBL12 numbers. The numbers are added
* as 12-byte integers. Overflow is ignored.
*Entry: x,y: pointers to the operands
*Exit: *x receives the sum
*Exceptions:
*/
void __add_12(_ULDBL12 *x, _ULDBL12 *y)
{
int c0,c1,c2;
c0 = __addl(*UL_LO_12(x),*UL_LO_12(y),UL_LO_12(x));
if (c0) {
c1 = __addl(*UL_MED_12(x),(u_long)1,UL_MED_12(x));
if (c1) {
(*UL_HI_12(x))++;
}
}
c2 = __addl(*UL_MED_12(x),*UL_MED_12(y),UL_MED_12(x));
if (c2) {
(*UL_HI_12(x))++;
}
/* ignore next carry -- assume no overflow will occur */
(void) __addl(*UL_HI_12(x),*UL_HI_12(y),UL_HI_12(x));
}
/*
*void __shl_12(_ULDBL12 *x) - _ULDBL12 shift left
*void __shr_12(_ULDBL12 *x) - _ULDBL12 shift right
*Purpose: Shift a _ULDBL12 number one bit to the left (right). The number
* is shifted as a 12-byte integer. The MSB is lost.
*Entry: x: a pointer to the operand
*Exit: *x is shifted one bit to the left (or right)
*Exceptions:
*/
void __shl_12(_ULDBL12 *p)
{
u_long c0,c1;
c0 = *UL_LO_12(p) & MSB_ULONG ? 1: 0;
c1 = *UL_MED_12(p) & MSB_ULONG ? 1: 0;
*UL_LO_12(p) <<= 1;
*UL_MED_12(p) = *UL_MED_12(p)<<1 | c0;
*UL_HI_12(p) = *UL_HI_12(p)<<1 | c1;
}
void __shr_12(_ULDBL12 *p)
{
u_long c2,c1;
c2 = *UL_HI_12(p) & 0x1 ? MSB_ULONG: 0;
c1 = *UL_MED_12(p) & 0x1 ? MSB_ULONG: 0;
*UL_HI_12(p) >>= 1;
*UL_MED_12(p) = *UL_MED_12(p)>>1 | c2;
*UL_LO_12(p) = *UL_LO_12(p)>>1 | c1;
}
/*
*void __mtold12(char *manptr,unsigned manlen,_ULDBL12 *ld12) -
* convert a mantissa into a _ULDBL12
*Purpose: convert a mantissa into a _ULDBL12. The mantissa is
* in the form of an array of manlen BCD digits and is
* considered to be an integer.
*Entry: manptr: the array containing the packed BCD digits of the mantissa
* manlen: the size of the array
* ld12: a pointer to the long double where the result will be stored
*Exit:
* ld12 gets the result of the conversion
*Exceptions:
*/
void __mtold12(char *manptr,
unsigned manlen,
_ULDBL12 *ld12)
{
_ULDBL12 tmp;
u_short expn = LD_BIASM1+80;
*UL_LO_12(ld12) = 0;
*UL_MED_12(ld12) = 0;
*UL_HI_12(ld12) = 0;
for (;manlen>0;manlen--,manptr++){
tmp = *ld12;
__shl_12(ld12);
__shl_12(ld12);
__add_12(ld12,&tmp);
__shl_12(ld12); /* multiply by 10 */
*UL_LO_12(&tmp) = (u_long)*manptr;
*UL_MED_12(&tmp) = 0;
*UL_HI_12(&tmp) = 0;
__add_12(ld12,&tmp);
}
/* normalize mantissa -- first shift word by word */
while (*UL_HI_12(ld12) == 0) {
*UL_HI_12(ld12) = *UL_MED_12(ld12) >> 16;
*UL_MED_12(ld12) = *UL_MED_12(ld12) << 16 | *UL_LO_12(ld12) >> 16;
(*UL_LO_12(ld12)) <<= 16;
expn -= 16;
}
while ((*UL_HI_12(ld12) & 0x8000) == 0) {
__shl_12(ld12);
expn--;
}
*U_EXP_12(ld12) = expn;
}