sub_n.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:2k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* Cray PVP mpn_sub_n -- subtract two limb vectors and store their difference
  2.    in a third limb vector.
  3. Copyright 1996, 2000, 2001 Free Software Foundation, Inc.
  4. This file is part of the GNU MP Library.
  5. The GNU MP Library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU Lesser General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or (at your
  8. option) any later version.
  9. The GNU MP Library is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  12. License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  15. /* This code runs at 4 cycles/limb.  It may be possible to bring it down
  16.    to 3 cycles/limb.  */
  17. #include "gmp.h"
  18. #include "gmp-impl.h"
  19. mp_limb_t
  20. mpn_sub_n (mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
  21. {
  22.   mp_limb_t cy[n];
  23.   mp_limb_t a, b, r, s0, c0, c1;
  24.   mp_size_t i;
  25.   int more_carries;
  26.   /* Main subtract loop.  Generate a raw output difference in rp[] and a
  27.      borrow vector in cy[].  */
  28. #pragma _CRI ivdep
  29.   for (i = 0; i < n; i++)
  30.     {
  31.       a = up[i];
  32.       b = vp[i];
  33.       s0 = a - b; /* a = s0 + b */
  34.       rp[i] = s0;
  35.       c0 = ((s0 & b) | ((s0 | b) & ~a)) >> 63;
  36.       cy[i] = c0;
  37.     }
  38.   /* Borrow subtract loop.  Subtract the borrow vector cy[] from the raw
  39.      difference rp[] and store the new difference back to rp[0].  If this
  40.      generates further borrow, set more_carries.  */
  41.   more_carries = 0;
  42. #pragma _CRI ivdep
  43.   for (i = 1; i < n; i++)
  44.     {
  45.       r = rp[i];
  46.       c0 = cy[i - 1];
  47.       s0 = r - c0; /* r = s0 + c0 */
  48.       rp[i] = s0;
  49.       c0 = (s0 & ~r) >> 63;
  50.       more_carries += c0;
  51.     }
  52.   /* If that second loop generated borrow, handle that in scalar loop.  */
  53.   if (more_carries)
  54.     {
  55.       mp_limb_t cyrec = 0;
  56.       /* Look for places where rp[k] contains just ones and cy[k-1] is
  57.  non-zero.  These are where we got a recurrency borrow.  */
  58.       for (i = 1; i < n; i++)
  59. {
  60.   r = rp[i];
  61.   c0 = (~r == 0 && cy[i - 1] != 0);
  62.   s0 = r - cyrec;
  63.   rp[i] = s0;
  64.   c1 = (s0 & ~r) >> 63;
  65.   cyrec = c0 | c1;
  66. }
  67.       return cyrec | cy[n - 1];
  68.     }
  69.   return cy[n - 1];
  70. }