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