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