# 2.11BSD#431 - /usr/src/lib/ccom/c10.c

##### Functions

    cexpr             X
    chkleaf           X
    comarg            X
    delay             X
    doinit            X
    main              X
    match             X
    movreg            X
    ncopy             X
    paint             X
    rcexpr            X
    reorder           X
    sdelay            X
    sreorder          X
    strfunc           X

##### Variables

    cone              X
    cregtab           X
    czero             X
    isn               X
    maprel            X
    notrel            X
    nreg              X
    sfuncr            X

##### Macros

    NOCVL             X
    NOCVR             X
    dbprint           X

       1: /*
       2:  *		C compiler, part 2
       3:  *
       4:  * (long)btodb(l) produced 'no code table error for op: >>(17) type: 6'
       5:  * allow both long and ulong at line ~341.  1996/6/19
       6: */
       7:
       8: #if !defined(lint) && defined(DOSCCS)
       9: static  char    sccsid[] = "@(#)c10.c	2.1 (2.11BSD GTE) 10/4/94";
      10: #endif
      11:
      12: #include "c1.h"
      13:
      14: #ifdef  DEBUG
      15: #define dbprint(op) printf("	/ %s", opntab[op])
      16: #else
      17: #define dbprint(op) /* */
      18: #endif
      19:
      20: static int debug = 0;
      21:
      22: char    maprel[] = {    EQUAL, NEQUAL, GREATEQ, GREAT, LESSEQ,
      23:             LESS, GREATQP, GREATP, LESSEQP, LESSP
      24: };
      25:
      26: char    notrel[] = {    NEQUAL, EQUAL, GREAT, GREATEQ, LESS,
      27:             LESSEQ, GREATP, GREATQP, LESSP, LESSEQP
      28: };
      29:
      30: struct tconst czero = { CON, INT, 0};
      31: struct tconst cone  = { CON, INT, 1};
      32:
      33: struct tname sfuncr = { NAME, STRUCT, STATIC, 0, 0, 0 };
      34:
      35: struct  table   *cregtab;
      36:
      37: int nreg    = 3;
      38: int isn = 10000;
      39:
      40: main(argc, argv)
      41: int argc;
      42: char    *argv[];
      43: {
      44:     char    buf1[BUFSIZ],
      45:         buf2[BUFSIZ];
      46:
      47:     if (argc<4) {
      48:         error("Arg count");
      49:         exit(1);
      50:     }
      51:     if (freopen(argv[1], "r", stdin)==NULL) {
      52:         error("Missing temp file");
      53:         exit(1);
      54:     }
      55:     setbuf(stdin,buf1); /* sbrk problems */
      56:     if ((freopen(argv[3], "w", stdout)) == NULL) {
      57:         error("Can't create %s", argv[3]);
      58:         exit(1);
      59:     }
      60:     setbuf(stdout,buf2);    /* sbrk problems */
      61:     funcbase = curbase = coremax = sbrk(0);
      62:     getree();
      63:     /*
      64: 	 * If any floating-point instructions
      65: 	 * were used, generate a reference that
      66: 	 * pulls in the floating-point part of printf.
      67: 	 */
      68:     if (nfloat)
      69:         printf(".globl	fltused\n");
      70:     /*
      71: 	 * tack on the string file.
      72: 	 */
      73:     printf(".globl\n.data\n");
      74:     if (*argv[2] != '-') {
      75:         if (freopen(argv[2], "r", stdin)==NULL) {
      76:             error("Missing temp file");
      77:             exit(1);
      78:         }
      79:         setbuf(stdin,buf1); /* sbrk problems */
      80:         getree();
      81:     }
      82:     if (totspace >= (unsigned)56000)
      83:         werror("possibly too much data");
      84:     exit(nerror!=0);
      85: }
      86:
      87: /*
      88:  * Given a tree, a code table, and a
      89:  * count of available registers, find the code table
      90:  * for the appropriate operator such that the operands
      91:  * are of the right type and the number of registers
      92:  * required is not too large.
      93:  * Return a ptr to the table entry or 0 if none found.
      94:  */
      95: struct optab *
      96: match(tree, table, nrleft, nocvt)
      97: union tree *tree;
      98: struct table *table;
      99: {
     100: #define NOCVL   1
     101: #define NOCVR   2
     102:     int op, d1, d2, dope;
     103:     union tree *p2;
     104:     register union tree *p1;
     105:     register struct optab *opt;
     106:
     107:     if (tree==NULL)
     108:         return(NULL);
     109:     if (table==lsptab)
     110:         table = sptab;
     111:     if ((op = tree->t.op)==0)
     112:         return(0);
     113:     dope = opdope[op];
     114:     if ((dope&LEAF) == 0)
     115:         p1 = tree->t.tr1;
     116:     else
     117:         p1 = tree;
     118:     d1 = dcalc(p1, nrleft);
     119:     if ((dope&BINARY)!=0) {
     120:         p2 = tree->t.tr2;
     121:         /*
     122: 		 * If a subtree starts off with a conversion operator,
     123: 		 * try for a match with the conversion eliminated.
     124: 		 * E.g. int = double can be done without generating
     125: 		 * the converted int in a register by
     126: 		 * movf double,fr0; movfi fr0,int .
     127: 		 */
     128:         if (opdope[p2->t.op]&CNVRT && (nocvt&NOCVR)==0
     129:              && (opdope[p2->t.tr1->t.op]&CNVRT)==0) {
     130:             tree->t.tr2 = p2->t.tr1;
     131:             if (opt = match(tree, table, nrleft, NOCVL))
     132:                 return(opt);
     133:             tree->t.tr2 = p2;
     134:         } else if (opdope[p1->t.op]&CNVRT && (nocvt&NOCVL)==0
     135:          && (opdope[p1->t.tr1->t.op]&CNVRT)==0) {
     136:             tree->t.tr1 = p1->t.tr1;
     137:             if (opt = match(tree, table, nrleft, NOCVR))
     138:                 return(opt);
     139:             tree->t.tr1 = p1;
     140:         }
     141:         d2 = dcalc(p2, nrleft);
     142:     }
     143:     for (; table->tabop!=op; table++)
     144:         if (table->tabop==0)
     145:             return(0);
     146:     for (opt = table->tabp; opt->tabdeg1!=0; opt++) {
     147:         if (d1 > (opt->tabdeg1&077)
     148:          || (opt->tabdeg1 >= 0100 && (p1->t.op != STAR)))
     149:             continue;
     150:         if (notcompat(p1, opt->tabtyp1, opt->tabdeg1, op))
     151:             continue;
     152:         if ((opdope[op]&BINARY)!=0 && p2!=0) {
     153:             if (d2 > (opt->tabdeg2&077)
     154:              || (opt->tabdeg2 >= 0100) && (p2->t.op != STAR) )
     155:                 continue;
     156:             if (notcompat(p2,opt->tabtyp2, opt->tabdeg2, 0))
     157:                 continue;
     158:             if ((opt->tabdeg2&077)==20 && xdcalc(p2,nrleft)>20)
     159:                 continue;
     160:         }
     161:         return(opt);
     162:     }
     163:     return(0);
     164: }
     165:
     166: /*
     167:  * Given a tree, a code table, and a register,
     168:  * produce code to evaluate the tree with the appropriate table.
     169:  * Registers reg and upcan be used.
     170:  * If there is a value, it is desired that it appear in reg.
     171:  * The routine returns the register in which the value actually appears.
     172:  * This routine must work or there is an error.
     173:  * If the table called for is cctab, sptab, or efftab,
     174:  * and tree can't be done using the called-for table,
     175:  * another try is made.
     176:  * If the tree can't be compiled using cctab, regtab is
     177:  * used and a "tst" instruction is produced.
     178:  * If the tree can't be compiled using sptab,
     179:  * regtab is used and the register is pushed on the stack.
     180:  * If the tree can't be compiled using efftab,
     181:  * just use regtab.
     182:  * Regtab must succeed or an "op not found" error results.
     183:  *
     184:  * A number of special cases are recognized, and
     185:  * there is an interaction with the optimizer routines.
     186:  */
     187: rcexpr(atree, atable, reg)
     188: union tree *atree;
     189: struct table *atable;
     190: {
     191:     register r;
     192:     int modf, nargs, recurf;
     193:     register union tree *tree;
     194:     register struct table *table;
     195:
     196:     table = atable;
     197:     recurf = 0;
     198:     if (reg<0) {
     199:         recurf++;
     200:         reg = ~reg;
     201:         if (reg>=020) {
     202:             reg -= 020;
     203:             recurf++;
     204:         }
     205:     }
     206: again:
     207:     if((tree=atree)==0)
     208:         return(0);
     209:     if (tree->t.type==VOID) {
     210:         if (table!=efftab)
     211:             error("Illegal use of void");
     212:         tree->t.type = INT;
     213:     }
     214:     if (opdope[tree->t.op]&RELAT && tree->t.tr2->t.op==CON
     215:         && tree->t.tr2->c.value==0
     216:         && table==cctab)
     217:         tree = atree = tree->t.tr1;
     218:     /*
     219: 	 * fieldselect(...) : in efftab mode,
     220: 	 * ignore the select, otherwise
     221: 	 * do the shift and mask.
     222: 	 */
     223:     if (tree->t.op == FSELT) {
     224:         if (table==efftab)
     225:             atree = tree = tree->t.tr1;
     226:         else {
     227:             tree->t.op = FSEL;
     228:             atree = tree = optim(tree);
     229:         }
     230:     }
     231:     switch (tree->t.op)  {
     232:
     233:     /*
     234: 	 * Structure assignments
     235: 	 */
     236:     case STRASG:
     237:         strasg(tree);
     238:         return(0);
     239:
     240:     /*
     241: 	 * An initializing expression
     242: 	 */
     243:     case INIT:
     244:         tree = optim(tree);
     245:         doinit(tree->t.type, tree->t.tr1);
     246:         return(0);
     247:
     248:     /*
     249: 	 * Put the value of an expression in r0,
     250: 	 * for a switch or a return
     251: 	 */
     252:     case RFORCE:
     253:         tree = tree->t.tr1;
     254:         if((r=rcexpr(tree, regtab, reg)) != 0)
     255:             movreg(r, 0, tree);
     256:         return(0);
     257:
     258:     /*
     259: 	 * sequential execution
     260: 	 */
     261:     case SEQNC:
     262:         r = nstack;
     263:         rcexpr(tree->t.tr1, efftab, reg);
     264:         nstack = r;
     265:         atree = tree = tree->t.tr2;
     266:         goto again;
     267:
     268:     /*
     269: 	 * In the generated &~ operator,
     270: 	 * fiddle things so a PDP-11 "bit"
     271: 	 * instruction will be produced when cctab is used.
     272: 	 */
     273:     case ANDN:
     274:         if (table==cctab) {
     275:             tree->t.op = TAND;
     276:             tree->t.tr2 = optim(tnode(COMPL, tree->t.type, tree->t.tr2, TNULL));
     277:         }
     278:         break;
     279:
     280:     /*
     281: 	 * Handle a subroutine call. It has to be done
     282: 	 * here because if cexpr got called twice, the
     283: 	 * arguments might be compiled twice.
     284: 	 * There is also some fiddling so the
     285: 	 * first argument, in favorable circumstances,
     286: 	 * goes to (sp) instead of -(sp), reducing
     287: 	 * the amount of stack-popping.
     288: 	 */
     289:     case CALL:
     290:         r = 0;
     291:         nargs = 0;
     292:         modf = 0;
     293: #ifdef notdef
     294:         /*
     295: 		 * The following code would catch instances of foo(...) where
     296: 		 * "foo" was anything other than a simple name.  In particular
     297: 		 * f(...), (fp(...))(...) and (ffp(...))(...) where "f" is a
     298: 		 * pointer to a function, "fp" is a function returning a
     299: 		 * pointer to a function and "ffp" is a pointer to a function
     300: 		 * returning a pointer to a function.  The catch would among
     301: 		 * other things cause the (sp)/-(sp) stack optimization to
     302: 		 * stop working.  The compiler has been tested in all these
     303: 		 * different cases with the catch commented out and all the
     304: 		 * code generated was correct.  So what was it here for?
     305: 		 * If a strange error crops up, uncommenting the catch might
     306: 		 * be tried ...
     307: 		 */
     308:         if (tree->t.tr1->t.op!=NAME || tree->t.tr1->n.class!=EXTERN) {
     309:             nargs++;
     310:             nstack++;
     311:         }
     312: #endif
     313:         tree = tree->t.tr2;
     314:         if(tree->t.op) {
     315:             while (tree->t.op==COMMA) {
     316:                 r += comarg(tree->t.tr2, &modf);
     317:                 tree = tree->t.tr1;
     318:                 nargs++;
     319:             }
     320:             r += comarg(tree, &modf);
     321:             nargs++;
     322:         }
     323:         tree = atree;
     324:         tree->t.op = CALL2;
     325:         if (modf && tree->t.tr1->t.op==NAME
     326:            && tree->t.tr1->n.class==EXTERN)
     327:             tree->t.op = CALL1;
     328:         if (cexpr(tree, regtab, reg)<0)
     329:             error("compiler botch: call");
     330:         popstk(r);
     331:         nstack -= nargs;
     332:         if (table==efftab || table==regtab)
     333:             return(0);
     334:         r = 0;
     335:         goto fixup;
     336:
     337:     /*
     338: 	 * Longs need special treatment.
     339: 	 */
     340:     case ASULSH:    /* 18 */
     341:     case ULSH:  /* 17 */
     342:         if (tree->t.type != LONG && tree->t.type != UNLONG)
     343:             break;
     344:         if (tree->t.tr2->t.op==ITOL)
     345:             tree->t.tr2 = tree->t.tr2->t.tr1;
     346:         else
     347:             tree->t.tr2 = optim(tnode(LTOI,INT,tree->t.tr2,TNULL));
     348:         if (tree->t.op==ASULSH)
     349:             {
     350:             tree->t.op = UASLSHL;
     351:             tree->t.tr1 = tnode(AMPER, LONG+PTR, tree->t.tr1, TNULL);
     352:             }
     353:         else
     354:             tree->t.op = ULLSHIFT;
     355:         break;
     356:
     357:     case ASLSH:
     358:     case LSHIFT:
     359:         if (tree->t.type==LONG || tree->t.type==UNLONG) {
     360:             if (tree->t.tr2->t.op==ITOL)
     361:                 tree->t.tr2 = tree->t.tr2->t.tr1;
     362:             else
     363:                 tree->t.tr2 = optim(tnode(LTOI,INT,tree->t.tr2,TNULL));
     364:             if (tree->t.op==ASLSH)
     365:                 tree->t.op = ASLSHL;
     366:             else
     367:                 tree->t.op = LLSHIFT;
     368:         }
     369:         break;
     370:
     371:     /*
     372: 	 * Try to change * to shift.
     373: 	 */
     374:     case TIMES:
     375:     case ASTIMES:
     376:         tree = pow2(tree);
     377:     }
     378:     /*
     379: 	 * Try to find postfix ++ and -- operators that can be
     380: 	 * pulled out and done after the rest of the expression
     381: 	 */
     382:     if (table!=cctab && table!=cregtab && recurf<2
     383:      && (opdope[tree->t.op]&LEAF)==0) {
     384:         if (r=delay(&atree, table, reg)) {
     385:             tree = atree;
     386:             table = efftab;
     387:             reg = r-1;
     388:         }
     389:     }
     390:     /*
     391: 	 * Basically, try to reorder the computation
     392: 	 * so  reg = x+y  is done as  reg = x; reg += y
     393: 	 */
     394:     if (recurf==0 && reorder(&atree, table, reg)) {
     395:         if (table==cctab && atree->t.op==NAME)
     396:             return(reg);
     397:     }
     398:     tree = atree;
     399:     if (table==efftab && tree->t.op==NAME)
     400:         return(reg);
     401:     if ((r=cexpr(tree, table, reg))>=0) {
     402:         if (table==cregtab && (tree->t.op==INCAFT
     403:             || tree->t.op==DECAFT || tree->t.op==TIMES))
     404:             goto fixup;
     405:         return(r);
     406:     }
     407:     if (table!=regtab && (table!=cctab||(opdope[tree->t.op]&RELAT)==0)) {
     408:         if((r=cexpr(tree, regtab, reg))>=0) {
     409:     fixup:
     410:             modf = isfloat(tree);
     411:             dbprint(tree->t.op);
     412:             if (table==sptab || table==lsptab) {
     413:                 if (tree->t.type==LONG || tree->t.type==UNLONG){
     414:                     printf("mov\tr%d,-(sp)\n",r+1);
     415:                     nstack++;
     416:                 }
     417:                 printf("mov%s	r%d,%s(sp)\n", modf=='f'?"f":"", r,
     418:                     table==sptab? "-":"");
     419:                 nstack++;
     420:             }
     421:             if (table==cctab || table==cregtab)
     422:                 printf("tst%s	r%d\n", modf=='f'?"f":"", r);
     423:             return(r);
     424:         }
     425:     }
     426:     /*
     427: 	 * Special grace for unsigned chars as right operands
     428: 	 */
     429:     if (opdope[tree->t.op]&BINARY && tree->t.tr2->t.type==UNCHAR) {
     430:         tree->t.tr2 = tnode(LOAD, UNSIGN, tree->t.tr2, TNULL);
     431:         return(rcexpr(tree, table, reg));
     432:     }
     433:     /*
     434: 	 * There's a last chance for this operator
     435: 	 */
     436:     if (tree->t.op==LTOI) {
     437:         r = rcexpr(tree->t.tr1, regtab, reg);
     438:         if (r >= 0) {
     439:             r++;
     440:             goto fixup;
     441:         }
     442:     }
     443:
     444:     r = tree->t.op;
     445:     if (tree->t.type == STRUCT)
     446:         error("Illegal operation on structure");
     447:     else if (r > 0 && r < UASLSHL && opntab[r])
     448:         error("No code table for op: %s(%d) type: %d", opntab[r], r,
     449:             tree->t.type);
     450:     else
     451:         error("No code table for op %d", r);
     452:     return(reg);
     453: }
     454:
     455: /*
     456:  * Try to compile the tree with the code table using
     457:  * registers areg and up.  If successful,
     458:  * return the register where the value actually ended up.
     459:  * If unsuccessful, return -1.
     460:  *
     461:  * Most of the work is the macro-expansion of the
     462:  * code table.
     463:  */
     464: cexpr(tree, table, areg)
     465: register union tree *tree;
     466: struct table *table;
     467: {
     468:     int c, r;
     469:     register union tree *p, *p1;
     470:     struct table *ctable;
     471:     union tree *p2;
     472:     char *string;
     473:     int reg, reg1, rreg, flag, opd;
     474:     struct optab *opt;
     475:
     476:     reg = areg;
     477:     p1 = tree->t.tr2;
     478:     c = tree->t.op;
     479:     opd = opdope[c];
     480:     /*
     481: 	 * When the value of a relational or a logical expression is
     482: 	 * desired, more work must be done.
     483: 	 */
     484:     if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) {
     485:         cbranch(tree, c=isn++, 1, reg);
     486:         rcexpr((union tree *)&czero, table, reg);
     487:         branch(isn, 0, 0);
     488:         label(c);
     489:         rcexpr((union tree *)&cone, table, reg);
     490:         label(isn++);
     491:         return(reg);
     492:     }
     493:     if(c==QUEST) {
     494:         if (table==cctab)
     495:             return(-1);
     496:         cbranch(tree->t.tr1, c=isn++, 0, reg);
     497:         flag = nstack;
     498:         rreg = rcexpr(p1->t.tr1, table, reg);
     499:         nstack = flag;
     500:         branch(r=isn++, 0, 0);
     501:         label(c);
     502:         reg = rcexpr(p1->t.tr2, table, rreg);
     503:         if (rreg!=reg)
     504:             movreg(reg, rreg, tree->t.tr2);
     505:         label(r);
     506:         return(rreg);
     507:     }
     508:     reg = oddreg(tree, reg);
     509:     reg1 = reg+1;
     510:     /*
     511: 	 * long values take 2 registers.
     512: 	 */
     513:     if ((tree->t.type==LONG||tree->t.type==UNLONG||opd&RELAT&&(tree->t.tr1->t.type==LONG||tree->t.tr1->t.type==UNLONG))
     514:        && tree->t.op!=ITOL)
     515:         reg1++;
     516:     /*
     517: 	 * Leaves of the expression tree
     518: 	 */
     519:     if ((r = chkleaf(tree, table, reg)) >= 0)
     520:         return(r);
     521:     /*
     522: 	 * x + (-1) is better done as x-1.
     523: 	 */
     524:     if (tree->t.op==PLUS||tree->t.op==ASPLUS) {
     525:         if ((p1=tree->t.tr2)->t.op==CON && p1->c.value==-1) {
     526:             p1->c.value = -p1->c.value;
     527:             tree->t.op += (MINUS-PLUS);
     528:         }
     529:     }
     530:     /*
     531: 	 * Because of a peculiarity of the PDP11 table
     532: 	 * char = *intreg++ and *--intreg cannot go through.
     533:  	 */
     534:     if (tree->t.tr2 && (tree->t.tr2->t.op==AUTOI||tree->t.tr2->t.op==AUTOD)
     535:      && (tree->t.tr1->t.type==CHAR || tree->t.tr1->t.type==UNCHAR)
     536:      && tree->t.tr2->t.type!=CHAR && tree->t.tr2->t.type!=UNCHAR)
     537:         tree->t.tr2 = tnode(LOAD, tree->t.tr2->t.type, tree->t.tr2, TNULL);
     538:     /*
     539: 	 * Another peculiarity of the PDP11 table manifested itself when
     540: 	 * amplifying the move3: table.  The same case which optimizes
     541: 	 * u_char to char moves is used to move a u_char to a register. This
     542: 	 * is wrong, leading to sign extension.  Rather than lose the ability
     543: 	 * to generate better code when moving a u_char to a char, a check
     544: 	 * is made here to prevent sign extension.
     545: 	 *
     546: 	 * If the opcode is assign, the destination is a register and the
     547: 	 * source is u_char then do a conversion.
     548: 	 *
     549: 	 * u_char handling in the compiler is a bit awkward, it would be nice
     550: 	 * if %aub in the tables had a more unique meaning.
     551: 	*/
     552:     if (tree->t.tr2 && tree->t.tr1->t.op == NAME
     553:      && tree->t.tr1->n.class == REG && tree->t.op == ASSIGN
     554:      && tree->t.tr2->t.type == UNCHAR)
     555:         tree->t.tr2 = tnode(LOAD, UNSIGN, tree->t.tr2, TNULL);
     556:     if (table==cregtab)
     557:         table = regtab;
     558:     /*
     559: 	 * The following peculiar code depends on the fact that
     560: 	 * if you just want the codition codes set, efftab
     561: 	 * will generate the right code unless the operator is
     562: 	 * a shift or
     563: 	 * postfix ++ or --. Unravelled, if the table is
     564: 	 * cctab and the operator is not special, try first
     565: 	 * for efftab;  if the table isn't, if the operator is,
     566: 	 * or the first match fails, try to match
     567: 	 * with the table actually asked for.
     568: 	 */
     569:     /*
     570: 	 * Account for longs and oddregs; below is really
     571: 	 * r = nreg - reg - (reg-areg) - (reg1-reg-1);
     572: 	 */
     573:     r = nreg - reg + areg - reg1 + 1;
     574:     if (table!=cctab || c==INCAFT || c==DECAFT || tree->t.type==LONG || tree->t.type==UNLONG
     575: /*	 || c==ASRSH || c==ASLSH || c==ASULSH || tree->t.tr1->t.type==UNCHAR */
     576:      || c==ASRSH || c==ASLSH || c==ASULSH
     577:      || (opt = match(tree, efftab, r, 0)) == 0)
     578:         if ((opt=match(tree, table, r, 0))==0)
     579:             return(-1);
     580:     string = opt->tabstring;
     581:     p1 = tree->t.tr1;
     582:     if (p1->t.op==FCON && p1->f.value>0) {
     583: /* nonportable */
     584:         printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p1->f.value,
     585:             ((unsigned short *)&(p1->f.fvalue))[0],
     586:             ((unsigned short *)&(p1->f.fvalue))[1],
     587:             ((unsigned short *)&(p1->f.fvalue))[2],
     588:             ((unsigned short *)&(p1->f.fvalue))[3] );
     589:         p1->c.value = -p1->c.value;
     590:     }
     591:     p2 = 0;
     592:     if (opdope[tree->t.op]&BINARY) {
     593:         p2 = tree->t.tr2;
     594:         if (p2->t.op==FCON && p2->f.value>0) {
     595: /* nonportable */
     596:             printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p2->f.value,
     597:                 ((unsigned short *)&(p2->f.fvalue))[0],
     598:                 ((unsigned short *)&(p2->f.fvalue))[1],
     599:                 ((unsigned short *)&(p2->f.fvalue))[2],
     600:                 ((unsigned short *)&(p2->f.fvalue))[3] );
     601:             p2->f.value = -p2->f.value;
     602:         }
     603:     }
     604: loop:
     605:     /*
     606: 	 * The 0200 bit asks for a tab.
     607: 	 */
     608:     if ((c = *string++) & 0200) {
     609:         c &= 0177;
     610:         putchar('\t');
     611:     }
     612:     switch (c) {
     613:
     614:     case '\n':
     615:         dbprint(tree->t.op);
     616:         break;
     617:
     618:     case '\0':
     619:         if (!isfloat(tree))
     620:             if (tree->t.op==DIVIDE||tree->t.op==ASDIV)
     621:                 reg--;
     622:         if (table==regtab && (opdope[tree->t.op]&ASSGOP)) {
     623:             if (tree->t.tr1->t.type==CHAR)
     624:                 printf("movb	r%d,r%d\n", reg, reg);
     625:         }
     626:         return(reg);
     627:
     628:     /* A1 */
     629:     case 'A':
     630:         p = p1;
     631:         goto adr;
     632:
     633:     /* A2 */
     634:     case 'B':
     635:         p = p2;
     636:         goto adr;
     637:
     638:     adr:
     639:         c = 0;
     640:         while (*string=='\'') {
     641:             c++;
     642:             string++;
     643:         }
     644:         if (*string=='+') {
     645:             c = 100;
     646:             string++;
     647:         }
     648:         pname(p, c);
     649:         goto loop;
     650:
     651:     /* I */
     652:     case 'M':
     653:         if ((c = *string)=='\'')
     654:             string++;
     655:         else
     656:             c = 0;
     657:         prins(tree->t.op, c, instab, 0);
     658:         goto loop;
     659:
     660:     /* B1 */
     661:     case 'C':
     662:         if ((opd&LEAF) != 0)
     663:             p = tree;
     664:         else
     665:             p = p1;
     666:         goto pbyte;
     667:
     668:     /* BF */
     669:     case 'P':
     670:         p = tree;
     671:         goto pb1;
     672:
     673:     /* B2 */
     674:     case 'D':
     675:         p = p2;
     676:     pbyte:
     677:         if (p->t.type==CHAR || p->t.type==UNCHAR)
     678:             putchar('b');
     679:     pb1:
     680:         if (isfloat(p))
     681:             putchar('f');
     682:         goto loop;
     683:
     684:     /* BE */
     685:     case 'L':
     686:         if (p1->t.type==CHAR || p2->t.type==CHAR
     687:          || p1->t.type==UNCHAR || p2->t.type==UNCHAR)
     688:             putchar('b');
     689:         p = tree;
     690:         goto pb1;
     691:
     692:     /* F */
     693:     case 'G':
     694:         p = p1;
     695:         flag = 01;
     696:         goto subtre;
     697:
     698:     /* S */
     699:     case 'K':
     700:         p = p2;
     701:         flag = 02;
     702:         goto subtre;
     703:
     704:     /* H */
     705:     case 'H':
     706:         p = tree;
     707:         flag = 04;
     708:
     709:     subtre:
     710:         ctable = regtab;
     711:         if (flag&04)
     712:             ctable = cregtab;
     713:         c = *string++ - 'A';
     714:         if (*string=='!') {
     715:             string++;
     716:             c |= 020;   /* force right register */
     717:         }
     718:         if (*string=='?') {
     719:             string++;
     720:             c |= 040;   /* force condition codes */
     721:         }
     722:         if ((c&02)!=0)
     723:             ctable = sptab;
     724:         if ((c&04)!=0)
     725:             ctable = cctab;
     726:         if ((flag&01) && ctable==regtab && (c&01)==0
     727:           && ((c&040)||tree->t.op==DIVIDE||tree->t.op==MOD
     728:            || tree->t.op==ASDIV||tree->t.op==ASMOD||tree->t.op==ITOL))
     729:             ctable = cregtab;
     730:         if ((c&01)!=0) {
     731:             p = p->t.tr1;
     732:             if(collcon(p) && ctable!=sptab) {
     733:                 if (p->t.op==STAR)
     734:                     p = p->t.tr1;
     735:                 p = p->t.tr1;
     736:             }
     737:         }
     738:         if (table==lsptab && ctable==sptab)
     739:             ctable = lsptab;
     740:         if (c&010)
     741:             r = reg1;
     742:         else
     743:             if (opdope[p->t.op]&LEAF || p->t.degree < 2)
     744:                 r = reg;
     745:             else
     746:                 r = areg;
     747:         rreg = rcexpr(p, ctable, r);
     748:         if (ctable!=regtab && ctable!=cregtab)
     749:             goto loop;
     750:         if (c&010) {
     751:             if (c&020 && rreg!=reg1)
     752:                 movreg(rreg, reg1, p);
     753:             else
     754:                 reg1 = rreg;
     755:         } else if (rreg!=reg)
     756:             if ((c&020)==0 && oddreg(tree, 0)==0 && tree->t.type!=LONG
     757:             && tree->t.type!=UNLONG
     758:             && (flag&04
     759:               || flag&01&&xdcalc(p2,nreg-rreg-1)<=(opt->tabdeg2&077)
     760:               || flag&02&&xdcalc(p1,nreg-rreg-1)<=(opt->tabdeg1&077))) {
     761:                 reg = rreg;
     762:                 reg1 = rreg+1;
     763:             } else
     764:                 movreg(rreg, reg, p);
     765:         goto loop;
     766:
     767:     /* R */
     768:     case 'I':
     769:         r = reg;
     770:         if (*string=='-') {
     771:             string++;
     772:             r--;
     773:         }
     774:         goto preg;
     775:
     776:     /* R1 */
     777:     case 'J':
     778:         r = reg1;
     779:     preg:
     780:         if (*string=='+') {
     781:             string++;
     782:             r++;
     783:         }
     784:         if (r>nreg || r>=4 && tree->t.type==DOUBLE) {
     785:             if (regpanic)
     786:                 error("Register overflow: simplify expression");
     787:             else
     788:                 longjmp(jmpbuf, 1);
     789:         }
     790:         printf("r%d", r);
     791:         goto loop;
     792:
     793:     case '-':       /* check -(sp) */
     794:         if (*string=='(') {
     795:             nstack++;
     796:             if (table!=lsptab)
     797:                 putchar('-');
     798:             goto loop;
     799:         }
     800:         break;
     801:
     802:     case ')':       /* check (sp)+ */
     803:         putchar(')');
     804:         if (*string=='+')
     805:             nstack--;
     806:         goto loop;
     807:
     808:     /* #1 */
     809:     case '#':
     810:         p = p1->t.tr1;
     811:         goto nmbr;
     812:
     813:     /* #2 */
     814:     case '"':
     815:         p = p2->t.tr1;
     816:
     817:     nmbr:
     818:         if(collcon(p)) {
     819:             if (p->t.op==STAR) {
     820:                 printf("*");
     821:                 p = p->t.tr1;
     822:             }
     823:             if ((p = p->t.tr2)->t.op == CON) {
     824:                 if (p->c.value)
     825:                     psoct(p->c.value);
     826:             } else if (p->t.op==AMPER)
     827:                 pname(p->t.tr1, 0);
     828:         }
     829:         goto loop;
     830:
     831:     /*
     832: 	 * Certain adjustments for / %
     833: 	 */
     834:     case 'T':
     835:         c = reg-1;
     836:         if (uns(p1) || uns(p2)) {
     837:             printf("clr	r%d\n", c);
     838:             goto loop;
     839:         }
     840:         if (dcalc(p1, 5)>12 && !match(p1, cctab, 10, 0))
     841:             printf("tst	r%d\n", reg);
     842:         printf("sxt	r%d\n", c);
     843:         goto loop;
     844:
     845:     case 'V':   /* adc sbc, clr, or sxt as required for longs */
     846:         switch(tree->t.op) {
     847:         case PLUS:
     848:         case ASPLUS:
     849:         case INCBEF:
     850:         case INCAFT:
     851:             printf("adc");
     852:             break;
     853:
     854:         case MINUS:
     855:         case ASMINUS:
     856:         case NEG:
     857:         case DECBEF:
     858:         case DECAFT:
     859:             printf("sbc");
     860:             break;
     861:
     862:         case ASSIGN:
     863:             p = tree->t.tr2;
     864:             goto lcasev;
     865:
     866:         case ASDIV:
     867:         case ASMOD:
     868:         case ASULSH:
     869:             p = tree->t.tr1;
     870:         lcasev:
     871:             if (p->t.type!=LONG && p->t.type!=UNLONG) {
     872:                 if (uns(p) || uns(tree->t.tr2))
     873:                     printf("clr");
     874:                 else
     875:                     printf("sxt");
     876:                 goto loop;
     877:             }
     878:         default:
     879:             while ((c = *string++)!='\n' && c!='\0');
     880:             break;
     881:         }
     882:         goto loop;
     883:
     884:     /*
     885: 	 * Mask used in field assignments
     886: 	 */
     887:     case 'Z':
     888:         printf("$%o", UNS(tree->F.mask));
     889:         goto loop;
     890:
     891:     /*
     892: 	 * Relational on long values.
     893: 	 * Might bug out early. E.g.,
     894: 	 * (long<0) can be determined with only 1 test.
     895: 	 */
     896:     case 'X':
     897:         if (xlongrel(*string++ - '0'))
     898:             return(reg);
     899:         goto loop;
     900:     }
     901:     putchar(c);
     902:     goto loop;
     903: }
     904:
     905: /*
     906:  * This routine just calls sreorder (below)
     907:  * on the subtrees and then on the tree itself.
     908:  * It returns non-zero if anything changed.
     909:  */
     910: reorder(treep, table, reg)
     911: union tree **treep;
     912: struct table *table;
     913: {
     914:     register r, o;
     915:     register union tree *p;
     916:
     917:     p = *treep;
     918:     o = p->t.op;
     919:     if (opdope[o]&LEAF||o==LOGOR||o==LOGAND||o==SEQNC||o==QUEST||o==COLON)
     920:         return(0);
     921:     while(sreorder(&p->t.tr1, regtab, reg, 1))
     922:         ;
     923:     if (opdope[o]&BINARY)
     924:         while(sreorder(&p->t.tr2, regtab, reg, 1))
     925:             ;
     926:     r = 0;
     927:     if (table!=cctab)
     928:     while (sreorder(treep, table, reg, 0))
     929:         r++;
     930:     *treep = optim(*treep);
     931:     return(r);
     932: }
     933:
     934: /*
     935:  * Basically this routine carries out two kinds of optimization.
     936:  * First, it observes that "x + (reg = y)" where actually
     937:  * the = is any assignment op is better done as "reg=y; x+reg".
     938:  * In this case rcexpr is called to do the first part and the
     939:  * tree is modified so the name of the register
     940:  * replaces the assignment.
     941:  * Moreover, expressions like "reg = x+y" are best done as
     942:  * "reg = x; reg += y" (so long as "reg" and "y" are not the same!).
     943:  */
     944: sreorder(treep, table, reg, recurf)
     945: union tree **treep;
     946: struct table *table;
     947: {
     948:     register union tree *p, *p1;
     949:
     950:     p = *treep;
     951:     if (opdope[p->t.op]&LEAF)
     952:         return(0);
     953:     if (p->t.op==PLUS && recurf)
     954:         if (reorder(&p->t.tr2, table, reg))
     955:             *treep = p = optim(p);
     956:     if ((p1 = p->t.tr1)==TNULL)
     957:         return(0);
     958:     if (p->t.op==STAR || p->t.op==PLUS) {
     959:         if (recurf && reorder(&p->t.tr1, table, reg)) {
     960:             *treep = p = optim(p);
     961:             if (opdope[p->t.op]&LEAF)
     962:                 return(0);
     963:         }
     964:         p1 = p->t.tr1;
     965:     }
     966:     if (p1->t.op==NAME) switch(p->t.op) {
     967:         case ASLSH:
     968:         case ASRSH:
     969:         case ASSIGN:
     970:             if (p1->n.class != REG || p1->n.type==CHAR
     971:               || isfloat(p->t.tr2))
     972:                 return(0);
     973:             if (p->t.op==ASSIGN) switch (p->t.tr2->t.op) {
     974:             case RSHIFT:
     975:                 if (p->t.type==UNSIGN)
     976:                     return(0);
     977:                 goto caseGEN;
     978:             case TIMES:
     979:                 if (!ispow2(p->t.tr2))
     980:                     break;
     981:                 p->t.tr2 = pow2(p->t.tr2);
     982:             case PLUS:
     983:             case MINUS:
     984:             case AND:
     985:             case ANDN:
     986:             case OR:
     987:             case EXOR:
     988:             case LSHIFT:
     989:             caseGEN:
     990:                 p1 = p->t.tr2->t.tr2;
     991:                 if (xdcalc(p1, 16) > 12
     992:                  || p1->t.op==NAME
     993:                  &&(p1->n.nloc==p->t.tr1->n.nloc
     994:                   || p1->n.regno==p->t.tr1->n.nloc))
     995:                     return(0);
     996:                 p1 = p->t.tr2;
     997:                 p->t.tr2 = p1->t.tr1;
     998:                 if (p1->t.tr1->t.op!=NAME
     999:                  || p1->t.tr1->n.class!=REG
    1000:                  || p1->t.tr1->n.nloc!=p->t.tr1->n.nloc)
    1001:                     rcexpr(p, efftab, reg);
    1002:                 p->t.tr2 = p1->t.tr2;
    1003:                 p->t.op = p1->t.op + ASPLUS - PLUS;
    1004:                 *treep = p;
    1005:                 return(1);
    1006:             }
    1007:             goto OK;
    1008:
    1009:         case ASTIMES:
    1010:             if (!ispow2(p))
    1011:                 return(0);
    1012:         case ASPLUS:
    1013:         case ASMINUS:
    1014:         case ASAND:
    1015:         case ASANDN:
    1016:         case ASOR:
    1017:         case ASXOR:
    1018:         case INCBEF:
    1019:         case DECBEF:
    1020:         OK:
    1021:             if (table==cctab||table==cregtab)
    1022:                 reg += 020;
    1023:             rcexpr(optim(p), efftab, ~reg);
    1024:             *treep = p1;
    1025:             return(1);
    1026:     }
    1027:     return(0);
    1028: }
    1029:
    1030: /*
    1031:  * Delay handles postfix ++ and --
    1032:  * It observes that "x + y++" is better
    1033:  * treated as "x + y; y++".
    1034:  * If the operator is ++ or -- itself,
    1035:  * it calls rcexpr to load the operand, letting
    1036:  * the calling instance of rcexpr to do the
    1037:  * ++ using efftab.
    1038:  * Otherwise it uses sdelay to search for inc/dec
    1039:  * among the operands.
    1040:  */
    1041: delay(treep, table, reg)
    1042: union tree **treep;
    1043: struct table *table;
    1044: {
    1045:     register union tree *p, *p1;
    1046:     register r;
    1047:
    1048:     p = *treep;
    1049:     if ((p->t.op==INCAFT||p->t.op==DECAFT)
    1050:      && p->t.tr1->t.op==NAME) {
    1051:         r = p->t.tr1->n.class;
    1052:         if (r == EXTERN || r == OFFS || r == STATIC &&
    1053:                 p->t.tr1->t.type == UNCHAR)
    1054:             return(1+rcexpr(p->t.tr1, table, reg));
    1055:         else
    1056:             return(1+rcexpr(paint(p->t.tr1, p->t.type), table,reg));
    1057:     }
    1058:     p1 = 0;
    1059: /*
    1060:  * typo fix, original code.
    1061:  *	if (opdope[p->t.op]&BINARY) {
    1062:  *		if (p->t.op==LOGAND || p->t.op==LOGOR
    1063:  *		 || p->t.op==QUEST || p->t.op==COLON || p->t.op==SEQNC)
    1064:  *			return(0);
    1065:  *		}
    1066:  *		p1 = sdelay(&p->t.tr2);
    1067:  *	if (p1==0)
    1068:  *		p1 = sdelay(&p->t.tr1);
    1069:  */
    1070:     if (opdope[p->t.op]&BINARY) {
    1071:         if (p->t.op==LOGAND || p->t.op==LOGOR
    1072:          || p->t.op==QUEST || p->t.op==COLON || p->t.op==SEQNC)
    1073:             return(0);
    1074:         p1 = sdelay(&p->t.tr2);
    1075:     }
    1076:     if (p1==0)
    1077:         p1 = sdelay(&p->t.tr1);
    1078:     if (p1) {
    1079:         r = rcexpr(optim(p), table, reg);
    1080:         *treep = p1;
    1081:         return(r+1);
    1082:     }
    1083:     return(0);
    1084: }
    1085:
    1086: union tree *
    1087: sdelay(ap)
    1088: union tree **ap;
    1089: {
    1090:     register union tree *p, *p1;
    1091:
    1092:     if ((p = *ap)==TNULL)
    1093:         return(TNULL);
    1094:     if ((p->t.op==INCAFT||p->t.op==DECAFT) && p->t.tr1->t.op==NAME) {
    1095:         *ap = paint(ncopy(p->t.tr1), p->t.type);
    1096:         return(p);
    1097:     }
    1098:     if (p->t.op==STAR || p->t.op==PLUS)
    1099:         if (p1=sdelay(&p->t.tr1))
    1100:             return(p1);
    1101:     if (p->t.op==PLUS)
    1102:         return(sdelay(&p->t.tr2));
    1103:     return(0);
    1104: }
    1105:
    1106: /*
    1107:  * Propagate possible implicit type-changing operation
    1108:  */
    1109: union tree *
    1110: paint(tp, type)
    1111: register union tree *tp;
    1112: register type;
    1113: {
    1114:
    1115:     if (tp->t.type==type)
    1116:         return(tp);
    1117:     if (tp->t.type==CHAR && type==INT)
    1118:         return(tp);
    1119:     if (tp->t.type==CHAR || tp->t.type==UNCHAR)
    1120:         return(optim(tnode(LOAD, type, tp, TNULL)));
    1121:     tp->t.type = type;
    1122:     if (tp->t.op==AMPER && type&XTYPE)
    1123:         tp->t.tr1 = paint(tp->t.tr1, decref(type));
    1124:     else if (tp->t.op==STAR)
    1125:         tp->t.tr1 = paint(tp->t.tr1, incref(type));
    1126:     else if (tp->t.op==ASSIGN) {
    1127:         paint(tp->t.tr1, type);
    1128:         paint(tp->t.tr2, type);
    1129:     }
    1130:     return(tp);
    1131: }
    1132:
    1133: /*
    1134:  * Copy a tree node for a register variable.
    1135:  * Used by sdelay because if *reg-- is turned
    1136:  * into *reg; reg-- the *reg will in turn
    1137:  * be changed to some offset class, accidentally
    1138:  * modifying the reg--.
    1139:  */
    1140: union tree *
    1141: ncopy(p)
    1142: register union tree *p;
    1143: {
    1144:     register union tree *q;
    1145:
    1146:     q = getblk(sizeof(struct xtname));
    1147:     q->n.op = p->n.op;
    1148:     q->n.type = p->n.type;
    1149:     q->n.class = p->n.class;
    1150:     q->n.regno = p->n.regno;
    1151:     q->n.offset = p->n.offset;
    1152:     if (q->n.class==EXTERN || q->n.class==XOFFS)
    1153:         q->x.name = p->x.name;
    1154:     else
    1155:         q->n.nloc = p->n.nloc;
    1156:     return(q);
    1157: }
    1158:
    1159: /*
    1160:  * If the tree can be immediately loaded into a register,
    1161:  * produce code to do so and return success.
    1162:  */
    1163: chkleaf(tree, table, reg)
    1164: register union tree *tree;
    1165: struct table *table;
    1166: {
    1167:     struct tnode lbuf;
    1168:
    1169:     if (tree->t.op!=STAR && dcalc(tree, nreg-reg) > 12)
    1170:         return(-1);
    1171:     lbuf.op = LOAD;
    1172:     lbuf.type = tree->t.type;
    1173:     lbuf.degree = tree->t.degree;
    1174:     lbuf.tr1 = tree;
    1175:     return(rcexpr((union tree *)&lbuf, table, reg));
    1176: }
    1177:
    1178: /*
    1179:  * Compile a function argument.
    1180:  * If the stack is currently empty, put it in (sp)
    1181:  * rather than -(sp); this will save a pop.
    1182:  * Return the number of bytes pushed,
    1183:  * for future popping.
    1184:  */
    1185: comarg(tree, flagp)
    1186: register union tree *tree;
    1187: int *flagp;
    1188: {
    1189:     register retval;
    1190:     int i;
    1191:     int size;
    1192:
    1193:     if (tree->t.op==STRASG) {
    1194:         size = tree->F.mask;
    1195:         tree = tree->t.tr1;
    1196:         tree = strfunc(tree);
    1197:         if (size <= sizeof(short)) {
    1198:             paint(tree, INT);
    1199:             goto normal;
    1200:         }
    1201:         if (size <= sizeof(long)) {
    1202:             paint(tree, LONG);
    1203:             goto normal;
    1204:         }
    1205:         if (tree->t.op!=NAME && tree->t.op!=STAR) {
    1206:             error("Unimplemented structure assignment");
    1207:             return(0);
    1208:         }
    1209:         tree = tnode(AMPER, STRUCT+PTR, tree, TNULL);
    1210:         tree = tnode(PLUS, STRUCT+PTR, tree, tconst(size, INT));
    1211:         tree = optim(tree);
    1212:         retval = rcexpr(tree, regtab, 0);
    1213:         size >>= 1;
    1214:         if (size <= 5) {
    1215:             for (i=0; i<size; i++)
    1216:                 printf("mov	-(r%d),-(sp)\n", retval);
    1217:         } else {
    1218:             if (retval!=0)
    1219:                 printf("mov	r%d,r0\n", retval);
    1220:             printf("mov	$%o,r1\n", UNS(size));
    1221:             printf("L%d:mov	-(r0),-(sp)\ndec\tr1\njne\tL%d\n", isn, isn);
    1222:             isn++;
    1223:         }
    1224:         nstack++;
    1225:         return(size*2);
    1226:     }
    1227: normal:
    1228:     if (nstack || isfloat(tree) || tree->t.type==LONG || tree->t.type==UNLONG) {
    1229:         rcexpr(tree, sptab, 0);
    1230:         retval = arlength(tree->t.type);
    1231:     } else {
    1232:         (*flagp)++;
    1233:         rcexpr(tree, lsptab, 0);
    1234:         retval = 0;
    1235:     }
    1236:     return(retval);
    1237: }
    1238:
    1239: union tree *
    1240: strfunc(tp)
    1241: register union tree *tp;
    1242: {
    1243:     if (tp->t.op != CALL)
    1244:         return(tp);
    1245:     paint(tp, STRUCT+PTR);
    1246:     return(tnode(STAR, STRUCT, tp, TNULL));
    1247: }
    1248:
    1249: /*
    1250:  * Compile an initializing expression
    1251:  */
    1252: doinit(type, tree)
    1253: register type;
    1254: register union tree *tree;
    1255: {
    1256:     float sfval;
    1257:     double fval;
    1258:     long lval;
    1259:
    1260:     if (type==CHAR || type==UNCHAR) {
    1261:         printf(".byte ");
    1262:         if (tree->t.type&XTYPE)
    1263:             goto illinit;
    1264:         type = INT;
    1265:     }
    1266:     if (type&XTYPE)
    1267:         type = INT;
    1268:     switch (type) {
    1269:     case INT:
    1270:     case UNSIGN:
    1271:         if (tree->t.op==FTOI) {
    1272:             if (tree->t.tr1->t.op!=FCON && tree->t.tr1->t.op!=SFCON)
    1273:                 goto illinit;
    1274:             tree = tree->t.tr1;
    1275:             tree->c.value = tree->f.fvalue;
    1276:             tree->t.op = CON;
    1277:         } else if (tree->t.op==LTOI) {
    1278:             if (tree->t.tr1->t.op!=LCON)
    1279:                 goto illinit;
    1280:             tree = tree->t.tr1;
    1281:             lval = tree->l.lvalue;
    1282:             tree->t.op = CON;
    1283:             tree->c.value = lval;
    1284:         }
    1285:         if (tree->t.op == CON)
    1286:             printf("%o\n", UNS(tree->c.value));
    1287:         else if (tree->t.op==AMPER) {
    1288:             pname(tree->t.tr1, 0);
    1289:             putchar('\n');
    1290:         } else
    1291:             goto illinit;
    1292:         return;
    1293:
    1294:     case DOUBLE:
    1295:     case FLOAT:
    1296:         if (tree->t.op==ITOF) {
    1297:             if (tree->t.tr1->t.op==CON) {
    1298:                 fval = tree->t.tr1->c.value;
    1299:             } else
    1300:                 goto illinit;
    1301:         } else if (tree->t.op==FCON || tree->t.op==SFCON)
    1302:             fval = tree->f.fvalue;
    1303:         else if (tree->t.op==LTOF) {
    1304:             if (tree->t.tr1->t.op!=LCON)
    1305:                 goto illinit;
    1306:             fval = tree->t.tr1->l.lvalue;
    1307:         } else
    1308:             goto illinit;
    1309:         if (type==FLOAT) {
    1310:             sfval = fval;
    1311: /* nonportable */
    1312:             printf("%o; %o\n",
    1313:                 ((unsigned short *)&sfval)[0],
    1314:                 ((unsigned short *)&sfval)[1] );
    1315:         } else
    1316:             printf("%o; %o; %o; %o\n",
    1317:                 ((unsigned short *)&fval)[0],
    1318:                 ((unsigned short *)&fval)[1],
    1319:                 ((unsigned short *)&fval)[2],
    1320:                 ((unsigned short *)&fval)[3] );
    1321:         return;
    1322:
    1323:     case UNLONG:
    1324:     case LONG:
    1325:         if (tree->t.op==FTOL) {
    1326:             tree = tree->t.tr1;
    1327:             if (tree->t.op==SFCON)
    1328:                 tree->t.op = FCON;
    1329:             if (tree->t.op!= FCON)
    1330:                 goto illinit;
    1331:             lval = tree->f.fvalue;
    1332:         } else if (tree->t.op==ITOL) {
    1333:             if (tree->t.tr1->t.op != CON)
    1334:                 goto illinit;
    1335:             if (uns(tree->t.tr1))
    1336:                 lval = (unsigned)tree->t.tr1->c.value;
    1337:             else
    1338:                 lval = tree->t.tr1->c.value;
    1339:         } else if (tree->t.op==LCON)
    1340:             lval = tree->l.lvalue;
    1341:         else
    1342:             goto illinit;
    1343: /* nonportable */
    1344:         printf("%o; %o\n", UNS((lval>>16)), UNS(lval));
    1345:         return;
    1346:     }
    1347: illinit:
    1348:     error("Illegal initialization");
    1349: }
    1350:
    1351: movreg(r0, r1, tree)
    1352: union tree *tree;
    1353: {
    1354:     register char *s;
    1355:     char c;
    1356:
    1357:     if (r0==r1)
    1358:         return;
    1359:     if (tree->t.type==LONG || tree->t.type == UNLONG) {
    1360:         if (r0>=nreg || r1>=nreg) {
    1361:             error("register overflow: compiler error");
    1362:         }
    1363:         s = "mov	r%d,r%d\nmov	r%d,r%d\n";
    1364:         if (r0 < r1)
    1365:             printf(s, r0+1,r1+1,r0,r1);
    1366:         else
    1367:             printf(s, r0,r1,r0+1,r1+1);
    1368:         return;
    1369:     }
    1370:     c = isfloat(tree);
    1371:     printf("mov%.1s	r%d,r%d\n", &c, r0, r1);
    1372: }

