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