00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <ctype.h>
00048 #include "sysc/datatypes/int/sc_int_ids.h"
00049 #include "sysc/datatypes/int/sc_nbutils.h"
00050 #include "sysc/kernel/sc_macros.h"
00051
00052
00053 namespace sc_dt
00054 {
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 small_type
00065 fsm_move(char c, small_type &b, small_type &s, small_type &state)
00066 {
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 switch (state) {
00082
00083 case 0:
00084 switch (c) {
00085 case '0': s = SC_POS; state = 1; return 0;
00086 case '+': s = SC_POS; state = 2; return 1;
00087 case '-': s = SC_NEG; state = 2; return 1;
00088 default: s = SC_POS; b = NB_DEFAULT_BASE; state = 3; return 0;
00089 }
00090
00091 case 1:
00092 switch (c) {
00093 case 'x': case 'X': b = SC_HEX; state = 3; return 2;
00094 case 'd': case 'D': b = SC_DEC; state = 3; return 2;
00095 case 'o': case 'O': b = SC_OCT; state = 3; return 2;
00096 case 'b': case 'B': b = SC_BIN; state = 3; return 2;
00097 default: b = NB_DEFAULT_BASE; state = 3; return 0;
00098 }
00099
00100 case 2:
00101 switch (c) {
00102 case '0': state = 1; return 0;
00103 default: b = NB_DEFAULT_BASE; state = 3; return 0;
00104 }
00105
00106 case 3:
00107 break;
00108
00109 default:
00110
00111 assert((0 <= state) && (state <= 3));
00112
00113 }
00114
00115 return 0;
00116
00117 }
00118
00119
00120
00121
00122
00123
00124 const char
00125 *get_base_and_sign(const char *v, small_type &b, small_type &s)
00126 {
00127
00128 #ifdef DEBUG_SYSTEMC
00129 assert(v != NULL);
00130 #endif
00131
00132 const small_type STATE_START = 0;
00133 const small_type STATE_FINISH = 3;
00134
00135
00136 s = SC_POS;
00137 b = NB_DEFAULT_BASE;
00138
00139 small_type state = STATE_START;
00140 small_type nskip = 0;
00141 const char *u = v;
00142
00143 while (*u) {
00144 if (isspace(*u))
00145 ++u;
00146 else {
00147 nskip += fsm_move(*u, b, s, state);
00148 if (state == STATE_FINISH)
00149 break;
00150 else
00151 ++u;
00152 }
00153 }
00154
00155 #ifdef DEBUG_SYSTEMC
00156
00157
00158
00159 assert(nskip <= 3);
00160 #endif
00161
00162 v += nskip;
00163
00164
00165
00166 if (*v == '\0') {
00167 char msg[BUFSIZ];
00168 std::sprintf( msg,
00169 "get_base_and_sign( const char* v, small_type&, small_type& ) : "
00170 "v = \"\" is not valid" );
00171 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00172 }
00173
00174 return v;
00175
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 void parse_binary_bits(
00191 const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
00192 {
00193 int bit_i;
00194 sc_digit ctrl;
00195 sc_digit data;
00196 int delta_n;
00197 int src_i;
00198 int src_n;
00199 int word_i;
00200
00201
00202
00203 if( src_p == 0 ) {
00204 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00205 "character string is zero" );
00206 }
00207 if( *src_p == 0 ) {
00208 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00209 "character string is empty" );
00210 }
00211
00212
00213
00214
00215
00216
00217 src_n = strlen(src_p);
00218 delta_n = src_n - (dst_n*BITS_PER_DIGIT);
00219 if ( delta_n > 0 )
00220 {
00221 src_p = &src_p[delta_n];
00222 src_n -= delta_n;
00223 }
00224 else
00225 {
00226 for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
00227 if ( ctrl_p )
00228 for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238 src_n = src_n - BITS_PER_DIGIT;
00239 for (word_i=0; word_i < dst_n; word_i++)
00240 {
00241 src_i = src_n;
00242
00243
00244
00245
00246 if ( src_i < 0 )
00247 {
00248 src_n += BITS_PER_DIGIT;
00249 src_i = 0;
00250 data = 0;
00251 ctrl = 0;
00252 for ( src_i = 0; src_i < src_n; src_i++ )
00253 {
00254 ctrl = ctrl << 1;
00255 data = data << 1;
00256 switch( src_p[src_i] )
00257 {
00258 case 'X':
00259 case 'x': ctrl = ctrl | 1; data = data | 1; break;
00260 case '1': data = data | 1; break;
00261 case 'Z':
00262 case 'z': ctrl = ctrl | 1; break;
00263 case '0': break;
00264 default:
00265 {
00266 char msg[BUFSIZ];
00267 std::sprintf( msg, "character string '%s' is not valid",
00268 src_p );
00269 SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
00270 }
00271 break;
00272 }
00273 }
00274 if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00275 data_p[word_i] = data;
00276 break;
00277 }
00278
00279
00280
00281
00282 ctrl = 0;
00283 data = 0;
00284 for ( bit_i = 0; bit_i < BITS_PER_DIGIT; bit_i++ )
00285 {
00286 ctrl = ctrl << 1;
00287 data = data << 1;
00288 switch( src_p[src_i++] )
00289 {
00290 case 'X':
00291 case 'x': ctrl = ctrl | 1; data = data | 1; break;
00292 case '1': data = data | 1; break;
00293 case 'Z':
00294 case 'z': ctrl = ctrl | 1; break;
00295 case '0': break;
00296 default:
00297 {
00298 char msg[BUFSIZ];
00299 std::sprintf( msg, "character string '%s' is not valid",
00300 src_p );
00301 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00302 }
00303 break;
00304 }
00305 }
00306 if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00307 data_p[word_i] = data;
00308 src_n = src_n - BITS_PER_DIGIT;
00309 }
00310 }
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 void parse_hex_bits(
00326 const char* src_p, int dst_n, sc_digit* data_p, sc_digit* ctrl_p )
00327 {
00328 sc_digit ctrl;
00329 sc_digit data;
00330 int delta_n;
00331 int digit_i;
00332 int src_i;
00333 int src_n;
00334 int word_i;
00335
00336
00337
00338 if( src_p == 0 ) {
00339 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00340 "character string is zero" );
00341 }
00342 if( *src_p == 0 ) {
00343 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_,
00344 "character string is empty" );
00345 }
00346
00347
00348
00349
00350
00351
00352 src_n = strlen(src_p);
00353 delta_n = src_n - (dst_n*8);
00354 if ( delta_n > 0 )
00355 {
00356 src_p = &src_p[delta_n];
00357 src_n -= delta_n;
00358 }
00359 else
00360 {
00361 for ( word_i = 0; word_i < dst_n; word_i++ ) data_p[word_i] = 0;
00362 if ( ctrl_p )
00363 for ( word_i = 0; word_i < dst_n; word_i++ ) ctrl_p[word_i] = 0;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373 src_n = src_n - 8;
00374 for (word_i=0; word_i < dst_n; word_i++)
00375 {
00376 src_i = src_n;
00377
00378
00379
00380
00381 if ( src_i < 0 )
00382 {
00383 src_n += 8;
00384 src_i = 0;
00385 data = 0;
00386 ctrl = 0;
00387 for ( src_i = 0; src_i < src_n; src_i++ )
00388 {
00389 ctrl = ctrl << 4;
00390 data = data << 4;
00391 switch( src_p[src_i] )
00392 {
00393 case 'X':
00394 case 'x': ctrl = ctrl | 15; data = data | 15; break;
00395 case 'F':
00396 case 'f': data = data | 15; break;
00397 case 'E':
00398 case 'e': data = data | 14; break;
00399 case 'D':
00400 case 'd': data = data | 13; break;
00401 case 'C':
00402 case 'c': data = data | 12; break;
00403 case 'B':
00404 case 'b': data = data | 11; break;
00405 case 'A':
00406 case 'a': data = data | 10; break;
00407 case '9': data = data | 9; break;
00408 case '8': data = data | 8; break;
00409 case '7': data = data | 7; break;
00410 case '6': data = data | 6; break;
00411 case '5': data = data | 5; break;
00412 case '4': data = data | 4; break;
00413 case '3': data = data | 3; break;
00414 case '2': data = data | 2; break;
00415 case '1': data = data | 1; break;
00416 case '0': break;
00417 case 'Z':
00418 case 'z': ctrl = ctrl | 15; break;
00419 default:
00420 {
00421 char msg[BUFSIZ];
00422 std::sprintf( msg, "character string '%s' is not valid",
00423 src_p );
00424 SC_REPORT_ERROR(sc_core::SC_ID_CONVERSION_FAILED_, msg);
00425 }
00426 break;
00427 }
00428 }
00429 if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00430 data_p[word_i] = data;
00431 break;
00432 }
00433
00434
00435
00436
00437 ctrl = 0;
00438 data = 0;
00439 for ( digit_i = 0; digit_i < 8; digit_i++ )
00440 {
00441 ctrl = ctrl << 4;
00442 data = data << 4;
00443 switch( src_p[src_i++] )
00444 {
00445 case 'X':
00446 case 'x': ctrl = ctrl | 15; data = data | 15; break;
00447 case 'F':
00448 case 'f': data = data | 15; break;
00449 case 'E':
00450 case 'e': data = data | 14; break;
00451 case 'D':
00452 case 'd': data = data | 13; break;
00453 case 'C':
00454 case 'c': data = data | 12; break;
00455 case 'B':
00456 case 'b': data = data | 11; break;
00457 case 'A':
00458 case 'a': data = data | 10; break;
00459 case '9': data = data | 9; break;
00460 case '8': data = data | 8; break;
00461 case '7': data = data | 7; break;
00462 case '6': data = data | 6; break;
00463 case '5': data = data | 5; break;
00464 case '4': data = data | 4; break;
00465 case '3': data = data | 3; break;
00466 case '2': data = data | 2; break;
00467 case '1': data = data | 1; break;
00468 case '0': break;
00469 case 'Z':
00470 case 'z': ctrl = ctrl | 15; break;
00471 default:
00472 {
00473 char msg[BUFSIZ];
00474 std::sprintf( msg, "character string '%s' is not valid",
00475 src_p );
00476 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00477 }
00478 break;
00479 }
00480 }
00481 if ( ctrl_p ) ctrl_p[word_i] = ctrl;
00482 data_p[word_i] = data;
00483 src_n = src_n - BITS_PER_DIGIT;
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 small_type
00496 vec_from_str(int unb, int und, sc_digit *u,
00497 const char *v, sc_numrep base)
00498 {
00499
00500 #ifdef DEBUG_SYSTEMC
00501 assert((unb > 0) && (und > 0) && (u != NULL));
00502 assert(v != NULL);
00503 #endif
00504
00505 is_valid_base(base);
00506
00507 small_type b, s;
00508
00509 v = get_base_and_sign(v, b, s);
00510
00511 if (base != SC_NOBASE) {
00512 if (b == NB_DEFAULT_BASE)
00513 b = base;
00514 else {
00515 char msg[BUFSIZ];
00516 std::sprintf( msg,
00517 "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
00518 "base = %s does not match the default base",
00519 to_string( base ).c_str() );
00520 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00521 }
00522 }
00523
00524 vec_zero(und, u);
00525
00526 char c;
00527
00528 for ( ; (c = *v); ++v) {
00529
00530 if (isalnum(c)) {
00531
00532 small_type val;
00533
00534 if (isalpha(c))
00535 val = toupper(c) - 'A' + 10;
00536 else
00537 val = c - '0';
00538
00539 if (val >= b) {
00540 char msg[BUFSIZ];
00541 std::sprintf( msg,
00542 "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
00543 "'%c' is not a valid digit in base %d",
00544 *v, b );
00545 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00546 }
00547
00548
00549 vec_mul_small_on(und, u, b);
00550
00551 if (val)
00552 vec_add_small_on(und, u, val);
00553
00554 }
00555 else {
00556 char msg[BUFSIZ];
00557 std::sprintf( msg,
00558 "vec_from_str( int, int, sc_digit*, const char*, sc_numrep base ) : "
00559 "'%c' is not a valid digit in base %d",
00560 *v, b );
00561 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
00562 }
00563 }
00564
00565 return convert_signed_SM_to_2C_to_SM(s, unb, und, u);
00566 }
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 void
00577 vec_add(int ulen, const sc_digit *u,
00578 int vlen, const sc_digit *v,
00579 sc_digit *w)
00580 {
00581
00582 #ifdef DEBUG_SYSTEMC
00583 assert((ulen > 0) && (u != NULL));
00584 assert((vlen > 0) && (v != NULL));
00585 assert(w != NULL);
00586 assert(ulen >= vlen);
00587 #endif
00588
00589 const sc_digit *uend = (u + ulen);
00590 const sc_digit *vend = (v + vlen);
00591
00592 register sc_digit carry = 0;
00593
00594
00595 while (v < vend) {
00596 carry += (*u++) + (*v++);
00597 (*w++) = carry & DIGIT_MASK;
00598 carry >>= BITS_PER_DIGIT;
00599 }
00600
00601
00602 while (carry && (u < uend)) {
00603 carry = (*u++) + 1;
00604 (*w++) = carry & DIGIT_MASK;
00605 carry >>= BITS_PER_DIGIT;
00606 }
00607
00608
00609 while (u < uend)
00610 (*w++) = (*u++);
00611
00612
00613 if (carry)
00614 (*w) = 1;
00615
00616 }
00617
00618
00619
00620
00621 void
00622 vec_add_on(int ulen, sc_digit *ubegin,
00623 int vlen, const sc_digit *v)
00624 {
00625
00626 #ifdef DEBUG_SYSTEMC
00627 assert((ulen > 0) && (ubegin != NULL));
00628 assert((vlen > 0) && (v != NULL));
00629 assert(ulen >= vlen);
00630 #endif
00631
00632 register sc_digit *u = ubegin;
00633 const sc_digit *uend = (u + ulen);
00634 const sc_digit *vend = (v + vlen);
00635
00636 register sc_digit carry = 0;
00637
00638
00639 while (v < vend) {
00640 carry += (*u) + (*v++);
00641 (*u++) = carry & DIGIT_MASK;
00642 carry >>= BITS_PER_DIGIT;
00643 }
00644
00645
00646 while (carry && (u < uend)) {
00647 carry = (*u) + 1;
00648 (*u++) = carry & DIGIT_MASK;
00649 carry >>= BITS_PER_DIGIT;
00650 }
00651
00652 #ifdef DEBUG_SYSTEMC
00653 if( carry != 0 ) {
00654 SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00655 "vec_add_on( int, sc_digit*, int, const "
00656 "sc_digit* ) : "
00657 "result of addition is wrapped around" );
00658 }
00659 #endif
00660
00661 }
00662
00663
00664
00665
00666 void
00667 vec_add_on2(int ulen, sc_digit *ubegin,
00668 int
00669 #ifdef DEBUG_SYSTEMC
00670 vlen
00671 #endif
00672 , const sc_digit *v)
00673 {
00674
00675 #ifdef DEBUG_SYSTEMC
00676 assert((ulen > 0) && (ubegin != NULL));
00677 assert((vlen > 0) && (v != NULL));
00678 assert(ulen < vlen);
00679 #endif
00680
00681 register sc_digit *u = ubegin;
00682 const sc_digit *uend = (u + ulen);
00683
00684 register sc_digit carry = 0;
00685
00686
00687 while (u < uend) {
00688 carry += (*u) + (*v++);
00689 (*u++) = carry & DIGIT_MASK;
00690 carry >>= BITS_PER_DIGIT;
00691 }
00692
00693 #ifdef DEBUG_SYSTEMC
00694 if( carry != 0 ) {
00695 SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00696 "vec_add_on2( int, sc_digit*, int, const "
00697 "sc_digit* ) : "
00698 "result of addition is wrapped around" );
00699 }
00700 #endif
00701 }
00702
00703
00704
00705 void
00706 vec_add_small(int ulen, const sc_digit *u,
00707 sc_digit v,
00708 sc_digit *w)
00709 {
00710
00711 #ifdef DEBUG_SYSTEMC
00712 assert((ulen > 0) && (u != NULL));
00713 assert(w != NULL);
00714 #endif
00715
00716 const sc_digit *uend = (u + ulen);
00717
00718
00719 register sc_digit carry = (*u++) + v;
00720 (*w++) = carry & DIGIT_MASK;
00721 carry >>= BITS_PER_DIGIT;
00722
00723
00724 while (carry && (u < uend)) {
00725 carry = (*u++) + 1;
00726 (*w++) = carry & DIGIT_MASK;
00727 carry >>= BITS_PER_DIGIT;
00728 }
00729
00730
00731 while (u < uend)
00732 (*w++) = (*u++);
00733
00734
00735 if (carry)
00736 (*w) = 1;
00737
00738 }
00739
00740
00741 void
00742 vec_add_small_on(int ulen, sc_digit *u, sc_digit v)
00743 {
00744
00745 #ifdef DEBUG_SYSTEMC
00746 assert((ulen > 0) && (u != NULL));
00747 #endif
00748
00749 register int i = 0;
00750
00751 while (v && (i < ulen)) {
00752 v += u[i];
00753 u[i++] = v & DIGIT_MASK;
00754 v >>= BITS_PER_DIGIT;
00755 }
00756
00757 #ifdef DEBUG_SYSTEMC
00758 if( v != 0 ) {
00759 SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00760 "vec_add_small_on( int, sc_digit*, unsigned "
00761 "long ) : "
00762 "result of addition is wrapped around" );
00763 }
00764 #endif
00765
00766 }
00767
00768
00769
00770
00771 void
00772 vec_sub(int ulen, const sc_digit *u,
00773 int vlen, const sc_digit *v,
00774 sc_digit *w)
00775 {
00776
00777 #ifdef DEBUG_SYSTEMC
00778 assert((ulen > 0) && (u != NULL));
00779 assert((vlen > 0) && (v != NULL));
00780 assert(w != NULL);
00781 assert(ulen >= vlen);
00782 #endif
00783
00784 const sc_digit *uend = (u + ulen);
00785 const sc_digit *vend = (v + vlen);
00786
00787 register sc_digit borrow = 0;
00788
00789
00790 while (v < vend) {
00791 borrow = ((*u++) + DIGIT_RADIX) - (*v++) - borrow;
00792 (*w++) = borrow & DIGIT_MASK;
00793 borrow = 1 - (borrow >> BITS_PER_DIGIT);
00794 }
00795
00796
00797 while (borrow && (u < uend)) {
00798 borrow = ((*u++) + DIGIT_RADIX) - 1;
00799 (*w++) = borrow & DIGIT_MASK;
00800 borrow = 1 - (borrow >> BITS_PER_DIGIT);
00801 }
00802
00803 #ifdef DEBUG_SYSTEMC
00804 assert(borrow == 0);
00805 #endif
00806
00807
00808 while (u < uend)
00809 (*w++) = (*u++);
00810
00811 }
00812
00813
00814
00815
00816 void
00817 vec_sub_on(int ulen, sc_digit *ubegin,
00818 int vlen, const sc_digit *v)
00819 {
00820
00821 #ifdef DEBUG_SYSTEMC
00822 assert((ulen > 0) && (ubegin != NULL));
00823 assert((vlen > 0) && (v != NULL));
00824 assert(ulen >= vlen);
00825 #endif
00826
00827 register sc_digit *u = ubegin;
00828 const sc_digit *uend = (u + ulen);
00829 const sc_digit *vend = (v + vlen);
00830
00831 register sc_digit borrow = 0;
00832
00833
00834 while (v < vend) {
00835 borrow = ((*u) + DIGIT_RADIX) - (*v++) - borrow;
00836 (*u++) = borrow & DIGIT_MASK;
00837 borrow = 1 - (borrow >> BITS_PER_DIGIT);
00838 }
00839
00840
00841 while (borrow && (u < uend)) {
00842 borrow = ((*u) + DIGIT_RADIX) - 1;
00843 (*u++) = borrow & DIGIT_MASK;
00844 borrow = 1 - (borrow >> BITS_PER_DIGIT);
00845 }
00846
00847 #ifdef DEBUG_SYSTEMC
00848 assert(borrow == 0);
00849 #endif
00850
00851 }
00852
00853
00854
00855
00856 void
00857 vec_sub_on2(int ulen, sc_digit *ubegin,
00858 int vlen, const sc_digit *v)
00859 {
00860
00861 #ifdef DEBUG_SYSTEMC
00862 assert((ulen > 0) && (ubegin != NULL));
00863 assert((vlen > 0) && (v != NULL));
00864 #endif
00865
00866 register sc_digit *u = ubegin;
00867 const sc_digit *uend = (u + sc_min(ulen, vlen));
00868
00869 register sc_digit borrow = 0;
00870
00871
00872 while (u < uend) {
00873 borrow = ((*v++) + DIGIT_RADIX) - (*u) - borrow;
00874 (*u++) = borrow & DIGIT_MASK;
00875 borrow = 1 - (borrow >> BITS_PER_DIGIT);
00876 }
00877
00878 #ifdef DEBUG_SYSTEMC
00879 if( borrow != 0 ) {
00880 SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
00881 "vec_sub_on2( int, sc_digit*, int, const "
00882 "sc_digit* ) : "
00883 "result of subtraction is wrapped around" );
00884 }
00885 #endif
00886 }
00887
00888
00889 void
00890 vec_sub_small(int ulen, const sc_digit *u,
00891 sc_digit v,
00892 sc_digit *w)
00893 {
00894
00895 #ifdef DEBUG_SYSTEMC
00896 assert(ulen > 0);
00897 assert(u != NULL);
00898 #endif
00899
00900 const sc_digit *uend = (u + ulen);
00901
00902
00903 register sc_digit borrow = ((*u++) + DIGIT_RADIX) - v;
00904 (*w++) = borrow & DIGIT_MASK;
00905 borrow = 1 - (borrow >> BITS_PER_DIGIT);
00906
00907
00908 while (borrow && (u < uend)) {
00909 borrow = ((*u++) + DIGIT_RADIX) - 1;
00910 (*w++) = borrow & DIGIT_MASK;
00911 borrow = 1 - (borrow >> BITS_PER_DIGIT);
00912 }
00913
00914 #ifdef DEBUG_SYSTEMC
00915 assert(borrow == 0);
00916 #endif
00917
00918
00919 while (u < uend)
00920 (*w++) = (*u++);
00921
00922 }
00923
00924
00925
00926 void
00927 vec_sub_small_on(int ulen, sc_digit *u, sc_digit v)
00928 {
00929
00930 #ifdef DEBUG_SYSTEMC
00931 assert((ulen > 0) && (u != NULL));
00932 #endif
00933
00934 for (register int i = 0; i < ulen; ++i) {
00935 v = (u[i] + DIGIT_RADIX) - v;
00936 u[i] = v & DIGIT_MASK;
00937 v = 1 - (v >> BITS_PER_DIGIT);
00938 }
00939
00940 #ifdef DEBUG_SYSTEMC
00941 assert(v == 0);
00942 #endif
00943
00944 }
00945
00946
00947 void
00948 vec_mul(int ulen, const sc_digit *u,
00949 int vlen, const sc_digit *vbegin,
00950 sc_digit *wbegin)
00951 {
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 #ifdef DEBUG_SYSTEMC
01010 assert((ulen > 0) && (u != NULL));
01011 assert((vlen > 0) && (vbegin != NULL));
01012 assert(wbegin != NULL);
01013 #endif
01014
01015 #define prod_h carry
01016
01017 const sc_digit *uend = (u + ulen);
01018 const sc_digit *vend = (vbegin + vlen);
01019
01020 while (u < uend) {
01021
01022 sc_digit u_h = (*u++);
01023 sc_digit u_l = low_half(u_h);
01024 u_h = high_half(u_h);
01025
01026 #ifdef DEBUG_SYSTEMC
01027
01028 assert(u_h == (u_h & HALF_DIGIT_MASK));
01029 #endif
01030
01031 register sc_digit carry = 0;
01032
01033 register sc_digit *w = (wbegin++);
01034
01035 register const sc_digit *v = vbegin;
01036
01037 while (v < vend) {
01038
01039 sc_digit v_h = (*v++);
01040 sc_digit v_l = low_half(v_h);
01041
01042 v_h = high_half(v_h);
01043
01044 #ifdef DEBUG_SYSTEMC
01045
01046 assert(v_h == (v_h & HALF_DIGIT_MASK));
01047 #endif
01048
01049 sc_digit prod_l = (*w) + u_l * v_l + low_half(carry);
01050
01051 prod_h = u_h * v_l + u_l * v_h + high_half(prod_l) + high_half(carry);
01052
01053 (*w++) = concat(low_half(prod_h), low_half(prod_l));
01054
01055 carry = u_h * v_h + high_half(prod_h);
01056
01057 }
01058
01059 (*w) = carry;
01060
01061 }
01062
01063 #undef prod_h
01064
01065 }
01066
01067
01068
01069 void
01070 vec_mul_small(int ulen, const sc_digit *u,
01071 sc_digit v, sc_digit *w)
01072 {
01073
01074 #ifdef DEBUG_SYSTEMC
01075 assert((ulen > 0) && (u != NULL));
01076 assert(w != NULL);
01077 assert((0 < v) && (v < HALF_DIGIT_RADIX));
01078 #endif
01079
01080 #define prod_h carry
01081
01082 const sc_digit *uend = (u + ulen);
01083
01084 register sc_digit carry = 0;
01085
01086 while (u < uend) {
01087
01088 sc_digit u_AB = (*u++);
01089
01090 #ifdef DEBUG_SYSTEMC
01091
01092 assert(high_half(u_AB) == high_half_masked(u_AB));
01093 #endif
01094
01095 sc_digit prod_l = v * low_half(u_AB) + low_half(carry);
01096
01097 prod_h = v * high_half(u_AB) + high_half(prod_l) + high_half(carry);
01098
01099 (*w++) = concat(low_half(prod_h), low_half(prod_l));
01100
01101 carry = high_half(prod_h);
01102
01103 }
01104
01105 (*w) = carry;
01106
01107 #undef prod_h
01108
01109 }
01110
01111
01112
01113 void
01114 vec_mul_small_on(int ulen, sc_digit *u, sc_digit v)
01115 {
01116
01117 #ifdef DEBUG_SYSTEMC
01118 assert((ulen > 0) && (u != NULL));
01119 assert((0 < v) && (v < HALF_DIGIT_RADIX));
01120 #endif
01121
01122 #define prod_h carry
01123
01124 register sc_digit carry = 0;
01125
01126 for (register int i = 0; i < ulen; ++i) {
01127
01128 #ifdef DEBUG_SYSTEMC
01129
01130 assert(high_half(u[i]) == high_half_masked(u[i]));
01131 #endif
01132
01133 sc_digit prod_l = v * low_half(u[i]) + low_half(carry);
01134
01135 prod_h = v * high_half(u[i]) + high_half(prod_l) + high_half(carry);
01136
01137 u[i] = concat(low_half(prod_h), low_half(prod_l));
01138
01139 carry = high_half(prod_h);
01140
01141 }
01142
01143 #undef prod_h
01144
01145 #ifdef DEBUG_SYSTEMC
01146 if( carry != 0 ) {
01147 SC_REPORT_WARNING( sc_core::SC_ID_WITHOUT_MESSAGE_,
01148 "vec_mul_small_on( int, sc_digit*, unsigned "
01149 "long ) : "
01150 "result of multiplication is wrapped around" );
01151 }
01152 #endif
01153 }
01154
01155
01156
01157 void
01158 vec_div_large(int ulen, const sc_digit *u,
01159 int vlen, const sc_digit *v,
01160 sc_digit *w)
01161 {
01162
01163 #ifdef DEBUG_SYSTEMC
01164 assert((ulen > 0) && (u != NULL));
01165 assert((vlen > 0) && (v != NULL));
01166 assert(w != NULL);
01167 assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
01168 #endif
01169
01170
01171
01172
01173
01174
01175
01176 int xlen = BYTES_PER_DIGIT * ulen + 1;
01177 int ylen = BYTES_PER_DIGIT * vlen;
01178
01179 #ifdef SC_MAX_NBITS
01180 uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01181 uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01182 uchar q[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01183 #else
01184 uchar *x = new uchar[xlen];
01185 uchar *y = new uchar[ylen];
01186 uchar *q = new uchar[xlen - ylen + 1];
01187 #endif
01188
01189
01190
01191
01192 xlen = vec_to_char(ulen, u, xlen, x);
01193
01194
01195 while ((--xlen >= 0) && (! x[xlen]));
01196 xlen++;
01197
01198
01199 ylen = vec_to_char(vlen, v, ylen, y);
01200
01201
01202 while ((--ylen >= 0) && (! y[ylen]));
01203 ylen++;
01204
01205 #ifdef DEBUG_SYSTEMC
01206 assert(xlen > 1);
01207 assert(ylen > 1);
01208 #endif
01209
01210
01211
01212
01213 x[xlen] = 0;
01214
01215
01216 register sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
01217
01218 const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
01219
01220
01221 for (register int k = xlen - ylen; k >= 0; --k) {
01222
01223
01224 register sc_digit qk;
01225
01226
01227
01228 int k2 = k + ylen;
01229
01230 qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
01231 (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
01232
01233 if (qk >= BYTE_RADIX)
01234 qk = BYTE_RADIX - 1;
01235
01236
01237 if (qk) {
01238
01239 register uchar *xk = (x + k);
01240
01241
01242 register sc_digit carry = 0;
01243
01244 for (register int i = 0; i < ylen; ++i) {
01245 carry += y[i] * qk;
01246 sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
01247 xk[i] = (uchar)(diff & BYTE_MASK);
01248 carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
01249 }
01250
01251
01252 if (carry) {
01253
01254
01255 carry = (xk[ylen] + BYTE_RADIX) - carry;
01256 xk[ylen] = (uchar)(carry & BYTE_MASK);
01257 carry = 1 - (carry >> BITS_PER_BYTE);
01258
01259 if (carry) {
01260
01261
01262 --qk;
01263
01264
01265
01266 carry = 0;
01267
01268 for (register int i = 0; i < ylen; ++i) {
01269 carry += xk[i] + y[i];
01270 xk[i] = (uchar)(carry & BYTE_MASK);
01271 carry >>= BITS_PER_BYTE;
01272 }
01273
01274 if (carry)
01275 xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
01276
01277 }
01278 }
01279 }
01280
01281 q[k] = (uchar)qk;
01282
01283 }
01284
01285
01286 vec_from_char(xlen - ylen + 1, q, ulen, w);
01287
01288 #ifndef SC_MAX_NBITS
01289 delete [] x;
01290 delete [] y;
01291 delete [] q;
01292 #endif
01293
01294 }
01295
01296
01297
01298 void
01299 vec_div_small(int ulen, const sc_digit *u,
01300 sc_digit v, sc_digit *q)
01301 {
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327 #ifdef DEBUG_SYSTEMC
01328 assert((ulen > 0) && (u != NULL));
01329 assert(q != NULL);
01330 assert((0 < v) && (v < HALF_DIGIT_RADIX));
01331 #endif
01332
01333 #define q_h r
01334
01335 register sc_digit r = 0;
01336 const sc_digit *ubegin = u;
01337
01338 u += ulen;
01339 q += ulen;
01340
01341 while (ubegin < u) {
01342
01343 sc_digit u_AB = (*--u);
01344
01345 #ifdef DEBUG_SYSTEMC
01346
01347 assert(high_half(u_AB) == high_half_masked(u_AB));
01348 #endif
01349
01350 register sc_digit num = concat(r, high_half(u_AB));
01351 q_h = num / v;
01352 num = concat((num % v), low_half(u_AB));
01353 (*--q) = concat(q_h, num / v);
01354 r = num % v;
01355
01356 }
01357
01358 #undef q_h
01359
01360 }
01361
01362
01363
01364 void
01365 vec_rem_large(int ulen, const sc_digit *u,
01366 int vlen, const sc_digit *v,
01367 sc_digit *w)
01368 {
01369
01370 #ifdef DEBUG_SYSTEMC
01371 assert((ulen > 0) && (u != NULL));
01372 assert((vlen > 0) && (v != NULL));
01373 assert(w != NULL);
01374 assert(BITS_PER_DIGIT >= 3 * BITS_PER_BYTE);
01375 #endif
01376
01377
01378
01379 int xlen = BYTES_PER_DIGIT * ulen + 1;
01380 int ylen = BYTES_PER_DIGIT * vlen;
01381
01382 #ifdef SC_MAX_NBITS
01383 uchar x[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01384 uchar y[DIV_CEIL2(SC_MAX_NBITS, BITS_PER_BYTE)];
01385 #else
01386 uchar *x = new uchar[xlen];
01387 uchar *y = new uchar[ylen];
01388 #endif
01389
01390
01391
01392
01393 xlen = vec_to_char(ulen, u, xlen, x);
01394
01395
01396 while ((--xlen >= 0) && (! x[xlen]));
01397 xlen++;
01398
01399
01400 ylen = vec_to_char(vlen, v, ylen, y);
01401
01402
01403 while ((--ylen >= 0) && (! y[ylen]));
01404 ylen++;
01405
01406 #ifdef DEBUG_SYSTEMC
01407 assert(xlen > 1);
01408 assert(ylen > 1);
01409 #endif
01410
01411
01412
01413
01414 x[xlen] = 0;
01415
01416
01417 register sc_digit y2 = (y[ylen - 1] << BITS_PER_BYTE) + y[ylen - 2];
01418
01419 const sc_digit DOUBLE_BITS_PER_BYTE = 2 * BITS_PER_BYTE;
01420
01421
01422 for (register int k = xlen - ylen; k >= 0; --k) {
01423
01424
01425 register sc_digit qk;
01426
01427
01428
01429 int k2 = k + ylen;
01430
01431 qk = ((x[k2] << DOUBLE_BITS_PER_BYTE) +
01432 (x[k2 - 1] << BITS_PER_BYTE) + x[k2 - 2]) / y2;
01433
01434 if (qk >= BYTE_RADIX)
01435 qk = BYTE_RADIX - 1;
01436
01437
01438 if (qk) {
01439
01440 register uchar *xk = (x + k);
01441
01442
01443 register sc_digit carry = 0;
01444
01445 for (register int i = 0; i < ylen; ++i) {
01446 carry += y[i] * qk;
01447 sc_digit diff = (xk[i] + BYTE_RADIX) - (carry & BYTE_MASK);
01448 xk[i] = (uchar)(diff & BYTE_MASK);
01449 carry = (carry >> BITS_PER_BYTE) + (1 - (diff >> BITS_PER_BYTE));
01450 }
01451
01452 if (carry) {
01453
01454
01455 carry = (xk[ylen] + BYTE_RADIX) - carry;
01456 xk[ylen] = (uchar)(carry & BYTE_MASK);
01457 carry = 1 - (carry >> BITS_PER_BYTE);
01458
01459 if (carry) {
01460
01461
01462
01463
01464
01465 carry = 0;
01466
01467 for (register int i = 0; i < ylen; ++i) {
01468 carry += xk[i] + y[i];
01469 xk[i] = (uchar)(carry & BYTE_MASK);
01470 carry >>= BITS_PER_BYTE;
01471 }
01472
01473 if (carry)
01474 xk[ylen] = (uchar)((xk[ylen] + 1) & BYTE_MASK);
01475
01476 }
01477 }
01478 }
01479 }
01480
01481
01482 vec_from_char(ylen, x, ulen, w);
01483
01484 #ifndef SC_MAX_NBITS
01485 delete [] x;
01486 delete [] y;
01487 #endif
01488
01489 }
01490
01491
01492
01493
01494 sc_digit
01495 vec_rem_small(int ulen, const sc_digit *u, sc_digit v)
01496 {
01497
01498 #ifdef DEBUG_SYSTEMC
01499 assert((ulen > 0) && (u != NULL));
01500 assert((0 < v) && (v < HALF_DIGIT_RADIX));
01501 #endif
01502
01503
01504
01505 register sc_digit r = 0;
01506 const sc_digit *ubegin = u;
01507
01508 u += ulen;
01509
01510 while (ubegin < u) {
01511 register sc_digit u_AB = (*--u);
01512
01513 #ifdef DEBUG_SYSTEMC
01514
01515 assert(high_half(u_AB) == high_half_masked(u_AB));
01516 #endif
01517
01518
01519 r = (concat(((concat(r, high_half(u_AB))) % v), low_half(u_AB))) % v;
01520 }
01521
01522 return r;
01523
01524 }
01525
01526
01527 sc_digit
01528 vec_rem_on_small(int ulen, sc_digit *u, sc_digit v)
01529 {
01530
01531 #ifdef DEBUG_SYSTEMC
01532 assert((ulen > 0) && (u != NULL));
01533 assert(v > 0);
01534 #endif
01535
01536 #define q_h r
01537
01538 register sc_digit r = 0;
01539 const sc_digit *ubegin = u;
01540
01541 u += ulen;
01542
01543 while (ubegin < u) {
01544
01545 sc_digit u_AB = (*--u);
01546
01547 #ifdef DEBUG_SYSTEMC
01548
01549 assert(high_half(u_AB) == high_half_masked(u_AB));
01550 #endif
01551
01552 register sc_digit num = concat(r, high_half(u_AB));
01553 q_h = num / v;
01554 num = concat((num % v), low_half(u_AB));
01555 (*u) = concat(q_h, num / v);
01556 r = num % v;
01557
01558 }
01559
01560 #undef q_h
01561
01562 return r;
01563
01564 }
01565
01566
01567 int
01568 vec_to_char(int ulen, const sc_digit *u,
01569 int vlen, uchar *v)
01570 {
01571
01572 #ifdef DEBUG_SYSTEMC
01573 assert((ulen > 0) && (u != NULL));
01574 assert((vlen > 0) && (v != NULL));
01575 #endif
01576
01577 register int nbits = ulen * BITS_PER_DIGIT;
01578
01579 register int right = 0;
01580 register int left = right + BITS_PER_BYTE - 1;
01581
01582 vlen = 0;
01583
01584 while (nbits > 0) {
01585
01586 int left_digit = left / BITS_PER_DIGIT;
01587 int right_digit = right / BITS_PER_DIGIT;
01588
01589 register int nsr = ((vlen << LOG2_BITS_PER_BYTE) % BITS_PER_DIGIT);
01590
01591 int d = u[right_digit] >> nsr;
01592
01593 if (left_digit != right_digit) {
01594
01595 if (left_digit < ulen)
01596 d |= u[left_digit] << (BITS_PER_DIGIT - nsr);
01597
01598 }
01599
01600 v[vlen++] = (uchar)(d & BYTE_MASK);
01601
01602 left += BITS_PER_BYTE;
01603 right += BITS_PER_BYTE;
01604 nbits -= BITS_PER_BYTE;
01605
01606 }
01607
01608 return vlen;
01609
01610 }
01611
01612
01613
01614 void
01615 vec_from_char(int ulen, const uchar *u,
01616 int vlen, sc_digit *v)
01617 {
01618
01619 #ifdef DEBUG_SYSTEMC
01620 assert((ulen > 0) && (u != NULL));
01621 assert((vlen > 0) && (v != NULL));
01622 assert(sizeof(uchar) <= sizeof(sc_digit));
01623 #endif
01624
01625 sc_digit *vend = (v + vlen);
01626
01627 const int nsr = BITS_PER_DIGIT - BITS_PER_BYTE;
01628 const sc_digit mask = one_and_ones(nsr);
01629
01630 (*v) = (sc_digit) u[ulen - 1];
01631
01632 for (register int i = ulen - 2; i >= 0; --i) {
01633
01634
01635
01636 register sc_digit *viter = v;
01637
01638 register sc_digit carry = 0;
01639
01640 while (viter < vend) {
01641 register sc_digit vval = (*viter);
01642 (*viter++) = (((vval & mask) << BITS_PER_BYTE) | carry);
01643 carry = vval >> nsr;
01644 }
01645
01646 if (viter < vend)
01647 (*viter) = carry;
01648
01649 (*v) |= (sc_digit) u[i];
01650
01651 }
01652
01653 }
01654
01655
01656
01657 void
01658 vec_shift_left(int ulen, sc_digit *u, int nsl)
01659 {
01660
01661 #ifdef DEBUG_SYSTEMC
01662 assert((ulen > 0) && (u != NULL));
01663 #endif
01664
01665 if (nsl <= 0)
01666 return;
01667
01668
01669 if (nsl >= (int) BITS_PER_DIGIT) {
01670
01671 int nd;
01672
01673 if (nsl % BITS_PER_DIGIT == 0) {
01674 nd = nsl / BITS_PER_DIGIT;
01675 nsl = 0;
01676 }
01677 else {
01678 nd = DIV_CEIL(nsl) - 1;
01679 nsl -= nd * BITS_PER_DIGIT;
01680 }
01681
01682 if (nd) {
01683
01684
01685 for (register int j = ulen - 1; j >= nd; --j)
01686 u[j] = u[j - nd];
01687
01688 vec_zero( sc_min( nd, ulen ), u );
01689
01690 }
01691
01692 if (nsl == 0)
01693 return;
01694
01695 }
01696
01697
01698 register sc_digit *uiter = u;
01699 sc_digit *uend = uiter + ulen;
01700
01701 int nsr = BITS_PER_DIGIT - nsl;
01702 sc_digit mask = one_and_ones(nsr);
01703
01704 register sc_digit carry = 0;
01705
01706 while (uiter < uend) {
01707 register sc_digit uval = (*uiter);
01708 (*uiter++) = (((uval & mask) << nsl) | carry);
01709 carry = uval >> nsr;
01710 }
01711
01712 if (uiter < uend)
01713 (*uiter) = carry;
01714
01715 }
01716
01717
01718
01719 void
01720 vec_shift_right(int ulen, sc_digit *u, int nsr, sc_digit fill)
01721 {
01722
01723 #ifdef DEBUG_SYSTEMC
01724 assert((ulen > 0) && (u != NULL));
01725 #endif
01726
01727
01728
01729 if (nsr <= 0)
01730 return;
01731
01732
01733 if (nsr >= (int) BITS_PER_DIGIT) {
01734
01735 int nd;
01736
01737 if (nsr % BITS_PER_DIGIT == 0) {
01738 nd = nsr / BITS_PER_DIGIT;
01739 nsr = 0;
01740 }
01741 else {
01742 nd = DIV_CEIL(nsr) - 1;
01743 nsr -= nd * BITS_PER_DIGIT;
01744 }
01745
01746 if (nd) {
01747
01748
01749 for (register int j = 0; j < (ulen - nd); ++j)
01750 u[j] = u[j + nd];
01751
01752 if (fill) {
01753 for (register int j = ulen - sc_min( nd, ulen ); j < ulen; ++j)
01754 u[j] = fill;
01755 }
01756 else
01757 vec_zero(ulen - sc_min( nd, ulen ), ulen, u);
01758
01759 }
01760
01761 if (nsr == 0)
01762 return;
01763
01764 }
01765
01766
01767 sc_digit *ubegin = u;
01768 register sc_digit *uiter = (ubegin + ulen);
01769
01770 int nsl = BITS_PER_DIGIT - nsr;
01771 sc_digit mask = one_and_ones(nsr);
01772
01773 register sc_digit carry = (fill & mask) << nsl;
01774
01775 while (ubegin < uiter) {
01776 register sc_digit uval = (*--uiter);
01777 (*uiter) = (uval >> nsr) | carry;
01778 carry = (uval & mask) << nsl;
01779 }
01780
01781 }
01782
01783
01784
01785
01786 void
01787 vec_reverse(int unb, int und, sc_digit *ud,
01788 int l, int r)
01789 {
01790
01791 #ifdef DEBUG_SYSTEMC
01792 assert((unb > 0) && (und > 0) && (ud != NULL));
01793 assert((0 <= r) && (r <= l) && (l < unb));
01794 #endif
01795
01796 if (l < r) {
01797 char msg[BUFSIZ];
01798 std::sprintf( msg, "vec_reverse( int, int, sc_digit*, int l, int r ) : "
01799 "l = %d < r = %d is not valid",
01800 l, r );
01801 SC_REPORT_ERROR( sc_core::SC_ID_CONVERSION_FAILED_, msg );
01802 }
01803
01804
01805 r = sc_max(r, 0);
01806 l = sc_min(l, unb - 1);
01807
01808
01809 #ifdef SC_MAX_NBITS
01810 sc_digit d[MAX_NDIGITS];
01811 #else
01812 sc_digit *d = new sc_digit[und];
01813 #endif
01814
01815
01816 vec_copy(und, d, ud);
01817
01818
01819
01820
01821 for (register int i = l, j = r; i >= r; --i, ++j) {
01822
01823 if ((d[digit_ord(i)] & one_and_zeros(bit_ord(i))) != 0)
01824 ud[digit_ord(j)] |= one_and_zeros(bit_ord(j));
01825 else
01826 ud[digit_ord(j)] &= ~(one_and_zeros(bit_ord(j)));
01827
01828 }
01829
01830 #ifndef SC_MAX_NBITS
01831 delete [] d;
01832 #endif
01833
01834 }
01835
01836 }
01837
01838
01839