Annotation of cci/usr/src/usr.bin/f77/f77pass1/putpcc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char sccsid[] = "@(#)putpcc.c   5.1 (Berkeley) 6/7/85";
                      9: #endif not lint
                     10: 
                     11: /*
                     12:  * putpcc.c
                     13:  *
                     14:  * Intermediate code generation for S. C. Johnson C compilers
                     15:  * New version using binary polish postfix intermediate
                     16:  *
                     17:  * University of Utah CS Dept modification history:
                     18:  *
                     19:  * $Header: putpcc.c,v 1.2 86/02/12 15:29:08 rcs Exp $
                     20:  * $Log:       putpcc.c,v $
                     21:  * Revision 1.2  86/02/12  15:29:08  rcs
                     22:  * 4.3 F77. C. Keating.
                     23:  * 
                     24:  * Revision 3.2  85/03/25  09:35:57  root
                     25:  * fseek return -1 on error.
                     26:  * 
                     27:  * Revision 3.1  85/02/27  19:06:55  donn
                     28:  * Changed to use pcc.h instead of pccdefs.h.
                     29:  * 
                     30:  * Revision 2.12  85/02/22  01:05:54  donn
                     31:  * putaddr() didn't know about intrinsic functions...
                     32:  * 
                     33:  * Revision 2.11  84/11/28  21:28:49  donn
                     34:  * Hacked putop() to handle any character expression being converted to int,
                     35:  * not just function calls.  Previously it bombed on concatenations.
                     36:  * 
                     37:  * Revision 2.10  84/11/01  22:07:07  donn
                     38:  * Yet another try at getting putop() to work right.  It appears that the
                     39:  * second pass can't abide certain explicit conversions (e.g. short to long)
                     40:  * so the conversion code in putop() tries to remove them.  I think this
                     41:  * version (finally) works.
                     42:  * 
                     43:  * Revision 2.9  84/10/29  02:30:57  donn
                     44:  * Earlier fix to putop() for conversions was insufficient -- we NEVER want to
                     45:  * see the type of the left operand of the thing left over from stripping off
                     46:  * conversions...
                     47:  * 
                     48:  * Revision 2.8  84/09/18  03:09:21  donn
                     49:  * Fixed bug in putop() where the left operand of an addrblock was being
                     50:  * extracted...  This caused an extremely obscure conversion error when
                     51:  * an array of longs was subscripted by a short.
                     52:  * 
                     53:  * Revision 2.7  84/08/19  20:10:19  donn
                     54:  * Removed stuff in putbranch that treats STGARG parameters specially -- the
                     55:  * bug in the code generation pass that motivated it has been fixed.
                     56:  * 
                     57:  * Revision 2.6  84/08/07  21:32:23  donn
                     58:  * Bumped the size of the buffer for the intermediate code file from 0.5K
                     59:  * to 4K on a VAX.
                     60:  * 
                     61:  * Revision 2.5  84/08/04  20:26:43  donn
                     62:  * Fixed a goof in the new putbranch() -- it now calls mkaltemp instead of
                     63:  * mktemp().  Correction due to Jerry Berkman.
                     64:  * 
                     65:  * Revision 2.4  84/07/24  19:07:15  donn
                     66:  * Fixed bug reported by Craig Leres in which putmnmx() mistakenly assumed
                     67:  * that mkaltemp() returns tempblocks, and tried to free them with frtemp().
                     68:  * 
                     69:  * Revision 2.3  84/07/19  17:22:09  donn
                     70:  * Changed putch1() so that OPPAREN expressions of type CHARACTER are legal.
                     71:  * 
                     72:  * Revision 2.2  84/07/19  12:30:38  donn
                     73:  * Fixed a type clash in Bob Corbett's new putbranch().
                     74:  * 
                     75:  * Revision 2.1  84/07/19  12:04:27  donn
                     76:  * Changed comment headers for UofU.
                     77:  * 
                     78:  * Revision 1.8  84/07/19  11:38:23  donn
                     79:  * Replaced putbranch() routine so that you can ASSIGN into argument variables.
                     80:  * The code is from Bob Corbett, donated by Jerry Berkman.
                     81:  * 
                     82:  * Revision 1.7  84/05/31  00:48:32  donn
                     83:  * Fixed an extremely obscure bug dealing with the comparison of CHARACTER*1
                     84:  * expressions -- a foulup in the order of COMOP and the comparison caused
                     85:  * one operand of the comparison to be garbage.
                     86:  * 
                     87:  * Revision 1.6  84/04/16  09:54:19  donn
                     88:  * Backed out earlier fix for bug where items in the argtemplist were
                     89:  * (incorrectly) being given away; this is now fixed in mkargtemp().
                     90:  * 
                     91:  * Revision 1.5  84/03/23  22:49:48  donn
                     92:  * Took out the initialization of the subroutine argument temporary list in
                     93:  * putcall() -- it needs to be done once per statement instead of once per call.
                     94:  * 
                     95:  * Revision 1.4  84/03/01  06:48:05  donn
                     96:  * Fixed bug in Bob Corbett's code for argument temporaries that caused an
                     97:  * addrblock to get thrown out inadvertently when it was needed for recycling
                     98:  * purposes later on.
                     99:  * 
                    100:  * Revision 1.3  84/02/26  06:32:38  donn
                    101:  * Added Berkeley changes to move data definitions around and reduce offsets.
                    102:  * 
                    103:  * Revision 1.2  84/02/26  06:27:45  donn
                    104:  * Added code to catch TTEMP values passed to putx().
                    105:  * 
                    106:  */
                    107: 
                    108: #if FAMILY != PCC
                    109:        WRONG put FILE !!!!
                    110: #endif
                    111: 
                    112: #include "defs.h"
                    113: #include <pcc.h>
                    114: 
                    115: Addrp putcall(), putcxeq(), putcx1(), realpart();
                    116: expptr imagpart();
                    117: ftnint lencat();
                    118: 
                    119: #define FOUR 4
                    120: extern int ops2[];
                    121: extern int types2[];
                    122: 
                    123: #if HERE==VAX || HERE == TAHOE
                    124: #define PCC_BUFFMAX 1024
                    125: #else
                    126: #define PCC_BUFFMAX 128
                    127: #endif
                    128: static long int p2buff[PCC_BUFFMAX];
                    129: static long int *p2bufp                = &p2buff[0];
                    130: static long int *p2bufend      = &p2buff[PCC_BUFFMAX];
                    131: 
                    132: 
                    133: puthead(s, class)
                    134: char *s;
                    135: int class;
                    136: {
                    137: char buff[100];
                    138: #if TARGET == VAX || TARGET == TAHOE
                    139:        if(s)
                    140:                p2ps("\t.globl\t_%s", s);
                    141: #endif
                    142: /* put out fake copy of left bracket line, to be redone later */
                    143: if( ! headerdone )
                    144:        {
                    145: #if FAMILY == PCC
                    146:        p2flush();
                    147: #endif
                    148:        headoffset = ftell(textfile);
                    149:        prhead(textfile);
                    150:        headerdone = YES;
                    151:        p2triple(PCCF_FEXPR, (strlen(infname)+ALILONG-1)/ALILONG, 0);
                    152:        p2str(infname);
                    153: #if TARGET == PDP11
                    154:        /* fake jump to start the optimizer */
                    155:        if(class != CLBLOCK)
                    156:                putgoto( fudgelabel = newlabel() );
                    157: #endif
                    158: 
                    159: #if TARGET == VAX || TARGET == TAHOE
                    160:        /* jump from top to bottom */
                    161:        if(s!=CNULL && class!=CLBLOCK)
                    162:                {
                    163:                int proflab = newlabel();
                    164:                p2pass("\t.align\t1");
                    165:                p2ps("_%s:", s);
                    166:                p2pi("\t.word\tLWM%d", procno);
                    167:                prsave(proflab);
                    168: #if TARGET == VAX
                    169:                p2pi("\tjbr\tL%d",
                    170: #else
                    171:                putgoto(
                    172: #endif
                    173:                 fudgelabel = newlabel());
                    174:                }
                    175: #endif
                    176:        }
                    177: }
                    178: 
                    179: 
                    180: 
                    181: 
                    182: 
                    183: /* It is necessary to precede each procedure with a "left bracket"
                    184:  * line that tells pass 2 how many register variables and how
                    185:  * much automatic space is required for the function.  This compiler
                    186:  * does not know how much automatic space is needed until the
                    187:  * entire procedure has been processed.  Therefore, "puthead"
                    188:  * is called at the begining to record the current location in textfile,
                    189:  * then to put out a placeholder left bracket line.  This procedure
                    190:  * repositions the file and rewrites that line, then puts the
                    191:  * file pointer back to the end of the file.
                    192:  */
                    193: 
                    194: putbracket()
                    195: {
                    196: long int hereoffset;
                    197: 
                    198: #if FAMILY == PCC
                    199:        p2flush();
                    200: #endif
                    201: hereoffset = ftell(textfile);
                    202: if(fseek(textfile, headoffset, 0) == -1)
                    203:        fatal("fseek failed");
                    204: prhead(textfile);
                    205: if(fseek(textfile, hereoffset, 0) == -1)
                    206:        fatal("fseek failed 2");
                    207: }
                    208: 
                    209: 
                    210: 
                    211: 
                    212: putrbrack(k)
                    213: int k;
                    214: {
                    215: p2op(PCCF_FRBRAC, k);
                    216: }
                    217: 
                    218: 
                    219: 
                    220: putnreg()
                    221: {
                    222: }
                    223: 
                    224: 
                    225: 
                    226: 
                    227: 
                    228: 
                    229: puteof()
                    230: {
                    231: p2op(PCCF_FEOF, 0);
                    232: p2flush();
                    233: }
                    234: 
                    235: 
                    236: 
                    237: putstmt()
                    238: {
                    239: p2triple(PCCF_FEXPR, 0, lineno);
                    240: }
                    241: 
                    242: 
                    243: 
                    244: 
                    245: /* put out code for if( ! p) goto l  */
                    246: putif(p,l)
                    247: register expptr p;
                    248: int l;
                    249: {
                    250: register int k;
                    251: 
                    252: if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
                    253:        {
                    254:        if(k != TYERROR)
                    255:                err("non-logical expression in IF statement");
                    256:        frexpr(p);
                    257:        }
                    258: else
                    259:        {
                    260:        putex1(p);
                    261:        p2icon( (long int) l , PCCT_INT);
                    262:        p2op(PCC_CBRANCH, 0);
                    263:        putstmt();
                    264:        }
                    265: }
                    266: 
                    267: 
                    268: 
                    269: 
                    270: 
                    271: /* put out code for  goto l   */
                    272: putgoto(label)
                    273: int label;
                    274: {
                    275: p2triple(PCC_GOTO, 1, label);
                    276: putstmt();
                    277: }
                    278: 
                    279: 
                    280: /* branch to address constant or integer variable */
                    281: putbranch(p)
                    282: register Addrp p;
                    283: {
                    284:   putex1((expptr) p);
                    285:   p2op(PCC_GOTO, PCCT_INT);
                    286:   putstmt();
                    287: }
                    288: 
                    289: 
                    290: 
                    291: /* put out label  l:     */
                    292: putlabel(label)
                    293: int label;
                    294: {
                    295: p2op(PCCF_FLABEL, label);
                    296: }
                    297: 
                    298: 
                    299: 
                    300: 
                    301: putexpr(p)
                    302: expptr p;
                    303: {
                    304: putex1(p);
                    305: putstmt();
                    306: }
                    307: 
                    308: 
                    309: 
                    310: 
                    311: putcmgo(index, nlab, labs)
                    312: expptr index;
                    313: int nlab;
                    314: struct Labelblock *labs[];
                    315: {
                    316: int i, labarray, skiplabel;
                    317: 
                    318: if(! ISINT(index->headblock.vtype) )
                    319:        {
                    320:        execerr("computed goto index must be integer", CNULL);
                    321:        return;
                    322:        }
                    323: 
                    324: #if TARGET == VAX || TARGET == TAHOE
                    325:        /* use special case instruction */
                    326:        casegoto(index, nlab, labs);
                    327: #else
                    328:        labarray = newlabel();
                    329:        preven(ALIADDR);
                    330:        prlabel(asmfile, labarray);
                    331:        prcona(asmfile, (ftnint) (skiplabel = newlabel()) );
                    332:        for(i = 0 ; i < nlab ; ++i)
                    333:                if( labs[i] )
                    334:                        prcona(asmfile, (ftnint)(labs[i]->labelno) );
                    335:        prcmgoto(index, nlab, skiplabel, labarray);
                    336:        putlabel(skiplabel);
                    337: #endif
                    338: }
                    339: 
                    340: putx(p)
                    341: expptr p;
                    342: {
                    343: char *memname();
                    344: int opc;
                    345: int ncomma;
                    346: int type, k;
                    347: 
                    348: if (!p)
                    349:        return;
                    350: 
                    351: switch(p->tag)
                    352:        {
                    353:        case TERROR:
                    354:                free( (charptr) p );
                    355:                break;
                    356: 
                    357:        case TCONST:
                    358:                switch(type = p->constblock.vtype)
                    359:                        {
                    360:                        case TYLOGICAL:
                    361:                                type = tyint;
                    362:                        case TYLONG:
                    363:                        case TYSHORT:
                    364:                                p2icon(p->constblock.const.ci, types2[type]);
                    365:                                free( (charptr) p );
                    366:                                break;
                    367: 
                    368:                        case TYADDR:
                    369:                                p2triple(PCC_ICON, 1, PCCT_INT|PCCTM_PTR);
                    370:                                p2word(0L);
                    371:                                p2name(memname(STGCONST,
                    372:                                        (int) p->constblock.const.ci) );
                    373:                                free( (charptr) p );
                    374:                                break;
                    375: 
                    376:                        default:
                    377:                                putx( putconst(p) );
                    378:                                break;
                    379:                        }
                    380:                break;
                    381: 
                    382:        case TEXPR:
                    383:                switch(opc = p->exprblock.opcode)
                    384:                        {
                    385:                        case OPCALL:
                    386:                        case OPCCALL:
                    387:                                if( ISCOMPLEX(p->exprblock.vtype) )
                    388:                                        putcxop(p);
                    389:                                else    putcall(p);
                    390:                                break;
                    391: 
                    392:                        case OPMIN:
                    393:                        case OPMAX:
                    394:                                putmnmx(p);
                    395:                                break;
                    396: 
                    397: 
                    398:                        case OPASSIGN:
                    399:                                if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
                    400:                                || ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
                    401:                                        frexpr( putcxeq(p) );
                    402:                                else if( ISCHAR(p) )
                    403:                                        putcheq(p);
                    404:                                else
                    405:                                        goto putopp;
                    406:                                break;
                    407: 
                    408:                        case OPEQ:
                    409:                        case OPNE:
                    410:                                if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
                    411:                                    ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
                    412:                                        {
                    413:                                        putcxcmp(p);
                    414:                                        break;
                    415:                                        }
                    416:                        case OPLT:
                    417:                        case OPLE:
                    418:                        case OPGT:
                    419:                        case OPGE:
                    420:                                if(ISCHAR(p->exprblock.leftp))
                    421:                                        {
                    422:                                        putchcmp(p);
                    423:                                        break;
                    424:                                        }
                    425:                                goto putopp;
                    426: 
                    427:                        case OPPOWER:
                    428:                                putpower(p);
                    429:                                break;
                    430: 
                    431:                        case OPSTAR:
                    432: #if FAMILY == PCC
                    433:                                /*   m * (2**k) -> m<<k   */
                    434:                                if(INT(p->exprblock.leftp->headblock.vtype) &&
                    435:                                   ISICON(p->exprblock.rightp) &&
                    436:                                   ( (k = log2(p->exprblock.rightp->constblock.const.ci))>0) )
                    437:                                        {
                    438:                                        p->exprblock.opcode = OPLSHIFT;
                    439:                                        frexpr(p->exprblock.rightp);
                    440:                                        p->exprblock.rightp = ICON(k);
                    441:                                        goto putopp;
                    442:                                        }
                    443: #endif
                    444: 
                    445:                        case OPMOD:
                    446:                                goto putopp;
                    447:                        case OPPLUS:
                    448:                        case OPMINUS:
                    449:                        case OPSLASH:
                    450:                        case OPNEG:
                    451:                                if( ISCOMPLEX(p->exprblock.vtype) )
                    452:                                        putcxop(p);
                    453:                                else    goto putopp;
                    454:                                break;
                    455: 
                    456:                        case OPCONV:
                    457:                                if( ISCOMPLEX(p->exprblock.vtype) )
                    458:                                        putcxop(p);
                    459:                                else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
                    460:                                        {
                    461:                                        ncomma = 0;
                    462:                                        putx( mkconv(p->exprblock.vtype,
                    463:                                                realpart(putcx1(p->exprblock.leftp,
                    464:                                                        &ncomma))));
                    465:                                        putcomma(ncomma, p->exprblock.vtype, NO);
                    466:                                        free( (charptr) p );
                    467:                                        }
                    468:                                else    goto putopp;
                    469:                                break;
                    470: 
                    471:                        case OPNOT:
                    472:                        case OPOR:
                    473:                        case OPAND:
                    474:                        case OPEQV:
                    475:                        case OPNEQV:
                    476:                        case OPADDR:
                    477:                        case OPPLUSEQ:
                    478:                        case OPSTAREQ:
                    479:                        case OPCOMMA:
                    480:                        case OPQUEST:
                    481:                        case OPCOLON:
                    482:                        case OPBITOR:
                    483:                        case OPBITAND:
                    484:                        case OPBITXOR:
                    485:                        case OPBITNOT:
                    486:                        case OPLSHIFT:
                    487:                        case OPRSHIFT:
                    488:                putopp:
                    489:                                putop(p);
                    490:                                break;
                    491: 
                    492:                        case OPPAREN:
                    493:                                putx (p->exprblock.leftp);
                    494:                                break;
                    495:                        default:
                    496:                                badop("putx", opc);
                    497:                        }
                    498:                break;
                    499: 
                    500:        case TADDR:
                    501:                putaddr(p, YES);
                    502:                break;
                    503: 
                    504:        case TTEMP:
                    505:                /*
                    506:                 * This type is sometimes passed to putx when errors occur
                    507:                 *      upstream, I don't know why.
                    508:                 */
                    509:                frexpr(p);
                    510:                break;
                    511: 
                    512:        default:
                    513:                badtag("putx", p->tag);
                    514:        }
                    515: }
                    516: 
                    517: 
                    518: 
                    519: LOCAL putop(p)
                    520: expptr p;
                    521: {
                    522: int k;
                    523: expptr lp, tp;
                    524: int pt, lt, tt;
                    525: int comma;
                    526: Addrp putch1();
                    527: 
                    528: switch(p->exprblock.opcode)    /* check for special cases and rewrite */
                    529:        {
                    530:        case OPCONV:
                    531:                tt = pt = p->exprblock.vtype;
                    532:                lp = p->exprblock.leftp;
                    533:                lt = lp->headblock.vtype;
                    534: #if TARGET == VAX
                    535:                if (pt == TYREAL && lt == TYDREAL)
                    536:                        {
                    537:                        putx(lp);
                    538:                        p2op(PCC_SCONV, PCCT_FLOAT);
                    539:                        return;
                    540:                        }
                    541: #endif
                    542:                while(p->tag==TEXPR && p->exprblock.opcode==OPCONV && (
                    543: #if TARGET != TAHOE
                    544:                       (ISREAL(pt)&&ISREAL(lt)) ||
                    545: #endif
                    546:                        (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
                    547:                        {
                    548: #if SZINT < SZLONG
                    549:                        if(lp->tag != TEXPR)
                    550:                                {
                    551:                                if(pt==TYINT && lt==TYLONG)
                    552:                                        break;
                    553:                                if(lt==TYINT && pt==TYLONG)
                    554:                                        break;
                    555:                                }
                    556: #endif
                    557: 
                    558: #if TARGET == VAX
                    559:                        if(pt==TYDREAL && lt==TYREAL)
                    560:                                {
                    561:                                if(lp->tag==TEXPR &&
                    562:                                   lp->exprblock.opcode==OPCONV &&
                    563:                                   lp->exprblock.leftp->headblock.vtype==TYDREAL)
                    564:                                        {
                    565:                                        putx(lp->exprblock.leftp);
                    566:                                        p2op(PCC_SCONV, PCCT_FLOAT);
                    567:                                        p2op(PCC_SCONV, PCCT_DOUBLE);
                    568:                                        free( (charptr) p );
                    569:                                        return;
                    570:                                        }
                    571:                                else break;
                    572:                                }
                    573: #endif
                    574:                        if(lt==TYCHAR && lp->tag==TEXPR)
                    575:                                {
                    576:                                int ncomma = 0;
                    577:                                p->exprblock.leftp = (expptr) putch1(lp, &ncomma);
                    578:                                putop(p);
                    579:                                putcomma(ncomma, pt, NO);
                    580:                                free( (charptr) p );
                    581:                                return;
                    582:                                }
                    583:                        free( (charptr) p );
                    584:                        p = lp;
                    585:                        pt = lt;
                    586:                        if (p->tag == TEXPR)
                    587:                                {
                    588:                                lp = p->exprblock.leftp;
                    589:                                lt = lp->headblock.vtype;
                    590:                                }
                    591:                        }
                    592:                if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
                    593:                        break;
                    594:                putx(p);
                    595:                if (types2[tt] != types2[pt] &&
                    596:                    ! ( (ISREAL(tt)&&ISREAL(pt)) ||
                    597:                        (INT(tt)&&(ONEOF(pt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
                    598:                        p2op(PCC_SCONV,types2[tt]);
                    599:                return;
                    600: 
                    601:        case OPADDR:
                    602:                comma = NO;
                    603:                lp = p->exprblock.leftp;
                    604:                if(lp->tag != TADDR)
                    605:                        {
                    606:                        tp = (expptr) mkaltemp
                    607:                                (lp->headblock.vtype,lp->headblock.vleng);
                    608:                        putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
                    609:                        lp = tp;
                    610:                        comma = YES;
                    611:                        }
                    612:                putaddr(lp, NO);
                    613:                if(comma)
                    614:                        putcomma(1, TYINT, NO);
                    615:                free( (charptr) p );
                    616:                return;
                    617: #if TARGET == VAX || TARGET == TAHOE
                    618: /* take advantage of a glitch in the code generator that does not check
                    619:    the type clash in an assignment or comparison of an integer zero and
                    620:    a floating left operand, and generates optimal code for the correct
                    621:    type.  (The PCC has no floating-constant node to encode this correctly.)
                    622: */
                    623:        case OPASSIGN:
                    624:        case OPLT:
                    625:        case OPLE:
                    626:        case OPGT:
                    627:        case OPGE:
                    628:        case OPEQ:
                    629:        case OPNE:
                    630:                if(ISREAL(p->exprblock.leftp->headblock.vtype) &&
                    631:                   ISREAL(p->exprblock.rightp->headblock.vtype) &&
                    632:                   ISCONST(p->exprblock.rightp) &&
                    633:                   p->exprblock.rightp->constblock.const.cd[0]==0)
                    634:                        {
                    635:                        p->exprblock.rightp->constblock.vtype = TYINT;
                    636:                        p->exprblock.rightp->constblock.const.ci = 0;
                    637:                        }
                    638: #endif
                    639:        }
                    640: 
                    641: if( (k = ops2[p->exprblock.opcode]) <= 0)
                    642:        badop("putop", p->exprblock.opcode);
                    643: putx(p->exprblock.leftp);
                    644: if(p->exprblock.rightp)
                    645:        putx(p->exprblock.rightp);
                    646: p2op(k, types2[p->exprblock.vtype]);
                    647: 
                    648: if(p->exprblock.vleng)
                    649:        frexpr(p->exprblock.vleng);
                    650: free( (charptr) p );
                    651: }
                    652: 
                    653: putforce(t, p)
                    654: int t;
                    655: expptr p;
                    656: {
                    657: p = mkconv(t, fixtype(p));
                    658: putx(p);
                    659: p2op(PCC_FORCE,
                    660: #if TARGET == TAHOE
                    661:        (t==TYLONG ? PCCT_LONG : (t==TYREAL ? PCCT_FLOAT : PCCT_DOUBLE)) );
                    662: #else
                    663:        (t==TYSHORT ? PCCT_SHORT : (t==TYLONG ? PCCT_LONG : PCCT_DOUBLE)) );
                    664: #endif
                    665: putstmt();
                    666: }
                    667: 
                    668: 
                    669: 
                    670: LOCAL putpower(p)
                    671: expptr p;
                    672: {
                    673: expptr base;
                    674: Addrp t1, t2;
                    675: ftnint k;
                    676: int type;
                    677: int ncomma;
                    678: 
                    679: if(!ISICON(p->exprblock.rightp) ||
                    680:     (k = p->exprblock.rightp->constblock.const.ci)<2)
                    681:        fatal("putpower: bad call");
                    682: base = p->exprblock.leftp;
                    683: type = base->headblock.vtype;
                    684: 
                    685: if ((k == 2) && base->tag == TADDR && ISCONST(base->addrblock.memoffset))
                    686: {
                    687:        putx( mkexpr(OPSTAR,cpexpr(base),cpexpr(base)));
                    688:        
                    689:        return;
                    690: }
                    691: t1 = mkaltemp(type, PNULL);
                    692: t2 = NULL;
                    693: ncomma = 1;
                    694: putassign(cpexpr(t1), cpexpr(base) );
                    695: 
                    696: for( ; (k&1)==0 && k>2 ; k>>=1 )
                    697:        {
                    698:        ++ncomma;
                    699:        putsteq(t1, t1);
                    700:        }
                    701: 
                    702: if(k == 2)
                    703:        putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) );
                    704: else
                    705:        {
                    706:        t2 = mkaltemp(type, PNULL);
                    707:        ++ncomma;
                    708:        putassign(cpexpr(t2), cpexpr(t1));
                    709:        
                    710:        for(k>>=1 ; k>1 ; k>>=1)
                    711:                {
                    712:                ++ncomma;
                    713:                putsteq(t1, t1);
                    714:                if(k & 1)
                    715:                        {
                    716:                        ++ncomma;
                    717:                        putsteq(t2, t1);
                    718:                        }
                    719:                }
                    720:        putx( mkexpr(OPSTAR, cpexpr(t2),
                    721:                mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ));
                    722:        }
                    723: putcomma(ncomma, type, NO);
                    724: frexpr(t1);
                    725: if(t2)
                    726:        frexpr(t2);
                    727: frexpr(p);
                    728: }
                    729: 
                    730: 
                    731: 
                    732: 
                    733: LOCAL Addrp intdouble(p, ncommap)
                    734: Addrp p;
                    735: int *ncommap;
                    736: {
                    737: register Addrp t;
                    738: 
                    739: t = mkaltemp(TYDREAL, PNULL);
                    740: ++*ncommap;
                    741: putassign(cpexpr(t), p);
                    742: return(t);
                    743: }
                    744: 
                    745: 
                    746: 
                    747: 
                    748: 
                    749: LOCAL Addrp putcxeq(p)
                    750: register expptr p;
                    751: {
                    752: register Addrp lp, rp;
                    753: int ncomma;
                    754: 
                    755: if(p->tag != TEXPR)
                    756:        badtag("putcxeq", p->tag);
                    757: 
                    758: ncomma = 0;
                    759: lp = putcx1(p->exprblock.leftp, &ncomma);
                    760: rp = putcx1(p->exprblock.rightp, &ncomma);
                    761: putassign(realpart(lp), realpart(rp));
                    762: if( ISCOMPLEX(p->exprblock.vtype) )
                    763:        {
                    764:        ++ncomma;
                    765:        putassign(imagpart(lp), imagpart(rp));
                    766:        }
                    767: putcomma(ncomma, TYREAL, NO);
                    768: frexpr(rp);
                    769: free( (charptr) p );
                    770: return(lp);
                    771: }
                    772: 
                    773: 
                    774: 
                    775: LOCAL putcxop(p)
                    776: expptr p;
                    777: {
                    778: Addrp putcx1();
                    779: int ncomma;
                    780: 
                    781: ncomma = 0;
                    782: putaddr( putcx1(p, &ncomma), NO);
                    783: putcomma(ncomma, TYINT, NO);
                    784: }
                    785: 
                    786: 
                    787: 
                    788: LOCAL Addrp putcx1(p, ncommap)
                    789: register expptr p;
                    790: int *ncommap;
                    791: {
                    792: expptr q;
                    793: Addrp lp, rp;
                    794: register Addrp resp;
                    795: int opcode;
                    796: int ltype, rtype;
                    797: expptr mkrealcon();
                    798: 
                    799: if(p == NULL)
                    800:        return(NULL);
                    801: 
                    802: switch(p->tag)
                    803:        {
                    804:        case TCONST:
                    805:                if( ISCOMPLEX(p->constblock.vtype) )
                    806:                        p = (expptr) putconst(p);
                    807:                return( (Addrp) p );
                    808: 
                    809:        case TADDR:
                    810:                if( ! addressable(p) )
                    811:                        {
                    812:                        ++*ncommap;
                    813:                        resp = mkaltemp(tyint, PNULL);
                    814:                        putassign( cpexpr(resp), p->addrblock.memoffset );
                    815:                        p->addrblock.memoffset = (expptr)resp;
                    816:                        }
                    817:                return( (Addrp) p );
                    818: 
                    819:        case TEXPR:
                    820:                if( ISCOMPLEX(p->exprblock.vtype) )
                    821:                        break;
                    822:                ++*ncommap;
                    823:                resp = mkaltemp(TYDREAL, NO);
                    824:                putassign( cpexpr(resp), p);
                    825:                return(resp);
                    826: 
                    827:        default:
                    828:                badtag("putcx1", p->tag);
                    829:        }
                    830: 
                    831: opcode = p->exprblock.opcode;
                    832: if(opcode==OPCALL || opcode==OPCCALL)
                    833:        {
                    834:        ++*ncommap;
                    835:        return( putcall(p) );
                    836:        }
                    837: else if(opcode == OPASSIGN)
                    838:        {
                    839:        ++*ncommap;
                    840:        return( putcxeq(p) );
                    841:        }
                    842: resp = mkaltemp(p->exprblock.vtype, PNULL);
                    843: if(lp = putcx1(p->exprblock.leftp, ncommap) )
                    844:        ltype = lp->vtype;
                    845: if(rp = putcx1(p->exprblock.rightp, ncommap) )
                    846:        rtype = rp->vtype;
                    847: 
                    848: switch(opcode)
                    849:        {
                    850:        case OPPAREN:
                    851:                frexpr (resp);
                    852:                resp = lp;
                    853:                lp = NULL;
                    854:                break;
                    855: 
                    856:        case OPCOMMA:
                    857:                frexpr(resp);
                    858:                resp = rp;
                    859:                rp = NULL;
                    860:                break;
                    861: 
                    862:        case OPNEG:
                    863:                putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), ENULL) );
                    864:                putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), ENULL) );
                    865:                *ncommap += 2;
                    866:                break;
                    867: 
                    868:        case OPPLUS:
                    869:        case OPMINUS:
                    870:                putassign( realpart(resp),
                    871:                        mkexpr(opcode, realpart(lp), realpart(rp) ));
                    872:                if(rtype < TYCOMPLEX)
                    873:                        putassign( imagpart(resp), imagpart(lp) );
                    874:                else if(ltype < TYCOMPLEX)
                    875:                        {
                    876:                        if(opcode == OPPLUS)
                    877:                                putassign( imagpart(resp), imagpart(rp) );
                    878:                        else    putassign( imagpart(resp),
                    879:                                        mkexpr(OPNEG, imagpart(rp), ENULL) );
                    880:                        }
                    881:                else
                    882:                        putassign( imagpart(resp),
                    883:                                mkexpr(opcode, imagpart(lp), imagpart(rp) ));
                    884: 
                    885:                *ncommap += 2;
                    886:                break;
                    887: 
                    888:        case OPSTAR:
                    889:                if(ltype < TYCOMPLEX)
                    890:                        {
                    891:                        if( ISINT(ltype) )
                    892:                                lp = intdouble(lp, ncommap);
                    893:                        putassign( realpart(resp),
                    894:                                mkexpr(OPSTAR, cpexpr(lp), realpart(rp) ));
                    895:                        putassign( imagpart(resp),
                    896:                                mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) ));
                    897:                        }
                    898:                else if(rtype < TYCOMPLEX)
                    899:                        {
                    900:                        if( ISINT(rtype) )
                    901:                                rp = intdouble(rp, ncommap);
                    902:                        putassign( realpart(resp),
                    903:                                mkexpr(OPSTAR, cpexpr(rp), realpart(lp) ));
                    904:                        putassign( imagpart(resp),
                    905:                                mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) ));
                    906:                        }
                    907:                else    {
                    908:                        putassign( realpart(resp), mkexpr(OPMINUS,
                    909:                                mkexpr(OPSTAR, realpart(lp), realpart(rp)),
                    910:                                mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) ));
                    911:                        putassign( imagpart(resp), mkexpr(OPPLUS,
                    912:                                mkexpr(OPSTAR, realpart(lp), imagpart(rp)),
                    913:                                mkexpr(OPSTAR, imagpart(lp), realpart(rp)) ));
                    914:                        }
                    915:                *ncommap += 2;
                    916:                break;
                    917: 
                    918:        case OPSLASH:
                    919:                /* fixexpr has already replaced all divisions
                    920:                 * by a complex by a function call
                    921:                 */
                    922:                if( ISINT(rtype) )
                    923:                        rp = intdouble(rp, ncommap);
                    924:                putassign( realpart(resp),
                    925:                        mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) );
                    926:                putassign( imagpart(resp),
                    927:                        mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) );
                    928:                *ncommap += 2;
                    929:                break;
                    930: 
                    931:        case OPCONV:
                    932:                putassign( realpart(resp), realpart(lp) );
                    933:                if( ISCOMPLEX(lp->vtype) )
                    934:                        q = imagpart(lp);
                    935:                else if(rp != NULL)
                    936:                        q = (expptr) realpart(rp);
                    937:                else
                    938:                        q = mkrealcon(TYDREAL, 0.0);
                    939:                putassign( imagpart(resp), q);
                    940:                *ncommap += 2;
                    941:                break;
                    942: 
                    943:        default:
                    944:                badop("putcx1", opcode);
                    945:        }
                    946: 
                    947: frexpr(lp);
                    948: frexpr(rp);
                    949: free( (charptr) p );
                    950: return(resp);
                    951: }
                    952: 
                    953: 
                    954: 
                    955: 
                    956: LOCAL putcxcmp(p)
                    957: register expptr p;
                    958: {
                    959: int opcode;
                    960: int ncomma;
                    961: register Addrp lp, rp;
                    962: expptr q;
                    963: 
                    964: if(p->tag != TEXPR)
                    965:        badtag("putcxcmp", p->tag);
                    966: 
                    967: ncomma = 0;
                    968: opcode = p->exprblock.opcode;
                    969: lp = putcx1(p->exprblock.leftp, &ncomma);
                    970: rp = putcx1(p->exprblock.rightp, &ncomma);
                    971: 
                    972: q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
                    973:        mkexpr(opcode, realpart(lp), realpart(rp)),
                    974:        mkexpr(opcode, imagpart(lp), imagpart(rp)) );
                    975: putx( fixexpr(q) );
                    976: putcomma(ncomma, TYINT, NO);
                    977: 
                    978: free( (charptr) lp);
                    979: free( (charptr) rp);
                    980: free( (charptr) p );
                    981: }
                    982: 
                    983: LOCAL Addrp putch1(p, ncommap)
                    984: register expptr p;
                    985: int * ncommap;
                    986: {
                    987: register Addrp t;
                    988: 
                    989: switch(p->tag)
                    990:        {
                    991:        case TCONST:
                    992:                return( putconst(p) );
                    993: 
                    994:        case TADDR:
                    995:                return( (Addrp) p );
                    996: 
                    997:        case TEXPR:
                    998:                ++*ncommap;
                    999: 
                   1000:                switch(p->exprblock.opcode)
                   1001:                        {
                   1002:                        expptr q;
                   1003: 
                   1004:                        case OPCALL:
                   1005:                        case OPCCALL:
                   1006:                                t = putcall(p);
                   1007:                                break;
                   1008: 
                   1009:                        case OPPAREN:
                   1010:                                --*ncommap;
                   1011:                                t = putch1(p->exprblock.leftp, ncommap);
                   1012:                                break;
                   1013: 
                   1014:                        case OPCONCAT:
                   1015:                                t = mkaltemp(TYCHAR, ICON(lencat(p)) );
                   1016:                                q = (expptr) cpexpr(p->headblock.vleng);
                   1017:                                putcat( cpexpr(t), p );
                   1018:                                /* put the correct length on the block */
                   1019:                                frexpr(t->vleng);
                   1020:                                t->vleng = q;
                   1021: 
                   1022:                                break;
                   1023: 
                   1024:                        case OPCONV:
                   1025:                                if(!ISICON(p->exprblock.vleng)
                   1026:                                   || p->exprblock.vleng->constblock.const.ci!=1
                   1027:                                   || ! INT(p->exprblock.leftp->headblock.vtype) )
                   1028:                                        fatal("putch1: bad character conversion");
                   1029:                                t = mkaltemp(TYCHAR, ICON(1) );
                   1030:                                putop( mkexpr(OPASSIGN, cpexpr(t), p) );
                   1031:                                break;
                   1032:                        default:
                   1033:                                badop("putch1", p->exprblock.opcode);
                   1034:                        }
                   1035:                return(t);
                   1036: 
                   1037:        default:
                   1038:                badtag("putch1", p->tag);
                   1039:        }
                   1040: /* NOTREACHED */
                   1041: }
                   1042: 
                   1043: 
                   1044: 
                   1045: 
                   1046: LOCAL putchop(p)
                   1047: expptr p;
                   1048: {
                   1049: int ncomma;
                   1050: 
                   1051: ncomma = 0;
                   1052: putaddr( putch1(p, &ncomma) , NO );
                   1053: putcomma(ncomma, TYCHAR, YES);
                   1054: }
                   1055: 
                   1056: 
                   1057: 
                   1058: 
                   1059: LOCAL putcheq(p)
                   1060: register expptr p;
                   1061: {
                   1062: int ncomma;
                   1063: expptr lp, rp;
                   1064: 
                   1065: if(p->tag != TEXPR)
                   1066:        badtag("putcheq", p->tag);
                   1067: 
                   1068: ncomma = 0;
                   1069: lp = p->exprblock.leftp;
                   1070: rp = p->exprblock.rightp;
                   1071: if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
                   1072:        putcat(lp, rp);
                   1073: else if( ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
                   1074:        {
                   1075:        putaddr( putch1(lp, &ncomma) , YES );
                   1076:        putaddr( putch1(rp, &ncomma) , YES );
                   1077:        putcomma(ncomma, TYINT, NO);
                   1078:        p2op(PCC_ASSIGN, PCCT_CHAR);
                   1079:        }
                   1080: else
                   1081:        {
                   1082:        putx( call2(TYINT, "s_copy", lp, rp) );
                   1083:        putcomma(ncomma, TYINT, NO);
                   1084:        }
                   1085: 
                   1086: frexpr(p->exprblock.vleng);
                   1087: free( (charptr) p );
                   1088: }
                   1089: 
                   1090: 
                   1091: 
                   1092: 
                   1093: LOCAL putchcmp(p)
                   1094: register expptr p;
                   1095: {
                   1096: int ncomma;
                   1097: expptr lp, rp;
                   1098: 
                   1099: if(p->tag != TEXPR)
                   1100:        badtag("putchcmp", p->tag);
                   1101: 
                   1102: ncomma = 0;
                   1103: lp = p->exprblock.leftp;
                   1104: rp = p->exprblock.rightp;
                   1105: 
                   1106: if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
                   1107:        {
                   1108:        putaddr( putch1(lp, &ncomma) , YES );
                   1109:        putcomma(ncomma, TYINT, NO);
                   1110:        ncomma = 0;
                   1111:        putaddr( putch1(rp, &ncomma) , YES );
                   1112:        putcomma(ncomma, TYINT, NO);
                   1113:        p2op(ops2[p->exprblock.opcode], PCCT_CHAR);
                   1114:        free( (charptr) p );
                   1115:        }
                   1116: else
                   1117:        {
                   1118:        p->exprblock.leftp = call2(TYINT,"s_cmp", lp, rp);
                   1119:        p->exprblock.rightp = ICON(0);
                   1120:        putop(p);
                   1121:        }
                   1122: }
                   1123: 
                   1124: 
                   1125: 
                   1126: 
                   1127: 
                   1128: LOCAL putcat(lhs, rhs)
                   1129: register Addrp lhs;
                   1130: register expptr rhs;
                   1131: {
                   1132: int n, ncomma;
                   1133: Addrp lp, cp;
                   1134: 
                   1135: ncomma = 0;
                   1136: n = ncat(rhs);
                   1137: lp = mkaltmpn(n, TYLENG, PNULL);
                   1138: cp = mkaltmpn(n, TYADDR, PNULL);
                   1139: 
                   1140: n = 0;
                   1141: putct1(rhs, lp, cp, &n, &ncomma);
                   1142: 
                   1143: putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) );
                   1144: putcomma(ncomma, TYINT, NO);
                   1145: }
                   1146: 
                   1147: 
                   1148: 
                   1149: 
                   1150: 
                   1151: LOCAL putct1(q, lp, cp, ip, ncommap)
                   1152: register expptr q;
                   1153: register Addrp lp, cp;
                   1154: int *ip, *ncommap;
                   1155: {
                   1156: int i;
                   1157: Addrp lp1, cp1;
                   1158: 
                   1159: if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
                   1160:        {
                   1161:        putct1(q->exprblock.leftp, lp, cp, ip, ncommap);
                   1162:        putct1(q->exprblock.rightp, lp, cp , ip, ncommap);
                   1163:        frexpr(q->exprblock.vleng);
                   1164:        free( (charptr) q );
                   1165:        }
                   1166: else
                   1167:        {
                   1168:        i = (*ip)++;
                   1169:        lp1 = (Addrp) cpexpr(lp);
                   1170:        lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG));
                   1171:        cp1 = (Addrp) cpexpr(cp);
                   1172:        cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR));
                   1173:        putassign( lp1, cpexpr(q->headblock.vleng) );
                   1174:        putassign( cp1, addrof(putch1(q,ncommap)) );
                   1175:        *ncommap += 2;
                   1176:        }
                   1177: }
                   1178: 
                   1179: LOCAL putaddr(p, indir)
                   1180: register Addrp p;
                   1181: int indir;
                   1182: {
                   1183: int type, type2, funct;
                   1184: ftnint offset, simoffset();
                   1185: expptr offp, shorten();
                   1186: 
                   1187: if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
                   1188:        {
                   1189:        frexpr(p);
                   1190:        return;
                   1191:        }
                   1192: if (p->tag != TADDR) badtag ("putaddr",p->tag);
                   1193: 
                   1194: type = p->vtype;
                   1195: type2 = types2[type];
                   1196: funct = (p->vclass==CLPROC ? PCCTM_FTN<<2 : 0);
                   1197: 
                   1198: offp = (p->memoffset ? (expptr) cpexpr(p->memoffset) : (expptr)NULL );
                   1199: 
                   1200: 
                   1201: #if (FUDGEOFFSET != 1)
                   1202: if(offp)
                   1203:        offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp);
                   1204: #endif
                   1205: 
                   1206: offset = simoffset( &offp );
                   1207: #if SZINT < SZLONG
                   1208:        if(offp)
                   1209:                if(shortsubs)
                   1210:                        offp = shorten(offp);
                   1211:                else
                   1212:                        offp = mkconv(TYINT, offp);
                   1213: #else
                   1214:        if(offp)
                   1215:                offp = mkconv(TYINT, offp);
                   1216: #endif
                   1217: 
                   1218: if (p->vclass == CLVAR
                   1219:     && (p->vstg == STGBSS || p->vstg == STGEQUIV)
                   1220:     && SMALLVAR(p->varsize)
                   1221:     && offset >= -32768 && offset <= 32767)
                   1222:   {
                   1223:     anylocals = YES;
                   1224:     if (indir && !offp)
                   1225:       p2ldisp(offset, memname(p->vstg, p->memno), type2);
                   1226:     else
                   1227:       {
                   1228:        p2reg(LVARREG, type2 | PCCTM_PTR);
                   1229:        p2triple(PCC_ICON, 1, PCCT_INT);
                   1230:        p2word(offset);
                   1231:        p2ndisp(memname(p->vstg, p->memno));
                   1232:        p2op(PCC_PLUS, type2 | PCCTM_PTR);
                   1233:        if (offp)
                   1234:          {
                   1235:            putx(offp);
                   1236:            p2op(PCC_PLUS, type2 | PCCTM_PTR);
                   1237:          }
                   1238:        if (indir)
                   1239:          p2op(PCC_DEREF, type2);
                   1240:       }
                   1241:     frexpr((tagptr) p);
                   1242:     return;
                   1243:   }
                   1244: 
                   1245: switch(p->vstg)
                   1246:        {
                   1247:        case STGAUTO:
                   1248:                if(indir && !offp)
                   1249:                        {
                   1250:                        p2oreg(offset, AUTOREG, type2);
                   1251:                        break;
                   1252:                        }
                   1253: 
                   1254:                if(!indir && !offp && !offset)
                   1255:                        {
                   1256:                        p2reg(AUTOREG, type2 | PCCTM_PTR);
                   1257:                        break;
                   1258:                        }
                   1259: 
                   1260:                p2reg(AUTOREG, type2 | PCCTM_PTR);
                   1261:                if(offp)
                   1262:                        {
                   1263:                        putx(offp);
                   1264:                        if(offset)
                   1265:                                p2icon(offset, PCCT_INT);
                   1266:                        }
                   1267:                else
                   1268:                        p2icon(offset, PCCT_INT);
                   1269:                if(offp && offset)
                   1270:                        p2op(PCC_PLUS, type2 | PCCTM_PTR);
                   1271:                p2op(PCC_PLUS, type2 | PCCTM_PTR);
                   1272:                if(indir)
                   1273:                        p2op(PCC_DEREF, type2);
                   1274:                break;
                   1275: 
                   1276:        case STGARG:
                   1277:                p2oreg(
                   1278: #ifdef ARGOFFSET
                   1279:                        ARGOFFSET +
                   1280: #endif
                   1281:                        (ftnint) (FUDGEOFFSET*p->memno),
                   1282:                        ARGREG,   type2 | PCCTM_PTR | funct );
                   1283: 
                   1284:        based:
                   1285:                if(offset)
                   1286:                        {
                   1287:                        p2icon(offset, PCCT_INT);
                   1288:                        p2op(PCC_PLUS, type2 | PCCTM_PTR);
                   1289:                        }
                   1290:                if(offp)
                   1291:                        {
                   1292:                        putx(offp);
                   1293:                        p2op(PCC_PLUS, type2 | PCCTM_PTR);
                   1294:                        }
                   1295:                if(indir)
                   1296:                        p2op(PCC_DEREF, type2);
                   1297:                break;
                   1298: 
                   1299:        case STGLENG:
                   1300:                if(indir)
                   1301:                        {
                   1302:                        p2oreg(
                   1303: #ifdef ARGOFFSET
                   1304:                                ARGOFFSET +
                   1305: #endif
                   1306:                                (ftnint) (FUDGEOFFSET*p->memno),
                   1307:                                ARGREG,   type2 );
                   1308:                        }
                   1309:                else    {
                   1310:                        p2reg(ARGREG, type2 | PCCTM_PTR );
                   1311:                        p2icon(
                   1312: #ifdef ARGOFFSET
                   1313:                                ARGOFFSET +
                   1314: #endif
                   1315:                                (ftnint) (FUDGEOFFSET*p->memno), PCCT_INT);
                   1316:                        p2op(PCC_PLUS, type2 | PCCTM_PTR );
                   1317:                        }
                   1318:                break;
                   1319: 
                   1320: 
                   1321:        case STGBSS:
                   1322:        case STGINIT:
                   1323:        case STGEXT:
                   1324:        case STGINTR:
                   1325:        case STGCOMMON:
                   1326:        case STGEQUIV:
                   1327:        case STGCONST:
                   1328:                if(offp)
                   1329:                        {
                   1330:                        putx(offp);
                   1331:                        putmem(p, PCC_ICON, offset);
                   1332:                        p2op(PCC_PLUS, type2 | PCCTM_PTR);
                   1333:                        if(indir)
                   1334:                                p2op(PCC_DEREF, type2);
                   1335:                        }
                   1336:                else
                   1337:                        putmem(p, (indir ? PCC_NAME : PCC_ICON), offset);
                   1338: 
                   1339:                break;
                   1340: 
                   1341:        case STGREG:
                   1342:                if(indir)
                   1343:                        p2reg(p->memno, type2);
                   1344:                else
                   1345:                        fatal("attempt to take address of a register");
                   1346:                break;
                   1347: 
                   1348:        case STGPREG:
                   1349:                if(indir && !offp)
                   1350:                        p2oreg(offset, p->memno, type2);
                   1351:                else
                   1352:                        {
                   1353:                        p2reg(p->memno, type2 | PCCTM_PTR);
                   1354:                        goto based;
                   1355:                        }
                   1356:                break;
                   1357: 
                   1358:        default:
                   1359:                badstg("putaddr", p->vstg);
                   1360:        }
                   1361: frexpr(p);
                   1362: }
                   1363: 
                   1364: 
                   1365: 
                   1366: 
                   1367: LOCAL putmem(p, class, offset)
                   1368: expptr p;
                   1369: int class;
                   1370: ftnint offset;
                   1371: {
                   1372: int type2;
                   1373: int funct;
                   1374: char *name,  *memname();
                   1375: 
                   1376: funct = (p->headblock.vclass==CLPROC ? PCCTM_FTN<<2 : 0);
                   1377: type2 = types2[p->headblock.vtype];
                   1378: if(p->headblock.vclass == CLPROC)
                   1379:        type2 |= (PCCTM_FTN<<2);
                   1380: name = memname(p->addrblock.vstg, p->addrblock.memno);
                   1381: if(class == PCC_ICON)
                   1382:        {
                   1383:        p2triple(PCC_ICON, name[0]!='\0', type2|PCCTM_PTR);
                   1384:        p2word(offset);
                   1385:        if(name[0])
                   1386:                p2name(name);
                   1387:        }
                   1388: else
                   1389:        {
                   1390:        p2triple(PCC_NAME, offset!=0, type2);
                   1391:        if(offset != 0)
                   1392:                p2word(offset);
                   1393:        p2name(name);
                   1394:        }
                   1395: }
                   1396: 
                   1397: 
                   1398: 
                   1399: LOCAL Addrp putcall(p)
                   1400: register Exprp p;
                   1401: {
                   1402: chainp arglist, charsp, cp;
                   1403: int n, first;
                   1404: Addrp t;
                   1405: register expptr q;
                   1406: Addrp fval, mkargtemp();
                   1407: int type, type2, ctype, qtype, indir;
                   1408: 
                   1409: type2 = types2[type = p->vtype];
                   1410: charsp = NULL;
                   1411: indir =  (p->opcode == OPCCALL);
                   1412: n = 0;
                   1413: first = YES;
                   1414: 
                   1415: if(p->rightp)
                   1416:        {
                   1417:        arglist = p->rightp->listblock.listp;
                   1418:        free( (charptr) (p->rightp) );
                   1419:        }
                   1420: else
                   1421:        arglist = NULL;
                   1422: 
                   1423: for(cp = arglist ; cp ; cp = cp->nextp)
                   1424:        {
                   1425:        q = (expptr) cp->datap;
                   1426:        if(indir)
                   1427:                ++n;
                   1428:        else    {
                   1429:                q = (expptr) (cp->datap);
                   1430:                if( ISCONST(q) )
                   1431:                        {
                   1432:                        q = (expptr) putconst(q);
                   1433:                        cp->datap = (tagptr) q;
                   1434:                        }
                   1435:                if( ISCHAR(q) && q->headblock.vclass!=CLPROC )
                   1436:                        {
                   1437:                        charsp = hookup(charsp,
                   1438:                                        mkchain(cpexpr(q->headblock.vleng),
                   1439:                                                CHNULL));
                   1440:                        n += 2;
                   1441:                        }
                   1442:                else
                   1443:                        n += 1;
                   1444:                }
                   1445:        }
                   1446: 
                   1447: if(type == TYCHAR)
                   1448:        {
                   1449:        if( ISICON(p->vleng) )
                   1450:                {
                   1451:                fval = mkargtemp(TYCHAR, p->vleng);
                   1452:                n += 2;
                   1453:                }
                   1454:        else    {
                   1455:                err("adjustable character function");
                   1456:                return;
                   1457:                }
                   1458:        }
                   1459: else if( ISCOMPLEX(type) )
                   1460:        {
                   1461:        fval = mkargtemp(type, PNULL);
                   1462:        n += 1;
                   1463:        }
                   1464: else
                   1465:        fval = NULL;
                   1466: 
                   1467: ctype = (fval ? PCCT_INT : type2);
                   1468: putaddr(p->leftp, NO);
                   1469: 
                   1470: if(fval)
                   1471:        {
                   1472:        first = NO;
                   1473:        putaddr( cpexpr(fval), NO);
                   1474:        if(type==TYCHAR)
                   1475:                {
                   1476:                putx( mkconv(TYLENG,p->vleng) );
                   1477:                p2op(PCC_CM, type2);
                   1478:                }
                   1479:        }
                   1480: 
                   1481: for(cp = arglist ; cp ; cp = cp->nextp)
                   1482:        {
                   1483:        q = (expptr) (cp->datap);
                   1484:        if(q->tag==TADDR && (indir || q->addrblock.vstg!=STGREG) )
                   1485:                putaddr(q, indir && q->addrblock.vtype!=TYCHAR);
                   1486:        else if( ISCOMPLEX(q->headblock.vtype) )
                   1487:                putcxop(q);
                   1488:        else if (ISCHAR(q) )
                   1489:                putchop(q);
                   1490:        else if( ! ISERROR(q) )
                   1491:                {
                   1492:                if(indir)
                   1493:                        putx(q);
                   1494:                else    {
                   1495:                        t = mkargtemp(qtype = q->headblock.vtype,
                   1496:                                q->headblock.vleng);
                   1497:                        putassign( cpexpr(t), q );
                   1498:                        putaddr(t, NO);
                   1499:                        putcomma(1, qtype, YES);
                   1500:                        }
                   1501:                }
                   1502:        if(first)
                   1503:                first = NO;
                   1504:        else
                   1505:                p2op(PCC_CM, type2);
                   1506:        }
                   1507: 
                   1508: if(arglist)
                   1509:        frchain(&arglist);
                   1510: for(cp = charsp ; cp ; cp = cp->nextp)
                   1511:        {
                   1512:        putx( mkconv(TYLENG,cp->datap) );
                   1513:        p2op(PCC_CM, type2);
                   1514:        }
                   1515: frchain(&charsp);
                   1516: #if TARGET == TAHOE
                   1517: if(indir && ctype==PCCT_FLOAT) /* function opcodes */
                   1518:        p2op(PCC_FORTCALL, ctype);
                   1519: else
                   1520: #endif
                   1521: p2op(n>0 ? PCC_CALL : PCC_UCALL , ctype);
                   1522: free( (charptr) p );
                   1523: return(fval);
                   1524: }
                   1525: 
                   1526: 
                   1527: 
                   1528: LOCAL putmnmx(p)
                   1529: register expptr p;
                   1530: {
                   1531: int op, type;
                   1532: int ncomma;
                   1533: expptr qp;
                   1534: chainp p0, p1;
                   1535: Addrp sp, tp;
                   1536: 
                   1537: if(p->tag != TEXPR)
                   1538:        badtag("putmnmx", p->tag);
                   1539: 
                   1540: type = p->exprblock.vtype;
                   1541: op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT );
                   1542: p0 = p->exprblock.leftp->listblock.listp;
                   1543: free( (charptr) (p->exprblock.leftp) );
                   1544: free( (charptr) p );
                   1545: 
                   1546: sp = mkaltemp(type, PNULL);
                   1547: tp = mkaltemp(type, PNULL);
                   1548: qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp));
                   1549: qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp);
                   1550: qp = fixexpr(qp);
                   1551: 
                   1552: ncomma = 1;
                   1553: putassign( cpexpr(sp), p0->datap );
                   1554: 
                   1555: for(p1 = p0->nextp ; p1 ; p1 = p1->nextp)
                   1556:        {
                   1557:        ++ncomma;
                   1558:        putassign( cpexpr(tp), p1->datap );
                   1559:        if(p1->nextp)
                   1560:                {
                   1561:                ++ncomma;
                   1562:                putassign( cpexpr(sp), cpexpr(qp) );
                   1563:                }
                   1564:        else
                   1565:                putx(qp);
                   1566:        }
                   1567: 
                   1568: putcomma(ncomma, type, NO);
                   1569: frexpr(sp);
                   1570: frexpr(tp);
                   1571: frchain( &p0 );
                   1572: }
                   1573: 
                   1574: 
                   1575: 
                   1576: 
                   1577: LOCAL putcomma(n, type, indir)
                   1578: int n, type, indir;
                   1579: {
                   1580: type = types2[type];
                   1581: if(indir)
                   1582:        type |= PCCTM_PTR;
                   1583: while(--n >= 0)
                   1584:        p2op(PCC_COMOP, type);
                   1585: }
                   1586: 
                   1587: 
                   1588: 
                   1589: 
                   1590: ftnint simoffset(p0)
                   1591: expptr *p0;
                   1592: {
                   1593: ftnint offset, prod;
                   1594: register expptr p, lp, rp;
                   1595: 
                   1596: offset = 0;
                   1597: p = *p0;
                   1598: if(p == NULL)
                   1599:        return(0);
                   1600: 
                   1601: if( ! ISINT(p->headblock.vtype) )
                   1602:        return(0);
                   1603: 
                   1604: if(p->tag==TEXPR && p->exprblock.opcode==OPSTAR)
                   1605:        {
                   1606:        lp = p->exprblock.leftp;
                   1607:        rp = p->exprblock.rightp;
                   1608:        if(ISICON(rp) && lp->tag==TEXPR &&
                   1609:           lp->exprblock.opcode==OPPLUS && ISICON(lp->exprblock.rightp))
                   1610:                {
                   1611:                p->exprblock.opcode = OPPLUS;
                   1612:                lp->exprblock.opcode = OPSTAR;
                   1613:                prod = rp->constblock.const.ci *
                   1614:                        lp->exprblock.rightp->constblock.const.ci;
                   1615:                lp->exprblock.rightp->constblock.const.ci = rp->constblock.const.ci;
                   1616:                rp->constblock.const.ci = prod;
                   1617:                }
                   1618:        }
                   1619: 
                   1620: if(p->tag==TEXPR && p->exprblock.opcode==OPPLUS &&
                   1621:     ISICON(p->exprblock.rightp))
                   1622:        {
                   1623:        rp = p->exprblock.rightp;
                   1624:        lp = p->exprblock.leftp;
                   1625:        offset += rp->constblock.const.ci;
                   1626:        frexpr(rp);
                   1627:        free( (charptr) p );
                   1628:        *p0 = lp;
                   1629:        }
                   1630: 
                   1631: if( ISCONST(p) )
                   1632:        {
                   1633:        offset += p->constblock.const.ci;
                   1634:        frexpr(p);
                   1635:        *p0 = NULL;
                   1636:        }
                   1637: 
                   1638: return(offset);
                   1639: }
                   1640: 
                   1641: 
                   1642: 
                   1643: 
                   1644: 
                   1645: p2op(op, type)
                   1646: int op, type;
                   1647: {
                   1648: p2triple(op, 0, type);
                   1649: }
                   1650: 
                   1651: p2icon(offset, type)
                   1652: ftnint offset;
                   1653: int type;
                   1654: {
                   1655: p2triple(PCC_ICON, 0, type);
                   1656: p2word(offset);
                   1657: }
                   1658: 
                   1659: 
                   1660: 
                   1661: 
                   1662: p2oreg(offset, reg, type)
                   1663: ftnint offset;
                   1664: int reg, type;
                   1665: {
                   1666: p2triple(PCC_OREG, reg, type);
                   1667: p2word(offset);
                   1668: p2name("");
                   1669: }
                   1670: 
                   1671: 
                   1672: 
                   1673: 
                   1674: p2reg(reg, type)
                   1675: int reg, type;
                   1676: {
                   1677: p2triple(PCC_REG, reg, type);
                   1678: }
                   1679: 
                   1680: 
                   1681: 
                   1682: p2pi(s, i)
                   1683: char *s;
                   1684: int i;
                   1685: {
                   1686: char buff[100];
                   1687: sprintf(buff, s, i);
                   1688: p2pass(buff);
                   1689: }
                   1690: 
                   1691: 
                   1692: 
                   1693: p2pij(s, i, j)
                   1694: char *s;
                   1695: int i, j;
                   1696: {
                   1697: char buff[100];
                   1698: sprintf(buff, s, i, j);
                   1699: p2pass(buff);
                   1700: }
                   1701: 
                   1702: 
                   1703: 
                   1704: 
                   1705: p2ps(s, t)
                   1706: char *s, *t;
                   1707: {
                   1708: char buff[100];
                   1709: sprintf(buff, s, t);
                   1710: p2pass(buff);
                   1711: }
                   1712: 
                   1713: 
                   1714: 
                   1715: 
                   1716: p2pass(s)
                   1717: char *s;
                   1718: {
                   1719: p2triple(PCCF_FTEXT, (strlen(s) + ALILONG-1)/ALILONG, 0);
                   1720: p2str(s);
                   1721: }
                   1722: 
                   1723: 
                   1724: 
                   1725: 
                   1726: p2str(s)
                   1727: register char *s;
                   1728: {
                   1729: union { long int word; char str[SZLONG]; } u;
                   1730: register int i;
                   1731: 
                   1732: i = 0;
                   1733: u.word = 0;
                   1734: while(*s)
                   1735:        {
                   1736:        u.str[i++] = *s++;
                   1737:        if(i == SZLONG)
                   1738:                {
                   1739:                p2word(u.word);
                   1740:                u.word = 0;
                   1741:                i = 0;
                   1742:                }
                   1743:        }
                   1744: if(i > 0)
                   1745:        p2word(u.word);
                   1746: }
                   1747: 
                   1748: 
                   1749: 
                   1750: 
                   1751: p2triple(op, var, type)
                   1752: int op, var, type;
                   1753: {
                   1754: register long word;
                   1755: word = PCCM_TRIPLE(op, var, type);
                   1756: p2word(word);
                   1757: }
                   1758: 
                   1759: 
                   1760: 
                   1761: 
                   1762: 
                   1763: p2name(s)
                   1764: register char *s;
                   1765: {
                   1766: register int i;
                   1767: 
                   1768: #ifdef UCBPASS2
                   1769:        /* arbitrary length names, terminated by a null,
                   1770:           padded to a full word */
                   1771: 
                   1772: #      define WL   sizeof(long int)
                   1773:        union { long int word; char str[WL]; } w;
                   1774:        
                   1775:        w.word = 0;
                   1776:        i = 0;
                   1777:        while(w.str[i++] = *s++)
                   1778:                if(i == WL)
                   1779:                        {
                   1780:                        p2word(w.word);
                   1781:                        w.word = 0;
                   1782:                        i = 0;
                   1783:                        }
                   1784:        if(i > 0)
                   1785:                p2word(w.word);
                   1786: #else
                   1787:        /* standard intermediate, names are 8 characters long */
                   1788: 
                   1789:        union  { long int word[2];  char str[8]; } u;
                   1790:        
                   1791:        u.word[0] = u.word[1] = 0;
                   1792:        for(i = 0 ; i<8 && *s ; ++i)
                   1793:                u.str[i] = *s++;
                   1794:        p2word(u.word[0]);
                   1795:        p2word(u.word[1]);
                   1796: 
                   1797: #endif
                   1798: 
                   1799: }
                   1800: 
                   1801: 
                   1802: 
                   1803: 
                   1804: p2word(w)
                   1805: long int w;
                   1806: {
                   1807: *p2bufp++ = w;
                   1808: if(p2bufp >= p2bufend)
                   1809:        p2flush();
                   1810: }
                   1811: 
                   1812: 
                   1813: 
                   1814: p2flush()
                   1815: {
                   1816: if(p2bufp > p2buff)
                   1817:        write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int));
                   1818: p2bufp = p2buff;
                   1819: }
                   1820: 
                   1821: 
                   1822: 
                   1823: LOCAL
                   1824: p2ldisp(offset, vname, type)
                   1825: ftnint offset;
                   1826: char *vname;
                   1827: int type;
                   1828: {
                   1829:   char buff[100];
                   1830: 
                   1831:   sprintf(buff, "%s-v.%d", vname, bsslabel);
                   1832:   p2triple(PCC_OREG, LVARREG, type);
                   1833:   p2word(offset);
                   1834:   p2name(buff);
                   1835: }
                   1836: 
                   1837: 
                   1838: 
                   1839: p2ndisp(vname)
                   1840: char *vname;
                   1841: {
                   1842:   char buff[100];
                   1843: 
                   1844:   sprintf(buff, "%s-v.%d", vname, bsslabel);
                   1845:   p2name(buff);
                   1846: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.