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