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 lo; 17 ulong hi; 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 51 void 52 _d2v(Vlong *y, double d) 53 { 54 union { double d; struct Vlong; } x; 55 ulong xhi, xlo, ylo, yhi; 56 int sh; 57 58 x.d = d; 59 60 xhi = (x.hi & 0xfffff) | 0x100000; 61 xlo = x.lo; 62 sh = 1075 - ((x.hi >> 20) & 0x7ff); 63 64 ylo = 0; 65 yhi = 0; 66 if(sh >= 0) { 67 /* v = (hi||lo) >> sh */ 68 if(sh < 32) { 69 if(sh == 0) { 70 ylo = xlo; 71 yhi = xhi; 72 } else { 73 ylo = (xlo >> sh) | (xhi << (32-sh)); 74 yhi = xhi >> sh; 75 } 76 } else { 77 if(sh == 32) { 78 ylo = xhi; 79 } else 80 if(sh < 64) { 81 ylo = xhi >> (sh-32); 82 } 83 } 84 } else { 85 /* v = (hi||lo) << -sh */ 86 sh = -sh; 87 if(sh <= 10) { 88 ylo = xlo << sh; 89 yhi = (xhi << sh) | (xlo >> (32-sh)); 90 } else { 91 /* overflow */ 92 yhi = d; /* causes something awful */ 93 } 94 } 95 if(x.hi & SIGN(32)) { 96 if(ylo != 0) { 97 ylo = -ylo; 98 yhi = ~yhi; 99 } else 100 yhi = -yhi; 101 } 102 103 y->hi = yhi; 104 y->lo = ylo; 105 } 106 107 void 108 _f2v(Vlong *y, float f) 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 *q, Vlong *r) 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(q) { 186 q->lo = quolo; 187 q->hi = quohi; 188 } 189 if(r) { 190 r->lo = numlo; 191 r->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 = *ret; 419 switch(type) { 420 default: 421 abort(); 422 break; 423 424 case 1: /* schar */ 425 t.lo = *(schar*)lv; 426 t.hi = t.lo >> 31; 427 fn(&u, t, rv); 428 *(schar*)lv = u.lo; 429 break; 430 431 case 2: /* uchar */ 432 t.lo = *(uchar*)lv; 433 t.hi = 0; 434 fn(&u, t, rv); 435 *(uchar*)lv = u.lo; 436 break; 437 438 case 3: /* short */ 439 t.lo = *(short*)lv; 440 t.hi = t.lo >> 31; 441 fn(&u, t, rv); 442 *(short*)lv = u.lo; 443 break; 444 445 case 4: /* ushort */ 446 t.lo = *(ushort*)lv; 447 t.hi = 0; 448 fn(&u, t, rv); 449 *(ushort*)lv = u.lo; 450 break; 451 452 case 9: /* int */ 453 t.lo = *(int*)lv; 454 t.hi = t.lo >> 31; 455 fn(&u, t, rv); 456 *(int*)lv = u.lo; 457 break; 458 459 case 10: /* uint */ 460 t.lo = *(uint*)lv; 461 t.hi = 0; 462 fn(&u, t, rv); 463 *(uint*)lv = u.lo; 464 break; 465 466 case 5: /* long */ 467 t.lo = *(long*)lv; 468 t.hi = t.lo >> 31; 469 fn(&u, t, rv); 470 *(long*)lv = u.lo; 471 break; 472 473 case 6: /* ulong */ 474 t.lo = *(ulong*)lv; 475 t.hi = 0; 476 fn(&u, t, rv); 477 *(ulong*)lv = u.lo; 478 break; 479 480 case 7: /* vlong */ 481 case 8: /* uvlong */ 482 fn(&u, *(Vlong*)lv, rv); 483 *(Vlong*)lv = u; 484 break; 485 } 486 *ret = u; 487 } 488 489 void 490 _p2v(Vlong *ret, void *p) 491 { 492 long t; 493 494 t = (ulong)p; 495 ret->lo = t; 496 ret->hi = 0; 497 } 498 499 void 500 _sl2v(Vlong *ret, long sl) 501 { 502 long t; 503 504 t = sl; 505 ret->lo = t; 506 ret->hi = t >> 31; 507 } 508 509 void 510 _ul2v(Vlong *ret, ulong ul) 511 { 512 long t; 513 514 t = ul; 515 ret->lo = t; 516 ret->hi = 0; 517 } 518 519 void 520 _si2v(Vlong *ret, int si) 521 { 522 long t; 523 524 t = si; 525 ret->lo = t; 526 ret->hi = t >> 31; 527 } 528 529 void 530 _ui2v(Vlong *ret, uint ui) 531 { 532 long t; 533 534 t = ui; 535 ret->lo = t; 536 ret->hi = 0; 537 } 538 539 void 540 _sh2v(Vlong *ret, long sh) 541 { 542 long t; 543 544 t = (sh << 16) >> 16; 545 ret->lo = t; 546 ret->hi = t >> 31; 547 } 548 549 void 550 _uh2v(Vlong *ret, ulong ul) 551 { 552 long t; 553 554 t = ul & 0xffff; 555 ret->lo = t; 556 ret->hi = 0; 557 } 558 559 void 560 _sc2v(Vlong *ret, long uc) 561 { 562 long t; 563 564 t = (uc << 24) >> 24; 565 ret->lo = t; 566 ret->hi = t >> 31; 567 } 568 569 void 570 _uc2v(Vlong *ret, ulong ul) 571 { 572 long t; 573 574 t = ul & 0xff; 575 ret->lo = t; 576 ret->hi = 0; 577 } 578 579 long 580 _v2sc(Vlong rv) 581 { 582 long t; 583 584 t = rv.lo & 0xff; 585 return (t << 24) >> 24; 586 } 587 588 long 589 _v2uc(Vlong rv) 590 { 591 592 return rv.lo & 0xff; 593 } 594 595 long 596 _v2sh(Vlong rv) 597 { 598 long t; 599 600 t = rv.lo & 0xffff; 601 return (t << 16) >> 16; 602 } 603 604 long 605 _v2uh(Vlong rv) 606 { 607 608 return rv.lo & 0xffff; 609 } 610 611 long 612 _v2sl(Vlong rv) 613 { 614 615 return rv.lo; 616 } 617 618 long 619 _v2ul(Vlong rv) 620 { 621 622 return rv.lo; 623 } 624 625 long 626 _v2si(Vlong rv) 627 { 628 629 return rv.lo; 630 } 631 632 long 633 _v2ui(Vlong rv) 634 { 635 636 return rv.lo; 637 } 638 639 int 640 _testv(Vlong rv) 641 { 642 return rv.lo || rv.hi; 643 } 644 645 int 646 _eqv(Vlong lv, Vlong rv) 647 { 648 return lv.lo == rv.lo && lv.hi == rv.hi; 649 } 650 651 int 652 _nev(Vlong lv, Vlong rv) 653 { 654 return lv.lo != rv.lo || lv.hi != rv.hi; 655 } 656 657 int 658 _ltv(Vlong lv, Vlong rv) 659 { 660 return (long)lv.hi < (long)rv.hi || 661 (lv.hi == rv.hi && lv.lo < rv.lo); 662 } 663 664 int 665 _lev(Vlong lv, Vlong rv) 666 { 667 return (long)lv.hi < (long)rv.hi || 668 (lv.hi == rv.hi && lv.lo <= rv.lo); 669 } 670 671 int 672 _gtv(Vlong lv, Vlong rv) 673 { 674 return (long)lv.hi > (long)rv.hi || 675 (lv.hi == rv.hi && lv.lo > rv.lo); 676 } 677 678 int 679 _gev(Vlong lv, Vlong rv) 680 { 681 return (long)lv.hi > (long)rv.hi || 682 (lv.hi == rv.hi && lv.lo >= rv.lo); 683 } 684 685 int 686 _lov(Vlong lv, Vlong rv) 687 { 688 return lv.hi < rv.hi || 689 (lv.hi == rv.hi && lv.lo < rv.lo); 690 } 691 692 int 693 _lsv(Vlong lv, Vlong rv) 694 { 695 return lv.hi < rv.hi || 696 (lv.hi == rv.hi && lv.lo <= rv.lo); 697 } 698 699 int 700 _hiv(Vlong lv, Vlong rv) 701 { 702 return lv.hi > rv.hi || 703 (lv.hi == rv.hi && lv.lo > rv.lo); 704 } 705 706 int 707 _hsv(Vlong lv, Vlong rv) 708 { 709 return lv.hi > rv.hi || 710 (lv.hi == rv.hi && lv.lo >= rv.lo); 711 } 712