github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/cmd/8g/gsubr.c (about) 1 // Derived from Inferno utils/8c/txt.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/8c/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 <u.h> 32 #include <libc.h> 33 #include "gg.h" 34 #include "../../pkg/runtime/funcdata.h" 35 36 // TODO(rsc): Can make this bigger if we move 37 // the text segment up higher in 8l for all GOOS. 38 // At the same time, can raise StackBig in ../../pkg/runtime/stack.h. 39 uint32 unmappedzero = 4096; 40 41 #define CASE(a,b) (((a)<<16)|((b)<<0)) 42 43 void 44 clearp(Prog *p) 45 { 46 p->as = AEND; 47 p->from.type = D_NONE; 48 p->from.index = D_NONE; 49 p->to.type = D_NONE; 50 p->to.index = D_NONE; 51 p->pc = pcloc; 52 pcloc++; 53 } 54 55 static int ddumped; 56 static Prog *dfirst; 57 static Prog *dpc; 58 59 /* 60 * generate and return proc with p->as = as, 61 * linked into program. pc is next instruction. 62 */ 63 Prog* 64 prog(int as) 65 { 66 Prog *p; 67 68 if(as == ADATA || as == AGLOBL) { 69 if(ddumped) 70 fatal("already dumped data"); 71 if(dpc == nil) { 72 dpc = mal(sizeof(*dpc)); 73 dfirst = dpc; 74 } 75 p = dpc; 76 dpc = mal(sizeof(*dpc)); 77 p->link = dpc; 78 } else { 79 p = pc; 80 pc = mal(sizeof(*pc)); 81 clearp(pc); 82 p->link = pc; 83 } 84 85 if(lineno == 0) { 86 if(debug['K']) 87 warn("prog: line 0"); 88 } 89 90 p->as = as; 91 p->lineno = lineno; 92 return p; 93 } 94 95 void 96 dumpdata(void) 97 { 98 ddumped = 1; 99 if(dfirst == nil) 100 return; 101 newplist(); 102 *pc = *dfirst; 103 pc = dpc; 104 clearp(pc); 105 } 106 107 /* 108 * generate a branch. 109 * t is ignored. 110 * likely values are for branch prediction: 111 * -1 unlikely 112 * 0 no opinion 113 * +1 likely 114 */ 115 Prog* 116 gbranch(int as, Type *t, int likely) 117 { 118 Prog *p; 119 120 USED(t); 121 p = prog(as); 122 p->to.type = D_BRANCH; 123 p->to.u.branch = P; 124 if(likely != 0) { 125 p->from.type = D_CONST; 126 p->from.offset = likely > 0; 127 } 128 return p; 129 } 130 131 /* 132 * patch previous branch to jump to to. 133 */ 134 void 135 patch(Prog *p, Prog *to) 136 { 137 if(p->to.type != D_BRANCH) 138 fatal("patch: not a branch"); 139 p->to.u.branch = to; 140 p->to.offset = to->pc; 141 } 142 143 Prog* 144 unpatch(Prog *p) 145 { 146 Prog *q; 147 148 if(p->to.type != D_BRANCH) 149 fatal("unpatch: not a branch"); 150 q = p->to.u.branch; 151 p->to.u.branch = P; 152 p->to.offset = 0; 153 return q; 154 } 155 156 /* 157 * start a new Prog list. 158 */ 159 Plist* 160 newplist(void) 161 { 162 Plist *pl; 163 164 pl = linknewplist(ctxt); 165 166 pc = mal(sizeof(*pc)); 167 clearp(pc); 168 pl->firstpc = pc; 169 170 return pl; 171 } 172 173 void 174 gused(Node *n) 175 { 176 gins(ANOP, n, N); // used 177 } 178 179 Prog* 180 gjmp(Prog *to) 181 { 182 Prog *p; 183 184 p = gbranch(AJMP, T, 0); 185 if(to != P) 186 patch(p, to); 187 return p; 188 } 189 190 void 191 ggloblnod(Node *nam) 192 { 193 Prog *p; 194 195 p = gins(AGLOBL, nam, N); 196 p->lineno = nam->lineno; 197 p->from.sym->gotype = linksym(ngotype(nam)); 198 p->to.sym = nil; 199 p->to.type = D_CONST; 200 p->to.offset = nam->type->width; 201 if(nam->readonly) 202 p->from.scale = RODATA; 203 if(nam->type != T && !haspointers(nam->type)) 204 p->from.scale |= NOPTR; 205 } 206 207 void 208 gargsize(int32 size) 209 { 210 Node n1, n2; 211 212 nodconst(&n1, types[TINT32], PCDATA_ArgSize); 213 nodconst(&n2, types[TINT32], size); 214 gins(APCDATA, &n1, &n2); 215 } 216 217 void 218 ggloblsym(Sym *s, int32 width, int dupok, int rodata) 219 { 220 Prog *p; 221 222 p = gins(AGLOBL, N, N); 223 p->from.type = D_EXTERN; 224 p->from.index = D_NONE; 225 p->from.sym = linksym(s); 226 p->to.type = D_CONST; 227 p->to.index = D_NONE; 228 p->to.offset = width; 229 if(dupok) 230 p->from.scale |= DUPOK; 231 if(rodata) 232 p->from.scale |= RODATA; 233 } 234 235 void 236 gtrack(Sym *s) 237 { 238 Prog *p; 239 240 p = gins(AUSEFIELD, N, N); 241 p->from.type = D_EXTERN; 242 p->from.index = D_NONE; 243 p->from.sym = linksym(s); 244 } 245 246 int 247 isfat(Type *t) 248 { 249 if(t != T) 250 switch(t->etype) { 251 case TSTRUCT: 252 case TARRAY: 253 case TSTRING: 254 case TINTER: // maybe remove later 255 return 1; 256 } 257 return 0; 258 } 259 260 /* 261 * naddr of func generates code for address of func. 262 * if using opcode that can take address implicitly, 263 * call afunclit to fix up the argument. 264 */ 265 void 266 afunclit(Addr *a, Node *n) 267 { 268 if(a->type == D_ADDR && a->index == D_EXTERN) { 269 a->type = D_EXTERN; 270 a->index = D_NONE; 271 a->sym = linksym(n->sym); 272 } 273 } 274 275 /* 276 * return Axxx for Oxxx on type t. 277 */ 278 int 279 optoas(int op, Type *t) 280 { 281 int a; 282 283 if(t == T) 284 fatal("optoas: t is nil"); 285 286 a = AGOK; 287 switch(CASE(op, simtype[t->etype])) { 288 default: 289 fatal("optoas: no entry %O-%T", op, t); 290 break; 291 292 case CASE(OADDR, TPTR32): 293 a = ALEAL; 294 break; 295 296 case CASE(OEQ, TBOOL): 297 case CASE(OEQ, TINT8): 298 case CASE(OEQ, TUINT8): 299 case CASE(OEQ, TINT16): 300 case CASE(OEQ, TUINT16): 301 case CASE(OEQ, TINT32): 302 case CASE(OEQ, TUINT32): 303 case CASE(OEQ, TINT64): 304 case CASE(OEQ, TUINT64): 305 case CASE(OEQ, TPTR32): 306 case CASE(OEQ, TPTR64): 307 case CASE(OEQ, TFLOAT32): 308 case CASE(OEQ, TFLOAT64): 309 a = AJEQ; 310 break; 311 312 case CASE(ONE, TBOOL): 313 case CASE(ONE, TINT8): 314 case CASE(ONE, TUINT8): 315 case CASE(ONE, TINT16): 316 case CASE(ONE, TUINT16): 317 case CASE(ONE, TINT32): 318 case CASE(ONE, TUINT32): 319 case CASE(ONE, TINT64): 320 case CASE(ONE, TUINT64): 321 case CASE(ONE, TPTR32): 322 case CASE(ONE, TPTR64): 323 case CASE(ONE, TFLOAT32): 324 case CASE(ONE, TFLOAT64): 325 a = AJNE; 326 break; 327 328 case CASE(OLT, TINT8): 329 case CASE(OLT, TINT16): 330 case CASE(OLT, TINT32): 331 case CASE(OLT, TINT64): 332 a = AJLT; 333 break; 334 335 case CASE(OLT, TUINT8): 336 case CASE(OLT, TUINT16): 337 case CASE(OLT, TUINT32): 338 case CASE(OLT, TUINT64): 339 a = AJCS; 340 break; 341 342 case CASE(OLE, TINT8): 343 case CASE(OLE, TINT16): 344 case CASE(OLE, TINT32): 345 case CASE(OLE, TINT64): 346 a = AJLE; 347 break; 348 349 case CASE(OLE, TUINT8): 350 case CASE(OLE, TUINT16): 351 case CASE(OLE, TUINT32): 352 case CASE(OLE, TUINT64): 353 a = AJLS; 354 break; 355 356 case CASE(OGT, TINT8): 357 case CASE(OGT, TINT16): 358 case CASE(OGT, TINT32): 359 case CASE(OGT, TINT64): 360 a = AJGT; 361 break; 362 363 case CASE(OGT, TUINT8): 364 case CASE(OGT, TUINT16): 365 case CASE(OGT, TUINT32): 366 case CASE(OGT, TUINT64): 367 case CASE(OLT, TFLOAT32): 368 case CASE(OLT, TFLOAT64): 369 a = AJHI; 370 break; 371 372 case CASE(OGE, TINT8): 373 case CASE(OGE, TINT16): 374 case CASE(OGE, TINT32): 375 case CASE(OGE, TINT64): 376 a = AJGE; 377 break; 378 379 case CASE(OGE, TUINT8): 380 case CASE(OGE, TUINT16): 381 case CASE(OGE, TUINT32): 382 case CASE(OGE, TUINT64): 383 case CASE(OLE, TFLOAT32): 384 case CASE(OLE, TFLOAT64): 385 a = AJCC; 386 break; 387 388 case CASE(OCMP, TBOOL): 389 case CASE(OCMP, TINT8): 390 case CASE(OCMP, TUINT8): 391 a = ACMPB; 392 break; 393 394 case CASE(OCMP, TINT16): 395 case CASE(OCMP, TUINT16): 396 a = ACMPW; 397 break; 398 399 case CASE(OCMP, TINT32): 400 case CASE(OCMP, TUINT32): 401 case CASE(OCMP, TPTR32): 402 a = ACMPL; 403 break; 404 405 case CASE(OAS, TBOOL): 406 case CASE(OAS, TINT8): 407 case CASE(OAS, TUINT8): 408 a = AMOVB; 409 break; 410 411 case CASE(OAS, TINT16): 412 case CASE(OAS, TUINT16): 413 a = AMOVW; 414 break; 415 416 case CASE(OAS, TINT32): 417 case CASE(OAS, TUINT32): 418 case CASE(OAS, TPTR32): 419 a = AMOVL; 420 break; 421 422 case CASE(OADD, TINT8): 423 case CASE(OADD, TUINT8): 424 a = AADDB; 425 break; 426 427 case CASE(OADD, TINT16): 428 case CASE(OADD, TUINT16): 429 a = AADDW; 430 break; 431 432 case CASE(OADD, TINT32): 433 case CASE(OADD, TUINT32): 434 case CASE(OADD, TPTR32): 435 case CASE(OADDPTR, TPTR32): 436 a = AADDL; 437 break; 438 439 case CASE(OSUB, TINT8): 440 case CASE(OSUB, TUINT8): 441 a = ASUBB; 442 break; 443 444 case CASE(OSUB, TINT16): 445 case CASE(OSUB, TUINT16): 446 a = ASUBW; 447 break; 448 449 case CASE(OSUB, TINT32): 450 case CASE(OSUB, TUINT32): 451 case CASE(OSUB, TPTR32): 452 a = ASUBL; 453 break; 454 455 case CASE(OINC, TINT8): 456 case CASE(OINC, TUINT8): 457 a = AINCB; 458 break; 459 460 case CASE(OINC, TINT16): 461 case CASE(OINC, TUINT16): 462 a = AINCW; 463 break; 464 465 case CASE(OINC, TINT32): 466 case CASE(OINC, TUINT32): 467 case CASE(OINC, TPTR32): 468 a = AINCL; 469 break; 470 471 case CASE(ODEC, TINT8): 472 case CASE(ODEC, TUINT8): 473 a = ADECB; 474 break; 475 476 case CASE(ODEC, TINT16): 477 case CASE(ODEC, TUINT16): 478 a = ADECW; 479 break; 480 481 case CASE(ODEC, TINT32): 482 case CASE(ODEC, TUINT32): 483 case CASE(ODEC, TPTR32): 484 a = ADECL; 485 break; 486 487 case CASE(OCOM, TINT8): 488 case CASE(OCOM, TUINT8): 489 a = ANOTB; 490 break; 491 492 case CASE(OCOM, TINT16): 493 case CASE(OCOM, TUINT16): 494 a = ANOTW; 495 break; 496 497 case CASE(OCOM, TINT32): 498 case CASE(OCOM, TUINT32): 499 case CASE(OCOM, TPTR32): 500 a = ANOTL; 501 break; 502 503 case CASE(OMINUS, TINT8): 504 case CASE(OMINUS, TUINT8): 505 a = ANEGB; 506 break; 507 508 case CASE(OMINUS, TINT16): 509 case CASE(OMINUS, TUINT16): 510 a = ANEGW; 511 break; 512 513 case CASE(OMINUS, TINT32): 514 case CASE(OMINUS, TUINT32): 515 case CASE(OMINUS, TPTR32): 516 a = ANEGL; 517 break; 518 519 case CASE(OAND, TINT8): 520 case CASE(OAND, TUINT8): 521 a = AANDB; 522 break; 523 524 case CASE(OAND, TINT16): 525 case CASE(OAND, TUINT16): 526 a = AANDW; 527 break; 528 529 case CASE(OAND, TINT32): 530 case CASE(OAND, TUINT32): 531 case CASE(OAND, TPTR32): 532 a = AANDL; 533 break; 534 535 case CASE(OOR, TINT8): 536 case CASE(OOR, TUINT8): 537 a = AORB; 538 break; 539 540 case CASE(OOR, TINT16): 541 case CASE(OOR, TUINT16): 542 a = AORW; 543 break; 544 545 case CASE(OOR, TINT32): 546 case CASE(OOR, TUINT32): 547 case CASE(OOR, TPTR32): 548 a = AORL; 549 break; 550 551 case CASE(OXOR, TINT8): 552 case CASE(OXOR, TUINT8): 553 a = AXORB; 554 break; 555 556 case CASE(OXOR, TINT16): 557 case CASE(OXOR, TUINT16): 558 a = AXORW; 559 break; 560 561 case CASE(OXOR, TINT32): 562 case CASE(OXOR, TUINT32): 563 case CASE(OXOR, TPTR32): 564 a = AXORL; 565 break; 566 567 case CASE(OLROT, TINT8): 568 case CASE(OLROT, TUINT8): 569 a = AROLB; 570 break; 571 572 case CASE(OLROT, TINT16): 573 case CASE(OLROT, TUINT16): 574 a = AROLW; 575 break; 576 577 case CASE(OLROT, TINT32): 578 case CASE(OLROT, TUINT32): 579 case CASE(OLROT, TPTR32): 580 a = AROLL; 581 break; 582 583 case CASE(OLSH, TINT8): 584 case CASE(OLSH, TUINT8): 585 a = ASHLB; 586 break; 587 588 case CASE(OLSH, TINT16): 589 case CASE(OLSH, TUINT16): 590 a = ASHLW; 591 break; 592 593 case CASE(OLSH, TINT32): 594 case CASE(OLSH, TUINT32): 595 case CASE(OLSH, TPTR32): 596 a = ASHLL; 597 break; 598 599 case CASE(ORSH, TUINT8): 600 a = ASHRB; 601 break; 602 603 case CASE(ORSH, TUINT16): 604 a = ASHRW; 605 break; 606 607 case CASE(ORSH, TUINT32): 608 case CASE(ORSH, TPTR32): 609 a = ASHRL; 610 break; 611 612 case CASE(ORSH, TINT8): 613 a = ASARB; 614 break; 615 616 case CASE(ORSH, TINT16): 617 a = ASARW; 618 break; 619 620 case CASE(ORSH, TINT32): 621 a = ASARL; 622 break; 623 624 case CASE(OHMUL, TINT8): 625 case CASE(OMUL, TINT8): 626 case CASE(OMUL, TUINT8): 627 a = AIMULB; 628 break; 629 630 case CASE(OHMUL, TINT16): 631 case CASE(OMUL, TINT16): 632 case CASE(OMUL, TUINT16): 633 a = AIMULW; 634 break; 635 636 case CASE(OHMUL, TINT32): 637 case CASE(OMUL, TINT32): 638 case CASE(OMUL, TUINT32): 639 case CASE(OMUL, TPTR32): 640 a = AIMULL; 641 break; 642 643 case CASE(OHMUL, TUINT8): 644 a = AMULB; 645 break; 646 647 case CASE(OHMUL, TUINT16): 648 a = AMULW; 649 break; 650 651 case CASE(OHMUL, TUINT32): 652 case CASE(OHMUL, TPTR32): 653 a = AMULL; 654 break; 655 656 case CASE(ODIV, TINT8): 657 case CASE(OMOD, TINT8): 658 a = AIDIVB; 659 break; 660 661 case CASE(ODIV, TUINT8): 662 case CASE(OMOD, TUINT8): 663 a = ADIVB; 664 break; 665 666 case CASE(ODIV, TINT16): 667 case CASE(OMOD, TINT16): 668 a = AIDIVW; 669 break; 670 671 case CASE(ODIV, TUINT16): 672 case CASE(OMOD, TUINT16): 673 a = ADIVW; 674 break; 675 676 case CASE(ODIV, TINT32): 677 case CASE(OMOD, TINT32): 678 a = AIDIVL; 679 break; 680 681 case CASE(ODIV, TUINT32): 682 case CASE(ODIV, TPTR32): 683 case CASE(OMOD, TUINT32): 684 case CASE(OMOD, TPTR32): 685 a = ADIVL; 686 break; 687 688 case CASE(OEXTEND, TINT16): 689 a = ACWD; 690 break; 691 692 case CASE(OEXTEND, TINT32): 693 a = ACDQ; 694 break; 695 } 696 return a; 697 } 698 699 #define FCASE(a, b, c) (((a)<<16)|((b)<<8)|(c)) 700 int 701 foptoas(int op, Type *t, int flg) 702 { 703 int et, a; 704 705 a = AGOK; 706 et = simtype[t->etype]; 707 708 if(use_sse) 709 goto sse; 710 711 // If we need Fpop, it means we're working on 712 // two different floating-point registers, not memory. 713 // There the instruction only has a float64 form. 714 if(flg & Fpop) 715 et = TFLOAT64; 716 717 // clear Frev if unneeded 718 switch(op) { 719 case OADD: 720 case OMUL: 721 flg &= ~Frev; 722 break; 723 } 724 725 switch(FCASE(op, et, flg)) { 726 case FCASE(OADD, TFLOAT32, 0): 727 return AFADDF; 728 case FCASE(OADD, TFLOAT64, 0): 729 return AFADDD; 730 case FCASE(OADD, TFLOAT64, Fpop): 731 return AFADDDP; 732 733 case FCASE(OSUB, TFLOAT32, 0): 734 return AFSUBF; 735 case FCASE(OSUB, TFLOAT32, Frev): 736 return AFSUBRF; 737 738 case FCASE(OSUB, TFLOAT64, 0): 739 return AFSUBD; 740 case FCASE(OSUB, TFLOAT64, Frev): 741 return AFSUBRD; 742 case FCASE(OSUB, TFLOAT64, Fpop): 743 return AFSUBDP; 744 case FCASE(OSUB, TFLOAT64, Fpop|Frev): 745 return AFSUBRDP; 746 747 case FCASE(OMUL, TFLOAT32, 0): 748 return AFMULF; 749 case FCASE(OMUL, TFLOAT64, 0): 750 return AFMULD; 751 case FCASE(OMUL, TFLOAT64, Fpop): 752 return AFMULDP; 753 754 case FCASE(ODIV, TFLOAT32, 0): 755 return AFDIVF; 756 case FCASE(ODIV, TFLOAT32, Frev): 757 return AFDIVRF; 758 759 case FCASE(ODIV, TFLOAT64, 0): 760 return AFDIVD; 761 case FCASE(ODIV, TFLOAT64, Frev): 762 return AFDIVRD; 763 case FCASE(ODIV, TFLOAT64, Fpop): 764 return AFDIVDP; 765 case FCASE(ODIV, TFLOAT64, Fpop|Frev): 766 return AFDIVRDP; 767 768 case FCASE(OCMP, TFLOAT32, 0): 769 return AFCOMF; 770 case FCASE(OCMP, TFLOAT32, Fpop): 771 return AFCOMFP; 772 case FCASE(OCMP, TFLOAT64, 0): 773 return AFCOMD; 774 case FCASE(OCMP, TFLOAT64, Fpop): 775 return AFCOMDP; 776 case FCASE(OCMP, TFLOAT64, Fpop2): 777 return AFCOMDPP; 778 779 case FCASE(OMINUS, TFLOAT32, 0): 780 return AFCHS; 781 case FCASE(OMINUS, TFLOAT64, 0): 782 return AFCHS; 783 } 784 785 fatal("foptoas %O %T %#x", op, t, flg); 786 return 0; 787 788 sse: 789 switch(CASE(op, et)) { 790 default: 791 fatal("foptoas-sse: no entry %O-%T", op, t); 792 break; 793 794 case CASE(OCMP, TFLOAT32): 795 a = AUCOMISS; 796 break; 797 798 case CASE(OCMP, TFLOAT64): 799 a = AUCOMISD; 800 break; 801 802 case CASE(OAS, TFLOAT32): 803 a = AMOVSS; 804 break; 805 806 case CASE(OAS, TFLOAT64): 807 a = AMOVSD; 808 break; 809 810 case CASE(OADD, TFLOAT32): 811 a = AADDSS; 812 break; 813 814 case CASE(OADD, TFLOAT64): 815 a = AADDSD; 816 break; 817 818 case CASE(OSUB, TFLOAT32): 819 a = ASUBSS; 820 break; 821 822 case CASE(OSUB, TFLOAT64): 823 a = ASUBSD; 824 break; 825 826 case CASE(OMUL, TFLOAT32): 827 a = AMULSS; 828 break; 829 830 case CASE(OMUL, TFLOAT64): 831 a = AMULSD; 832 break; 833 834 case CASE(ODIV, TFLOAT32): 835 a = ADIVSS; 836 break; 837 838 case CASE(ODIV, TFLOAT64): 839 a = ADIVSD; 840 break; 841 } 842 return a; 843 } 844 845 846 static int resvd[] = 847 { 848 // D_DI, // for movstring 849 // D_SI, // for movstring 850 851 D_AX, // for divide 852 D_CX, // for shift 853 D_DX, // for divide 854 D_SP, // for stack 855 856 D_BL, // because D_BX can be allocated 857 D_BH, 858 }; 859 860 void 861 ginit(void) 862 { 863 int i; 864 865 for(i=0; i<nelem(reg); i++) 866 reg[i] = 1; 867 for(i=D_AX; i<=D_DI; i++) 868 reg[i] = 0; 869 for(i=D_X0; i<=D_X7; i++) 870 reg[i] = 0; 871 for(i=0; i<nelem(resvd); i++) 872 reg[resvd[i]]++; 873 } 874 875 uintptr regpc[D_NONE]; 876 877 void 878 gclean(void) 879 { 880 int i; 881 882 for(i=0; i<nelem(resvd); i++) 883 reg[resvd[i]]--; 884 885 for(i=D_AX; i<=D_DI; i++) 886 if(reg[i]) 887 yyerror("reg %R left allocated at %ux", i, regpc[i]); 888 for(i=D_X0; i<=D_X7; i++) 889 if(reg[i]) 890 yyerror("reg %R left allocated\n", i); 891 } 892 893 int32 894 anyregalloc(void) 895 { 896 int i, j; 897 898 for(i=D_AX; i<=D_DI; i++) { 899 if(reg[i] == 0) 900 goto ok; 901 for(j=0; j<nelem(resvd); j++) 902 if(resvd[j] == i) 903 goto ok; 904 return 1; 905 ok:; 906 } 907 for(i=D_X0; i<=D_X7; i++) 908 if(reg[i]) 909 return 1; 910 return 0; 911 } 912 913 /* 914 * allocate register of type t, leave in n. 915 * if o != N, o is desired fixed register. 916 * caller must regfree(n). 917 */ 918 void 919 regalloc(Node *n, Type *t, Node *o) 920 { 921 int i, et; 922 923 if(t == T) 924 fatal("regalloc: t nil"); 925 et = simtype[t->etype]; 926 927 switch(et) { 928 case TINT64: 929 case TUINT64: 930 fatal("regalloc64"); 931 932 case TINT8: 933 case TUINT8: 934 case TINT16: 935 case TUINT16: 936 case TINT32: 937 case TUINT32: 938 case TPTR32: 939 case TPTR64: 940 case TBOOL: 941 if(o != N && o->op == OREGISTER) { 942 i = o->val.u.reg; 943 if(i >= D_AX && i <= D_DI) 944 goto out; 945 } 946 for(i=D_AX; i<=D_DI; i++) 947 if(reg[i] == 0) 948 goto out; 949 950 fprint(2, "registers allocated at\n"); 951 for(i=D_AX; i<=D_DI; i++) 952 fprint(2, "\t%R\t%#lux\n", i, regpc[i]); 953 yyerror("out of fixed registers"); 954 goto err; 955 956 case TFLOAT32: 957 case TFLOAT64: 958 if(!use_sse) { 959 i = D_F0; 960 goto out; 961 } 962 if(o != N && o->op == OREGISTER) { 963 i = o->val.u.reg; 964 if(i >= D_X0 && i <= D_X7) 965 goto out; 966 } 967 for(i=D_X0; i<=D_X7; i++) 968 if(reg[i] == 0) 969 goto out; 970 fprint(2, "registers allocated at\n"); 971 for(i=D_X0; i<=D_X7; i++) 972 fprint(2, "\t%R\t%#lux\n", i, regpc[i]); 973 fatal("out of floating registers"); 974 } 975 yyerror("regalloc: unknown type %T", t); 976 977 err: 978 nodreg(n, t, 0); 979 return; 980 981 out: 982 if (i == D_SP) 983 print("alloc SP\n"); 984 if(reg[i] == 0) { 985 regpc[i] = (uintptr)getcallerpc(&n); 986 if(i == D_AX || i == D_CX || i == D_DX || i == D_SP) { 987 dump("regalloc-o", o); 988 fatal("regalloc %R", i); 989 } 990 } 991 reg[i]++; 992 nodreg(n, t, i); 993 } 994 995 void 996 regfree(Node *n) 997 { 998 int i; 999 1000 if(n->op == ONAME) 1001 return; 1002 if(n->op != OREGISTER && n->op != OINDREG) 1003 fatal("regfree: not a register"); 1004 i = n->val.u.reg; 1005 if(i == D_SP) 1006 return; 1007 if(i < 0 || i >= nelem(reg)) 1008 fatal("regfree: reg out of range"); 1009 if(reg[i] <= 0) 1010 fatal("regfree: reg not allocated"); 1011 reg[i]--; 1012 if(reg[i] == 0 && (i == D_AX || i == D_CX || i == D_DX || i == D_SP)) 1013 fatal("regfree %R", i); 1014 } 1015 1016 /* 1017 * initialize n to be register r of type t. 1018 */ 1019 void 1020 nodreg(Node *n, Type *t, int r) 1021 { 1022 if(t == T) 1023 fatal("nodreg: t nil"); 1024 1025 memset(n, 0, sizeof(*n)); 1026 n->op = OREGISTER; 1027 n->addable = 1; 1028 ullmancalc(n); 1029 n->val.u.reg = r; 1030 n->type = t; 1031 } 1032 1033 /* 1034 * initialize n to be indirect of register r; n is type t. 1035 */ 1036 void 1037 nodindreg(Node *n, Type *t, int r) 1038 { 1039 nodreg(n, t, r); 1040 n->op = OINDREG; 1041 } 1042 1043 Node* 1044 nodarg(Type *t, int fp) 1045 { 1046 Node *n; 1047 NodeList *l; 1048 Type *first; 1049 Iter savet; 1050 1051 // entire argument struct, not just one arg 1052 switch(t->etype) { 1053 default: 1054 fatal("nodarg %T", t); 1055 1056 case TSTRUCT: 1057 if(!t->funarg) 1058 fatal("nodarg: TSTRUCT but not funarg"); 1059 n = nod(ONAME, N, N); 1060 n->sym = lookup(".args"); 1061 n->type = t; 1062 first = structfirst(&savet, &t); 1063 if(first == nil) 1064 fatal("nodarg: bad struct"); 1065 if(first->width == BADWIDTH) 1066 fatal("nodarg: offset not computed for %T", t); 1067 n->xoffset = first->width; 1068 n->addable = 1; 1069 break; 1070 1071 case TFIELD: 1072 if(fp == 1 && t->sym != S && !isblanksym(t->sym)) { 1073 for(l=curfn->dcl; l; l=l->next) { 1074 n = l->n; 1075 if((n->class == PPARAM || n->class == PPARAMOUT) && n->sym == t->sym) 1076 return n; 1077 } 1078 } 1079 1080 n = nod(ONAME, N, N); 1081 n->type = t->type; 1082 n->sym = t->sym; 1083 if(t->width == BADWIDTH) 1084 fatal("nodarg: offset not computed for %T", t); 1085 n->xoffset = t->width; 1086 n->addable = 1; 1087 n->orig = t->nname; 1088 break; 1089 } 1090 1091 // Rewrite argument named _ to __, 1092 // or else the assignment to _ will be 1093 // discarded during code generation. 1094 if(isblank(n)) 1095 n->sym = lookup("__"); 1096 1097 switch(fp) { 1098 default: 1099 fatal("nodarg %T %d", t, fp); 1100 1101 case 0: // output arg 1102 n->op = OINDREG; 1103 n->val.u.reg = D_SP; 1104 break; 1105 1106 case 1: // input arg 1107 n->class = PPARAM; 1108 break; 1109 } 1110 1111 n->typecheck = 1; 1112 return n; 1113 } 1114 1115 /* 1116 * generate 1117 * as $c, reg 1118 */ 1119 void 1120 gconreg(int as, vlong c, int reg) 1121 { 1122 Node n1, n2; 1123 1124 nodconst(&n1, types[TINT64], c); 1125 nodreg(&n2, types[TINT64], reg); 1126 gins(as, &n1, &n2); 1127 } 1128 1129 /* 1130 * swap node contents 1131 */ 1132 void 1133 nswap(Node *a, Node *b) 1134 { 1135 Node t; 1136 1137 t = *a; 1138 *a = *b; 1139 *b = t; 1140 } 1141 1142 /* 1143 * return constant i node. 1144 * overwritten by next call, but useful in calls to gins. 1145 */ 1146 Node* 1147 ncon(uint32 i) 1148 { 1149 static Node n; 1150 1151 if(n.type == T) 1152 nodconst(&n, types[TUINT32], 0); 1153 mpmovecfix(n.val.u.xval, i); 1154 return &n; 1155 } 1156 1157 /* 1158 * Is this node a memory operand? 1159 */ 1160 int 1161 ismem(Node *n) 1162 { 1163 switch(n->op) { 1164 case OITAB: 1165 case OSPTR: 1166 case OLEN: 1167 case OCAP: 1168 case OINDREG: 1169 case ONAME: 1170 case OPARAM: 1171 case OCLOSUREVAR: 1172 return 1; 1173 } 1174 return 0; 1175 } 1176 1177 Node sclean[10]; 1178 int nsclean; 1179 1180 /* 1181 * n is a 64-bit value. fill in lo and hi to refer to its 32-bit halves. 1182 */ 1183 void 1184 split64(Node *n, Node *lo, Node *hi) 1185 { 1186 Node n1; 1187 int64 i; 1188 1189 if(!is64(n->type)) 1190 fatal("split64 %T", n->type); 1191 1192 if(nsclean >= nelem(sclean)) 1193 fatal("split64 clean"); 1194 sclean[nsclean].op = OEMPTY; 1195 nsclean++; 1196 switch(n->op) { 1197 default: 1198 if(!dotaddable(n, &n1)) { 1199 igen(n, &n1, N); 1200 sclean[nsclean-1] = n1; 1201 } 1202 n = &n1; 1203 goto common; 1204 case ONAME: 1205 if(n->class == PPARAMREF) { 1206 cgen(n->heapaddr, &n1); 1207 sclean[nsclean-1] = n1; 1208 // fall through. 1209 n = &n1; 1210 } 1211 goto common; 1212 case OINDREG: 1213 common: 1214 *lo = *n; 1215 *hi = *n; 1216 lo->type = types[TUINT32]; 1217 if(n->type->etype == TINT64) 1218 hi->type = types[TINT32]; 1219 else 1220 hi->type = types[TUINT32]; 1221 hi->xoffset += 4; 1222 break; 1223 1224 case OLITERAL: 1225 convconst(&n1, n->type, &n->val); 1226 i = mpgetfix(n1.val.u.xval); 1227 nodconst(lo, types[TUINT32], (uint32)i); 1228 i >>= 32; 1229 if(n->type->etype == TINT64) 1230 nodconst(hi, types[TINT32], (int32)i); 1231 else 1232 nodconst(hi, types[TUINT32], (uint32)i); 1233 break; 1234 } 1235 } 1236 1237 void 1238 splitclean(void) 1239 { 1240 if(nsclean <= 0) 1241 fatal("splitclean"); 1242 nsclean--; 1243 if(sclean[nsclean].op != OEMPTY) 1244 regfree(&sclean[nsclean]); 1245 } 1246 1247 /* 1248 * set up nodes representing fp constants 1249 */ 1250 Node zerof; 1251 Node two64f; 1252 Node two63f; 1253 1254 void 1255 bignodes(void) 1256 { 1257 static int did; 1258 1259 if(did) 1260 return; 1261 did = 1; 1262 1263 two64f = *ncon(0); 1264 two64f.type = types[TFLOAT64]; 1265 two64f.val.ctype = CTFLT; 1266 two64f.val.u.fval = mal(sizeof *two64f.val.u.fval); 1267 mpmovecflt(two64f.val.u.fval, 18446744073709551616.); 1268 1269 two63f = two64f; 1270 two63f.val.u.fval = mal(sizeof *two63f.val.u.fval); 1271 mpmovecflt(two63f.val.u.fval, 9223372036854775808.); 1272 1273 zerof = two64f; 1274 zerof.val.u.fval = mal(sizeof *zerof.val.u.fval); 1275 mpmovecflt(zerof.val.u.fval, 0); 1276 } 1277 1278 void 1279 memname(Node *n, Type *t) 1280 { 1281 tempname(n, t); 1282 strcpy(namebuf, n->sym->name); 1283 namebuf[0] = '.'; // keep optimizer from registerizing 1284 n->sym = lookup(namebuf); 1285 n->orig->sym = n->sym; 1286 } 1287 1288 static void floatmove(Node *f, Node *t); 1289 static void floatmove_387(Node *f, Node *t); 1290 static void floatmove_sse(Node *f, Node *t); 1291 1292 void 1293 gmove(Node *f, Node *t) 1294 { 1295 int a, ft, tt; 1296 Type *cvt; 1297 Node r1, r2, flo, fhi, tlo, thi, con; 1298 1299 if(debug['M']) 1300 print("gmove %N -> %N\n", f, t); 1301 1302 ft = simsimtype(f->type); 1303 tt = simsimtype(t->type); 1304 cvt = t->type; 1305 1306 if(iscomplex[ft] || iscomplex[tt]) { 1307 complexmove(f, t); 1308 return; 1309 } 1310 if(isfloat[ft] || isfloat[tt]) { 1311 floatmove(f, t); 1312 return; 1313 } 1314 1315 // cannot have two integer memory operands; 1316 // except 64-bit, which always copies via registers anyway. 1317 if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t)) 1318 goto hard; 1319 1320 // convert constant to desired type 1321 if(f->op == OLITERAL) { 1322 convconst(&con, t->type, &f->val); 1323 f = &con; 1324 ft = simsimtype(con.type); 1325 } 1326 1327 // value -> value copy, only one memory operand. 1328 // figure out the instruction to use. 1329 // break out of switch for one-instruction gins. 1330 // goto rdst for "destination must be register". 1331 // goto hard for "convert to cvt type first". 1332 // otherwise handle and return. 1333 1334 switch(CASE(ft, tt)) { 1335 default: 1336 goto fatal; 1337 1338 /* 1339 * integer copy and truncate 1340 */ 1341 case CASE(TINT8, TINT8): // same size 1342 case CASE(TINT8, TUINT8): 1343 case CASE(TUINT8, TINT8): 1344 case CASE(TUINT8, TUINT8): 1345 a = AMOVB; 1346 break; 1347 1348 case CASE(TINT16, TINT8): // truncate 1349 case CASE(TUINT16, TINT8): 1350 case CASE(TINT32, TINT8): 1351 case CASE(TUINT32, TINT8): 1352 case CASE(TINT16, TUINT8): 1353 case CASE(TUINT16, TUINT8): 1354 case CASE(TINT32, TUINT8): 1355 case CASE(TUINT32, TUINT8): 1356 a = AMOVB; 1357 goto rsrc; 1358 1359 case CASE(TINT64, TINT8): // truncate low word 1360 case CASE(TUINT64, TINT8): 1361 case CASE(TINT64, TUINT8): 1362 case CASE(TUINT64, TUINT8): 1363 split64(f, &flo, &fhi); 1364 nodreg(&r1, t->type, D_AX); 1365 gmove(&flo, &r1); 1366 gins(AMOVB, &r1, t); 1367 splitclean(); 1368 return; 1369 1370 case CASE(TINT16, TINT16): // same size 1371 case CASE(TINT16, TUINT16): 1372 case CASE(TUINT16, TINT16): 1373 case CASE(TUINT16, TUINT16): 1374 a = AMOVW; 1375 break; 1376 1377 case CASE(TINT32, TINT16): // truncate 1378 case CASE(TUINT32, TINT16): 1379 case CASE(TINT32, TUINT16): 1380 case CASE(TUINT32, TUINT16): 1381 a = AMOVW; 1382 goto rsrc; 1383 1384 case CASE(TINT64, TINT16): // truncate low word 1385 case CASE(TUINT64, TINT16): 1386 case CASE(TINT64, TUINT16): 1387 case CASE(TUINT64, TUINT16): 1388 split64(f, &flo, &fhi); 1389 nodreg(&r1, t->type, D_AX); 1390 gmove(&flo, &r1); 1391 gins(AMOVW, &r1, t); 1392 splitclean(); 1393 return; 1394 1395 case CASE(TINT32, TINT32): // same size 1396 case CASE(TINT32, TUINT32): 1397 case CASE(TUINT32, TINT32): 1398 case CASE(TUINT32, TUINT32): 1399 a = AMOVL; 1400 break; 1401 1402 case CASE(TINT64, TINT32): // truncate 1403 case CASE(TUINT64, TINT32): 1404 case CASE(TINT64, TUINT32): 1405 case CASE(TUINT64, TUINT32): 1406 split64(f, &flo, &fhi); 1407 nodreg(&r1, t->type, D_AX); 1408 gmove(&flo, &r1); 1409 gins(AMOVL, &r1, t); 1410 splitclean(); 1411 return; 1412 1413 case CASE(TINT64, TINT64): // same size 1414 case CASE(TINT64, TUINT64): 1415 case CASE(TUINT64, TINT64): 1416 case CASE(TUINT64, TUINT64): 1417 split64(f, &flo, &fhi); 1418 split64(t, &tlo, &thi); 1419 if(f->op == OLITERAL) { 1420 gins(AMOVL, &flo, &tlo); 1421 gins(AMOVL, &fhi, &thi); 1422 } else { 1423 nodreg(&r1, t->type, D_AX); 1424 nodreg(&r2, t->type, D_DX); 1425 gins(AMOVL, &flo, &r1); 1426 gins(AMOVL, &fhi, &r2); 1427 gins(AMOVL, &r1, &tlo); 1428 gins(AMOVL, &r2, &thi); 1429 } 1430 splitclean(); 1431 splitclean(); 1432 return; 1433 1434 /* 1435 * integer up-conversions 1436 */ 1437 case CASE(TINT8, TINT16): // sign extend int8 1438 case CASE(TINT8, TUINT16): 1439 a = AMOVBWSX; 1440 goto rdst; 1441 case CASE(TINT8, TINT32): 1442 case CASE(TINT8, TUINT32): 1443 a = AMOVBLSX; 1444 goto rdst; 1445 case CASE(TINT8, TINT64): // convert via int32 1446 case CASE(TINT8, TUINT64): 1447 cvt = types[TINT32]; 1448 goto hard; 1449 1450 case CASE(TUINT8, TINT16): // zero extend uint8 1451 case CASE(TUINT8, TUINT16): 1452 a = AMOVBWZX; 1453 goto rdst; 1454 case CASE(TUINT8, TINT32): 1455 case CASE(TUINT8, TUINT32): 1456 a = AMOVBLZX; 1457 goto rdst; 1458 case CASE(TUINT8, TINT64): // convert via uint32 1459 case CASE(TUINT8, TUINT64): 1460 cvt = types[TUINT32]; 1461 goto hard; 1462 1463 case CASE(TINT16, TINT32): // sign extend int16 1464 case CASE(TINT16, TUINT32): 1465 a = AMOVWLSX; 1466 goto rdst; 1467 case CASE(TINT16, TINT64): // convert via int32 1468 case CASE(TINT16, TUINT64): 1469 cvt = types[TINT32]; 1470 goto hard; 1471 1472 case CASE(TUINT16, TINT32): // zero extend uint16 1473 case CASE(TUINT16, TUINT32): 1474 a = AMOVWLZX; 1475 goto rdst; 1476 case CASE(TUINT16, TINT64): // convert via uint32 1477 case CASE(TUINT16, TUINT64): 1478 cvt = types[TUINT32]; 1479 goto hard; 1480 1481 case CASE(TINT32, TINT64): // sign extend int32 1482 case CASE(TINT32, TUINT64): 1483 split64(t, &tlo, &thi); 1484 nodreg(&flo, tlo.type, D_AX); 1485 nodreg(&fhi, thi.type, D_DX); 1486 gmove(f, &flo); 1487 gins(ACDQ, N, N); 1488 gins(AMOVL, &flo, &tlo); 1489 gins(AMOVL, &fhi, &thi); 1490 splitclean(); 1491 return; 1492 1493 case CASE(TUINT32, TINT64): // zero extend uint32 1494 case CASE(TUINT32, TUINT64): 1495 split64(t, &tlo, &thi); 1496 gmove(f, &tlo); 1497 gins(AMOVL, ncon(0), &thi); 1498 splitclean(); 1499 return; 1500 } 1501 1502 gins(a, f, t); 1503 return; 1504 1505 rsrc: 1506 // requires register source 1507 regalloc(&r1, f->type, t); 1508 gmove(f, &r1); 1509 gins(a, &r1, t); 1510 regfree(&r1); 1511 return; 1512 1513 rdst: 1514 // requires register destination 1515 regalloc(&r1, t->type, t); 1516 gins(a, f, &r1); 1517 gmove(&r1, t); 1518 regfree(&r1); 1519 return; 1520 1521 hard: 1522 // requires register intermediate 1523 regalloc(&r1, cvt, t); 1524 gmove(f, &r1); 1525 gmove(&r1, t); 1526 regfree(&r1); 1527 return; 1528 1529 fatal: 1530 // should not happen 1531 fatal("gmove %N -> %N", f, t); 1532 } 1533 1534 static void 1535 floatmove(Node *f, Node *t) 1536 { 1537 Node r1, r2, t1, t2, tlo, thi, con, f0, f1, ax, dx, cx; 1538 Type *cvt; 1539 int ft, tt; 1540 Prog *p1, *p2, *p3; 1541 1542 ft = simsimtype(f->type); 1543 tt = simsimtype(t->type); 1544 cvt = t->type; 1545 1546 // cannot have two floating point memory operands. 1547 if(isfloat[ft] && isfloat[tt] && ismem(f) && ismem(t)) 1548 goto hard; 1549 1550 // convert constant to desired type 1551 if(f->op == OLITERAL) { 1552 convconst(&con, t->type, &f->val); 1553 f = &con; 1554 ft = simsimtype(con.type); 1555 1556 // some constants can't move directly to memory. 1557 if(ismem(t)) { 1558 // float constants come from memory. 1559 if(isfloat[tt]) 1560 goto hard; 1561 } 1562 } 1563 1564 // value -> value copy, only one memory operand. 1565 // figure out the instruction to use. 1566 // break out of switch for one-instruction gins. 1567 // goto rdst for "destination must be register". 1568 // goto hard for "convert to cvt type first". 1569 // otherwise handle and return. 1570 1571 switch(CASE(ft, tt)) { 1572 default: 1573 if(use_sse) 1574 floatmove_sse(f, t); 1575 else 1576 floatmove_387(f, t); 1577 return; 1578 1579 // float to very long integer. 1580 case CASE(TFLOAT32, TINT64): 1581 case CASE(TFLOAT64, TINT64): 1582 if(f->op == OREGISTER) { 1583 cvt = f->type; 1584 goto hardmem; 1585 } 1586 nodreg(&r1, types[ft], D_F0); 1587 if(ft == TFLOAT32) 1588 gins(AFMOVF, f, &r1); 1589 else 1590 gins(AFMOVD, f, &r1); 1591 1592 // set round to zero mode during conversion 1593 memname(&t1, types[TUINT16]); 1594 memname(&t2, types[TUINT16]); 1595 gins(AFSTCW, N, &t1); 1596 gins(AMOVW, ncon(0xf7f), &t2); 1597 gins(AFLDCW, &t2, N); 1598 if(tt == TINT16) 1599 gins(AFMOVWP, &r1, t); 1600 else if(tt == TINT32) 1601 gins(AFMOVLP, &r1, t); 1602 else 1603 gins(AFMOVVP, &r1, t); 1604 gins(AFLDCW, &t1, N); 1605 return; 1606 1607 case CASE(TFLOAT32, TUINT64): 1608 case CASE(TFLOAT64, TUINT64): 1609 if(!ismem(f)) { 1610 cvt = f->type; 1611 goto hardmem; 1612 } 1613 bignodes(); 1614 nodreg(&f0, types[ft], D_F0); 1615 nodreg(&f1, types[ft], D_F0 + 1); 1616 nodreg(&ax, types[TUINT16], D_AX); 1617 1618 if(ft == TFLOAT32) 1619 gins(AFMOVF, f, &f0); 1620 else 1621 gins(AFMOVD, f, &f0); 1622 1623 // if 0 > v { answer = 0 } 1624 gins(AFMOVD, &zerof, &f0); 1625 gins(AFUCOMIP, &f0, &f1); 1626 p1 = gbranch(optoas(OGT, types[tt]), T, 0); 1627 // if 1<<64 <= v { answer = 0 too } 1628 gins(AFMOVD, &two64f, &f0); 1629 gins(AFUCOMIP, &f0, &f1); 1630 p2 = gbranch(optoas(OGT, types[tt]), T, 0); 1631 patch(p1, pc); 1632 gins(AFMOVVP, &f0, t); // don't care about t, but will pop the stack 1633 split64(t, &tlo, &thi); 1634 gins(AMOVL, ncon(0), &tlo); 1635 gins(AMOVL, ncon(0), &thi); 1636 splitclean(); 1637 p1 = gbranch(AJMP, T, 0); 1638 patch(p2, pc); 1639 1640 // in range; algorithm is: 1641 // if small enough, use native float64 -> int64 conversion. 1642 // otherwise, subtract 2^63, convert, and add it back. 1643 1644 // set round to zero mode during conversion 1645 memname(&t1, types[TUINT16]); 1646 memname(&t2, types[TUINT16]); 1647 gins(AFSTCW, N, &t1); 1648 gins(AMOVW, ncon(0xf7f), &t2); 1649 gins(AFLDCW, &t2, N); 1650 1651 // actual work 1652 gins(AFMOVD, &two63f, &f0); 1653 gins(AFUCOMIP, &f0, &f1); 1654 p2 = gbranch(optoas(OLE, types[tt]), T, 0); 1655 gins(AFMOVVP, &f0, t); 1656 p3 = gbranch(AJMP, T, 0); 1657 patch(p2, pc); 1658 gins(AFMOVD, &two63f, &f0); 1659 gins(AFSUBDP, &f0, &f1); 1660 gins(AFMOVVP, &f0, t); 1661 split64(t, &tlo, &thi); 1662 gins(AXORL, ncon(0x80000000), &thi); // + 2^63 1663 patch(p3, pc); 1664 splitclean(); 1665 // restore rounding mode 1666 gins(AFLDCW, &t1, N); 1667 1668 patch(p1, pc); 1669 return; 1670 1671 /* 1672 * integer to float 1673 */ 1674 case CASE(TINT64, TFLOAT32): 1675 case CASE(TINT64, TFLOAT64): 1676 if(t->op == OREGISTER) 1677 goto hardmem; 1678 nodreg(&f0, t->type, D_F0); 1679 gins(AFMOVV, f, &f0); 1680 if(tt == TFLOAT32) 1681 gins(AFMOVFP, &f0, t); 1682 else 1683 gins(AFMOVDP, &f0, t); 1684 return; 1685 1686 case CASE(TUINT64, TFLOAT32): 1687 case CASE(TUINT64, TFLOAT64): 1688 // algorithm is: 1689 // if small enough, use native int64 -> float64 conversion. 1690 // otherwise, halve (rounding to odd?), convert, and double. 1691 nodreg(&ax, types[TUINT32], D_AX); 1692 nodreg(&dx, types[TUINT32], D_DX); 1693 nodreg(&cx, types[TUINT32], D_CX); 1694 tempname(&t1, f->type); 1695 split64(&t1, &tlo, &thi); 1696 gmove(f, &t1); 1697 gins(ACMPL, &thi, ncon(0)); 1698 p1 = gbranch(AJLT, T, 0); 1699 // native 1700 nodreg(&r1, types[tt], D_F0); 1701 gins(AFMOVV, &t1, &r1); 1702 if(tt == TFLOAT32) 1703 gins(AFMOVFP, &r1, t); 1704 else 1705 gins(AFMOVDP, &r1, t); 1706 p2 = gbranch(AJMP, T, 0); 1707 // simulated 1708 patch(p1, pc); 1709 gmove(&tlo, &ax); 1710 gmove(&thi, &dx); 1711 p1 = gins(ASHRL, ncon(1), &ax); 1712 p1->from.index = D_DX; // double-width shift DX -> AX 1713 p1->from.scale = 0; 1714 gins(AMOVL, ncon(0), &cx); 1715 gins(ASETCC, N, &cx); 1716 gins(AORL, &cx, &ax); 1717 gins(ASHRL, ncon(1), &dx); 1718 gmove(&dx, &thi); 1719 gmove(&ax, &tlo); 1720 nodreg(&r1, types[tt], D_F0); 1721 nodreg(&r2, types[tt], D_F0 + 1); 1722 gins(AFMOVV, &t1, &r1); 1723 gins(AFMOVD, &r1, &r1); 1724 gins(AFADDDP, &r1, &r2); 1725 if(tt == TFLOAT32) 1726 gins(AFMOVFP, &r1, t); 1727 else 1728 gins(AFMOVDP, &r1, t); 1729 patch(p2, pc); 1730 splitclean(); 1731 return; 1732 } 1733 1734 hard: 1735 // requires register intermediate 1736 regalloc(&r1, cvt, t); 1737 gmove(f, &r1); 1738 gmove(&r1, t); 1739 regfree(&r1); 1740 return; 1741 1742 hardmem: 1743 // requires memory intermediate 1744 tempname(&r1, cvt); 1745 gmove(f, &r1); 1746 gmove(&r1, t); 1747 return; 1748 } 1749 1750 static void 1751 floatmove_387(Node *f, Node *t) 1752 { 1753 Node r1, t1, t2; 1754 Type *cvt; 1755 Prog *p1, *p2, *p3; 1756 int a, ft, tt; 1757 1758 ft = simsimtype(f->type); 1759 tt = simsimtype(t->type); 1760 cvt = t->type; 1761 1762 switch(CASE(ft, tt)) { 1763 default: 1764 goto fatal; 1765 1766 /* 1767 * float to integer 1768 */ 1769 case CASE(TFLOAT32, TINT16): 1770 case CASE(TFLOAT32, TINT32): 1771 case CASE(TFLOAT32, TINT64): 1772 case CASE(TFLOAT64, TINT16): 1773 case CASE(TFLOAT64, TINT32): 1774 case CASE(TFLOAT64, TINT64): 1775 if(t->op == OREGISTER) 1776 goto hardmem; 1777 nodreg(&r1, types[ft], D_F0); 1778 if(f->op != OREGISTER) { 1779 if(ft == TFLOAT32) 1780 gins(AFMOVF, f, &r1); 1781 else 1782 gins(AFMOVD, f, &r1); 1783 } 1784 1785 // set round to zero mode during conversion 1786 memname(&t1, types[TUINT16]); 1787 memname(&t2, types[TUINT16]); 1788 gins(AFSTCW, N, &t1); 1789 gins(AMOVW, ncon(0xf7f), &t2); 1790 gins(AFLDCW, &t2, N); 1791 if(tt == TINT16) 1792 gins(AFMOVWP, &r1, t); 1793 else if(tt == TINT32) 1794 gins(AFMOVLP, &r1, t); 1795 else 1796 gins(AFMOVVP, &r1, t); 1797 gins(AFLDCW, &t1, N); 1798 return; 1799 1800 case CASE(TFLOAT32, TINT8): 1801 case CASE(TFLOAT32, TUINT16): 1802 case CASE(TFLOAT32, TUINT8): 1803 case CASE(TFLOAT64, TINT8): 1804 case CASE(TFLOAT64, TUINT16): 1805 case CASE(TFLOAT64, TUINT8): 1806 // convert via int32. 1807 tempname(&t1, types[TINT32]); 1808 gmove(f, &t1); 1809 switch(tt) { 1810 default: 1811 fatal("gmove %T", t); 1812 case TINT8: 1813 gins(ACMPL, &t1, ncon(-0x80)); 1814 p1 = gbranch(optoas(OLT, types[TINT32]), T, -1); 1815 gins(ACMPL, &t1, ncon(0x7f)); 1816 p2 = gbranch(optoas(OGT, types[TINT32]), T, -1); 1817 p3 = gbranch(AJMP, T, 0); 1818 patch(p1, pc); 1819 patch(p2, pc); 1820 gmove(ncon(-0x80), &t1); 1821 patch(p3, pc); 1822 gmove(&t1, t); 1823 break; 1824 case TUINT8: 1825 gins(ATESTL, ncon(0xffffff00), &t1); 1826 p1 = gbranch(AJEQ, T, +1); 1827 gins(AMOVL, ncon(0), &t1); 1828 patch(p1, pc); 1829 gmove(&t1, t); 1830 break; 1831 case TUINT16: 1832 gins(ATESTL, ncon(0xffff0000), &t1); 1833 p1 = gbranch(AJEQ, T, +1); 1834 gins(AMOVL, ncon(0), &t1); 1835 patch(p1, pc); 1836 gmove(&t1, t); 1837 break; 1838 } 1839 return; 1840 1841 case CASE(TFLOAT32, TUINT32): 1842 case CASE(TFLOAT64, TUINT32): 1843 // convert via int64. 1844 cvt = types[TINT64]; 1845 goto hardmem; 1846 1847 /* 1848 * integer to float 1849 */ 1850 case CASE(TINT16, TFLOAT32): 1851 case CASE(TINT16, TFLOAT64): 1852 case CASE(TINT32, TFLOAT32): 1853 case CASE(TINT32, TFLOAT64): 1854 case CASE(TINT64, TFLOAT32): 1855 case CASE(TINT64, TFLOAT64): 1856 if(t->op != OREGISTER) 1857 goto hard; 1858 if(f->op == OREGISTER) { 1859 cvt = f->type; 1860 goto hardmem; 1861 } 1862 switch(ft) { 1863 case TINT16: 1864 a = AFMOVW; 1865 break; 1866 case TINT32: 1867 a = AFMOVL; 1868 break; 1869 default: 1870 a = AFMOVV; 1871 break; 1872 } 1873 break; 1874 1875 case CASE(TINT8, TFLOAT32): 1876 case CASE(TINT8, TFLOAT64): 1877 case CASE(TUINT16, TFLOAT32): 1878 case CASE(TUINT16, TFLOAT64): 1879 case CASE(TUINT8, TFLOAT32): 1880 case CASE(TUINT8, TFLOAT64): 1881 // convert via int32 memory 1882 cvt = types[TINT32]; 1883 goto hardmem; 1884 1885 case CASE(TUINT32, TFLOAT32): 1886 case CASE(TUINT32, TFLOAT64): 1887 // convert via int64 memory 1888 cvt = types[TINT64]; 1889 goto hardmem; 1890 1891 /* 1892 * float to float 1893 */ 1894 case CASE(TFLOAT32, TFLOAT32): 1895 case CASE(TFLOAT64, TFLOAT64): 1896 // The way the code generator uses floating-point 1897 // registers, a move from F0 to F0 is intended as a no-op. 1898 // On the x86, it's not: it pushes a second copy of F0 1899 // on the floating point stack. So toss it away here. 1900 // Also, F0 is the *only* register we ever evaluate 1901 // into, so we should only see register/register as F0/F0. 1902 if(ismem(f) && ismem(t)) 1903 goto hard; 1904 if(f->op == OREGISTER && t->op == OREGISTER) { 1905 if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0) 1906 goto fatal; 1907 return; 1908 } 1909 a = AFMOVF; 1910 if(ft == TFLOAT64) 1911 a = AFMOVD; 1912 if(ismem(t)) { 1913 if(f->op != OREGISTER || f->val.u.reg != D_F0) 1914 fatal("gmove %N", f); 1915 a = AFMOVFP; 1916 if(ft == TFLOAT64) 1917 a = AFMOVDP; 1918 } 1919 break; 1920 1921 case CASE(TFLOAT32, TFLOAT64): 1922 if(ismem(f) && ismem(t)) 1923 goto hard; 1924 if(f->op == OREGISTER && t->op == OREGISTER) { 1925 if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0) 1926 goto fatal; 1927 return; 1928 } 1929 if(f->op == OREGISTER) 1930 gins(AFMOVDP, f, t); 1931 else 1932 gins(AFMOVF, f, t); 1933 return; 1934 1935 case CASE(TFLOAT64, TFLOAT32): 1936 if(ismem(f) && ismem(t)) 1937 goto hard; 1938 if(f->op == OREGISTER && t->op == OREGISTER) { 1939 tempname(&r1, types[TFLOAT32]); 1940 gins(AFMOVFP, f, &r1); 1941 gins(AFMOVF, &r1, t); 1942 return; 1943 } 1944 if(f->op == OREGISTER) 1945 gins(AFMOVFP, f, t); 1946 else 1947 gins(AFMOVD, f, t); 1948 return; 1949 } 1950 1951 gins(a, f, t); 1952 return; 1953 1954 hard: 1955 // requires register intermediate 1956 regalloc(&r1, cvt, t); 1957 gmove(f, &r1); 1958 gmove(&r1, t); 1959 regfree(&r1); 1960 return; 1961 1962 hardmem: 1963 // requires memory intermediate 1964 tempname(&r1, cvt); 1965 gmove(f, &r1); 1966 gmove(&r1, t); 1967 return; 1968 1969 fatal: 1970 // should not happen 1971 fatal("gmove %lN -> %lN", f, t); 1972 return; 1973 } 1974 1975 static void 1976 floatmove_sse(Node *f, Node *t) 1977 { 1978 Node r1; 1979 Type *cvt; 1980 int a, ft, tt; 1981 1982 ft = simsimtype(f->type); 1983 tt = simsimtype(t->type); 1984 1985 switch(CASE(ft, tt)) { 1986 default: 1987 // should not happen 1988 fatal("gmove %N -> %N", f, t); 1989 return; 1990 /* 1991 * float to integer 1992 */ 1993 case CASE(TFLOAT32, TINT16): 1994 case CASE(TFLOAT32, TINT8): 1995 case CASE(TFLOAT32, TUINT16): 1996 case CASE(TFLOAT32, TUINT8): 1997 case CASE(TFLOAT64, TINT16): 1998 case CASE(TFLOAT64, TINT8): 1999 case CASE(TFLOAT64, TUINT16): 2000 case CASE(TFLOAT64, TUINT8): 2001 // convert via int32. 2002 cvt = types[TINT32]; 2003 goto hard; 2004 2005 case CASE(TFLOAT32, TUINT32): 2006 case CASE(TFLOAT64, TUINT32): 2007 // convert via int64. 2008 cvt = types[TINT64]; 2009 goto hardmem; 2010 2011 case CASE(TFLOAT32, TINT32): 2012 a = ACVTTSS2SL; 2013 goto rdst; 2014 2015 case CASE(TFLOAT64, TINT32): 2016 a = ACVTTSD2SL; 2017 goto rdst; 2018 2019 /* 2020 * integer to float 2021 */ 2022 case CASE(TINT8, TFLOAT32): 2023 case CASE(TINT8, TFLOAT64): 2024 case CASE(TINT16, TFLOAT32): 2025 case CASE(TINT16, TFLOAT64): 2026 case CASE(TUINT16, TFLOAT32): 2027 case CASE(TUINT16, TFLOAT64): 2028 case CASE(TUINT8, TFLOAT32): 2029 case CASE(TUINT8, TFLOAT64): 2030 // convert via int32 memory 2031 cvt = types[TINT32]; 2032 goto hard; 2033 2034 case CASE(TUINT32, TFLOAT32): 2035 case CASE(TUINT32, TFLOAT64): 2036 // convert via int64 memory 2037 cvt = types[TINT64]; 2038 goto hardmem; 2039 2040 case CASE(TINT32, TFLOAT32): 2041 a = ACVTSL2SS; 2042 goto rdst; 2043 2044 case CASE(TINT32, TFLOAT64): 2045 a = ACVTSL2SD; 2046 goto rdst; 2047 2048 /* 2049 * float to float 2050 */ 2051 case CASE(TFLOAT32, TFLOAT32): 2052 a = AMOVSS; 2053 break; 2054 2055 case CASE(TFLOAT64, TFLOAT64): 2056 a = AMOVSD; 2057 break; 2058 2059 case CASE(TFLOAT32, TFLOAT64): 2060 a = ACVTSS2SD; 2061 goto rdst; 2062 2063 case CASE(TFLOAT64, TFLOAT32): 2064 a = ACVTSD2SS; 2065 goto rdst; 2066 } 2067 2068 gins(a, f, t); 2069 return; 2070 2071 hard: 2072 // requires register intermediate 2073 regalloc(&r1, cvt, t); 2074 gmove(f, &r1); 2075 gmove(&r1, t); 2076 regfree(&r1); 2077 return; 2078 2079 hardmem: 2080 // requires memory intermediate 2081 tempname(&r1, cvt); 2082 gmove(f, &r1); 2083 gmove(&r1, t); 2084 return; 2085 2086 rdst: 2087 // requires register destination 2088 regalloc(&r1, t->type, t); 2089 gins(a, f, &r1); 2090 gmove(&r1, t); 2091 regfree(&r1); 2092 return; 2093 } 2094 2095 int 2096 samaddr(Node *f, Node *t) 2097 { 2098 2099 if(f->op != t->op) 2100 return 0; 2101 2102 switch(f->op) { 2103 case OREGISTER: 2104 if(f->val.u.reg != t->val.u.reg) 2105 break; 2106 return 1; 2107 } 2108 return 0; 2109 } 2110 /* 2111 * generate one instruction: 2112 * as f, t 2113 */ 2114 Prog* 2115 gins(int as, Node *f, Node *t) 2116 { 2117 Prog *p; 2118 Addr af, at; 2119 int w; 2120 2121 if(as == AFMOVF && f && f->op == OREGISTER && t && t->op == OREGISTER) 2122 fatal("gins MOVF reg, reg"); 2123 if(as == ACVTSD2SS && f && f->op == OLITERAL) 2124 fatal("gins CVTSD2SS const"); 2125 if(as == AMOVSD && t && t->op == OREGISTER && t->val.u.reg == D_F0) 2126 fatal("gins MOVSD into F0"); 2127 2128 switch(as) { 2129 case AMOVB: 2130 case AMOVW: 2131 case AMOVL: 2132 if(f != N && t != N && samaddr(f, t)) 2133 return nil; 2134 break; 2135 2136 case ALEAL: 2137 if(f != N && isconst(f, CTNIL)) 2138 fatal("gins LEAL nil %T", f->type); 2139 break; 2140 } 2141 2142 memset(&af, 0, sizeof af); 2143 memset(&at, 0, sizeof at); 2144 if(f != N) 2145 naddr(f, &af, 1); 2146 if(t != N) 2147 naddr(t, &at, 1); 2148 p = prog(as); 2149 if(f != N) 2150 p->from = af; 2151 if(t != N) 2152 p->to = at; 2153 if(debug['g']) 2154 print("%P\n", p); 2155 2156 w = 0; 2157 switch(as) { 2158 case AMOVB: 2159 w = 1; 2160 break; 2161 case AMOVW: 2162 w = 2; 2163 break; 2164 case AMOVL: 2165 w = 4; 2166 break; 2167 } 2168 2169 if(1 && w != 0 && f != N && (af.width > w || at.width > w)) { 2170 dump("bad width from:", f); 2171 dump("bad width to:", t); 2172 fatal("bad width: %P (%d, %d)\n", p, af.width, at.width); 2173 } 2174 2175 return p; 2176 } 2177 2178 /* 2179 * generate code to compute n; 2180 * make a refer to result. 2181 */ 2182 void 2183 naddr(Node *n, Addr *a, int canemitcode) 2184 { 2185 Sym *s; 2186 2187 a->scale = 0; 2188 a->index = D_NONE; 2189 a->type = D_NONE; 2190 a->gotype = nil; 2191 a->node = N; 2192 if(n == N) 2193 return; 2194 2195 switch(n->op) { 2196 default: 2197 fatal("naddr: bad %O %D", n->op, a); 2198 break; 2199 2200 case OREGISTER: 2201 a->type = n->val.u.reg; 2202 a->sym = nil; 2203 break; 2204 2205 case OINDREG: 2206 a->type = n->val.u.reg+D_INDIR; 2207 a->sym = linksym(n->sym); 2208 a->offset = n->xoffset; 2209 break; 2210 2211 case OPARAM: 2212 // n->left is PHEAP ONAME for stack parameter. 2213 // compute address of actual parameter on stack. 2214 a->etype = n->left->type->etype; 2215 a->width = n->left->type->width; 2216 a->offset = n->xoffset; 2217 a->sym = linksym(n->left->sym); 2218 a->type = D_PARAM; 2219 a->node = n->left->orig; 2220 break; 2221 2222 case OCLOSUREVAR: 2223 if(!curfn->needctxt) 2224 fatal("closurevar without needctxt"); 2225 a->type = D_DX+D_INDIR; 2226 a->offset = n->xoffset; 2227 a->sym = nil; 2228 break; 2229 2230 case OCFUNC: 2231 naddr(n->left, a, canemitcode); 2232 a->sym = linksym(n->left->sym); 2233 break; 2234 2235 case ONAME: 2236 a->etype = 0; 2237 a->width = 0; 2238 if(n->type != T) { 2239 a->etype = simtype[n->type->etype]; 2240 dowidth(n->type); 2241 a->width = n->type->width; 2242 } 2243 a->offset = n->xoffset; 2244 s = n->sym; 2245 a->node = n->orig; 2246 //if(a->node >= (Node*)&n) 2247 // fatal("stack node"); 2248 if(s == S) 2249 s = lookup(".noname"); 2250 if(n->method) { 2251 if(n->type != T) 2252 if(n->type->sym != S) 2253 if(n->type->sym->pkg != nil) 2254 s = pkglookup(s->name, n->type->sym->pkg); 2255 } 2256 2257 switch(n->class) { 2258 default: 2259 fatal("naddr: ONAME class %S %d\n", n->sym, n->class); 2260 case PEXTERN: 2261 a->type = D_EXTERN; 2262 break; 2263 case PAUTO: 2264 a->type = D_AUTO; 2265 break; 2266 case PPARAM: 2267 case PPARAMOUT: 2268 a->type = D_PARAM; 2269 break; 2270 case PFUNC: 2271 a->index = D_EXTERN; 2272 a->type = D_ADDR; 2273 s = funcsym(s); 2274 break; 2275 } 2276 a->sym = linksym(s); 2277 break; 2278 2279 case OLITERAL: 2280 switch(n->val.ctype) { 2281 default: 2282 fatal("naddr: const %lT", n->type); 2283 break; 2284 case CTFLT: 2285 a->type = D_FCONST; 2286 a->u.dval = mpgetflt(n->val.u.fval); 2287 break; 2288 case CTINT: 2289 case CTRUNE: 2290 a->sym = nil; 2291 a->type = D_CONST; 2292 a->offset = mpgetfix(n->val.u.xval); 2293 break; 2294 case CTSTR: 2295 datagostring(n->val.u.sval, a); 2296 break; 2297 case CTBOOL: 2298 a->sym = nil; 2299 a->type = D_CONST; 2300 a->offset = n->val.u.bval; 2301 break; 2302 case CTNIL: 2303 a->sym = nil; 2304 a->type = D_CONST; 2305 a->offset = 0; 2306 break; 2307 } 2308 break; 2309 2310 case OADDR: 2311 naddr(n->left, a, canemitcode); 2312 if(a->type >= D_INDIR) { 2313 a->type -= D_INDIR; 2314 break; 2315 } 2316 if(a->type == D_EXTERN || a->type == D_STATIC || 2317 a->type == D_AUTO || a->type == D_PARAM) 2318 if(a->index == D_NONE) { 2319 a->index = a->type; 2320 a->type = D_ADDR; 2321 break; 2322 } 2323 fatal("naddr: OADDR\n"); 2324 2325 case OITAB: 2326 // itable of interface value 2327 naddr(n->left, a, canemitcode); 2328 if(a->type == D_CONST && a->offset == 0) 2329 break; // len(nil) 2330 a->etype = tptr; 2331 a->width = widthptr; 2332 break; 2333 2334 case OSPTR: 2335 // pointer in a string or slice 2336 naddr(n->left, a, canemitcode); 2337 if(a->type == D_CONST && a->offset == 0) 2338 break; // ptr(nil) 2339 a->etype = simtype[tptr]; 2340 a->offset += Array_array; 2341 a->width = widthptr; 2342 break; 2343 2344 case OLEN: 2345 // len of string or slice 2346 naddr(n->left, a, canemitcode); 2347 if(a->type == D_CONST && a->offset == 0) 2348 break; // len(nil) 2349 a->etype = TUINT32; 2350 a->offset += Array_nel; 2351 a->width = 4; 2352 break; 2353 2354 case OCAP: 2355 // cap of string or slice 2356 naddr(n->left, a, canemitcode); 2357 if(a->type == D_CONST && a->offset == 0) 2358 break; // cap(nil) 2359 a->etype = TUINT32; 2360 a->offset += Array_cap; 2361 a->width = 4; 2362 break; 2363 2364 // case OADD: 2365 // if(n->right->op == OLITERAL) { 2366 // v = n->right->vconst; 2367 // naddr(n->left, a, canemitcode); 2368 // } else 2369 // if(n->left->op == OLITERAL) { 2370 // v = n->left->vconst; 2371 // naddr(n->right, a, canemitcode); 2372 // } else 2373 // goto bad; 2374 // a->offset += v; 2375 // break; 2376 2377 } 2378 } 2379 2380 int 2381 dotaddable(Node *n, Node *n1) 2382 { 2383 int o; 2384 int64 oary[10]; 2385 Node *nn; 2386 2387 if(n->op != ODOT) 2388 return 0; 2389 2390 o = dotoffset(n, oary, &nn); 2391 if(nn != N && nn->addable && o == 1 && oary[0] >= 0) { 2392 *n1 = *nn; 2393 n1->type = n->type; 2394 n1->xoffset += oary[0]; 2395 return 1; 2396 } 2397 return 0; 2398 } 2399 2400 void 2401 sudoclean(void) 2402 { 2403 } 2404 2405 int 2406 sudoaddable(int as, Node *n, Addr *a) 2407 { 2408 USED(as); 2409 USED(n); 2410 USED(a); 2411 2412 return 0; 2413 }