diff options
Diffstat (limited to 'lib/mpi')
| -rw-r--r-- | lib/mpi/Makefile | 1 | ||||
| -rw-r--r-- | lib/mpi/longlong.h | 138 | ||||
| -rw-r--r-- | lib/mpi/mpi-bit.c | 2 | ||||
| -rw-r--r-- | lib/mpi/mpi-cmp.c | 70 | ||||
| -rw-r--r-- | lib/mpi/mpi-pow.c | 4 | ||||
| -rw-r--r-- | lib/mpi/mpicoder.c | 55 |
6 files changed, 131 insertions, 139 deletions
diff --git a/lib/mpi/Makefile b/lib/mpi/Makefile index 45ca90a8639c..019a68c90144 100644 --- a/lib/mpi/Makefile +++ b/lib/mpi/Makefile | |||
| @@ -14,6 +14,7 @@ mpi-y = \ | |||
| 14 | generic_mpih-add1.o \ | 14 | generic_mpih-add1.o \ |
| 15 | mpicoder.o \ | 15 | mpicoder.o \ |
| 16 | mpi-bit.o \ | 16 | mpi-bit.o \ |
| 17 | mpi-cmp.o \ | ||
| 17 | mpih-cmp.o \ | 18 | mpih-cmp.o \ |
| 18 | mpih-div.o \ | 19 | mpih-div.o \ |
| 19 | mpih-mul.o \ | 20 | mpih-mul.o \ |
diff --git a/lib/mpi/longlong.h b/lib/mpi/longlong.h index 29f98624ef93..678ce4f1e124 100644 --- a/lib/mpi/longlong.h +++ b/lib/mpi/longlong.h | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | 19 | * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
| 20 | * MA 02111-1307, USA. */ | 20 | * MA 02111-1307, USA. */ |
| 21 | 21 | ||
| 22 | #include <asm-generic/bitops/count_zeros.h> | ||
| 23 | |||
| 22 | /* You have to define the following before including this file: | 24 | /* You have to define the following before including this file: |
| 23 | * | 25 | * |
| 24 | * UWtype -- An unsigned type, default type for operations (typically a "word") | 26 | * UWtype -- An unsigned type, default type for operations (typically a "word") |
| @@ -146,12 +148,6 @@ do { \ | |||
| 146 | : "1" ((USItype)(n1)), \ | 148 | : "1" ((USItype)(n1)), \ |
| 147 | "r" ((USItype)(n0)), \ | 149 | "r" ((USItype)(n0)), \ |
| 148 | "r" ((USItype)(d))) | 150 | "r" ((USItype)(d))) |
| 149 | |||
| 150 | #define count_leading_zeros(count, x) \ | ||
| 151 | __asm__ ("clz %0,%1" \ | ||
| 152 | : "=r" ((USItype)(count)) \ | ||
| 153 | : "r" ((USItype)(x))) | ||
| 154 | #define COUNT_LEADING_ZEROS_0 32 | ||
| 155 | #endif /* __a29k__ */ | 151 | #endif /* __a29k__ */ |
| 156 | 152 | ||
| 157 | #if defined(__alpha) && W_TYPE_SIZE == 64 | 153 | #if defined(__alpha) && W_TYPE_SIZE == 64 |
| @@ -298,11 +294,6 @@ extern UDItype __udiv_qrnnd(); | |||
| 298 | : "1" ((USItype)(nh)), \ | 294 | : "1" ((USItype)(nh)), \ |
| 299 | "0" ((USItype)(nl)), \ | 295 | "0" ((USItype)(nl)), \ |
| 300 | "g" ((USItype)(d))) | 296 | "g" ((USItype)(d))) |
| 301 | #define count_leading_zeros(count, x) \ | ||
| 302 | __asm__ ("bsch/1 %1,%0" \ | ||
| 303 | : "=g" (count) \ | ||
| 304 | : "g" ((USItype)(x)), \ | ||
| 305 | "0" ((USItype)0)) | ||
| 306 | #endif | 297 | #endif |
| 307 | 298 | ||
| 308 | /*************************************** | 299 | /*************************************** |
| @@ -354,27 +345,6 @@ do { USItype __r; \ | |||
| 354 | } while (0) | 345 | } while (0) |
| 355 | extern USItype __udiv_qrnnd(); | 346 | extern USItype __udiv_qrnnd(); |
| 356 | #endif /* LONGLONG_STANDALONE */ | 347 | #endif /* LONGLONG_STANDALONE */ |
| 357 | #define count_leading_zeros(count, x) \ | ||
| 358 | do { \ | ||
| 359 | USItype __tmp; \ | ||
| 360 | __asm__ ( \ | ||
| 361 | "ldi 1,%0\n" \ | ||
| 362 | "extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ | ||
| 363 | "extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \ | ||
| 364 | "ldo 16(%0),%0 ; Yes. Perform add.\n" \ | ||
| 365 | "extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ | ||
| 366 | "extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \ | ||
| 367 | "ldo 8(%0),%0 ; Yes. Perform add.\n" \ | ||
| 368 | "extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ | ||
| 369 | "extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \ | ||
| 370 | "ldo 4(%0),%0 ; Yes. Perform add.\n" \ | ||
| 371 | "extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ | ||
| 372 | "extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \ | ||
| 373 | "ldo 2(%0),%0 ; Yes. Perform add.\n" \ | ||
| 374 | "extru %1,30,1,%1 ; Extract bit 1.\n" \ | ||
| 375 | "sub %0,%1,%0 ; Subtract it. " \ | ||
| 376 | : "=r" (count), "=r" (__tmp) : "1" (x)); \ | ||
| 377 | } while (0) | ||
| 378 | #endif /* hppa */ | 348 | #endif /* hppa */ |
| 379 | 349 | ||
| 380 | /*************************************** | 350 | /*************************************** |
| @@ -457,15 +427,6 @@ do { \ | |||
| 457 | : "0" ((USItype)(n0)), \ | 427 | : "0" ((USItype)(n0)), \ |
| 458 | "1" ((USItype)(n1)), \ | 428 | "1" ((USItype)(n1)), \ |
| 459 | "rm" ((USItype)(d))) | 429 | "rm" ((USItype)(d))) |
| 460 | #define count_leading_zeros(count, x) \ | ||
| 461 | do { \ | ||
| 462 | USItype __cbtmp; \ | ||
| 463 | __asm__ ("bsrl %1,%0" \ | ||
| 464 | : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ | ||
| 465 | (count) = __cbtmp ^ 31; \ | ||
| 466 | } while (0) | ||
| 467 | #define count_trailing_zeros(count, x) \ | ||
| 468 | __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) | ||
| 469 | #ifndef UMUL_TIME | 430 | #ifndef UMUL_TIME |
| 470 | #define UMUL_TIME 40 | 431 | #define UMUL_TIME 40 |
| 471 | #endif | 432 | #endif |
| @@ -536,15 +497,6 @@ do { \ | |||
| 536 | "dI" ((USItype)(d))); \ | 497 | "dI" ((USItype)(d))); \ |
| 537 | (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ | 498 | (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ |
| 538 | } while (0) | 499 | } while (0) |
| 539 | #define count_leading_zeros(count, x) \ | ||
| 540 | do { \ | ||
| 541 | USItype __cbtmp; \ | ||
| 542 | __asm__ ("scanbit %1,%0" \ | ||
| 543 | : "=r" (__cbtmp) \ | ||
| 544 | : "r" ((USItype)(x))); \ | ||
| 545 | (count) = __cbtmp ^ 31; \ | ||
| 546 | } while (0) | ||
| 547 | #define COUNT_LEADING_ZEROS_0 (-32) /* sic */ | ||
| 548 | #if defined(__i960mx) /* what is the proper symbol to test??? */ | 500 | #if defined(__i960mx) /* what is the proper symbol to test??? */ |
| 549 | #define rshift_rhlc(r, h, l, c) \ | 501 | #define rshift_rhlc(r, h, l, c) \ |
| 550 | do { \ | 502 | do { \ |
| @@ -603,11 +555,6 @@ do { \ | |||
| 603 | : "0" ((USItype)(n0)), \ | 555 | : "0" ((USItype)(n0)), \ |
| 604 | "1" ((USItype)(n1)), \ | 556 | "1" ((USItype)(n1)), \ |
| 605 | "dmi" ((USItype)(d))) | 557 | "dmi" ((USItype)(d))) |
| 606 | #define count_leading_zeros(count, x) \ | ||
| 607 | __asm__ ("bfffo %1{%b2:%b2},%0" \ | ||
| 608 | : "=d" ((USItype)(count)) \ | ||
| 609 | : "od" ((USItype)(x)), "n" (0)) | ||
| 610 | #define COUNT_LEADING_ZEROS_0 32 | ||
| 611 | #else /* not mc68020 */ | 558 | #else /* not mc68020 */ |
| 612 | #define umul_ppmm(xh, xl, a, b) \ | 559 | #define umul_ppmm(xh, xl, a, b) \ |
| 613 | do { USItype __umul_tmp1, __umul_tmp2; \ | 560 | do { USItype __umul_tmp1, __umul_tmp2; \ |
| @@ -664,15 +611,6 @@ do { USItype __umul_tmp1, __umul_tmp2; \ | |||
| 664 | "rJ" ((USItype)(bh)), \ | 611 | "rJ" ((USItype)(bh)), \ |
| 665 | "rJ" ((USItype)(al)), \ | 612 | "rJ" ((USItype)(al)), \ |
| 666 | "rJ" ((USItype)(bl))) | 613 | "rJ" ((USItype)(bl))) |
| 667 | #define count_leading_zeros(count, x) \ | ||
| 668 | do { \ | ||
| 669 | USItype __cbtmp; \ | ||
| 670 | __asm__ ("ff1 %0,%1" \ | ||
| 671 | : "=r" (__cbtmp) \ | ||
| 672 | : "r" ((USItype)(x))); \ | ||
| 673 | (count) = __cbtmp ^ 31; \ | ||
| 674 | } while (0) | ||
| 675 | #define COUNT_LEADING_ZEROS_0 63 /* sic */ | ||
| 676 | #if defined(__m88110__) | 614 | #if defined(__m88110__) |
| 677 | #define umul_ppmm(wh, wl, u, v) \ | 615 | #define umul_ppmm(wh, wl, u, v) \ |
| 678 | do { \ | 616 | do { \ |
| @@ -779,12 +717,6 @@ do { \ | |||
| 779 | : "0" (__xx.__ll), \ | 717 | : "0" (__xx.__ll), \ |
| 780 | "g" ((USItype)(d))); \ | 718 | "g" ((USItype)(d))); \ |
| 781 | (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) | 719 | (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) |
| 782 | #define count_trailing_zeros(count, x) \ | ||
| 783 | do { \ | ||
| 784 | __asm__("ffsd %2,%0" \ | ||
| 785 | : "=r"((USItype) (count)) \ | ||
| 786 | : "0"((USItype) 0), "r"((USItype) (x))); \ | ||
| 787 | } while (0) | ||
| 788 | #endif /* __ns32000__ */ | 720 | #endif /* __ns32000__ */ |
| 789 | 721 | ||
| 790 | /*************************************** | 722 | /*************************************** |
| @@ -855,11 +787,6 @@ do { \ | |||
| 855 | "rI" ((USItype)(al)), \ | 787 | "rI" ((USItype)(al)), \ |
| 856 | "r" ((USItype)(bl))); \ | 788 | "r" ((USItype)(bl))); \ |
| 857 | } while (0) | 789 | } while (0) |
| 858 | #define count_leading_zeros(count, x) \ | ||
| 859 | __asm__ ("{cntlz|cntlzw} %0,%1" \ | ||
| 860 | : "=r" ((USItype)(count)) \ | ||
| 861 | : "r" ((USItype)(x))) | ||
| 862 | #define COUNT_LEADING_ZEROS_0 32 | ||
| 863 | #if defined(_ARCH_PPC) | 790 | #if defined(_ARCH_PPC) |
| 864 | #define umul_ppmm(ph, pl, m0, m1) \ | 791 | #define umul_ppmm(ph, pl, m0, m1) \ |
| 865 | do { \ | 792 | do { \ |
| @@ -1001,19 +928,6 @@ do { \ | |||
| 1001 | } while (0) | 928 | } while (0) |
| 1002 | #define UMUL_TIME 20 | 929 | #define UMUL_TIME 20 |
| 1003 | #define UDIV_TIME 200 | 930 | #define UDIV_TIME 200 |
| 1004 | #define count_leading_zeros(count, x) \ | ||
| 1005 | do { \ | ||
| 1006 | if ((x) >= 0x10000) \ | ||
| 1007 | __asm__ ("clz %0,%1" \ | ||
| 1008 | : "=r" ((USItype)(count)) \ | ||
| 1009 | : "r" ((USItype)(x) >> 16)); \ | ||
| 1010 | else { \ | ||
| 1011 | __asm__ ("clz %0,%1" \ | ||
| 1012 | : "=r" ((USItype)(count)) \ | ||
| 1013 | : "r" ((USItype)(x))); \ | ||
| 1014 | (count) += 16; \ | ||
| 1015 | } \ | ||
| 1016 | } while (0) | ||
| 1017 | #endif /* RT/ROMP */ | 931 | #endif /* RT/ROMP */ |
| 1018 | 932 | ||
| 1019 | /*************************************** | 933 | /*************************************** |
| @@ -1142,13 +1056,6 @@ do { \ | |||
| 1142 | "rI" ((USItype)(d)) \ | 1056 | "rI" ((USItype)(d)) \ |
| 1143 | : "%g1" __AND_CLOBBER_CC) | 1057 | : "%g1" __AND_CLOBBER_CC) |
| 1144 | #define UDIV_TIME 37 | 1058 | #define UDIV_TIME 37 |
| 1145 | #define count_leading_zeros(count, x) \ | ||
| 1146 | __asm__ ("scan %1,0,%0" \ | ||
| 1147 | : "=r" ((USItype)(x)) \ | ||
| 1148 | : "r" ((USItype)(count))) | ||
| 1149 | /* Early sparclites return 63 for an argument of 0, but they warn that future | ||
| 1150 | implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 | ||
| 1151 | undefined. */ | ||
| 1152 | #endif /* __sparclite__ */ | 1059 | #endif /* __sparclite__ */ |
| 1153 | #endif /* __sparc_v8__ */ | 1060 | #endif /* __sparc_v8__ */ |
| 1154 | /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ | 1061 | /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ |
| @@ -1454,47 +1361,6 @@ do { \ | |||
| 1454 | #define udiv_qrnnd __udiv_qrnnd_c | 1361 | #define udiv_qrnnd __udiv_qrnnd_c |
| 1455 | #endif | 1362 | #endif |
| 1456 | 1363 | ||
| 1457 | #undef count_leading_zeros | ||
| 1458 | #if !defined(count_leading_zeros) | ||
| 1459 | extern | ||
| 1460 | #ifdef __STDC__ | ||
| 1461 | const | ||
| 1462 | #endif | ||
| 1463 | unsigned char __clz_tab[]; | ||
| 1464 | #define count_leading_zeros(count, x) \ | ||
| 1465 | do { \ | ||
| 1466 | UWtype __xr = (x); \ | ||
| 1467 | UWtype __a; \ | ||
| 1468 | \ | ||
| 1469 | if (W_TYPE_SIZE <= 32) { \ | ||
| 1470 | __a = __xr < ((UWtype) 1 << 2*__BITS4) \ | ||
| 1471 | ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \ | ||
| 1472 | : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ | ||
| 1473 | } \ | ||
| 1474 | else { \ | ||
| 1475 | for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ | ||
| 1476 | if (((__xr >> __a) & 0xff) != 0) \ | ||
| 1477 | break; \ | ||
| 1478 | } \ | ||
| 1479 | \ | ||
| 1480 | (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ | ||
| 1481 | } while (0) | ||
| 1482 | /* This version gives a well-defined value for zero. */ | ||
| 1483 | #define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE | ||
| 1484 | #endif | ||
| 1485 | |||
| 1486 | #if !defined(count_trailing_zeros) | ||
| 1487 | /* Define count_trailing_zeros using count_leading_zeros. The latter might be | ||
| 1488 | defined in asm, but if it is not, the C version above is good enough. */ | ||
| 1489 | #define count_trailing_zeros(count, x) \ | ||
| 1490 | do { \ | ||
| 1491 | UWtype __ctz_x = (x); \ | ||
| 1492 | UWtype __ctz_c; \ | ||
| 1493 | count_leading_zeros(__ctz_c, __ctz_x & -__ctz_x); \ | ||
| 1494 | (count) = W_TYPE_SIZE - 1 - __ctz_c; \ | ||
| 1495 | } while (0) | ||
| 1496 | #endif | ||
| 1497 | |||
| 1498 | #ifndef UDIV_NEEDS_NORMALIZATION | 1364 | #ifndef UDIV_NEEDS_NORMALIZATION |
| 1499 | #define UDIV_NEEDS_NORMALIZATION 0 | 1365 | #define UDIV_NEEDS_NORMALIZATION 0 |
| 1500 | #endif | 1366 | #endif |
diff --git a/lib/mpi/mpi-bit.c b/lib/mpi/mpi-bit.c index 568724804f29..503537e08436 100644 --- a/lib/mpi/mpi-bit.c +++ b/lib/mpi/mpi-bit.c | |||
| @@ -45,7 +45,7 @@ unsigned mpi_get_nbits(MPI a) | |||
| 45 | if (a->nlimbs) { | 45 | if (a->nlimbs) { |
| 46 | mpi_limb_t alimb = a->d[a->nlimbs - 1]; | 46 | mpi_limb_t alimb = a->d[a->nlimbs - 1]; |
| 47 | if (alimb) | 47 | if (alimb) |
| 48 | count_leading_zeros(n, alimb); | 48 | n = count_leading_zeros(alimb); |
| 49 | else | 49 | else |
| 50 | n = BITS_PER_MPI_LIMB; | 50 | n = BITS_PER_MPI_LIMB; |
| 51 | n = BITS_PER_MPI_LIMB - n + (a->nlimbs - 1) * BITS_PER_MPI_LIMB; | 51 | n = BITS_PER_MPI_LIMB - n + (a->nlimbs - 1) * BITS_PER_MPI_LIMB; |
diff --git a/lib/mpi/mpi-cmp.c b/lib/mpi/mpi-cmp.c new file mode 100644 index 000000000000..1871e7b61ca0 --- /dev/null +++ b/lib/mpi/mpi-cmp.c | |||
| @@ -0,0 +1,70 @@ | |||
| 1 | /* mpi-cmp.c - MPI functions | ||
| 2 | * Copyright (C) 1998, 1999 Free Software Foundation, Inc. | ||
| 3 | * | ||
| 4 | * This file is part of GnuPG. | ||
| 5 | * | ||
| 6 | * GnuPG is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * GnuPG is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include "mpi-internal.h" | ||
| 22 | |||
| 23 | int mpi_cmp_ui(MPI u, unsigned long v) | ||
| 24 | { | ||
| 25 | mpi_limb_t limb = v; | ||
| 26 | |||
| 27 | mpi_normalize(u); | ||
| 28 | if (!u->nlimbs && !limb) | ||
| 29 | return 0; | ||
| 30 | if (u->sign) | ||
| 31 | return -1; | ||
| 32 | if (u->nlimbs > 1) | ||
| 33 | return 1; | ||
| 34 | |||
| 35 | if (u->d[0] == limb) | ||
| 36 | return 0; | ||
| 37 | else if (u->d[0] > limb) | ||
| 38 | return 1; | ||
| 39 | else | ||
| 40 | return -1; | ||
| 41 | } | ||
| 42 | EXPORT_SYMBOL_GPL(mpi_cmp_ui); | ||
| 43 | |||
| 44 | int mpi_cmp(MPI u, MPI v) | ||
| 45 | { | ||
| 46 | mpi_size_t usize, vsize; | ||
| 47 | int cmp; | ||
| 48 | |||
| 49 | mpi_normalize(u); | ||
| 50 | mpi_normalize(v); | ||
| 51 | usize = u->nlimbs; | ||
| 52 | vsize = v->nlimbs; | ||
| 53 | if (!u->sign && v->sign) | ||
| 54 | return 1; | ||
| 55 | if (u->sign && !v->sign) | ||
| 56 | return -1; | ||
| 57 | if (usize != vsize && !u->sign && !v->sign) | ||
| 58 | return usize - vsize; | ||
| 59 | if (usize != vsize && u->sign && v->sign) | ||
| 60 | return vsize + usize; | ||
| 61 | if (!usize) | ||
| 62 | return 0; | ||
| 63 | cmp = mpihelp_cmp(u->d, v->d, usize); | ||
| 64 | if (!cmp) | ||
| 65 | return 0; | ||
| 66 | if ((cmp < 0 ? 1 : 0) == (u->sign ? 1 : 0)) | ||
| 67 | return 1; | ||
| 68 | return -1; | ||
| 69 | } | ||
| 70 | EXPORT_SYMBOL_GPL(mpi_cmp); | ||
diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c index 67f3e79af914..5464c8744ea9 100644 --- a/lib/mpi/mpi-pow.c +++ b/lib/mpi/mpi-pow.c | |||
| @@ -77,7 +77,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod) | |||
| 77 | mp = mp_marker = mpi_alloc_limb_space(msize); | 77 | mp = mp_marker = mpi_alloc_limb_space(msize); |
| 78 | if (!mp) | 78 | if (!mp) |
| 79 | goto enomem; | 79 | goto enomem; |
| 80 | count_leading_zeros(mod_shift_cnt, mod->d[msize - 1]); | 80 | mod_shift_cnt = count_leading_zeros(mod->d[msize - 1]); |
| 81 | if (mod_shift_cnt) | 81 | if (mod_shift_cnt) |
| 82 | mpihelp_lshift(mp, mod->d, msize, mod_shift_cnt); | 82 | mpihelp_lshift(mp, mod->d, msize, mod_shift_cnt); |
| 83 | else | 83 | else |
| @@ -169,7 +169,7 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod) | |||
| 169 | 169 | ||
| 170 | i = esize - 1; | 170 | i = esize - 1; |
| 171 | e = ep[i]; | 171 | e = ep[i]; |
| 172 | count_leading_zeros(c, e); | 172 | c = count_leading_zeros(e); |
| 173 | e = (e << c) << 1; /* shift the exp bits to the left, lose msb */ | 173 | e = (e << c) << 1; /* shift the exp bits to the left, lose msb */ |
| 174 | c = BITS_PER_MPI_LIMB - 1 - c; | 174 | c = BITS_PER_MPI_LIMB - 1 - c; |
| 175 | 175 | ||
diff --git a/lib/mpi/mpicoder.c b/lib/mpi/mpicoder.c index f0fa65995800..3962b7f7fe3f 100644 --- a/lib/mpi/mpicoder.c +++ b/lib/mpi/mpicoder.c | |||
| @@ -18,10 +18,65 @@ | |||
| 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/bitops.h> | ||
| 22 | #include <asm-generic/bitops/count_zeros.h> | ||
| 21 | #include "mpi-internal.h" | 23 | #include "mpi-internal.h" |
| 22 | 24 | ||
| 23 | #define MAX_EXTERN_MPI_BITS 16384 | 25 | #define MAX_EXTERN_MPI_BITS 16384 |
| 24 | 26 | ||
| 27 | /** | ||
| 28 | * mpi_read_raw_data - Read a raw byte stream as a positive integer | ||
| 29 | * @xbuffer: The data to read | ||
| 30 | * @nbytes: The amount of data to read | ||
| 31 | */ | ||
| 32 | MPI mpi_read_raw_data(const void *xbuffer, size_t nbytes) | ||
| 33 | { | ||
| 34 | const uint8_t *buffer = xbuffer; | ||
| 35 | int i, j; | ||
| 36 | unsigned nbits, nlimbs; | ||
| 37 | mpi_limb_t a; | ||
| 38 | MPI val = NULL; | ||
| 39 | |||
| 40 | while (nbytes >= 0 && buffer[0] == 0) { | ||
| 41 | buffer++; | ||
| 42 | nbytes--; | ||
| 43 | } | ||
| 44 | |||
| 45 | nbits = nbytes * 8; | ||
| 46 | if (nbits > MAX_EXTERN_MPI_BITS) { | ||
| 47 | pr_info("MPI: mpi too large (%u bits)\n", nbits); | ||
| 48 | return NULL; | ||
| 49 | } | ||
| 50 | if (nbytes > 0) | ||
| 51 | nbits -= count_leading_zeros(buffer[0]); | ||
| 52 | else | ||
| 53 | nbits = 0; | ||
| 54 | |||
| 55 | nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; | ||
| 56 | val = mpi_alloc(nlimbs); | ||
| 57 | if (!val) | ||
| 58 | return NULL; | ||
| 59 | val->nbits = nbits; | ||
| 60 | val->sign = 0; | ||
| 61 | val->nlimbs = nlimbs; | ||
| 62 | |||
| 63 | if (nbytes > 0) { | ||
| 64 | i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; | ||
| 65 | i %= BYTES_PER_MPI_LIMB; | ||
| 66 | for (j = nlimbs; j > 0; j--) { | ||
| 67 | a = 0; | ||
| 68 | for (; i < BYTES_PER_MPI_LIMB; i++) { | ||
| 69 | a <<= 8; | ||
| 70 | a |= *buffer++; | ||
| 71 | } | ||
| 72 | i = 0; | ||
| 73 | val->d[j - 1] = a; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | return val; | ||
| 77 | } | ||
| 78 | EXPORT_SYMBOL_GPL(mpi_read_raw_data); | ||
| 79 | |||
| 25 | MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) | 80 | MPI mpi_read_from_buffer(const void *xbuffer, unsigned *ret_nread) |
| 26 | { | 81 | { |
| 27 | const uint8_t *buffer = xbuffer; | 82 | const uint8_t *buffer = xbuffer; |
