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