Guest User

Untitled

a guest
Aug 6th, 2021
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 82.66 KB | None | 0 0
  1. //
  2. // Copyright (c) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  4. //
  5. // Copyright 2015 Xamarin Inc
  6. //
  7. // File: decimal.c
  8. //
  9. // Ported from C++ to C and adjusted to Mono runtime
  10. //
  11. // Pending:
  12. //   DoToCurrency (they look like new methods we do not have)
  13. //
  14. #ifndef DISABLE_DECIMAL
  15. #include "config.h"
  16. #include <stdint.h>
  17. #include <glib.h>
  18. #include <mono/utils/mono-compiler.h>
  19. #include <mono/metadata/exception.h>
  20. #include <mono/metadata/object-internals.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <math.h>
  25. #ifdef HAVE_MEMORY_H
  26. #include <memory.h>
  27. #endif
  28. #ifdef _MSC_VER
  29. #include <intrin.h>
  30. #endif
  31. #include "decimal-ms.h"
  32.  
  33. #define min(a, b) (((a) < (b)) ? (a) : (b))
  34.  
  35. typedef enum {
  36.     MONO_DECIMAL_OK,
  37.     MONO_DECIMAL_OVERFLOW,
  38.     MONO_DECIMAL_INVALID_ARGUMENT,
  39.     MONO_DECIMAL_DIVBYZERO,
  40.     MONO_DECIMAL_ARGUMENT_OUT_OF_RANGE
  41. } MonoDecimalStatus;
  42.  
  43. #ifndef FC_GC_POLL
  44. #   define FC_GC_POLL()
  45. #endif
  46.  
  47. static const uint32_t ten_to_nine    = 1000000000U;
  48. static const uint32_t ten_to_ten_div_4 = 2500000000U;
  49. #define POWER10_MAX     9
  50. #define DECIMAL_NEG ((uint8_t)0x80)
  51. #define DECMAX 28
  52. #define DECIMAL_SCALE(dec)       ((dec).u.u.scale)
  53. #define DECIMAL_SIGN(dec)        ((dec).u.u.sign)
  54. #define DECIMAL_SIGNSCALE(dec)   ((dec).u.signscale)
  55. #define DECIMAL_LO32(dec)        ((dec).v.v.Lo32)
  56. #define DECIMAL_MID32(dec)       ((dec).v.v.Mid32)
  57. #define DECIMAL_HI32(dec)        ((dec).Hi32)
  58. #define DECIMAL_LO64_GET(dec)    ((dec).v.Lo64)
  59. #define DECIMAL_LO64_SET(dec,value)   {(dec).v.Lo64 = value; }
  60.  
  61. #define DECIMAL_SETZERO(dec) {DECIMAL_LO32(dec) = 0; DECIMAL_MID32(dec) = 0; DECIMAL_HI32(dec) = 0; DECIMAL_SIGNSCALE(dec) = 0;}
  62. #define COPYDEC(dest, src) {DECIMAL_SIGNSCALE(dest) = DECIMAL_SIGNSCALE(src); DECIMAL_HI32(dest) = DECIMAL_HI32(src); \
  63.     DECIMAL_MID32(dest) = DECIMAL_MID32(src); DECIMAL_LO32(dest) = DECIMAL_LO32(src); }
  64.  
  65. #define DEC_SCALE_MAX   28
  66. #define POWER10_MAX     9
  67.  
  68. #define OVFL_MAX_9_HI   4
  69. #define OVFL_MAX_9_MID  1266874889
  70. #define OVFL_MAX_9_LO   3047500985u
  71.  
  72. #define OVFL_MAX_5_HI   42949
  73. #define OVFL_MAX_5_MID  2890341191
  74.  
  75. #define OVFL_MAX_1_HI   429496729
  76.  
  77. typedef union {
  78.     uint64_t int64;
  79.     struct {
  80. #if BYTE_ORDER == G_BIG_ENDIAN
  81.         uint32_t Hi;
  82.         uint32_t Lo;
  83. #else
  84.         uint32_t Lo;
  85.         uint32_t Hi;
  86. #endif
  87.     } u;
  88. } SPLIT64;
  89.  
  90. static const SPLIT64    ten_to_eighteen = { 1000000000000000000ULL };
  91. // Double Bias
  92. #define DBLBIAS 1022
  93.  
  94. // Structure to access an encoded double floating point
  95. typedef union{
  96.     struct {
  97. #if BYTE_ORDER == G_BIG_ENDIAN
  98.       unsigned int sign:1;
  99.       unsigned int exp:11;
  100.       unsigned int mantHi:20;
  101.       unsigned int mantLo;
  102. #else // BIGENDIAN
  103.       unsigned int mantLo;
  104.       unsigned int mantHi:20;
  105.       unsigned int exp:11;
  106.       unsigned int sign:1;
  107. #endif
  108.     } u;
  109.     double dbl;
  110. } DoubleStructure;
  111.  
  112. #if BYTE_ORDER == G_BIG_ENDIAN
  113. #define DEFDS(Lo, Hi, exp, sign) { {sign, exp, Hi, Lo } }
  114. #else
  115. #define DEFDS(Lo, Hi, exp, sign) { {Lo, Hi, exp, sign} }
  116. #endif
  117.  
  118. const DoubleStructure ds2to64 = DEFDS(0, 0, DBLBIAS + 65, 0);
  119.  
  120. // Single floating point Bias
  121. #define SNGBIAS 126
  122.  
  123. // Structure to access an encoded single floating point
  124. typedef struct {
  125. #if BYTE_ORDER == G_BIG_ENDIAN
  126.     unsigned int sign:1;
  127.     unsigned int exp:8;
  128.     unsigned int mant:23;
  129. #else
  130.     unsigned int mant:23;
  131.     unsigned int exp:8;
  132.     unsigned int sign:1;
  133. #endif
  134. } SingleStructure;
  135.  
  136. //
  137. // Data tables
  138. //
  139.  
  140. static const uint32_t power10 [POWER10_MAX+1] = {
  141.     1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
  142. };
  143.  
  144.  
  145. static const double double_power10[] = {
  146.     1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
  147.     1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
  148.     1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
  149.     1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
  150.     1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, 1e48, 1e49,
  151.     1e50, 1e51, 1e52, 1e53, 1e54, 1e55, 1e56, 1e57, 1e58, 1e59,
  152.     1e60, 1e61, 1e62, 1e63, 1e64, 1e65, 1e66, 1e67, 1e68, 1e69,
  153.     1e70, 1e71, 1e72, 1e73, 1e74, 1e75, 1e76, 1e77, 1e78, 1e79,
  154.     1e80 };
  155.  
  156. const SPLIT64 sdl_power10[] = { {10000000000ULL},          // 1E10
  157.                 {100000000000ULL},         // 1E11
  158.                 {1000000000000ULL},        // 1E12
  159.                 {10000000000000ULL},       // 1E13
  160.                 {100000000000000ULL} };    // 1E14
  161.  
  162. static const uint64_t long_power10[] = {
  163.     1,
  164.     10ULL,
  165.     100ULL,
  166.     1000ULL,
  167.     10000ULL,
  168.     100000ULL,
  169.     1000000ULL,
  170.     10000000ULL,
  171.     100000000ULL,
  172.     1000000000ULL,
  173.     10000000000ULL,
  174.     100000000000ULL,
  175.     1000000000000ULL,
  176.     10000000000000ULL,
  177.     100000000000000ULL,
  178.     1000000000000000ULL,
  179.     10000000000000000ULL,
  180.     100000000000000000ULL,
  181.     1000000000000000000ULL,
  182.     10000000000000000000ULL};
  183.  
  184. typedef struct  {
  185.     uint32_t Hi, Mid, Lo;
  186. } DECOVFL;
  187.  
  188. const DECOVFL power_overflow[] = {
  189. // This is a table of the largest values that can be in the upper two
  190. // ULONGs of a 96-bit number that will not overflow when multiplied
  191. // by a given power.  For the upper word, this is a table of
  192. // 2^32 / 10^n for 1 <= n <= 9.  For the lower word, this is the
  193. // remaining fraction part * 2^32.  2^32 = 4294967296.
  194. //
  195.     { 429496729u, 2576980377u, 2576980377u }, // 10^1 remainder 0.6
  196.     { 42949672u,  4123168604u, 687194767u  }, // 10^2 remainder 0.16
  197.     { 4294967u,   1271310319u, 2645699854u }, // 10^3 remainder 0.616
  198.     { 429496u,    3133608139u, 694066715u  }, // 10^4 remainder 0.1616
  199.     { 42949u,     2890341191u, 2216890319u }, // 10^5 remainder 0.51616
  200.     { 4294u,      4154504685u, 2369172679u }, // 10^6 remainder 0.551616
  201.     { 429u,       2133437386u, 4102387834u }, // 10^7 remainder 0.9551616
  202.     { 42u,        4078814305u, 410238783u  }, // 10^8 remainder 0.09991616
  203.     { 4u,         1266874889u, 3047500985u }, // 10^9 remainder 0.709551616
  204. };
  205.  
  206.  
  207. #define UInt32x32To64(a, b) ((uint64_t)((uint32_t)(a)) * (uint64_t)((uint32_t)(b)))
  208. #define Div64by32(num, den) ((uint32_t)((uint64_t)(num) / (uint32_t)(den)))
  209. #define Mod64by32(num, den) ((uint32_t)((uint64_t)(num) % (uint32_t)(den)))
  210.  
  211. static double
  212. fnDblPower10(int ix)
  213. {
  214.     const int maxIx = (sizeof(double_power10)/sizeof(double_power10[0]));
  215.     g_assert(ix >= 0);
  216.     if (ix < maxIx)
  217.         return double_power10[ix];
  218.     return pow(10.0, ix);
  219. } // double fnDblPower10()
  220.  
  221.  
  222. static inline int64_t
  223. DivMod32by32(int32_t num, int32_t den)
  224. {
  225.     SPLIT64  sdl;
  226.  
  227.     sdl.u.Lo = num / den;
  228.     sdl.u.Hi = num % den;
  229.     return sdl.int64;
  230. }
  231.  
  232. static inline int64_t
  233. DivMod64by32(int64_t num, int32_t den)
  234. {
  235.     SPLIT64  sdl;
  236.  
  237.     sdl.u.Lo = Div64by32(num, den);
  238.     sdl.u.Hi = Mod64by32(num, den);
  239.     return sdl.int64;
  240. }
  241.  
  242. static uint64_t
  243. UInt64x64To128(SPLIT64 op1, SPLIT64 op2, uint64_t *hi)
  244. {
  245.     SPLIT64  tmp1;
  246.     SPLIT64  tmp2;
  247.     SPLIT64  tmp3;
  248.  
  249.     tmp1.int64 = UInt32x32To64(op1.u.Lo, op2.u.Lo); // lo partial prod
  250.     tmp2.int64 = UInt32x32To64(op1.u.Lo, op2.u.Hi); // mid 1 partial prod
  251.     tmp1.u.Hi += tmp2.u.Lo;
  252.     if (tmp1.u.Hi < tmp2.u.Lo)  // test for carry
  253.         tmp2.u.Hi++;
  254.     tmp3.int64 = UInt32x32To64(op1.u.Hi, op2.u.Hi) + (uint64_t)tmp2.u.Hi;
  255.     tmp2.int64 = UInt32x32To64(op1.u.Hi, op2.u.Lo);
  256.     tmp1.u.Hi += tmp2.u.Lo;
  257.     if (tmp1.u.Hi < tmp2.u.Lo)  // test for carry
  258.         tmp2.u.Hi++;
  259.     tmp3.int64 += (uint64_t)tmp2.u.Hi;
  260.  
  261.     *hi = tmp3.int64;
  262.     return tmp1.int64;
  263. }
  264.  
  265. /**
  266. * FullDiv64By32:
  267. *
  268. * Entry:
  269. *   pdlNum  - Pointer to 64-bit dividend
  270. *   ulDen   - 32-bit divisor
  271. *
  272. * Purpose:
  273. *   Do full divide, yielding 64-bit result and 32-bit remainder.
  274. *
  275. * Exit:
  276. *   Quotient overwrites dividend.
  277. *   Returns remainder.
  278. *
  279. * Exceptions:
  280. *   None.
  281. */
  282. // Was: FullDiv64By32
  283. static uint32_t
  284. FullDiv64By32 (uint64_t *num, uint32_t den)
  285. {
  286.     SPLIT64  tmp;
  287.     SPLIT64  res;
  288.    
  289.     tmp.int64 = *num;
  290.     res.u.Hi = 0;
  291.    
  292.     if (tmp.u.Hi >= den) {
  293.         // DivMod64by32 returns quotient in Lo, remainder in Hi.
  294.         //
  295.         res.u.Lo = tmp.u.Hi;
  296.         res.int64 = DivMod64by32(res.int64, den);
  297.         tmp.u.Hi = res.u.Hi;
  298.         res.u.Hi = res.u.Lo;
  299.     }
  300.    
  301.     tmp.int64 = DivMod64by32(tmp.int64, den);
  302.     res.u.Lo = tmp.u.Lo;
  303.     *num = res.int64;
  304.     return tmp.u.Hi;
  305. }
  306.  
  307. /***
  308.  * SearchScale
  309.  *
  310.  * Entry:
  311.  *   res_hi - Top uint32_t of quotient
  312.  *   res_mid - Middle uint32_t of quotient
  313.  *   res_lo - Bottom uint32_t of quotient
  314.  *   scale  - Scale factor of quotient, range -DEC_SCALE_MAX to DEC_SCALE_MAX
  315.  *
  316.  * Purpose:
  317.  *   Determine the max power of 10, <= 9, that the quotient can be scaled
  318.  *   up by and still fit in 96 bits.
  319.  *
  320.  * Exit:
  321.  *   Returns power of 10 to scale by, -1 if overflow error.
  322.  *
  323.  ***********************************************************************/
  324.  
  325. static int
  326. SearchScale(uint32_t res_hi, uint32_t res_mid, uint32_t res_lo, int scale)
  327. {
  328.     int   cur_scale;
  329.  
  330.     // Quick check to stop us from trying to scale any more.
  331.     //
  332.     if (res_hi > OVFL_MAX_1_HI || scale >= DEC_SCALE_MAX) {
  333.         cur_scale = 0;
  334.         goto HaveScale;
  335.     }
  336.  
  337.     if (scale > DEC_SCALE_MAX - 9) {
  338.         // We can't scale by 10^9 without exceeding the max scale factor.
  339.         // See if we can scale to the max.  If not, we'll fall into
  340.         // standard search for scale factor.
  341.         //
  342.         cur_scale = DEC_SCALE_MAX - scale;
  343.         if (res_hi < power_overflow[cur_scale - 1].Hi)
  344.             goto HaveScale;
  345.  
  346.         if (res_hi == power_overflow[cur_scale - 1].Hi) {
  347.         UpperEq:
  348.             if (res_mid > power_overflow[cur_scale - 1].Mid ||
  349.                 (res_mid == power_overflow[cur_scale - 1].Mid && res_lo > power_overflow[cur_scale - 1].Lo)) {
  350.                 cur_scale--;
  351.             }
  352.             goto HaveScale;
  353.         }
  354.     } else if (res_hi < OVFL_MAX_9_HI || (res_hi == OVFL_MAX_9_HI && res_mid < OVFL_MAX_9_MID) || (res_hi == OVFL_MAX_9_HI && res_mid == OVFL_MAX_9_MID && res_lo <= OVFL_MAX_9_LO))
  355.         return 9;
  356.  
  357.     // Search for a power to scale by < 9.  Do a binary search
  358.     // on power_overflow[].
  359.     //
  360.     cur_scale = 5;
  361.     if (res_hi < OVFL_MAX_5_HI)
  362.         cur_scale = 7;
  363.     else if (res_hi > OVFL_MAX_5_HI)
  364.         cur_scale = 3;
  365.     else
  366.         goto UpperEq;
  367.  
  368.     // cur_scale is 3 or 7.
  369.     //
  370.     if (res_hi < power_overflow[cur_scale - 1].Hi)
  371.         cur_scale++;
  372.     else if (res_hi > power_overflow[cur_scale - 1].Hi)
  373.         cur_scale--;
  374.     else
  375.         goto UpperEq;
  376.  
  377.     // cur_scale is 2, 4, 6, or 8.
  378.     //
  379.     // In all cases, we already found we could not use the power one larger.
  380.     // So if we can use this power, it is the biggest, and we're done.  If
  381.     // we can't use this power, the one below it is correct for all cases
  382.     // unless it's 10^1 -- we might have to go to 10^0 (no scaling).
  383.     //
  384.     if (res_hi > power_overflow[cur_scale - 1].Hi)
  385.         cur_scale--;
  386.  
  387.     if (res_hi == power_overflow[cur_scale - 1].Hi)
  388.         goto UpperEq;
  389.  
  390. HaveScale:
  391.     // cur_scale = largest power of 10 we can scale by without overflow,
  392.     // cur_scale < 9.  See if this is enough to make scale factor
  393.     // positive if it isn't already.
  394.     //
  395.     if (cur_scale + scale < 0)
  396.         cur_scale = -1;
  397.  
  398.     return cur_scale;
  399. }
  400.  
  401.  
  402. /**
  403. * Div96By32
  404. *
  405. * Entry:
  406. *   rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
  407. *   ulDen   - 32-bit divisor.
  408. *
  409. * Purpose:
  410. *   Do full divide, yielding 96-bit result and 32-bit remainder.
  411. *
  412. * Exit:
  413. *   Quotient overwrites dividend.
  414. *   Returns remainder.
  415. *
  416. * Exceptions:
  417. *   None.
  418. *
  419. */
  420. static uint32_t
  421. Div96By32(uint32_t *num, uint32_t den)
  422. {
  423.     SPLIT64  tmp;
  424.  
  425.     tmp.u.Hi = 0;
  426.  
  427.     if (num[2] != 0)
  428.         goto Div3Word;
  429.  
  430.     if (num[1] >= den)
  431.         goto Div2Word;
  432.  
  433.     tmp.u.Hi = num[1];
  434.     num[1] = 0;
  435.     goto Div1Word;
  436.  
  437. Div3Word:
  438.     tmp.u.Lo = num[2];
  439.     tmp.int64 = DivMod64by32(tmp.int64, den);
  440.     num[2] = tmp.u.Lo;
  441. Div2Word:
  442.     tmp.u.Lo = num[1];
  443.     tmp.int64 = DivMod64by32(tmp.int64, den);
  444.     num[1] = tmp.u.Lo;
  445. Div1Word:
  446.     tmp.u.Lo = num[0];
  447.     tmp.int64 = DivMod64by32(tmp.int64, den);
  448.     num[0] = tmp.u.Lo;
  449.     return tmp.u.Hi;
  450. }
  451.  
  452. /***
  453.  * DecFixInt
  454.  *
  455.  * Entry:
  456.  *   pdecRes - Pointer to Decimal result location
  457.  *   operand  - Pointer to Decimal operand
  458.  *
  459.  * Purpose:
  460.  *   Chop the value to integer.  Return remainder so Int() function
  461.  *   can round down if non-zero.
  462.  *
  463.  * Exit:
  464.  *   Returns remainder.
  465.  *
  466.  * Exceptions:
  467.  *   None.
  468.  *
  469.  ***********************************************************************/
  470.  
  471. static uint32_t
  472. DecFixInt(MonoDecimal * result, MonoDecimal * operand)
  473. {
  474.     uint32_t   num[3];
  475.     uint32_t   rem;
  476.     uint32_t   pwr;
  477.     int     scale;
  478.  
  479.     if (operand->u.u.scale > 0) {
  480.         num[0] = operand->v.v.Lo32;
  481.         num[1] = operand->v.v.Mid32;
  482.         num[2] = operand->Hi32;
  483.         scale = operand->u.u.scale;
  484.         result->u.u.sign = operand->u.u.sign;
  485.         rem = 0;
  486.  
  487.         do {
  488.             if (scale > POWER10_MAX)
  489.                 pwr = ten_to_nine;
  490.             else
  491.                 pwr = power10[scale];
  492.  
  493.             rem |= Div96By32(num, pwr);
  494.             scale -= 9;
  495.         }while (scale > 0);
  496.  
  497.         result->v.v.Lo32 = num[0];
  498.         result->v.v.Mid32 = num[1];
  499.         result->Hi32 = num[2];
  500.         result->u.u.scale = 0;
  501.  
  502.         return rem;
  503.     }
  504.  
  505.     COPYDEC(*result, *operand);
  506.     // Odd, the Microsoft code does not set result->reserved to zero on this case
  507.     return 0;
  508. }
  509.  
  510. /**
  511.  * ScaleResult:
  512.  *
  513.  * Entry:
  514.  *   res - Array of uint32_ts with value, least-significant first.
  515.  *   hi_res  - Index of last non-zero value in res.
  516.  *   scale  - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX
  517.  *
  518.  * Purpose:
  519.  *   See if we need to scale the result to fit it in 96 bits.
  520.  *   Perform needed scaling.  Adjust scale factor accordingly.
  521.  *
  522.  * Exit:
  523.  *   res updated in place, always 3 uint32_ts.
  524.  *   New scale factor returned, -1 if overflow error.
  525.  *
  526.  */
  527. static int
  528. ScaleResult(uint32_t *res, int hi_res, int scale)
  529. {
  530.     int     new_scale;
  531.     int     cur;
  532.     uint32_t   pwr;
  533.     uint32_t   tmp;
  534.     uint32_t   sticky;
  535.     SPLIT64 sdlTmp;
  536.  
  537.     // See if we need to scale the result.  The combined scale must
  538.     // be <= DEC_SCALE_MAX and the upper 96 bits must be zero.
  539.     //
  540.     // Start by figuring a lower bound on the scaling needed to make
  541.     // the upper 96 bits zero.  hi_res is the index into res[]
  542.     // of the highest non-zero uint32_t.
  543.     //
  544.     new_scale =   hi_res * 32 - 64 - 1;
  545.     if (new_scale > 0) {
  546.  
  547.         // Find the MSB.
  548.         //
  549.         tmp = res[hi_res];
  550.         if (!(tmp & 0xFFFF0000)) {
  551.             new_scale -= 16;
  552.             tmp <<= 16;
  553.         }
  554.         if (!(tmp & 0xFF000000)) {
  555.             new_scale -= 8;
  556.             tmp <<= 8;
  557.         }
  558.         if (!(tmp & 0xF0000000)) {
  559.             new_scale -= 4;
  560.             tmp <<= 4;
  561.         }
  562.         if (!(tmp & 0xC0000000)) {
  563.             new_scale -= 2;
  564.             tmp <<= 2;
  565.         }
  566.         if (!(tmp & 0x80000000)) {
  567.             new_scale--;
  568.             tmp <<= 1;
  569.         }
  570.    
  571.         // Multiply bit position by log10(2) to figure it's power of 10.
  572.         // We scale the log by 256.  log(2) = .30103, * 256 = 77.  Doing this
  573.         // with a multiply saves a 96-byte lookup table.  The power returned
  574.         // is <= the power of the number, so we must add one power of 10
  575.         // to make it's integer part zero after dividing by 256.
  576.         //
  577.         // Note: the result of this multiplication by an approximation of
  578.         // log10(2) have been exhaustively checked to verify it gives the
  579.         // correct result.  (There were only 95 to check...)
  580.         //
  581.         new_scale = ((new_scale * 77) >> 8) + 1;
  582.  
  583.         // new_scale = min scale factor to make high 96 bits zero, 0 - 29.
  584.         // This reduces the scale factor of the result.  If it exceeds the
  585.         // current scale of the result, we'll overflow.
  586.         //
  587.         if (new_scale > scale)
  588.             return -1;
  589.     }
  590.     else
  591.         new_scale = 0;
  592.  
  593.     // Make sure we scale by enough to bring the current scale factor
  594.     // into valid range.
  595.     //
  596.     if (new_scale < scale - DEC_SCALE_MAX)
  597.         new_scale = scale - DEC_SCALE_MAX;
  598.  
  599.     if (new_scale != 0) {
  600.         // Scale by the power of 10 given by new_scale.  Note that this is
  601.         // NOT guaranteed to bring the number within 96 bits -- it could
  602.         // be 1 power of 10 short.
  603.         //
  604.         scale -= new_scale;
  605.         sticky = 0;
  606.         sdlTmp.u.Hi = 0; // initialize remainder
  607.  
  608.         for (;;) {
  609.  
  610.             sticky |= sdlTmp.u.Hi; // record remainder as sticky bit
  611.  
  612.             if (new_scale > POWER10_MAX)
  613.                 pwr = ten_to_nine;
  614.             else
  615.                 pwr = power10[new_scale];
  616.  
  617.             // Compute first quotient.
  618.             // DivMod64by32 returns quotient in Lo, remainder in Hi.
  619.             //
  620.             sdlTmp.int64 = DivMod64by32(res[hi_res], pwr);
  621.             res[hi_res] = sdlTmp.u.Lo;
  622.             cur = hi_res - 1;
  623.  
  624.             if (cur >= 0) {
  625.                 // If first quotient was 0, update hi_res.
  626.                 //
  627.                 if (sdlTmp.u.Lo == 0)
  628.                     hi_res--;
  629.  
  630.                 // Compute subsequent quotients.
  631.                 //
  632.                 do {
  633.                     sdlTmp.u.Lo = res[cur];
  634.                     sdlTmp.int64 = DivMod64by32(sdlTmp.int64, pwr);
  635.                     res[cur] = sdlTmp.u.Lo;
  636.                     cur--;
  637.                 } while (cur >= 0);
  638.  
  639.             }
  640.  
  641.             new_scale -= POWER10_MAX;
  642.             if (new_scale > 0)
  643.                 continue; // scale some more
  644.  
  645.             // If we scaled enough, hi_res would be 2 or less.  If not,
  646.             // divide by 10 more.
  647.             //
  648.             if (hi_res > 2) {
  649.                 new_scale = 1;
  650.                 scale--;
  651.                 continue; // scale by 10
  652.             }
  653.  
  654.             // Round final result.  See if remainder >= 1/2 of divisor.
  655.             // If remainder == 1/2 divisor, round up if odd or sticky bit set.
  656.             //
  657.             pwr >>= 1;  // power of 10 always even
  658.             if ( pwr <= sdlTmp.u.Hi && (pwr < sdlTmp.u.Hi ||
  659.                             ((res[0] & 1) | sticky)) ) {
  660.                 cur = -1;
  661.                 while (++res[++cur] == 0);
  662.                
  663.                 if (cur > 2) {
  664.                     // The rounding caused us to carry beyond 96 bits.
  665.                     // Scale by 10 more.
  666.                     //
  667.                     hi_res = cur;
  668.                     sticky = 0;  // no sticky bit
  669.                     sdlTmp.u.Hi = 0; // or remainder
  670.                     new_scale = 1;
  671.                     scale--;
  672.                     continue; // scale by 10
  673.                 }
  674.             }
  675.            
  676.             // We may have scaled it more than we planned.  Make sure the scale
  677.             // factor hasn't gone negative, indicating overflow.
  678.             //
  679.             if (scale < 0)
  680.                 return -1;
  681.            
  682.             return scale;
  683.         } // for(;;)
  684.     }
  685.     return scale;
  686. }
  687.  
  688. // Decimal multiply
  689. // Returns: MONO_DECIMAL_OVERFLOW or MONO_DECIMAL_OK
  690. static MonoDecimalStatus
  691. MONO_VarDecMul(MonoDecimal * left, MonoDecimal * right, MonoDecimal * result)
  692. {
  693.     SPLIT64 tmp;
  694.     SPLIT64 tmp2;
  695.     SPLIT64 tmp3;
  696.     int     scale;
  697.     int     hi_prod;
  698.     uint32_t   pwr;
  699.     uint32_t   rem_lo;
  700.     uint32_t   rem_hi;
  701.     uint32_t   prod[6];
  702.  
  703.     scale = left->u.u.scale + right->u.u.scale;
  704.  
  705.     if ((left->Hi32 | left->v.v.Mid32 | right->Hi32 | right->v.v.Mid32) == 0) {
  706.         // Upper 64 bits are zero.
  707.         //
  708.         tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
  709.         if (scale > DEC_SCALE_MAX)
  710.         {
  711.             // Result scale is too big.  Divide result by power of 10 to reduce it.
  712.             // If the amount to divide by is > 19 the result is guaranteed
  713.             // less than 1/2.  [max value in 64 bits = 1.84E19]
  714.             //
  715.             scale -= DEC_SCALE_MAX;
  716.             if (scale > 19) {
  717.             ReturnZero:
  718.                 DECIMAL_SETZERO(*result);
  719.                 return MONO_DECIMAL_OK;
  720.             }
  721.  
  722.             if (scale > POWER10_MAX) {
  723.                 // Divide by 1E10 first, to get the power down to a 32-bit quantity.
  724.                 // 1E10 itself doesn't fit in 32 bits, so we'll divide by 2.5E9 now
  725.                 // then multiply the next divisor by 4 (which will be a max of 4E9).
  726.                 //
  727.                 rem_lo = FullDiv64By32(&tmp.int64, ten_to_ten_div_4);
  728.                 pwr = power10[scale - 10] << 2;
  729.             } else {
  730.                 pwr = power10[scale];
  731.                 rem_lo = 0;
  732.             }
  733.  
  734.             // Power to divide by fits in 32 bits.
  735.             //
  736.             rem_hi = FullDiv64By32(&tmp.int64, pwr);
  737.  
  738.             // Round result.  See if remainder >= 1/2 of divisor.
  739.             // Divisor is a power of 10, so it is always even.
  740.             //
  741.             pwr >>= 1;
  742.             if (rem_hi >= pwr && (rem_hi > pwr || (rem_lo | (tmp.u.Lo & 1))))
  743.                 tmp.int64++;
  744.  
  745.             scale = DEC_SCALE_MAX;
  746.         }
  747.         DECIMAL_LO32(*result) = tmp.u.Lo;
  748.         DECIMAL_MID32(*result) = tmp.u.Hi;
  749.         DECIMAL_HI32(*result) = 0;
  750.     } else {
  751.         // At least one operand has bits set in the upper 64 bits.
  752.         //
  753.         // Compute and accumulate the 9 partial products into a
  754.         // 192-bit (24-byte) result.
  755.         //
  756.         //                [l-h][l-m][l-l]   left high, middle, low
  757.         //             x  [r-h][r-m][r-l]   right high, middle, low
  758.         // ------------------------------
  759.         //
  760.         //                     [0-h][0-l]   l-l * r-l
  761.         //                [1ah][1al]        l-l * r-m
  762.         //                [1bh][1bl]        l-m * r-l
  763.         //           [2ah][2al]             l-m * r-m
  764.         //           [2bh][2bl]             l-l * r-h
  765.         //           [2ch][2cl]             l-h * r-l
  766.         //      [3ah][3al]                  l-m * r-h
  767.         //      [3bh][3bl]                  l-h * r-m
  768.         // [4-h][4-l]                       l-h * r-h
  769.         // ------------------------------
  770.         // [p-5][p-4][p-3][p-2][p-1][p-0]   prod[] array
  771.         //
  772.         tmp.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Lo32);
  773.         prod[0] = tmp.u.Lo;
  774.  
  775.         tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->v.v.Mid32) + tmp.u.Hi;
  776.  
  777.         tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Lo32);
  778.         tmp.int64 += tmp2.int64; // this could generate carry
  779.         prod[1] = tmp.u.Lo;
  780.         if (tmp.int64 < tmp2.int64) // detect carry
  781.             tmp2.u.Hi = 1;
  782.         else
  783.             tmp2.u.Hi = 0;
  784.         tmp2.u.Lo = tmp.u.Hi;
  785.  
  786.         tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->v.v.Mid32) + tmp2.int64;
  787.  
  788.         if (left->Hi32 | right->Hi32) {
  789.             // Highest 32 bits is non-zero.  Calculate 5 more partial products.
  790.             //
  791.             tmp2.int64 = UInt32x32To64(left->v.v.Lo32, right->Hi32);
  792.             tmp.int64 += tmp2.int64; // this could generate carry
  793.             if (tmp.int64 < tmp2.int64) // detect carry
  794.                 tmp3.u.Hi = 1;
  795.             else
  796.                 tmp3.u.Hi = 0;
  797.  
  798.             tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Lo32);
  799.             tmp.int64 += tmp2.int64; // this could generate carry
  800.             prod[2] = tmp.u.Lo;
  801.             if (tmp.int64 < tmp2.int64) // detect carry
  802.                 tmp3.u.Hi++;
  803.             tmp3.u.Lo = tmp.u.Hi;
  804.  
  805.             tmp.int64 = UInt32x32To64(left->v.v.Mid32, right->Hi32);
  806.             tmp.int64 += tmp3.int64; // this could generate carry
  807.             if (tmp.int64 < tmp3.int64) // detect carry
  808.                 tmp3.u.Hi = 1;
  809.             else
  810.                 tmp3.u.Hi = 0;
  811.  
  812.             tmp2.int64 = UInt32x32To64(left->Hi32, right->v.v.Mid32);
  813.             tmp.int64 += tmp2.int64; // this could generate carry
  814.             prod[3] = tmp.u.Lo;
  815.             if (tmp.int64 < tmp2.int64) // detect carry
  816.                 tmp3.u.Hi++;
  817.             tmp3.u.Lo = tmp.u.Hi;
  818.  
  819.             tmp.int64 = UInt32x32To64(left->Hi32, right->Hi32) + tmp3.int64;
  820.             prod[4] = tmp.u.Lo;
  821.             prod[5] = tmp.u.Hi;
  822.  
  823.             hi_prod = 5;
  824.         }
  825.         else {
  826.             prod[2] = tmp.u.Lo;
  827.             prod[3] = tmp.u.Hi;
  828.             hi_prod = 3;
  829.         }
  830.  
  831.         // Check for leading zero uint32_ts on the product
  832.         //
  833.         while (prod[hi_prod] == 0) {
  834.             hi_prod--;
  835.             if (hi_prod < 0)
  836.                 goto ReturnZero;
  837.         }
  838.  
  839.         scale = ScaleResult(prod, hi_prod, scale);
  840.         if (scale == -1)
  841.             return MONO_DECIMAL_OVERFLOW;
  842.  
  843.         result->v.v.Lo32 = prod[0];
  844.         result->v.v.Mid32 = prod[1];
  845.         result->Hi32 = prod[2];
  846.     }
  847.  
  848.     result->u.u.sign = right->u.u.sign ^ left->u.u.sign;
  849.     result->u.u.scale = (char)scale;
  850.     return MONO_DECIMAL_OK;
  851. }
  852.  
  853. // Addition and subtraction
  854. static MonoDecimalStatus
  855. DecAddSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result, int8_t sign)
  856. {
  857.     uint32_t     num[6];
  858.     uint32_t     pwr;
  859.     int       scale;
  860.     int       hi_prod;
  861.     int       cur;
  862.     SPLIT64   tmp;
  863.     MonoDecimal decRes;
  864.     MonoDecimal decTmp;
  865.     MonoDecimal *pdecTmp;
  866.  
  867.     sign ^= (right->u.u.sign ^ left->u.u.sign) & DECIMAL_NEG;
  868.  
  869.     if (right->u.u.scale == left->u.u.scale) {
  870.         // Scale factors are equal, no alignment necessary.
  871.         //
  872.         decRes.u.signscale = left->u.signscale;
  873.  
  874.     AlignedAdd:
  875.         if (sign) {
  876.             // Signs differ - subtract
  877.             //
  878.             DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right));
  879.             DECIMAL_HI32(decRes) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
  880.  
  881.             // Propagate carry
  882.             //
  883.             if (DECIMAL_LO64_GET(decRes) > DECIMAL_LO64_GET(*left)) {
  884.                 decRes.Hi32--;
  885.                 if (decRes.Hi32 >= left->Hi32)
  886.                     goto SignFlip;
  887.             } else if (decRes.Hi32 > left->Hi32) {
  888.                 // Got negative result.  Flip its sign.
  889.                 //
  890.             SignFlip:
  891.                 DECIMAL_LO64_SET(decRes, -(uint64_t)DECIMAL_LO64_GET(decRes));
  892.                 decRes.Hi32 = ~decRes.Hi32;
  893.                 if (DECIMAL_LO64_GET(decRes) == 0)
  894.                     decRes.Hi32++;
  895.                 decRes.u.u.sign ^= DECIMAL_NEG;
  896.             }
  897.  
  898.         } else {
  899.             // Signs are the same - add
  900.             //
  901.             DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right));
  902.             decRes.Hi32 = left->Hi32 + right->Hi32;
  903.  
  904.             // Propagate carry
  905.             //
  906.             if (DECIMAL_LO64_GET(decRes) < DECIMAL_LO64_GET(*left)) {
  907.                 decRes.Hi32++;
  908.                 if (decRes.Hi32 <= left->Hi32)
  909.                     goto AlignedScale;
  910.             } else if (decRes.Hi32 < left->Hi32) {
  911.             AlignedScale:
  912.                 // The addition carried above 96 bits.  Divide the result by 10,
  913.                 // dropping the scale factor.
  914.                 //
  915.                 if (decRes.u.u.scale == 0)
  916.                     return MONO_DECIMAL_OVERFLOW;
  917.                 decRes.u.u.scale--;
  918.  
  919.                 tmp.u.Lo = decRes.Hi32;
  920.                 tmp.u.Hi = 1;
  921.                 tmp.int64 = DivMod64by32(tmp.int64, 10);
  922.                 decRes.Hi32 = tmp.u.Lo;
  923.  
  924.                 tmp.u.Lo = decRes.v.v.Mid32;
  925.                 tmp.int64 = DivMod64by32(tmp.int64, 10);
  926.                 decRes.v.v.Mid32 = tmp.u.Lo;
  927.  
  928.                 tmp.u.Lo = decRes.v.v.Lo32;
  929.                 tmp.int64 = DivMod64by32(tmp.int64, 10);
  930.                 decRes.v.v.Lo32 = tmp.u.Lo;
  931.  
  932.                 // See if we need to round up.
  933.                 //
  934.                 if (tmp.u.Hi >= 5 && (tmp.u.Hi > 5 || (decRes.v.v.Lo32 & 1))) {
  935.                     DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(decRes)+1)
  936.                         if (DECIMAL_LO64_GET(decRes) == 0)
  937.                             decRes.Hi32++;
  938.                 }
  939.             }
  940.         }
  941.     }
  942.     else {
  943.         // Scale factors are not equal.  Assume that a larger scale
  944.         // factor (more decimal places) is likely to mean that number
  945.         // is smaller.  Start by guessing that the right operand has
  946.         // the larger scale factor.  The result will have the larger
  947.         // scale factor.
  948.         //
  949.         decRes.u.u.scale = right->u.u.scale;  // scale factor of "smaller"
  950.         decRes.u.u.sign = left->u.u.sign;    // but sign of "larger"
  951.         scale = decRes.u.u.scale - left->u.u.scale;
  952.  
  953.         if (scale < 0) {
  954.             // Guessed scale factor wrong. Swap operands.
  955.             //
  956.             scale = -scale;
  957.             decRes.u.u.scale = left->u.u.scale;
  958.             decRes.u.u.sign ^= sign;
  959.             pdecTmp = right;
  960.             right = left;
  961.             left = pdecTmp;
  962.         }
  963.  
  964.         // *left will need to be multiplied by 10^scale so
  965.         // it will have the same scale as *right.  We could be
  966.         // extending it to up to 192 bits of precision.
  967.         //
  968.         if (scale <= POWER10_MAX) {
  969.             // Scaling won't make it larger than 4 uint32_ts
  970.             //
  971.             pwr = power10[scale];
  972.             DECIMAL_LO64_SET(decTmp, UInt32x32To64(left->v.v.Lo32, pwr));
  973.             tmp.int64 = UInt32x32To64(left->v.v.Mid32, pwr);
  974.             tmp.int64 += decTmp.v.v.Mid32;
  975.             decTmp.v.v.Mid32 = tmp.u.Lo;
  976.             decTmp.Hi32 = tmp.u.Hi;
  977.             tmp.int64 = UInt32x32To64(left->Hi32, pwr);
  978.             tmp.int64 += decTmp.Hi32;
  979.             if (tmp.u.Hi == 0) {
  980.                 // Result fits in 96 bits.  Use standard aligned add.
  981.                 //
  982.                 decTmp.Hi32 = tmp.u.Lo;
  983.                 left = &decTmp;
  984.                 goto AlignedAdd;
  985.             }
  986.             num[0] = decTmp.v.v.Lo32;
  987.             num[1] = decTmp.v.v.Mid32;
  988.             num[2] = tmp.u.Lo;
  989.             num[3] = tmp.u.Hi;
  990.             hi_prod = 3;
  991.         }
  992.         else {
  993.             // Have to scale by a bunch.  Move the number to a buffer
  994.             // where it has room to grow as it's scaled.
  995.             //
  996.             num[0] = left->v.v.Lo32;
  997.             num[1] = left->v.v.Mid32;
  998.             num[2] = left->Hi32;
  999.             hi_prod = 2;
  1000.  
  1001.             // Scan for zeros in the upper words.
  1002.             //
  1003.             if (num[2] == 0) {
  1004.                 hi_prod = 1;
  1005.                 if (num[1] == 0) {
  1006.                     hi_prod = 0;
  1007.                     if (num[0] == 0) {
  1008.                         // Left arg is zero, return right.
  1009.                         //
  1010.                         DECIMAL_LO64_SET(decRes, DECIMAL_LO64_GET(*right));
  1011.                         decRes.Hi32 = right->Hi32;
  1012.                         decRes.u.u.sign ^= sign;
  1013.                         goto RetDec;
  1014.                     }
  1015.                 }
  1016.             }
  1017.  
  1018.             // Scaling loop, up to 10^9 at a time.  hi_prod stays updated
  1019.             // with index of highest non-zero uint32_t.
  1020.             //
  1021.             for (; scale > 0; scale -= POWER10_MAX) {
  1022.                 if (scale > POWER10_MAX)
  1023.                     pwr = ten_to_nine;
  1024.                 else
  1025.                     pwr = power10[scale];
  1026.  
  1027.                 tmp.u.Hi = 0;
  1028.                 for (cur = 0; cur <= hi_prod; cur++) {
  1029.                     tmp.int64 = UInt32x32To64(num[cur], pwr) + tmp.u.Hi;
  1030.                     num[cur] = tmp.u.Lo;
  1031.                 }
  1032.  
  1033.                 if (tmp.u.Hi != 0)
  1034.                     // We're extending the result by another uint32_t.
  1035.                     num[++hi_prod] = tmp.u.Hi;
  1036.             }
  1037.         }
  1038.  
  1039.         // Scaling complete, do the add.  Could be subtract if signs differ.
  1040.         //
  1041.         tmp.u.Lo = num[0];
  1042.         tmp.u.Hi = num[1];
  1043.  
  1044.         if (sign) {
  1045.             // Signs differ, subtract.
  1046.             //
  1047.             DECIMAL_LO64_SET(decRes, tmp.int64 - DECIMAL_LO64_GET(*right));
  1048.             decRes.Hi32 = num[2] - right->Hi32;
  1049.  
  1050.             // Propagate carry
  1051.             //
  1052.             if (DECIMAL_LO64_GET(decRes) > tmp.int64) {
  1053.                 decRes.Hi32--;
  1054.                 if (decRes.Hi32 >= num[2])
  1055.                     goto LongSub;
  1056.             }
  1057.             else if (decRes.Hi32 > num[2]) {
  1058.             LongSub:
  1059.                 // If num has more than 96 bits of precision, then we need to
  1060.                 // carry the subtraction into the higher bits.  If it doesn't,
  1061.                 // then we subtracted in the wrong order and have to flip the
  1062.                 // sign of the result.
  1063.                 //
  1064.                 if (hi_prod <= 2)
  1065.                     goto SignFlip;
  1066.  
  1067.                 cur = 3;
  1068.                 while(num[cur++]-- == 0);
  1069.                 if (num[hi_prod] == 0)
  1070.                     hi_prod--;
  1071.             }
  1072.         }
  1073.         else {
  1074.             // Signs the same, add.
  1075.             //
  1076.             DECIMAL_LO64_SET(decRes, tmp.int64 + DECIMAL_LO64_GET(*right));
  1077.             decRes.Hi32 = num[2] + right->Hi32;
  1078.  
  1079.             // Propagate carry
  1080.             //
  1081.             if (DECIMAL_LO64_GET(decRes) < tmp.int64) {
  1082.                 decRes.Hi32++;
  1083.                 if (decRes.Hi32 <= num[2])
  1084.                     goto LongAdd;
  1085.             }
  1086.             else if (decRes.Hi32 < num[2]) {
  1087.             LongAdd:
  1088.                 // Had a carry above 96 bits.
  1089.                 //
  1090.                 cur = 3;
  1091.                 do {
  1092.                     if (hi_prod < cur) {
  1093.                         num[cur] = 1;
  1094.                         hi_prod = cur;
  1095.                         break;
  1096.                     }
  1097.                 }while (++num[cur++] == 0);
  1098.             }
  1099.         }
  1100.  
  1101.         if (hi_prod > 2) {
  1102.             num[0] = decRes.v.v.Lo32;
  1103.             num[1] = decRes.v.v.Mid32;
  1104.             num[2] = decRes.Hi32;
  1105.             decRes.u.u.scale = ScaleResult(num, hi_prod, decRes.u.u.scale);
  1106.             if (decRes.u.u.scale == (uint8_t) -1)
  1107.                 return MONO_DECIMAL_OVERFLOW;
  1108.  
  1109.             decRes.v.v.Lo32 = num[0];
  1110.             decRes.v.v.Mid32 = num[1];
  1111.             decRes.Hi32 = num[2];
  1112.         }
  1113.     }
  1114.  
  1115. RetDec:
  1116.     COPYDEC(*result, decRes);
  1117.     // Odd, the Microsoft code does not set result->reserved to zero on this case
  1118.     return MONO_DECIMAL_OK;
  1119. }
  1120.  
  1121. // Decimal addition
  1122. static MonoDecimalStatus
  1123. MONO_VarDecAdd(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
  1124. {
  1125.     return DecAddSub (left, right, result, 0);
  1126. }
  1127.  
  1128. // Decimal subtraction
  1129. static MonoDecimalStatus
  1130. MONO_VarDecSub(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
  1131. {
  1132.     return DecAddSub (left, right, result, DECIMAL_NEG);
  1133. }
  1134.  
  1135. /**
  1136.  * IncreaseScale:
  1137.  *
  1138.  * Entry:
  1139.  *   num - Pointer to 96-bit number as array of uint32_ts, least-sig first
  1140.  *   pwr   - Scale factor to multiply by
  1141.  *
  1142.  * Purpose:
  1143.  *   Multiply the two numbers.  The low 96 bits of the result overwrite
  1144.  *   the input.  The last 32 bits of the product are the return value.
  1145.  *
  1146.  * Exit:
  1147.  *   Returns highest 32 bits of product.
  1148.  *
  1149.  * Exceptions:
  1150.  *   None.
  1151.  *
  1152.  */
  1153. static uint32_t
  1154. IncreaseScale(uint32_t *num, uint32_t pwr)
  1155. {
  1156.     SPLIT64   sdlTmp;
  1157.  
  1158.     sdlTmp.int64 = UInt32x32To64(num[0], pwr);
  1159.     num[0] = sdlTmp.u.Lo;
  1160.     sdlTmp.int64 = UInt32x32To64(num[1], pwr) + sdlTmp.u.Hi;
  1161.     num[1] = sdlTmp.u.Lo;
  1162.     sdlTmp.int64 = UInt32x32To64(num[2], pwr) + sdlTmp.u.Hi;
  1163.     num[2] = sdlTmp.u.Lo;
  1164.     return sdlTmp.u.Hi;
  1165. }
  1166.  
  1167. /**
  1168.  * Div96By64:
  1169.  *
  1170.  * Entry:
  1171.  *   rgulNum - Pointer to 96-bit dividend as array of uint32_ts, least-sig first
  1172.  *   sdlDen  - 64-bit divisor.
  1173.  *
  1174.  * Purpose:
  1175.  *   Do partial divide, yielding 32-bit result and 64-bit remainder.
  1176.  *   Divisor must be larger than upper 64 bits of dividend.
  1177.  *
  1178.  * Exit:
  1179.  *   Remainder overwrites lower 64-bits of dividend.
  1180.  *   Returns quotient.
  1181.  *
  1182.  * Exceptions:
  1183.  *   None.
  1184.  *
  1185.  */
  1186. static uint32_t
  1187. Div96By64(uint32_t *num, SPLIT64 den)
  1188. {
  1189.     SPLIT64 quo;
  1190.     SPLIT64 sdlNum;
  1191.     SPLIT64 prod;
  1192.  
  1193.     sdlNum.u.Lo = num[0];
  1194.  
  1195.     if (num[2] >= den.u.Hi) {
  1196.         // Divide would overflow.  Assume a quotient of 2^32, and set
  1197.         // up remainder accordingly.  Then jump to loop which reduces
  1198.         // the quotient.
  1199.         //
  1200.         sdlNum.u.Hi = num[1] - den.u.Lo;
  1201.         quo.u.Lo = 0;
  1202.         goto NegRem;
  1203.     }
  1204.  
  1205.     // Hardware divide won't overflow
  1206.     //
  1207.     if (num[2] == 0 && num[1] < den.u.Hi)
  1208.         // Result is zero.  Entire dividend is remainder.
  1209.         //
  1210.         return 0;
  1211.  
  1212.     // DivMod64by32 returns quotient in Lo, remainder in Hi.
  1213.     //
  1214.     quo.u.Lo = num[1];
  1215.     quo.u.Hi = num[2];
  1216.     quo.int64 = DivMod64by32(quo.int64, den.u.Hi);
  1217.     sdlNum.u.Hi = quo.u.Hi; // remainder
  1218.  
  1219.     // Compute full remainder, rem = dividend - (quo * divisor).
  1220.     //
  1221.     prod.int64 = UInt32x32To64(quo.u.Lo, den.u.Lo); // quo * lo divisor
  1222.     sdlNum.int64 -= prod.int64;
  1223.  
  1224.     if (sdlNum.int64 > ~prod.int64) {
  1225.     NegRem:
  1226.         // Remainder went negative.  Add divisor back in until it's positive,
  1227.         // a max of 2 times.
  1228.         //
  1229.         do {
  1230.             quo.u.Lo--;
  1231.             sdlNum.int64 += den.int64;
  1232.         }while (sdlNum.int64 >= den.int64);
  1233.     }
  1234.  
  1235.     num[0] = sdlNum.u.Lo;
  1236.     num[1] = sdlNum.u.Hi;
  1237.     return quo.u.Lo;
  1238. }
  1239.  
  1240. /***
  1241. * Div128By96
  1242. *
  1243. * Entry:
  1244. *   rgulNum - Pointer to 128-bit dividend as array of uint32_ts, least-sig first
  1245. *   den - Pointer to 96-bit divisor.
  1246. *
  1247. * Purpose:
  1248. *   Do partial divide, yielding 32-bit result and 96-bit remainder.
  1249. *   Top divisor uint32_t must be larger than top dividend uint32_t.  This is
  1250. *   assured in the initial call because the divisor is normalized
  1251. *   and the dividend can't be.  In subsequent calls, the remainder
  1252. *   is multiplied by 10^9 (max), so it can be no more than 1/4 of
  1253. *   the divisor which is effectively multiplied by 2^32 (4 * 10^9).
  1254. *
  1255. * Exit:
  1256. *   Remainder overwrites lower 96-bits of dividend.
  1257. *   Returns quotient.
  1258. *
  1259. * Exceptions:
  1260. *   None.
  1261. *
  1262. ***********************************************************************/
  1263.  
  1264. static uint32_t
  1265. Div128By96(uint32_t *num, uint32_t *den)
  1266. {
  1267.     SPLIT64 sdlQuo;
  1268.     SPLIT64 sdlNum;
  1269.     SPLIT64 sdlProd1;
  1270.     SPLIT64 sdlProd2;
  1271.  
  1272.     sdlNum.u.Lo = num[0];
  1273.     sdlNum.u.Hi = num[1];
  1274.  
  1275.     if (num[3] == 0 && num[2] < den[2]){
  1276.         // Result is zero.  Entire dividend is remainder.
  1277.         //
  1278.         return 0;
  1279.     }
  1280.  
  1281.     // DivMod64by32 returns quotient in Lo, remainder in Hi.
  1282.     //
  1283.     sdlQuo.u.Lo = num[2];
  1284.     sdlQuo.u.Hi = num[3];
  1285.     sdlQuo.int64 = DivMod64by32(sdlQuo.int64, den[2]);
  1286.  
  1287.     // Compute full remainder, rem = dividend - (quo * divisor).
  1288.     //
  1289.     sdlProd1.int64 = UInt32x32To64(sdlQuo.u.Lo, den[0]); // quo * lo divisor
  1290.     sdlProd2.int64 = UInt32x32To64(sdlQuo.u.Lo, den[1]); // quo * mid divisor
  1291.     sdlProd2.int64 += sdlProd1.u.Hi;
  1292.     sdlProd1.u.Hi = sdlProd2.u.Lo;
  1293.  
  1294.     sdlNum.int64 -= sdlProd1.int64;
  1295.     num[2] = sdlQuo.u.Hi - sdlProd2.u.Hi; // sdlQuo.Hi is remainder
  1296.  
  1297.     // Propagate carries
  1298.     //
  1299.     if (sdlNum.int64 > ~sdlProd1.int64) {
  1300.         num[2]--;
  1301.         if (num[2] >= ~sdlProd2.u.Hi)
  1302.             goto NegRem;
  1303.     } else if (num[2] > ~sdlProd2.u.Hi) {
  1304.     NegRem:
  1305.         // Remainder went negative.  Add divisor back in until it's positive,
  1306.         // a max of 2 times.
  1307.         //
  1308.         sdlProd1.u.Lo = den[0];
  1309.         sdlProd1.u.Hi = den[1];
  1310.  
  1311.         for (;;) {
  1312.             sdlQuo.u.Lo--;
  1313.             sdlNum.int64 += sdlProd1.int64;
  1314.             num[2] += den[2];
  1315.  
  1316.             if (sdlNum.int64 < sdlProd1.int64) {
  1317.                 // Detected carry. Check for carry out of top
  1318.                 // before adding it in.
  1319.                 //
  1320.                 if (num[2]++ < den[2])
  1321.                     break;
  1322.             }
  1323.             if (num[2] < den[2])
  1324.                 break; // detected carry
  1325.         }
  1326.     }
  1327.  
  1328.     num[0] = sdlNum.u.Lo;
  1329.     num[1] = sdlNum.u.Hi;
  1330.     return sdlQuo.u.Lo;
  1331. }
  1332.  
  1333. // Add a 32 bit unsigned long to an array of 3 unsigned longs representing a 96 integer
  1334. // Returns FALSE if there is an overflow
  1335. static gboolean
  1336. Add32To96(uint32_t *num, uint32_t value)
  1337. {
  1338.     num[0] += value;
  1339.     if (num[0] < value) {
  1340.         if (++num[1] == 0) {                
  1341.             if (++num[2] == 0) {                
  1342.                 return FALSE;
  1343.             }            
  1344.         }
  1345.     }
  1346.     return TRUE;
  1347. }
  1348.  
  1349. static void
  1350. OverflowUnscale (uint32_t *quo, gboolean remainder)
  1351. {
  1352.     SPLIT64  sdlTmp;
  1353.    
  1354.     // We have overflown, so load the high bit with a one.
  1355.     sdlTmp.u.Hi = 1u;
  1356.     sdlTmp.u.Lo = quo[2];
  1357.     sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
  1358.     quo[2] = sdlTmp.u.Lo;
  1359.     sdlTmp.u.Lo = quo[1];
  1360.     sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
  1361.     quo[1] = sdlTmp.u.Lo;
  1362.     sdlTmp.u.Lo = quo[0];
  1363.     sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10u);
  1364.     quo[0] = sdlTmp.u.Lo;
  1365.     // The remainder is the last digit that does not fit, so we can use it to work out if we need to round up
  1366.     if ((sdlTmp.u.Hi > 5) || ((sdlTmp.u.Hi == 5) && ( remainder || (quo[0] & 1)))) {
  1367.         Add32To96(quo, 1u);
  1368.     }
  1369. }
  1370.  
  1371. // MONO_VarDecDiv - Decimal divide
  1372. static MonoDecimalStatus
  1373. MONO_VarDecDiv(MonoDecimal *left, MonoDecimal *right, MonoDecimal *result)
  1374. {
  1375.     uint32_t   quo[3];
  1376.     uint32_t   quoSave[3];
  1377.     uint32_t   rem[4];
  1378.     uint32_t   divisor[3];
  1379.     uint32_t   pwr;
  1380.     uint32_t   utmp;
  1381.     uint32_t   utmp1;
  1382.     SPLIT64 sdlTmp;
  1383.     SPLIT64 sdlDivisor;
  1384.     int     scale;
  1385.     int     cur_scale;
  1386.  
  1387.     scale = left->u.u.scale - right->u.u.scale;
  1388.     divisor[0] = right->v.v.Lo32;
  1389.     divisor[1] = right->v.v.Mid32;
  1390.     divisor[2] = right->Hi32;
  1391.  
  1392.     if (divisor[1] == 0 && divisor[2] == 0) {
  1393.         // Divisor is only 32 bits.  Easy divide.
  1394.         //
  1395.         if (divisor[0] == 0)
  1396.             return MONO_DECIMAL_DIVBYZERO;
  1397.  
  1398.         quo[0] = left->v.v.Lo32;
  1399.         quo[1] = left->v.v.Mid32;
  1400.         quo[2] = left->Hi32;
  1401.         rem[0] = Div96By32(quo, divisor[0]);
  1402.  
  1403.         for (;;) {
  1404.             if (rem[0] == 0) {
  1405.                 if (scale < 0) {
  1406.                     cur_scale = min(9, -scale);
  1407.                     goto HaveScale;
  1408.                 }
  1409.                 break;
  1410.             }
  1411.  
  1412.             // We have computed a quotient based on the natural scale
  1413.             // ( <dividend scale> - <divisor scale> ).  We have a non-zero
  1414.             // remainder, so now we should increase the scale if possible to
  1415.             // include more quotient bits.
  1416.             //
  1417.             // If it doesn't cause overflow, we'll loop scaling by 10^9 and
  1418.             // computing more quotient bits as long as the remainder stays
  1419.             // non-zero.  If scaling by that much would cause overflow, we'll
  1420.             // drop out of the loop and scale by as much as we can.
  1421.             //
  1422.             // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
  1423.             // = 4.294 967 296.  So the upper limit is quo[2] == 4 and
  1424.             // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+.  Since
  1425.             // quotient bits in quo[0] could be all 1's, then 1,266,874,888
  1426.             // is the largest value in quo[1] (when quo[2] == 4) that is
  1427.             // assured not to overflow.
  1428.             //
  1429.             cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
  1430.             if (cur_scale == 0) {
  1431.                 // No more scaling to be done, but remainder is non-zero.
  1432.                 // Round quotient.
  1433.                 //
  1434.                 utmp = rem[0] << 1;
  1435.                 if (utmp < rem[0] || (utmp >= divisor[0] &&
  1436.                               (utmp > divisor[0] || (quo[0] & 1)))) {
  1437.                 RoundUp:
  1438.                     if (++quo[0] == 0)
  1439.                         if (++quo[1] == 0)
  1440.                             quo[2]++;
  1441.                 }
  1442.                 break;
  1443.             }
  1444.  
  1445.             if (cur_scale == -1)
  1446.                 return MONO_DECIMAL_OVERFLOW;
  1447.  
  1448.         HaveScale:
  1449.             pwr = power10[cur_scale];
  1450.             scale += cur_scale;
  1451.  
  1452.             if (IncreaseScale(quo, pwr) != 0)
  1453.                 return MONO_DECIMAL_OVERFLOW;
  1454.  
  1455.             sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
  1456.             rem[0] = sdlTmp.u.Hi;
  1457.  
  1458.             quo[0] += sdlTmp.u.Lo;
  1459.             if (quo[0] < sdlTmp.u.Lo) {
  1460.                 if (++quo[1] == 0)
  1461.                     quo[2]++;
  1462.             }
  1463.         } // for (;;)
  1464.     }
  1465.     else {
  1466.         // Divisor has bits set in the upper 64 bits.
  1467.         //
  1468.         // Divisor must be fully normalized (shifted so bit 31 of the most
  1469.         // significant uint32_t is 1).  Locate the MSB so we know how much to
  1470.         // normalize by.  The dividend will be shifted by the same amount so
  1471.         // the quotient is not changed.
  1472.         //
  1473.         if (divisor[2] == 0)
  1474.             utmp = divisor[1];
  1475.         else
  1476.             utmp = divisor[2];
  1477.  
  1478.         cur_scale = 0;
  1479.         if (!(utmp & 0xFFFF0000)) {
  1480.             cur_scale += 16;
  1481.             utmp <<= 16;
  1482.         }
  1483.         if (!(utmp & 0xFF000000)) {
  1484.             cur_scale += 8;
  1485.             utmp <<= 8;
  1486.         }
  1487.         if (!(utmp & 0xF0000000)) {
  1488.             cur_scale += 4;
  1489.             utmp <<= 4;
  1490.         }
  1491.         if (!(utmp & 0xC0000000)) {
  1492.             cur_scale += 2;
  1493.             utmp <<= 2;
  1494.         }
  1495.         if (!(utmp & 0x80000000)) {
  1496.             cur_scale++;
  1497.             utmp <<= 1;
  1498.         }
  1499.    
  1500.         // Shift both dividend and divisor left by cur_scale.
  1501.         //
  1502.         sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
  1503.         rem[0] = sdlTmp.u.Lo;
  1504.         rem[1] = sdlTmp.u.Hi;
  1505.         sdlTmp.u.Lo = left->v.v.Mid32;
  1506.         sdlTmp.u.Hi = left->Hi32;
  1507.         sdlTmp.int64 <<= cur_scale;
  1508.         rem[2] = sdlTmp.u.Hi;
  1509.         rem[3] = (left->Hi32 >> (31 - cur_scale)) >> 1;
  1510.  
  1511.         sdlDivisor.u.Lo = divisor[0];
  1512.         sdlDivisor.u.Hi = divisor[1];
  1513.         sdlDivisor.int64 <<= cur_scale;
  1514.  
  1515.         if (divisor[2] == 0) {
  1516.             // Have a 64-bit divisor in sdlDivisor.  The remainder
  1517.             // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
  1518.             //
  1519.             sdlTmp.u.Lo = rem[2];
  1520.             sdlTmp.u.Hi = rem[3];
  1521.  
  1522.             quo[2] = 0;
  1523.             quo[1] = Div96By64(&rem[1], sdlDivisor);
  1524.             quo[0] = Div96By64(rem, sdlDivisor);
  1525.  
  1526.             for (;;) {
  1527.                 if ((rem[0] | rem[1]) == 0) {
  1528.                     if (scale < 0) {
  1529.                         cur_scale = min(9, -scale);
  1530.                         goto HaveScale64;
  1531.                     }
  1532.                     break;
  1533.                 }
  1534.  
  1535.                 // Remainder is non-zero.  Scale up quotient and remainder by
  1536.                 // powers of 10 so we can compute more significant bits.
  1537.                 //
  1538.                 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
  1539.                 if (cur_scale == 0) {
  1540.                     // No more scaling to be done, but remainder is non-zero.
  1541.                     // Round quotient.
  1542.                     //
  1543.                     sdlTmp.u.Lo = rem[0];
  1544.                     sdlTmp.u.Hi = rem[1];
  1545.                     if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
  1546.                         (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
  1547.                         goto RoundUp;
  1548.                     break;
  1549.                 }
  1550.  
  1551.                 if (cur_scale == -1)
  1552.                     return MONO_DECIMAL_OVERFLOW;
  1553.  
  1554.             HaveScale64:
  1555.                 pwr = power10[cur_scale];
  1556.                 scale += cur_scale;
  1557.  
  1558.                 if (IncreaseScale(quo, pwr) != 0)
  1559.                     return MONO_DECIMAL_OVERFLOW;
  1560.  
  1561.                 rem[2] = 0;  // rem is 64 bits, IncreaseScale uses 96
  1562.                 IncreaseScale(rem, pwr);
  1563.                 utmp = Div96By64(rem, sdlDivisor);
  1564.                 quo[0] += utmp;
  1565.                 if (quo[0] < utmp)
  1566.                     if (++quo[1] == 0)
  1567.                         quo[2]++;
  1568.  
  1569.             } // for (;;)
  1570.         }
  1571.         else {
  1572.             // Have a 96-bit divisor in divisor[].
  1573.             //
  1574.             // Start by finishing the shift left by cur_scale.
  1575.             //
  1576.             sdlTmp.u.Lo = divisor[1];
  1577.             sdlTmp.u.Hi = divisor[2];
  1578.             sdlTmp.int64 <<= cur_scale;
  1579.             divisor[0] = sdlDivisor.u.Lo;
  1580.             divisor[1] = sdlDivisor.u.Hi;
  1581.             divisor[2] = sdlTmp.u.Hi;
  1582.  
  1583.             // The remainder (currently 96 bits spread over 4 uint32_ts)
  1584.             // will be < divisor.
  1585.             //
  1586.             quo[2] = 0;
  1587.             quo[1] = 0;
  1588.             quo[0] = Div128By96(rem, divisor);
  1589.  
  1590.             for (;;) {
  1591.                 if ((rem[0] | rem[1] | rem[2]) == 0) {
  1592.                     if (scale < 0) {
  1593.                         cur_scale = min(9, -scale);
  1594.                         goto HaveScale96;
  1595.                     }
  1596.                     break;
  1597.                 }
  1598.  
  1599.                 // Remainder is non-zero.  Scale up quotient and remainder by
  1600.                 // powers of 10 so we can compute more significant bits.
  1601.                 //
  1602.                 cur_scale = SearchScale(quo[2], quo[1], quo [0], scale);
  1603.                 if (cur_scale == 0) {
  1604.                     // No more scaling to be done, but remainder is non-zero.
  1605.                     // Round quotient.
  1606.                     //
  1607.                     if (rem[2] >= 0x80000000)
  1608.                         goto RoundUp;
  1609.  
  1610.                     utmp = rem[0] > 0x80000000;
  1611.                     utmp1 = rem[1] > 0x80000000;
  1612.                     rem[0] <<= 1;
  1613.                     rem[1] = (rem[1] << 1) + utmp;
  1614.                     rem[2] = (rem[2] << 1) + utmp1;
  1615.  
  1616.                     if ((rem[2] > divisor[2] || rem[2] == divisor[2]) &&
  1617.                         ((rem[1] > divisor[1] || rem[1] == divisor[1]) &&
  1618.                          ((rem[0] > divisor[0] || rem[0] == divisor[0]) &&
  1619.                           (quo[0] & 1))))
  1620.                         goto RoundUp;
  1621.                     break;
  1622.                 }
  1623.  
  1624.                 if (cur_scale == -1)
  1625.                     return MONO_DECIMAL_OVERFLOW;
  1626.  
  1627.             HaveScale96:
  1628.                 pwr = power10[cur_scale];
  1629.                 scale += cur_scale;
  1630.  
  1631.                 if (IncreaseScale(quo, pwr) != 0)
  1632.                     return MONO_DECIMAL_OVERFLOW;
  1633.  
  1634.                 rem[3] = IncreaseScale(rem, pwr);
  1635.                 utmp = Div128By96(rem, divisor);
  1636.                 quo[0] += utmp;
  1637.                 if (quo[0] < utmp)
  1638.                     if (++quo[1] == 0)
  1639.                         quo[2]++;
  1640.  
  1641.             } // for (;;)
  1642.         }
  1643.     }
  1644.  
  1645.     // No more remainder.  Try extracting any extra powers of 10 we may have
  1646.     // added.  We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
  1647.     // If a division by one of these powers returns a zero remainder, then
  1648.     // we keep the quotient.  If the remainder is not zero, then we restore
  1649.     // the previous value.
  1650.     //
  1651.     // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
  1652.     // we can extract.  We use this as a quick test on whether to try a
  1653.     // given power.
  1654.     //
  1655.     while ((quo[0] & 0xFF) == 0 && scale >= 8) {
  1656.         quoSave[0] = quo[0];
  1657.         quoSave[1] = quo[1];
  1658.         quoSave[2] = quo[2];
  1659.  
  1660.         if (Div96By32(quoSave, 100000000) == 0) {
  1661.             quo[0] = quoSave[0];
  1662.             quo[1] = quoSave[1];
  1663.             quo[2] = quoSave[2];
  1664.             scale -= 8;
  1665.         }
  1666.         else
  1667.             break;
  1668.     }
  1669.  
  1670.     if ((quo[0] & 0xF) == 0 && scale >= 4) {
  1671.         quoSave[0] = quo[0];
  1672.         quoSave[1] = quo[1];
  1673.         quoSave[2] = quo[2];
  1674.  
  1675.         if (Div96By32(quoSave, 10000) == 0) {
  1676.             quo[0] = quoSave[0];
  1677.             quo[1] = quoSave[1];
  1678.             quo[2] = quoSave[2];
  1679.             scale -= 4;
  1680.         }
  1681.     }
  1682.  
  1683.     if ((quo[0] & 3) == 0 && scale >= 2) {
  1684.         quoSave[0] = quo[0];
  1685.         quoSave[1] = quo[1];
  1686.         quoSave[2] = quo[2];
  1687.  
  1688.         if (Div96By32(quoSave, 100) == 0) {
  1689.             quo[0] = quoSave[0];
  1690.             quo[1] = quoSave[1];
  1691.             quo[2] = quoSave[2];
  1692.             scale -= 2;
  1693.         }
  1694.     }
  1695.  
  1696.     if ((quo[0] & 1) == 0 && scale >= 1) {
  1697.         quoSave[0] = quo[0];
  1698.         quoSave[1] = quo[1];
  1699.         quoSave[2] = quo[2];
  1700.  
  1701.         if (Div96By32(quoSave, 10) == 0) {
  1702.             quo[0] = quoSave[0];
  1703.             quo[1] = quoSave[1];
  1704.             quo[2] = quoSave[2];
  1705.             scale -= 1;
  1706.         }
  1707.     }
  1708.  
  1709.     result->Hi32 = quo[2];
  1710.     result->v.v.Mid32 = quo[1];
  1711.     result->v.v.Lo32 = quo[0];
  1712.     result->u.u.scale = scale;
  1713.     result->u.u.sign = left->u.u.sign ^ right->u.u.sign;
  1714.     return MONO_DECIMAL_OK;
  1715. }
  1716.  
  1717. // MONO_VarDecAbs - Decimal Absolute Value
  1718. static void
  1719. MONO_VarDecAbs (MonoDecimal *pdecOprd, MonoDecimal *result)
  1720. {
  1721.     COPYDEC(*result, *pdecOprd);
  1722.     result->u.u.sign &= ~DECIMAL_NEG;
  1723.     // Microsoft does not set reserved here
  1724. }
  1725.  
  1726. // MONO_VarDecFix - Decimal Fix (chop to integer)
  1727. static void
  1728. MONO_VarDecFix (MonoDecimal *pdecOprd, MonoDecimal *result)
  1729. {
  1730.     DecFixInt(result, pdecOprd);
  1731. }
  1732.  
  1733.  
  1734. // MONO_VarDecInt - Decimal Int (round down to integer)
  1735. static void
  1736. MONO_VarDecInt (MonoDecimal *pdecOprd, MonoDecimal *result)
  1737. {
  1738.     if (DecFixInt(result, pdecOprd) != 0 && (result->u.u.sign & DECIMAL_NEG)) {
  1739.         // We have chopped off a non-zero amount from a negative value.  Since
  1740.         // we round toward -infinity, we must increase the integer result by
  1741.         // 1 to make it more negative.  This will never overflow because
  1742.         // in order to have a remainder, we must have had a non-zero scale factor.
  1743.         // Our scale factor is back to zero now.
  1744.         //
  1745.         DECIMAL_LO64_SET(*result, DECIMAL_LO64_GET(*result) + 1);
  1746.         if (DECIMAL_LO64_GET(*result) == 0)
  1747.             result->Hi32++;
  1748.     }
  1749. }
  1750.  
  1751.  
  1752. // MONO_VarDecNeg - Decimal Negate
  1753. static void
  1754. MONO_VarDecNeg (MonoDecimal *pdecOprd, MonoDecimal *result)
  1755. {
  1756.     COPYDEC(*result, *pdecOprd);
  1757.     // Microsoft does not set result->reserved to zero on this case.
  1758.     result->u.u.sign ^= DECIMAL_NEG;
  1759. }
  1760.  
  1761. //
  1762. // Returns: MONO_DECIMAL_INVALID_ARGUMENT, MONO_DECIMAL_OK
  1763. //
  1764. static MonoDecimalStatus
  1765. MONO_VarDecRound(MonoDecimal *input, int cDecimals, MonoDecimal *result)
  1766. {
  1767.     uint32_t num[3];
  1768.     uint32_t rem;
  1769.     uint32_t sticky;
  1770.     uint32_t pwr;
  1771.     int scale;
  1772.  
  1773.     if (cDecimals < 0)
  1774.         return MONO_DECIMAL_INVALID_ARGUMENT;
  1775.  
  1776.     scale = input->u.u.scale - cDecimals;
  1777.     if (scale > 0) {
  1778.         num[0] = input->v.v.Lo32;
  1779.         num[1] = input->v.v.Mid32;
  1780.         num[2] = input->Hi32;
  1781.         result->u.u.sign = input->u.u.sign;
  1782.         rem = sticky = 0;
  1783.  
  1784.         do {
  1785.             sticky |= rem;
  1786.             if (scale > POWER10_MAX)
  1787.                 pwr = ten_to_nine;
  1788.             else
  1789.                 pwr = power10[scale];
  1790.  
  1791.             rem = Div96By32(num, pwr);
  1792.             scale -= 9;
  1793.         }while (scale > 0);
  1794.  
  1795.         // Now round.  rem has last remainder, sticky has sticky bits.
  1796.         // To do IEEE rounding, we add LSB of result to sticky bits so
  1797.         // either causes round up if remainder * 2 == last divisor.
  1798.         //
  1799.         sticky |= num[0] & 1;
  1800.         rem = (rem << 1) + (sticky != 0);
  1801.         if (pwr < rem &&
  1802.             ++num[0] == 0 &&
  1803.             ++num[1] == 0
  1804.             )
  1805.             ++num[2];
  1806.  
  1807.         result->v.v.Lo32 = num[0];
  1808.         result->v.v.Mid32 = num[1];
  1809.         result->Hi32 = num[2];
  1810.         result->u.u.scale = cDecimals;
  1811.         return MONO_DECIMAL_OK;
  1812.     }
  1813.  
  1814.     COPYDEC(*result, *input);
  1815.     // Odd, the Microsoft source does not set the result->reserved to zero here.
  1816.     return MONO_DECIMAL_OK;
  1817. }
  1818.  
  1819. //
  1820. // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
  1821. static MonoDecimalStatus
  1822. MONO_VarDecFromR4 (float input, MonoDecimal* result)
  1823. {
  1824.     int         exp;    // number of bits to left of binary point
  1825.     int         power;
  1826.     uint32_t       mant;
  1827.     double      dbl;
  1828.     SPLIT64     sdlLo;
  1829.     SPLIT64     sdlHi;
  1830.     int         lmax, cur;  // temps used during scale reduction
  1831.    
  1832.     // The most we can scale by is 10^28, which is just slightly more
  1833.     // than 2^93.  So a float with an exponent of -94 could just
  1834.     // barely reach 0.5, but smaller exponents will always round to zero.
  1835.     //
  1836.     if ((exp = ((SingleStructure *)&input)->exp - SNGBIAS) < -94 ) {
  1837.         DECIMAL_SETZERO(*result);
  1838.         return MONO_DECIMAL_OK;
  1839.     }
  1840.  
  1841.     if (exp > 96)
  1842.         return MONO_DECIMAL_OVERFLOW;
  1843.  
  1844.     // Round the input to a 7-digit integer.  The R4 format has
  1845.     // only 7 digits of precision, and we want to keep garbage digits
  1846.     // out of the Decimal were making.
  1847.     //
  1848.     // Calculate max power of 10 input value could have by multiplying
  1849.     // the exponent by log10(2).  Using scaled integer multiplcation,
  1850.     // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
  1851.     //
  1852.     dbl = fabs(input);
  1853.     power = 6 - ((exp * 19728) >> 16);
  1854.    
  1855.     if (power >= 0) {
  1856.         // We have less than 7 digits, scale input up.
  1857.         //
  1858.         if (power > DECMAX)
  1859.             power = DECMAX;
  1860.        
  1861.         dbl = dbl * double_power10[power];
  1862.     } else {
  1863.         if (power != -1 || dbl >= 1E7)
  1864.             dbl = dbl / fnDblPower10(-power);
  1865.         else
  1866.             power = 0; // didn't scale it
  1867.     }
  1868.    
  1869.     g_assert (dbl < 1E7);
  1870.     if (dbl < 1E6 && power < DECMAX) {
  1871.         dbl *= 10;
  1872.         power++;
  1873.         g_assert(dbl >= 1E6);
  1874.     }
  1875.    
  1876.     // Round to integer
  1877.     //
  1878.     mant = (int32_t)dbl;
  1879.     dbl -= (double)mant;  // difference between input & integer
  1880.     if ( dbl > 0.5 || (dbl == 0.5 && (mant & 1)))
  1881.         mant++;
  1882.    
  1883.     if (mant == 0) {
  1884.         DECIMAL_SETZERO(*result);
  1885.         return MONO_DECIMAL_OK;
  1886.     }
  1887.    
  1888.     if (power < 0) {
  1889.         // Add -power factors of 10, -power <= (29 - 7) = 22.
  1890.         //
  1891.         power = -power;
  1892.         if (power < 10) {
  1893.             sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power]);
  1894.            
  1895.             DECIMAL_LO32(*result) = sdlLo.u.Lo;
  1896.             DECIMAL_MID32(*result) = sdlLo.u.Hi;
  1897.             DECIMAL_HI32(*result) = 0;
  1898.         } else {
  1899.             // Have a big power of 10.
  1900.             //
  1901.             if (power > 18) {
  1902.                 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 18]);
  1903.                 sdlLo.int64 = UInt64x64To128(sdlLo, ten_to_eighteen, &sdlHi.int64);
  1904.                
  1905.                 if (sdlHi.u.Hi != 0)
  1906.                     return MONO_DECIMAL_OVERFLOW;
  1907.             }
  1908.             else {
  1909.                 sdlLo.int64 = UInt32x32To64(mant, (uint32_t)long_power10[power - 9]);
  1910.                 sdlHi.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Hi);
  1911.                 sdlLo.int64 = UInt32x32To64(ten_to_nine, sdlLo.u.Lo);
  1912.                 sdlHi.int64 += sdlLo.u.Hi;
  1913.                 sdlLo.u.Hi = sdlHi.u.Lo;
  1914.                 sdlHi.u.Lo = sdlHi.u.Hi;
  1915.             }
  1916.             DECIMAL_LO32(*result) = sdlLo.u.Lo;
  1917.             DECIMAL_MID32(*result) = sdlLo.u.Hi;
  1918.             DECIMAL_HI32(*result) = sdlHi.u.Lo;
  1919.         }
  1920.         DECIMAL_SCALE(*result) = 0;
  1921.     } else {
  1922.         // Factor out powers of 10 to reduce the scale, if possible.
  1923.         // The maximum number we could factor out would be 6.  This
  1924.         // comes from the fact we have a 7-digit number, and the
  1925.         // MSD must be non-zero -- but the lower 6 digits could be
  1926.         // zero.  Note also the scale factor is never negative, so
  1927.         // we can't scale by any more than the power we used to
  1928.         // get the integer.
  1929.         //
  1930.         // DivMod32by32 returns the quotient in Lo, the remainder in Hi.
  1931.         //
  1932.         lmax = min(power, 6);
  1933.        
  1934.         // lmax is the largest power of 10 to try, lmax <= 6.
  1935.         // We'll try powers 4, 2, and 1 unless they're too big.
  1936.         //
  1937.         for (cur = 4; cur > 0; cur >>= 1)
  1938.         {
  1939.             if (cur > lmax)
  1940.                 continue;
  1941.            
  1942.             sdlLo.int64 = DivMod32by32(mant, (uint32_t)long_power10[cur]);
  1943.            
  1944.             if (sdlLo.u.Hi == 0) {
  1945.                 mant = sdlLo.u.Lo;
  1946.                 power -= cur;
  1947.                 lmax -= cur;
  1948.             }
  1949.         }
  1950.         DECIMAL_LO32(*result) = mant;
  1951.         DECIMAL_MID32(*result) = 0;
  1952.         DECIMAL_HI32(*result) = 0;
  1953.         DECIMAL_SCALE(*result) = power;
  1954.     }
  1955.    
  1956.     DECIMAL_SIGN(*result) = (char)((SingleStructure *)&input)->sign << 7;
  1957.     return MONO_DECIMAL_OK;
  1958. }
  1959.  
  1960. //
  1961. // Returns MONO_DECIMAL_OK or MONO_DECIMAL_OVERFLOW
  1962. static MonoDecimalStatus
  1963. MONO_VarDecFromR8 (double input, MonoDecimal *result)
  1964. {
  1965.     int         exp;    // number of bits to left of binary point
  1966.     int         power;  // power-of-10 scale factor
  1967.     SPLIT64     sdlMant;
  1968.     SPLIT64     sdlLo;
  1969.     double      dbl;
  1970.     int         lmax, cur;  // temps used during scale reduction
  1971.     uint32_t       pwr_cur;
  1972.     uint32_t       quo;
  1973.    
  1974.    
  1975.     // The most we can scale by is 10^28, which is just slightly more
  1976.     // than 2^93.  So a float with an exponent of -94 could just
  1977.     // barely reach 0.5, but smaller exponents will always round to zero.
  1978.     //
  1979.     if ((exp = ((DoubleStructure *)&input)->u.exp - DBLBIAS) < -94) {
  1980.         DECIMAL_SETZERO(*result);
  1981.         return MONO_DECIMAL_OK;
  1982.     }
  1983.  
  1984.     if (exp > 96)
  1985.         return MONO_DECIMAL_OVERFLOW;
  1986.  
  1987.     // Round the input to a 15-digit integer.  The R8 format has
  1988.     // only 15 digits of precision, and we want to keep garbage digits
  1989.     // out of the Decimal were making.
  1990.     //
  1991.     // Calculate max power of 10 input value could have by multiplying
  1992.     // the exponent by log10(2).  Using scaled integer multiplcation,
  1993.     // log10(2) * 2 ^ 16 = .30103 * 65536 = 19728.3.
  1994.     //
  1995.     dbl = fabs(input);
  1996.     power = 14 - ((exp * 19728) >> 16);
  1997.    
  1998.     if (power >= 0) {
  1999.         // We have less than 15 digits, scale input up.
  2000.         //
  2001.         if (power > DECMAX)
  2002.             power = DECMAX;
  2003.  
  2004.         dbl = dbl * double_power10[power];
  2005.     } else {
  2006.         if (power != -1 || dbl >= 1E15)
  2007.             dbl = dbl / fnDblPower10(-power);
  2008.         else
  2009.             power = 0; // didn't scale it
  2010.     }
  2011.  
  2012.     g_assert (dbl < 1E15);
  2013.     if (dbl < 1E14 && power < DECMAX) {
  2014.         dbl *= 10;
  2015.         power++;
  2016.         g_assert(dbl >= 1E14);
  2017.     }
  2018.  
  2019.     // Round to int64
  2020.     //
  2021.     sdlMant.int64 = (int64_t)dbl;
  2022.     dbl -= (double)(int64_t)sdlMant.int64;  // dif between input & integer
  2023.     if ( dbl > 0.5 || (dbl == 0.5 && (sdlMant.u.Lo & 1)))
  2024.         sdlMant.int64++;
  2025.  
  2026.     if (sdlMant.int64 == 0) {
  2027.         DECIMAL_SETZERO(*result);
  2028.         return MONO_DECIMAL_OK;
  2029.     }
  2030.  
  2031.     if (power < 0) {
  2032.         // Add -power factors of 10, -power <= (29 - 15) = 14.
  2033.         //
  2034.         power = -power;
  2035.         if (power < 10) {
  2036.             sdlLo.int64 = UInt32x32To64(sdlMant.u.Lo, (uint32_t)long_power10[power]);
  2037.             sdlMant.int64 = UInt32x32To64(sdlMant.u.Hi, (uint32_t)long_power10[power]);
  2038.             sdlMant.int64 += sdlLo.u.Hi;
  2039.             sdlLo.u.Hi = sdlMant.u.Lo;
  2040.             sdlMant.u.Lo = sdlMant.u.Hi;
  2041.         }
  2042.         else {
  2043.             // Have a big power of 10.
  2044.             //
  2045.             g_assert(power <= 14);
  2046.             sdlLo.int64 = UInt64x64To128(sdlMant, sdl_power10[power-10], &sdlMant.int64);
  2047.  
  2048.             if (sdlMant.u.Hi != 0)
  2049.                 return MONO_DECIMAL_OVERFLOW;
  2050.         }
  2051.         DECIMAL_LO32(*result) = sdlLo.u.Lo;
  2052.         DECIMAL_MID32(*result) = sdlLo.u.Hi;
  2053.         DECIMAL_HI32(*result) = sdlMant.u.Lo;
  2054.         DECIMAL_SCALE(*result) = 0;
  2055.     }
  2056.     else {
  2057.         // Factor out powers of 10 to reduce the scale, if possible.
  2058.         // The maximum number we could factor out would be 14.  This
  2059.         // comes from the fact we have a 15-digit number, and the
  2060.         // MSD must be non-zero -- but the lower 14 digits could be
  2061.         // zero.  Note also the scale factor is never negative, so
  2062.         // we can't scale by any more than the power we used to
  2063.         // get the integer.
  2064.         //
  2065.         // DivMod64by32 returns the quotient in Lo, the remainder in Hi.
  2066.         //
  2067.         lmax = min(power, 14);
  2068.  
  2069.         // lmax is the largest power of 10 to try, lmax <= 14.
  2070.         // We'll try powers 8, 4, 2, and 1 unless they're too big.
  2071.         //
  2072.         for (cur = 8; cur > 0; cur >>= 1)
  2073.         {
  2074.             if (cur > lmax)
  2075.                 continue;
  2076.  
  2077.             pwr_cur = (uint32_t)long_power10[cur];
  2078.  
  2079.             if (sdlMant.u.Hi >= pwr_cur) {
  2080.                 // Overflow if we try to divide in one step.
  2081.                 //
  2082.                 sdlLo.int64 = DivMod64by32(sdlMant.u.Hi, pwr_cur);
  2083.                 quo = sdlLo.u.Lo;
  2084.                 sdlLo.u.Lo = sdlMant.u.Lo;
  2085.                 sdlLo.int64 = DivMod64by32(sdlLo.int64, pwr_cur);
  2086.             }
  2087.             else {
  2088.                 quo = 0;
  2089.                 sdlLo.int64 = DivMod64by32(sdlMant.int64, pwr_cur);
  2090.             }
  2091.  
  2092.             if (sdlLo.u.Hi == 0) {
  2093.                 sdlMant.u.Hi = quo;
  2094.                 sdlMant.u.Lo = sdlLo.u.Lo;
  2095.                 power -= cur;
  2096.                 lmax -= cur;
  2097.             }
  2098.         }
  2099.  
  2100.         DECIMAL_HI32(*result) = 0;
  2101.         DECIMAL_SCALE(*result) = power;
  2102.         DECIMAL_LO32(*result) = sdlMant.u.Lo;
  2103.         DECIMAL_MID32(*result) = sdlMant.u.Hi;
  2104.     }
  2105.  
  2106.     DECIMAL_SIGN(*result) = (char)((DoubleStructure *)&input)->u.sign << 7;
  2107.     return MONO_DECIMAL_OK;
  2108. }
  2109.  
  2110. // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
  2111. static MonoDecimalStatus
  2112. MONO_VarR8FromDec(MonoDecimal *input, double *result)
  2113. {
  2114.     SPLIT64  tmp;
  2115.     double   dbl;
  2116.    
  2117.     if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
  2118.         return MONO_DECIMAL_INVALID_ARGUMENT;
  2119.    
  2120.     tmp.u.Lo = DECIMAL_LO32(*input);
  2121.     tmp.u.Hi = DECIMAL_MID32(*input);
  2122.    
  2123.     if ((int32_t)DECIMAL_MID32(*input) < 0)
  2124.         dbl = (ds2to64.dbl + (double)(int64_t)tmp.int64 +
  2125.                (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input)) ;
  2126.     else
  2127.         dbl = ((double)(int64_t)tmp.int64 +
  2128.                (double)DECIMAL_HI32(*input) * ds2to64.dbl) / fnDblPower10(DECIMAL_SCALE(*input));
  2129.    
  2130.     if (DECIMAL_SIGN(*input))
  2131.         dbl = -dbl;
  2132.    
  2133.     *result = dbl;
  2134.     return MONO_DECIMAL_OK;
  2135. }
  2136.  
  2137. // Returns: MONO_DECIMAL_OK, or MONO_DECIMAL_INVALID_ARGUMENT
  2138. static MonoDecimalStatus
  2139. MONO_VarR4FromDec(MonoDecimal *input, float *result)
  2140. {
  2141.     double   dbl;
  2142.    
  2143.     if (DECIMAL_SCALE(*input) > DECMAX || (DECIMAL_SIGN(*input) & ~DECIMAL_NEG) != 0)
  2144.         return MONO_DECIMAL_INVALID_ARGUMENT;
  2145.    
  2146.     // Can't overflow; no errors possible.
  2147.     //
  2148.     MONO_VarR8FromDec(input, &dbl);
  2149.     *result = (float)dbl;
  2150.     return MONO_DECIMAL_OK;
  2151. }
  2152.  
  2153. static void
  2154. DecShiftLeft(MonoDecimal* value)
  2155. {
  2156.     g_assert(value != NULL);
  2157.  
  2158.     unsigned int c0 = DECIMAL_LO32(*value) & 0x80000000? 1: 0;
  2159.     unsigned int c1 = DECIMAL_MID32(*value) & 0x80000000? 1: 0;
  2160.     DECIMAL_LO32(*value) <<= 1;
  2161.     DECIMAL_MID32(*value) = DECIMAL_MID32(*value) << 1 | c0;
  2162.     DECIMAL_HI32(*value) = DECIMAL_HI32(*value) << 1 | c1;
  2163. }
  2164.  
  2165. static int
  2166. D32AddCarry(uint32_t* value, uint32_t i)
  2167. {
  2168.     uint32_t v = *value;
  2169.     uint32_t sum = v + i;
  2170.     *value = sum;
  2171.     return sum < v || sum < i? 1: 0;
  2172. }
  2173.  
  2174. static void
  2175. DecAdd(MonoDecimal *value, MonoDecimal* d)
  2176. {
  2177.     g_assert(value != NULL && d != NULL);
  2178.  
  2179.     if (D32AddCarry(&DECIMAL_LO32(*value), DECIMAL_LO32(*d))) {
  2180.         if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
  2181.             D32AddCarry(&DECIMAL_HI32(*value), 1);
  2182.         }
  2183.     }
  2184.     if (D32AddCarry(&DECIMAL_MID32(*value), DECIMAL_MID32(*d))) {
  2185.         D32AddCarry(&DECIMAL_HI32(*value), 1);
  2186.     }
  2187.     D32AddCarry(&DECIMAL_HI32(*value), DECIMAL_HI32(*d));
  2188. }
  2189.  
  2190. static void
  2191. DecMul10(MonoDecimal* value)
  2192. {
  2193.     g_assert (value != NULL);
  2194.  
  2195.     MonoDecimal d = *value;
  2196.     DecShiftLeft(value);
  2197.     DecShiftLeft(value);
  2198.     DecAdd(value, &d);
  2199.     DecShiftLeft(value);
  2200. }
  2201.  
  2202. static void
  2203. DecAddInt32(MonoDecimal* value, unsigned int i)
  2204. {
  2205.     g_assert(value != NULL);
  2206.  
  2207.     if (D32AddCarry(&DECIMAL_LO32(*value), i)) {
  2208.         if (D32AddCarry(&DECIMAL_MID32(*value), 1)) {
  2209.             D32AddCarry(&DECIMAL_HI32(*value), 1);
  2210.         }
  2211.     }
  2212. }
  2213.  
  2214. MonoDecimalCompareResult
  2215. mono_decimal_compare (MonoDecimal *left, MonoDecimal *right)
  2216. {
  2217.     uint32_t   left_sign;
  2218.     uint32_t   right_sign;
  2219.  
  2220.     // First check signs and whether either are zero.  If both are
  2221.     // non-zero and of the same sign, just use subtraction to compare.
  2222.     //
  2223.     left_sign = left->v.v.Lo32 | left->v.v.Mid32 | left->Hi32;
  2224.     right_sign = right->v.v.Lo32 | right->v.v.Mid32 | right->Hi32;
  2225.     if (left_sign != 0)
  2226.         left_sign = (left->u.u.sign & DECIMAL_NEG) | 1;
  2227.  
  2228.     if (right_sign != 0)
  2229.         right_sign = (right->u.u.sign & DECIMAL_NEG) | 1;
  2230.  
  2231.     // left_sign & right_sign have values 1, 0, or 0x81 depending on if the left/right
  2232.     // operand is +, 0, or -.
  2233.     //
  2234.     if (left_sign == right_sign) {
  2235.         if (left_sign == 0)    // both are zero
  2236.             return MONO_DECIMAL_CMP_EQ; // return equal
  2237.  
  2238.         MonoDecimal result;
  2239.  
  2240.         DecAddSub(left, right, &result, DECIMAL_NEG);
  2241.         if (DECIMAL_LO64_GET(result) == 0 && result.Hi32 == 0)
  2242.             return MONO_DECIMAL_CMP_EQ;
  2243.         if (result.u.u.sign & DECIMAL_NEG)
  2244.             return MONO_DECIMAL_CMP_LT;
  2245.         return MONO_DECIMAL_CMP_GT;
  2246.     }
  2247.  
  2248.     //
  2249.     // Signs are different.  Use signed byte comparison
  2250.     //
  2251.     if ((signed char)left_sign > (signed char)right_sign)
  2252.         return MONO_DECIMAL_CMP_GT;
  2253.     return MONO_DECIMAL_CMP_LT;
  2254. }
  2255.  
  2256. void
  2257. mono_decimal_init_single (MonoDecimal *_this, float value)
  2258. {
  2259.     if (MONO_VarDecFromR4 (value, _this) == MONO_DECIMAL_OVERFLOW) {
  2260.         mono_set_pending_exception (mono_get_exception_overflow ());
  2261.         return;
  2262.     }
  2263.     _this->reserved = 0;
  2264. }
  2265.  
  2266. void
  2267. mono_decimal_init_double (MonoDecimal *_this, double value)
  2268. {
  2269.     if (MONO_VarDecFromR8 (value, _this) == MONO_DECIMAL_OVERFLOW) {
  2270.         mono_set_pending_exception (mono_get_exception_overflow ());
  2271.         return;
  2272.     }
  2273.     _this->reserved = 0;
  2274. }
  2275.  
  2276. void
  2277. mono_decimal_floor (MonoDecimal *d)
  2278. {
  2279.     MonoDecimal decRes;
  2280.  
  2281.     MONO_VarDecInt(d, &decRes);
  2282.    
  2283.     // copy decRes into d
  2284.     COPYDEC(*d, decRes);
  2285.     d->reserved = 0;
  2286.     FC_GC_POLL ();
  2287. }
  2288.  
  2289. int32_t
  2290. mono_decimal_get_hash_code (MonoDecimal *d)
  2291. {
  2292.     double dbl;
  2293.  
  2294.     if (MONO_VarR8FromDec(d, &dbl) != MONO_DECIMAL_OK)
  2295.         return 0;
  2296.    
  2297.     if (dbl == 0.0) {
  2298.         // Ensure 0 and -0 have the same hash code
  2299.         return 0;
  2300.     }
  2301.     // conversion to double is lossy and produces rounding errors so we mask off the lowest 4 bits
  2302.     //
  2303.     // For example these two numerically equal decimals with different internal representations produce
  2304.     // slightly different results when converted to double:
  2305.     //
  2306.     // decimal a = new decimal(new int[] { 0x76969696, 0x2fdd49fa, 0x409783ff, 0x00160000 });
  2307.     //                     => (decimal)1999021.176470588235294117647000000000 => (double)1999021.176470588
  2308.     // decimal b = new decimal(new int[] { 0x3f0f0f0f, 0x1e62edcc, 0x06758d33, 0x00150000 });
  2309.     //                     => (decimal)1999021.176470588235294117647000000000 => (double)1999021.1764705882
  2310.     //
  2311.     return ((((int *)&dbl)[0]) & 0xFFFFFFF0) ^ ((int *)&dbl)[1];
  2312.    
  2313. }
  2314.  
  2315. void
  2316. mono_decimal_multiply (MonoDecimal *d1, MonoDecimal *d2)
  2317. {
  2318.     MonoDecimal decRes;
  2319.  
  2320.     MonoDecimalStatus status = MONO_VarDecMul(d1, d2, &decRes);
  2321.     if (status != MONO_DECIMAL_OK) {
  2322.         mono_set_pending_exception (mono_get_exception_overflow ());
  2323.         return;
  2324.     }
  2325.  
  2326.     COPYDEC(*d1, decRes);
  2327.     d1->reserved = 0;
  2328.  
  2329.     FC_GC_POLL ();
  2330. }
  2331.  
  2332. void
  2333. mono_decimal_round (MonoDecimal *d, int32_t decimals)
  2334. {
  2335.     MonoDecimal decRes;
  2336.    
  2337.     // GC is only triggered for throwing, no need to protect result
  2338.     if (decimals < 0 || decimals > 28) {
  2339.         mono_set_pending_exception (mono_get_exception_argument_out_of_range ("d"));
  2340.         return;
  2341.     }
  2342.  
  2343.     MONO_VarDecRound(d, decimals, &decRes);
  2344.  
  2345.     // copy decRes into d
  2346.     COPYDEC(*d, decRes);
  2347.     d->reserved = 0;
  2348.  
  2349.     FC_GC_POLL();
  2350. }
  2351.  
  2352. void
  2353. mono_decimal_tocurrency (MonoDecimal *decimal)
  2354. {
  2355.     // TODO
  2356. }
  2357.  
  2358. double
  2359. mono_decimal_to_double (MonoDecimal d)
  2360. {
  2361.     double result = 0.0;
  2362.     // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
  2363.     MONO_VarR8FromDec(&d, &result);
  2364.     return result;
  2365. }
  2366.  
  2367. int32_t
  2368. mono_decimal_to_int32 (MonoDecimal d)
  2369. {
  2370.     MonoDecimal result;
  2371.    
  2372.     // The following can not return an error, it only returns INVALID_ARG if the decimals is < 0
  2373.     MONO_VarDecRound(&d, 0, &result);
  2374.    
  2375.     if (DECIMAL_SCALE(result) != 0) {
  2376.         d = result;
  2377.         MONO_VarDecFix (&d, &result);
  2378.     }
  2379.    
  2380.     if (DECIMAL_HI32(result) == 0 && DECIMAL_MID32(result) == 0) {
  2381.         int32_t i = DECIMAL_LO32(result);
  2382.         if ((int16_t)DECIMAL_SIGNSCALE(result) >= 0) {
  2383.             if (i >= 0)
  2384.                 return i;
  2385.         } else {
  2386.             i = -i;
  2387.             if (i <= 0)
  2388.                 return i;
  2389.         }
  2390.     }
  2391.    
  2392.     mono_set_pending_exception (mono_get_exception_overflow ());
  2393.     return 0;
  2394. }
  2395.  
  2396. float
  2397. mono_decimal_to_float (MonoDecimal d)
  2398. {
  2399.     float result = 0.0f;
  2400.     // Note: this can fail if the input is an invalid decimal, but for compatibility we should return 0
  2401.     MONO_VarR4FromDec(&d, &result);
  2402.     return result;
  2403. }
  2404.  
  2405. void
  2406. mono_decimal_truncate (MonoDecimal *d)
  2407. {
  2408.     MonoDecimal decRes;
  2409.  
  2410.     MONO_VarDecFix(d, &decRes);
  2411.  
  2412.     // copy decRes into d
  2413.     COPYDEC(*d, decRes);
  2414.     d->reserved = 0;
  2415.     FC_GC_POLL();
  2416. }
  2417.  
  2418. void
  2419. mono_decimal_addsub (MonoDecimal *left, MonoDecimal *right, uint8_t sign)
  2420. {
  2421.     MonoDecimal result, decTmp;
  2422.     MonoDecimal *pdecTmp, *leftOriginal;
  2423.     uint32_t    num[6], pwr;
  2424.     int         scale, hi_prod, cur;
  2425.     SPLIT64     sdlTmp;
  2426.    
  2427.     g_assert(sign == 0 || sign == DECIMAL_NEG);
  2428.  
  2429.     leftOriginal = left;
  2430.  
  2431.     sign ^= (DECIMAL_SIGN(*right) ^ DECIMAL_SIGN(*left)) & DECIMAL_NEG;
  2432.  
  2433.     if (DECIMAL_SCALE(*right) == DECIMAL_SCALE(*left)) {
  2434.         // Scale factors are equal, no alignment necessary.
  2435.         //
  2436.         DECIMAL_SIGNSCALE(result) = DECIMAL_SIGNSCALE(*left);
  2437.  
  2438.     AlignedAdd:
  2439.         if (sign) {
  2440.             // Signs differ - subtract
  2441.             //
  2442.             DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) - DECIMAL_LO64_GET(*right)));
  2443.             DECIMAL_HI32(result) = DECIMAL_HI32(*left) - DECIMAL_HI32(*right);
  2444.  
  2445.             // Propagate carry
  2446.             //
  2447.             if (DECIMAL_LO64_GET(result) > DECIMAL_LO64_GET(*left)) {
  2448.                 DECIMAL_HI32(result)--;
  2449.                 if (DECIMAL_HI32(result) >= DECIMAL_HI32(*left))
  2450.                     goto SignFlip;
  2451.             } else if (DECIMAL_HI32(result) > DECIMAL_HI32(*left)) {
  2452.                 // Got negative result.  Flip its sign.
  2453.                 //
  2454.             SignFlip:
  2455.                 DECIMAL_LO64_SET(result, -(int64_t)DECIMAL_LO64_GET(result));
  2456.                 DECIMAL_HI32(result) = ~DECIMAL_HI32(result);
  2457.                 if (DECIMAL_LO64_GET(result) == 0)
  2458.                     DECIMAL_HI32(result)++;
  2459.                 DECIMAL_SIGN(result) ^= DECIMAL_NEG;
  2460.             }
  2461.  
  2462.         } else {
  2463.             // Signs are the same - add
  2464.             //
  2465.             DECIMAL_LO64_SET(result, (DECIMAL_LO64_GET(*left) + DECIMAL_LO64_GET(*right)));
  2466.             DECIMAL_HI32(result) = DECIMAL_HI32(*left) + DECIMAL_HI32(*right);
  2467.  
  2468.             // Propagate carry
  2469.             //
  2470.             if (DECIMAL_LO64_GET(result) < DECIMAL_LO64_GET(*left)) {
  2471.                 DECIMAL_HI32(result)++;
  2472.                 if (DECIMAL_HI32(result) <= DECIMAL_HI32(*left))
  2473.                     goto AlignedScale;
  2474.             } else if (DECIMAL_HI32(result) < DECIMAL_HI32(*left)) {
  2475.             AlignedScale:
  2476.                 // The addition carried above 96 bits.  Divide the result by 10,
  2477.                 // dropping the scale factor.
  2478.                 //
  2479.                 if (DECIMAL_SCALE(result) == 0) {
  2480.                     mono_set_pending_exception (mono_get_exception_overflow ());
  2481.                     return;
  2482.                 }
  2483.                 DECIMAL_SCALE(result)--;
  2484.  
  2485.                 sdlTmp.u.Lo = DECIMAL_HI32(result);
  2486.                 sdlTmp.u.Hi = 1;
  2487.                 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
  2488.                 DECIMAL_HI32(result) = sdlTmp.u.Lo;
  2489.  
  2490.                 sdlTmp.u.Lo = DECIMAL_MID32(result);
  2491.                 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
  2492.                 DECIMAL_MID32(result) = sdlTmp.u.Lo;
  2493.  
  2494.                 sdlTmp.u.Lo = DECIMAL_LO32(result);
  2495.                 sdlTmp.int64 = DivMod64by32(sdlTmp.int64, 10);
  2496.                 DECIMAL_LO32(result) = sdlTmp.u.Lo;
  2497.  
  2498.                 // See if we need to round up.
  2499.                 //
  2500.                 if (sdlTmp.u.Hi >= 5 && (sdlTmp.u.Hi > 5 || (DECIMAL_LO32(result) & 1))) {
  2501.                     DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(result)+1);
  2502.                     if (DECIMAL_LO64_GET(result) == 0)
  2503.                         DECIMAL_HI32(result)++;
  2504.                 }
  2505.             }
  2506.         }
  2507.     } else {
  2508.         // Scale factors are not equal.  Assume that a larger scale
  2509.         // factor (more decimal places) is likely to mean that number
  2510.         // is smaller.  Start by guessing that the right operand has
  2511.         // the larger scale factor.  The result will have the larger
  2512.         // scale factor.
  2513.         //
  2514.         DECIMAL_SCALE(result) = DECIMAL_SCALE(*right);  // scale factor of "smaller"
  2515.         DECIMAL_SIGN(result) = DECIMAL_SIGN(*left);    // but sign of "larger"
  2516.         scale = DECIMAL_SCALE(result)- DECIMAL_SCALE(*left);
  2517.  
  2518.         if (scale < 0) {
  2519.             // Guessed scale factor wrong. Swap operands.
  2520.             //
  2521.             scale = -scale;
  2522.             DECIMAL_SCALE(result) = DECIMAL_SCALE(*left);
  2523.             DECIMAL_SIGN(result) ^= sign;
  2524.             pdecTmp = right;
  2525.             right = left;
  2526.             left = pdecTmp;
  2527.         }
  2528.  
  2529.         // *left will need to be multiplied by 10^scale so
  2530.         // it will have the same scale as *right.  We could be
  2531.         // extending it to up to 192 bits of precision.
  2532.         //
  2533.         if (scale <= POWER10_MAX) {
  2534.             // Scaling won't make it larger than 4 uint32_ts
  2535.             //
  2536.             pwr = power10[scale];
  2537.             DECIMAL_LO64_SET(decTmp, UInt32x32To64(DECIMAL_LO32(*left), pwr));
  2538.             sdlTmp.int64 = UInt32x32To64(DECIMAL_MID32(*left), pwr);
  2539.             sdlTmp.int64 += DECIMAL_MID32(decTmp);
  2540.             DECIMAL_MID32(decTmp) = sdlTmp.u.Lo;
  2541.             DECIMAL_HI32(decTmp) = sdlTmp.u.Hi;
  2542.             sdlTmp.int64 = UInt32x32To64(DECIMAL_HI32(*left), pwr);
  2543.             sdlTmp.int64 += DECIMAL_HI32(decTmp);
  2544.             if (sdlTmp.u.Hi == 0) {
  2545.                 // Result fits in 96 bits.  Use standard aligned add.
  2546.                 //
  2547.                 DECIMAL_HI32(decTmp) = sdlTmp.u.Lo;
  2548.                 left = &decTmp;
  2549.                 goto AlignedAdd;
  2550.             }
  2551.             num[0] = DECIMAL_LO32(decTmp);
  2552.             num[1] = DECIMAL_MID32(decTmp);
  2553.             num[2] = sdlTmp.u.Lo;
  2554.             num[3] = sdlTmp.u.Hi;
  2555.             hi_prod = 3;
  2556.         } else {
  2557.             // Have to scale by a bunch.  Move the number to a buffer
  2558.             // where it has room to grow as it's scaled.
  2559.             //
  2560.             num[0] = DECIMAL_LO32(*left);
  2561.             num[1] = DECIMAL_MID32(*left);
  2562.             num[2] = DECIMAL_HI32(*left);
  2563.             hi_prod = 2;
  2564.  
  2565.             // Scan for zeros in the upper words.
  2566.             //
  2567.             if (num[2] == 0) {
  2568.                 hi_prod = 1;
  2569.                 if (num[1] == 0) {
  2570.                     hi_prod = 0;
  2571.                     if (num[0] == 0) {
  2572.                         // Left arg is zero, return right.
  2573.                         //
  2574.                         DECIMAL_LO64_SET(result, DECIMAL_LO64_GET(*right));
  2575.                         DECIMAL_HI32(result) = DECIMAL_HI32(*right);
  2576.                         DECIMAL_SIGN(result) ^= sign;
  2577.                         goto RetDec;
  2578.                     }
  2579.                 }
  2580.             }
  2581.  
  2582.             // Scaling loop, up to 10^9 at a time.  hi_prod stays updated
  2583.             // with index of highest non-zero uint32_t.
  2584.             //
  2585.             for (; scale > 0; scale -= POWER10_MAX) {
  2586.                 if (scale > POWER10_MAX)
  2587.                     pwr = ten_to_nine;
  2588.                 else
  2589.                     pwr = power10[scale];
  2590.  
  2591.                 sdlTmp.u.Hi = 0;
  2592.                 for (cur = 0; cur <= hi_prod; cur++) {
  2593.                     sdlTmp.int64 = UInt32x32To64(num[cur], pwr) + sdlTmp.u.Hi;
  2594.                     num[cur] = sdlTmp.u.Lo;
  2595.                 }
  2596.  
  2597.                 if (sdlTmp.u.Hi != 0)
  2598.                     // We're extending the result by another uint32_t.
  2599.                     num[++hi_prod] = sdlTmp.u.Hi;
  2600.             }
  2601.         }
  2602.  
  2603.         // Scaling complete, do the add.  Could be subtract if signs differ.
  2604.         //
  2605.         sdlTmp.u.Lo = num[0];
  2606.         sdlTmp.u.Hi = num[1];
  2607.  
  2608.         if (sign) {
  2609.             // Signs differ, subtract.
  2610.             //
  2611.             DECIMAL_LO64_SET(result, (sdlTmp.int64 - DECIMAL_LO64_GET(*right)));
  2612.             DECIMAL_HI32(result) = num[2] - DECIMAL_HI32(*right);
  2613.  
  2614.             // Propagate carry
  2615.             //
  2616.             if (DECIMAL_LO64_GET(result) > sdlTmp.int64) {
  2617.                 DECIMAL_HI32(result)--;
  2618.                 if (DECIMAL_HI32(result) >= num[2])
  2619.                     goto LongSub;
  2620.             } else if (DECIMAL_HI32(result) > num[2]) {
  2621.             LongSub:
  2622.                 // If num has more than 96 bits of precision, then we need to
  2623.                 // carry the subtraction into the higher bits.  If it doesn't,
  2624.                 // then we subtracted in the wrong order and have to flip the
  2625.                 // sign of the result.
  2626.                 //
  2627.                 if (hi_prod <= 2)
  2628.                     goto SignFlip;
  2629.  
  2630.                 cur = 3;
  2631.                 while(num[cur++]-- == 0);
  2632.                 if (num[hi_prod] == 0)
  2633.                     hi_prod--;
  2634.             }
  2635.         } else {
  2636.             // Signs the same, add.
  2637.             //
  2638.             DECIMAL_LO64_SET(result, (sdlTmp.int64 + DECIMAL_LO64_GET(*right)));
  2639.             DECIMAL_HI32(result) = num[2] + DECIMAL_HI32(*right);
  2640.  
  2641.             // Propagate carry
  2642.             //
  2643.             if (DECIMAL_LO64_GET(result) < sdlTmp.int64) {
  2644.                 DECIMAL_HI32(result)++;
  2645.                 if (DECIMAL_HI32(result) <= num[2])
  2646.                     goto LongAdd;
  2647.             } else if (DECIMAL_HI32(result) < num[2]) {
  2648.             LongAdd:
  2649.                 // Had a carry above 96 bits.
  2650.                 //
  2651.                 cur = 3;
  2652.                 do {
  2653.                     if (hi_prod < cur) {
  2654.                         num[cur] = 1;
  2655.                         hi_prod = cur;
  2656.                         break;
  2657.                     }
  2658.                 }while (++num[cur++] == 0);
  2659.             }
  2660.         }
  2661.  
  2662.         if (hi_prod > 2) {
  2663.             num[0] = DECIMAL_LO32(result);
  2664.             num[1] = DECIMAL_MID32(result);
  2665.             num[2] = DECIMAL_HI32(result);
  2666.             DECIMAL_SCALE(result) = (uint8_t)ScaleResult(num, hi_prod, DECIMAL_SCALE(result));
  2667.             if (DECIMAL_SCALE(result) == (uint8_t)-1) {
  2668.                 mono_set_pending_exception (mono_get_exception_overflow ());
  2669.                 return;
  2670.             }
  2671.  
  2672.             DECIMAL_LO32(result) = num[0];
  2673.             DECIMAL_MID32(result) = num[1];
  2674.             DECIMAL_HI32(result) = num[2];
  2675.         }
  2676.     }
  2677.  
  2678. RetDec:
  2679.     left = leftOriginal;
  2680.     COPYDEC(*left, result);
  2681.     left->reserved = 0;
  2682. }
  2683.  
  2684. void
  2685. mono_decimal_divide (MonoDecimal *left, MonoDecimal *right)
  2686. {
  2687.     uint32_t quo[3], quo_save[3],rem[4], divisor[3];
  2688.     uint32_t pwr, tmp, tmp1;
  2689.     SPLIT64  sdlTmp, sdlDivisor;
  2690.     int      scale, cur_scale;
  2691.     gboolean unscale;
  2692.  
  2693.     scale = DECIMAL_SCALE(*left) - DECIMAL_SCALE(*right);
  2694.     unscale = FALSE;
  2695.     divisor[0] = DECIMAL_LO32(*right);
  2696.     divisor[1] = DECIMAL_MID32(*right);
  2697.     divisor[2] = DECIMAL_HI32(*right);
  2698.  
  2699.     if (divisor[1] == 0 && divisor[2] == 0) {
  2700.         // Divisor is only 32 bits.  Easy divide.
  2701.         //
  2702.         if (divisor[0] == 0) {
  2703.             mono_set_pending_exception (mono_get_exception_divide_by_zero ());
  2704.             return;
  2705.         }
  2706.  
  2707.         quo[0] = DECIMAL_LO32(*left);
  2708.         quo[1] = DECIMAL_MID32(*left);
  2709.         quo[2] = DECIMAL_HI32(*left);
  2710.         rem[0] = Div96By32(quo, divisor[0]);
  2711.  
  2712.         for (;;) {
  2713.             if (rem[0] == 0) {
  2714.                 if (scale < 0) {
  2715.                     cur_scale = min(9, -scale);
  2716.                     goto HaveScale;
  2717.                 }
  2718.                 break;
  2719.             }
  2720.             // We need to unscale if and only if we have a non-zero remainder
  2721.             unscale = TRUE;
  2722.  
  2723.             // We have computed a quotient based on the natural scale
  2724.             // ( <dividend scale> - <divisor scale> ).  We have a non-zero
  2725.             // remainder, so now we should increase the scale if possible to
  2726.             // include more quotient bits.
  2727.             //
  2728.             // If it doesn't cause overflow, we'll loop scaling by 10^9 and
  2729.             // computing more quotient bits as long as the remainder stays
  2730.             // non-zero.  If scaling by that much would cause overflow, we'll
  2731.             // drop out of the loop and scale by as much as we can.
  2732.             //
  2733.             // Scaling by 10^9 will overflow if quo[2].quo[1] >= 2^32 / 10^9
  2734.             // = 4.294 967 296.  So the upper limit is quo[2] == 4 and
  2735.             // quo[1] == 0.294 967 296 * 2^32 = 1,266,874,889.7+.  Since
  2736.             // quotient bits in quo[0] could be all 1's, then 1,266,874,888
  2737.             // is the largest value in quo[1] (when quo[2] == 4) that is
  2738.             // assured not to overflow.
  2739.             //
  2740.             cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
  2741.             if (cur_scale == 0) {
  2742.                 // No more scaling to be done, but remainder is non-zero.
  2743.                 // Round quotient.
  2744.                 //
  2745.                 tmp = rem[0] << 1;
  2746.                 if (tmp < rem[0] || (tmp >= divisor[0] &&
  2747.                                (tmp > divisor[0] || (quo[0] & 1)))) {
  2748.                 RoundUp:
  2749.                     if (!Add32To96(quo, 1)) {
  2750.                         if (scale == 0) {
  2751.                             mono_set_pending_exception (mono_get_exception_overflow ());
  2752.                             return;
  2753.                         }
  2754.                         scale--;
  2755.                         OverflowUnscale(quo, TRUE);
  2756.                         break;
  2757.                     }      
  2758.                 }
  2759.                 break;
  2760.             }
  2761.  
  2762.             if (cur_scale < 0) {
  2763.                 mono_set_pending_exception (mono_get_exception_overflow ());
  2764.                 return;
  2765.             }
  2766.  
  2767.         HaveScale:
  2768.             pwr = power10[cur_scale];
  2769.             scale += cur_scale;
  2770.  
  2771.             if (IncreaseScale(quo, pwr) != 0) {
  2772.                 mono_set_pending_exception (mono_get_exception_overflow ());
  2773.                 return;
  2774.             }
  2775.  
  2776.             sdlTmp.int64 = DivMod64by32(UInt32x32To64(rem[0], pwr), divisor[0]);
  2777.             rem[0] = sdlTmp.u.Hi;
  2778.  
  2779.             if (!Add32To96(quo, sdlTmp.u.Lo)) {
  2780.                 if (scale == 0) {
  2781.                     mono_set_pending_exception (mono_get_exception_overflow ());
  2782.                     return;
  2783.                 }
  2784.                 scale--;
  2785.                 OverflowUnscale(quo, (rem[0] != 0));
  2786.                 break;
  2787.             }
  2788.         } // for (;;)
  2789.     } else {
  2790.         // Divisor has bits set in the upper 64 bits.
  2791.         //
  2792.         // Divisor must be fully normalized (shifted so bit 31 of the most
  2793.         // significant uint32_t is 1).  Locate the MSB so we know how much to
  2794.         // normalize by.  The dividend will be shifted by the same amount so
  2795.         // the quotient is not changed.
  2796.         //
  2797.         if (divisor[2] == 0)
  2798.             tmp = divisor[1];
  2799.         else
  2800.             tmp = divisor[2];
  2801.  
  2802.         cur_scale = 0;
  2803.         if (!(tmp & 0xFFFF0000)) {
  2804.             cur_scale += 16;
  2805.             tmp <<= 16;
  2806.         }
  2807.         if (!(tmp & 0xFF000000)) {
  2808.             cur_scale += 8;
  2809.             tmp <<= 8;
  2810.         }
  2811.         if (!(tmp & 0xF0000000)) {
  2812.             cur_scale += 4;
  2813.             tmp <<= 4;
  2814.         }
  2815.         if (!(tmp & 0xC0000000)) {
  2816.             cur_scale += 2;
  2817.             tmp <<= 2;
  2818.         }
  2819.         if (!(tmp & 0x80000000)) {
  2820.             cur_scale++;
  2821.             tmp <<= 1;
  2822.         }
  2823.    
  2824.         // Shift both dividend and divisor left by cur_scale.
  2825.         //
  2826.         sdlTmp.int64 = DECIMAL_LO64_GET(*left) << cur_scale;
  2827.         rem[0] = sdlTmp.u.Lo;
  2828.         rem[1] = sdlTmp.u.Hi;
  2829.         sdlTmp.u.Lo = DECIMAL_MID32(*left);
  2830.         sdlTmp.u.Hi = DECIMAL_HI32(*left);
  2831.         sdlTmp.int64 <<= cur_scale;
  2832.         rem[2] = sdlTmp.u.Hi;
  2833.         rem[3] = (DECIMAL_HI32(*left) >> (31 - cur_scale)) >> 1;
  2834.  
  2835.         sdlDivisor.u.Lo = divisor[0];
  2836.         sdlDivisor.u.Hi = divisor[1];
  2837.         sdlDivisor.int64 <<= cur_scale;
  2838.  
  2839.         if (divisor[2] == 0) {
  2840.             // Have a 64-bit divisor in sdlDivisor.  The remainder
  2841.             // (currently 96 bits spread over 4 uint32_ts) will be < divisor.
  2842.             //
  2843.             sdlTmp.u.Lo = rem[2];
  2844.             sdlTmp.u.Hi = rem[3];
  2845.  
  2846.             quo[2] = 0;
  2847.             quo[1] = Div96By64(&rem[1], sdlDivisor);
  2848.             quo[0] = Div96By64(rem, sdlDivisor);
  2849.  
  2850.             for (;;) {
  2851.                 if ((rem[0] | rem[1]) == 0) {
  2852.                     if (scale < 0) {
  2853.                         cur_scale = min(9, -scale);
  2854.                         goto HaveScale64;
  2855.                     }
  2856.                     break;
  2857.                 }
  2858.  
  2859.                 // We need to unscale if and only if we have a non-zero remainder
  2860.                 unscale = TRUE;
  2861.  
  2862.                 // Remainder is non-zero.  Scale up quotient and remainder by
  2863.                 // powers of 10 so we can compute more significant bits.
  2864.                 //
  2865.                 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
  2866.                 if (cur_scale == 0) {
  2867.                     // No more scaling to be done, but remainder is non-zero.
  2868.                     // Round quotient.
  2869.                     //
  2870.                     sdlTmp.u.Lo = rem[0];
  2871.                     sdlTmp.u.Hi = rem[1];
  2872.                     if (sdlTmp.u.Hi >= 0x80000000 || (sdlTmp.int64 <<= 1) > sdlDivisor.int64 ||
  2873.                         (sdlTmp.int64 == sdlDivisor.int64 && (quo[0] & 1)))
  2874.                         goto RoundUp;
  2875.                     break;
  2876.                 }
  2877.  
  2878.                 if (cur_scale < 0) {
  2879.                     mono_set_pending_exception (mono_get_exception_overflow ());
  2880.                     return;
  2881.                 }
  2882.  
  2883.             HaveScale64:
  2884.                 pwr = power10[cur_scale];
  2885.                 scale += cur_scale;
  2886.  
  2887.                 if (IncreaseScale(quo, pwr) != 0) {
  2888.                     mono_set_pending_exception (mono_get_exception_overflow ());
  2889.                     return;
  2890.                 }
  2891.                
  2892.                 rem[2] = 0;  // rem is 64 bits, IncreaseScale uses 96
  2893.                 IncreaseScale(rem, pwr);
  2894.                 tmp = Div96By64(rem, sdlDivisor);
  2895.                 if (!Add32To96(quo, tmp)) {
  2896.                     if (scale == 0) {
  2897.                         mono_set_pending_exception (mono_get_exception_overflow ());
  2898.                         return;
  2899.                     }
  2900.                     scale--;
  2901.                     OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0));
  2902.                     break;
  2903.                 }      
  2904.  
  2905.             } // for (;;)
  2906.         } else {
  2907.             // Have a 96-bit divisor in divisor[].
  2908.             //
  2909.             // Start by finishing the shift left by cur_scale.
  2910.             //
  2911.             sdlTmp.u.Lo = divisor[1];
  2912.             sdlTmp.u.Hi = divisor[2];
  2913.             sdlTmp.int64 <<= cur_scale;
  2914.             divisor[0] = sdlDivisor.u.Lo;
  2915.             divisor[1] = sdlDivisor.u.Hi;
  2916.             divisor[2] = sdlTmp.u.Hi;
  2917.  
  2918.             // The remainder (currently 96 bits spread over 4 uint32_ts)
  2919.             // will be < divisor.
  2920.             //
  2921.             quo[2] = 0;
  2922.             quo[1] = 0;
  2923.             quo[0] = Div128By96(rem, divisor);
  2924.  
  2925.             for (;;) {
  2926.                 if ((rem[0] | rem[1] | rem[2]) == 0) {
  2927.                     if (scale < 0) {
  2928.                         cur_scale = min(9, -scale);
  2929.                         goto HaveScale96;
  2930.                     }
  2931.                     break;
  2932.                 }
  2933.  
  2934.                 // We need to unscale if and only if we have a non-zero remainder
  2935.                 unscale = TRUE;
  2936.  
  2937.                 // Remainder is non-zero.  Scale up quotient and remainder by
  2938.                 // powers of 10 so we can compute more significant bits.
  2939.                 //
  2940.                 cur_scale = SearchScale(quo[2], quo[1], quo[0], scale);
  2941.                 if (cur_scale == 0) {
  2942.                     // No more scaling to be done, but remainder is non-zero.
  2943.                     // Round quotient.
  2944.                     //
  2945.                     if (rem[2] >= 0x80000000)
  2946.                         goto RoundUp;
  2947.  
  2948.                     tmp = rem[0] > 0x80000000;
  2949.                     tmp1 = rem[1] > 0x80000000;
  2950.                     rem[0] <<= 1;
  2951.                     rem[1] = (rem[1] << 1) + tmp;
  2952.                     rem[2] = (rem[2] << 1) + tmp1;
  2953.  
  2954.                     if (rem[2] > divisor[2] || (rem[2] == divisor[2] && (rem[1] > divisor[1] || rem[1] == (divisor[1] && (rem[0] > divisor[0] || (rem[0] == divisor[0] && (quo[0] & 1)))))))
  2955.                         goto RoundUp;
  2956.                     break;
  2957.                 }
  2958.  
  2959.                 if (cur_scale < 0) {
  2960.                     mono_set_pending_exception (mono_get_exception_overflow ());
  2961.                     return;
  2962.                 }
  2963.                
  2964.             HaveScale96:
  2965.                 pwr = power10[cur_scale];
  2966.                 scale += cur_scale;
  2967.  
  2968.                 if (IncreaseScale(quo, pwr) != 0) {
  2969.                     mono_set_pending_exception (mono_get_exception_overflow ());
  2970.                     return;
  2971.                 }
  2972.  
  2973.                 rem[3] = IncreaseScale(rem, pwr);
  2974.                 tmp = Div128By96(rem, divisor);
  2975.                 if (!Add32To96(quo, tmp)) {
  2976.                     if (scale == 0) {
  2977.                         mono_set_pending_exception (mono_get_exception_overflow ());
  2978.                         return;
  2979.                     }
  2980.                    
  2981.                     scale--;
  2982.                     OverflowUnscale(quo, (rem[0] != 0 || rem[1] != 0 || rem[2] != 0 || rem[3] != 0));
  2983.                     break;
  2984.                 }      
  2985.  
  2986.             } // for (;;)
  2987.         }
  2988.     }
  2989.  
  2990.     // We need to unscale if and only if we have a non-zero remainder
  2991.     if (unscale) {
  2992.         // Try extracting any extra powers of 10 we may have
  2993.         // added.  We do this by trying to divide out 10^8, 10^4, 10^2, and 10^1.
  2994.         // If a division by one of these powers returns a zero remainder, then
  2995.         // we keep the quotient.  If the remainder is not zero, then we restore
  2996.         // the previous value.
  2997.         //
  2998.         // Since 10 = 2 * 5, there must be a factor of 2 for every power of 10
  2999.         // we can extract.  We use this as a quick test on whether to try a
  3000.         // given power.
  3001.         //
  3002.         while ((quo[0] & 0xFF) == 0 && scale >= 8) {
  3003.             quo_save[0] = quo[0];
  3004.             quo_save[1] = quo[1];
  3005.             quo_save[2] = quo[2];
  3006.  
  3007.             if (Div96By32(quo_save, 100000000) == 0) {
  3008.                 quo[0] = quo_save[0];
  3009.                 quo[1] = quo_save[1];
  3010.                 quo[2] = quo_save[2];
  3011.                 scale -= 8;
  3012.             } else
  3013.                 break;
  3014.         }
  3015.  
  3016.         if ((quo[0] & 0xF) == 0 && scale >= 4) {
  3017.             quo_save[0] = quo[0];
  3018.             quo_save[1] = quo[1];
  3019.             quo_save[2] = quo[2];
  3020.  
  3021.             if (Div96By32(quo_save, 10000) == 0) {
  3022.                 quo[0] = quo_save[0];
  3023.                 quo[1] = quo_save[1];
  3024.                 quo[2] = quo_save[2];
  3025.                 scale -= 4;
  3026.             }
  3027.         }
  3028.  
  3029.         if ((quo[0] & 3) == 0 && scale >= 2) {
  3030.             quo_save[0] = quo[0];
  3031.             quo_save[1] = quo[1];
  3032.             quo_save[2] = quo[2];
  3033.  
  3034.             if (Div96By32(quo_save, 100) == 0) {
  3035.                 quo[0] = quo_save[0];
  3036.                 quo[1] = quo_save[1];
  3037.                 quo[2] = quo_save[2];
  3038.                 scale -= 2;
  3039.             }
  3040.         }
  3041.  
  3042.         if ((quo[0] & 1) == 0 && scale >= 1) {
  3043.             quo_save[0] = quo[0];
  3044.             quo_save[1] = quo[1];
  3045.             quo_save[2] = quo[2];
  3046.  
  3047.             if (Div96By32(quo_save, 10) == 0) {
  3048.                 quo[0] = quo_save[0];
  3049.                 quo[1] = quo_save[1];
  3050.                 quo[2] = quo_save[2];
  3051.                 scale -= 1;
  3052.             }
  3053.         }
  3054.     }
  3055.  
  3056.     DECIMAL_SIGN(*left) = DECIMAL_SIGN(*left) ^ DECIMAL_SIGN(*right);
  3057.     DECIMAL_HI32(*left) = quo[2];
  3058.     DECIMAL_MID32(*left) = quo[1];
  3059.     DECIMAL_LO32(*left) = quo[0];
  3060.     DECIMAL_SCALE(*left) = (uint8_t)scale;
  3061.     left->reserved = 0;
  3062.  
  3063. }
  3064.  
  3065. #define DECIMAL_PRECISION 29
  3066. #define NUMBER_MAXDIGITS 50
  3067. typedef struct  {
  3068.     int32_t precision;
  3069.     int32_t scale;
  3070.     int32_t sign;
  3071.     uint16_t digits[NUMBER_MAXDIGITS + 1];
  3072.     uint16_t* allDigits;
  3073. } CLRNumber;
  3074.  
  3075. int
  3076. mono_decimal_from_number (void *from, MonoDecimal *target)
  3077. {
  3078.     CLRNumber *number = (CLRNumber *) from;
  3079.     g_assert(number != NULL);
  3080.     g_assert(target != NULL);
  3081.  
  3082.     MonoDecimal d;
  3083.     d.reserved = 0;
  3084.     DECIMAL_SIGNSCALE(d) = 0;
  3085.     DECIMAL_HI32(d) = 0;
  3086.     DECIMAL_LO32(d) = 0;
  3087.     DECIMAL_MID32(d) = 0;
  3088.     uint16_t* p = number->digits;
  3089.     g_assert(p != NULL);
  3090.     int e = number->scale;
  3091.     if (!*p) {
  3092.         // To avoid risking an app-compat issue with pre 4.5 (where some app was illegally using Reflection to examine the internal scale bits), we'll only force
  3093.         // the scale to 0 if the scale was previously positive
  3094.         if (e > 0) {
  3095.             e = 0;
  3096.         }
  3097.     } else {
  3098.         if (e > DECIMAL_PRECISION) return 0;
  3099.         while ((e > 0 || (*p && e > -28)) && (DECIMAL_HI32(d) < 0x19999999 || (DECIMAL_HI32(d) == 0x19999999 && (DECIMAL_MID32(d) < 0x99999999 || (DECIMAL_MID32(d) == 0x99999999 && (DECIMAL_LO32(d) < 0x99999999 || (DECIMAL_LO32(d) == 0x99999999 && *p <= '5'))))))) {
  3100.             DecMul10(&d);
  3101.             if (*p)
  3102.                 DecAddInt32(&d, *p++ - '0');
  3103.             e--;
  3104.         }
  3105.         if (*p++ >= '5') {
  3106.             gboolean round = TRUE;
  3107.             if (*(p-1) == '5' && *(p-2) % 2 == 0) { // Check if previous digit is even, only if the when we are unsure whether hows to do Banker's rounding
  3108.                 // For digits > 5 we will be roundinp up anyway.
  3109.                 int count = 20; // Look at the next 20 digits to check to round
  3110.                 while (*p == '0' && count != 0) {
  3111.                     p++;
  3112.                     count--;
  3113.                 }
  3114.                 if (*p == '\0' || count == 0)
  3115.                     round = FALSE;// Do nothing
  3116.             }
  3117.            
  3118.             if (round) {
  3119.                 DecAddInt32(&d, 1);
  3120.                 if ((DECIMAL_HI32(d) | DECIMAL_MID32(d) | DECIMAL_LO32(d)) == 0) {
  3121.                     DECIMAL_HI32(d) = 0x19999999;
  3122.                     DECIMAL_MID32(d) = 0x99999999;
  3123.                     DECIMAL_LO32(d) = 0x9999999A;
  3124.                     e++;
  3125.                 }
  3126.             }
  3127.         }
  3128.     }
  3129.     if (e > 0)
  3130.         return 0;
  3131.     if (e <= -DECIMAL_PRECISION) {
  3132.         // Parsing a large scale zero can give you more precision than fits in the decimal.
  3133.         // This should only happen for actual zeros or very small numbers that round to zero.
  3134.         DECIMAL_SIGNSCALE(d) = 0;
  3135.         DECIMAL_HI32(d) = 0;
  3136.         DECIMAL_LO32(d) = 0;
  3137.         DECIMAL_MID32(d) = 0;
  3138.         DECIMAL_SCALE(d) = (DECIMAL_PRECISION - 1);
  3139.     } else {
  3140.         DECIMAL_SCALE(d) = (uint8_t)(-e);
  3141.     }
  3142.    
  3143.     DECIMAL_SIGN(d) = number->sign? DECIMAL_NEG: 0;
  3144.     *target = d;
  3145.     return 1;
  3146. }
  3147.  
  3148.  
  3149. #endif
  3150.  
Advertisement
Add Comment
Please, Sign In to add comment