1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_nbexterns.cpp -- External functions for both sc_signed and sc_unsigned
23                      classes. These functions work on two parameters u and
24                      v, and copy the result to the first parameter u. This
25                      is also the reason that they are suffixed with _on_help.
26
27  Original Author: Ali Dasdan, Synopsys, Inc.
28
29 *****************************************************************************/
30
31/*****************************************************************************
32
33  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
34  changes you are making here.
35
36      Name, Affiliation, Date:
37  Description of Modification:
38
39 *****************************************************************************/
40
41
42// $Log: sc_nbexterns.cpp,v $
43// Revision 1.2  2011/02/18 20:19:15  acg
44//  Andy Goodrich: updating Copyright notice.
45//
46// Revision 1.1.1.1  2006/12/15 20:20:05  acg
47// SystemC 2.3
48//
49// Revision 1.3  2006/01/13 18:49:32  acg
50// Added $Log command so that CVS check in comments are reproduced in the
51// source.
52//
53
54#include "systemc/ext/dt/int/sc_nbexterns.hh"
55#include "systemc/ext/utils/functions.hh"
56
57namespace sc_dt
58{
59
60// ----------------------------------------------------------------------------
61//  SECTION: External functions for PLUS operators.
62// ----------------------------------------------------------------------------
63
64// Handles the cases 3 and 4 and returns the result in u.
65void
66add_on_help(small_type &us, int /* unb */, int und, sc_digit *ud,
67            small_type vs, int /* vnb */, int vnd, const sc_digit *vd)
68{
69    vnd = vec_skip_leading_zeros(vnd, vd);
70
71    if (us == vs) {  // case 3
72        if (und >= vnd)
73            vec_add_on(und, ud, vnd, vd);
74        else
75            vec_add_on2(und, ud, vnd, vd);
76
77    } else {  // case 4
78        // vec_cmp expects that und is the number of non-zero digits in ud.
79        int new_und = vec_skip_leading_zeros(und, ud);
80        int cmp_res = vec_cmp(new_und, ud, vnd, vd);
81
82        if (cmp_res == 0) { // u == v
83            us = SC_ZERO;
84            vec_zero(und, ud);
85            return;
86        }
87
88        if (cmp_res > 0) { // u > v
89            vec_sub_on(und, ud, vnd, vd);
90        } else { // u < v
91            us = -us;
92            vec_sub_on2(und, ud, vnd, vd);
93        }
94    }
95}
96
97
98// ----------------------------------------------------------------------------
99
100/*
101
102mul_on_help_signed and mul_on_help_unsigned have the same body except
103that CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and
104unsigned, respectively.  This comment also applies to the
105signed/unsigned versions of div_on_help and mod_on_help. It is
106possible to take COPY_DIGITS out of these functions and create a
107single version of each of these helper functions; however, this will
108impose an onverhead on performance. In the versions below, any change
109in the signed version of a helper function must be carried to a
110corresponding change in the unsigned verion of the same function or
111vice versa.
112
113*/
114
115
116// ----------------------------------------------------------------------------
117//  SECTION: External functions of MULTIPLICATION operators.
118// ----------------------------------------------------------------------------
119
120void
121mul_on_help_signed(small_type &us, int unb, int und, sc_digit *ud,
122                   int vnb, int vnd, const sc_digit *vd)
123{
124#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
125#define COPY_DIGITS copy_digits_signed
126    { // Body of mul_on_help
127        int old_und = und;
128
129        und = vec_skip_leading_zeros(und, ud);
130        vnd = vec_skip_leading_zeros(vnd, vd);
131
132        sc_digit ud0 = (*ud);
133        sc_digit vd0 = (*vd);
134
135        if ((vnd == 1) && (vd0 == 1)) {
136            us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
137            return;
138        }
139
140        if ((und == 1) && (ud0 == 1)) {
141            COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
142            return;
143        }
144
145        if ((und == 1) && (vnd == 1) &&
146            (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
147
148            sc_digit d = ud0 * vd0;
149            COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
150            return;
151        }
152
153        int nd = und + vnd;
154
155#ifdef SC_MAX_NBITS
156        sc_digit d[MAX_NDIGITS];
157#else
158        sc_digit *d = new sc_digit[nd];
159#endif
160
161        vec_zero(nd, d);
162
163        if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
164            vec_mul_small(vnd, vd, ud0, d);
165        else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
166            vec_mul_small(und, ud, vd0, d);
167        else if (vnd < und)
168            vec_mul(und, ud, vnd, vd, d);
169        else
170            vec_mul(vnd, vd, und, ud, d);
171
172        COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
173
174#ifndef SC_MAX_NBITS
175        delete [] d;
176#endif
177    }
178#undef COPY_DIGITS
179#undef CONVERT_SM_to_2C_to_SM
180}
181
182
183void
184mul_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud,
185                     int vnb, int vnd, const sc_digit *vd)
186{
187#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
188#define COPY_DIGITS copy_digits_unsigned
189    { // Body of mul_on_help
190        int old_und = und;
191
192        und = vec_skip_leading_zeros(und, ud);
193        vnd = vec_skip_leading_zeros(vnd, vd);
194
195        sc_digit ud0 = (*ud);
196        sc_digit vd0 = (*vd);
197
198        if ((vnd == 1) && (vd0 == 1)) {
199            us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
200            return;
201        }
202
203        if ((und == 1) && (ud0 == 1)) {
204            COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
205            return;
206        }
207
208        if ((und == 1) && (vnd == 1) &&
209            (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
210
211            sc_digit d = ud0 * vd0;
212            COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
213            return;
214        }
215
216        int nd = und + vnd;
217
218#ifdef SC_MAX_NBITS
219        sc_digit d[MAX_NDIGITS];
220#else
221        sc_digit *d = new sc_digit[nd];
222#endif
223
224        vec_zero(nd, d);
225
226        if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
227            vec_mul_small(vnd, vd, ud0, d);
228        else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
229            vec_mul_small(und, ud, vd0, d);
230        else if (vnd < und)
231            vec_mul(und, ud, vnd, vd, d);
232        else
233            vec_mul(vnd, vd, und, ud, d);
234
235        COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
236
237#ifndef SC_MAX_NBITS
238        delete [] d;
239#endif
240      }
241#undef COPY_DIGITS
242#undef CONVERT_SM_to_2C_to_SM
243}
244
245
246// ----------------------------------------------------------------------------
247//  SECTION: External functions for DIVISION operators.
248// ----------------------------------------------------------------------------
249
250void
251div_on_help_signed(small_type &us, int unb, int und, sc_digit *ud,
252                   int vnb, int vnd, const sc_digit *vd)
253{
254#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
255#define COPY_DIGITS copy_digits_signed
256    {  // Body of div_on_help
257        int old_und = und;
258
259        und = vec_skip_leading_zeros(und, ud);
260        vnd = vec_skip_leading_zeros(vnd, vd);
261
262        int cmp_res = vec_cmp(und, ud, vnd, vd);
263
264        if (cmp_res < 0) { // u < v => u / v = 0 - case 4
265            us = SC_ZERO;
266            vec_zero(old_und, ud);
267            return;
268        }
269
270        sc_digit vd0 = (*vd);
271
272        if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1)) {
273            us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
274            return;
275        }
276
277        // One extra digit for d is allocated to simplify vec_div_*().
278        int nd = sc_max(und, vnd) + 1;
279
280#ifdef SC_MAX_NBITS
281        sc_digit d[MAX_NDIGITS + 1];
282#else
283        sc_digit *d = new sc_digit[nd];
284#endif
285
286        vec_zero(nd, d);
287
288        // u = v => u / v = 1 - case 3
289        if (cmp_res == 0)
290            d[0] = 1;
291        else if ((vnd == 1) && (und == 1))
292            d[0] = (*ud) / vd0;
293        else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
294            vec_div_small(und, ud, vd0, d);
295        else
296            vec_div_large(und, ud, vnd, vd, d);
297
298        COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
299
300#ifndef SC_MAX_NBITS
301        delete [] d;
302#endif
303    }
304#undef COPY_DIGITS
305#undef CONVERT_SM_to_2C_to_SM
306}
307
308
309void
310div_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud,
311                     int vnb, int vnd, const sc_digit *vd)
312{
313#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
314#define COPY_DIGITS copy_digits_unsigned
315    { // Body of div_on_help
316        int old_und = und;
317
318        und = vec_skip_leading_zeros(und, ud);
319        vnd = vec_skip_leading_zeros(vnd, vd);
320
321        int cmp_res = vec_cmp(und, ud, vnd, vd);
322
323        if (cmp_res < 0) { // u < v => u / v = 0 - case 4
324            us = SC_ZERO;
325            vec_zero(old_und, ud);
326            return;
327        }
328
329        sc_digit vd0 = (*vd);
330
331        if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1))  {
332            us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
333            return;
334        }
335
336        // One extra digit for d is allocated to simplify vec_div_*().
337        int nd = sc_max(und, vnd) + 1;
338
339#ifdef SC_MAX_NBITS
340        sc_digit d[MAX_NDIGITS + 1];
341#else
342        sc_digit *d = new sc_digit[nd];
343#endif
344
345        vec_zero(nd, d);
346
347        // u = v => u / v = 1 - case 3
348        if (cmp_res == 0)
349            d[0] = 1;
350        else if ((vnd == 1) && (und == 1))
351            d[0] = (*ud) / vd0;
352        else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
353            vec_div_small(und, ud, vd0, d);
354        else
355            vec_div_large(und, ud, vnd, vd, d);
356
357        COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
358
359#ifndef SC_MAX_NBITS
360        delete [] d;
361#endif
362      }
363#undef COPY_DIGITS
364#undef CONVERT_SM_to_2C_to_SM
365}
366
367
368// ----------------------------------------------------------------------------
369//  SECTION: External functions for MOD operators.
370// ----------------------------------------------------------------------------
371
372void
373mod_on_help_signed(small_type &us, int unb, int und, sc_digit *ud,
374                   int /* vnb */, int vnd, const sc_digit *vd)
375{
376#define COPY_DIGITS copy_digits_signed
377    { // Body of mod_on_help
378        int old_und = und;
379
380        und = vec_skip_leading_zeros(und, ud);
381        vnd = vec_skip_leading_zeros(vnd, vd);
382
383        int cmp_res = vec_cmp(und, ud, vnd, vd);
384
385        // u < v => u % v = u - case 4
386        if (cmp_res < 0)
387            return;
388
389        // u = v => u % v = 0 - case 3
390        if (cmp_res == 0) {
391            us = SC_ZERO;
392            vec_zero(old_und, ud);
393            return;
394        }
395        // else if u > v - case 5
396
397        sc_digit vd0 = (*vd);
398
399        if ((vnd == 1) && (vd0 == 1)) {
400            us = SC_ZERO;
401            vec_zero(old_und, ud);
402            return;
403        }
404
405        // One extra digit for d is allocated to simplify vec_div_*().
406        int nd = sc_max(und, vnd) + 1;
407
408#ifdef SC_MAX_NBITS
409        sc_digit d[MAX_NDIGITS + 1];
410#else
411        sc_digit *d = new sc_digit[nd];
412#endif
413
414        vec_zero(nd, d);
415
416        if ((vnd == 1) && (und == 1))
417            d[0] = (*ud) % vd0;
418        if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
419            d[0] = vec_rem_small(und, ud, vd0);
420        else
421            vec_rem_large(und, ud, vnd, vd, d);
422
423        us = check_for_zero(us, nd - 1, d);
424
425        if (us == SC_ZERO)
426            vec_zero(old_und, ud);
427        else
428            COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
429
430#ifndef SC_MAX_NBITS
431        delete [] d;
432#endif
433    }
434#undef COPY_DIGITS
435}
436
437
438void
439mod_on_help_unsigned(small_type &us, int unb, int und, sc_digit *ud,
440                     int /* vnb */, int vnd, const sc_digit *vd)
441{
442#define COPY_DIGITS copy_digits_unsigned
443    { // Body of mod_on_help
444        int old_und = und;
445
446        und = vec_skip_leading_zeros(und, ud);
447        vnd = vec_skip_leading_zeros(vnd, vd);
448
449        int cmp_res = vec_cmp(und, ud, vnd, vd);
450
451        // u < v => u % v = u - case 4
452        if (cmp_res < 0)
453            return;
454
455        // u = v => u % v = 0 - case 3
456        if (cmp_res == 0) {
457            us = SC_ZERO;
458            vec_zero(old_und, ud);
459            return;
460        }
461
462        // else if u > v - case 5
463
464        sc_digit vd0 = (*vd);
465
466        if ((vnd == 1) && (vd0 == 1)) {
467            us = SC_ZERO;
468            vec_zero(old_und, ud);
469            return;
470        }
471
472        // One extra digit for d is allocated to simplify vec_div_*().
473        int nd = sc_max(und, vnd) + 1;
474
475#ifdef SC_MAX_NBITS
476        sc_digit d[MAX_NDIGITS + 1];
477#else
478        sc_digit *d = new sc_digit[nd];
479#endif
480
481        vec_zero(nd, d);
482
483        if ((vnd == 1) && (und == 1))
484            d[0] = (*ud) % vd0;
485        if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
486            d[0] = vec_rem_small(und, ud, vd0);
487        else
488            vec_rem_large(und, ud, vnd, vd, d);
489
490        us = check_for_zero(us, nd - 1, d);
491
492        if (us == SC_ZERO)
493            vec_zero(old_und, ud);
494        else
495            COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
496
497#ifndef SC_MAX_NBITS
498        delete [] d;
499#endif
500    }
501#undef COPY_DIGITS
502}
503
504
505// ----------------------------------------------------------------------------
506//  SECTION: External functions for AND operators.
507// ----------------------------------------------------------------------------
508
509// Handles the cases 2-5 and returns the result in u.
510void
511and_on_help(small_type us, int /* unb */, int und, sc_digit *ud,
512            small_type vs, int /* vnb */, int vnd, const sc_digit *vd)
513{
514    sc_digit *x = ud;
515    const sc_digit *y = vd;
516    int xnd = und;
517    int ynd = vnd;
518
519    // Truncate y.
520    if (xnd < ynd)
521        ynd = xnd;
522
523    const sc_digit *xend = (x + xnd);
524    const sc_digit *yend = (y + ynd);
525
526    // x is longer than y.
527    small_type s = mul_signs(us, vs);
528
529    if (s > 0) {
530        if (us > 0) { // case 2
531            while (y < yend)
532                (*x++) &= (*y++);
533            while (x < xend)
534                (*x++) = 0;
535        } else { // case 3
536            sc_digit xcarry = 1;
537            sc_digit ycarry = 1;
538            while (y < yend) {
539                xcarry += (~(*x) & DIGIT_MASK);
540                ycarry += (~(*y++) & DIGIT_MASK);
541                (*x++) = (xcarry & ycarry) & DIGIT_MASK;
542                xcarry >>= BITS_PER_DIGIT;
543                ycarry >>= BITS_PER_DIGIT;
544            }
545            while (x < xend) {
546                xcarry += (~(*x) & DIGIT_MASK);
547                ycarry += DIGIT_MASK;
548                (*x++) = (xcarry & ycarry) & DIGIT_MASK;
549                xcarry >>= BITS_PER_DIGIT;
550                ycarry >>= BITS_PER_DIGIT;
551            }
552
553        }
554    } else {
555        if (us > 0) { // case 4
556            sc_digit ycarry = 1;
557            while (y < yend) {
558                ycarry += (~(*y++) & DIGIT_MASK);
559                (*x++) &= ycarry & DIGIT_MASK;
560                ycarry >>= BITS_PER_DIGIT;
561            }
562            while (x < xend) {
563                ycarry += DIGIT_MASK;
564                (*x++) &= ycarry & DIGIT_MASK;
565                ycarry >>= BITS_PER_DIGIT;
566            }
567        } else { // case 5
568            sc_digit xcarry = 1;
569            while (y < yend) {
570                xcarry += (~(*x) & DIGIT_MASK);
571                (*x++) = (xcarry & (*y++)) & DIGIT_MASK;
572                xcarry >>= BITS_PER_DIGIT;
573            }
574            while (x < xend)
575                (*x++) = 0;
576        }
577    }
578}
579
580
581// ----------------------------------------------------------------------------
582//  SECTION: External functions for OR operators.
583// ----------------------------------------------------------------------------
584
585// Handles the cases 3-5 and returns the result in u.
586void
587or_on_help(small_type us, int /* unb */, int und, sc_digit *ud,
588           small_type vs, int /* vnb */, int vnd, const sc_digit *vd)
589{
590    sc_digit *x = ud;
591    const sc_digit *y = vd;
592    int xnd = und;
593    int ynd = vnd;
594
595    if (xnd < ynd)
596        ynd = xnd;
597
598    const sc_digit *xend = (x + xnd);
599    const sc_digit *yend = (y + ynd);
600
601    // x is longer than y.
602    small_type s = mul_signs(us, vs);
603
604    if (s > 0) {
605        if (us > 0) { // case 3
606            while (y < yend)
607                (*x++) |= (*y++);
608            // No change for the rest of x.
609        } else { // case 4
610            sc_digit xcarry = 1;
611            sc_digit ycarry = 1;
612            while (y < yend) {
613                xcarry += (~(*x) & DIGIT_MASK);
614                ycarry += (~(*y++) & DIGIT_MASK);
615                (*x++) = (xcarry | ycarry) & DIGIT_MASK;
616                xcarry >>= BITS_PER_DIGIT;
617                ycarry >>= BITS_PER_DIGIT;
618            }
619            while (x < xend) {
620                xcarry += (~(*x) & DIGIT_MASK);
621                ycarry += DIGIT_MASK;
622                (*x++) = (xcarry | ycarry) & DIGIT_MASK;
623                xcarry >>= BITS_PER_DIGIT;
624                ycarry >>= BITS_PER_DIGIT;
625            }
626        }
627    } else {
628        if (us > 0) { // case 5
629            sc_digit ycarry = 1;
630            while (y < yend) {
631                ycarry += (~(*y++) & DIGIT_MASK);
632                (*x) = ((*x) | ycarry) & DIGIT_MASK;
633                x++;
634                ycarry >>= BITS_PER_DIGIT;
635            }
636            while (x < xend) {
637                ycarry += DIGIT_MASK;
638                (*x) = ((*x) | ycarry) & DIGIT_MASK;
639                x++;
640                ycarry >>= BITS_PER_DIGIT;
641            }
642        } else { // case 6
643            sc_digit xcarry = 1;
644            while (y < yend) {
645                xcarry += (~(*x) & DIGIT_MASK);
646                (*x++) = (xcarry | (*y++)) & DIGIT_MASK;
647                xcarry >>= BITS_PER_DIGIT;
648            }
649            while (x < xend) {
650                xcarry += (~(*x) & DIGIT_MASK);
651                (*x++) = xcarry & DIGIT_MASK;
652                xcarry >>= BITS_PER_DIGIT;
653            }
654        }
655    }
656}
657
658
659// ----------------------------------------------------------------------------
660//  SECTION: External functions for XOR operators.
661// ----------------------------------------------------------------------------
662
663// Handles the cases 3-5 and returns the result in u.
664void
665xor_on_help(small_type us, int /* unb */, int und, sc_digit *ud,
666            small_type vs, int /* vnb */, int vnd, const sc_digit *vd)
667{
668    sc_digit *x = ud;
669    const sc_digit *y = vd;
670    int xnd = und;
671    int ynd = vnd;
672
673    if (xnd < ynd)
674        ynd = xnd;
675
676    const sc_digit *xend = (x + xnd);
677    const sc_digit *yend = (y + ynd);
678
679    // x is longer than y.
680    small_type s = mul_signs(us, vs);
681
682    if (s > 0) {
683        if (us > 0) { // case 3
684            while (y < yend) {
685                (*x) = ((*x) ^ (*y)) & DIGIT_MASK;
686                x++;
687                y++;
688            }
689            // No change for the rest of x.
690        } else { // case 4
691            sc_digit xcarry = 1;
692            sc_digit ycarry = 1;
693            while (y < yend) {
694                xcarry += (~(*x) & DIGIT_MASK);
695                ycarry += (~(*y++) & DIGIT_MASK);
696                (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
697                xcarry >>= BITS_PER_DIGIT;
698                ycarry >>= BITS_PER_DIGIT;
699            }
700            while (x < xend) {
701                xcarry += (~(*x) & DIGIT_MASK);
702                ycarry += DIGIT_MASK;
703                (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
704                xcarry >>= BITS_PER_DIGIT;
705                ycarry >>= BITS_PER_DIGIT;
706            }
707        }
708    } else {
709        if (us > 0) { // case 5
710            sc_digit ycarry = 1;
711            while (y < yend) {
712                ycarry += (~(*y++) & DIGIT_MASK);
713                (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
714                x++;
715                ycarry >>= BITS_PER_DIGIT;
716            }
717            while (x < xend) {
718                ycarry += DIGIT_MASK;
719                (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
720                x++;
721                ycarry >>= BITS_PER_DIGIT;
722            }
723        } else { // case 6
724            sc_digit xcarry = 1;
725            while (y < yend) {
726                xcarry += (~(*x) & DIGIT_MASK);
727                (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK;
728                xcarry >>= BITS_PER_DIGIT;
729            }
730            while (x < xend) {
731                xcarry += (~(*x) & DIGIT_MASK);
732                (*x++) = xcarry & DIGIT_MASK;
733                xcarry >>= BITS_PER_DIGIT;
734            }
735        }
736    }
737}
738
739} // namespace sc_dt
740