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 "sysc/datatypes/int/sc_nbexterns.h"
55#include "sysc/kernel/sc_macros.h"
56
57
58namespace sc_dt
59{
60
61// ----------------------------------------------------------------------------
62//  SECTION: External functions for PLUS operators.
63// ----------------------------------------------------------------------------
64
65// Handles the cases 3 and 4 and returns the result in u.
66void
67add_on_help(small_type &us, int /* unb */, int und,
68            sc_digit *ud,
69            small_type vs, int /* vnb */, int vnd,
70            const sc_digit *vd)
71{
72
73  vnd = vec_skip_leading_zeros(vnd, vd);
74
75  if (us == vs) {  // case 3
76
77    if (und >= vnd)
78      vec_add_on(und, ud, vnd, vd);
79    else
80      vec_add_on2(und, ud, vnd, vd);
81
82  }
83  else {  // case 4
84
85    // vec_cmp expects that und is the number of non-zero digits in ud.
86    int new_und = vec_skip_leading_zeros(und, ud);
87    int cmp_res = vec_cmp(new_und, ud, vnd, vd);
88
89    if (cmp_res == 0)  { // u == v
90      us = SC_ZERO;
91      vec_zero(und, ud);
92      return;
93    }
94
95    if (cmp_res > 0) // u > v
96      vec_sub_on(und, ud, vnd, vd);
97
98    else { // u < v
99      us = -us;
100      vec_sub_on2(und, ud, vnd, vd);
101    }
102
103  }
104}
105
106
107// ----------------------------------------------------------------------------
108
109/*
110
111mul_on_help_signed and mul_on_help_unsigned have the same body except
112that CONVERT_SM_to_2C_to_SM and COPY_DIGITS are defined for signed and
113unsigned, respectively.  This comment also applies to the
114signed/unsigned versions of div_on_help and mod_on_help. It is
115possible to take COPY_DIGITS out of these functions and create a
116single version of each of these helper functions; however, this will
117impose an onverhead on performance. In the versions below, any change
118in the signed version of a helper function must be carried to a
119corresponding change in the unsigned verion of the same function or
120vice versa.
121
122*/
123
124
125// ----------------------------------------------------------------------------
126//  SECTION: External functions of MULTIPLICATION operators.
127// ----------------------------------------------------------------------------
128
129void
130mul_on_help_signed(small_type &us,
131                   int unb, int und,
132                   sc_digit *ud,
133                   int vnb, int vnd,
134                   const sc_digit *vd)
135{
136#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
137#define COPY_DIGITS copy_digits_signed
138
139  {  // Body of mul_on_help
140
141    int old_und = und;
142
143    und = vec_skip_leading_zeros(und, ud);
144    vnd = vec_skip_leading_zeros(vnd, vd);
145
146    sc_digit ud0 = (*ud);
147    sc_digit vd0 = (*vd);
148
149    if ((vnd == 1) && (vd0 == 1)) {
150      us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
151      return;
152    }
153
154    if ((und == 1) && (ud0 == 1)) {
155      COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
156      return;
157    }
158
159    if ((und == 1) && (vnd == 1) &&
160        (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
161
162      sc_digit d = ud0 * vd0;
163      COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
164      return;
165
166    }
167
168    int nd = und + vnd;
169
170#ifdef SC_MAX_NBITS
171    sc_digit d[MAX_NDIGITS];
172#else
173    sc_digit *d = new sc_digit[nd];
174#endif
175
176    vec_zero(nd, d);
177
178    if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
179      vec_mul_small(vnd, vd, ud0, d);
180
181    else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
182      vec_mul_small(und, ud, vd0, d);
183
184    else if (vnd < und)
185      vec_mul(und, ud, vnd, vd, d);
186
187    else
188      vec_mul(vnd, vd, und, ud, d);
189
190    COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
191
192#ifndef SC_MAX_NBITS
193    delete [] d;
194#endif
195
196  }
197
198#undef COPY_DIGITS
199#undef CONVERT_SM_to_2C_to_SM
200
201}
202
203
204void
205mul_on_help_unsigned(small_type &us,
206                     int unb, int und,
207                     sc_digit *ud,
208                     int vnb, int vnd,
209                     const sc_digit *vd)
210{
211#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
212#define COPY_DIGITS copy_digits_unsigned
213
214  {  // Body of mul_on_help
215
216    int old_und = und;
217
218    und = vec_skip_leading_zeros(und, ud);
219    vnd = vec_skip_leading_zeros(vnd, vd);
220
221    sc_digit ud0 = (*ud);
222    sc_digit vd0 = (*vd);
223
224    if ((vnd == 1) && (vd0 == 1)) {
225      us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
226      return;
227    }
228
229    if ((und == 1) && (ud0 == 1)) {
230      COPY_DIGITS(us, unb, old_und, ud, vnb, vnd, vd);
231      return;
232    }
233
234    if ((und == 1) && (vnd == 1) &&
235        (ud0 < HALF_DIGIT_RADIX) && (vd0 < HALF_DIGIT_RADIX)) {
236
237      sc_digit d = ud0 * vd0;
238      COPY_DIGITS(us, unb, old_und, ud, unb + vnb, 1, &d);
239      return;
240
241    }
242
243    int nd = und + vnd;
244
245#ifdef SC_MAX_NBITS
246    sc_digit d[MAX_NDIGITS];
247#else
248    sc_digit *d = new sc_digit[nd];
249#endif
250
251    vec_zero(nd, d);
252
253    if ((und == 1) && (ud0 < HALF_DIGIT_RADIX))
254      vec_mul_small(vnd, vd, ud0, d);
255
256    else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
257      vec_mul_small(und, ud, vd0, d);
258
259    else if (vnd < und)
260      vec_mul(und, ud, vnd, vd, d);
261
262    else
263      vec_mul(vnd, vd, und, ud, d);
264
265    COPY_DIGITS(us, unb, old_und, ud, unb + vnb, nd, d);
266
267#ifndef SC_MAX_NBITS
268    delete [] d;
269#endif
270
271  }
272
273#undef COPY_DIGITS
274#undef CONVERT_SM_to_2C_to_SM
275
276}
277
278
279// ----------------------------------------------------------------------------
280//  SECTION: External functions for DIVISION operators.
281// ----------------------------------------------------------------------------
282
283void
284div_on_help_signed(small_type &us,
285                   int unb, int und,
286                   sc_digit *ud,
287                   int vnb, int vnd,
288                   const sc_digit *vd)
289{
290#define CONVERT_SM_to_2C_to_SM convert_signed_SM_to_2C_to_SM
291#define COPY_DIGITS copy_digits_signed
292
293  {  // Body of div_on_help
294
295    int old_und = und;
296
297    und = vec_skip_leading_zeros(und, ud);
298    vnd = vec_skip_leading_zeros(vnd, vd);
299
300    int cmp_res = vec_cmp(und, ud, vnd, vd);
301
302    if (cmp_res < 0) { // u < v => u / v = 0 - case 4
303      us = SC_ZERO;
304      vec_zero(old_und, ud);
305      return;
306    }
307
308    sc_digit vd0 = (*vd);
309
310    if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1))  {
311      us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
312      return;
313    }
314
315    // One extra digit for d is allocated to simplify vec_div_*().
316    int nd = sc_max(und, vnd) + 1;
317
318#ifdef SC_MAX_NBITS
319    sc_digit d[MAX_NDIGITS + 1];
320#else
321    sc_digit *d = new sc_digit[nd];
322#endif
323
324    vec_zero(nd, d);
325
326    // u = v => u / v = 1 - case 3
327    if (cmp_res == 0)
328      d[0] = 1;
329
330    else if ((vnd == 1) && (und == 1))
331      d[0] = (*ud) / vd0;
332
333    else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
334      vec_div_small(und, ud, vd0, d);
335
336    else
337      vec_div_large(und, ud, vnd, vd, d);
338
339    COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
340
341#ifndef SC_MAX_NBITS
342    delete [] d;
343#endif
344
345  }
346
347#undef COPY_DIGITS
348#undef CONVERT_SM_to_2C_to_SM
349
350}
351
352
353void
354div_on_help_unsigned(small_type &us,
355                     int unb, int und,
356                     sc_digit *ud,
357                     int vnb, int vnd,
358                     const sc_digit *vd)
359{
360#define CONVERT_SM_to_2C_to_SM convert_unsigned_SM_to_2C_to_SM
361#define COPY_DIGITS copy_digits_unsigned
362
363  {  // Body of div_on_help
364
365    int old_und = und;
366
367    und = vec_skip_leading_zeros(und, ud);
368    vnd = vec_skip_leading_zeros(vnd, vd);
369
370    int cmp_res = vec_cmp(und, ud, vnd, vd);
371
372    if (cmp_res < 0) { // u < v => u / v = 0 - case 4
373      us = SC_ZERO;
374      vec_zero(old_und, ud);
375      return;
376    }
377
378    sc_digit vd0 = (*vd);
379
380    if ((cmp_res > 0) && (vnd == 1) && (vd0 == 1))  {
381      us = CONVERT_SM_to_2C_to_SM(us, unb, old_und, ud);
382      return;
383    }
384
385    // One extra digit for d is allocated to simplify vec_div_*().
386    int nd = sc_max(und, vnd) + 1;
387
388#ifdef SC_MAX_NBITS
389    sc_digit d[MAX_NDIGITS + 1];
390#else
391    sc_digit *d = new sc_digit[nd];
392#endif
393
394    vec_zero(nd, d);
395
396    // u = v => u / v = 1 - case 3
397    if (cmp_res == 0)
398      d[0] = 1;
399
400    else if ((vnd == 1) && (und == 1))
401      d[0] = (*ud) / vd0;
402
403    else if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
404      vec_div_small(und, ud, vd0, d);
405
406    else
407      vec_div_large(und, ud, vnd, vd, d);
408
409    COPY_DIGITS(us, unb, old_und, ud, sc_max(unb, vnb), nd - 1, d);
410
411#ifndef SC_MAX_NBITS
412    delete [] d;
413#endif
414
415  }
416
417#undef COPY_DIGITS
418#undef CONVERT_SM_to_2C_to_SM
419
420}
421
422
423// ----------------------------------------------------------------------------
424//  SECTION: External functions for MOD operators.
425// ----------------------------------------------------------------------------
426
427void
428mod_on_help_signed(small_type &us,
429                   int unb, int und,
430                   sc_digit *ud,
431                   int /* vnb */, int vnd,
432                   const sc_digit *vd)
433{
434
435#define COPY_DIGITS copy_digits_signed
436
437  { // Body of mod_on_help
438
439    int old_und = und;
440
441    und = vec_skip_leading_zeros(und, ud);
442    vnd = vec_skip_leading_zeros(vnd, vd);
443
444    int cmp_res = vec_cmp(und, ud, vnd, vd);
445
446    // u < v => u % v = u - case 4
447    if (cmp_res < 0)
448      return;
449
450    // u = v => u % v = 0 - case 3
451    if (cmp_res == 0) {
452      us = SC_ZERO;
453      vec_zero(old_und, ud);
454      return;
455    }
456
457    // else if u > v - case 5
458
459    sc_digit vd0 = (*vd);
460
461    if ((vnd == 1) && (vd0 == 1)) {
462      us = SC_ZERO;
463      vec_zero(old_und, ud);
464      return;
465    }
466
467    // One extra digit for d is allocated to simplify vec_div_*().
468    int nd = sc_max(und, vnd) + 1;
469
470#ifdef SC_MAX_NBITS
471    sc_digit d[MAX_NDIGITS + 1];
472#else
473    sc_digit *d = new sc_digit[nd];
474#endif
475
476    vec_zero(nd, d);
477
478    if ((vnd == 1) && (und == 1))
479      d[0] = (*ud) % vd0;
480
481    if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
482      d[0] = vec_rem_small(und, ud, vd0);
483
484    else
485      vec_rem_large(und, ud, vnd, vd, d);
486
487    us = check_for_zero(us, nd - 1, d);
488
489    if (us == SC_ZERO)
490      vec_zero(old_und, ud);
491    else
492      COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
493
494#ifndef SC_MAX_NBITS
495    delete [] d;
496#endif
497
498  }
499
500#undef COPY_DIGITS
501
502}
503
504
505void
506mod_on_help_unsigned(small_type &us,
507                     int unb, int und,
508                     sc_digit *ud,
509                     int /* vnb */, int vnd,
510                     const sc_digit *vd)
511{
512
513#define COPY_DIGITS copy_digits_unsigned
514
515  { // Body of mod_on_help
516
517    int old_und = und;
518
519    und = vec_skip_leading_zeros(und, ud);
520    vnd = vec_skip_leading_zeros(vnd, vd);
521
522    int cmp_res = vec_cmp(und, ud, vnd, vd);
523
524    // u < v => u % v = u - case 4
525    if (cmp_res < 0)
526      return;
527
528    // u = v => u % v = 0 - case 3
529    if (cmp_res == 0) {
530      us = SC_ZERO;
531      vec_zero(old_und, ud);
532      return;
533    }
534
535    // else if u > v - case 5
536
537    sc_digit vd0 = (*vd);
538
539    if ((vnd == 1) && (vd0 == 1)) {
540      us = SC_ZERO;
541      vec_zero(old_und, ud);
542      return;
543    }
544
545    // One extra digit for d is allocated to simplify vec_div_*().
546    int nd = sc_max(und, vnd) + 1;
547
548#ifdef SC_MAX_NBITS
549    sc_digit d[MAX_NDIGITS + 1];
550#else
551    sc_digit *d = new sc_digit[nd];
552#endif
553
554    vec_zero(nd, d);
555
556    if ((vnd == 1) && (und == 1))
557      d[0] = (*ud) % vd0;
558
559    if ((vnd == 1) && (vd0 < HALF_DIGIT_RADIX))
560      d[0] = vec_rem_small(und, ud, vd0);
561
562    else
563      vec_rem_large(und, ud, vnd, vd, d);
564
565    us = check_for_zero(us, nd - 1, d);
566
567    if (us == SC_ZERO)
568      vec_zero(old_und, ud);
569    else
570      COPY_DIGITS(us, unb, old_und, ud, sc_min(unb, vnd), nd - 1, d);
571
572#ifndef SC_MAX_NBITS
573    delete [] d;
574#endif
575
576  }
577
578#undef COPY_DIGITS
579
580}
581
582
583// ----------------------------------------------------------------------------
584//  SECTION: External functions for AND operators.
585// ----------------------------------------------------------------------------
586
587// Handles the cases 2-5 and returns the result in u.
588void
589and_on_help(small_type us,
590            int /* unb */, int und,
591            sc_digit *ud,
592            small_type vs,
593            int /* vnb */, int vnd,
594            const sc_digit *vd)
595{
596
597  sc_digit *x = ud;
598  const sc_digit *y = vd;
599  int xnd = und;
600  int ynd = vnd;
601
602  // Truncate y.
603  if (xnd < ynd)
604    ynd = xnd;
605
606  const sc_digit *xend = (x + xnd);
607  const sc_digit *yend = (y + ynd);
608
609  // x is longer than y.
610
611  small_type s = mul_signs(us, vs);
612
613  if (s > 0) {
614
615    if (us > 0) { // case 2
616
617      while (y < yend)
618        (*x++) &= (*y++);
619
620      while (x < xend)
621        (*x++) = 0;
622
623    }
624    else {  // case 3
625
626      sc_digit xcarry = 1;
627      sc_digit ycarry = 1;
628
629      while (y < yend) {
630        xcarry += (~(*x) & DIGIT_MASK);
631        ycarry += (~(*y++) & DIGIT_MASK);
632        (*x++) = (xcarry & ycarry) & DIGIT_MASK;
633        xcarry >>= BITS_PER_DIGIT;
634        ycarry >>= BITS_PER_DIGIT;
635      }
636
637      while (x < xend) {
638        xcarry += (~(*x) & DIGIT_MASK);
639        ycarry += DIGIT_MASK;
640        (*x++) = (xcarry & ycarry) & DIGIT_MASK;
641        xcarry >>= BITS_PER_DIGIT;
642        ycarry >>= BITS_PER_DIGIT;
643      }
644
645    }
646  }
647  else {
648
649    if (us > 0) { // case 4
650
651      sc_digit ycarry = 1;
652
653      while (y < yend) {
654        ycarry += (~(*y++) & DIGIT_MASK);
655        (*x++) &= ycarry & DIGIT_MASK;
656        ycarry >>= BITS_PER_DIGIT;
657      }
658
659      while (x < xend) {
660        ycarry += DIGIT_MASK;
661        (*x++) &= ycarry & DIGIT_MASK;
662        ycarry >>= BITS_PER_DIGIT;
663      }
664
665    }
666    else {  // case 5
667
668      sc_digit xcarry = 1;
669
670      while (y < yend) {
671        xcarry += (~(*x) & DIGIT_MASK);
672        (*x++) = (xcarry & (*y++)) & DIGIT_MASK;
673        xcarry >>= BITS_PER_DIGIT;
674      }
675
676      while (x < xend)
677        (*x++) = 0;
678
679    }
680  }
681}
682
683
684// ----------------------------------------------------------------------------
685//  SECTION: External functions for OR operators.
686// ----------------------------------------------------------------------------
687
688// Handles the cases 3-5 and returns the result in u.
689void
690or_on_help(small_type us,
691           int /* unb */, int und,
692           sc_digit *ud,
693           small_type vs,
694           int /* vnb */, int vnd,
695           const sc_digit *vd)
696{
697
698  sc_digit *x = ud;
699  const sc_digit *y = vd;
700  int xnd = und;
701  int ynd = vnd;
702
703  if (xnd < ynd)
704    ynd = xnd;
705
706  const sc_digit *xend = (x + xnd);
707  const sc_digit *yend = (y + ynd);
708
709  // x is longer than y.
710
711  small_type s = mul_signs(us, vs);
712
713  if (s > 0) {
714
715    if (us > 0) { // case 3
716
717      while (y < yend)
718        (*x++) |= (*y++);
719
720      // No change for the rest of x.
721
722    }
723    else {  // case 4
724
725      sc_digit xcarry = 1;
726      sc_digit ycarry = 1;
727
728      while (y < yend) {
729        xcarry += (~(*x) & DIGIT_MASK);
730        ycarry += (~(*y++) & DIGIT_MASK);
731        (*x++) = (xcarry | ycarry) & DIGIT_MASK;
732        xcarry >>= BITS_PER_DIGIT;
733        ycarry >>= BITS_PER_DIGIT;
734      }
735
736      while (x < xend) {
737        xcarry += (~(*x) & DIGIT_MASK);
738        ycarry += DIGIT_MASK;
739        (*x++) = (xcarry | ycarry) & DIGIT_MASK;
740        xcarry >>= BITS_PER_DIGIT;
741        ycarry >>= BITS_PER_DIGIT;
742      }
743    }
744
745  }
746  else {
747
748    if (us > 0) { // case 5
749
750      sc_digit ycarry = 1;
751
752      while (y < yend) {
753        ycarry += (~(*y++) & DIGIT_MASK);
754        (*x) = ((*x) | ycarry) & DIGIT_MASK;
755        x++;
756        ycarry >>= BITS_PER_DIGIT;
757      }
758
759      while (x < xend) {
760        ycarry += DIGIT_MASK;
761        (*x) = ((*x) | ycarry) & DIGIT_MASK;
762        x++;
763        ycarry >>= BITS_PER_DIGIT;
764      }
765
766    }
767    else {  // case 6
768
769      sc_digit xcarry = 1;
770
771      while (y < yend) {
772        xcarry += (~(*x) & DIGIT_MASK);
773        (*x++) = (xcarry | (*y++)) & DIGIT_MASK;
774        xcarry >>= BITS_PER_DIGIT;
775      }
776
777      while (x < xend) {
778        xcarry += (~(*x) & DIGIT_MASK);
779        (*x++) = xcarry & DIGIT_MASK;
780        xcarry >>= BITS_PER_DIGIT;
781      }
782    }
783  }
784}
785
786
787// ----------------------------------------------------------------------------
788//  SECTION: External functions for XOR operators.
789// ----------------------------------------------------------------------------
790
791// Handles the cases 3-5 and returns the result in u.
792void
793xor_on_help(small_type us,
794            int /* unb */, int und,
795            sc_digit *ud,
796            small_type vs,
797            int /* vnb */, int vnd,
798            const sc_digit *vd)
799{
800
801  sc_digit *x = ud;
802  const sc_digit *y = vd;
803  int xnd = und;
804  int ynd = vnd;
805
806  if (xnd < ynd)
807    ynd = xnd;
808
809  const sc_digit *xend = (x + xnd);
810  const sc_digit *yend = (y + ynd);
811
812  // x is longer than y.
813
814  small_type s = mul_signs(us, vs);
815
816  if (s > 0) {
817
818    if (us > 0) { // case 3
819
820      while (y < yend) {
821        (*x) = ((*x) ^ (*y)) & DIGIT_MASK;
822        x++;
823        y++;
824      }
825
826      // No change for the rest of x.
827
828    }
829    else {  // case 4
830
831      sc_digit xcarry = 1;
832      sc_digit ycarry = 1;
833
834      while (y < yend) {
835        xcarry += (~(*x) & DIGIT_MASK);
836        ycarry += (~(*y++) & DIGIT_MASK);
837        (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
838        xcarry >>= BITS_PER_DIGIT;
839        ycarry >>= BITS_PER_DIGIT;
840      }
841
842      while (x < xend) {
843        xcarry += (~(*x) & DIGIT_MASK);
844        ycarry += DIGIT_MASK;
845        (*x++) = (xcarry ^ ycarry) & DIGIT_MASK;
846        xcarry >>= BITS_PER_DIGIT;
847        ycarry >>= BITS_PER_DIGIT;
848      }
849    }
850  }
851  else {
852
853    if (us > 0) { // case 5
854
855      sc_digit ycarry = 1;
856
857      while (y < yend) {
858        ycarry += (~(*y++) & DIGIT_MASK);
859        (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
860        x++;
861        ycarry >>= BITS_PER_DIGIT;
862      }
863
864      while (x < xend) {
865        ycarry += DIGIT_MASK;
866        (*x) = ((*x) ^ ycarry) & DIGIT_MASK;
867        x++;
868        ycarry >>= BITS_PER_DIGIT;
869      }
870
871    }
872    else {  // case 6
873
874      sc_digit xcarry = 1;
875
876      while (y < yend) {
877        xcarry += (~(*x) & DIGIT_MASK);
878        (*x++) = (xcarry ^ (*y++)) & DIGIT_MASK;
879        xcarry >>= BITS_PER_DIGIT;
880      }
881
882      while (x < xend) {
883        xcarry += (~(*x) & DIGIT_MASK);
884        (*x++) = xcarry & DIGIT_MASK;
885        xcarry >>= BITS_PER_DIGIT;
886      }
887    }
888  }
889}
890
891} // namespace sc_dt
892
893
894// End of file
895