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 58 void 59 _d2v(Vlong *y, double d) 60 { 61 union { double d; struct Vlong; } x; 62 ulong xhi, xlo, ylo, yhi; 63 int sh; 64 65 x.d = d; 66 67 xhi = (x.hi & 0xfffff) | 0x100000; 68 xlo = x.lo; 69 sh = 1075 - ((x.hi >> 20) & 0x7ff); 70 71 ylo = 0; 72 yhi = 0; 73 if(sh >= 0) { 74 /* v = (hi||lo) >> sh */ 75 if(sh < 32) { 76 if(sh == 0) { 77 ylo = xlo; 78 yhi = xhi; 79 } else { 80 ylo = (xlo >> sh) | (xhi << (32-sh)); 81 yhi = xhi >> sh; 82 } 83 } else { 84 if(sh == 32) { 85 ylo = xhi; 86 } else 87 if(sh < 64) { 88 ylo = xhi >> (sh-32); 89 } 90 } 91 } else { 92 /* v = (hi||lo) << -sh */ 93 sh = -sh; 94 if(sh <= 10) { 95 ylo = xlo << sh; 96 yhi = (xhi << sh) | (xlo >> (32-sh)); 97 } else { 98 /* overflow */ 99 yhi = d; /* causes something awful */ 100 } 101 } 102 if(x.hi & SIGN(32)) { 103 if(ylo != 0) { 104 ylo = -ylo; 105 yhi = ~yhi; 106 } else 107 yhi = -yhi; 108 } 109 110 y->hi = yhi; 111 y->lo = ylo; 112 } 113 114 void 115 _f2v(Vlong *y, float f) 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 141 static void 142 dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r) 143 { 144 ulong numlo, numhi, denhi, denlo, quohi, quolo, t; 145 int i; 146 147 numhi = num.hi; 148 numlo = num.lo; 149 denhi = den.hi; 150 denlo = den.lo; 151 152 /* 153 * get a divide by zero 154 */ 155 if(denlo==0 && denhi==0) { 156 numlo = numlo / denlo; 157 } 158 159 /* 160 * set up the divisor and find the number of iterations needed 161 */ 162 if(numhi >= SIGN(32)) { 163 quohi = SIGN(32); 164 quolo = 0; 165 } else { 166 quohi = numhi; 167 quolo = numlo; 168 } 169 i = 0; 170 while(denhi < quohi || (denhi == quohi && denlo < quolo)) { 171 denhi = (denhi<<1) | (denlo>>31); 172 denlo <<= 1; 173 i++; 174 } 175 176 quohi = 0; 177 quolo = 0; 178 for(; i >= 0; i--) { 179 quohi = (quohi<<1) | (quolo>>31); 180 quolo <<= 1; 181 if(numhi > denhi || (numhi == denhi && numlo >= denlo)) { 182 t = numlo; 183 numlo -= denlo; 184 if(numlo > t) 185 numhi--; 186 numhi -= denhi; 187 quolo |= 1; 188 } 189 denlo = (denlo>>1) | (denhi<<31); 190 denhi >>= 1; 191 } 192 193 if(q) { 194 q->lo = quolo; 195 q->hi = quohi; 196 } 197 if(r) { 198 r->lo = numlo; 199 r->hi = numhi; 200 } 201 } 202 203 void 204 _divvu(Vlong *q, Vlong n, Vlong d) 205 { 206 207 if(n.hi == 0 && d.hi == 0) { 208 q->hi = 0; 209 q->lo = n.lo / d.lo; 210 return; 211 } 212 dodiv(n, d, q, 0); 213 } 214 215 void 216 _modvu(Vlong *r, Vlong n, Vlong d) 217 { 218 219 if(n.hi == 0 && d.hi == 0) { 220 r->hi = 0; 221 r->lo = n.lo % d.lo; 222 return; 223 } 224 dodiv(n, d, 0, r); 225 } 226 227 static void 228 vneg(Vlong *v) 229 { 230 231 if(v->lo == 0) { 232 v->hi = -v->hi; 233 return; 234 } 235 v->lo = -v->lo; 236 v->hi = ~v->hi; 237 } 238 239 void 240 _divv(Vlong *q, Vlong n, Vlong d) 241 { 242 long nneg, dneg; 243 244 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { 245 q->lo = (long)n.lo / (long)d.lo; 246 q->hi = ((long)q->lo) >> 31; 247 return; 248 } 249 nneg = n.hi >> 31; 250 if(nneg) 251 vneg(&n); 252 dneg = d.hi >> 31; 253 if(dneg) 254 vneg(&d); 255 dodiv(n, d, q, 0); 256 if(nneg != dneg) 257 vneg(q); 258 } 259 260 void 261 _modv(Vlong *r, Vlong n, Vlong d) 262 { 263 long nneg, dneg; 264 265 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { 266 r->lo = (long)n.lo % (long)d.lo; 267 r->hi = ((long)r->lo) >> 31; 268 return; 269 } 270 nneg = n.hi >> 31; 271 if(nneg) 272 vneg(&n); 273 dneg = d.hi >> 31; 274 if(dneg) 275 vneg(&d); 276 dodiv(n, d, 0, r); 277 if(nneg) 278 vneg(r); 279 } 280 281 void 282 _rshav(Vlong *r, Vlong a, int b) 283 { 284 long t; 285 286 t = a.hi; 287 if(b >= 32) { 288 r->hi = t>>31; 289 if(b >= 64) { 290 /* this is illegal re C standard */ 291 r->lo = t>>31; 292 return; 293 } 294 r->lo = t >> (b-32); 295 return; 296 } 297 if(b <= 0) { 298 r->hi = t; 299 r->lo = a.lo; 300 return; 301 } 302 r->hi = t >> b; 303 r->lo = (t << (32-b)) | (a.lo >> b); 304 } 305 306 void 307 _rshlv(Vlong *r, Vlong a, int b) 308 { 309 ulong t; 310 311 t = a.hi; 312 if(b >= 32) { 313 r->hi = 0; 314 if(b >= 64) { 315 /* this is illegal re C standard */ 316 r->lo = 0; 317 return; 318 } 319 r->lo = t >> (b-32); 320 return; 321 } 322 if(b <= 0) { 323 r->hi = t; 324 r->lo = a.lo; 325 return; 326 } 327 r->hi = t >> b; 328 r->lo = (t << (32-b)) | (a.lo >> b); 329 } 330 331 void 332 _lshv(Vlong *r, Vlong a, int b) 333 { 334 ulong t; 335 336 t = a.lo; 337 if(b >= 32) { 338 r->lo = 0; 339 if(b >= 64) { 340 /* this is illegal re C standard */ 341 r->hi = 0; 342 return; 343 } 344 r->hi = t << (b-32); 345 return; 346 } 347 if(b <= 0) { 348 r->lo = t; 349 r->hi = a.hi; 350 return; 351 } 352 r->lo = t << b; 353 r->hi = (t >> (32-b)) | (a.hi << b); 354 } 355 356 void 357 _andv(Vlong *r, Vlong a, Vlong b) 358 { 359 r->hi = a.hi & b.hi; 360 r->lo = a.lo & b.lo; 361 } 362 363 void 364 _orv(Vlong *r, Vlong a, Vlong b) 365 { 366 r->hi = a.hi | b.hi; 367 r->lo = a.lo | b.lo; 368 } 369 370 void 371 _xorv(Vlong *r, Vlong a, Vlong b) 372 { 373 r->hi = a.hi ^ b.hi; 374 r->lo = a.lo ^ b.lo; 375 } 376 377 void 378 _vpp(Vlong *l, Vlong *r) 379 { 380 381 l->hi = r->hi; 382 l->lo = r->lo; 383 r->lo++; 384 if(r->lo == 0) 385 r->hi++; 386 } 387 388 void 389 _vmm(Vlong *l, Vlong *r) 390 { 391 392 l->hi = r->hi; 393 l->lo = r->lo; 394 if(r->lo == 0) 395 r->hi--; 396 r->lo--; 397 } 398 399 void 400 _ppv(Vlong *l, Vlong *r) 401 { 402 403 r->lo++; 404 if(r->lo == 0) 405 r->hi++; 406 l->hi = r->hi; 407 l->lo = r->lo; 408 } 409 410 void 411 _mmv(Vlong *l, Vlong *r) 412 { 413 414 if(r->lo == 0) 415 r->hi--; 416 r->lo--; 417 l->hi = r->hi; 418 l->lo = r->lo; 419 } 420 421 void 422 _vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv) 423 { 424 Vlong t, u; 425 426 u = *ret; 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