#### Defined functions

cexpr defined in line 464; used 4 times

- in line 328, 401, 408
- in /usr/src/lib/ccom/c11.c line 699

chkleaf defined in line 1163; used 1 times

- in line 519

comarg defined in line 1185; used 2 times

- in line 316-320(2)

delay defined in line 1041; used 1 times

- in line 384

doinit defined in line 1252; used 1 times

- in line 245

main defined in line 40; never used
match defined in line 95; used 6 times

- in line 131, 137, 577-578(2), 840
- in /usr/src/lib/ccom/c1.h line 150

movreg defined in line 1351; used 4 times

- in line 255, 504, 752, 764

ncopy defined in line 1140; used 2 times

- in line 1095
- in /usr/src/lib/ccom/c1.h line 156

paint defined in line 1109; used 24 times

- in line 1056, 1095, 1123-1128(4), 1198-1202(2), 1245
- in /usr/src/lib/ccom/c1.h line 165
- in /usr/src/lib/ccom/c11.c line 1056, 1164-1166(2)
- in /usr/src/lib/ccom/c12.c line 200-201(2), 240, 318, 408, 521-524(2), 554-557(2), 717, 760

rcexpr defined in line 187; used 18 times

- in line 254, 263, 431, 437, 486-489(2), 498-502(2), 747, 1001, 1023, 1054-1056(2), 1079, 1175, 1212, 1229-1233(2)

