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