1: # 2: /* 3: 4: C compiler, part 2 5: 6: 7: */ 8: 9: #include "c1h.c" 10: 11: char maprel[] { EQUAL, NEQUAL, GREATEQ, GREAT, LESSEQ, 12: LESS, GREATQP, GREATP, LESSEQP, LESSP 13: }; 14: 15: char notrel[] { NEQUAL, EQUAL, GREAT, GREATEQ, LESS, 16: LESSEQ, GREATP, GREATQP, LESSP, LESSEQP 17: }; 18: 19: struct tconst czero { CON, INT, 0, 0}; 20: struct tconst cone { CON, INT, 0, 1}; 21: struct tconst fczero { SFCON, DOUBLE, 0, 0 }; 22: 23: struct table *cregtab; 24: 25: int nreg 3; 26: int isn 10000; 27: int namsiz 8; 28: 29: main(argc, argv) 30: char *argv[]; 31: { 32: extern fout; 33: 34: if (argc<4) { 35: error("Arg count"); 36: exit(1); 37: } 38: if(fopen(argv[1], ascbuf)<0) { 39: error("Missing temp file"); 40: exit(1); 41: } 42: if ((fout = creat(argv[3], 0666)) < 0) { 43: error("Can't create %s", argv[3]); 44: exit(1); 45: } 46: spacep = treespace; 47: getree(); 48: /* 49: * If any floating-point instructions 50: * were used, generate a reference which 51: * pulls in the floating-point part of printf. 52: */ 53: if (nfloat) 54: printf(".globl fltused\n"); 55: /* 56: * tack on the string file. 57: */ 58: close(ascbuf[0]); 59: if (fopen(argv[2], ascbuf)<0) { 60: error("Missing temp file"); 61: exit(1); 62: } 63: printf(".globl\n.data\n"); 64: getree(); 65: flush(); 66: exit(nerror!=0); 67: } 68: 69: /* 70: * Given a tree, a code table, and a 71: * count of available registers, find the code table 72: * for the appropriate operator such that the operands 73: * are of the right type and the number of registers 74: * required is not too large. 75: * Return a ptr to the table entry or 0 if none found. 76: */ 77: char *match(atree, table, nrleft) 78: struct tnode *atree; 79: struct table *table; 80: { 81: int op, d1, d2, t1, t2, dope; 82: struct tnode *p2; 83: register struct tnode *p1, *tree; 84: register struct optab *opt; 85: 86: if ((tree=atree)==0) 87: return(0); 88: if (table==lsptab) 89: table = sptab; 90: if ((op = tree->op)==0) 91: return(0); 92: dope = opdope[op]; 93: if ((dope&LEAF) == 0) 94: p1 = tree->tr1; 95: else 96: p1 = tree; 97: t1 = p1->type; 98: d1 = dcalc(p1, nrleft); 99: if ((dope&BINARY)!=0) { 100: p2 = tree->tr2; 101: /* 102: * If a subtree starts off with a conversion operator, 103: * try for a match with the conversion eliminated. 104: * E.g. int = double can be done without generating 105: * the converted int in a register by 106: * movf double,fr0; movfi fr0,int . 107: */ 108: if(opdope[p1->op]&CNVRT && (opdope[p2->op]&CNVRT)==0) { 109: tree->tr1 = p1->tr1; 110: if (opt = match(tree, table, nrleft)) 111: return(opt); 112: tree->tr1 = p1; 113: } else if (opdope[p2->op]&CNVRT && (opdope[p1->op]&CNVRT)==0) { 114: tree->tr2 = p2->tr1; 115: if (opt = match(tree, table, nrleft)) 116: return(opt); 117: tree->tr2 = p2; 118: } 119: t2 = p2->type; 120: d2 = dcalc(p2, nrleft); 121: } 122: for (; table->op!=op; table++) 123: if (table->op==0) 124: return(0); 125: for (opt = table->tabp; opt->tabdeg1!=0; opt++) { 126: if (d1 > (opt->tabdeg1&077) 127: || (opt->tabdeg1 >= 0100 && (p1->op != STAR))) 128: continue; 129: if (notcompat(p1, opt->tabtyp1, op)) { 130: continue; 131: } 132: if ((opdope[op]&BINARY)!=0 && p2!=0) { 133: if (d2 > (opt->tabdeg2&077) 134: || (opt->tabdeg2 >= 0100) && (p2->op != STAR) ) 135: continue; 136: if (notcompat(p2,opt->tabtyp2, 0)) 137: continue; 138: } 139: return(opt); 140: } 141: return(0); 142: } 143: 144: /* 145: * Given a tree, a code table, and a register, 146: * produce code to evaluate the tree with the appropriate table. 147: * Registers reg and upcan be used. 148: * If there is a value, it is desired that it appear in reg. 149: * The routine returns the register in which the value actually appears. 150: * This routine must work or there is an error. 151: * If the table called for is cctab, sptab, or efftab, 152: * and tree can't be done using the called-for table, 153: * another try is made. 154: * If the tree can't be compiled using cctab, regtab is 155: * used and a "tst" instruction is produced. 156: * If the tree can't be compiled using sptab, 157: * regtab is used and the register is pushed on the stack. 158: * If the tree can't be compiled using efftab, 159: * just use regtab. 160: * Regtab must succeed or an "op not found" error results. 161: * 162: * A number of special cases are recognized, and 163: * there is an interaction with the optimizer routines. 164: */ 165: rcexpr(atree, atable, reg) 166: struct tnode *atree; 167: struct table *atable; 168: { 169: register r; 170: int modf, nargs, recurf; 171: register struct tnode *tree; 172: register struct table *table; 173: 174: table = atable; 175: recurf = 0; 176: if (reg<0) { 177: recurf++; 178: reg = ~reg; 179: if (reg>=020) { 180: reg =- 020; 181: recurf++; 182: } 183: } 184: if((tree=atree)==0) 185: return(0); 186: switch (tree->op) { 187: 188: /* 189: * A conditional branch 190: */ 191: case CBRANCH: 192: cbranch(optim(tree->btree), tree->lbl, tree->cond, 0); 193: return(0); 194: 195: /* 196: * An initializing expression 197: */ 198: case INIT: 199: if (tree->tr1->op == AMPER) 200: tree->tr1 = tree->tr1->tr1; 201: if (tree->tr1->op==NAME) 202: pname(tree->tr1); 203: else if (tree->tr1==CON) 204: psoct(tree->tr1->value); 205: else 206: error("Illegal initialization"); 207: putchar('\n'); 208: return(0); 209: 210: /* 211: * Put the value of an expression in r0, 212: * for a switch or a return 213: */ 214: case RFORCE: 215: if((r=rcexpr(tree->tr1, regtab, reg)) != 0) 216: printf("mov%c r%d,r0\n", isfloat(tree->tr1), r); 217: return(0); 218: 219: /* 220: * sequential execution 221: */ 222: case COMMA: 223: rcexpr(tree->tr1, efftab, reg); 224: atree = tree = tree->tr2; 225: break; 226: 227: /* 228: * In the generated &~ operator, 229: * fiddle things so a PDP-11 "bit" 230: * instruction will be produced when cctab is used. 231: */ 232: case NAND: 233: if (table==cctab) { 234: tree->op = TAND; 235: tree->tr2 = optim(block(1, COMPL, INT, 0, tree->tr2)); 236: } 237: break; 238: 239: 240: /* 241: * Handle a subroutine call. It has to be done 242: * here because if cexpr got called twice, the 243: * arguments might be compiled twice. 244: * There is also some fiddling so the 245: * first argument, in favorable circumstances, 246: * goes to (sp) instead of -(sp), reducing 247: * the amount of stack-popping. 248: */ 249: case CALL: 250: r = 0; 251: nargs = 0; 252: modf = 0; 253: if (tree->tr1->op!=NAME) { /* get nargs right */ 254: nargs++; 255: nstack++; 256: } 257: tree = tree->tr2; 258: if(tree->op) { 259: while (tree->op==COMMA) { 260: r =+ comarg(tree->tr2, &modf); 261: tree = tree->tr1; 262: nargs++; 263: } 264: r =+ comarg(tree, &modf); 265: nargs++; 266: } 267: tree = atree; 268: tree->op = CALL2; 269: if (modf && tree->tr1->op==NAME && tree->tr1->class==EXTERN) 270: tree->op = CALL1; 271: cexpr(tree, regtab, reg); 272: popstk(r); 273: nstack =- nargs; 274: if (table==efftab || table==regtab) 275: return(0); 276: r = 0; 277: goto fixup; 278: 279: /* 280: * Longs need special treatment. 281: */ 282: case ASLSH: 283: case LSHIFT: 284: if (tree->type==LONG) { 285: if (tree->tr2->op==ITOL) 286: tree->tr2 = tree->tr2->tr1; 287: if (tree->op==ASLSH) 288: tree->op = ASLSHL; 289: else 290: tree->op = LLSHIFT; 291: } 292: break; 293: 294: /* 295: * Try to change * and / to shifts. 296: */ 297: case TIMES: 298: case DIVIDE: 299: case ASTIMES: 300: case ASDIV: 301: tree = pow2(tree); 302: } 303: /* 304: * Try to find postfix ++ and -- operators that can be 305: * pulled out and done after the rest of the expression 306: */ 307: if (table!=cctab && table!=cregtab && recurf<2 308: && (opdope[tree->op]&LEAF)==0) { 309: if (r=delay(&atree, table, reg)) { 310: tree = atree; 311: table = efftab; 312: reg = r-1; 313: } 314: } 315: /* 316: * Basically, try to reorder the computation 317: * so reg = x+y is done as reg = x; reg =+ y 318: */ 319: if (recurf==0 && reorder(&atree, table, reg)) { 320: if (table==cctab && atree->op==NAME) 321: return(reg); 322: } 323: tree = atree; 324: if (table==efftab && tree->op==NAME) 325: return(reg); 326: if ((r=cexpr(tree, table, reg))>=0) 327: return(r); 328: if (table!=regtab) { 329: if((r=cexpr(tree, regtab, reg))>=0) { 330: fixup: 331: modf = isfloat(tree); 332: if (table==sptab || table==lsptab) { 333: if (tree->type==LONG) { 334: printf("mov\tr%d,-(sp)\n",r+1); 335: nstack++; 336: } 337: printf("mov%c r%d,%c(sp)\n", modf, r, 338: table==sptab? '-':0); 339: nstack++; 340: } 341: if (table==cctab) 342: printf("tst%c r%d\n", modf, r); 343: return(r); 344: } 345: } 346: if (tree->op>0 && tree->op<RFORCE && opntab[tree->op]) 347: error("No code table for op: %s", opntab[tree->op]); 348: else 349: error("No code table for op %d", tree->op); 350: return(reg); 351: } 352: 353: /* 354: * Try to compile the tree with the code table using 355: * registers areg and up. If successful, 356: * return the register where the value actually ended up. 357: * If unsuccessful, return -1. 358: * 359: * Most of the work is the macro-expansion of the 360: * code table. 361: */ 362: cexpr(atree, table, areg) 363: struct tnode *atree; 364: struct table *table; 365: { 366: int c, r; 367: register struct tnode *p, *p1, *tree; 368: struct table *ctable; 369: struct tnode *p2; 370: char *string; 371: int reg, reg1, rreg, flag, opd; 372: char *opt; 373: 374: tree = atree; 375: reg = areg; 376: p1 = tree->tr2; 377: c = tree->op; 378: opd = opdope[c]; 379: /* 380: * When the value of a relational or a logical expression is 381: * desired, more work must be done. 382: */ 383: if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) { 384: cbranch(tree, c=isn++, 1, reg); 385: rcexpr(&czero, table, reg); 386: branch(isn, 0); 387: label(c); 388: rcexpr(&cone, table, reg); 389: label(isn++); 390: return(reg); 391: } 392: if(c==QUEST) { 393: if (table==cctab) 394: return(-1); 395: cbranch(tree->tr1, c=isn++, 0, reg); 396: flag = nstack; 397: rreg = rcexpr(p1->tr1, table, reg); 398: nstack = flag; 399: branch(r=isn++, 0); 400: label(c); 401: reg = rcexpr(p1->tr2, table, rreg); 402: if (rreg!=reg) 403: printf("mov%c r%d,r%d\n", 404: isfloat(tree),reg,rreg); 405: label(r); 406: return(rreg); 407: } 408: reg = oddreg(tree, reg); 409: reg1 = reg+1; 410: /* 411: * long values take 2 registers. 412: */ 413: if (tree->type==LONG && tree->op!=ITOL) 414: reg1++; 415: /* 416: * Leaves of the expression tree 417: */ 418: if ((r = chkleaf(tree, table, reg)) >= 0) 419: return(r); 420: /* 421: * x + (-1) is better done as x-1. 422: */ 423: 424: if ((tree->op==PLUS||tree->op==ASPLUS) && 425: (p1=tree->tr2)->op == CON && p1->value == -1) { 426: p1->value = 1; 427: tree->op =+ (MINUS-PLUS); 428: } 429: if (table==cregtab) 430: table = regtab; 431: /* 432: * The following peculiar code depends on the fact that 433: * if you just want the codition codes set, efftab 434: * will generate the right code unless the operator is 435: * postfix ++ or --. Unravelled, if the table is 436: * cctab and the operator is not special, try first 437: * for efftab; if the table isn't, if the operator is, 438: * or the first match fails, try to match 439: * with the table actually asked for. 440: */ 441: if (table!=cctab || c==INCAFT || c==DECAFT 442: || (opt = match(tree, efftab, nreg-reg)) == 0) 443: if ((opt=match(tree, table, nreg-reg))==0) 444: return(-1); 445: string = opt->tabstring; 446: p1 = tree->tr1; 447: p2 = 0; 448: if (opdope[tree->op]&BINARY) 449: p2 = tree->tr2; 450: loop: 451: /* 452: * The 0200 bit asks for a tab. 453: */ 454: if ((c = *string++) & 0200) { 455: c =& 0177; 456: putchar('\t'); 457: } 458: switch (c) { 459: 460: case '\0': 461: if (!isfloat(tree)) 462: if (tree->op==DIVIDE || tree->op==ASDIV) 463: reg--; 464: return(reg); 465: 466: /* A1 */ 467: case 'A': 468: p = p1; 469: goto adr; 470: 471: /* A2 */ 472: case 'B': 473: p = p2; 474: goto adr; 475: 476: adr: 477: c = 0; 478: if (*string=='\'') { 479: c = 1; 480: string++; 481: } else if (*string=='+') { 482: c = 2; 483: string++; 484: } 485: pname(p, c); 486: goto loop; 487: 488: /* I */ 489: case 'M': 490: if ((c = *string)=='\'') 491: string++; 492: else 493: c = 0; 494: prins(tree->op, c, instab); 495: goto loop; 496: 497: /* B1 */ 498: case 'C': 499: if ((opd&LEAF) != 0) 500: p = tree; 501: else 502: p = p1; 503: goto pbyte; 504: 505: /* BF */ 506: case 'P': 507: p = tree; 508: goto pb1; 509: 510: /* B2 */ 511: case 'D': 512: p = p2; 513: pbyte: 514: if (p->type==CHAR) 515: putchar('b'); 516: pb1: 517: if (isfloat(p)) 518: putchar('f'); 519: goto loop; 520: 521: /* BE */ 522: case 'L': 523: if (p1->type==CHAR || p2->type==CHAR) 524: putchar('b'); 525: p = tree; 526: goto pb1; 527: 528: /* F */ 529: case 'G': 530: p = p1; 531: flag = 01; 532: goto subtre; 533: 534: /* S */ 535: case 'K': 536: p = p2; 537: flag = 02; 538: goto subtre; 539: 540: /* H */ 541: case 'H': 542: p = tree; 543: flag = 04; 544: 545: subtre: 546: ctable = regtab; 547: c = *string++ - 'A'; 548: if (*string=='!') { 549: string++; 550: c =| 020; /* force right register */ 551: } 552: if ((c&02)!=0) 553: ctable = sptab; 554: if ((c&04)!=0) 555: ctable = cctab; 556: if ((flag&01) && ctable==regtab && (c&01)==0 557: && (tree->op==DIVIDE||tree->op==MOD 558: || tree->op==ASDIV||tree->op==ASMOD)) 559: ctable = cregtab; 560: if ((c&01)!=0) { 561: p = p->tr1; 562: if(collcon(p) && ctable!=sptab) { 563: if (p->op==STAR) 564: p = p->tr1; 565: p = p->tr1; 566: } 567: } 568: if (table==lsptab && ctable==sptab) 569: ctable = lsptab; 570: if (c&010) 571: r = reg1; 572: else 573: if (opdope[p->op]&LEAF || p->degree < 2) 574: r = reg; 575: else 576: r = areg; 577: rreg = rcexpr(p, ctable, r); 578: if (ctable!=regtab && ctable!=cregtab) 579: goto loop; 580: if (c&010) { 581: if (c&020 && rreg!=reg1) 582: printf("mov%c r%d,r%d\n", 583: isfloat(tree),rreg,reg1); 584: else 585: reg1 = rreg; 586: } else if (rreg!=reg) 587: if ((c&020)==0 && oddreg(tree, 0)==0 && (flag&04 || 588: flag&01 589: && xdcalc(p2, nreg-rreg-1) <= (opt->tabdeg2&077) 590: || flag&02 591: && xdcalc(p1,nreg-rreg-1) <= (opt->tabdeg1&077))) { 592: reg = rreg; 593: reg1 = rreg+1; 594: } else 595: printf("mov%c\tr%d,r%d\n", 596: isfloat(tree), rreg, reg); 597: goto loop; 598: 599: /* R */ 600: case 'I': 601: r = reg; 602: if (*string=='-') { 603: string++; 604: r--; 605: } 606: goto preg; 607: 608: /* R1 */ 609: case 'J': 610: r = reg1; 611: preg: 612: if (*string=='+') { 613: string++; 614: r++; 615: } 616: if (r>nreg) 617: error("Register overflow: simplify expression"); 618: printf("r%d", r); 619: goto loop; 620: 621: case '-': /* check -(sp) */ 622: if (*string=='(') { 623: nstack++; 624: if (table!=lsptab) 625: putchar('-'); 626: goto loop; 627: } 628: break; 629: 630: case ')': /* check (sp)+ */ 631: putchar(')'); 632: if (*string=='+') 633: nstack--; 634: goto loop; 635: 636: /* #1 */ 637: case '#': 638: p = p1->tr1; 639: goto nmbr; 640: 641: /* #2 */ 642: case '"': 643: p = p2->tr1; 644: 645: nmbr: 646: if(collcon(p)) { 647: if (p->op==STAR) { 648: printf("*"); 649: p = p->tr1; 650: } 651: if ((p = p->tr2)->op == CON) { 652: if (p->value) 653: psoct(p->value); 654: } else if (p->op==AMPER) 655: pname(p->tr1, 0); 656: } 657: goto loop; 658: 659: case 'T': /* "tst R" if 1st op not in cctab */ 660: if (dcalc(p1, 5)>12 && !match(p1, cctab, 10)) 661: printf("tst r%d\n", reg); 662: goto loop; 663: case 'V': /* adc or sbc as required for longs */ 664: switch(tree->op) { 665: case PLUS: 666: case ASPLUS: 667: case INCBEF: 668: case INCAFT: 669: printf("adc"); 670: break; 671: 672: case MINUS: 673: case ASMINUS: 674: case NEG: 675: case DECBEF: 676: case DECAFT: 677: printf("sbc"); 678: break; 679: 680: default: 681: while ((c = *string++)!='\n' && c!='\0'); 682: break; 683: } 684: goto loop; 685: } 686: putchar(c); 687: goto loop; 688: } 689: 690: /* 691: * This routine just calls sreorder (below) 692: * on the subtrees and then on the tree itself. 693: * It returns non-zero if anything changed. 694: */ 695: reorder(treep, table, reg) 696: struct tnode **treep; 697: struct table *table; 698: { 699: register r, r1; 700: register struct tnode *p; 701: 702: p = *treep; 703: if (opdope[p->op]&LEAF) 704: return(0); 705: r1 = 0; 706: while(sreorder(&p->tr1, table, reg)) 707: r1++; 708: if (opdope[p->op]&BINARY) 709: while(sreorder(&p->tr2, table, reg)) 710: r1++; 711: r = 0; 712: while (sreorder(treep, table, reg)) 713: r++; 714: *treep = optim(*treep); 715: return(r); 716: } 717: 718: /* 719: * Basically this routine carries out two kinds of optimization. 720: * First, it observes that "x + (reg = y)" where actually 721: * the = is any assignment op is better done as "reg=y; x+reg". 722: * In this case rcexpr is called to do the first part and the 723: * tree is modified so the name of the register 724: * replaces the assignment. 725: * Moreover, expressions like "reg = x+y" are best done as 726: * "reg = x; reg =+ y" (so long as "reg" and "y" are not the same!). 727: */ 728: sreorder(treep, table, reg) 729: struct tnode **treep; 730: struct table *table; 731: { 732: register struct tnode *p, *p1; 733: 734: p = *treep; 735: if (opdope[p->op]&LEAF) 736: return(0); 737: if (p->op==PLUS) 738: if (reorder(&p->tr2, table, reg)) 739: *treep = p = optim(p); 740: p1 = p->tr1; 741: if (p->op==STAR || p->op==PLUS) { 742: if (reorder(&p->tr1, table, reg)) 743: *treep = p = optim(p); 744: p1 = p->tr1; 745: } 746: if (p1->op==NAME) switch(p->op) { 747: case ASLSH: 748: case ASRSH: 749: case ASSIGN: 750: if (p1->class != REG || isfloat(p->tr2)) 751: return(0); 752: if (p->op==ASSIGN) switch (p->tr2->op) { 753: case TIMES: 754: case DIVIDE: 755: if (!ispow2(p->tr2)) 756: break; 757: p->tr2 = pow2(p->tr2); 758: case PLUS: 759: case MINUS: 760: case AND: 761: case NAND: 762: case OR: 763: case EXOR: 764: case LSHIFT: 765: case RSHIFT: 766: p1 = p->tr2->tr2; 767: if (xdcalc(p1) > 12 768: || p1->op==NAME 769: &&(p1->nloc==p->tr1->nloc 770: || p1->regno==p->tr1->nloc)) 771: return(0); 772: p1 = p->tr2; 773: p->tr2 = p1->tr1; 774: if (p1->tr1->op!=NAME 775: || p1->tr1->class!=REG 776: || p1->tr1->nloc!=p->tr1->nloc) 777: rcexpr(p, efftab, reg); 778: p->tr2 = p1->tr2; 779: p->op = p1->op + ASPLUS - PLUS; 780: *treep = p; 781: return(1); 782: } 783: goto OK; 784: 785: case ASTIMES: 786: case ASDIV: 787: if (!ispow2(p)) 788: return(0); 789: case ASPLUS: 790: case ASMINUS: 791: case ASSAND: 792: case ASSNAND: 793: case ASOR: 794: case ASXOR: 795: case DECBEF: 796: case INCBEF: 797: OK: 798: if (table==cctab||table==cregtab) 799: reg =+ 020; 800: rcexpr(optim(p), efftab, ~reg); 801: *treep = p1; 802: return(1); 803: } 804: return(0); 805: } 806: 807: /* 808: * Delay handles postfix ++ and -- 809: * It observes that "x + y++" is better 810: * treated as "x + y; y++". 811: * If the operator is ++ or -- itself, 812: * it calls rcexpr to load the operand, letting 813: * the calling instance of rcexpr to do the 814: * ++ using efftab. 815: * Otherwise it uses sdelay to search for inc/dec 816: * among the operands. 817: */ 818: delay(treep, table, reg) 819: struct tnode **treep; 820: { 821: register struct tnode *p, *p1; 822: register r; 823: 824: p = *treep; 825: if (table!=efftab && (p->op==INCAFT||p->op==DECAFT) 826: && p->tr1->op==NAME) { 827: return(1+rcexpr(p->tr1, table, reg)); 828: } 829: p1 = 0; 830: if (opdope[p->op]&BINARY) 831: p1 = sdelay(&p->tr2); 832: if (p1==0) 833: p1 = sdelay(&p->tr1); 834: if (p1) { 835: r = rcexpr(optim(p), table, reg); 836: *treep = p1; 837: return(r+1); 838: } 839: return(0); 840: } 841: 842: sdelay(ap) 843: struct tnode **ap; 844: { 845: register struct tnode *p, *p1; 846: 847: p = *ap; 848: if ((p->op==INCAFT||p->op==DECAFT) && p->tr1->op==NAME) { 849: *ap = ncopy(p->tr1); 850: return(p); 851: } 852: if (p->op==STAR || p->op==PLUS) 853: if (p1=sdelay(&p->tr1)) 854: return(p1); 855: if (p->op==PLUS) 856: return(sdelay(&p->tr2)); 857: return(0); 858: } 859: 860: /* 861: * Copy a tree node for a register variable. 862: * Used by sdelay because if *reg-- is turned 863: * into *reg; reg-- the *reg will in turn 864: * be changed to some offset class, accidentally 865: * modifying the reg--. 866: */ 867: ncopy(ap) 868: struct tname *ap; 869: { 870: register struct tname *p; 871: 872: p = ap; 873: if (p->class!=REG) 874: return(p); 875: return(block(3, NAME, p->type, p->elsize, p->tr1, 876: p->offset, p->nloc)); 877: } 878: 879: /* 880: * If the tree can be immediately loaded into a register, 881: * produce code to do so and return success. 882: */ 883: chkleaf(atree, table, reg) 884: struct tnode *atree; 885: { 886: struct tnode lbuf; 887: register struct tnode *tree; 888: 889: tree = atree; 890: if (tree->op!=STAR && dcalc(tree, nreg-reg) > 12) 891: return(-1); 892: lbuf.op = LOAD; 893: lbuf.type = tree->type; 894: lbuf.degree = tree->degree; 895: lbuf.tr1 = tree; 896: return(rcexpr(&lbuf, table, reg)); 897: } 898: 899: /* 900: * Compile a function argument. 901: * If the stack is currently empty, put it in (sp) 902: * rather than -(sp); this will save a pop. 903: * Return the number of bytes pushed, 904: * for future popping. 905: */ 906: comarg(atree, flagp) 907: int *flagp; 908: { 909: register struct tnode *tree; 910: register retval; 911: 912: tree = atree; 913: if (nstack || isfloat(tree) || tree->type==LONG) { 914: rcexpr(tree, sptab, 0); 915: retval = arlength(tree->type); 916: } else { 917: (*flagp)++; 918: rcexpr(tree, lsptab, 0); 919: retval = 0; 920: } 921: return(retval); 922: }