reorder defined in line 910; used 4 times

- in line 394, 954-959(2)
- in /usr/src/lib/ccom/c11.c line 676

sdelay defined in line 1086; used 5 times

- in line 1074-1077(2), 1099-1102(2)
- in /usr/src/lib/ccom/c1.h line 155

sreorder defined in line 944; used 3 times

- in line 921-928(3)

strfunc defined in line 1239; used 3 times

- in line 1196
- in /usr/src/lib/ccom/c1.h line 158
- in /usr/src/lib/ccom/c11.c line 1162

#### Defined variables

cone defined in line 31; used 1 times

- in line 489

cregtab defined in line 35; used 8 times

- in line 382, 402, 421, 556, 712, 729, 748, 1021

czero defined in line 30; used 1 times

- in line 486

debug defined in line 20; never used
isn defined in line 38; used 8 times

- in line 485-490(3), 496-500(2), 1221-1222(3)

maprel defined in line 22; never used
notrel defined in line 26; never used
nreg defined in line 37; used 7 times

- in line 573, 759-760(2), 784, 1169, 1360(2)

sccsid defined in line 9; never used
sfuncr defined in line 33; never used

#### Defined macros

NOCVL defined in line 100; used 2 times

- in line 131-134(2)

NOCVR defined in line 101; used 2 times

- in line 128, 137

dbprint defined in line 17; used 2 times

- in line 411, 615

Last modified: 1996-06-20 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3118 |