Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* Copyright (C) 2007-2015 Free Software Foundation, Inc.
  2.  
  3. This file is part of GCC.
  4.  
  5. GCC is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free
  7. Software Foundation; either version 3, or (at your option) any later
  8. version.
  9.  
  10. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13. for more details.
  14.  
  15. Under Section 7 of GPL version 3, you are granted additional
  16. permissions described in the GCC Runtime Library Exception, version
  17. 3.1, as published by the Free Software Foundation.
  18.  
  19. You should have received a copy of the GNU General Public License and
  20. a copy of the GCC Runtime Library Exception along with this program;
  21. see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  22. <http://www.gnu.org/licenses/>.  */
  23.  
  24. #include "bid_internal.h"
  25.  
  26. #if DECIMAL_CALL_BY_REFERENCE
  27. void
  28. bid64dq_mul (UINT64 * pres, UINT64 * px, UINT128 * py
  29.              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  30.              _EXC_INFO_PARAM) {
  31.   UINT64 x = *px;
  32. #if !DECIMAL_GLOBAL_ROUNDING
  33.   unsigned int rnd_mode = *prnd_mode;
  34. #endif
  35. #else
  36. UINT64
  37. bid64dq_mul (UINT64 x, UINT128 y
  38.              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  39.              _EXC_INFO_PARAM) {
  40. #endif
  41.   UINT64 res = 0xbaddbaddbaddbaddull;
  42.   UINT128 x1;
  43.  
  44. #if DECIMAL_CALL_BY_REFERENCE
  45.   bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  46.   bid64qq_mul (&res, &x1, py
  47.                _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  48.                _EXC_INFO_ARG);
  49. #else
  50.   x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  51.   res = bid64qq_mul (x1, y
  52.                      _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  53.                      _EXC_INFO_ARG);
  54. #endif
  55.   BID_RETURN (res);
  56. }
  57.  
  58.  
  59. #if DECIMAL_CALL_BY_REFERENCE
  60. void
  61. bid64qd_mul (UINT64 * pres, UINT128 * px, UINT64 * py
  62.              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  63.              _EXC_INFO_PARAM) {
  64.   UINT64 y = *py;
  65. #if !DECIMAL_GLOBAL_ROUNDING
  66.   unsigned int rnd_mode = *prnd_mode;
  67. #endif
  68. #else
  69. UINT64
  70. bid64qd_mul (UINT128 x, UINT64 y
  71.              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  72.              _EXC_INFO_PARAM) {
  73. #endif
  74.   UINT64 res = 0xbaddbaddbaddbaddull;
  75.   UINT128 y1;
  76.  
  77. #if DECIMAL_CALL_BY_REFERENCE
  78.   bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  79.   bid64qq_mul (&res, px, &y1
  80.                _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  81.                _EXC_INFO_ARG);
  82. #else
  83.   y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  84.   res = bid64qq_mul (x, y1
  85.                      _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  86.                      _EXC_INFO_ARG);
  87. #endif
  88.   BID_RETURN (res);
  89. }
  90.  
  91.  
  92. #if DECIMAL_CALL_BY_REFERENCE
  93. void
  94. bid64qq_mul (UINT64 * pres, UINT128 * px, UINT128 * py
  95.              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  96.              _EXC_INFO_PARAM) {
  97.   UINT128 x = *px, y = *py;
  98. #if !DECIMAL_GLOBAL_ROUNDING
  99.   unsigned int rnd_mode = *prnd_mode;
  100. #endif
  101. #else
  102. UINT64
  103. bid64qq_mul (UINT128 x, UINT128 y
  104.              _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  105.              _EXC_INFO_PARAM) {
  106. #endif
  107.  
  108.   UINT128 z = { {0x0000000000000000ull, 0x5ffe000000000000ull}
  109.   };
  110.   UINT64 res = 0xbaddbaddbaddbaddull;
  111.   UINT64 x_sign, y_sign, p_sign;
  112.   UINT64 x_exp, y_exp, p_exp;
  113.   int true_p_exp;
  114.   UINT128 C1, C2;
  115.  
  116.   BID_SWAP128 (z);
  117.   // skip cases where at least one operand is NaN or infinity
  118.   if (!(((x.w[HIGH_128W] & MASK_NAN) == MASK_NAN) ||
  119.         ((y.w[HIGH_128W] & MASK_NAN) == MASK_NAN) ||
  120.         ((x.w[HIGH_128W] & MASK_ANY_INF) == MASK_INF) ||
  121.         ((y.w[HIGH_128W] & MASK_ANY_INF) == MASK_INF))) {
  122.     // x, y are 0 or f but not inf or NaN => unpack the arguments and check
  123.     // for non-canonical values
  124.  
  125.     x_sign = x.w[HIGH_128W] & MASK_SIGN;        // 0 for positive, MASK_SIGN for negative
  126.     C1.w[1] = x.w[HIGH_128W] & MASK_COEFF;
  127.     C1.w[0] = x.w[LOW_128W];
  128.     // check for non-canonical values - treated as zero
  129.     if ((x.w[HIGH_128W] & 0x6000000000000000ull) ==
  130.         0x6000000000000000ull) {
  131.       // G0_G1=11 => non-canonical
  132.       x_exp = (x.w[HIGH_128W] << 2) & MASK_EXP; // biased and shifted left 49 bits
  133.       C1.w[1] = 0;      // significand high
  134.       C1.w[0] = 0;      // significand low
  135.     } else {    // G0_G1 != 11
  136.       x_exp = x.w[HIGH_128W] & MASK_EXP;        // biased and shifted left 49 bits
  137.       if (C1.w[1] > 0x0001ed09bead87c0ull ||
  138.           (C1.w[1] == 0x0001ed09bead87c0ull &&
  139.            C1.w[0] > 0x378d8e63ffffffffull)) {
  140.         // x is non-canonical if coefficient is larger than 10^34 -1
  141.         C1.w[1] = 0;
  142.         C1.w[0] = 0;
  143.       } else {  // canonical          
  144.         ;
  145.       }
  146.     }
  147.     y_sign = y.w[HIGH_128W] & MASK_SIGN;        // 0 for positive, MASK_SIGN for negative
  148.     C2.w[1] = y.w[HIGH_128W] & MASK_COEFF;
  149.     C2.w[0] = y.w[LOW_128W];
  150.     // check for non-canonical values - treated as zero
  151.     if ((y.w[HIGH_128W] & 0x6000000000000000ull) ==
  152.         0x6000000000000000ull) {
  153.       // G0_G1=11 => non-canonical
  154.       y_exp = (y.w[HIGH_128W] << 2) & MASK_EXP; // biased and shifted left 49 bits
  155.       C2.w[1] = 0;      // significand high
  156.       C2.w[0] = 0;      // significand low
  157.     } else {    // G0_G1 != 11
  158.       y_exp = y.w[HIGH_128W] & MASK_EXP;        // biased and shifted left 49 bits
  159.       if (C2.w[1] > 0x0001ed09bead87c0ull ||
  160.           (C2.w[1] == 0x0001ed09bead87c0ull &&
  161.            C2.w[0] > 0x378d8e63ffffffffull)) {
  162.         // y is non-canonical if coefficient is larger than 10^34 -1
  163.         C2.w[1] = 0;
  164.         C2.w[0] = 0;
  165.       } else {  // canonical
  166.         ;
  167.       }
  168.     }
  169.     p_sign = x_sign ^ y_sign;   // sign of the product
  170.  
  171.     true_p_exp = (x_exp >> 49) - 6176 + (y_exp >> 49) - 6176;
  172.     // true_p_exp, p_exp are used only for 0 * 0, 0 * f, or f * 0
  173.     if (true_p_exp < -398)
  174.       p_exp = 0;        // cannot be less than EXP_MIN
  175.     else if (true_p_exp > 369)
  176.       p_exp = (UINT64) (369 + 398) << 53;       // cannot be more than EXP_MAX
  177.     else
  178.       p_exp = (UINT64) (true_p_exp + 398) << 53;
  179.  
  180.     if ((C1.w[1] == 0x0 && C1.w[0] == 0x0) ||
  181.         (C2.w[1] == 0x0 && C2.w[0] == 0x0)) {
  182.       // x = 0 or y = 0
  183.       // the result is 0
  184.       res = p_sign | p_exp;     // preferred exponent in [EXP_MIN, EXP_MAX]
  185.       BID_RETURN (res)
  186.     }   // else continue
  187.   }
  188.   // swap x and y - ensure that a NaN in x has 'higher precedence' than one in y
  189. #if DECIMAL_CALL_BY_REFERENCE
  190.   bid64qqq_fma (&res, &y, &x, &z
  191.                 _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  192.                 _EXC_INFO_ARG);
  193. #else
  194.   res = bid64qqq_fma (y, x, z
  195.                       _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  196.                       _EXC_INFO_ARG);
  197. #endif
  198.   BID_RETURN (res);
  199. }
  200.  
  201.  
  202. #if DECIMAL_CALL_BY_REFERENCE
  203. void
  204. bid128dd_mul (UINT128 * pres, UINT64 * px, UINT64 * py
  205.               _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  206.               _EXC_INFO_PARAM) {
  207.   UINT64 x = *px, y = *py;
  208. #if !DECIMAL_GLOBAL_ROUNDING
  209.   unsigned int rnd_mode = *prnd_mode;
  210. #endif
  211. #else
  212. UINT128
  213. bid128dd_mul (UINT64 x, UINT64 y
  214.               _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  215.               _EXC_INFO_PARAM) {
  216. #endif
  217.   UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
  218.   };
  219.   UINT128 x1, y1;
  220.  
  221. #if DECIMAL_CALL_BY_REFERENCE
  222.   bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  223.   bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  224.   bid128_mul (&res, &x1, &y1
  225.               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  226.               _EXC_INFO_ARG);
  227. #else
  228.   x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  229.   y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  230.   res = bid128_mul (x1, y1
  231.                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  232.                     _EXC_INFO_ARG);
  233. #endif
  234.   BID_RETURN (res);
  235. }
  236.  
  237.  
  238. #if DECIMAL_CALL_BY_REFERENCE
  239. void
  240. bid128dq_mul (UINT128 * pres, UINT64 * px, UINT128 * py
  241.               _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  242.               _EXC_INFO_PARAM) {
  243.   UINT64 x = *px;
  244. #if !DECIMAL_GLOBAL_ROUNDING
  245.   unsigned int rnd_mode = *prnd_mode;
  246. #endif
  247. #else
  248. UINT128
  249. bid128dq_mul (UINT64 x, UINT128 y
  250.               _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  251.               _EXC_INFO_PARAM) {
  252. #endif
  253.   UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
  254.   };
  255.   UINT128 x1;
  256.  
  257. #if DECIMAL_CALL_BY_REFERENCE
  258.   bid64_to_bid128 (&x1, &x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  259.   bid128_mul (&res, &x1, py
  260.               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  261.               _EXC_INFO_ARG);
  262. #else
  263.   x1 = bid64_to_bid128 (x _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  264.   res = bid128_mul (x1, y
  265.                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  266.                     _EXC_INFO_ARG);
  267. #endif
  268.   BID_RETURN (res);
  269. }
  270.  
  271.  
  272. #if DECIMAL_CALL_BY_REFERENCE
  273. void
  274. bid128qd_mul (UINT128 * pres, UINT128 * px, UINT64 * py
  275.               _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  276.               _EXC_INFO_PARAM) {
  277.   UINT64 y = *py;
  278. #if !DECIMAL_GLOBAL_ROUNDING
  279.   unsigned int rnd_mode = *prnd_mode;
  280. #endif
  281. #else
  282. UINT128
  283. bid128qd_mul (UINT128 x, UINT64 y
  284.               _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  285.               _EXC_INFO_PARAM) {
  286. #endif
  287.   UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
  288.   };
  289.   UINT128 y1;
  290.  
  291. #if DECIMAL_CALL_BY_REFERENCE
  292.   bid64_to_bid128 (&y1, &y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  293.   bid128_mul (&res, px, &y1
  294.               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  295.               _EXC_INFO_ARG);
  296. #else
  297.   y1 = bid64_to_bid128 (y _EXC_FLAGS_ARG _EXC_MASKS_ARG _EXC_INFO_ARG);
  298.   res = bid128_mul (x, y1
  299.                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  300.                     _EXC_INFO_ARG);
  301. #endif
  302.   BID_RETURN (res);
  303. }
  304.  
  305.  
  306. // bid128_mul stands for bid128qq_mul
  307. #if DECIMAL_CALL_BY_REFERENCE
  308. void
  309. bid128_mul (UINT128 * pres, UINT128 * px,
  310.             UINT128 *
  311.             py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  312.             _EXC_INFO_PARAM) {
  313.   UINT128 x = *px, y = *py;
  314.  
  315. #if !DECIMAL_GLOBAL_ROUNDING
  316.   unsigned int rnd_mode = *prnd_mode;
  317.  
  318. #endif
  319. #else
  320. UINT128
  321. bid128_mul (UINT128 x,
  322.             UINT128 y _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
  323.             _EXC_INFO_PARAM) {
  324.  
  325. #endif
  326.   UINT128 z = { {0x0000000000000000ull, 0x5ffe000000000000ull}
  327.   };
  328.   UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
  329.   };
  330.   UINT64 x_sign, y_sign, p_sign;
  331.   UINT64 x_exp, y_exp, p_exp;
  332.   int true_p_exp;
  333.   UINT128 C1, C2;
  334.  
  335.   BID_SWAP128 (x);
  336.   BID_SWAP128 (y);
  337.   // skip cases where at least one operand is NaN or infinity
  338.   if (!(((x.w[1] & MASK_NAN) == MASK_NAN) ||
  339.         ((y.w[1] & MASK_NAN) == MASK_NAN) ||
  340.         ((x.w[1] & MASK_ANY_INF) == MASK_INF) ||
  341.         ((y.w[1] & MASK_ANY_INF) == MASK_INF))) {
  342.     // x, y are 0 or f but not inf or NaN => unpack the arguments and check
  343.     // for non-canonical values
  344.  
  345.     x_sign = x.w[1] & MASK_SIGN;        // 0 for positive, MASK_SIGN for negative
  346.     C1.w[1] = x.w[1] & MASK_COEFF;
  347.     C1.w[0] = x.w[0];
  348.     // check for non-canonical values - treated as zero
  349.     if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
  350.       // G0_G1=11 => non-canonical
  351.       x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  352.       C1.w[1] = 0;      // significand high
  353.       C1.w[0] = 0;      // significand low
  354.     } else {    // G0_G1 != 11
  355.       x_exp = x.w[1] & MASK_EXP;        // biased and shifted left 49 bits
  356.       if (C1.w[1] > 0x0001ed09bead87c0ull ||
  357.           (C1.w[1] == 0x0001ed09bead87c0ull &&
  358.            C1.w[0] > 0x378d8e63ffffffffull)) {
  359.         // x is non-canonical if coefficient is larger than 10^34 -1
  360.         C1.w[1] = 0;
  361.         C1.w[0] = 0;
  362.       } else {  // canonical          
  363.         ;
  364.       }
  365.     }
  366.     y_sign = y.w[1] & MASK_SIGN;        // 0 for positive, MASK_SIGN for negative
  367.     C2.w[1] = y.w[1] & MASK_COEFF;
  368.     C2.w[0] = y.w[0];
  369.     // check for non-canonical values - treated as zero
  370.     if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {
  371.       // G0_G1=11 => non-canonical
  372.       y_exp = (y.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits
  373.       C2.w[1] = 0;      // significand high
  374.       C2.w[0] = 0;      // significand low
  375.     } else {    // G0_G1 != 11
  376.       y_exp = y.w[1] & MASK_EXP;        // biased and shifted left 49 bits
  377.       if (C2.w[1] > 0x0001ed09bead87c0ull ||
  378.           (C2.w[1] == 0x0001ed09bead87c0ull &&
  379.            C2.w[0] > 0x378d8e63ffffffffull)) {
  380.         // y is non-canonical if coefficient is larger than 10^34 -1
  381.         C2.w[1] = 0;
  382.         C2.w[0] = 0;
  383.       } else {  // canonical
  384.         ;
  385.       }
  386.     }
  387.     p_sign = x_sign ^ y_sign;   // sign of the product
  388.  
  389.     true_p_exp = (x_exp >> 49) - 6176 + (y_exp >> 49) - 6176;
  390.     // true_p_exp, p_exp are used only for 0 * 0, 0 * f, or f * 0
  391.     if (true_p_exp < -6176)
  392.       p_exp = 0;        // cannot be less than EXP_MIN
  393.     else if (true_p_exp > 6111)
  394.       p_exp = (UINT64) (6111 + 6176) << 49;     // cannot be more than EXP_MAX
  395.     else
  396.       p_exp = (UINT64) (true_p_exp + 6176) << 49;
  397.  
  398.     if ((C1.w[1] == 0x0 && C1.w[0] == 0x0) ||
  399.         (C2.w[1] == 0x0 && C2.w[0] == 0x0)) {
  400.       // x = 0 or y = 0
  401.       // the result is 0
  402.       res.w[1] = p_sign | p_exp;        // preferred exponent in [EXP_MIN, EXP_MAX]
  403.       res.w[0] = 0x0;
  404.       BID_SWAP128 (res);
  405.       BID_RETURN (res)
  406.     }   // else continue
  407.   }
  408.  
  409.   BID_SWAP128 (x);
  410.   BID_SWAP128 (y);
  411.   BID_SWAP128 (z);
  412.   // swap x and y - ensure that a NaN in x has 'higher precedence' than one in y
  413. #if DECIMAL_CALL_BY_REFERENCE
  414.   bid128_fma (&res, &y, &x, &z
  415.               _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  416.               _EXC_INFO_ARG);
  417. #else
  418.   res = bid128_fma (y, x, z
  419.                     _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
  420.                     _EXC_INFO_ARG);
  421. #endif
  422.   BID_RETURN (res);
  423. }
  424.