[BACK]Return to mode1o.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpn / alpha / ev5

Annotation of OpenXM_contrib/gmp/mpn/alpha/ev5/mode1o.c, Revision 1.1

1.1     ! ohara       1: /* Alpha EV5 mpn_modexact_1c_odd -- mpn by limb exact style remainder.
        !             2:
        !             3:         cycles/limb
        !             4:    EV5:    30.0
        !             5:    EV6:    15.0
        !             6: */
        !             7:
        !             8: /*
        !             9: Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
        !            10:
        !            11: This file is part of the GNU MP Library.
        !            12:
        !            13: The GNU MP Library is free software; you can redistribute it and/or modify
        !            14: it under the terms of the GNU Lesser General Public License as published by
        !            15: the Free Software Foundation; either version 2.1 of the License, or (at your
        !            16: option) any later version.
        !            17:
        !            18: The GNU MP Library is distributed in the hope that it will be useful, but
        !            19: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            20: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
        !            21: License for more details.
        !            22:
        !            23: You should have received a copy of the GNU Lesser General Public License
        !            24: along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
        !            25: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
        !            26: MA 02111-1307, USA.
        !            27: */
        !            28:
        !            29: #include "gmp.h"
        !            30: #include "gmp-impl.h"
        !            31: #include "longlong.h"
        !            32:
        !            33:
        !            34: /* modlimb_invert is already faster than invert_limb or a "%", so the
        !            35:    modexact style can be used even at size==1.
        !            36:
        !            37:    The dependent chain is a subtract (1), mul1 (13) and umulh (15), which
        !            38:    would suggest 29 is a lower bound, or maybe the measured 30 is already as
        !            39:    good as possible, not sure.
        !            40:
        !            41:    For reference, ev6 runs this code at 15 cycles, which is 1 faster than
        !            42:    the generic loop at 16.  But maybe something better is possible.  */
        !            43:
        !            44: mp_limb_t
        !            45: mpn_modexact_1c_odd (mp_srcptr src, mp_size_t size, mp_limb_t d, mp_limb_t h)
        !            46: {
        !            47:   mp_limb_t  s, x, y, inverse, dummy;
        !            48:   mp_limb_t  c = 0;
        !            49:   mp_size_t  i;
        !            50:
        !            51:   ASSERT (size >= 1);
        !            52:   ASSERT (d & 1);
        !            53:
        !            54:   modlimb_invert (inverse, d);
        !            55:
        !            56:   i = 0;
        !            57:   if (size == 1)
        !            58:     {
        !            59:       s = src[0];
        !            60:       goto last_step;
        !            61:     }
        !            62:
        !            63:   do
        !            64:     {
        !            65:       s = src[i];
        !            66:       x = s - c;
        !            67:       c = (x > s);
        !            68:
        !            69:       y = x - h;
        !            70:       c += (y > x);
        !            71:       y *= inverse;
        !            72:       umul_ppmm (h, dummy, y, d);
        !            73:     }
        !            74:   while (++i < size-1);
        !            75:
        !            76:
        !            77:   s = src[i];
        !            78:   if (s <= d)
        !            79:     {
        !            80:       /* With high<=d the final step can be a subtract and addback.  If
        !            81:         c+h==0 then the addback will restore to l>=0.  If c+h==d then will
        !            82:         get x==d if s==0, but that's ok per the function definition.  */
        !            83:
        !            84:       c += h;
        !            85:
        !            86:       x = c - s;
        !            87:       if (x > c)
        !            88:        x += d;
        !            89:
        !            90:       ASSERT (x <= d);
        !            91:       return x;
        !            92:     }
        !            93:   else
        !            94:     {
        !            95:       /* Can't skip a divide, just do the loop code once more. */
        !            96:     last_step:
        !            97:       x = s - c;
        !            98:       c = (x > s);
        !            99:
        !           100:       y = x - h;
        !           101:       c += (y > x);
        !           102:
        !           103:       y *= inverse;
        !           104:       umul_ppmm (h, dummy, y, d);
        !           105:
        !           106:       c += h;
        !           107:
        !           108:       ASSERT (c <= d);
        !           109:       return c;
        !           110:     }
        !           111: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>