Fix building on clang10 on ubuntu 20.04 (#1215)
authorMike McLaughlin <mikem@microsoft.com>
Wed, 10 Jun 2020 17:09:34 +0000 (10:09 -0700)
committerGitHub <noreply@github.com>
Wed, 10 Jun 2020 17:09:34 +0000 (10:09 -0700)
documentation/building/linux-instructions.md
src/pal/inc/pal.h
src/pal/src/CMakeLists.txt
src/pal/src/cruntime/misc.cpp
src/pal/src/cruntime/thread.cpp [deleted file]
src/palrt/CMakeLists.txt
src/palrt/decarith.cpp [deleted file]
src/palrt/decconv.cpp [deleted file]

index 0980c4369164d82634b5ab7d8eaba67c237334f5..ef7b1fca8b65dcc8a218f7f171aedff7a506fdec 100644 (file)
@@ -78,6 +78,14 @@ Install the required packages:
 
 See the section below on how to clone, build and test the repo.
 
+#### Ubuntu 20.04 ####
+
+Install the required packages:
+
+    sudo apt update
+    sudo apt install cmake clang curl gdb gettext git libicu-dev lldb liblldb-dev libunwind8 llvm make python python-lldb tar wget zip 
+
+See the section below on how to clone, build and test the repo.
 #### Alpine 3.8/3.9 ####
 
 Install the required packages:
index 2049a5e2b8c0f8f06ec44204a2f98818e3439fe4..3a32e32b43d362b195db1083ee2335b730dfc8b8 100644 (file)
@@ -3439,7 +3439,6 @@ CreatePipe(
 #define exp           PAL_exp
 #define log           PAL_log
 #define log10         PAL_log10
-#define pow           PAL_pow
 #define acosf         PAL_acosf
 #define acoshf        PAL_acoshf
 #define asinf         PAL_asinf
@@ -3448,7 +3447,6 @@ CreatePipe(
 #define expf          PAL_expf
 #define logf          PAL_logf
 #define log10f        PAL_log10f
-#define powf          PAL_powf
 #define malloc        PAL_malloc
 #define free          PAL_free
 #define mkstemp       PAL_mkstemp
@@ -3495,33 +3493,15 @@ typedef struct {
 
 PALIMPORT div_t div(int numer, int denom);
 
-#if defined(_DEBUG)
+#ifndef __THROW
+#define __THROW
+#endif 
 
-/*++
-Function:
-PAL_memcpy
-
-Overlapping buffer-safe version of memcpy.
-See MSDN doc for memcpy
---*/
-EXTERN_C
-PALIMPORT
-void *PAL_memcpy (void *dest, const void *src, size_t count);
-
-PALIMPORT void * __cdecl memcpy(void *, const void *, size_t);
-
-#define memcpy PAL_memcpy
-#define IS_PAL_memcpy 1
-#define TEST_PAL_DEFERRED(def) IS_##def
-#define IS_REDEFINED_IN_PAL(def) TEST_PAL_DEFERRED(def)
-#else //defined(_DEBUG)
-PALIMPORT void * __cdecl memcpy(void *, const void *, size_t);
-#endif //defined(_DEBUG)
+PALIMPORT void * __cdecl memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __THROW;
 PALIMPORT int    __cdecl memcmp(const void *, const void *, size_t);
 PALIMPORT void * __cdecl memset(void *, int, size_t);
 PALIMPORT void * __cdecl memmove(void *, const void *, size_t);
 PALIMPORT void * __cdecl memchr(const void *, int, size_t);
-PALIMPORT long long int __cdecl atoll(const char *);
 PALIMPORT size_t __cdecl strlen(const char *);
 PALIMPORT int __cdecl strcmp(const char*, const char *);
 PALIMPORT int __cdecl strncmp(const char*, const char *, size_t);
@@ -3679,67 +3659,12 @@ unsigned int __cdecl _rotr(unsigned int value, int shift)
 #endif // !__has_builtin(_rotr)
 
 PALIMPORT int __cdecl abs(int);
-#ifndef PAL_STDCPP_COMPAT
-PALIMPORT LONG __cdecl labs(LONG);
-#endif // !PAL_STDCPP_COMPAT
+
 // clang complains if this is declared with __int64
 PALIMPORT long long __cdecl llabs(long long);
 
-PALIMPORT int __cdecl _finite(double);
-PALIMPORT int __cdecl _isnan(double);
-PALIMPORT double __cdecl _copysign(double, double);
-PALIMPORT double __cdecl acos(double);
-PALIMPORT double __cdecl acosh(double);
-PALIMPORT double __cdecl asin(double);
-PALIMPORT double __cdecl asinh(double);
-PALIMPORT double __cdecl atan(double);
-PALIMPORT double __cdecl atanh(double);
-PALIMPORT double __cdecl atan2(double, double);
-PALIMPORT double __cdecl cbrt(double);
-PALIMPORT double __cdecl ceil(double);
-PALIMPORT double __cdecl cos(double);
-PALIMPORT double __cdecl cosh(double);
-PALIMPORT double __cdecl exp(double);
 PALIMPORT double __cdecl fabs(double);
-PALIMPORT double __cdecl floor(double);
-PALIMPORT double __cdecl fmod(double, double); 
-PALIMPORT double __cdecl log(double);
-PALIMPORT double __cdecl log10(double);
-PALIMPORT double __cdecl modf(double, double*);
-PALIMPORT double __cdecl pow(double, double);
-PALIMPORT double __cdecl sin(double);
-PALIMPORT double __cdecl sinh(double);
-PALIMPORT double __cdecl sqrt(double);
-PALIMPORT double __cdecl tan(double);
-PALIMPORT double __cdecl tanh(double);
-
-PALIMPORT int __cdecl _finitef(float);
-PALIMPORT int __cdecl _isnanf(float);
-PALIMPORT float __cdecl _copysignf(float, float);
-PALIMPORT float __cdecl acosf(float);
-PALIMPORT float __cdecl acoshf(float);
-PALIMPORT float __cdecl asinf(float);
-PALIMPORT float __cdecl asinhf(float);
-PALIMPORT float __cdecl atanf(float);
-PALIMPORT float __cdecl atanhf(float);
-PALIMPORT float __cdecl atan2f(float, float);
-PALIMPORT float __cdecl cbrtf(float);
-PALIMPORT float __cdecl ceilf(float);
-PALIMPORT float __cdecl cosf(float);
-PALIMPORT float __cdecl coshf(float);
-PALIMPORT float __cdecl expf(float);
 PALIMPORT float __cdecl fabsf(float);
-PALIMPORT float __cdecl floorf(float);
-PALIMPORT float __cdecl fmodf(float, float); 
-PALIMPORT float __cdecl logf(float);
-PALIMPORT float __cdecl log10f(float);
-PALIMPORT float __cdecl modff(float, float*);
-PALIMPORT float __cdecl powf(float, float);
-PALIMPORT float __cdecl sinf(float);
-PALIMPORT float __cdecl sinhf(float);
-PALIMPORT float __cdecl sqrtf(float);
-PALIMPORT float __cdecl tanf(float);
-PALIMPORT float __cdecl tanhf(float);
 
 #ifndef PAL_STDCPP_COMPAT
 
@@ -3770,9 +3695,6 @@ PALIMPORT void * __cdecl realloc(void *, size_t);
 
 #endif // !PAL_STDCPP_COMPAT
 
-PALIMPORT PAL_NORETURN void __cdecl exit(int);
-int __cdecl atexit(void (__cdecl *function)(void));
-
 PALIMPORT void __cdecl qsort(void *, size_t, size_t, int (__cdecl *)(const void *, const void *));
 PALIMPORT void * __cdecl bsearch(const void *, const void *, size_t, size_t,
 int (__cdecl *)(const void *, const void *));
index b81173f8e17ce8ed497a3b25f41219aed2657b57..a5c6f6a2eb67967747bcdc43f3755f3fedf2a596 100644 (file)
@@ -127,7 +127,6 @@ set(SOURCES
   cruntime/silent_printf.cpp
   cruntime/string.cpp
   cruntime/stringtls.cpp
-  cruntime/thread.cpp
   cruntime/wchar.cpp
   cruntime/wchartls.cpp
   debug/debug.cpp
index f2c9caeea67f2e4a31d111726db874933801f487..b8ccda6ef0198b5bcd829b7325ee59ae840adb76 100644 (file)
@@ -291,23 +291,3 @@ void PAL__mm_setcsr(unsigned int i)
 }
 
 #endif // _AMD64_ 
-
-/*++
-Function:
-PAL_memcpy
-
-Overlapping buffer-safe version of memcpy.
-See MSDN doc for memcpy
---*/
-EXTERN_C
-PALIMPORT
-void *PAL_memcpy (void *dest, const void *src, size_t count)
-{
-    UINT_PTR x = (UINT_PTR)dest, y = (UINT_PTR)src;
-    _ASSERTE((x + count <= y) || (y + count <= x));
-    
-    void *ret;
-    #undef memcpy
-    ret = memcpy(dest, src, count);
-    return ret;
-}
diff --git a/src/pal/src/cruntime/thread.cpp b/src/pal/src/cruntime/thread.cpp
deleted file mode 100644 (file)
index bc88e16..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/*++
-
-
-
-Module Name:
-
-    thread.c
-
-Abstract:
-
-    Implementation of the threads/process functions in the C runtime library
-    that are Windows specific.
-
-
-
---*/
-
-#include "pal/palinternal.h"
-#include "pal/dbgmsg.h"
-#include "pal/init.h"
-
-SET_DEFAULT_DEBUG_CHANNEL(CRT);
-
-int
-PAL_atexit(void (__cdecl *function)(void))
-{
-    int ret;
-    
-    PERF_ENTRY(atexit);
-    ENTRY ("atexit(function=%p)\n", function);
-    ret = atexit(function);
-    LOGEXIT ("atexit returns int %d", ret);
-    PERF_EXIT(atexit);
-    return ret;
-}
index fd83b324da6358ef3535b41203cfc5a1e5931cae..aa11eba906698c4373df52f533a8c98e15346c48 100644 (file)
@@ -17,8 +17,6 @@ set(PALRT_SOURCES
     bstr.cpp
     coguid.cpp
     comem.cpp
-    decarith.cpp
-    decconv.cpp
     guid.cpp
     memorystream.cpp
     path.cpp
diff --git a/src/palrt/decarith.cpp b/src/palrt/decarith.cpp
deleted file mode 100644 (file)
index f190707..0000000
+++ /dev/null
@@ -1,1267 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-//
-// ===========================================================================
-// File: decarith.cpp
-// 
-// ===========================================================================
-/***
-*
-*Purpose:
-*  Implement arithmetic for Decimal data type.
-*
-*Implementation Notes:
-*
-*****************************************************************************/
-
-#include "common.h"
-
-#include <oleauto.h>
-#include "convert.h"
-
-//***********************************************************************
-//
-// Additional Decimal and Int64 definitions
-//
-#define COPYDEC(dest, src) {DECIMAL_SIGNSCALE(dest) = DECIMAL_SIGNSCALE(src); DECIMAL_HI32(dest) = DECIMAL_HI32(src); \
-    DECIMAL_MID32(dest) = DECIMAL_MID32(src); DECIMAL_LO32(dest) = DECIMAL_LO32(src); }
-
-#define DEC_SCALE_MAX   28
-#define POWER10_MAX     9
-
-// The following functions are defined in the classlibnative\bcltype\decimal.cpp
-ULONG Div96By32(ULONG *rgulNum, ULONG ulDen);
-ULONG Div96By64(ULONG *rgulNum, SPLIT64 sdlDen);
-ULONG Div128By96(ULONG *rgulNum, ULONG *rgulDen);
-int ScaleResult(ULONG *rgulRes, int iHiRes, int iScale);
-ULONG IncreaseScale(ULONG *rgulNum, ULONG ulPwr);
-
-//***********************************************************************
-//
-// Data tables
-//
-
-static ULONG rgulPower10[POWER10_MAX+1] = {1, 10, 100, 1000, 10000, 100000, 1000000,
-                                           10000000, 100000000, 1000000000};
-
-struct DECOVFL
-{
-    ULONG Hi;
-    ULONG Mid;
-};
-
-static DECOVFL PowerOvfl[] = {
-// This is a table of the largest values that can be in the upper two
-// ULONGs of a 96-bit number that will not overflow when multiplied
-// by a given power.  For the upper word, this is a table of 
-// 2^32 / 10^n for 1 <= n <= 9.  For the lower word, this is the
-// remaining fraction part * 2^32.  2^32 = 4294967296.
-//
-    { 429496729UL, 2576980377UL }, // 10^1 remainder 0.6
-    { 42949672UL,  4123168604UL }, // 10^2 remainder 0.16
-    { 4294967UL,   1271310319UL }, // 10^3 remainder 0.616
-    { 429496UL,    3133608139UL }, // 10^4 remainder 0.1616
-    { 42949UL,     2890341191UL }, // 10^5 remainder 0.51616
-    { 4294UL,      4154504685UL }, // 10^6 remainder 0.551616
-    { 429UL,       2133437386UL }, // 10^7 remainder 0.9551616
-    { 42UL,        4078814305UL }, // 10^8 remainder 0.09991616
-//  { 4UL,         1266874889UL }, // 10^9 remainder 0.709551616
-};
-
-#define OVFL_MAX_9_HI   4
-#define OVFL_MAX_9_MID  1266874889
-
-#define OVFL_MAX_5_HI   42949
-#define OVFL_MAX_5_MID  2890341191
-
-#define OVFL_MAX_1_HI   429496729
-
-
-
-//***********************************************************************
-//
-// static helper functions
-//
-
-/***
-* FullDiv64By32
-*
-* Entry:
-*   pdlNum  - Pointer to 64-bit dividend
-*   ulDen   - 32-bit divisor
-*
-* Purpose:
-*   Do full divide, yielding 64-bit result and 32-bit remainder.
-*
-* Exit:
-*   Quotient overwrites dividend.
-*   Returns remainder.
-*
-* Exceptions:
-*   None.
-*
-***********************************************************************/
-
-ULONG FullDiv64By32(DWORDLONG *pdlNum, ULONG ulDen)
-{
-    SPLIT64  sdlTmp;
-    SPLIT64  sdlRes;
-
-    sdlTmp.int64 = *pdlNum;
-    sdlRes.u.Hi = 0;
-
-    if (sdlTmp.u.Hi >= ulDen) {
-      // DivMod64by32 returns quotient in Lo, remainder in Hi.
-      //
-      sdlRes.u.Lo = sdlTmp.u.Hi;
-      sdlRes.int64 = DivMod64by32(sdlRes.int64, ulDen);
-      sdlTmp.u.Hi = sdlRes.u.Hi;
-      sdlRes.u.Hi = sdlRes.u.Lo;
-    }
-
-    sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulDen);
-    sdlRes.u.Lo = sdlTmp.u.Lo;
-    *pdlNum = sdlRes.int64;
-    return sdlTmp.u.Hi;
-}
-
-
-
-
-/***
-* SearchScale
-*
-* Entry:
-*   ulResHi - Top ULONG of quotient
-*   ulResLo - Middle ULONG of quotient
-*   iScale  - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX
-*
-* Purpose:
-*   Determine the max power of 10, <= 9, that the quotient can be scaled
-*   up by and still fit in 96 bits.
-*
-* Exit:
-*   Returns power of 10 to scale by, -1 if overflow error.
-*
-***********************************************************************/
-
-int SearchScale(ULONG ulResHi, ULONG ulResLo, int iScale)
-{
-    int   iCurScale;
-
-    // Quick check to stop us from trying to scale any more.
-    //
-    if (ulResHi > OVFL_MAX_1_HI || iScale >= DEC_SCALE_MAX) {
-      iCurScale = 0;
-      goto HaveScale;
-    }
-
-    if (iScale > DEC_SCALE_MAX - 9) {
-      // We can't scale by 10^9 without exceeding the max scale factor.
-      // See if we can scale to the max.  If not, we'll fall into
-      // standard search for scale factor.
-      //
-      iCurScale = DEC_SCALE_MAX - iScale;
-      if (ulResHi < PowerOvfl[iCurScale - 1].Hi)
-        goto HaveScale;
-
-      if (ulResHi == PowerOvfl[iCurScale - 1].Hi) {
-  UpperEq:
-        if (ulResLo >= PowerOvfl[iCurScale - 1].Mid)
-          iCurScale--;
-        goto HaveScale;
-      }
-    }
-    else if (ulResHi < OVFL_MAX_9_HI || (ulResHi == OVFL_MAX_9_HI && 
-          ulResLo < OVFL_MAX_9_MID))
-      return 9;
-
-    // Search for a power to scale by < 9.  Do a binary search
-    // on PowerOvfl[].
-    //
-    iCurScale = 5;
-    if (ulResHi < OVFL_MAX_5_HI)
-      iCurScale = 7;
-    else if (ulResHi > OVFL_MAX_5_HI)
-      iCurScale = 3;
-    else
-      goto UpperEq;
-
-    // iCurScale is 3 or 7.
-    //
-    if (ulResHi < PowerOvfl[iCurScale - 1].Hi)
-      iCurScale++;
-    else if (ulResHi > PowerOvfl[iCurScale - 1].Hi)
-      iCurScale--;
-    else
-      goto UpperEq;
-
-    // iCurScale is 2, 4, 6, or 8.
-    //
-    // In all cases, we already found we could not use the power one larger.
-    // So if we can use this power, it is the biggest, and we're done.  If
-    // we can't use this power, the one below it is correct for all cases 
-    // unless it's 10^1 -- we might have to go to 10^0 (no scaling).
-    // 
-    if (ulResHi > PowerOvfl[iCurScale - 1].Hi)
-      iCurScale--;
-
-    if (ulResHi == PowerOvfl[iCurScale - 1].Hi)
-      goto UpperEq;
-
-HaveScale:
-    // iCurScale = largest power of 10 we can scale by without overflow, 
-    // iCurScale < 9.  See if this is enough to make scale factor 
-    // positive if it isn't already.
-    // 
-    if (iCurScale + iScale < 0)
-      iCurScale = -1;
-
-    return iCurScale;
-}
-
-/***
-* DecFixInt
-*
-* Entry:
-*   pdecRes - Pointer to Decimal result location
-*   pdecIn  - Pointer to Decimal operand
-*
-* Purpose:
-*   Chop the value to integer.  Return remainder so Int() function
-*   can round down if non-zero.
-*
-* Exit:
-*   Returns remainder.
-*
-* Exceptions:
-*   None.
-*
-***********************************************************************/
-
-ULONG DecFixInt(LPDECIMAL pdecRes, LPDECIMAL pdecIn)
-{
-    ULONG   rgulNum[3];
-    ULONG   ulRem;
-    ULONG   ulPwr;
-    int     iScale;
-
-    if (pdecIn->u.u.scale > 0) {
-      rgulNum[0] = pdecIn->v.v.Lo32;
-      rgulNum[1] = pdecIn->v.v.Mid32;
-      rgulNum[2] = pdecIn->Hi32;
-      iScale = pdecIn->u.u.scale;
-      pdecRes->u.u.sign = pdecIn->u.u.sign;
-      ulRem = 0;
-
-      do {
-        if (iScale > POWER10_MAX)
-          ulPwr = ulTenToNine;
-        else
-          ulPwr = rgulPower10[iScale];
-
-        ulRem |= Div96By32(rgulNum, ulPwr);
-        iScale -= 9;
-      }while (iScale > 0);
-
-      pdecRes->v.v.Lo32 = rgulNum[0];
-      pdecRes->v.v.Mid32 = rgulNum[1];
-      pdecRes->Hi32 = rgulNum[2];
-      pdecRes->u.u.scale = 0;
-
-      return ulRem;
-    }
-
-    COPYDEC(*pdecRes, *pdecIn)
-    return 0;
-}
-
-
-//***********************************************************************
-//
-// 
-//
-
-//**********************************************************************
-//
-// VarDecMul - Decimal Multiply
-//
-//**********************************************************************
-
-STDAPI VarDecMul(LPDECIMAL pdecL, LPDECIMAL pdecR, LPDECIMAL pdecRes)
-{
-    SPLIT64 sdlTmp;
-    SPLIT64 sdlTmp2;
-    SPLIT64 sdlTmp3;
-    int     iScale;
-    int     iHiProd;
-    ULONG   ulPwr;
-    ULONG   ulRemLo;
-    ULONG   ulRemHi;
-    ULONG   rgulProd[6];
-
-    iScale = pdecL->u.u.scale + pdecR->u.u.scale;
-
-    if ((pdecL->Hi32 | pdecL->v.v.Mid32 | pdecR->Hi32 | pdecR->v.v.Mid32) == 0)
-    {
-      // Upper 64 bits are zero.
-      //
-      sdlTmp.int64 = UInt32x32To64(pdecL->v.v.Lo32, pdecR->v.v.Lo32);
-      if (iScale > DEC_SCALE_MAX)
-      {
-              // Result iScale is too big.  Divide result by power of 10 to reduce it.
-              // If the amount to divide by is > 19 the result is guaranteed
-              // less than 1/2.  [max value in 64 bits = 1.84E19]
-              //
-              iScale -= DEC_SCALE_MAX;
-              if (iScale > 19)
-        {
-ReturnZero:
-                DECIMAL_SETZERO(*pdecRes);
-                return NOERROR;
-              }
-              if (iScale > POWER10_MAX) 
-        {
-                // Divide by 1E10 first, to get the power down to a 32-bit quantity.
-                // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now
-                // then multiply the next divisor by 4 (which will be a max of 4E9).
-                // 
-                ulRemLo = FullDiv64By32(&sdlTmp.int64, ulTenToTenDiv4);
-                ulPwr = rgulPower10[iScale - 10] << 2;
-              }
-              else 
-        {
-                ulPwr = rgulPower10[iScale];
-                ulRemLo = 0;
-              }
-
-              // Power to divide by fits in 32 bits.
-              //
-              ulRemHi = FullDiv64By32(&sdlTmp.int64, ulPwr);
-
-              // Round result.  See if remainder >= 1/2 of divisor.
-              // Divisor is a power of 10, so it is always even.
-              //
-              ulPwr >>= 1;
-              if (ulRemHi >= ulPwr && (ulRemHi > ulPwr || (ulRemLo | (sdlTmp.u.Lo & 1))))
-                sdlTmp.int64++;
-
-        iScale = DEC_SCALE_MAX;
-      }
-      DECIMAL_LO32(*pdecRes) = sdlTmp.u.Lo;
-      DECIMAL_MID32(*pdecRes) = sdlTmp.u.Hi;
-      DECIMAL_HI32(*pdecRes) = 0;
-    }
-    else 
-    {
-
-      // At least one operand has bits set in the upper 64 bits.
-      //
-      // Compute and accumulate the 9 partial products into a 
-      // 192-bit (24-byte) result.
-      //
-      //                [l-h][l-m][l-l]   left high, middle, low
-      //             x  [r-h][r-m][r-l]   right high, middle, low
-      // ------------------------------
-      //
-      //                     [0-h][0-l]   l-l * r-l
-      //                [1ah][1al]        l-l * r-m
-      //                [1bh][1bl]        l-m * r-l
-      //           [2ah][2al]             l-m * r-m
-      //           [2bh][2bl]             l-l * r-h
-      //           [2ch][2cl]             l-h * r-l
-      //      [3ah][3al]                  l-m * r-h
-      //      [3bh][3bl]                  l-h * r-m
-      // [4-h][4-l]                       l-h * r-h
-      // ------------------------------
-      // [p-5][p-4][p-3][p-2][p-1][p-0]   prod[] array
-      //
-      sdlTmp.int64 = UInt32x32To64(pdecL->v.v.Lo32, pdecR->v.v.Lo32);
-      rgulProd[0] = sdlTmp.u.Lo;
-
-      sdlTmp2.int64 = UInt32x32To64(pdecL->v.v.Lo32, pdecR->v.v.Mid32) + sdlTmp.u.Hi;
-
-      sdlTmp.int64 = UInt32x32To64(pdecL->v.v.Mid32, pdecR->v.v.Lo32);
-      sdlTmp.int64 += sdlTmp2.int64; // this could generate carry
-      rgulProd[1] = sdlTmp.u.Lo;
-      if (sdlTmp.int64 < sdlTmp2.int64) // detect carry
-        sdlTmp2.u.Hi = 1;
-      else
-        sdlTmp2.u.Hi = 0;
-      sdlTmp2.u.Lo = sdlTmp.u.Hi;
-
-      sdlTmp.int64 = UInt32x32To64(pdecL->v.v.Mid32, pdecR->v.v.Mid32) + sdlTmp2.int64;
-
-      if (pdecL->Hi32 | pdecR->Hi32) {
-        // Highest 32 bits is non-zero.  Calculate 5 more partial products.
-        //
-        sdlTmp2.int64 = UInt32x32To64(pdecL->v.v.Lo32, pdecR->Hi32);
-        sdlTmp.int64 += sdlTmp2.int64; // this could generate carry
-        if (sdlTmp.int64 < sdlTmp2.int64) // detect carry
-          sdlTmp3.u.Hi = 1;
-        else
-          sdlTmp3.u.Hi = 0;
-
-        sdlTmp2.int64 = UInt32x32To64(pdecL->Hi32, pdecR->v.v.Lo32);
-        sdlTmp.int64 += sdlTmp2.int64; // this could generate carry
-        rgulProd[2] = sdlTmp.u.Lo;
-        if (sdlTmp.int64 < sdlTmp2.int64) // detect carry
-          sdlTmp3.u.Hi++;
-        sdlTmp3.u.Lo = sdlTmp.u.Hi;
-
-        sdlTmp.int64 = UInt32x32To64(pdecL->v.v.Mid32, pdecR->Hi32);
-        sdlTmp.int64 += sdlTmp3.int64; // this could generate carry
-        if (sdlTmp.int64 < sdlTmp3.int64) // detect carry
-          sdlTmp3.u.Hi = 1;
-        else
-          sdlTmp3.u.Hi = 0;
-
-        sdlTmp2.int64 = UInt32x32To64(pdecL->Hi32, pdecR->v.v.Mid32);
-        sdlTmp.int64 += sdlTmp2.int64; // this could generate carry
-        rgulProd[3] = sdlTmp.u.Lo;
-        if (sdlTmp.int64 < sdlTmp2.int64) // detect carry
-          sdlTmp3.u.Hi++;
-        sdlTmp3.u.Lo = sdlTmp.u.Hi;
-
-        sdlTmp.int64 = UInt32x32To64(pdecL->Hi32, pdecR->Hi32) + sdlTmp3.int64;
-        rgulProd[4] = sdlTmp.u.Lo;
-        rgulProd[5] = sdlTmp.u.Hi;
-
-        iHiProd = 5;
-      }
-      else {
-        rgulProd[2] = sdlTmp.u.Lo;
-        rgulProd[3] = sdlTmp.u.Hi;
-        iHiProd = 3;
-      }
-
-      // Check for leading zero ULONGs on the product
-      //
-      while (rgulProd[iHiProd] == 0) {
-        iHiProd--;
-        if (iHiProd < 0)
-          goto ReturnZero;
-      }
-
-      iScale = ScaleResult(rgulProd, iHiProd, iScale);
-      if (iScale == -1)
-        return DISP_E_OVERFLOW;
-
-      pdecRes->v.v.Lo32 = rgulProd[0];
-      pdecRes->v.v.Mid32 = rgulProd[1];
-      pdecRes->Hi32 = rgulProd[2];
-    }
-
-    pdecRes->u.u.sign = pdecR->u.u.sign ^ pdecL->u.u.sign;
-    pdecRes->u.u.scale = (char)iScale;
-    return NOERROR;
-}
-
-
-//**********************************************************************
-//
-// VarDecAdd - Decimal Addition
-// VarDecSub - Decimal Subtraction
-//
-//**********************************************************************
-
-static HRESULT DecAddSub(LPDECIMAL pdecL, LPDECIMAL pdecR, LPDECIMAL pdecRes, char bSign);
-
-STDAPI VarDecAdd(LPDECIMAL pdecL, LPDECIMAL pdecR, LPDECIMAL pdecRes)
-{
-    return DecAddSub(pdecL, pdecR, pdecRes, 0);
-}
-
-
-STDAPI VarDecSub(LPDECIMAL pdecL, LPDECIMAL pdecR, LPDECIMAL pdecRes)
-{
-    return DecAddSub(pdecL, pdecR, pdecRes, DECIMAL_NEG);
-}
-
-
-static HRESULT DecAddSub(LPDECIMAL pdecL, LPDECIMAL pdecR, LPDECIMAL pdecRes, char bSign)
-{
-    ULONG     rgulNum[6];
-    ULONG     ulPwr;
-    int       iScale;
-    int       iHiProd;
-    int       iCur;
-    SPLIT64   sdlTmp;
-    DECIMAL   decRes;
-    DECIMAL   decTmp;
-    LPDECIMAL pdecTmp;
-
-    bSign ^= (pdecR->u.u.sign ^ pdecL->u.u.sign) & DECIMAL_NEG;
-
-    if (pdecR->u.u.scale == pdecL->u.u.scale) {
-      // Scale factors are equal, no alignment necessary.
-      //
-      decRes.u.signscale = pdecL->u.signscale;
-
-AlignedAdd:
-      if (bSign) {
-        // Signs differ - subtract
-        //
-        DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*pdecL) - DECIMAL_LO64_GET(*pdecR));
-        DECIMAL_HI32(decRes) = DECIMAL_HI32(*pdecL) - DECIMAL_HI32(*pdecR);
-
-        // Propagate carry
-        //
-        if (DECIMAL_LO64_GET(decRes) > DECIMAL_LO64_GET(*pdecL)) {
-          decRes.Hi32--;
-          if (decRes.Hi32 >= pdecL->Hi32)
-            goto SignFlip;
-        }
-        else if (decRes.Hi32 > pdecL->Hi32) {
-          // Got negative result.  Flip its sign.
-          //
-SignFlip:
-          DECIMAL_LO64_SET(decRes, -(LONGLONG)DECIMAL_LO64_GET(decRes));
-          decRes.Hi32 = ~decRes.Hi32;
-          if (DECIMAL_LO64_GET(decRes) == 0)
-            decRes.Hi32++;
-          decRes.u.u.sign ^= DECIMAL_NEG;
-        }
-
-      }
-      else {
-        // Signs are the same - add
-        //
-        DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*pdecL) + DECIMAL_LO64_GET(*pdecR));
-        decRes.Hi32 = pdecL->Hi32 + pdecR->Hi32;
-
-        // Propagate carry
-        //
-        if (DECIMAL_LO64_GET(decRes) < DECIMAL_LO64_GET(*pdecL)) {
-          decRes.Hi32++;
-          if (decRes.Hi32 <= pdecL->Hi32)
-            goto AlignedScale;
-        }
-        else if (decRes.Hi32 < pdecL->Hi32) {
-AlignedScale:
-          // The addition carried above 96 bits.  Divide the result by 10,
-          // dropping the scale factor.
-          //
-          if (decRes.u.u.scale == 0)
-            return DISP_E_OVERFLOW;
-          decRes.u.u.scale--;
-
-          sdlTmp.u.Lo = decRes.Hi32;
-          sdlTmp.u.Hi = 1;
-          sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
-          decRes.Hi32 = sdlTmp.u.Lo;
-
-          sdlTmp.u.Lo = decRes.v.v.Mid32;
-          sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
-          decRes.v.v.Mid32 = sdlTmp.u.Lo;
-
-          sdlTmp.u.Lo = decRes.v.v.Lo32;
-          sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
-          decRes.v.v.Lo32 = sdlTmp.u.Lo;
-
-          // See if we need to round up.
-          //
-          if (sdlTmp.u.Hi >= 5 && (sdlTmp.u.Hi > 5 || (decRes.v.v.Lo32 & 1))) {
-            DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(decRes)+1)
-            if (DECIMAL_LO64_GET(decRes) == 0)
-              decRes.Hi32++;
-          }
-        }
-      }
-    }
-    else {
-      // Scale factors are not equal.  Assume that a larger scale
-      // factor (more decimal places) is likely to mean that number
-      // is smaller.  Start by guessing that the right operand has
-      // the larger scale factor.  The result will have the larger
-      // scale factor.
-      //
-      decRes.u.u.scale = pdecR->u.u.scale;  // scale factor of "smaller"
-      decRes.u.u.sign = pdecL->u.u.sign;    // but sign of "larger"
-      iScale = decRes.u.u.scale - pdecL->u.u.scale;
-
-      if (iScale < 0) {
-        // Guessed scale factor wrong. Swap operands.
-        //
-        iScale = -iScale;
-        decRes.u.u.scale = pdecL->u.u.scale;
-        decRes.u.u.sign ^= bSign;
-        pdecTmp = pdecR;
-        pdecR = pdecL;
-        pdecL = pdecTmp;
-      }
-
-      // *pdecL will need to be multiplied by 10^iScale so
-      // it will have the same scale as *pdecR.  We could be
-      // extending it to up to 192 bits of precision.
-      //
-      if (iScale <= POWER10_MAX) {
-        // Scaling won't make it larger than 4 ULONGs
-        //
-        ulPwr = rgulPower10[iScale];
-        DECIMAL_LO64_SET(decTmp, UInt32x32To64(pdecL->v.v.Lo32, ulPwr));
-        sdlTmp.int64 = UInt32x32To64(pdecL->v.v.Mid32, ulPwr);
-        sdlTmp.int64 += decTmp.v.v.Mid32;
-        decTmp.v.v.Mid32 = sdlTmp.u.Lo;
-        decTmp.Hi32 = sdlTmp.u.Hi;
-        sdlTmp.int64 = UInt32x32To64(pdecL->Hi32, ulPwr);
-        sdlTmp.int64 += decTmp.Hi32;
-        if (sdlTmp.u.Hi == 0) {
-          // Result fits in 96 bits.  Use standard aligned add.
-          //
-          decTmp.Hi32 = sdlTmp.u.Lo;
-          pdecL = &decTmp;
-          goto AlignedAdd;
-        }
-        rgulNum[0] = decTmp.v.v.Lo32;
-        rgulNum[1] = decTmp.v.v.Mid32;
-        rgulNum[2] = sdlTmp.u.Lo;
-        rgulNum[3] = sdlTmp.u.Hi;
-        iHiProd = 3;
-      }
-      else {
-        // Have to scale by a bunch.  Move the number to a buffer
-        // where it has room to grow as it's scaled.
-        //
-        rgulNum[0] = pdecL->v.v.Lo32;
-        rgulNum[1] = pdecL->v.v.Mid32;
-        rgulNum[2] = pdecL->Hi32;
-        iHiProd = 2;
-
-        // Scan for zeros in the upper words.
-        //
-        if (rgulNum[2] == 0) {
-          iHiProd = 1;
-          if (rgulNum[1] == 0) {
-            iHiProd = 0;
-            if (rgulNum[0] == 0) {
-              // Left arg is zero, return right.
-              //
-              DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*pdecR));
-              decRes.Hi32 = pdecR->Hi32;
-              decRes.u.u.sign ^= bSign;
-              goto RetDec;
-            }
-          }
-        }
-
-        // Scaling loop, up to 10^9 at a time.  iHiProd stays updated
-        // with index of highest non-zero ULONG.
-        //
-        for (; iScale > 0; iScale -= POWER10_MAX) {
-          if (iScale > POWER10_MAX)
-            ulPwr = ulTenToNine;
-          else
-            ulPwr = rgulPower10[iScale];
-
-          sdlTmp.u.Hi = 0;
-          for (iCur = 0; iCur <= iHiProd; iCur++) {
-            sdlTmp.int64 = UInt32x32To64(rgulNum[iCur], ulPwr) + sdlTmp.u.Hi;
-            rgulNum[iCur] = sdlTmp.u.Lo;
-          }
-
-          if (sdlTmp.u.Hi != 0)
-            // We're extending the result by another ULONG.
-            rgulNum[++iHiProd] = sdlTmp.u.Hi;
-        }
-      }
-
-      // Scaling complete, do the add.  Could be subtract if signs differ.
-      //
-      sdlTmp.u.Lo = rgulNum[0];
-      sdlTmp.u.Hi = rgulNum[1];
-
-      if (bSign) {
-        // Signs differ, subtract.
-        //
-        DECIMAL_LO64_SET(decRes, sdlTmp.int64 - DECIMAL_LO64_GET(*pdecR));
-        decRes.Hi32 = rgulNum[2] - pdecR->Hi32;
-
-        // Propagate carry
-        //
-        if (DECIMAL_LO64_GET(decRes) > sdlTmp.int64) {
-          decRes.Hi32--;
-          if (decRes.Hi32 >= rgulNum[2])
-            goto LongSub;
-        }
-        else if (decRes.Hi32 > rgulNum[2]) {
-LongSub:
-          // If rgulNum has more than 96 bits of precision, then we need to
-          // carry the subtraction into the higher bits.  If it doesn't,
-          // then we subtracted in the wrong order and have to flip the 
-          // sign of the result.
-          // 
-          if (iHiProd <= 2)
-            goto SignFlip;
-
-          iCur = 3;
-          while(rgulNum[iCur++]-- == 0);
-          if (rgulNum[iHiProd] == 0)
-            iHiProd--;
-        }
-      }
-      else {
-        // Signs the same, add.
-        //
-        DECIMAL_LO64_SET(decRes, sdlTmp.int64 + DECIMAL_LO64_GET(*pdecR));
-        decRes.Hi32 = rgulNum[2] + pdecR->Hi32;
-
-        // Propagate carry
-        //
-        if (DECIMAL_LO64_GET(decRes) < sdlTmp.int64) {
-          decRes.Hi32++;
-          if (decRes.Hi32 <= rgulNum[2])
-            goto LongAdd;
-        }
-        else if (decRes.Hi32 < rgulNum[2]) {
-LongAdd:
-          // Had a carry above 96 bits.
-          //
-          iCur = 3;
-          do {
-            if (iHiProd < iCur) {
-              rgulNum[iCur] = 1;
-              iHiProd = iCur;
-              break;
-            }
-          }while (++rgulNum[iCur++] == 0);
-        }
-      }
-
-      if (iHiProd > 2) {
-        rgulNum[0] = decRes.v.v.Lo32;
-        rgulNum[1] = decRes.v.v.Mid32;
-        rgulNum[2] = decRes.Hi32;
-        decRes.u.u.scale = ScaleResult(rgulNum, iHiProd, decRes.u.u.scale);
-        if (decRes.u.u.scale == (BYTE) -1)
-          return DISP_E_OVERFLOW;
-
-        decRes.v.v.Lo32 = rgulNum[0];
-        decRes.v.v.Mid32 = rgulNum[1];
-        decRes.Hi32 = rgulNum[2];
-      }
-    }
-
-RetDec:
-    COPYDEC(*pdecRes, decRes)
-    return NOERROR;
-}
-
-
-//**********************************************************************
-//
-// VarDecDiv - Decimal Divide
-//
-//**********************************************************************
-
-STDAPI VarDecDiv(LPDECIMAL pdecL, LPDECIMAL pdecR, LPDECIMAL pdecRes)
-{
-    ULONG   rgulQuo[3];
-    ULONG   rgulQuoSave[3];
-    ULONG   rgulRem[4];
-    ULONG   rgulDivisor[3];
-    ULONG   ulPwr;
-    ULONG   ulTmp;
-    ULONG   ulTmp1;
-    SPLIT64 sdlTmp;
-    SPLIT64 sdlDivisor;
-    int     iScale;
-    int     iCurScale;
-
-    iScale = pdecL->u.u.scale - pdecR->u.u.scale;
-    rgulDivisor[0] = pdecR->v.v.Lo32;
-    rgulDivisor[1] = pdecR->v.v.Mid32;
-    rgulDivisor[2] = pdecR->Hi32;
-
-    if (rgulDivisor[1] == 0 && rgulDivisor[2] == 0) {
-      // Divisor is only 32 bits.  Easy divide.
-      //
-      if (rgulDivisor[0] == 0)
-        return DISP_E_DIVBYZERO;
-
-      rgulQuo[0] = pdecL->v.v.Lo32;
-      rgulQuo[1] = pdecL->v.v.Mid32;
-      rgulQuo[2] = pdecL->Hi32;
-      rgulRem[0] = Div96By32(rgulQuo, rgulDivisor[0]);
-
-      for (;;) {
-        if (rgulRem[0] == 0) {
-          if (iScale < 0) {
-            iCurScale = min(9, -iScale);
-            goto HaveScale;
-          }
-          break;
-        }
-
-        // We have computed a quotient based on the natural scale 
-        // ( <dividend scale> - <divisor scale> ).  We have a non-zero 
-        // remainder, so now we should increase the scale if possible to 
-        // include more quotient bits.
-        // 
-        // If it doesn't cause overflow, we'll loop scaling by 10^9 and 
-        // computing more quotient bits as long as the remainder stays 
-        // non-zero.  If scaling by that much would cause overflow, we'll 
-        // drop out of the loop and scale by as much as we can.
-        // 
-        // Scaling by 10^9 will overflow if rgulQuo[2].rgulQuo[1] >= 2^32 / 10^9 
-        // = 4.294 967 296.  So the upper limit is rgulQuo[2] == 4 and 
-        // rgulQuo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+.  Since 
-        // quotient bits in rgulQuo[0] could be all 1's, then 1,266,874,888 
-        // is the largest value in rgulQuo[1] (when rgulQuo[2] == 4) that is 
-        // assured not to overflow.
-        // 
-        iCurScale = SearchScale(rgulQuo[2], rgulQuo[1], iScale);
-        if (iCurScale == 0) {
-          // No more scaling to be done, but remainder is non-zero.
-          // Round quotient.
-          //
-          ulTmp = rgulRem[0] << 1;
-          if (ulTmp < rgulRem[0] || (ulTmp >= rgulDivisor[0] &&
-              (ulTmp > rgulDivisor[0] || (rgulQuo[0] & 1)))) {
-RoundUp:
-            if (++rgulQuo[0] == 0)
-              if (++rgulQuo[1] == 0)
-                rgulQuo[2]++;
-          }
-          break;
-        }
-
-        if (iCurScale == -1)
-          return DISP_E_OVERFLOW;
-
-HaveScale:
-        ulPwr = rgulPower10[iCurScale];
-        iScale += iCurScale;
-
-        if (IncreaseScale(rgulQuo, ulPwr) != 0)
-          return DISP_E_OVERFLOW;
-
-        sdlTmp.int64 = DivMod64by32(UInt32x32To64(rgulRem[0], ulPwr), rgulDivisor[0]);
-        rgulRem[0] = sdlTmp.u.Hi;
-
-        rgulQuo[0] += sdlTmp.u.Lo;
-        if (rgulQuo[0] < sdlTmp.u.Lo) {
-          if (++rgulQuo[1] == 0)
-            rgulQuo[2]++;
-        }
-      } // for (;;)
-    }
-    else {
-      // Divisor has bits set in the upper 64 bits.
-      //
-      // Divisor must be fully normalized (shifted so bit 31 of the most 
-      // significant ULONG is 1).  Locate the MSB so we know how much to 
-      // normalize by.  The dividend will be shifted by the same amount so 
-      // the quotient is not changed.
-      //
-      if (rgulDivisor[2] == 0)
-        ulTmp = rgulDivisor[1];
-      else
-        ulTmp = rgulDivisor[2];
-
-      iCurScale = 0;
-      if (!(ulTmp & 0xFFFF0000)) {
-        iCurScale += 16;
-        ulTmp <<= 16;
-      }
-      if (!(ulTmp & 0xFF000000)) {
-        iCurScale += 8;
-        ulTmp <<= 8;
-      }
-      if (!(ulTmp & 0xF0000000)) {
-        iCurScale += 4;
-        ulTmp <<= 4;
-      }
-      if (!(ulTmp & 0xC0000000)) {
-        iCurScale += 2;
-        ulTmp <<= 2;
-      }
-      if (!(ulTmp & 0x80000000)) {
-        iCurScale++;
-        ulTmp <<= 1;
-      }
-    
-      // Shift both dividend and divisor left by iCurScale.
-      // 
-      sdlTmp.int64 = DECIMAL_LO64_GET(*pdecL) << iCurScale;
-      rgulRem[0] = sdlTmp.u.Lo;
-      rgulRem[1] = sdlTmp.u.Hi;
-      sdlTmp.u.Lo = pdecL->v.v.Mid32;
-      sdlTmp.u.Hi = pdecL->Hi32;
-      sdlTmp.int64 <<= iCurScale;
-      rgulRem[2] = sdlTmp.u.Hi;
-      rgulRem[3] = (pdecL->Hi32 >> (31 - iCurScale)) >> 1;
-
-      sdlDivisor.u.Lo = rgulDivisor[0];
-      sdlDivisor.u.Hi = rgulDivisor[1];
-      sdlDivisor.int64 <<= iCurScale;
-
-      if (rgulDivisor[2] == 0) {
-        // Have a 64-bit divisor in sdlDivisor.  The remainder
-        // (currently 96 bits spread over 4 ULONGs) will be < divisor.
-        //
-        sdlTmp.u.Lo = rgulRem[2];
-        sdlTmp.u.Hi = rgulRem[3];
-
-        rgulQuo[2] = 0;
-        rgulQuo[1] = Div96By64(&rgulRem[1], sdlDivisor);
-        rgulQuo[0] = Div96By64(rgulRem, sdlDivisor);
-
-        for (;;) {
-          if ((rgulRem[0] | rgulRem[1]) == 0) {
-            if (iScale < 0) {
-              iCurScale = min(9, -iScale);
-              goto HaveScale64;
-            }
-            break;
-          }
-
-          // Remainder is non-zero.  Scale up quotient and remainder by 
-          // powers of 10 so we can compute more significant bits.
-          // 
-          iCurScale = SearchScale(rgulQuo[2], rgulQuo[1], iScale);
-          if (iCurScale == 0) {
-            // No more scaling to be done, but remainder is non-zero.
-            // Round quotient.
-            //
-            sdlTmp.u.Lo = rgulRem[0];
-            sdlTmp.u.Hi = rgulRem[1];
-            if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
-                (sdlTmp.int64 == sdlDivisor.int64 && (rgulQuo[0] & 1)))
-              goto RoundUp;
-            break;
-          }
-
-          if (iCurScale == -1)
-            return DISP_E_OVERFLOW;
-
-HaveScale64:
-          ulPwr = rgulPower10[iCurScale];
-          iScale += iCurScale;
-
-          if (IncreaseScale(rgulQuo, ulPwr) != 0)
-            return DISP_E_OVERFLOW;
-
-          rgulRem[2] = 0;  // rem is 64 bits, IncreaseScale uses 96
-          IncreaseScale(rgulRem, ulPwr);
-          ulTmp = Div96By64(rgulRem, sdlDivisor);
-          rgulQuo[0] += ulTmp;
-          if (rgulQuo[0] < ulTmp)
-            if (++rgulQuo[1] == 0)
-              rgulQuo[2]++;
-
-        } // for (;;)
-      }
-      else {
-        // Have a 96-bit divisor in rgulDivisor[].
-        //
-        // Start by finishing the shift left by iCurScale.
-        //
-        sdlTmp.u.Lo = rgulDivisor[1];
-        sdlTmp.u.Hi = rgulDivisor[2];
-        sdlTmp.int64 <<= iCurScale;
-        rgulDivisor[0] = sdlDivisor.u.Lo;
-        rgulDivisor[1] = sdlDivisor.u.Hi;
-        rgulDivisor[2] = sdlTmp.u.Hi;
-
-        // The remainder (currently 96 bits spread over 4 ULONGs) 
-        // will be < divisor.
-        // 
-        rgulQuo[2] = 0;
-        rgulQuo[1] = 0;
-        rgulQuo[0] = Div128By96(rgulRem, rgulDivisor);
-
-        for (;;) {
-          if ((rgulRem[0] | rgulRem[1] | rgulRem[2]) == 0) {
-            if (iScale < 0) {
-              iCurScale = min(9, -iScale);
-              goto HaveScale96;
-            }
-            break;
-          }
-
-          // Remainder is non-zero.  Scale up quotient and remainder by 
-          // powers of 10 so we can compute more significant bits.
-          // 
-          iCurScale = SearchScale(rgulQuo[2], rgulQuo[1], iScale);
-          if (iCurScale == 0) {
-            // No more scaling to be done, but remainder is non-zero.
-            // Round quotient.
-            //
-            if (rgulRem[2] >= 0x80000000)
-              goto RoundUp;
-
-            ulTmp = rgulRem[0] > 0x80000000;
-            ulTmp1 = rgulRem[1] > 0x80000000;
-            rgulRem[0] <<= 1;
-            rgulRem[1] = (rgulRem[1] << 1) + ulTmp;
-            rgulRem[2] = (rgulRem[2] << 1) + ulTmp1;
-
-            if (rgulRem[2] > rgulDivisor[2] || (rgulRem[2] == rgulDivisor[2] &&
-                (rgulRem[1] > rgulDivisor[1] || (rgulRem[1] == rgulDivisor[1] &&
-                (rgulRem[0] > rgulDivisor[0] || (rgulRem[0] == rgulDivisor[0] &&
-                (rgulQuo[0] & 1)))))))
-              goto RoundUp;
-            break;
-          }
-
-          if (iCurScale == -1)
-            return DISP_E_OVERFLOW;
-
-HaveScale96:
-          ulPwr = rgulPower10[iCurScale];
-          iScale += iCurScale;
-
-          if (IncreaseScale(rgulQuo, ulPwr) != 0)
-            return DISP_E_OVERFLOW;
-
-          rgulRem[3] = IncreaseScale(rgulRem, ulPwr);
-          ulTmp = Div128By96(rgulRem, rgulDivisor);
-          rgulQuo[0] += ulTmp;
-          if (rgulQuo[0] < ulTmp)
-            if (++rgulQuo[1] == 0)
-              rgulQuo[2]++;
-
-        } // for (;;)
-      }
-    }
-
-    // No more remainder.  Try extracting any extra powers of 10 we may have 
-    // added.  We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
-    // If a division by one of these powers returns a zero remainder, then
-    // we keep the quotient.  If the remainder is not zero, then we restore
-    // the previous value.
-    // 
-    // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
-    // we can extract.  We use this as a quick test on whether to try a
-    // given power.
-    // 
-    while ((rgulQuo[0] & 0xFF) == 0 && iScale >= 8) {
-      rgulQuoSave[0] = rgulQuo[0];
-      rgulQuoSave[1] = rgulQuo[1];
-      rgulQuoSave[2] = rgulQuo[2];
-
-      if (Div96By32(rgulQuoSave, 100000000) == 0) {
-        rgulQuo[0] = rgulQuoSave[0];
-        rgulQuo[1] = rgulQuoSave[1];
-        rgulQuo[2] = rgulQuoSave[2];
-        iScale -= 8;
-      }
-      else
-        break;
-    }
-
-    if ((rgulQuo[0] & 0xF) == 0 && iScale >= 4) {
-      rgulQuoSave[0] = rgulQuo[0];
-      rgulQuoSave[1] = rgulQuo[1];
-      rgulQuoSave[2] = rgulQuo[2];
-
-      if (Div96By32(rgulQuoSave, 10000) == 0) {
-        rgulQuo[0] = rgulQuoSave[0];
-        rgulQuo[1] = rgulQuoSave[1];
-        rgulQuo[2] = rgulQuoSave[2];
-        iScale -= 4;
-      }
-    }
-
-    if ((rgulQuo[0] & 3) == 0 && iScale >= 2) {
-      rgulQuoSave[0] = rgulQuo[0];
-      rgulQuoSave[1] = rgulQuo[1];
-      rgulQuoSave[2] = rgulQuo[2];
-
-      if (Div96By32(rgulQuoSave, 100) == 0) {
-        rgulQuo[0] = rgulQuoSave[0];
-        rgulQuo[1] = rgulQuoSave[1];
-        rgulQuo[2] = rgulQuoSave[2];
-        iScale -= 2;
-      }
-    }
-
-    if ((rgulQuo[0] & 1) == 0 && iScale >= 1) {
-      rgulQuoSave[0] = rgulQuo[0];
-      rgulQuoSave[1] = rgulQuo[1];
-      rgulQuoSave[2] = rgulQuo[2];
-
-      if (Div96By32(rgulQuoSave, 10) == 0) {
-        rgulQuo[0] = rgulQuoSave[0];
-        rgulQuo[1] = rgulQuoSave[1];
-        rgulQuo[2] = rgulQuoSave[2];
-        iScale -= 1;
-      }
-    }
-
-    pdecRes->Hi32 = rgulQuo[2];
-    pdecRes->v.v.Mid32 = rgulQuo[1];
-    pdecRes->v.v.Lo32 = rgulQuo[0];
-    pdecRes->u.u.scale = iScale;
-    pdecRes->u.u.sign = pdecL->u.u.sign ^ pdecR->u.u.sign;
-    return NOERROR;
-}
-
-
-//**********************************************************************
-//
-// VarDecAbs - Decimal Absolute Value
-//
-//**********************************************************************
-
-STDAPI VarDecAbs(LPDECIMAL pdecOprd, LPDECIMAL pdecRes)
-{
-    COPYDEC(*pdecRes, *pdecOprd)
-    pdecRes->u.u.sign &= ~DECIMAL_NEG;
-    return NOERROR;
-}
-
-
-//**********************************************************************
-//
-// VarDecFix - Decimal Fix (chop to integer)
-//
-//**********************************************************************
-
-STDAPI VarDecFix(LPDECIMAL pdecOprd, LPDECIMAL pdecRes)
-{
-    DecFixInt(pdecRes, pdecOprd);
-    return NOERROR;
-}
-
-
-//**********************************************************************
-//
-// VarDecInt - Decimal Int (round down to integer)
-//
-//**********************************************************************
-
-STDAPI VarDecInt(LPDECIMAL pdecOprd, LPDECIMAL pdecRes)
-{
-    if (DecFixInt(pdecRes, pdecOprd) != 0 && (pdecRes->u.u.sign & DECIMAL_NEG)) {
-      // We have chopped off a non-zero amount from a negative value.  Since
-      // we round toward -infinity, we must increase the integer result by
-      // 1 to make it more negative.  This will never overflow because
-      // in order to have a remainder, we must have had a non-zero scale factor.
-      // Our scale factor is back to zero now.
-      //
-      DECIMAL_LO64_SET(*pdecRes, DECIMAL_LO64_GET(*pdecRes) + 1);
-      if (DECIMAL_LO64_GET(*pdecRes) == 0)
-        pdecRes->Hi32++;
-    }
-    return NOERROR;
-}
-
-
-//**********************************************************************
-//
-// VarDecNeg - Decimal Negate
-//
-//**********************************************************************
-
-STDAPI VarDecNeg(LPDECIMAL pdecOprd, LPDECIMAL pdecRes)
-{
-    COPYDEC(*pdecRes, *pdecOprd)
-    pdecRes->u.u.sign ^= DECIMAL_NEG;
-    return NOERROR;
-}
-
-
-//**********************************************************************
-//
-// VarDecCmp - Decimal Compare
-//
-//**********************************************************************
-
-STDAPI VarDecCmp(LPDECIMAL pdecL, LPDECIMAL pdecR)
-{
-    ULONG   ulSgnL;
-    ULONG   ulSgnR;
-
-    // First check signs and whether either are zero.  If both are
-    // non-zero and of the same sign, just use subtraction to compare.
-    //
-    ulSgnL = pdecL->v.v.Lo32 | pdecL->v.v.Mid32 | pdecL->Hi32;
-    ulSgnR = pdecR->v.v.Lo32 | pdecR->v.v.Mid32 | pdecR->Hi32;
-    if (ulSgnL != 0)
-      ulSgnL = (pdecL->u.u.sign & DECIMAL_NEG) | 1;
-
-    if (ulSgnR != 0)
-      ulSgnR = (pdecR->u.u.sign & DECIMAL_NEG) | 1;
-
-    // ulSgnL & ulSgnR have values 1, 0, or 0x81 depending on if the left/right
-    // operand is +, 0, or -.
-    //
-    if (ulSgnL == ulSgnR) {
-      if (ulSgnL == 0)    // both are zero
-        return VARCMP_EQ; // return equal
-
-      DECIMAL decRes;
-
-      DecAddSub(pdecL, pdecR, &decRes, DECIMAL_NEG);
-      if (DECIMAL_LO64_GET(decRes) == 0 && decRes.Hi32 == 0)
-        return VARCMP_EQ;
-      if (decRes.u.u.sign & DECIMAL_NEG)
-        return VARCMP_LT;
-      return VARCMP_GT;
-    }
-
-    // Signs are different.  Used signed byte compares
-    //
-    if ((char)ulSgnL > (char)ulSgnR)
-      return VARCMP_GT;
-    return VARCMP_LT;
-}
-
-STDAPI VarDecRound(LPDECIMAL pdecIn, int cDecimals, LPDECIMAL pdecRes)
-{
-    ULONG   rgulNum[3];
-    ULONG   ulRem;
-    ULONG   ulSticky;
-    ULONG   ulPwr;
-    int            iScale;
-
-    if (cDecimals < 0)
-      return E_INVALIDARG;
-
-    iScale = pdecIn->u.u.scale - cDecimals;
-    if (iScale > 0)
-    {
-      rgulNum[0] = pdecIn->v.v.Lo32;
-      rgulNum[1] = pdecIn->v.v.Mid32;
-      rgulNum[2] = pdecIn->Hi32;
-      pdecRes->u.u.sign = pdecIn->u.u.sign;
-      ulRem = ulSticky = 0;
-
-      do {
-       ulSticky |= ulRem;
-       if (iScale > POWER10_MAX)
-         ulPwr = ulTenToNine;
-       else
-         ulPwr = rgulPower10[iScale];
-
-       ulRem = Div96By32(rgulNum, ulPwr);
-       iScale -= 9;
-      }while (iScale > 0);
-
-      // Now round.  ulRem has last remainder, ulSticky has sticky bits.
-      // To do IEEE rounding, we add LSB of result to sticky bits so
-      // either causes round up if remainder * 2 == last divisor.
-      //
-      ulSticky |= rgulNum[0] & 1;
-      ulRem = (ulRem << 1) + (ulSticky != 0);
-      if (ulPwr < ulRem &&
-         ++rgulNum[0] == 0 &&
-         ++rgulNum[1] == 0
-        )
-       ++rgulNum[2];
-
-      pdecRes->v.v.Lo32 = rgulNum[0];
-      pdecRes->v.v.Mid32 = rgulNum[1];
-      pdecRes->Hi32 = rgulNum[2];
-      pdecRes->u.u.scale = cDecimals;
-      return NOERROR;
-    }
-
-    COPYDEC(*pdecRes, *pdecIn)
-    return NOERROR;
-}
diff --git a/src/palrt/decconv.cpp b/src/palrt/decconv.cpp
deleted file mode 100644 (file)
index 9cb7575..0000000
+++ /dev/null
@@ -1,602 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//
-
-//
-// ===========================================================================
-// File: decconv.cpp
-// 
-// ===========================================================================
-/***
-*
-*Purpose:
-*  This module contains the low level conversion for Decimal data type.
-*
-*Implementation Notes:
-*
-*****************************************************************************/
-
-#include "common.h"
-#include "convert.h"
-
-#include <oleauto.h>
-#include <math.h>
-#include <limits.h>
-
-#define VALIDATEDECIMAL(dec) \
-    if (DECIMAL_SCALE(dec) > DECMAX || (DECIMAL_SIGN(dec) & ~DECIMAL_NEG) != 0) \
-        return E_INVALIDARG;
-
-#define RESULT(X)   ((HRESULT)(X))
-        
-//***********************************************************************
-//
-// Data tables
-//
-
-const double dblPower10[] = {
-    1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 
-    1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 
-    1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 
-    1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, 
-    1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49, 
-    1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
-    1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69, 
-    1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
-    1e80 };
-
-double fnDblPower10(int ix)
-{
-    const int maxIx = (sizeof(dblPower10)/sizeof(dblPower10[0]));
-    _ASSERTE(ix >= 0);
-    if (ix < maxIx)
-        return dblPower10[ix];
-    return pow(10.0, ix);
-} // double fnDblPower10()
-
-#define DBLBIAS 1022
-#define SNGBIAS 126
-#define DECMAX 28
-
-const SPLIT64    sdlTenToEighteen = { UI64(1000000000000000000) };
-const DBLSTRUCT ds2to64 = DEFDS(0, 0, DBLBIAS + 65, 0);
-
-//***********************************************************************
-//
-// Data tables
-//
-
-const SPLIT64 sdlPower10[] = { {UI64(10000000000)},          // 1E10
-                          {UI64(100000000000)},     // 1E11
-                          {UI64(1000000000000)},    // 1E12
-                          {UI64(10000000000000)},   // 1E13
-                          {UI64(100000000000000)} }; // 1E14
-
-const unsigned __int64 ulPower10[] = {1,
-                    UI64(10),
-                    UI64(100),
-                    UI64(1000),
-                    UI64(10000),
-                    UI64(100000),
-                    UI64(1000000),
-                    UI64(10000000),
-                    UI64(100000000),
-                    UI64(1000000000),
-                    UI64(10000000000),
-                    UI64(100000000000),
-                    UI64(1000000000000),
-                    UI64(10000000000000),
-                    UI64(100000000000000),
-                    UI64(1000000000000000),
-                    UI64(10000000000000000),
-                    UI64(100000000000000000),
-                    UI64(1000000000000000000),
-                    UI64(10000000000000000000)};
-
-DWORDLONG UInt64x64To128(SPLIT64 sdlOp1, SPLIT64 sdlOp2, DWORDLONG *pdlHi)
-{
-    SPLIT64  sdlTmp1;
-    SPLIT64  sdlTmp2;
-    SPLIT64  sdlTmp3;
-
-    sdlTmp1.int64 = UInt32x32To64(sdlOp1.u.Lo, sdlOp2.u.Lo); // lo partial prod
-    sdlTmp2.int64 = UInt32x32To64(sdlOp1.u.Lo, sdlOp2.u.Hi); // mid 1 partial prod
-    sdlTmp1.u.Hi += sdlTmp2.u.Lo;
-    if (sdlTmp1.u.Hi < sdlTmp2.u.Lo)  // test for carry
-      sdlTmp2.u.Hi++;
-    sdlTmp3.int64 = UInt32x32To64(sdlOp1.u.Hi, sdlOp2.u.Hi) + (DWORDLONG)sdlTmp2.u.Hi;
-    sdlTmp2.int64 = UInt32x32To64(sdlOp1.u.Hi, sdlOp2.u.Lo);
-    sdlTmp1.u.Hi += sdlTmp2.u.Lo;
-    if (sdlTmp1.u.Hi < sdlTmp2.u.Lo)  // test for carry
-      sdlTmp2.u.Hi++;
-    sdlTmp3.int64 += (DWORDLONG)sdlTmp2.u.Hi;
-
-    *pdlHi = sdlTmp3.int64;
-    return sdlTmp1.int64;
-}
-
-                    
-//***********************************************************************
-//
-// Conversion to/from Decimal data type
-//
-
-
-STDAPI 
-VarDecFromR4(float fltIn, DECIMAL FAR* pdecOut)
-{
-    int         iExp;    // number of bits to left of binary point
-    int         iPower;
-    ULONG       ulMant;
-    double      dbl;
-    SPLIT64     sdlLo;
-    SPLIT64     sdlHi;
-    int         lmax, cur;  // temps used during scale reduction
-
-    // The most we can scale by is 10^28, which is just slightly more
-    // than 2^93.  So a float with an exponent of -94 could just
-    // barely reach 0.5, but smaller exponents will always round to zero.
-    //
-    if ( (iExp = ((SNGSTRUCT *)&fltIn)->exp - SNGBIAS) < -94 )
-    {
-      DECIMAL_SETZERO(*pdecOut);
-      return NOERROR;
-    }
-
-    if (iExp > 96)
-      return RESULT(DISP_E_OVERFLOW);
-
-    // Round the input to a 7-digit integer.  The R4 format has
-    // only 7 digits of precision, and we want to keep garbage digits
-    // out of the Decimal were making.
-    //
-    // Calculate max power of 10 input value could have by multiplying 
-    // the exponent by log10(2).  Using scaled integer multiplcation, 
-    // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
-    //
-    dbl = fabs(fltIn);
-    iPower = 6 - ((iExp * 19728) >> 16);
-
-    if (iPower >= 0) {
-      // We have less than 7 digits, scale input up.
-      //
-      if (iPower > DECMAX)
-        iPower = DECMAX;
-
-      dbl = dbl * dblPower10[iPower];
-    }
-    else {
-      if (iPower != -1 || dbl >= 1E7)
-        dbl = dbl / fnDblPower10(-iPower);
-      else 
-        iPower = 0; // didn't scale it
-    }
-
-    _ASSERTE(dbl < 1E7);
-    if (dbl < 1E6 && iPower < DECMAX)
-    {
-      dbl *= 10;
-      iPower++;
-      _ASSERTE(dbl >= 1E6);
-    }
-
-    // Round to integer
-    //
-    ulMant = (LONG)dbl;
-    dbl -= (double)ulMant;  // difference between input & integer
-    if ( dbl > 0.5 || (dbl == 0.5 && (ulMant & 1)) )
-      ulMant++;
-
-    if (ulMant == 0)
-    {
-      DECIMAL_SETZERO(*pdecOut);
-      return NOERROR;
-    }
-
-    if (iPower < 0) {
-      // Add -iPower factors of 10, -iPower <= (29 - 7) = 22.
-      //
-      iPower = -iPower;
-      if (iPower < 10) {
-        sdlLo.int64 = UInt32x32To64(ulMant, (ULONG)ulPower10[iPower]);
-
-        DECIMAL_LO32(*pdecOut) = sdlLo.u.Lo;
-        DECIMAL_MID32(*pdecOut) = sdlLo.u.Hi;
-        DECIMAL_HI32(*pdecOut) = 0;
-      }
-      else {
-        // Have a big power of 10.
-        //
-        if (iPower > 18) {
-          sdlLo.int64 = UInt32x32To64(ulMant, (ULONG)ulPower10[iPower - 18]);
-          sdlLo.int64 = UInt64x64To128(sdlLo, sdlTenToEighteen, &sdlHi.int64);
-
-          if (sdlHi.u.Hi != 0)
-            return RESULT(DISP_E_OVERFLOW);
-        }
-        else {
-          sdlLo.int64 = UInt32x32To64(ulMant, (ULONG)ulPower10[iPower - 9]);
-          sdlHi.int64 = UInt32x32To64(ulTenToNine, sdlLo.u.Hi);
-          sdlLo.int64 = UInt32x32To64(ulTenToNine, sdlLo.u.Lo);
-          sdlHi.int64 += sdlLo.u.Hi;
-          sdlLo.u.Hi = sdlHi.u.Lo;
-          sdlHi.u.Lo = sdlHi.u.Hi;
-        }
-        DECIMAL_LO32(*pdecOut) = sdlLo.u.Lo;
-        DECIMAL_MID32(*pdecOut) = sdlLo.u.Hi;
-        DECIMAL_HI32(*pdecOut) = sdlHi.u.Lo;
-      }
-      DECIMAL_SCALE(*pdecOut) = 0;
-    }
-    else {
-      // Factor out powers of 10 to reduce the scale, if possible.
-      // The maximum number we could factor out would be 6.  This
-      // comes from the fact we have a 7-digit number, and the
-      // MSD must be non-zero -- but the lower 6 digits could be
-      // zero.  Note also the scale factor is never negative, so
-      // we can't scale by any more than the power we used to
-      // get the integer.
-      //
-      // DivMod32by32 returns the quotient in Lo, the remainder in Hi.
-      //
-      lmax = min(iPower, 6);
-
-      // lmax is the largest power of 10 to try, lmax <= 6.
-      // We'll try powers 4, 2, and 1 unless they're too big.
-      //
-      for (cur = 4; cur > 0; cur >>= 1)
-      {
-        if (cur > lmax)
-          continue;
-
-        sdlLo.int64 = DivMod32by32(ulMant, (ULONG)ulPower10[cur]);
-
-        if (sdlLo.u.Hi == 0) {
-          ulMant = sdlLo.u.Lo;
-          iPower -= cur;
-          lmax -= cur;
-        }
-      }
-      DECIMAL_LO32(*pdecOut) = ulMant;
-      DECIMAL_MID32(*pdecOut) = 0;
-      DECIMAL_HI32(*pdecOut) = 0;
-      DECIMAL_SCALE(*pdecOut) = iPower;
-    }
-
-    DECIMAL_SIGN(*pdecOut) = (char)((SNGSTRUCT *)&fltIn)->sign << 7;
-    return NOERROR;
-}
-
-STDAPI 
-VarDecFromR8(double dblIn, DECIMAL FAR* pdecOut)
-{
-    int         iExp;    // number of bits to left of binary point
-    int         iPower;  // power-of-10 scale factor
-    SPLIT64     sdlMant;
-    SPLIT64     sdlLo;
-    double      dbl;
-    int         lmax, cur;  // temps used during scale reduction
-    ULONG       ulPwrCur;
-    ULONG       ulQuo;
-
-
-    // The most we can scale by is 10^28, which is just slightly more
-    // than 2^93.  So a float with an exponent of -94 could just
-    // barely reach 0.5, but smaller exponents will always round to zero.
-    //
-    if ( (iExp = ((DBLSTRUCT *)&dblIn)->u.exp - DBLBIAS) < -94 )
-    {
-      DECIMAL_SETZERO(*pdecOut);
-      return NOERROR;
-    }
-
-    if (iExp > 96)
-      return RESULT(DISP_E_OVERFLOW);
-
-    // Round the input to a 15-digit integer.  The R8 format has
-    // only 15 digits of precision, and we want to keep garbage digits
-    // out of the Decimal were making.
-    //
-    // Calculate max power of 10 input value could have by multiplying 
-    // the exponent by log10(2).  Using scaled integer multiplcation, 
-    // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
-    //
-    dbl = fabs(dblIn);
-    iPower = 14 - ((iExp * 19728) >> 16);
-
-    if (iPower >= 0) {
-      // We have less than 15 digits, scale input up.
-      //
-      if (iPower > DECMAX)
-        iPower = DECMAX;
-
-      dbl = dbl * dblPower10[iPower];
-    }
-    else {
-      if (iPower != -1 || dbl >= 1E15)
-        dbl = dbl / fnDblPower10(-iPower);
-      else 
-        iPower = 0; // didn't scale it
-    }
-
-    _ASSERTE(dbl < 1E15);
-    if (dbl < 1E14 && iPower < DECMAX)
-    {
-      dbl *= 10;
-      iPower++;
-      _ASSERTE(dbl >= 1E14);
-    }
-
-    // Round to int64
-    //
-    sdlMant.int64 = (LONGLONG)dbl;
-    dbl -= (double)(LONGLONG)sdlMant.int64;  // dif between input & integer
-    if ( dbl > 0.5 || (dbl == 0.5 && (sdlMant.u.Lo & 1)) )
-      sdlMant.int64++;
-
-    if (sdlMant.int64 == 0)
-    {
-      DECIMAL_SETZERO(*pdecOut);
-      return NOERROR;
-    }
-
-    if (iPower < 0) {
-      // Add -iPower factors of 10, -iPower <= (29 - 15) = 14.
-      //
-      iPower = -iPower;
-      if (iPower < 10) {
-        sdlLo.int64 = UInt32x32To64(sdlMant.u.Lo, (ULONG)ulPower10[iPower]);
-        sdlMant.int64 = UInt32x32To64(sdlMant.u.Hi, (ULONG)ulPower10[iPower]);
-        sdlMant.int64 += sdlLo.u.Hi;
-        sdlLo.u.Hi = sdlMant.u.Lo;
-        sdlMant.u.Lo = sdlMant.u.Hi;
-      }
-      else {
-        // Have a big power of 10.
-        //
-        _ASSERTE(iPower <= 14);
-        sdlLo.int64 = UInt64x64To128(sdlMant, sdlPower10[iPower-10], &sdlMant.int64);
-
-        if (sdlMant.u.Hi != 0)
-          return RESULT(DISP_E_OVERFLOW);
-      }
-      DECIMAL_LO32(*pdecOut) = sdlLo.u.Lo;
-      DECIMAL_MID32(*pdecOut) = sdlLo.u.Hi;
-      DECIMAL_HI32(*pdecOut) = sdlMant.u.Lo;
-      DECIMAL_SCALE(*pdecOut) = 0;
-    }
-    else {
-      // Factor out powers of 10 to reduce the scale, if possible.
-      // The maximum number we could factor out would be 14.  This
-      // comes from the fact we have a 15-digit number, and the 
-      // MSD must be non-zero -- but the lower 14 digits could be 
-      // zero.  Note also the scale factor is never negative, so
-      // we can't scale by any more than the power we used to
-      // get the integer.
-      //
-      // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
-      //
-      lmax = min(iPower, 14);
-
-      // lmax is the largest power of 10 to try, lmax <= 14.
-      // We'll try powers 8, 4, 2, and 1 unless they're too big.
-      //
-      for (cur = 8; cur > 0; cur >>= 1)
-      {
-        if (cur > lmax)
-          continue;
-
-        ulPwrCur = (ULONG)ulPower10[cur];
-
-        if (sdlMant.u.Hi >= ulPwrCur) {
-          // Overflow if we try to divide in one step.
-          //
-          sdlLo.int64 = DivMod64by32(sdlMant.u.Hi, ulPwrCur);
-          ulQuo = sdlLo.u.Lo;
-          sdlLo.u.Lo = sdlMant.u.Lo;
-          sdlLo.int64 = DivMod64by32(sdlLo.int64, ulPwrCur);
-        }
-        else {
-          ulQuo = 0;
-          sdlLo.int64 = DivMod64by32(sdlMant.int64, ulPwrCur);
-        }
-
-        if (sdlLo.u.Hi == 0) {
-          sdlMant.u.Hi = ulQuo;
-          sdlMant.u.Lo = sdlLo.u.Lo;
-          iPower -= cur;
-          lmax -= cur;
-        }
-      }
-
-      DECIMAL_HI32(*pdecOut) = 0;
-      DECIMAL_SCALE(*pdecOut) = iPower;
-      DECIMAL_LO32(*pdecOut) = sdlMant.u.Lo;
-      DECIMAL_MID32(*pdecOut) = sdlMant.u.Hi;
-    }
-
-    DECIMAL_SIGN(*pdecOut) = (char)((DBLSTRUCT *)&dblIn)->u.sign << 7;
-    return NOERROR;
-}
-
-STDAPI
-VarDecFromCy(CY cyIn, DECIMAL FAR* pdecOut)
-{
-    DECIMAL_SIGN(*pdecOut) = (UCHAR)((cyIn.u.Hi >> 24) & DECIMAL_NEG);
-    if (DECIMAL_SIGN(*pdecOut))
-      cyIn.int64 = -cyIn.int64;
-
-    DECIMAL_LO32(*pdecOut) = cyIn.u.Lo;
-    DECIMAL_MID32(*pdecOut) = cyIn.u.Hi;
-    DECIMAL_SCALE(*pdecOut) = 4;
-    DECIMAL_HI32(*pdecOut) = 0;
-    return NOERROR;
-}
-
-STDAPI VarR4FromDec(DECIMAL FAR* pdecIn, float FAR* pfltOut)
-{
-    double   dbl;
-
-    VALIDATEDECIMAL(*pdecIn); // E_INVALIDARG check
-
-    // Can't overflow; no errors possible.
-    //
-    VarR8FromDec(pdecIn, &dbl);
-    *pfltOut = (float)dbl;
-    return NOERROR;
-}
-
-STDAPI VarR8FromDec(DECIMAL FAR* pdecIn, double FAR* pdblOut)
-{
-    SPLIT64  sdlTmp;
-    double   dbl;
-
-    VALIDATEDECIMAL(*pdecIn); // E_INVALIDARG check
-
-    sdlTmp.u.Lo = DECIMAL_LO32(*pdecIn);
-    sdlTmp.u.Hi = DECIMAL_MID32(*pdecIn);
-
-    if ( (LONG)DECIMAL_MID32(*pdecIn) < 0 )
-      dbl = (ds2to64.dbl + (double)(LONGLONG)sdlTmp.int64 +
-             (double)DECIMAL_HI32(*pdecIn) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*pdecIn)) ;
-    else
-      dbl = ((double)(LONGLONG)sdlTmp.int64 +
-             (double)DECIMAL_HI32(*pdecIn) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*pdecIn));
-
-    if (DECIMAL_SIGN(*pdecIn))
-      dbl = -dbl;
-
-    *pdblOut = dbl;
-    return NOERROR;
-}
-
-STDAPI VarCyFromDec(DECIMAL FAR* pdecIn, CY FAR* pcyOut)
-{
-    SPLIT64  sdlTmp;
-    SPLIT64  sdlTmp1;
-    int      scale;
-    ULONG    ulPwr;
-    ULONG    ul;
-
-    VALIDATEDECIMAL(*pdecIn); // E_INVALIDARG check
-
-    scale = DECIMAL_SCALE(*pdecIn) - 4;  // the power of 10 to divide by
-
-    if (scale == 0) {
-      // No scaling needed -- the Decimal has 4 decimal places,
-      // just what Currency needs.
-      //
-      if ( DECIMAL_HI32(*pdecIn) != 0 ||
-          (DECIMAL_MID32(*pdecIn) >= 0x80000000 &&
-          (DECIMAL_MID32(*pdecIn) != 0x80000000 || DECIMAL_LO32(*pdecIn) != 0 || !DECIMAL_SIGN(*pdecIn))) )
-        return RESULT(DISP_E_OVERFLOW);
-
-      sdlTmp.u.Lo = DECIMAL_LO32(*pdecIn);
-      sdlTmp.u.Hi = DECIMAL_MID32(*pdecIn);
-
-      if (DECIMAL_SIGN(*pdecIn))
-        pcyOut->int64 = -(LONGLONG)sdlTmp.int64;
-      else
-        pcyOut->int64 = sdlTmp.int64;
-      return NOERROR;
-    }
-
-    // Need to scale to get 4 decimal places.  -4 <= scale <= 24.
-    //
-    if (scale < 0) {
-      sdlTmp1.int64 = UInt32x32To64((ULONG)ulPower10[-scale], DECIMAL_MID32(*pdecIn));
-      sdlTmp.int64 = UInt32x32To64((ULONG)ulPower10[-scale], DECIMAL_LO32(*pdecIn));
-      sdlTmp.u.Hi += sdlTmp1.u.Lo;
-      if (DECIMAL_HI32(*pdecIn) != 0 || sdlTmp1.u.Hi != 0 || sdlTmp1.u.Lo > sdlTmp.u.Hi)
-        return RESULT(DISP_E_OVERFLOW);
-    }
-    else if (scale < 10) {
-      // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
-      //
-      ulPwr = (ULONG)ulPower10[scale];
-      if (DECIMAL_HI32(*pdecIn) >= ulPwr)
-        return RESULT(DISP_E_OVERFLOW);
-      sdlTmp1.u.Lo = DECIMAL_MID32(*pdecIn);
-      sdlTmp1.u.Hi = DECIMAL_HI32(*pdecIn);
-      sdlTmp1.int64 = DivMod64by32(sdlTmp1.int64, ulPwr);
-      sdlTmp.u.Hi = sdlTmp1.u.Lo;    // quotient to high half of result
-      sdlTmp1.u.Lo = DECIMAL_LO32(*pdecIn); // extended remainder
-      sdlTmp1.int64 = DivMod64by32(sdlTmp1.int64, ulPwr);
-      sdlTmp.u.Lo = sdlTmp1.u.Lo;    // quotient to low half of result
-
-      // Round result based on remainder in sdlTmp1.Hi.
-      //
-      ulPwr >>= 1;  // compare to power/2 (power always even)
-      if (sdlTmp1.u.Hi > ulPwr || (sdlTmp1.u.Hi == ulPwr && (sdlTmp.u.Lo & 1)))
-        sdlTmp.int64++;
-    }
-    else {
-      // We have a power of 10 in the range 10 - 24.  These powers do
-      // not fit in 32 bits.  We'll handle this by scaling 2 or 3 times,
-      // first by 10^10, then by the remaining amount (or 10^9, then
-      // the last bit).
-      //
-      // To scale by 10^10, we'll actually divide by 10^10/4, which fits
-      // in 32 bits.  The second scaling is multiplied by four
-      // to account for it, just barely assured of fitting in 32 bits
-      // (4E9 < 2^32).  Note that the upper third of the quotient is
-      // either zero or one, so we skip the divide step to calculate it.  
-      // (Max 4E9 divided by 2.5E9.)
-      //
-      // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
-      //
-      if (DECIMAL_HI32(*pdecIn) >= ulTenToTenDiv4) {
-        sdlTmp.u.Hi = 1;                // upper 1st quotient
-        sdlTmp1.u.Hi = DECIMAL_HI32(*pdecIn) - ulTenToTenDiv4;  // remainder
-      }
-      else {
-        sdlTmp.u.Hi = 0;                // upper 1st quotient
-        sdlTmp1.u.Hi = DECIMAL_HI32(*pdecIn);    // remainder
-      }
-      sdlTmp1.u.Lo = DECIMAL_MID32(*pdecIn);     // extended remainder
-      sdlTmp1.int64 = DivMod64by32(sdlTmp1.int64, ulTenToTenDiv4);
-      sdlTmp.u.Lo = sdlTmp1.u.Lo;         // middle 1st quotient
-
-      sdlTmp1.u.Lo = DECIMAL_LO32(*pdecIn);      // extended remainder
-      sdlTmp1.int64 = DivMod64by32(sdlTmp1.int64, ulTenToTenDiv4);
-
-      ulPwr = (ULONG)(ulPower10[min(scale-10, 9)] << 2);
-      sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulPwr);
-      ul = sdlTmp.u.Lo;                 // upper 2nd quotient
-
-      sdlTmp.u.Lo = sdlTmp1.u.Lo;         // extended remainder
-      sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulPwr);
-      sdlTmp1.u.Lo = sdlTmp.u.Hi;         // save final remainder
-      sdlTmp.u.Hi = ul;                 // position high result
-
-      if (scale >= 20) {
-        ulPwr = (ULONG)(ulPower10[scale-19]);
-        sdlTmp.int64 = DivMod64by32(sdlTmp.int64, ulPwr);
-        sdlTmp1.u.Hi |= sdlTmp1.u.Lo;     // combine sticky bits
-        sdlTmp1.u.Lo = sdlTmp.u.Hi;       // final remainder
-        sdlTmp.u.Hi = 0;                // guaranteed result fits in 32 bits
-      }
-
-      // Round result based on remainder in sdlTmp1.Lo.  sdlTmp1.Hi is
-      // the remainder from the first division(s), representing sticky bits.
-      // Current result is in sdlTmp.
-      //
-      ulPwr >>= 1;  // compare to power/2 (power always even)
-      if (sdlTmp1.u.Lo > ulPwr || (sdlTmp1.u.Lo == ulPwr &&
-                       ((sdlTmp.u.Lo & 1) || sdlTmp1.u.Hi != 0)))
-        sdlTmp.int64++;
-    }
-
-    if (sdlTmp.u.Hi >= 0x80000000 &&
-        (sdlTmp.int64 != UI64(0x8000000000000000) || !DECIMAL_SIGN(*pdecIn)))
-      return RESULT(DISP_E_OVERFLOW);
-
-    if (DECIMAL_SIGN(*pdecIn))
-      sdlTmp.int64 = -(LONGLONG)sdlTmp.int64;
-
-    pcyOut->int64 = sdlTmp.int64;
-    return NOERROR;
-}
-
-