LEFT | RIGHT |
(no file at all) | |
| 1 // Inferno's libkern/vlrt-386.c |
| 2 // http://code.google.com/p/inferno-os/source/browse/libkern/vlrt-386.c |
| 3 // |
| 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. |
| 5 // Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vita
nuova.com). All rights reserved. |
| 6 // Portions Copyright 2009 The Go Authors. All rights reserved. |
| 7 // |
| 8 // Permission is hereby granted, free of charge, to any person obtaining a copy |
| 9 // of this software and associated documentation files (the "Software"), to deal |
| 10 // in the Software without restriction, including without limitation the rights |
| 11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 12 // copies of the Software, and to permit persons to whom the Software is |
| 13 // furnished to do so, subject to the following conditions: |
| 14 // |
| 15 // The above copyright notice and this permission notice shall be included in |
| 16 // all copies or substantial portions of the Software. |
| 17 // |
| 18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| 24 // THE SOFTWARE. |
| 25 |
| 26 // +build arm 386 |
| 27 |
| 28 #include "textflag.h" |
| 29 |
| 30 /* |
| 31 * C runtime for 64-bit divide, others. |
| 32 * |
| 33 * TODO(rsc): The simple functions are dregs--8c knows how |
| 34 * to generate the code directly now. Find and remove. |
| 35 */ |
| 36 |
| 37 void runtime·panicdivide(void); |
| 38 |
| 39 typedef unsigned long ulong; |
| 40 typedef unsigned int uint; |
| 41 typedef unsigned short ushort; |
| 42 typedef unsigned char uchar; |
| 43 typedef signed char schar; |
| 44 |
| 45 #define SIGN(n) (1UL<<(n-1)) |
| 46 |
| 47 typedef struct Vlong Vlong; |
| 48 struct Vlong |
| 49 { |
| 50 ulong lo; |
| 51 ulong hi; |
| 52 }; |
| 53 |
| 54 typedef union Vlong64 Vlong64; |
| 55 union Vlong64 |
| 56 { |
| 57 long long v; |
| 58 Vlong v2; |
| 59 }; |
| 60 |
| 61 void runtime·abort(void); |
| 62 |
| 63 #pragma textflag NOSPLIT |
| 64 Vlong |
| 65 _addv(Vlong a, Vlong b) |
| 66 { |
| 67 Vlong r; |
| 68 |
| 69 r.lo = a.lo + b.lo; |
| 70 r.hi = a.hi + b.hi; |
| 71 if(r.lo < a.lo) |
| 72 r.hi++; |
| 73 return r; |
| 74 } |
| 75 |
| 76 #pragma textflag NOSPLIT |
| 77 Vlong |
| 78 _subv(Vlong a, Vlong b) |
| 79 { |
| 80 Vlong r; |
| 81 |
| 82 r.lo = a.lo - b.lo; |
| 83 r.hi = a.hi - b.hi; |
| 84 if(r.lo > a.lo) |
| 85 r.hi--; |
| 86 return r; |
| 87 } |
| 88 |
| 89 Vlong |
| 90 _d2v(double d) |
| 91 { |
| 92 union { double d; Vlong vl; } x; |
| 93 ulong xhi, xlo, ylo, yhi; |
| 94 int sh; |
| 95 Vlong y; |
| 96 |
| 97 x.d = d; |
| 98 |
| 99 xhi = (x.vl.hi & 0xfffff) | 0x100000; |
| 100 xlo = x.vl.lo; |
| 101 sh = 1075 - ((x.vl.hi >> 20) & 0x7ff); |
| 102 |
| 103 ylo = 0; |
| 104 yhi = 0; |
| 105 if(sh >= 0) { |
| 106 /* v = (hi||lo) >> sh */ |
| 107 if(sh < 32) { |
| 108 if(sh == 0) { |
| 109 ylo = xlo; |
| 110 yhi = xhi; |
| 111 } else { |
| 112 ylo = (xlo >> sh) | (xhi << (32-sh)); |
| 113 yhi = xhi >> sh; |
| 114 } |
| 115 } else { |
| 116 if(sh == 32) { |
| 117 ylo = xhi; |
| 118 } else |
| 119 if(sh < 64) { |
| 120 ylo = xhi >> (sh-32); |
| 121 } |
| 122 } |
| 123 } else { |
| 124 /* v = (hi||lo) << -sh */ |
| 125 sh = -sh; |
| 126 if(sh <= 10) { /* NOTE: sh <= 11 on ARM??? */ |
| 127 ylo = xlo << sh; |
| 128 yhi = (xhi << sh) | (xlo >> (32-sh)); |
| 129 } else { |
| 130 /* overflow */ |
| 131 yhi = d; /* causes something awful */ |
| 132 } |
| 133 } |
| 134 if(x.vl.hi & SIGN(32)) { |
| 135 if(ylo != 0) { |
| 136 ylo = -ylo; |
| 137 yhi = ~yhi; |
| 138 } else |
| 139 yhi = -yhi; |
| 140 } |
| 141 |
| 142 y.hi = yhi; |
| 143 y.lo = ylo; |
| 144 return y; |
| 145 } |
| 146 |
| 147 Vlong |
| 148 _f2v(float f) |
| 149 { |
| 150 return _d2v(f); |
| 151 } |
| 152 |
| 153 double |
| 154 _ul2d(ulong u) |
| 155 { |
| 156 // compensate for bug in c |
| 157 if(u & SIGN(32)) { |
| 158 u ^= SIGN(32); |
| 159 return 2147483648. + u; |
| 160 } |
| 161 return u; |
| 162 } |
| 163 |
| 164 double |
| 165 _v2d(Vlong x) |
| 166 { |
| 167 if(x.hi & SIGN(32)) { |
| 168 if(x.lo) { |
| 169 x.lo = -x.lo; |
| 170 x.hi = ~x.hi; |
| 171 } else |
| 172 x.hi = -x.hi; |
| 173 return -(_ul2d(x.hi)*4294967296. + _ul2d(x.lo)); |
| 174 } |
| 175 return (long)x.hi*4294967296. + x.lo; |
| 176 } |
| 177 |
| 178 float |
| 179 _v2f(Vlong x) |
| 180 { |
| 181 return _v2d(x); |
| 182 } |
| 183 |
| 184 ulong runtime·_div64by32(Vlong, ulong, ulong*); |
| 185 int runtime·_mul64by32(Vlong*, Vlong, ulong); |
| 186 |
| 187 static void |
| 188 slowdodiv(Vlong num, Vlong den, Vlong *q, Vlong *r) |
| 189 { |
| 190 ulong numlo, numhi, denhi, denlo, quohi, quolo, t; |
| 191 int i; |
| 192 |
| 193 numhi = num.hi; |
| 194 numlo = num.lo; |
| 195 denhi = den.hi; |
| 196 denlo = den.lo; |
| 197 |
| 198 /* |
| 199 * get a divide by zero |
| 200 */ |
| 201 if(denlo==0 && denhi==0) { |
| 202 runtime·panicdivide(); |
| 203 } |
| 204 |
| 205 /* |
| 206 * set up the divisor and find the number of iterations needed |
| 207 */ |
| 208 if(numhi >= SIGN(32)) { |
| 209 quohi = SIGN(32); |
| 210 quolo = 0; |
| 211 } else { |
| 212 quohi = numhi; |
| 213 quolo = numlo; |
| 214 } |
| 215 i = 0; |
| 216 while(denhi < quohi || (denhi == quohi && denlo < quolo)) { |
| 217 denhi = (denhi<<1) | (denlo>>31); |
| 218 denlo <<= 1; |
| 219 i++; |
| 220 } |
| 221 |
| 222 quohi = 0; |
| 223 quolo = 0; |
| 224 for(; i >= 0; i--) { |
| 225 quohi = (quohi<<1) | (quolo>>31); |
| 226 quolo <<= 1; |
| 227 if(numhi > denhi || (numhi == denhi && numlo >= denlo)) { |
| 228 t = numlo; |
| 229 numlo -= denlo; |
| 230 if(numlo > t) |
| 231 numhi--; |
| 232 numhi -= denhi; |
| 233 quolo |= 1; |
| 234 } |
| 235 denlo = (denlo>>1) | (denhi<<31); |
| 236 denhi >>= 1; |
| 237 } |
| 238 |
| 239 if(q) { |
| 240 q->lo = quolo; |
| 241 q->hi = quohi; |
| 242 } |
| 243 if(r) { |
| 244 r->lo = numlo; |
| 245 r->hi = numhi; |
| 246 } |
| 247 } |
| 248 |
| 249 #ifdef GOARCH_arm |
| 250 static void |
| 251 dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp) |
| 252 { |
| 253 slowdodiv(num, den, qp, rp); |
| 254 } |
| 255 #endif |
| 256 |
| 257 #ifdef GOARCH_386 |
| 258 static void |
| 259 dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp) |
| 260 { |
| 261 ulong n; |
| 262 Vlong x, q, r; |
| 263 ········ |
| 264 if(den.hi > num.hi || (den.hi == num.hi && den.lo > num.lo)){ |
| 265 if(qp) { |
| 266 qp->hi = 0; |
| 267 qp->lo = 0; |
| 268 } |
| 269 if(rp) { |
| 270 rp->hi = num.hi; |
| 271 rp->lo = num.lo; |
| 272 } |
| 273 return; |
| 274 } |
| 275 |
| 276 if(den.hi != 0){ |
| 277 q.hi = 0; |
| 278 n = num.hi/den.hi; |
| 279 if(runtime·_mul64by32(&x, den, n) || x.hi > num.hi || (x.hi == n
um.hi && x.lo > num.lo)) |
| 280 slowdodiv(num, den, &q, &r); |
| 281 else { |
| 282 q.lo = n; |
| 283 *(long long*)&r = *(long long*)&num - *(long long*)&x; |
| 284 } |
| 285 } else { |
| 286 if(num.hi >= den.lo){ |
| 287 if(den.lo == 0) |
| 288 runtime·panicdivide(); |
| 289 q.hi = n = num.hi/den.lo; |
| 290 num.hi -= den.lo*n; |
| 291 } else { |
| 292 q.hi = 0; |
| 293 } |
| 294 q.lo = runtime·_div64by32(num, den.lo, &r.lo); |
| 295 r.hi = 0; |
| 296 } |
| 297 if(qp) { |
| 298 qp->lo = q.lo; |
| 299 qp->hi = q.hi; |
| 300 } |
| 301 if(rp) { |
| 302 rp->lo = r.lo; |
| 303 rp->hi = r.hi; |
| 304 } |
| 305 } |
| 306 #endif |
| 307 |
| 308 Vlong |
| 309 _divvu(Vlong n, Vlong d) |
| 310 { |
| 311 Vlong q; |
| 312 |
| 313 if(n.hi == 0 && d.hi == 0) { |
| 314 if(d.lo == 0) |
| 315 runtime·panicdivide(); |
| 316 q.hi = 0; |
| 317 q.lo = n.lo / d.lo; |
| 318 return q; |
| 319 } |
| 320 dodiv(n, d, &q, 0); |
| 321 return q; |
| 322 } |
| 323 |
| 324 Vlong |
| 325 _modvu(Vlong n, Vlong d) |
| 326 { |
| 327 Vlong r; |
| 328 |
| 329 if(n.hi == 0 && d.hi == 0) { |
| 330 if(d.lo == 0) |
| 331 runtime·panicdivide(); |
| 332 r.hi = 0; |
| 333 r.lo = n.lo % d.lo; |
| 334 return r; |
| 335 } |
| 336 dodiv(n, d, 0, &r); |
| 337 return r; |
| 338 } |
| 339 |
| 340 static void |
| 341 vneg(Vlong *v) |
| 342 { |
| 343 |
| 344 if(v->lo == 0) { |
| 345 v->hi = -v->hi; |
| 346 return; |
| 347 } |
| 348 v->lo = -v->lo; |
| 349 v->hi = ~v->hi; |
| 350 } |
| 351 |
| 352 Vlong |
| 353 _divv(Vlong n, Vlong d) |
| 354 { |
| 355 long nneg, dneg; |
| 356 Vlong q; |
| 357 |
| 358 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { |
| 359 if((long)n.lo == -0x80000000 && (long)d.lo == -1) { |
| 360 // special case: 32-bit -0x80000000 / -1 causes divide e
rror, |
| 361 // but it's okay in this 64-bit context. |
| 362 q.lo = 0x80000000; |
| 363 q.hi = 0; |
| 364 return q; |
| 365 } |
| 366 if(d.lo == 0) |
| 367 runtime·panicdivide(); |
| 368 q.lo = (long)n.lo / (long)d.lo; |
| 369 q.hi = ((long)q.lo) >> 31; |
| 370 return q; |
| 371 } |
| 372 nneg = n.hi >> 31; |
| 373 if(nneg) |
| 374 vneg(&n); |
| 375 dneg = d.hi >> 31; |
| 376 if(dneg) |
| 377 vneg(&d); |
| 378 dodiv(n, d, &q, 0); |
| 379 if(nneg != dneg) |
| 380 vneg(&q); |
| 381 return q; |
| 382 } |
| 383 |
| 384 Vlong |
| 385 _modv(Vlong n, Vlong d) |
| 386 { |
| 387 long nneg, dneg; |
| 388 Vlong r; |
| 389 |
| 390 if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) { |
| 391 if((long)n.lo == -0x80000000 && (long)d.lo == -1) { |
| 392 // special case: 32-bit -0x80000000 % -1 causes divide e
rror, |
| 393 // but it's okay in this 64-bit context. |
| 394 r.lo = 0; |
| 395 r.hi = 0; |
| 396 return r; |
| 397 } |
| 398 if(d.lo == 0) |
| 399 runtime·panicdivide(); |
| 400 r.lo = (long)n.lo % (long)d.lo; |
| 401 r.hi = ((long)r.lo) >> 31; |
| 402 return r; |
| 403 } |
| 404 nneg = n.hi >> 31; |
| 405 if(nneg) |
| 406 vneg(&n); |
| 407 dneg = d.hi >> 31; |
| 408 if(dneg) |
| 409 vneg(&d); |
| 410 dodiv(n, d, 0, &r); |
| 411 if(nneg) |
| 412 vneg(&r); |
| 413 return r; |
| 414 } |
| 415 |
| 416 #pragma textflag NOSPLIT |
| 417 Vlong |
| 418 _rshav(Vlong a, int b) |
| 419 { |
| 420 long t; |
| 421 Vlong r; |
| 422 |
| 423 t = a.hi; |
| 424 if(b >= 32) { |
| 425 r.hi = t>>31; |
| 426 if(b >= 64) { |
| 427 /* this is illegal re C standard */ |
| 428 r.lo = t>>31; |
| 429 return r; |
| 430 } |
| 431 r.lo = t >> (b-32); |
| 432 return r; |
| 433 } |
| 434 if(b <= 0) { |
| 435 r.hi = t; |
| 436 r.lo = a.lo; |
| 437 return r; |
| 438 } |
| 439 r.hi = t >> b; |
| 440 r.lo = (t << (32-b)) | (a.lo >> b); |
| 441 return r; |
| 442 } |
| 443 |
| 444 #pragma textflag NOSPLIT |
| 445 Vlong |
| 446 _rshlv(Vlong a, int b) |
| 447 { |
| 448 ulong t; |
| 449 Vlong r; |
| 450 |
| 451 t = a.hi; |
| 452 if(b >= 32) { |
| 453 r.hi = 0; |
| 454 if(b >= 64) { |
| 455 /* this is illegal re C standard */ |
| 456 r.lo = 0; |
| 457 return r; |
| 458 } |
| 459 r.lo = t >> (b-32); |
| 460 return r; |
| 461 } |
| 462 if(b <= 0) { |
| 463 r.hi = t; |
| 464 r.lo = a.lo; |
| 465 return r; |
| 466 } |
| 467 r.hi = t >> b; |
| 468 r.lo = (t << (32-b)) | (a.lo >> b); |
| 469 return r; |
| 470 } |
| 471 |
| 472 #pragma textflag NOSPLIT |
| 473 Vlong |
| 474 _lshv(Vlong a, int b) |
| 475 { |
| 476 ulong t; |
| 477 |
| 478 t = a.lo; |
| 479 if(b >= 32) { |
| 480 if(b >= 64) { |
| 481 /* this is illegal re C standard */ |
| 482 return (Vlong){0, 0}; |
| 483 } |
| 484 return (Vlong){0, t<<(b-32)}; |
| 485 } |
| 486 if(b <= 0) { |
| 487 return (Vlong){t, a.hi}; |
| 488 } |
| 489 return (Vlong){t<<b, (t >> (32-b)) | (a.hi << b)}; |
| 490 } |
| 491 |
| 492 #pragma textflag NOSPLIT |
| 493 Vlong |
| 494 _andv(Vlong a, Vlong b) |
| 495 { |
| 496 Vlong r; |
| 497 |
| 498 r.hi = a.hi & b.hi; |
| 499 r.lo = a.lo & b.lo; |
| 500 return r; |
| 501 } |
| 502 |
| 503 #pragma textflag NOSPLIT |
| 504 Vlong |
| 505 _orv(Vlong a, Vlong b) |
| 506 { |
| 507 Vlong r; |
| 508 |
| 509 r.hi = a.hi | b.hi; |
| 510 r.lo = a.lo | b.lo; |
| 511 return r; |
| 512 } |
| 513 |
| 514 #pragma textflag NOSPLIT |
| 515 Vlong |
| 516 _xorv(Vlong a, Vlong b) |
| 517 { |
| 518 Vlong r; |
| 519 |
| 520 r.hi = a.hi ^ b.hi; |
| 521 r.lo = a.lo ^ b.lo; |
| 522 return r; |
| 523 } |
| 524 |
| 525 Vlong |
| 526 _vpp(Vlong *r) |
| 527 { |
| 528 Vlong l; |
| 529 |
| 530 l = *r; |
| 531 r->lo++; |
| 532 if(r->lo == 0) |
| 533 r->hi++; |
| 534 return l; |
| 535 } |
| 536 |
| 537 #pragma textflag NOSPLIT |
| 538 Vlong |
| 539 _vmm(Vlong *r) |
| 540 { |
| 541 Vlong l; |
| 542 |
| 543 l = *r; |
| 544 if(r->lo == 0) |
| 545 r->hi--; |
| 546 r->lo--; |
| 547 return l; |
| 548 } |
| 549 |
| 550 #pragma textflag NOSPLIT |
| 551 Vlong |
| 552 _ppv(Vlong *r) |
| 553 { |
| 554 |
| 555 r->lo++; |
| 556 if(r->lo == 0) |
| 557 r->hi++; |
| 558 return *r; |
| 559 } |
| 560 |
| 561 #pragma textflag NOSPLIT |
| 562 Vlong |
| 563 _mmv(Vlong *r) |
| 564 { |
| 565 |
| 566 if(r->lo == 0) |
| 567 r->hi--; |
| 568 r->lo--; |
| 569 return *r; |
| 570 } |
| 571 |
| 572 #pragma textflag NOSPLIT |
| 573 Vlong |
| 574 _vasop(void *lv, Vlong fn(Vlong, Vlong), int type, Vlong rv) |
| 575 { |
| 576 Vlong t, u; |
| 577 |
| 578 u.lo = 0; |
| 579 u.hi = 0; |
| 580 switch(type) { |
| 581 default: |
| 582 runtime·abort(); |
| 583 break; |
| 584 |
| 585 case 1: /* schar */ |
| 586 t.lo = *(schar*)lv; |
| 587 t.hi = t.lo >> 31; |
| 588 u = fn(t, rv); |
| 589 *(schar*)lv = u.lo; |
| 590 break; |
| 591 |
| 592 case 2: /* uchar */ |
| 593 t.lo = *(uchar*)lv; |
| 594 t.hi = 0; |
| 595 u = fn(t, rv); |
| 596 *(uchar*)lv = u.lo; |
| 597 break; |
| 598 |
| 599 case 3: /* short */ |
| 600 t.lo = *(short*)lv; |
| 601 t.hi = t.lo >> 31; |
| 602 u = fn(t, rv); |
| 603 *(short*)lv = u.lo; |
| 604 break; |
| 605 |
| 606 case 4: /* ushort */ |
| 607 t.lo = *(ushort*)lv; |
| 608 t.hi = 0; |
| 609 u = fn(t, rv); |
| 610 *(ushort*)lv = u.lo; |
| 611 break; |
| 612 |
| 613 case 9: /* int */ |
| 614 t.lo = *(int*)lv; |
| 615 t.hi = t.lo >> 31; |
| 616 u = fn(t, rv); |
| 617 *(int*)lv = u.lo; |
| 618 break; |
| 619 |
| 620 case 10: /* uint */ |
| 621 t.lo = *(uint*)lv; |
| 622 t.hi = 0; |
| 623 u = fn(t, rv); |
| 624 *(uint*)lv = u.lo; |
| 625 break; |
| 626 |
| 627 case 5: /* long */ |
| 628 t.lo = *(long*)lv; |
| 629 t.hi = t.lo >> 31; |
| 630 u = fn(t, rv); |
| 631 *(long*)lv = u.lo; |
| 632 break; |
| 633 |
| 634 case 6: /* ulong */ |
| 635 t.lo = *(ulong*)lv; |
| 636 t.hi = 0; |
| 637 u = fn(t, rv); |
| 638 *(ulong*)lv = u.lo; |
| 639 break; |
| 640 |
| 641 case 7: /* vlong */ |
| 642 case 8: /* uvlong */ |
| 643 if((void*)fn == _lshv || (void*)fn == _rshav || (void*)fn == _rs
hlv) |
| 644 u = ((Vlong(*)(Vlong,int))fn)(*(Vlong*)lv, *(int*)&rv); |
| 645 else |
| 646 u = fn(*(Vlong*)lv, rv); |
| 647 *(Vlong*)lv = u; |
| 648 break; |
| 649 } |
| 650 return u; |
| 651 } |
| 652 |
| 653 #pragma textflag NOSPLIT |
| 654 Vlong |
| 655 _p2v(void *p) |
| 656 { |
| 657 long t; |
| 658 Vlong ret; |
| 659 |
| 660 t = (ulong)p; |
| 661 ret.lo = t; |
| 662 ret.hi = 0; |
| 663 return ret; |
| 664 } |
| 665 |
| 666 #pragma textflag NOSPLIT |
| 667 Vlong |
| 668 _sl2v(long sl) |
| 669 { |
| 670 long t; |
| 671 Vlong ret; |
| 672 |
| 673 t = sl; |
| 674 ret.lo = t; |
| 675 ret.hi = t >> 31; |
| 676 return ret; |
| 677 } |
| 678 |
| 679 #pragma textflag NOSPLIT |
| 680 Vlong |
| 681 _ul2v(ulong ul) |
| 682 { |
| 683 long t; |
| 684 Vlong ret; |
| 685 |
| 686 t = ul; |
| 687 ret.lo = t; |
| 688 ret.hi = 0; |
| 689 return ret; |
| 690 } |
| 691 |
| 692 #pragma textflag NOSPLIT |
| 693 Vlong |
| 694 _si2v(int si) |
| 695 { |
| 696 return (Vlong){si, si>>31}; |
| 697 } |
| 698 |
| 699 #pragma textflag NOSPLIT |
| 700 Vlong |
| 701 _ui2v(uint ui) |
| 702 { |
| 703 long t; |
| 704 Vlong ret; |
| 705 |
| 706 t = ui; |
| 707 ret.lo = t; |
| 708 ret.hi = 0; |
| 709 return ret; |
| 710 } |
| 711 |
| 712 #pragma textflag NOSPLIT |
| 713 Vlong |
| 714 _sh2v(long sh) |
| 715 { |
| 716 long t; |
| 717 Vlong ret; |
| 718 |
| 719 t = (sh << 16) >> 16; |
| 720 ret.lo = t; |
| 721 ret.hi = t >> 31; |
| 722 return ret; |
| 723 } |
| 724 |
| 725 #pragma textflag NOSPLIT |
| 726 Vlong |
| 727 _uh2v(ulong ul) |
| 728 { |
| 729 long t; |
| 730 Vlong ret; |
| 731 |
| 732 t = ul & 0xffff; |
| 733 ret.lo = t; |
| 734 ret.hi = 0; |
| 735 return ret; |
| 736 } |
| 737 |
| 738 #pragma textflag NOSPLIT |
| 739 Vlong |
| 740 _sc2v(long uc) |
| 741 { |
| 742 long t; |
| 743 Vlong ret; |
| 744 |
| 745 t = (uc << 24) >> 24; |
| 746 ret.lo = t; |
| 747 ret.hi = t >> 31; |
| 748 return ret; |
| 749 } |
| 750 |
| 751 #pragma textflag NOSPLIT |
| 752 Vlong |
| 753 _uc2v(ulong ul) |
| 754 { |
| 755 long t; |
| 756 Vlong ret; |
| 757 |
| 758 t = ul & 0xff; |
| 759 ret.lo = t; |
| 760 ret.hi = 0; |
| 761 return ret; |
| 762 } |
| 763 |
| 764 #pragma textflag NOSPLIT |
| 765 long |
| 766 _v2sc(Vlong rv) |
| 767 { |
| 768 long t; |
| 769 |
| 770 t = rv.lo & 0xff; |
| 771 return (t << 24) >> 24; |
| 772 } |
| 773 |
| 774 #pragma textflag NOSPLIT |
| 775 long |
| 776 _v2uc(Vlong rv) |
| 777 { |
| 778 |
| 779 return rv.lo & 0xff; |
| 780 } |
| 781 |
| 782 #pragma textflag NOSPLIT |
| 783 long |
| 784 _v2sh(Vlong rv) |
| 785 { |
| 786 long t; |
| 787 |
| 788 t = rv.lo & 0xffff; |
| 789 return (t << 16) >> 16; |
| 790 } |
| 791 |
| 792 #pragma textflag NOSPLIT |
| 793 long |
| 794 _v2uh(Vlong rv) |
| 795 { |
| 796 |
| 797 return rv.lo & 0xffff; |
| 798 } |
| 799 |
| 800 #pragma textflag NOSPLIT |
| 801 long |
| 802 _v2sl(Vlong rv) |
| 803 { |
| 804 |
| 805 return rv.lo; |
| 806 } |
| 807 |
| 808 #pragma textflag NOSPLIT |
| 809 long |
| 810 _v2ul(Vlong rv) |
| 811 { |
| 812 |
| 813 return rv.lo; |
| 814 } |
| 815 |
| 816 #pragma textflag NOSPLIT |
| 817 long |
| 818 _v2si(Vlong rv) |
| 819 { |
| 820 return rv.lo; |
| 821 } |
| 822 |
| 823 #pragma textflag NOSPLIT |
| 824 long |
| 825 _v2ui(Vlong rv) |
| 826 { |
| 827 |
| 828 return rv.lo; |
| 829 } |
| 830 |
| 831 #pragma textflag NOSPLIT |
| 832 int |
| 833 _testv(Vlong rv) |
| 834 { |
| 835 return rv.lo || rv.hi; |
| 836 } |
| 837 |
| 838 #pragma textflag NOSPLIT |
| 839 int |
| 840 _eqv(Vlong lv, Vlong rv) |
| 841 { |
| 842 return lv.lo == rv.lo && lv.hi == rv.hi; |
| 843 } |
| 844 |
| 845 #pragma textflag NOSPLIT |
| 846 int |
| 847 _nev(Vlong lv, Vlong rv) |
| 848 { |
| 849 return lv.lo != rv.lo || lv.hi != rv.hi; |
| 850 } |
| 851 |
| 852 #pragma textflag NOSPLIT |
| 853 int |
| 854 _ltv(Vlong lv, Vlong rv) |
| 855 { |
| 856 return (long)lv.hi < (long)rv.hi || |
| 857 (lv.hi == rv.hi && lv.lo < rv.lo); |
| 858 } |
| 859 |
| 860 #pragma textflag NOSPLIT |
| 861 int |
| 862 _lev(Vlong lv, Vlong rv) |
| 863 { |
| 864 return (long)lv.hi < (long)rv.hi || |
| 865 (lv.hi == rv.hi && lv.lo <= rv.lo); |
| 866 } |
| 867 |
| 868 #pragma textflag NOSPLIT |
| 869 int |
| 870 _gtv(Vlong lv, Vlong rv) |
| 871 { |
| 872 return (long)lv.hi > (long)rv.hi || |
| 873 (lv.hi == rv.hi && lv.lo > rv.lo); |
| 874 } |
| 875 |
| 876 #pragma textflag NOSPLIT |
| 877 int |
| 878 _gev(Vlong lv, Vlong rv) |
| 879 { |
| 880 return (long)lv.hi > (long)rv.hi || |
| 881 (lv.hi == rv.hi && lv.lo >= rv.lo); |
| 882 } |
| 883 |
| 884 #pragma textflag NOSPLIT |
| 885 int |
| 886 _lov(Vlong lv, Vlong rv) |
| 887 { |
| 888 return lv.hi < rv.hi || |
| 889 (lv.hi == rv.hi && lv.lo < rv.lo); |
| 890 } |
| 891 |
| 892 #pragma textflag NOSPLIT |
| 893 int |
| 894 _lsv(Vlong lv, Vlong rv) |
| 895 { |
| 896 return lv.hi < rv.hi || |
| 897 (lv.hi == rv.hi && lv.lo <= rv.lo); |
| 898 } |
| 899 |
| 900 #pragma textflag NOSPLIT |
| 901 int |
| 902 _hiv(Vlong lv, Vlong rv) |
| 903 { |
| 904 return lv.hi > rv.hi || |
| 905 (lv.hi == rv.hi && lv.lo > rv.lo); |
| 906 } |
| 907 |
| 908 #pragma textflag NOSPLIT |
| 909 int |
| 910 _hsv(Vlong lv, Vlong rv) |
| 911 { |
| 912 return lv.hi > rv.hi || |
| 913 (lv.hi == rv.hi && lv.lo >= rv.lo); |
| 914 } |
LEFT | RIGHT |