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