1 typedef unsigned long ulong; 2 typedef unsigned int uint; 3 typedef unsigned short ushort; 4 typedef unsigned char uchar; 5 typedef signed char schar; 6 7 #define SIGN(n) (1UL<<(n-1)) 8 9 typedef struct Vlong Vlong; 10 struct Vlong 11 { 12 union 13 { 14 struct 15 { 16 ulong hi; 17 ulong lo; 18 }; 19 struct 20 { 21 ushort hims; 22 ushort hils; 23 ushort loms; 24 ushort lols; 25 }; 26 }; 27 }; 28 29 void abort(void); 30 31 /* needed by profiler; can't be profiled */ 32 #pragma profile off 33 void 34 _addv(Vlong *r, Vlong a, Vlong b) 35 { 36 ulong lo, hi; 37 38 lo = a.lo + b.lo; 39 hi = a.hi + b.hi; 40 if(lo < a.lo) 41 hi++; 42 r->lo = lo; 43 r->hi = hi; 44 } 45 46 void 47 _subv(Vlong *r, Vlong a, Vlong b) 48 { 49 ulong lo, hi; 50 51 lo = a.lo - b.lo; 52 hi = a.hi - b.hi; 53 if(lo > a.lo) 54 hi--; 55 r->lo = lo; 56 r->hi = hi; 57 } 58 59 #pragma profile on 60 61 void 62 _d2v(Vlong *y, double d) 63 { 64 union { double d; struct Vlong; } x; 65 ulong xhi, xlo, ylo, yhi; 66 int sh; 67 68 x.d = d; 69 70 xhi = (x.hi & 0xfffff) | 0x100000; 71 xlo = x.lo; 72 sh = 1075 - ((x.hi >> 20) & 0x7ff); 73 74 ylo = 0; 75 yhi = 0; 76 if(sh >= 0) { 77 /* v = (hi||lo) >> sh */ 78 if(sh < 32) { 79 if(sh == 0) { 80 ylo = xlo; 81 yhi = xhi; 82 } else { 83 ylo = (xlo >> sh) | (xhi << (32-sh)); 84 yhi = xhi >> sh; 85 } 86 } else { 87 if(sh == 32) { 88 ylo = xhi; 89 } else 90 if(sh < 64) { 91 ylo = xhi >> (sh-32); 92 } 93 } 94 } else { 95 /* v = (hi||lo) << -sh */ 96 sh = -sh; 97 if(sh <= 10) { 98 ylo = xlo << sh; 99 yhi = (xhi << sh) | (xlo >> (32-sh)); 100 } else { 101 /* overflow */ 102 yhi = d; /* causes something awful */ 103 } 104 } 105 if(x.hi & SIGN(32)) { 106 if(ylo != 0) { 107 ylo = -ylo; 108 yhi = ~yhi; 109 } else 110 yhi = -yhi; 111 } 112 113 y->hi = yhi; 114 y->lo = ylo; 115 } 116 117 void 118 _f2v(Vlong *y, float f) 119 { 120 121 _d2v(y, f); 122 } 123 124 double 125 _v2d(Vlong x) 126 { 127 if(x.hi & SIGN(32)) { 128 if(x.lo) { 129 x.lo = -x.lo; 130 x.hi = ~x.hi; 131 } else 132 x.hi = -x.hi; 133 return -((long)x.hi*4294967296. + x.lo); 134 } 135 return (long)x.hi*4294967296. + x.lo; 136 } 137 138 float 139 _v2f(Vlong x) 140 { 141 return _v2d(x); 142 } 143 144 static void 145 dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r) 146 { 147 ulong numlo, numhi, denhi, denlo, quohi, quolo, t; 148 int i; 149 150 numhi = num.hi; 151 numlo = num.lo; 152 denhi = den.hi; 153 denlo = den.lo; 154 155 /* 156 * get a divide by zero 157 */ 158 if(denlo==0 && denhi==0) { 159 numlo = numlo / denlo; 160 } 161 162 /* 163 * set up the divisor and find the number of iterations needed 164 */ 165 if(numhi >= SIGN(32)) { 166 quohi = SIGN(32); 167 quolo = 0; 168 } else { 169 quohi = numhi; 170 quolo = numlo; 171 } 172 i = 0; 173 while(denhi < quohi || (denhi == quohi && denlo < quolo)) { 174 denhi = (denhi<<1) | (denlo>>31); 175 denlo <<= 1; 176 i++; 177 } 178 179 quohi = 0; 180 quolo = 0; 181 for(; i >= 0; i--) { 182 quohi = (quohi<<1) | (quolo>>31); 183 quolo <<= 1; 184 if(numhi > denhi || (numhi == denhi && numlo >= denlo)) { 185 t = numlo; 186 numlo -= denlo; 187 if(numlo > t) 188 numhi--; 189 numhi -= denhi; 190 quolo |= 1; 191 } 192 denlo = (denlo>>1) | (denhi<<31); 193 denhi >>= 1; 194 } 195 196 if(q) { 197 q->lo = quolo; 198 q->hi = quohi; 199 } 200 if(r) { 201 r->lo = numlo; 202 r->hi = numhi; 203 } 204 } 205 206 void 207 _divvu(Vlong *q, Vlong n, Vlong d) 208 { 209 210 if(n.hi == 0 && d.hi == 0) { 211 q->hi = 0; 212 q->lo = n.lo / d.lo; 213 return; 214 } 215 dodiv(n, d, q, 0); 216 } 217 218 void 219 _modvu(Vlong *r, Vlong n, Vlong d) 220 { 221 222 if(n.hi == 0 && d.hi == 0) { 223 r->hi = 0; 224 r->lo = n.lo % d.lo; 225 return; 226 } 227 dodiv(n, d, 0, r); 228 } 229 230 static void 231 vneg(Vlong *v) 232 { 233 234 if(v->lo == 0) { 235 v->hi = -v->hi; 236 return; 237 } 238 v->lo = -v->lo; 239 v->hi = ~v->hi; 240 } 241 242 void 243 _divv(Vlong *q, Vlong n, Vlong d) 244 { 245 long nneg, dneg; 246 247 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { 248 q->lo = (long)n.lo / (long)d.lo; 249 q->hi = ((long)q->lo) >> 31; 250 return; 251 } 252 nneg = n.hi >> 31; 253 if(nneg) 254 vneg(&n); 255 dneg = d.hi >> 31; 256 if(dneg) 257 vneg(&d); 258 dodiv(n, d, q, 0); 259 if(nneg != dneg) 260 vneg(q); 261 } 262 263 void 264 _modv(Vlong *r, Vlong n, Vlong d) 265 { 266 long nneg, dneg; 267 268 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { 269 r->lo = (long)n.lo % (long)d.lo; 270 r->hi = ((long)r->lo) >> 31; 271 return; 272 } 273 nneg = n.hi >> 31; 274 if(nneg) 275 vneg(&n); 276 dneg = d.hi >> 31; 277 if(dneg) 278 vneg(&d); 279 dodiv(n, d, 0, r); 280 if(nneg) 281 vneg(r); 282 } 283 284 void 285 _rshav(Vlong *r, Vlong a, int b) 286 { 287 long t; 288 289 t = a.hi; 290 if(b >= 32) { 291 r->hi = t>>31; 292 if(b >= 64) { 293 /* this is illegal re C standard */ 294 r->lo = t>>31; 295 return; 296 } 297 r->lo = t >> (b-32); 298 return; 299 } 300 if(b <= 0) { 301 r->hi = t; 302 r->lo = a.lo; 303 return; 304 } 305 r->hi = t >> b; 306 r->lo = (t << (32-b)) | (a.lo >> b); 307 } 308 309 void 310 _rshlv(Vlong *r, Vlong a, int b) 311 { 312 ulong t; 313 314 t = a.hi; 315 if(b >= 32) { 316 r->hi = 0; 317 if(b >= 64) { 318 /* this is illegal re C standard */ 319 r->lo = 0; 320 return; 321 } 322 r->lo = t >> (b-32); 323 return; 324 } 325 if(b <= 0) { 326 r->hi = t; 327 r->lo = a.lo; 328 return; 329 } 330 r->hi = t >> b; 331 r->lo = (t << (32-b)) | (a.lo >> b); 332 } 333 334 void 335 _lshv(Vlong *r, Vlong a, int b) 336 { 337 ulong t; 338 339 t = a.lo; 340 if(b >= 32) { 341 r->lo = 0; 342 if(b >= 64) { 343 /* this is illegal re C standard */ 344 r->hi = 0; 345 return; 346 } 347 r->hi = t << (b-32); 348 return; 349 } 350 if(b <= 0) { 351 r->lo = t; 352 r->hi = a.hi; 353 return; 354 } 355 r->lo = t << b; 356 r->hi = (t >> (32-b)) | (a.hi << b); 357 } 358 359 void 360 _andv(Vlong *r, Vlong a, Vlong b) 361 { 362 r->hi = a.hi & b.hi; 363 r->lo = a.lo & b.lo; 364 } 365 366 void 367 _orv(Vlong *r, Vlong a, Vlong b) 368 { 369 r->hi = a.hi | b.hi; 370 r->lo = a.lo | b.lo; 371 } 372 373 void 374 _xorv(Vlong *r, Vlong a, Vlong b) 375 { 376 r->hi = a.hi ^ b.hi; 377 r->lo = a.lo ^ b.lo; 378 } 379 380 void 381 _vpp(Vlong *l, Vlong *r) 382 { 383 384 l->hi = r->hi; 385 l->lo = r->lo; 386 r->lo++; 387 if(r->lo == 0) 388 r->hi++; 389 } 390 391 void 392 _vmm(Vlong *l, Vlong *r) 393 { 394 395 l->hi = r->hi; 396 l->lo = r->lo; 397 if(r->lo == 0) 398 r->hi--; 399 r->lo--; 400 } 401 402 void 403 _ppv(Vlong *l, Vlong *r) 404 { 405 406 r->lo++; 407 if(r->lo == 0) 408 r->hi++; 409 l->hi = r->hi; 410 l->lo = r->lo; 411 } 412 413 void 414 _mmv(Vlong *l, Vlong *r) 415 { 416 417 if(r->lo == 0) 418 r->hi--; 419 r->lo--; 420 l->hi = r->hi; 421 l->lo = r->lo; 422 } 423 424 void 425 _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv) 426 { 427 Vlong t, u; 428 429 u = *ret; 430 switch(type) { 431 default: 432 abort(); 433 break; 434 435 case 1: /* schar */ 436 t.lo = *(schar*)lv; 437 t.hi = t.lo >> 31; 438 fn(&u, t, rv); 439 *(schar*)lv = u.lo; 440 break; 441 442 case 2: /* uchar */ 443 t.lo = *(uchar*)lv; 444 t.hi = 0; 445 fn(&u, t, rv); 446 *(uchar*)lv = u.lo; 447 break; 448 449 case 3: /* short */ 450 t.lo = *(short*)lv; 451 t.hi = t.lo >> 31; 452 fn(&u, t, rv); 453 *(short*)lv = u.lo; 454 break; 455 456 case 4: /* ushort */ 457 t.lo = *(ushort*)lv; 458 t.hi = 0; 459 fn(&u, t, rv); 460 *(ushort*)lv = u.lo; 461 break; 462 463 case 9: /* int */ 464 t.lo = *(int*)lv; 465 t.hi = t.lo >> 31; 466 fn(&u, t, rv); 467 *(int*)lv = u.lo; 468 break; 469 470 case 10: /* uint */ 471 t.lo = *(uint*)lv; 472 t.hi = 0; 473 fn(&u, t, rv); 474 *(uint*)lv = u.lo; 475 break; 476 477 case 5: /* long */ 478 t.lo = *(long*)lv; 479 t.hi = t.lo >> 31; 480 fn(&u, t, rv); 481 *(long*)lv = u.lo; 482 break; 483 484 case 6: /* ulong */ 485 t.lo = *(ulong*)lv; 486 t.hi = 0; 487 fn(&u, t, rv); 488 *(ulong*)lv = u.lo; 489 break; 490 491 case 7: /* vlong */ 492 case 8: /* uvlong */ 493 fn(&u, *(Vlong*)lv, rv); 494 *(Vlong*)lv = u; 495 break; 496 } 497 *ret = u; 498 } 499 500 void 501 _p2v(Vlong *ret, void *p) 502 { 503 long t; 504 505 t = (ulong)p; 506 ret->lo = t; 507 ret->hi = 0; 508 } 509 510 void 511 _sl2v(Vlong *ret, long sl) 512 { 513 long t; 514 515 t = sl; 516 ret->lo = t; 517 ret->hi = t >> 31; 518 } 519 520 void 521 _ul2v(Vlong *ret, ulong ul) 522 { 523 long t; 524 525 t = ul; 526 ret->lo = t; 527 ret->hi = 0; 528 } 529 530 void 531 _si2v(Vlong *ret, int si) 532 { 533 long t; 534 535 t = si; 536 ret->lo = t; 537 ret->hi = t >> 31; 538 } 539 540 void 541 _ui2v(Vlong *ret, uint ui) 542 { 543 long t; 544 545 t = ui; 546 ret->lo = t; 547 ret->hi = 0; 548 } 549 550 void 551 _sh2v(Vlong *ret, long sh) 552 { 553 long t; 554 555 t = (sh << 16) >> 16; 556 ret->lo = t; 557 ret->hi = t >> 31; 558 } 559 560 void 561 _uh2v(Vlong *ret, ulong ul) 562 { 563 long t; 564 565 t = ul & 0xffff; 566 ret->lo = t; 567 ret->hi = 0; 568 } 569 570 void 571 _sc2v(Vlong *ret, long uc) 572 { 573 long t; 574 575 t = (uc << 24) >> 24; 576 ret->lo = t; 577 ret->hi = t >> 31; 578 } 579 580 void 581 _uc2v(Vlong *ret, ulong ul) 582 { 583 long t; 584 585 t = ul & 0xff; 586 ret->lo = t; 587 ret->hi = 0; 588 } 589 590 long 591 _v2sc(Vlong rv) 592 { 593 long t; 594 595 t = rv.lo & 0xff; 596 return (t << 24) >> 24; 597 } 598 599 long 600 _v2uc(Vlong rv) 601 { 602 603 return rv.lo & 0xff; 604 } 605 606 long 607 _v2sh(Vlong rv) 608 { 609 long t; 610 611 t = rv.lo & 0xffff; 612 return (t << 16) >> 16; 613 } 614 615 long 616 _v2uh(Vlong rv) 617 { 618 619 return rv.lo & 0xffff; 620 } 621 622 long 623 _v2sl(Vlong rv) 624 { 625 626 return rv.lo; 627 } 628 629 long 630 _v2ul(Vlong rv) 631 { 632 633 return rv.lo; 634 } 635 636 long 637 _v2si(Vlong rv) 638 { 639 640 return rv.lo; 641 } 642 643 long 644 _v2ui(Vlong rv) 645 { 646 647 return rv.lo; 648 } 649 650 int 651 _testv(Vlong rv) 652 { 653 return rv.lo || rv.hi; 654 } 655 656 int 657 _eqv(Vlong lv, Vlong rv) 658 { 659 return lv.lo == rv.lo && lv.hi == rv.hi; 660 } 661 662 int 663 _nev(Vlong lv, Vlong rv) 664 { 665 return lv.lo != rv.lo || lv.hi != rv.hi; 666 } 667 668 int 669 _ltv(Vlong lv, Vlong rv) 670 { 671 return (long)lv.hi < (long)rv.hi || 672 (lv.hi == rv.hi && lv.lo < rv.lo); 673 } 674 675 int 676 _lev(Vlong lv, Vlong rv) 677 { 678 return (long)lv.hi < (long)rv.hi || 679 (lv.hi == rv.hi && lv.lo <= rv.lo); 680 } 681 682 int 683 _gtv(Vlong lv, Vlong rv) 684 { 685 return (long)lv.hi > (long)rv.hi || 686 (lv.hi == rv.hi && lv.lo > rv.lo); 687 } 688 689 int 690 _gev(Vlong lv, Vlong rv) 691 { 692 return (long)lv.hi > (long)rv.hi || 693 (lv.hi == rv.hi && lv.lo >= rv.lo); 694 } 695 696 int 697 _lov(Vlong lv, Vlong rv) 698 { 699 return lv.hi < rv.hi || 700 (lv.hi == rv.hi && lv.lo < rv.lo); 701 } 702 703 int 704 _lsv(Vlong lv, Vlong rv) 705 { 706 return lv.hi < rv.hi || 707 (lv.hi == rv.hi && lv.lo <= rv.lo); 708 } 709 710 int 711 _hiv(Vlong lv, Vlong rv) 712 { 713 return lv.hi > rv.hi || 714 (lv.hi == rv.hi && lv.lo > rv.lo); 715 } 716 717 int 718 _hsv(Vlong lv, Vlong rv) 719 { 720 return lv.hi > rv.hi || 721 (lv.hi == rv.hi && lv.lo >= rv.lo); 722 } 723