github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/6c/txt.c (about) 1 // Inferno utils/6c/txt.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/txt.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 #include "gc.h" 32 33 void 34 ginit(void) 35 { 36 int i; 37 Type *t; 38 39 thechar = '6'; 40 thestring = "amd64"; 41 dodefine("_64BIT"); 42 listinit(); 43 nstring = 0; 44 mnstring = 0; 45 nrathole = 0; 46 pc = 0; 47 breakpc = -1; 48 continpc = -1; 49 cases = C; 50 firstp = P; 51 lastp = P; 52 tfield = types[TINT]; 53 54 typeword = typechlvp; 55 typecmplx = typesu; 56 57 /* TO DO */ 58 memmove(typechlpv, typechlp, sizeof(typechlpv)); 59 typechlpv[TVLONG] = 1; 60 typechlpv[TUVLONG] = 1; 61 62 zprog.link = P; 63 zprog.as = AGOK; 64 zprog.from.type = D_NONE; 65 zprog.from.index = D_NONE; 66 zprog.from.scale = 0; 67 zprog.to = zprog.from; 68 69 lregnode.op = OREGISTER; 70 lregnode.class = CEXREG; 71 lregnode.reg = REGTMP; 72 lregnode.complex = 0; 73 lregnode.addable = 11; 74 lregnode.type = types[TLONG]; 75 76 qregnode = lregnode; 77 qregnode.type = types[TVLONG]; 78 79 constnode.op = OCONST; 80 constnode.class = CXXX; 81 constnode.complex = 0; 82 constnode.addable = 20; 83 constnode.type = types[TLONG]; 84 85 vconstnode = constnode; 86 vconstnode.type = types[TVLONG]; 87 88 fconstnode.op = OCONST; 89 fconstnode.class = CXXX; 90 fconstnode.complex = 0; 91 fconstnode.addable = 20; 92 fconstnode.type = types[TDOUBLE]; 93 94 nodsafe = new(ONAME, Z, Z); 95 nodsafe->sym = slookup(".safe"); 96 nodsafe->type = types[TINT]; 97 nodsafe->etype = types[TINT]->etype; 98 nodsafe->class = CAUTO; 99 complex(nodsafe); 100 101 t = typ(TARRAY, types[TCHAR]); 102 symrathole = slookup(".rathole"); 103 symrathole->class = CGLOBL; 104 symrathole->type = t; 105 106 nodrat = new(ONAME, Z, Z); 107 nodrat->sym = symrathole; 108 nodrat->type = types[TIND]; 109 nodrat->etype = TVOID; 110 nodrat->class = CGLOBL; 111 complex(nodrat); 112 nodrat->type = t; 113 114 nodret = new(ONAME, Z, Z); 115 nodret->sym = slookup(".ret"); 116 nodret->type = types[TIND]; 117 nodret->etype = TIND; 118 nodret->class = CPARAM; 119 nodret = new(OIND, nodret, Z); 120 complex(nodret); 121 122 if(0) 123 com64init(); 124 125 for(i=0; i<nelem(reg); i++) { 126 reg[i] = 1; 127 if(i >= D_AX && i <= D_R15 && i != D_SP) 128 reg[i] = 0; 129 if(i >= D_X0 && i <= D_X7) 130 reg[i] = 0; 131 } 132 } 133 134 void 135 gclean(void) 136 { 137 int i; 138 Sym *s; 139 140 reg[D_SP]--; 141 for(i=D_AX; i<=D_R15; i++) 142 if(reg[i]) 143 diag(Z, "reg %R left allocated", i); 144 for(i=D_X0; i<=D_X7; i++) 145 if(reg[i]) 146 diag(Z, "reg %R left allocated", i); 147 while(mnstring) 148 outstring("", 1L); 149 symstring->type->width = nstring; 150 symrathole->type->width = nrathole; 151 for(i=0; i<NHASH; i++) 152 for(s = hash[i]; s != S; s = s->link) { 153 if(s->type == T) 154 continue; 155 if(s->type->width == 0) 156 continue; 157 if(s->class != CGLOBL && s->class != CSTATIC) 158 continue; 159 if(s->type == types[TENUM]) 160 continue; 161 gpseudo(AGLOBL, s, nodconst(s->type->width)); 162 } 163 nextpc(); 164 p->as = AEND; 165 outcode(); 166 } 167 168 void 169 nextpc(void) 170 { 171 172 p = alloc(sizeof(*p)); 173 *p = zprog; 174 p->lineno = nearln; 175 pc++; 176 if(firstp == P) { 177 firstp = p; 178 lastp = p; 179 return; 180 } 181 lastp->link = p; 182 lastp = p; 183 } 184 185 void 186 gargs(Node *n, Node *tn1, Node *tn2) 187 { 188 int32 regs; 189 Node fnxargs[20], *fnxp; 190 191 regs = cursafe; 192 193 fnxp = fnxargs; 194 garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */ 195 196 curarg = 0; 197 fnxp = fnxargs; 198 garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */ 199 200 cursafe = regs; 201 } 202 203 int 204 nareg(void) 205 { 206 int i, n; 207 208 n = 0; 209 for(i=D_AX; i<=D_R15; i++) 210 if(reg[i] == 0) 211 n++; 212 return n; 213 } 214 215 void 216 garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp) 217 { 218 Node nod; 219 220 if(n == Z) 221 return; 222 if(n->op == OLIST) { 223 garg1(n->left, tn1, tn2, f, fnxp); 224 garg1(n->right, tn1, tn2, f, fnxp); 225 return; 226 } 227 if(f == 0) { 228 if(n->complex >= FNX) { 229 regsalloc(*fnxp, n); 230 nod = znode; 231 nod.op = OAS; 232 nod.left = *fnxp; 233 nod.right = n; 234 nod.type = n->type; 235 cgen(&nod, Z); 236 (*fnxp)++; 237 } 238 return; 239 } 240 if(typesu[n->type->etype]) { 241 regaalloc(tn2, n); 242 if(n->complex >= FNX) { 243 sugen(*fnxp, tn2, n->type->width); 244 (*fnxp)++; 245 } else 246 sugen(n, tn2, n->type->width); 247 return; 248 } 249 if(REGARG >= 0 && curarg == 0 && typechlpv[n->type->etype]) { 250 regaalloc1(tn1, n); 251 if(n->complex >= FNX) { 252 cgen(*fnxp, tn1); 253 (*fnxp)++; 254 } else 255 cgen(n, tn1); 256 return; 257 } 258 if(vconst(n) == 0) { 259 regaalloc(tn2, n); 260 gmove(n, tn2); 261 return; 262 } 263 regalloc(tn1, n, Z); 264 if(n->complex >= FNX) { 265 cgen(*fnxp, tn1); 266 (*fnxp)++; 267 } else 268 cgen(n, tn1); 269 regaalloc(tn2, n); 270 gmove(tn1, tn2); 271 regfree(tn1); 272 } 273 274 Node* 275 nodgconst(vlong v, Type *t) 276 { 277 if(!typev[t->etype]) 278 return nodconst((int32)v); 279 vconstnode.vconst = v; 280 return &vconstnode; 281 } 282 283 Node* 284 nodconst(int32 v) 285 { 286 constnode.vconst = v; 287 return &constnode; 288 } 289 290 Node* 291 nodfconst(double d) 292 { 293 fconstnode.fconst = d; 294 return &fconstnode; 295 } 296 297 int 298 isreg(Node *n, int r) 299 { 300 301 if(n->op == OREGISTER) 302 if(n->reg == r) 303 return 1; 304 return 0; 305 } 306 307 int 308 nodreg(Node *n, Node *nn, int r) 309 { 310 int et; 311 312 *n = qregnode; 313 n->reg = r; 314 if(nn != Z){ 315 et = nn->type->etype; 316 if(!typefd[et] && nn->type->width <= SZ_LONG && 0) 317 n->type = typeu[et]? types[TUINT]: types[TINT]; 318 else 319 n->type = nn->type; 320 //print("nodreg %s [%s]\n", tnames[et], tnames[n->type->etype]); 321 n->lineno = nn->lineno; 322 } 323 if(reg[r] == 0) 324 return 0; 325 if(nn != Z) { 326 if(nn->op == OREGISTER) 327 if(nn->reg == r) 328 return 0; 329 } 330 return 1; 331 } 332 333 void 334 regret(Node *n, Node *nn) 335 { 336 int r; 337 338 r = REGRET; 339 if(typefd[nn->type->etype]) 340 r = FREGRET; 341 nodreg(n, nn, r); 342 reg[r]++; 343 } 344 345 void 346 regalloc(Node *n, Node *tn, Node *o) 347 { 348 int i; 349 350 switch(tn->type->etype) { 351 case TCHAR: 352 case TUCHAR: 353 case TSHORT: 354 case TUSHORT: 355 case TINT: 356 case TUINT: 357 case TLONG: 358 case TULONG: 359 case TVLONG: 360 case TUVLONG: 361 case TIND: 362 if(o != Z && o->op == OREGISTER) { 363 i = o->reg; 364 if(i >= D_AX && i <= D_R15) 365 goto out; 366 } 367 for(i=D_AX; i<=D_R15; i++) 368 if(reg[i] == 0) 369 goto out; 370 diag(tn, "out of fixed registers"); 371 goto err; 372 373 case TFLOAT: 374 case TDOUBLE: 375 if(o != Z && o->op == OREGISTER) { 376 i = o->reg; 377 if(i >= D_X0 && i <= D_X7) 378 goto out; 379 } 380 for(i=D_X0; i<=D_X7; i++) 381 if(reg[i] == 0) 382 goto out; 383 diag(tn, "out of float registers"); 384 goto out; 385 } 386 diag(tn, "unknown type in regalloc: %T", tn->type); 387 err: 388 i = 0; 389 out: 390 if(i) 391 reg[i]++; 392 nodreg(n, tn, i); 393 } 394 395 void 396 regialloc(Node *n, Node *tn, Node *o) 397 { 398 Node nod; 399 400 nod = *tn; 401 nod.type = types[TIND]; 402 regalloc(n, &nod, o); 403 } 404 405 void 406 regfree(Node *n) 407 { 408 int i; 409 410 i = 0; 411 if(n->op != OREGISTER && n->op != OINDREG) 412 goto err; 413 i = n->reg; 414 if(i < 0 || i >= nelem(reg)) 415 goto err; 416 if(reg[i] <= 0) 417 goto err; 418 reg[i]--; 419 return; 420 err: 421 diag(n, "error in regfree: %R", i); 422 } 423 424 void 425 regsalloc(Node *n, Node *nn) 426 { 427 cursafe = align(cursafe, nn->type, Aaut3, nil); 428 maxargsafe = maxround(maxargsafe, cursafe+curarg); 429 *n = *nodsafe; 430 n->xoffset = -(stkoff + cursafe); 431 n->type = nn->type; 432 n->etype = nn->type->etype; 433 n->lineno = nn->lineno; 434 } 435 436 void 437 regaalloc1(Node *n, Node *nn) 438 { 439 if(REGARG < 0) { 440 fatal(n, "regaalloc1 and REGARG<0"); 441 return; 442 } 443 nodreg(n, nn, REGARG); 444 reg[REGARG]++; 445 curarg = align(curarg, nn->type, Aarg1, nil); 446 curarg = align(curarg, nn->type, Aarg2, nil); 447 maxargsafe = maxround(maxargsafe, cursafe+curarg); 448 } 449 450 void 451 regaalloc(Node *n, Node *nn) 452 { 453 curarg = align(curarg, nn->type, Aarg1, nil); 454 *n = *nn; 455 n->op = OINDREG; 456 n->reg = REGSP; 457 n->xoffset = curarg; 458 n->complex = 0; 459 n->addable = 20; 460 curarg = align(curarg, nn->type, Aarg2, nil); 461 maxargsafe = maxround(maxargsafe, cursafe+curarg); 462 } 463 464 void 465 regind(Node *n, Node *nn) 466 { 467 468 if(n->op != OREGISTER) { 469 diag(n, "regind not OREGISTER"); 470 return; 471 } 472 n->op = OINDREG; 473 n->type = nn->type; 474 } 475 476 void 477 naddr(Node *n, Adr *a) 478 { 479 int32 v; 480 481 a->type = D_NONE; 482 if(n == Z) 483 return; 484 switch(n->op) { 485 default: 486 bad: 487 diag(n, "bad in naddr: %O %D", n->op, a); 488 break; 489 490 case OREGISTER: 491 a->type = n->reg; 492 a->sym = S; 493 break; 494 495 case OEXREG: 496 a->type = D_INDIR + D_GS; 497 a->offset = n->reg - 1; 498 break; 499 500 case OIND: 501 naddr(n->left, a); 502 if(a->type >= D_AX && a->type <= D_R15) 503 a->type += D_INDIR; 504 else 505 if(a->type == D_CONST) 506 a->type = D_NONE+D_INDIR; 507 else 508 if(a->type == D_ADDR) { 509 a->type = a->index; 510 a->index = D_NONE; 511 } else 512 goto bad; 513 break; 514 515 case OINDEX: 516 a->type = idx.ptr; 517 if(n->left->op == OADDR || n->left->op == OCONST) 518 naddr(n->left, a); 519 if(a->type >= D_AX && a->type <= D_R15) 520 a->type += D_INDIR; 521 else 522 if(a->type == D_CONST) 523 a->type = D_NONE+D_INDIR; 524 else 525 if(a->type == D_ADDR) { 526 a->type = a->index; 527 a->index = D_NONE; 528 } else 529 goto bad; 530 a->index = idx.reg; 531 a->scale = n->scale; 532 a->offset += n->xoffset; 533 break; 534 535 case OINDREG: 536 a->type = n->reg+D_INDIR; 537 a->sym = S; 538 a->offset = n->xoffset; 539 break; 540 541 case ONAME: 542 a->etype = n->etype; 543 a->type = D_STATIC; 544 a->sym = n->sym; 545 a->offset = n->xoffset; 546 if(n->class == CSTATIC) 547 break; 548 if(n->class == CEXTERN || n->class == CGLOBL) { 549 a->type = D_EXTERN; 550 break; 551 } 552 if(n->class == CAUTO) { 553 a->type = D_AUTO; 554 break; 555 } 556 if(n->class == CPARAM) { 557 a->type = D_PARAM; 558 break; 559 } 560 goto bad; 561 562 case OCONST: 563 if(typefd[n->type->etype]) { 564 a->type = D_FCONST; 565 a->dval = n->fconst; 566 break; 567 } 568 a->sym = S; 569 a->type = D_CONST; 570 if(typev[n->type->etype] || n->type->etype == TIND) 571 a->offset = n->vconst; 572 else 573 a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG); 574 break; 575 576 case OADDR: 577 naddr(n->left, a); 578 if(a->type >= D_INDIR) { 579 a->type -= D_INDIR; 580 break; 581 } 582 if(a->type == D_EXTERN || a->type == D_STATIC || 583 a->type == D_AUTO || a->type == D_PARAM) 584 if(a->index == D_NONE) { 585 a->index = a->type; 586 a->type = D_ADDR; 587 break; 588 } 589 goto bad; 590 591 case OADD: 592 if(n->right->op == OCONST) { 593 v = n->right->vconst; 594 naddr(n->left, a); 595 } else 596 if(n->left->op == OCONST) { 597 v = n->left->vconst; 598 naddr(n->right, a); 599 } else 600 goto bad; 601 a->offset += v; 602 break; 603 604 } 605 } 606 607 void 608 gcmp(int op, Node *n, vlong val) 609 { 610 Node *cn, nod; 611 612 cn = nodgconst(val, n->type); 613 if(!immconst(cn)){ 614 regalloc(&nod, n, Z); 615 gmove(cn, &nod); 616 gopcode(op, n->type, n, &nod); 617 regfree(&nod); 618 }else 619 gopcode(op, n->type, n, cn); 620 } 621 622 #define CASE(a,b) ((a<<8)|(b<<0)) 623 624 void 625 gmove(Node *f, Node *t) 626 { 627 int ft, tt, t64, a; 628 Node nod, nod1, nod2, nod3; 629 Prog *p1, *p2; 630 631 ft = f->type->etype; 632 tt = t->type->etype; 633 t64 = tt == TVLONG || tt == TUVLONG || tt == TIND; 634 if(debug['M']) 635 print("gop: %O %O[%s],%O[%s]\n", OAS, 636 f->op, tnames[ft], t->op, tnames[tt]); 637 if(typefd[ft] && f->op == OCONST) { 638 /* TO DO: pick up special constants, possibly preloaded */ 639 if(f->fconst == 0.0){ 640 regalloc(&nod, t, t); 641 gins(AXORPD, &nod, &nod); 642 gmove(&nod, t); 643 regfree(&nod); 644 return; 645 } 646 } 647 /* 648 * load 649 */ 650 if(ft == TVLONG || ft == TUVLONG) 651 if(f->op == OCONST) 652 if(f->vconst > 0x7fffffffLL || f->vconst < -0x7fffffffLL) 653 if(t->op != OREGISTER) { 654 regalloc(&nod, f, Z); 655 gmove(f, &nod); 656 gmove(&nod, t); 657 regfree(&nod); 658 return; 659 } 660 661 if(f->op == ONAME || f->op == OINDREG || 662 f->op == OIND || f->op == OINDEX) 663 switch(ft) { 664 case TCHAR: 665 a = AMOVBLSX; 666 if(t64) 667 a = AMOVBQSX; 668 goto ld; 669 case TUCHAR: 670 a = AMOVBLZX; 671 if(t64) 672 a = AMOVBQZX; 673 goto ld; 674 case TSHORT: 675 a = AMOVWLSX; 676 if(t64) 677 a = AMOVWQSX; 678 goto ld; 679 case TUSHORT: 680 a = AMOVWLZX; 681 if(t64) 682 a = AMOVWQZX; 683 goto ld; 684 case TINT: 685 case TLONG: 686 if(typefd[tt]) { 687 regalloc(&nod, t, t); 688 if(tt == TDOUBLE) 689 a = ACVTSL2SD; 690 else 691 a = ACVTSL2SS; 692 gins(a, f, &nod); 693 gmove(&nod, t); 694 regfree(&nod); 695 return; 696 } 697 a = AMOVL; 698 if(t64) 699 a = AMOVLQSX; 700 goto ld; 701 case TUINT: 702 case TULONG: 703 a = AMOVL; 704 if(t64) 705 a = AMOVLQZX; /* could probably use plain MOVL */ 706 goto ld; 707 case TVLONG: 708 if(typefd[tt]) { 709 regalloc(&nod, t, t); 710 if(tt == TDOUBLE) 711 a = ACVTSQ2SD; 712 else 713 a = ACVTSQ2SS; 714 gins(a, f, &nod); 715 gmove(&nod, t); 716 regfree(&nod); 717 return; 718 } 719 case TUVLONG: 720 a = AMOVQ; 721 goto ld; 722 case TIND: 723 a = AMOVQ; 724 725 ld: 726 regalloc(&nod, f, t); 727 nod.type = t64? types[TVLONG]: types[TINT]; 728 gins(a, f, &nod); 729 gmove(&nod, t); 730 regfree(&nod); 731 return; 732 733 case TFLOAT: 734 a = AMOVSS; 735 goto fld; 736 case TDOUBLE: 737 a = AMOVSD; 738 fld: 739 regalloc(&nod, f, t); 740 if(tt != TDOUBLE && tt != TFLOAT){ /* TO DO: why is this here */ 741 prtree(f, "odd tree"); 742 nod.type = t64? types[TVLONG]: types[TINT]; 743 } 744 gins(a, f, &nod); 745 gmove(&nod, t); 746 regfree(&nod); 747 return; 748 } 749 750 /* 751 * store 752 */ 753 if(t->op == ONAME || t->op == OINDREG || 754 t->op == OIND || t->op == OINDEX) 755 switch(tt) { 756 case TCHAR: 757 case TUCHAR: 758 a = AMOVB; goto st; 759 case TSHORT: 760 case TUSHORT: 761 a = AMOVW; goto st; 762 case TINT: 763 case TUINT: 764 case TLONG: 765 case TULONG: 766 a = AMOVL; goto st; 767 case TVLONG: 768 case TUVLONG: 769 case TIND: 770 a = AMOVQ; goto st; 771 772 st: 773 if(f->op == OCONST) { 774 gins(a, f, t); 775 return; 776 } 777 fst: 778 regalloc(&nod, t, f); 779 gmove(f, &nod); 780 gins(a, &nod, t); 781 regfree(&nod); 782 return; 783 784 case TFLOAT: 785 a = AMOVSS; 786 goto fst; 787 case TDOUBLE: 788 a = AMOVSD; 789 goto fst; 790 } 791 792 /* 793 * convert 794 */ 795 switch(CASE(ft,tt)) { 796 default: 797 /* 798 * integer to integer 799 ******** 800 a = AGOK; break; 801 802 case CASE( TCHAR, TCHAR): 803 case CASE( TUCHAR, TCHAR): 804 case CASE( TSHORT, TCHAR): 805 case CASE( TUSHORT,TCHAR): 806 case CASE( TINT, TCHAR): 807 case CASE( TUINT, TCHAR): 808 case CASE( TLONG, TCHAR): 809 case CASE( TULONG, TCHAR): 810 811 case CASE( TCHAR, TUCHAR): 812 case CASE( TUCHAR, TUCHAR): 813 case CASE( TSHORT, TUCHAR): 814 case CASE( TUSHORT,TUCHAR): 815 case CASE( TINT, TUCHAR): 816 case CASE( TUINT, TUCHAR): 817 case CASE( TLONG, TUCHAR): 818 case CASE( TULONG, TUCHAR): 819 820 case CASE( TSHORT, TSHORT): 821 case CASE( TUSHORT,TSHORT): 822 case CASE( TINT, TSHORT): 823 case CASE( TUINT, TSHORT): 824 case CASE( TLONG, TSHORT): 825 case CASE( TULONG, TSHORT): 826 827 case CASE( TSHORT, TUSHORT): 828 case CASE( TUSHORT,TUSHORT): 829 case CASE( TINT, TUSHORT): 830 case CASE( TUINT, TUSHORT): 831 case CASE( TLONG, TUSHORT): 832 case CASE( TULONG, TUSHORT): 833 834 case CASE( TINT, TINT): 835 case CASE( TUINT, TINT): 836 case CASE( TLONG, TINT): 837 case CASE( TULONG, TINT): 838 839 case CASE( TINT, TUINT): 840 case CASE( TUINT, TUINT): 841 case CASE( TLONG, TUINT): 842 case CASE( TULONG, TUINT): 843 *****/ 844 a = AMOVL; 845 break; 846 847 case CASE( TINT, TIND): 848 case CASE( TINT, TVLONG): 849 case CASE( TINT, TUVLONG): 850 case CASE( TLONG, TIND): 851 case CASE( TLONG, TVLONG): 852 case CASE( TLONG, TUVLONG): 853 a = AMOVLQSX; 854 if(f->op == OCONST) { 855 f->vconst &= (uvlong)0xffffffffU; 856 if(f->vconst & 0x80000000) 857 f->vconst |= (vlong)0xffffffff << 32; 858 a = AMOVQ; 859 } 860 break; 861 862 case CASE( TUINT, TIND): 863 case CASE( TUINT, TVLONG): 864 case CASE( TUINT, TUVLONG): 865 case CASE( TULONG, TVLONG): 866 case CASE( TULONG, TUVLONG): 867 case CASE( TULONG, TIND): 868 a = AMOVLQZX; 869 if(f->op == OCONST) { 870 f->vconst &= (uvlong)0xffffffffU; 871 a = AMOVQ; 872 } 873 break; 874 875 case CASE( TIND, TCHAR): 876 case CASE( TIND, TUCHAR): 877 case CASE( TIND, TSHORT): 878 case CASE( TIND, TUSHORT): 879 case CASE( TIND, TINT): 880 case CASE( TIND, TUINT): 881 case CASE( TIND, TLONG): 882 case CASE( TIND, TULONG): 883 case CASE( TVLONG, TCHAR): 884 case CASE( TVLONG, TUCHAR): 885 case CASE( TVLONG, TSHORT): 886 case CASE( TVLONG, TUSHORT): 887 case CASE( TVLONG, TINT): 888 case CASE( TVLONG, TUINT): 889 case CASE( TVLONG, TLONG): 890 case CASE( TVLONG, TULONG): 891 case CASE( TUVLONG, TCHAR): 892 case CASE( TUVLONG, TUCHAR): 893 case CASE( TUVLONG, TSHORT): 894 case CASE( TUVLONG, TUSHORT): 895 case CASE( TUVLONG, TINT): 896 case CASE( TUVLONG, TUINT): 897 case CASE( TUVLONG, TLONG): 898 case CASE( TUVLONG, TULONG): 899 a = AMOVQL; 900 if(f->op == OCONST) { 901 f->vconst &= (int)0xffffffffU; 902 a = AMOVL; 903 } 904 break; 905 906 case CASE( TIND, TIND): 907 case CASE( TIND, TVLONG): 908 case CASE( TIND, TUVLONG): 909 case CASE( TVLONG, TIND): 910 case CASE( TVLONG, TVLONG): 911 case CASE( TVLONG, TUVLONG): 912 case CASE( TUVLONG, TIND): 913 case CASE( TUVLONG, TVLONG): 914 case CASE( TUVLONG, TUVLONG): 915 a = AMOVQ; 916 break; 917 918 case CASE( TSHORT, TINT): 919 case CASE( TSHORT, TUINT): 920 case CASE( TSHORT, TLONG): 921 case CASE( TSHORT, TULONG): 922 a = AMOVWLSX; 923 if(f->op == OCONST) { 924 f->vconst &= 0xffff; 925 if(f->vconst & 0x8000) 926 f->vconst |= 0xffff0000; 927 a = AMOVL; 928 } 929 break; 930 931 case CASE( TSHORT, TVLONG): 932 case CASE( TSHORT, TUVLONG): 933 case CASE( TSHORT, TIND): 934 a = AMOVWQSX; 935 if(f->op == OCONST) { 936 f->vconst &= 0xffff; 937 if(f->vconst & 0x8000){ 938 f->vconst |= 0xffff0000; 939 f->vconst |= (vlong)~0 << 32; 940 } 941 a = AMOVL; 942 } 943 break; 944 945 case CASE( TUSHORT,TINT): 946 case CASE( TUSHORT,TUINT): 947 case CASE( TUSHORT,TLONG): 948 case CASE( TUSHORT,TULONG): 949 a = AMOVWLZX; 950 if(f->op == OCONST) { 951 f->vconst &= 0xffff; 952 a = AMOVL; 953 } 954 break; 955 956 case CASE( TUSHORT,TVLONG): 957 case CASE( TUSHORT,TUVLONG): 958 case CASE( TUSHORT,TIND): 959 a = AMOVWQZX; 960 if(f->op == OCONST) { 961 f->vconst &= 0xffff; 962 a = AMOVL; /* MOVL also zero-extends to 64 bits */ 963 } 964 break; 965 966 case CASE( TCHAR, TSHORT): 967 case CASE( TCHAR, TUSHORT): 968 case CASE( TCHAR, TINT): 969 case CASE( TCHAR, TUINT): 970 case CASE( TCHAR, TLONG): 971 case CASE( TCHAR, TULONG): 972 a = AMOVBLSX; 973 if(f->op == OCONST) { 974 f->vconst &= 0xff; 975 if(f->vconst & 0x80) 976 f->vconst |= 0xffffff00; 977 a = AMOVL; 978 } 979 break; 980 981 case CASE( TCHAR, TVLONG): 982 case CASE( TCHAR, TUVLONG): 983 case CASE( TCHAR, TIND): 984 a = AMOVBQSX; 985 if(f->op == OCONST) { 986 f->vconst &= 0xff; 987 if(f->vconst & 0x80){ 988 f->vconst |= 0xffffff00; 989 f->vconst |= (vlong)~0 << 32; 990 } 991 a = AMOVQ; 992 } 993 break; 994 995 case CASE( TUCHAR, TSHORT): 996 case CASE( TUCHAR, TUSHORT): 997 case CASE( TUCHAR, TINT): 998 case CASE( TUCHAR, TUINT): 999 case CASE( TUCHAR, TLONG): 1000 case CASE( TUCHAR, TULONG): 1001 a = AMOVBLZX; 1002 if(f->op == OCONST) { 1003 f->vconst &= 0xff; 1004 a = AMOVL; 1005 } 1006 break; 1007 1008 case CASE( TUCHAR, TVLONG): 1009 case CASE( TUCHAR, TUVLONG): 1010 case CASE( TUCHAR, TIND): 1011 a = AMOVBQZX; 1012 if(f->op == OCONST) { 1013 f->vconst &= 0xff; 1014 a = AMOVL; /* zero-extends to 64-bits */ 1015 } 1016 break; 1017 1018 /* 1019 * float to fix 1020 */ 1021 case CASE( TFLOAT, TCHAR): 1022 case CASE( TFLOAT, TUCHAR): 1023 case CASE( TFLOAT, TSHORT): 1024 case CASE( TFLOAT, TUSHORT): 1025 case CASE( TFLOAT, TINT): 1026 case CASE( TFLOAT, TUINT): 1027 case CASE( TFLOAT, TLONG): 1028 case CASE( TFLOAT, TULONG): 1029 case CASE( TFLOAT, TVLONG): 1030 case CASE( TFLOAT, TUVLONG): 1031 case CASE( TFLOAT, TIND): 1032 1033 case CASE( TDOUBLE,TCHAR): 1034 case CASE( TDOUBLE,TUCHAR): 1035 case CASE( TDOUBLE,TSHORT): 1036 case CASE( TDOUBLE,TUSHORT): 1037 case CASE( TDOUBLE,TINT): 1038 case CASE( TDOUBLE,TUINT): 1039 case CASE( TDOUBLE,TLONG): 1040 case CASE( TDOUBLE,TULONG): 1041 case CASE( TDOUBLE,TVLONG): 1042 case CASE( TDOUBLE,TUVLONG): 1043 case CASE( TDOUBLE,TIND): 1044 regalloc(&nod, t, Z); 1045 if(ewidth[tt] == SZ_VLONG || typeu[tt] && ewidth[tt] == SZ_INT){ 1046 if(ft == TFLOAT) 1047 a = ACVTTSS2SQ; 1048 else 1049 a = ACVTTSD2SQ; 1050 }else{ 1051 if(ft == TFLOAT) 1052 a = ACVTTSS2SL; 1053 else 1054 a = ACVTTSD2SL; 1055 } 1056 gins(a, f, &nod); 1057 gmove(&nod, t); 1058 regfree(&nod); 1059 return; 1060 1061 /* 1062 * uvlong to float 1063 */ 1064 case CASE( TUVLONG, TDOUBLE): 1065 case CASE( TUVLONG, TFLOAT): 1066 a = ACVTSQ2SS; 1067 if(tt == TDOUBLE) 1068 a = ACVTSQ2SD; 1069 regalloc(&nod, f, f); 1070 gmove(f, &nod); 1071 regalloc(&nod1, t, t); 1072 gins(ACMPQ, &nod, nodconst(0)); 1073 gins(AJLT, Z, Z); 1074 p1 = p; 1075 gins(a, &nod, &nod1); 1076 gins(AJMP, Z, Z); 1077 p2 = p; 1078 patch(p1, pc); 1079 regalloc(&nod2, f, Z); 1080 regalloc(&nod3, f, Z); 1081 gmove(&nod, &nod2); 1082 gins(ASHRQ, nodconst(1), &nod2); 1083 gmove(&nod, &nod3); 1084 gins(AANDL, nodconst(1), &nod3); 1085 gins(AORQ, &nod3, &nod2); 1086 gins(a, &nod2, &nod1); 1087 gins(tt == TDOUBLE? AADDSD: AADDSS, &nod1, &nod1); 1088 regfree(&nod2); 1089 regfree(&nod3); 1090 patch(p2, pc); 1091 regfree(&nod); 1092 regfree(&nod1); 1093 return; 1094 1095 case CASE( TULONG, TDOUBLE): 1096 case CASE( TUINT, TDOUBLE): 1097 case CASE( TULONG, TFLOAT): 1098 case CASE( TUINT, TFLOAT): 1099 a = ACVTSQ2SS; 1100 if(tt == TDOUBLE) 1101 a = ACVTSQ2SD; 1102 regalloc(&nod, f, f); 1103 gins(AMOVLQZX, f, &nod); 1104 regalloc(&nod1, t, t); 1105 gins(a, &nod, &nod1); 1106 gmove(&nod1, t); 1107 regfree(&nod); 1108 regfree(&nod1); 1109 return; 1110 1111 /* 1112 * fix to float 1113 */ 1114 case CASE( TCHAR, TFLOAT): 1115 case CASE( TUCHAR, TFLOAT): 1116 case CASE( TSHORT, TFLOAT): 1117 case CASE( TUSHORT,TFLOAT): 1118 case CASE( TINT, TFLOAT): 1119 case CASE( TLONG, TFLOAT): 1120 case CASE( TVLONG, TFLOAT): 1121 case CASE( TIND, TFLOAT): 1122 1123 case CASE( TCHAR, TDOUBLE): 1124 case CASE( TUCHAR, TDOUBLE): 1125 case CASE( TSHORT, TDOUBLE): 1126 case CASE( TUSHORT,TDOUBLE): 1127 case CASE( TINT, TDOUBLE): 1128 case CASE( TLONG, TDOUBLE): 1129 case CASE( TVLONG, TDOUBLE): 1130 case CASE( TIND, TDOUBLE): 1131 regalloc(&nod, t, t); 1132 if(ewidth[ft] == SZ_VLONG){ 1133 if(tt == TFLOAT) 1134 a = ACVTSQ2SS; 1135 else 1136 a = ACVTSQ2SD; 1137 }else{ 1138 if(tt == TFLOAT) 1139 a = ACVTSL2SS; 1140 else 1141 a = ACVTSL2SD; 1142 } 1143 gins(a, f, &nod); 1144 gmove(&nod, t); 1145 regfree(&nod); 1146 return; 1147 1148 /* 1149 * float to float 1150 */ 1151 case CASE( TFLOAT, TFLOAT): 1152 a = AMOVSS; 1153 break; 1154 case CASE( TDOUBLE,TFLOAT): 1155 a = ACVTSD2SS; 1156 break; 1157 case CASE( TFLOAT, TDOUBLE): 1158 a = ACVTSS2SD; 1159 break; 1160 case CASE( TDOUBLE,TDOUBLE): 1161 a = AMOVSD; 1162 break; 1163 } 1164 if(a == AMOVQ || a == AMOVSD || a == AMOVSS || a == AMOVL && ewidth[ft] == ewidth[tt]) /* TO DO: check AMOVL */ 1165 if(samaddr(f, t)) 1166 return; 1167 gins(a, f, t); 1168 } 1169 1170 void 1171 doindex(Node *n) 1172 { 1173 Node nod, nod1; 1174 int32 v; 1175 1176 if(debug['Y']) 1177 prtree(n, "index"); 1178 1179 if(n->left->complex >= FNX) 1180 print("botch in doindex\n"); 1181 1182 regalloc(&nod, &qregnode, Z); 1183 v = constnode.vconst; 1184 cgen(n->right, &nod); 1185 idx.ptr = D_NONE; 1186 if(n->left->op == OCONST) 1187 idx.ptr = D_CONST; 1188 else if(n->left->op == OREGISTER) 1189 idx.ptr = n->left->reg; 1190 else if(n->left->op != OADDR) { 1191 reg[D_BP]++; // can't be used as a base 1192 regalloc(&nod1, &qregnode, Z); 1193 cgen(n->left, &nod1); 1194 idx.ptr = nod1.reg; 1195 regfree(&nod1); 1196 reg[D_BP]--; 1197 } 1198 idx.reg = nod.reg; 1199 regfree(&nod); 1200 constnode.vconst = v; 1201 } 1202 1203 void 1204 gins(int a, Node *f, Node *t) 1205 { 1206 1207 if(f != Z && f->op == OINDEX) 1208 doindex(f); 1209 if(t != Z && t->op == OINDEX) 1210 doindex(t); 1211 nextpc(); 1212 p->as = a; 1213 if(f != Z) 1214 naddr(f, &p->from); 1215 if(t != Z) 1216 naddr(t, &p->to); 1217 if(debug['g']) 1218 print("%P\n", p); 1219 } 1220 1221 void 1222 gopcode(int o, Type *ty, Node *f, Node *t) 1223 { 1224 int a, et; 1225 1226 et = TLONG; 1227 if(ty != T) 1228 et = ty->etype; 1229 if(debug['M']) { 1230 if(f != Z && f->type != T) 1231 print("gop: %O %O[%s],", o, f->op, tnames[et]); 1232 else 1233 print("gop: %O Z,", o); 1234 if(t != Z && t->type != T) 1235 print("%O[%s]\n", t->op, tnames[t->type->etype]); 1236 else 1237 print("Z\n"); 1238 } 1239 a = AGOK; 1240 switch(o) { 1241 case OCOM: 1242 a = ANOTL; 1243 if(et == TCHAR || et == TUCHAR) 1244 a = ANOTB; 1245 if(et == TSHORT || et == TUSHORT) 1246 a = ANOTW; 1247 if(et == TVLONG || et == TUVLONG || et == TIND) 1248 a = ANOTQ; 1249 break; 1250 1251 case ONEG: 1252 a = ANEGL; 1253 if(et == TCHAR || et == TUCHAR) 1254 a = ANEGB; 1255 if(et == TSHORT || et == TUSHORT) 1256 a = ANEGW; 1257 if(et == TVLONG || et == TUVLONG || et == TIND) 1258 a = ANEGQ; 1259 break; 1260 1261 case OADDR: 1262 a = ALEAQ; 1263 break; 1264 1265 case OASADD: 1266 case OADD: 1267 a = AADDL; 1268 if(et == TCHAR || et == TUCHAR) 1269 a = AADDB; 1270 if(et == TSHORT || et == TUSHORT) 1271 a = AADDW; 1272 if(et == TVLONG || et == TUVLONG || et == TIND) 1273 a = AADDQ; 1274 if(et == TFLOAT) 1275 a = AADDSS; 1276 if(et == TDOUBLE) 1277 a = AADDSD; 1278 break; 1279 1280 case OASSUB: 1281 case OSUB: 1282 a = ASUBL; 1283 if(et == TCHAR || et == TUCHAR) 1284 a = ASUBB; 1285 if(et == TSHORT || et == TUSHORT) 1286 a = ASUBW; 1287 if(et == TVLONG || et == TUVLONG || et == TIND) 1288 a = ASUBQ; 1289 if(et == TFLOAT) 1290 a = ASUBSS; 1291 if(et == TDOUBLE) 1292 a = ASUBSD; 1293 break; 1294 1295 case OASOR: 1296 case OOR: 1297 a = AORL; 1298 if(et == TCHAR || et == TUCHAR) 1299 a = AORB; 1300 if(et == TSHORT || et == TUSHORT) 1301 a = AORW; 1302 if(et == TVLONG || et == TUVLONG || et == TIND) 1303 a = AORQ; 1304 break; 1305 1306 case OASAND: 1307 case OAND: 1308 a = AANDL; 1309 if(et == TCHAR || et == TUCHAR) 1310 a = AANDB; 1311 if(et == TSHORT || et == TUSHORT) 1312 a = AANDW; 1313 if(et == TVLONG || et == TUVLONG || et == TIND) 1314 a = AANDQ; 1315 break; 1316 1317 case OASXOR: 1318 case OXOR: 1319 a = AXORL; 1320 if(et == TCHAR || et == TUCHAR) 1321 a = AXORB; 1322 if(et == TSHORT || et == TUSHORT) 1323 a = AXORW; 1324 if(et == TVLONG || et == TUVLONG || et == TIND) 1325 a = AXORQ; 1326 break; 1327 1328 case OASLSHR: 1329 case OLSHR: 1330 a = ASHRL; 1331 if(et == TCHAR || et == TUCHAR) 1332 a = ASHRB; 1333 if(et == TSHORT || et == TUSHORT) 1334 a = ASHRW; 1335 if(et == TVLONG || et == TUVLONG || et == TIND) 1336 a = ASHRQ; 1337 break; 1338 1339 case OASASHR: 1340 case OASHR: 1341 a = ASARL; 1342 if(et == TCHAR || et == TUCHAR) 1343 a = ASARB; 1344 if(et == TSHORT || et == TUSHORT) 1345 a = ASARW; 1346 if(et == TVLONG || et == TUVLONG || et == TIND) 1347 a = ASARQ; 1348 break; 1349 1350 case OASASHL: 1351 case OASHL: 1352 a = ASALL; 1353 if(et == TCHAR || et == TUCHAR) 1354 a = ASALB; 1355 if(et == TSHORT || et == TUSHORT) 1356 a = ASALW; 1357 if(et == TVLONG || et == TUVLONG || et == TIND) 1358 a = ASALQ; 1359 break; 1360 1361 case OROTL: 1362 a = AROLL; 1363 if(et == TCHAR || et == TUCHAR) 1364 a = AROLB; 1365 if(et == TSHORT || et == TUSHORT) 1366 a = AROLW; 1367 if(et == TVLONG || et == TUVLONG || et == TIND) 1368 a = AROLQ; 1369 break; 1370 1371 case OFUNC: 1372 a = ACALL; 1373 break; 1374 1375 case OASMUL: 1376 case OMUL: 1377 if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0) 1378 t = Z; 1379 a = AIMULL; 1380 if(et == TVLONG || et == TUVLONG || et == TIND) 1381 a = AIMULQ; 1382 if(et == TFLOAT) 1383 a = AMULSS; 1384 if(et == TDOUBLE) 1385 a = AMULSD; 1386 break; 1387 1388 case OASMOD: 1389 case OMOD: 1390 case OASDIV: 1391 case ODIV: 1392 a = AIDIVL; 1393 if(et == TVLONG || et == TUVLONG || et == TIND) 1394 a = AIDIVQ; 1395 if(et == TFLOAT) 1396 a = ADIVSS; 1397 if(et == TDOUBLE) 1398 a = ADIVSD; 1399 break; 1400 1401 case OASLMUL: 1402 case OLMUL: 1403 a = AMULL; 1404 if(et == TVLONG || et == TUVLONG || et == TIND) 1405 a = AMULQ; 1406 break; 1407 1408 case OASLMOD: 1409 case OLMOD: 1410 case OASLDIV: 1411 case OLDIV: 1412 a = ADIVL; 1413 if(et == TVLONG || et == TUVLONG || et == TIND) 1414 a = ADIVQ; 1415 break; 1416 1417 case OEQ: 1418 case ONE: 1419 case OLT: 1420 case OLE: 1421 case OGE: 1422 case OGT: 1423 case OLO: 1424 case OLS: 1425 case OHS: 1426 case OHI: 1427 a = ACMPL; 1428 if(et == TCHAR || et == TUCHAR) 1429 a = ACMPB; 1430 if(et == TSHORT || et == TUSHORT) 1431 a = ACMPW; 1432 if(et == TVLONG || et == TUVLONG || et == TIND) 1433 a = ACMPQ; 1434 if(et == TFLOAT) 1435 a = AUCOMISS; 1436 if(et == TDOUBLE) 1437 a = AUCOMISD; 1438 gins(a, f, t); 1439 switch(o) { 1440 case OEQ: a = AJEQ; break; 1441 case ONE: a = AJNE; break; 1442 case OLT: a = AJLT; break; 1443 case OLE: a = AJLE; break; 1444 case OGE: a = AJGE; break; 1445 case OGT: a = AJGT; break; 1446 case OLO: a = AJCS; break; 1447 case OLS: a = AJLS; break; 1448 case OHS: a = AJCC; break; 1449 case OHI: a = AJHI; break; 1450 } 1451 gins(a, Z, Z); 1452 return; 1453 } 1454 if(a == AGOK) 1455 diag(Z, "bad in gopcode %O", o); 1456 gins(a, f, t); 1457 } 1458 1459 int 1460 samaddr(Node *f, Node *t) 1461 { 1462 return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg; 1463 } 1464 1465 void 1466 gbranch(int o) 1467 { 1468 int a; 1469 1470 a = AGOK; 1471 switch(o) { 1472 case ORETURN: 1473 a = ARET; 1474 break; 1475 case OGOTO: 1476 a = AJMP; 1477 break; 1478 } 1479 nextpc(); 1480 if(a == AGOK) { 1481 diag(Z, "bad in gbranch %O", o); 1482 nextpc(); 1483 } 1484 p->as = a; 1485 } 1486 1487 void 1488 patch(Prog *op, int32 pc) 1489 { 1490 1491 op->to.offset = pc; 1492 op->to.type = D_BRANCH; 1493 } 1494 1495 void 1496 gpseudo(int a, Sym *s, Node *n) 1497 { 1498 1499 nextpc(); 1500 p->as = a; 1501 p->from.type = D_EXTERN; 1502 p->from.sym = s; 1503 1504 switch(a) { 1505 case ATEXT: 1506 p->from.scale = textflag; 1507 textflag = 0; 1508 break; 1509 case AGLOBL: 1510 p->from.scale = s->dataflag; 1511 break; 1512 } 1513 1514 if(s->class == CSTATIC) 1515 p->from.type = D_STATIC; 1516 naddr(n, &p->to); 1517 if(a == ADATA || a == AGLOBL) 1518 pc--; 1519 } 1520 1521 void 1522 gpcdata(int index, int value) 1523 { 1524 Node n1; 1525 1526 n1 = *nodconst(index); 1527 gins(APCDATA, &n1, nodconst(value)); 1528 } 1529 1530 void 1531 gprefetch(Node *n) 1532 { 1533 Node n1; 1534 1535 regalloc(&n1, n, Z); 1536 gmove(n, &n1); 1537 n1.op = OINDREG; 1538 gins(APREFETCHNTA, &n1, Z); 1539 regfree(&n1); 1540 } 1541 1542 int 1543 sconst(Node *n) 1544 { 1545 int32 v; 1546 1547 if(n->op == OCONST && !typefd[n->type->etype]) { 1548 v = n->vconst; 1549 if(v >= -32766L && v < 32766L) 1550 return 1; 1551 } 1552 return 0; 1553 } 1554 1555 int32 1556 exreg(Type *t) 1557 { 1558 int32 o; 1559 1560 if(typechlpv[t->etype]) { 1561 if(exregoffset >= 64) 1562 return 0; 1563 o = exregoffset; 1564 exregoffset += 8; 1565 return o+1; // +1 to avoid 0 == failure; naddr's case OEXREG will subtract 1. 1566 } 1567 return 0; 1568 } 1569 1570 schar ewidth[NTYPE] = 1571 { 1572 -1, /*[TXXX]*/ 1573 SZ_CHAR, /*[TCHAR]*/ 1574 SZ_CHAR, /*[TUCHAR]*/ 1575 SZ_SHORT, /*[TSHORT]*/ 1576 SZ_SHORT, /*[TUSHORT]*/ 1577 SZ_INT, /*[TINT]*/ 1578 SZ_INT, /*[TUINT]*/ 1579 SZ_LONG, /*[TLONG]*/ 1580 SZ_LONG, /*[TULONG]*/ 1581 SZ_VLONG, /*[TVLONG]*/ 1582 SZ_VLONG, /*[TUVLONG]*/ 1583 SZ_FLOAT, /*[TFLOAT]*/ 1584 SZ_DOUBLE, /*[TDOUBLE]*/ 1585 SZ_IND, /*[TIND]*/ 1586 0, /*[TFUNC]*/ 1587 -1, /*[TARRAY]*/ 1588 0, /*[TVOID]*/ 1589 -1, /*[TSTRUCT]*/ 1590 -1, /*[TUNION]*/ 1591 SZ_INT, /*[TENUM]*/ 1592 }; 1593 int32 ncast[NTYPE] = 1594 { 1595 0, /*[TXXX]*/ 1596 BCHAR|BUCHAR, /*[TCHAR]*/ 1597 BCHAR|BUCHAR, /*[TUCHAR]*/ 1598 BSHORT|BUSHORT, /*[TSHORT]*/ 1599 BSHORT|BUSHORT, /*[TUSHORT]*/ 1600 BINT|BUINT|BLONG|BULONG, /*[TINT]*/ 1601 BINT|BUINT|BLONG|BULONG, /*[TUINT]*/ 1602 BINT|BUINT|BLONG|BULONG, /*[TLONG]*/ 1603 BINT|BUINT|BLONG|BULONG, /*[TULONG]*/ 1604 BVLONG|BUVLONG|BIND, /*[TVLONG]*/ 1605 BVLONG|BUVLONG|BIND, /*[TUVLONG]*/ 1606 BFLOAT, /*[TFLOAT]*/ 1607 BDOUBLE, /*[TDOUBLE]*/ 1608 BVLONG|BUVLONG|BIND, /*[TIND]*/ 1609 0, /*[TFUNC]*/ 1610 0, /*[TARRAY]*/ 1611 0, /*[TVOID]*/ 1612 BSTRUCT, /*[TSTRUCT]*/ 1613 BUNION, /*[TUNION]*/ 1614 0, /*[TENUM]*/ 1615 };