diff options
Diffstat (limited to 'private/windbg/lib/mantold.c')
-rw-r--r-- | private/windbg/lib/mantold.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/private/windbg/lib/mantold.c b/private/windbg/lib/mantold.c new file mode 100644 index 000000000..05dc6db7c --- /dev/null +++ b/private/windbg/lib/mantold.c @@ -0,0 +1,184 @@ +/*** +*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 "cv.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; +} |