github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/gc/mparith2.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include <u.h> 6 #include <libc.h> 7 #include "go.h" 8 9 // 10 // return the significant 11 // words of the argument 12 // 13 static int 14 mplen(Mpint *a) 15 { 16 int i, n; 17 long *a1; 18 19 n = -1; 20 a1 = &a->a[0]; 21 for(i=0; i<Mpprec; i++) { 22 if(*a1++ != 0) 23 n = i; 24 } 25 return n+1; 26 } 27 28 // 29 // left shift mpint by one 30 // ignores sign 31 // 32 static void 33 mplsh(Mpint *a, int quiet) 34 { 35 long *a1, x; 36 int i, c; 37 38 c = 0; 39 a1 = &a->a[0]; 40 for(i=0; i<Mpprec; i++) { 41 x = (*a1 << 1) + c; 42 c = 0; 43 if(x >= Mpbase) { 44 x -= Mpbase; 45 c = 1; 46 } 47 *a1++ = x; 48 } 49 a->ovf = c; 50 if(a->ovf && !quiet) 51 yyerror("constant shift overflow"); 52 } 53 54 // 55 // left shift mpint by Mpscale 56 // ignores sign 57 // 58 static void 59 mplshw(Mpint *a, int quiet) 60 { 61 long *a1; 62 int i; 63 64 a1 = &a->a[Mpprec-1]; 65 if(*a1) { 66 a->ovf = 1; 67 if(!quiet) 68 yyerror("constant shift overflow"); 69 } 70 for(i=1; i<Mpprec; i++) { 71 a1[0] = a1[-1]; 72 a1--; 73 } 74 a1[0] = 0; 75 } 76 77 // 78 // right shift mpint by one 79 // ignores sign and overflow 80 // 81 static void 82 mprsh(Mpint *a) 83 { 84 long *a1, x, lo; 85 int i, c; 86 87 c = 0; 88 lo = a->a[0] & 1; 89 a1 = &a->a[Mpprec]; 90 for(i=0; i<Mpprec; i++) { 91 x = *--a1; 92 *a1 = (x + c) >> 1; 93 c = 0; 94 if(x & 1) 95 c = Mpbase; 96 } 97 if(a->neg && lo != 0) 98 mpaddcfix(a, -1); 99 } 100 101 // 102 // right shift mpint by Mpscale 103 // ignores sign and overflow 104 // 105 static void 106 mprshw(Mpint *a) 107 { 108 long *a1, lo; 109 int i; 110 111 lo = a->a[0]; 112 a1 = &a->a[0]; 113 for(i=1; i<Mpprec; i++) { 114 a1[0] = a1[1]; 115 a1++; 116 } 117 a1[0] = 0; 118 if(a->neg && lo != 0) 119 mpaddcfix(a, -1); 120 } 121 122 // 123 // return the sign of (abs(a)-abs(b)) 124 // 125 static int 126 mpcmp(Mpint *a, Mpint *b) 127 { 128 long x, *a1, *b1; 129 int i; 130 131 if(a->ovf || b->ovf) { 132 if(nsavederrors+nerrors == 0) 133 yyerror("ovf in cmp"); 134 return 0; 135 } 136 137 a1 = &a->a[0] + Mpprec; 138 b1 = &b->a[0] + Mpprec; 139 140 for(i=0; i<Mpprec; i++) { 141 x = *--a1 - *--b1; 142 if(x > 0) 143 return +1; 144 if(x < 0) 145 return -1; 146 } 147 return 0; 148 } 149 150 // 151 // negate a 152 // ignore sign and ovf 153 // 154 static void 155 mpneg(Mpint *a) 156 { 157 long x, *a1; 158 int i, c; 159 160 a1 = &a->a[0]; 161 c = 0; 162 for(i=0; i<Mpprec; i++) { 163 x = -*a1 -c; 164 c = 0; 165 if(x < 0) { 166 x += Mpbase; 167 c = 1; 168 } 169 *a1++ = x; 170 } 171 } 172 173 // shift left by s (or right by -s) 174 void 175 mpshiftfix(Mpint *a, int s) 176 { 177 if(s >= 0) { 178 while(s >= Mpscale) { 179 mplshw(a, 0); 180 s -= Mpscale; 181 } 182 while(s > 0) { 183 mplsh(a, 0); 184 s--; 185 } 186 } else { 187 s = -s; 188 while(s >= Mpscale) { 189 mprshw(a); 190 s -= Mpscale; 191 } 192 while(s > 0) { 193 mprsh(a); 194 s--; 195 } 196 } 197 } 198 199 /// implements fix arihmetic 200 201 void 202 mpaddfixfix(Mpint *a, Mpint *b, int quiet) 203 { 204 int i, c; 205 long x, *a1, *b1; 206 207 if(a->ovf || b->ovf) { 208 if(nsavederrors+nerrors == 0) 209 yyerror("ovf in mpaddxx"); 210 a->ovf = 1; 211 return; 212 } 213 214 c = 0; 215 a1 = &a->a[0]; 216 b1 = &b->a[0]; 217 if(a->neg != b->neg) 218 goto sub; 219 220 // perform a+b 221 for(i=0; i<Mpprec; i++) { 222 x = *a1 + *b1++ + c; 223 c = 0; 224 if(x >= Mpbase) { 225 x -= Mpbase; 226 c = 1; 227 } 228 *a1++ = x; 229 } 230 a->ovf = c; 231 if(a->ovf && !quiet) 232 yyerror("constant addition overflow"); 233 234 return; 235 236 sub: 237 // perform a-b 238 switch(mpcmp(a, b)) { 239 case 0: 240 mpmovecfix(a, 0); 241 break; 242 243 case 1: 244 for(i=0; i<Mpprec; i++) { 245 x = *a1 - *b1++ - c; 246 c = 0; 247 if(x < 0) { 248 x += Mpbase; 249 c = 1; 250 } 251 *a1++ = x; 252 } 253 break; 254 255 case -1: 256 a->neg ^= 1; 257 for(i=0; i<Mpprec; i++) { 258 x = *b1++ - *a1 - c; 259 c = 0; 260 if(x < 0) { 261 x += Mpbase; 262 c = 1; 263 } 264 *a1++ = x; 265 } 266 break; 267 } 268 } 269 270 void 271 mpmulfixfix(Mpint *a, Mpint *b) 272 { 273 274 int i, j, na, nb; 275 long *a1, x; 276 Mpint s, q; 277 278 if(a->ovf || b->ovf) { 279 if(nsavederrors+nerrors == 0) 280 yyerror("ovf in mpmulfixfix"); 281 a->ovf = 1; 282 return; 283 } 284 285 // pick the smaller 286 // to test for bits 287 na = mplen(a); 288 nb = mplen(b); 289 if(na > nb) { 290 mpmovefixfix(&s, a); 291 a1 = &b->a[0]; 292 na = nb; 293 } else { 294 mpmovefixfix(&s, b); 295 a1 = &a->a[0]; 296 } 297 s.neg = 0; 298 299 mpmovecfix(&q, 0); 300 for(i=0; i<na; i++) { 301 x = *a1++; 302 for(j=0; j<Mpscale; j++) { 303 if(x & 1) 304 mpaddfixfix(&q, &s, 1); 305 mplsh(&s, 1); 306 x >>= 1; 307 } 308 } 309 310 q.neg = a->neg ^ b->neg; 311 mpmovefixfix(a, &q); 312 if(a->ovf) 313 yyerror("constant multiplication overflow"); 314 } 315 316 void 317 mpmulfract(Mpint *a, Mpint *b) 318 { 319 320 int i, j; 321 long *a1, x; 322 Mpint s, q; 323 324 if(a->ovf || b->ovf) { 325 if(nsavederrors+nerrors == 0) 326 yyerror("ovf in mpmulflt"); 327 a->ovf = 1; 328 return; 329 } 330 331 mpmovefixfix(&s, b); 332 a1 = &a->a[Mpprec]; 333 s.neg = 0; 334 mpmovecfix(&q, 0); 335 336 x = *--a1; 337 if(x != 0) 338 yyerror("mpmulfract not normal"); 339 340 for(i=0; i<Mpprec-1; i++) { 341 x = *--a1; 342 if(x == 0) { 343 mprshw(&s); 344 continue; 345 } 346 for(j=0; j<Mpscale; j++) { 347 x <<= 1; 348 if(x & Mpbase) 349 mpaddfixfix(&q, &s, 1); 350 mprsh(&s); 351 } 352 } 353 354 q.neg = a->neg ^ b->neg; 355 mpmovefixfix(a, &q); 356 if(a->ovf) 357 yyerror("constant multiplication overflow"); 358 } 359 360 void 361 mporfixfix(Mpint *a, Mpint *b) 362 { 363 int i; 364 long x, *a1, *b1; 365 366 x = 0; 367 if(a->ovf || b->ovf) { 368 if(nsavederrors+nerrors == 0) 369 yyerror("ovf in mporfixfix"); 370 mpmovecfix(a, 0); 371 a->ovf = 1; 372 return; 373 } 374 if(a->neg) { 375 a->neg = 0; 376 mpneg(a); 377 } 378 if(b->neg) 379 mpneg(b); 380 381 a1 = &a->a[0]; 382 b1 = &b->a[0]; 383 for(i=0; i<Mpprec; i++) { 384 x = *a1 | *b1++; 385 *a1++ = x; 386 } 387 388 if(b->neg) 389 mpneg(b); 390 if(x & Mpsign) { 391 a->neg = 1; 392 mpneg(a); 393 } 394 } 395 396 void 397 mpandfixfix(Mpint *a, Mpint *b) 398 { 399 int i; 400 long x, *a1, *b1; 401 402 x = 0; 403 if(a->ovf || b->ovf) { 404 if(nsavederrors+nerrors == 0) 405 yyerror("ovf in mpandfixfix"); 406 mpmovecfix(a, 0); 407 a->ovf = 1; 408 return; 409 } 410 if(a->neg) { 411 a->neg = 0; 412 mpneg(a); 413 } 414 if(b->neg) 415 mpneg(b); 416 417 a1 = &a->a[0]; 418 b1 = &b->a[0]; 419 for(i=0; i<Mpprec; i++) { 420 x = *a1 & *b1++; 421 *a1++ = x; 422 } 423 424 if(b->neg) 425 mpneg(b); 426 if(x & Mpsign) { 427 a->neg = 1; 428 mpneg(a); 429 } 430 } 431 432 void 433 mpandnotfixfix(Mpint *a, Mpint *b) 434 { 435 int i; 436 long x, *a1, *b1; 437 438 x = 0; 439 if(a->ovf || b->ovf) { 440 if(nsavederrors+nerrors == 0) 441 yyerror("ovf in mpandnotfixfix"); 442 mpmovecfix(a, 0); 443 a->ovf = 1; 444 return; 445 } 446 if(a->neg) { 447 a->neg = 0; 448 mpneg(a); 449 } 450 if(b->neg) 451 mpneg(b); 452 453 a1 = &a->a[0]; 454 b1 = &b->a[0]; 455 for(i=0; i<Mpprec; i++) { 456 x = *a1 & ~*b1++; 457 *a1++ = x; 458 } 459 460 if(b->neg) 461 mpneg(b); 462 if(x & Mpsign) { 463 a->neg = 1; 464 mpneg(a); 465 } 466 } 467 468 void 469 mpxorfixfix(Mpint *a, Mpint *b) 470 { 471 int i; 472 long x, *a1, *b1; 473 474 x = 0; 475 if(a->ovf || b->ovf) { 476 if(nsavederrors+nerrors == 0) 477 yyerror("ovf in mporfixfix"); 478 mpmovecfix(a, 0); 479 a->ovf = 1; 480 return; 481 } 482 if(a->neg) { 483 a->neg = 0; 484 mpneg(a); 485 } 486 if(b->neg) 487 mpneg(b); 488 489 a1 = &a->a[0]; 490 b1 = &b->a[0]; 491 for(i=0; i<Mpprec; i++) { 492 x = *a1 ^ *b1++; 493 *a1++ = x; 494 } 495 496 if(b->neg) 497 mpneg(b); 498 if(x & Mpsign) { 499 a->neg = 1; 500 mpneg(a); 501 } 502 } 503 504 void 505 mplshfixfix(Mpint *a, Mpint *b) 506 { 507 vlong s; 508 509 if(a->ovf || b->ovf) { 510 if(nsavederrors+nerrors == 0) 511 yyerror("ovf in mporfixfix"); 512 mpmovecfix(a, 0); 513 a->ovf = 1; 514 return; 515 } 516 s = mpgetfix(b); 517 if(s < 0 || s >= Mpprec*Mpscale) { 518 yyerror("stupid shift: %lld", s); 519 mpmovecfix(a, 0); 520 return; 521 } 522 523 mpshiftfix(a, s); 524 } 525 526 void 527 mprshfixfix(Mpint *a, Mpint *b) 528 { 529 vlong s; 530 531 if(a->ovf || b->ovf) { 532 if(nsavederrors+nerrors == 0) 533 yyerror("ovf in mprshfixfix"); 534 mpmovecfix(a, 0); 535 a->ovf = 1; 536 return; 537 } 538 s = mpgetfix(b); 539 if(s < 0 || s >= Mpprec*Mpscale) { 540 yyerror("stupid shift: %lld", s); 541 if(a->neg) 542 mpmovecfix(a, -1); 543 else 544 mpmovecfix(a, 0); 545 return; 546 } 547 548 mpshiftfix(a, -s); 549 } 550 551 void 552 mpnegfix(Mpint *a) 553 { 554 a->neg ^= 1; 555 } 556 557 vlong 558 mpgetfix(Mpint *a) 559 { 560 vlong v; 561 562 if(a->ovf) { 563 if(nsavederrors+nerrors == 0) 564 yyerror("constant overflow"); 565 return 0; 566 } 567 568 v = (uvlong)a->a[0]; 569 v |= (uvlong)a->a[1] << Mpscale; 570 v |= (uvlong)a->a[2] << (Mpscale+Mpscale); 571 if(a->neg) 572 v = -(uvlong)v; 573 return v; 574 } 575 576 void 577 mpmovecfix(Mpint *a, vlong c) 578 { 579 int i; 580 long *a1; 581 vlong x; 582 583 a->neg = 0; 584 a->ovf = 0; 585 586 x = c; 587 if(x < 0) { 588 a->neg = 1; 589 x = -(uvlong)x; 590 } 591 592 a1 = &a->a[0]; 593 for(i=0; i<Mpprec; i++) { 594 *a1++ = x&Mpmask; 595 x >>= Mpscale; 596 } 597 } 598 599 void 600 mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d) 601 { 602 int i, ns, ds; 603 604 ns = n->neg; 605 ds = d->neg; 606 n->neg = 0; 607 d->neg = 0; 608 609 mpmovefixfix(r, n); 610 mpmovecfix(q, 0); 611 612 // shift denominator until it 613 // is larger than numerator 614 for(i=0; i<Mpprec*Mpscale; i++) { 615 if(mpcmp(d, r) > 0) 616 break; 617 mplsh(d, 1); 618 } 619 620 // if it never happens 621 // denominator is probably zero 622 if(i >= Mpprec*Mpscale) { 623 q->ovf = 1; 624 r->ovf = 1; 625 n->neg = ns; 626 d->neg = ds; 627 yyerror("constant division overflow"); 628 return; 629 } 630 631 // shift denominator back creating 632 // quotient a bit at a time 633 // when done the remaining numerator 634 // will be the remainder 635 for(; i>0; i--) { 636 mplsh(q, 1); 637 mprsh(d); 638 if(mpcmp(d, r) <= 0) { 639 mpaddcfix(q, 1); 640 mpsubfixfix(r, d); 641 } 642 } 643 644 n->neg = ns; 645 d->neg = ds; 646 r->neg = ns; 647 q->neg = ns^ds; 648 } 649 650 static int 651 iszero(Mpint *a) 652 { 653 long *a1; 654 int i; 655 a1 = &a->a[0] + Mpprec; 656 for(i=0; i<Mpprec; i++) { 657 if(*--a1 != 0) 658 return 0; 659 } 660 return 1; 661 } 662 663 void 664 mpdivfract(Mpint *a, Mpint *b) 665 { 666 Mpint n, d; 667 int i, j, neg; 668 long *a1, x; 669 670 mpmovefixfix(&n, a); // numerator 671 mpmovefixfix(&d, b); // denominator 672 a1 = &a->a[Mpprec]; // quotient 673 674 neg = n.neg ^ d.neg; 675 n.neg = 0; 676 d.neg = 0; 677 for(i=0; i<Mpprec; i++) { 678 x = 0; 679 for(j=0; j<Mpscale; j++) { 680 x <<= 1; 681 if(mpcmp(&d, &n) <= 0) { 682 if(!iszero(&d)) 683 x |= 1; 684 mpsubfixfix(&n, &d); 685 } 686 mprsh(&d); 687 } 688 *--a1 = x; 689 } 690 a->neg = neg; 691 } 692 693 int 694 mptestfix(Mpint *a) 695 { 696 Mpint b; 697 int r; 698 699 mpmovecfix(&b, 0); 700 r = mpcmp(a, &b); 701 if(a->neg) { 702 if(r > 0) 703 return -1; 704 if(r < 0) 705 return +1; 706 } 707 return r; 708 }