chiark / gitweb /
Add two's-complement functionality. Improve mpx_udiv a little by
[catacomb] / mpx.c
1 /* -*-c-*-
2  *
3  * $Id: mpx.c,v 1.4 1999/11/17 18:04:09 mdw Exp $
4  *
5  * Low-level multiprecision arithmetic
6  *
7  * (c) 1999 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of Catacomb.
13  *
14  * Catacomb is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Library General Public License as
16  * published by the Free Software Foundation; either version 2 of the
17  * License, or (at your option) any later version.
18  * 
19  * Catacomb is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU Library General Public License for more details.
23  * 
24  * You should have received a copy of the GNU Library General Public
25  * License along with Catacomb; if not, write to the Free
26  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
27  * MA 02111-1307, USA.
28  */
29
30 /*----- Revision history --------------------------------------------------* 
31  *
32  * $Log: mpx.c,v $
33  * Revision 1.4  1999/11/17 18:04:09  mdw
34  * Add two's-complement functionality.  Improve mpx_udiv a little by
35  * performing the multiplication of the divisor by q with the subtraction
36  * from r.
37  *
38  * Revision 1.3  1999/11/13 01:57:31  mdw
39  * Remove stray debugging code.
40  *
41  * Revision 1.2  1999/11/13 01:50:59  mdw
42  * Multiprecision routines finished and tested.
43  *
44  * Revision 1.1  1999/09/03 08:41:12  mdw
45  * Initial import.
46  *
47  */
48
49 /*----- Header files ------------------------------------------------------*/
50
51 #include <assert.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55
56 #include <mLib/bits.h>
57
58 #include "mptypes.h"
59 #include "mpx.h"
60
61 /*----- Loading and storing -----------------------------------------------*/
62
63 /* --- @mpx_storel@ --- *
64  *
65  * Arguments:   @const mpw *v, *vl@ = base and limit of source vector
66  *              @void *pp@ = pointer to octet array
67  *              @size_t sz@ = size of octet array
68  *
69  * Returns:     ---
70  *
71  * Use:         Stores an MP in an octet array, least significant octet
72  *              first.  High-end octets are silently discarded if there
73  *              isn't enough space for them.
74  */
75
76 void mpx_storel(const mpw *v, const mpw *vl, void *pp, size_t sz)
77 {
78   mpw n, w = 0;
79   octet *p = pp, *q = p + sz;
80   unsigned bits = 0;
81
82   while (p < q) {
83     if (bits < 8) {
84       if (v >= vl) {
85         *p++ = U8(w);
86         break;
87       }
88       n = *v++;
89       *p++ = U8(w | n << bits);
90       w = n >> (8 - bits);
91       bits += MPW_BITS - 8;
92     } else {
93       *p++ = U8(w);
94       w >>= 8;
95       bits -= 8;
96     }
97   }
98   memset(p, 0, q - p);
99 }
100
101 /* --- @mpx_loadl@ --- *
102  *
103  * Arguments:   @mpw *v, *vl@ = base and limit of destination vector
104  *              @const void *pp@ = pointer to octet array
105  *              @size_t sz@ = size of octet array
106  *
107  * Returns:     ---
108  *
109  * Use:         Loads an MP in an octet array, least significant octet
110  *              first.  High-end octets are ignored if there isn't enough
111  *              space for them.
112  */
113
114 void mpx_loadl(mpw *v, mpw *vl, const void *pp, size_t sz)
115 {
116   unsigned n;
117   mpw w = 0;
118   const octet *p = pp, *q = p + sz;
119   unsigned bits = 0;
120
121   if (v >= vl)
122     return;
123   while (p < q) {
124     n = U8(*p++);
125     w |= n << bits;
126     bits += 8;
127     if (bits >= MPW_BITS) {
128       *v++ = MPW(w);
129       w = n >> (MPW_BITS - bits + 8);
130       bits -= MPW_BITS;
131       if (v >= vl)
132         return;
133     }
134   }
135   *v++ = w;
136   MPX_ZERO(v, vl);
137 }
138
139 /* --- @mpx_storeb@ --- *
140  *
141  * Arguments:   @const mpw *v, *vl@ = base and limit of source vector
142  *              @void *pp@ = pointer to octet array
143  *              @size_t sz@ = size of octet array
144  *
145  * Returns:     ---
146  *
147  * Use:         Stores an MP in an octet array, most significant octet
148  *              first.  High-end octets are silently discarded if there
149  *              isn't enough space for them.
150  */
151
152 void mpx_storeb(const mpw *v, const mpw *vl, void *pp, size_t sz)
153 {
154   mpw n, w = 0;
155   octet *p = pp, *q = p + sz;
156   unsigned bits = 0;
157
158   while (q > p) {
159     if (bits < 8) {
160       if (v >= vl) {
161         *--q = U8(w);
162         break;
163       }
164       n = *v++;
165       *--q = U8(w | n << bits);
166       w = n >> (8 - bits);
167       bits += MPW_BITS - 8;
168     } else {
169       *--q = U8(w);
170       w >>= 8;
171       bits -= 8;
172     }
173   }
174   memset(p, 0, q - p);
175 }
176
177 /* --- @mpx_loadb@ --- *
178  *
179  * Arguments:   @mpw *v, *vl@ = base and limit of destination vector
180  *              @const void *pp@ = pointer to octet array
181  *              @size_t sz@ = size of octet array
182  *
183  * Returns:     ---
184  *
185  * Use:         Loads an MP in an octet array, most significant octet
186  *              first.  High-end octets are ignored if there isn't enough
187  *              space for them.
188  */
189
190 void mpx_loadb(mpw *v, mpw *vl, const void *pp, size_t sz)
191 {
192   unsigned n;
193   mpw w = 0;
194   const octet *p = pp, *q = p + sz;
195   unsigned bits = 0;
196
197   if (v >= vl)
198     return;
199   while (q > p) {
200     n = U8(*--q);
201     w |= n << bits;
202     bits += 8;
203     if (bits >= MPW_BITS) {
204       *v++ = MPW(w);
205       w = n >> (MPW_BITS - bits + 8);
206       bits -= MPW_BITS;
207       if (v >= vl)
208         return;
209     }
210   }
211   *v++ = w;
212   MPX_ZERO(v, vl);
213 }
214
215 /*----- Logical shifting --------------------------------------------------*/
216
217 /* --- @mpx_lsl@ --- *
218  *
219  * Arguments:   @mpw *dv, *dvl@ = destination vector base and limit
220  *              @const mpw *av, *avl@ = source vector base and limit
221  *              @size_t n@ = number of bit positions to shift by
222  *
223  * Returns:     ---
224  *
225  * Use:         Performs a logical shift left operation on an integer.
226  */
227
228 void mpx_lsl(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl, size_t n)
229 {
230   size_t nw;
231   unsigned nb;
232
233   /* --- Trivial special case --- */
234
235   if (n == 0)
236     MPX_COPY(dv, dvl, av, avl);
237
238   /* --- Single bit shifting --- */
239
240   else if (n == 1) {
241     mpw w = 0;
242     while (av < avl) {
243       mpw t;
244       if (dv >= dvl)
245         goto done;
246       t = *av++;
247       *dv++ = MPW((t << 1) | w);
248       w = t >> (MPW_BITS - 1);
249     }
250     if (dv >= dvl)
251       goto done;
252     *dv++ = MPW(w);
253     MPX_ZERO(dv, dvl);
254     goto done;
255   }
256
257   /* --- Break out word and bit shifts for more sophisticated work --- */
258         
259   nw = n / MPW_BITS;
260   nb = n % MPW_BITS;
261
262   /* --- Handle a shift by a multiple of the word size --- */
263
264   if (nb == 0) {
265     MPX_COPY(dv + nw, dvl, av, avl);
266     memset(dv, 0, MPWS(nw));
267   }
268
269   /* --- And finally the difficult case --- *
270    *
271    * This is a little convoluted, because I have to start from the end and
272    * work backwards to avoid overwriting the source, if they're both the same
273    * block of memory.
274    */
275
276   else {
277     mpw w;
278     size_t nr = MPW_BITS - nb;
279     size_t dvn = dvl - dv;
280     size_t avn = avl - av;
281
282     if (dvn <= nw) {
283       MPX_ZERO(dv, dvl);
284       goto done;
285     }
286
287     if (dvn > avn + nw) {
288       size_t off = avn + nw + 1;
289       MPX_ZERO(dv + off, dvl);
290       dvl = dv + off;
291       w = 0;
292     } else {
293       avl = av + dvn - nw;
294       w = *--avl << nb;
295     }
296
297     while (avl > av) {
298       mpw t = *--avl;
299       *--dvl = (t >> nr) | w;
300       w = t << nb;
301     }
302
303     *--dvl = w;
304     MPX_ZERO(dv, dvl);
305   }
306
307 done:;
308 }
309
310 /* --- @mpx_lsr@ --- *
311  *
312  * Arguments:   @mpw *dv, *dvl@ = destination vector base and limit
313  *              @const mpw *av, *avl@ = source vector base and limit
314  *              @size_t n@ = number of bit positions to shift by
315  *
316  * Returns:     ---
317  *
318  * Use:         Performs a logical shift right operation on an integer.
319  */
320
321 void mpx_lsr(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl, size_t n)
322 {
323   size_t nw;
324   unsigned nb;
325
326   /* --- Trivial special case --- */
327
328   if (n == 0)
329     MPX_COPY(dv, dvl, av, avl);
330
331   /* --- Single bit shifting --- */
332
333   else if (n == 1) {
334     mpw w = *av++ >> 1;
335     while (av < avl) {
336       mpw t;
337       if (dv >= dvl)
338         goto done;
339       t = *av++;
340       *dv++ = MPW((t << (MPW_BITS - 1)) | w);
341       w = t >> 1;
342     }
343     if (dv >= dvl)
344       goto done;
345     *dv++ = MPW(w);
346     MPX_ZERO(dv, dvl);
347     goto done;
348   }
349
350   /* --- Break out word and bit shifts for more sophisticated work --- */
351
352   nw = n / MPW_BITS;
353   nb = n % MPW_BITS;
354
355   /* --- Handle a shift by a multiple of the word size --- */
356
357   if (nb == 0)
358     MPX_COPY(dv, dvl, av + nw, avl);
359
360   /* --- And finally the difficult case --- */
361
362   else {
363     mpw w;
364     size_t nr = MPW_BITS - nb;
365
366     av += nw;
367     w = *av++;
368     while (av < avl) {
369       mpw t;
370       if (dv >= dvl)
371         goto done;
372       t = *av++;
373       *dv++ = MPW((w >> nb) | (t << nr));
374       w = t;
375     }
376     if (dv < dvl) {
377       *dv++ = MPW(w >> nb);
378       MPX_ZERO(dv, dvl);
379     }
380   }
381
382 done:;
383 }
384
385 /*----- Unsigned arithmetic -----------------------------------------------*/
386
387 /* --- @mpx_2c@ --- *
388  *
389  * Arguments:   @mpw *dv, *dvl@ = destination vector
390  *              @const mpw *v, *vl@ = source vector
391  *
392  * Returns:     ---
393  *
394  * Use:         Calculates the two's complement of @v@.
395  */
396
397 void mpx_2c(mpw *dv, mpw *dvl, const mpw *v, const mpw *vl)
398 {
399   mpw c = 0;
400   while (dv < dvl && v < vl)
401     *dv++ = c = MPW(~*v++);
402   if (dv < dvl) {
403     if (c > MPW_MAX / 2)
404       c = MPW(~0);
405     while (dv < dvl)
406       *dv++ = c;
407   }
408   MPX_UADDN(dv, dvl, 1);
409 }
410
411 /* --- @mpx_ucmp@ --- *
412  *
413  * Arguments:   @const mpw *av, *avl@ = first argument vector base and limit
414  *              @const mpw *bv, *bvl@ = second argument vector base and limit
415  *
416  * Returns:     Less than, equal to, or greater than zero depending on
417  *              whether @a@ is less than, equal to or greater than @b@,
418  *              respectively.
419  *
420  * Use:         Performs an unsigned integer comparison.
421  */
422
423 int mpx_ucmp(const mpw *av, const mpw *avl, const mpw *bv, const mpw *bvl)
424 {
425   MPX_SHRINK(av, avl);
426   MPX_SHRINK(bv, bvl);
427
428   if (avl - av > bvl - bv)
429     return (+1);
430   else if (avl - av < bvl - bv)
431     return (-1);
432   else while (avl > av) {
433     mpw a = *--avl, b = *--bvl;
434     if (a > b)
435       return (+1);
436     else if (a < b)
437       return (-1);
438   }
439   return (0);
440 }
441   
442 /* --- @mpx_uadd@ --- *
443  *
444  * Arguments:   @mpw *dv, *dvl@ = destination vector base and limit
445  *              @const mpw *av, *avl@ = first addend vector base and limit
446  *              @const mpw *bv, *bvl@ = second addend vector base and limit
447  *
448  * Returns:     ---
449  *
450  * Use:         Performs unsigned integer addition.  If the result overflows
451  *              the destination vector, high-order bits are discarded.  This
452  *              means that two's complement addition happens more or less for
453  *              free, although that's more a side-effect than anything else.
454  *              The result vector may be equal to either or both source
455  *              vectors, but may not otherwise overlap them.
456  */
457
458 void mpx_uadd(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl,
459               const mpw *bv, const mpw *bvl)
460 {
461   mpw c = 0;
462
463   while (av < avl || bv < bvl) {
464     mpw a, b;
465     mpd x;
466     if (dv >= dvl)
467       return;
468     a = (av < avl) ? *av++ : 0;
469     b = (bv < bvl) ? *bv++ : 0;
470     x = (mpd)a + (mpd)b + c;
471     *dv++ = MPW(x);
472     c = x >> MPW_BITS;
473   }
474   if (dv < dvl) {
475     *dv++ = c;
476     MPX_ZERO(dv, dvl);
477   }
478 }
479
480 /* --- @mpx_usub@ --- *
481  *
482  * Arguments:   @mpw *dv, *dvl@ = destination vector base and limit
483  *              @const mpw *av, *avl@ = first argument vector base and limit
484  *              @const mpw *bv, *bvl@ = second argument vector base and limit
485  *
486  * Returns:     ---
487  *
488  * Use:         Performs unsigned integer subtraction.  If the result
489  *              overflows the destination vector, high-order bits are
490  *              discarded.  This means that two's complement subtraction
491  *              happens more or less for free, althuogh that's more a side-
492  *              effect than anything else.  The result vector may be equal to
493  *              either or both source vectors, but may not otherwise overlap
494  *              them.
495  */
496
497 void mpx_usub(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl,
498               const mpw *bv, const mpw *bvl)
499 {
500   mpw c = 0;
501
502   while (av < avl || bv < bvl) {
503     mpw a, b;
504     mpd x;
505     if (dv >= dvl)
506       return;
507     a = (av < avl) ? *av++ : 0;
508     b = (bv < bvl) ? *bv++ : 0;
509     x = (mpd)a - (mpd)b - c;
510     *dv++ = MPW(x);
511     if (x >> MPW_BITS)
512       c = 1;
513     else
514       c = 0;
515   }
516   if (c)
517     c = MPW_MAX;
518   while (dv < dvl)
519     *dv++ = c;
520 }
521
522 /* --- @mpx_umul@ --- *
523  *
524  * Arguments:   @mpw *dv, *dvl@ = destination vector base and limit
525  *              @const mpw *av, *avl@ = multiplicand vector base and limit
526  *              @const mpw *bv, *bvl@ = multiplier vector base and limit
527  *
528  * Returns:     ---
529  *
530  * Use:         Performs unsigned integer multiplication.  If the result
531  *              overflows the desination vector, high-order bits are
532  *              discarded.  The result vector may not overlap the argument
533  *              vectors in any way.
534  */
535
536 void mpx_umul(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl,
537               const mpw *bv, const mpw *bvl)
538 {
539   /* --- This is probably worthwhile on a multiply --- */
540
541   MPX_SHRINK(av, avl);
542   MPX_SHRINK(bv, bvl);
543
544   /* --- Deal with a multiply by zero --- */
545   
546   if (bv == bvl) {
547     MPX_ZERO(dv, dvl);
548     return;
549   }
550
551   /* --- Do the initial multiply and initialize the accumulator --- */
552
553   MPX_UMULN(dv, dvl, av, avl, *bv++);
554
555   /* --- Do the remaining multiply/accumulates --- */
556
557   while (dv < dvl && bv < bvl) {
558     mpw m = *bv++;
559     mpw c = 0;
560     const mpw *avv = av;
561     mpw *dvv = ++dv;
562
563     while (avv < avl) {
564       mpd x;
565       if (dvv >= dvl)
566         goto next;
567       x = (mpd)*dvv + (mpd)m * (mpd)*avv++ + c;
568       *dvv++ = MPW(x);
569       c = x >> MPW_BITS;
570     }
571     MPX_UADDN(dvv, dvl, c);
572   next:;
573   }
574 }
575
576 /* --- @mpx_usqr@ --- *
577  *
578  * Arguments:   @mpw *dv, *dvl@ = destination vector base and limit
579  *              @const mpw *av, *av@ = source vector base and limit
580  *
581  * Returns:     ---
582  *
583  * Use:         Performs unsigned integer squaring.  The result vector must
584  *              not overlap the source vector in any way.
585  */
586
587 void mpx_usqr(mpw *dv, mpw *dvl, const mpw *av, const mpw *avl)
588 {
589   MPX_ZERO(dv, dvl);
590
591   /* --- Main loop --- */
592
593   while (av < avl) {
594     const mpw *avv = av;
595     mpw *dvv = dv;
596     mpw a = *av;
597     mpd c;
598
599     /* --- Stop if I've run out of destination --- */
600
601     if (dvv >= dvl)
602       break;
603
604     /* --- Work out the square at this point in the proceedings --- */
605
606     {
607       mpd x = (mpd)a * (mpd)a + *dvv;
608       *dvv++ = MPW(x);
609       c = MPW(x >> MPW_BITS);
610     }
611
612     /* --- Now fix up the rest of the vector upwards --- */
613
614     avv++;
615     while (dvv < dvl && avv < avl) {
616       mpd x = (mpd)a * (mpd)*avv++;
617       mpd y = ((x << 1) & MPW_MAX) + c + *dvv;
618       c = (x >> (MPW_BITS - 1)) + (y >> MPW_BITS);
619       *dvv++ = MPW(y);
620     }
621     while (dvv < dvl && c) {
622       mpd x = c + *dvv;
623       *dvv++ = MPW(x);
624       c = x >> MPW_BITS;
625     }
626
627     /* --- Get ready for the next round --- */
628
629     av++;
630     dv += 2;
631   }
632 }
633
634 /* --- @mpx_udiv@ --- *
635  *
636  * Arguments:   @mpw *qv, *qvl@ = quotient vector base and limit
637  *              @mpw *rv, *rvl@ = dividend/remainder vector base and limit
638  *              @const mpw *dv, *dvl@ = divisor vector base and limit
639  *              @mpw *sv, *svl@ = scratch workspace
640  *
641  * Returns:     ---
642  *
643  * Use:         Performs unsigned integer division.  If the result overflows
644  *              the quotient vector, high-order bits are discarded.  (Clearly
645  *              the remainder vector can't overflow.)  The various vectors
646  *              may not overlap in any way.  Yes, I know it's a bit odd
647  *              requiring the dividend to be in the result position but it
648  *              does make some sense really.  The remainder must have
649  *              headroom for at least two extra words.  The scratch space
650  *              must be at least one word larger than the divisor.
651  */
652
653 void mpx_udiv(mpw *qv, mpw *qvl, mpw *rv, mpw *rvl,
654               const mpw *dv, const mpw *dvl,
655               mpw *sv, mpw *svl)
656 {
657   unsigned norm = 0;
658   size_t scale;
659   mpw d, dd;
660
661   /* --- Initialize the quotient --- */
662
663   MPX_ZERO(qv, qvl);
664
665   /* --- Perform some sanity checks --- */
666
667   MPX_SHRINK(dv, dvl);
668   assert(((void)"division by zero in mpx_udiv", dv < dvl));
669
670   /* --- Normalize the divisor --- *
671    *
672    * The algorithm requires that the divisor be at least two digits long.
673    * This is easy to fix.
674    */
675
676   {
677     unsigned b;
678
679     d = dvl[-1];
680     for (b = MPW_BITS / 2; b; b >>= 1) {
681       if (d < (MPW_MAX >> b)) {
682         d <<= b;
683         norm += b;
684       }
685     }
686     if (dv + 1 == dvl)
687       norm += MPW_BITS;
688   }
689
690   /* --- Normalize the dividend/remainder to match --- */
691
692   if (norm) {
693     mpx_lsl(rv, rvl, rv, rvl, norm);
694     mpx_lsl(sv, svl, dv, dvl, norm);
695     dv = sv;
696     dvl = svl;
697     MPX_SHRINK(dv, dvl);
698   }
699
700   MPX_SHRINK(rv, rvl);
701   d = dvl[-1];
702   dd = dvl[-2];
703
704   /* --- Work out the relative scales --- */
705
706   {
707     size_t rvn = rvl - rv;
708     size_t dvn = dvl - dv;
709
710     /* --- If the divisor is clearly larger, notice this --- */
711
712     if (dvn > rvn) {
713       mpx_lsr(rv, rvl, rv, rvl, norm);
714       return;
715     }
716
717     scale = rvn - dvn;
718   }
719
720   /* --- Calculate the most significant quotient digit --- *
721    *
722    * Because the divisor has its top bit set, this can only happen once.  The
723    * pointer arithmetic is a little contorted, to make sure that the
724    * behaviour is defined.
725    */
726
727   if (MPX_UCMP(rv + scale, rvl, >=, dv, dvl)) {
728     mpx_usub(rv + scale, rvl, rv + scale, rvl, dv, dvl);
729     if (qvl - qv > scale)
730       qv[scale] = 1;
731   }
732
733   /* --- Now for the main loop --- */
734
735   {
736     mpw *rvv = rvl - 2;
737
738     while (scale) {
739       mpw q;
740       mpd rh;
741
742       /* --- Get an estimate for the next quotient digit --- */
743
744       mpw r = rvv[1];
745       mpw rr = rvv[0];
746       mpw rrr = *--rvv;
747
748       scale--;
749       rh = ((mpd)r << MPW_BITS) | rr;
750       if (r == d)
751         q = MPW_MAX;
752       else
753         q = MPW(rh / d);
754
755       /* --- Refine the estimate --- */
756
757       {
758         mpd yh = (mpd)d * q;
759         mpd yl = (mpd)dd * q;
760
761         if (yl > MPW_MAX) {
762           yh += yl >> MPW_BITS;
763           yl &= MPW_MAX;
764         }
765
766         while (yh > rh || (yh == rh && yl > rrr)) {
767           q--;
768           yh -= d;
769           if (yl < dd) {
770             yh++;
771             yl += MPW_MAX;
772           }
773           yl -= dd;
774         }
775       }
776
777       /* --- Remove a chunk from the dividend --- */
778
779       {
780         mpw *svv;
781         const mpw *dvv;
782         mpw mc = 0, sc = 0;
783
784         /* --- Calculate the size of the chunk --- *
785          *
786          * This does the whole job of calculating @r >> scale - qd@.
787          */
788
789         for (svv = rv + scale, dvv = dv;
790              dvv < dvl && svv < rvl;
791              svv++, dvv++) {
792           mpd x = (mpd)*dvv * (mpd)q + mc;
793           mc = x >> MPW_BITS;
794           x = (mpd)*svv - MPW(x) - sc;
795           *svv = MPW(x);
796           if (x >> MPW_BITS)
797             sc = 1;
798           else
799             sc = 0;
800         }
801
802         if (svv < rvl) {
803           mpd x = (mpd)*svv - mc - sc;
804           *svv++ = MPW(x);
805           if (x >> MPW_BITS)
806             sc = MPW_MAX;
807           else
808             sc = 0;
809           while (svv < rvl)
810             *svv++ = sc;
811         }
812
813         /* --- Fix if the quotient was too large --- *
814          *
815          * This doesn't seem to happen very often.
816          */
817
818         if (rvl[-1] > MPW_MAX / 2) {
819           mpx_uadd(rv + scale, rvl, rv + scale, rvl, dv, dvl);
820           q--;
821         }
822       }
823
824       /* --- Done for another iteration --- */
825
826       if (qvl - qv > scale)
827         qv[scale] = q;
828       r = rr;
829       rr = rrr;
830     }
831   }
832
833   /* --- Now fiddle with unnormalizing and things --- */
834
835   mpx_lsr(rv, rvl, rv, rvl, norm);
836 }
837
838 /*----- That's all, folks -------------------------------------------------*/