Annotation of researchv10no/cmd/f2c/put.c, revision 1.1

1.1     ! root        1: /****************************************************************
        !             2: Copyright 1990, 1991, 1993 by AT&T Bell Laboratories and Bellcore.
        !             3: 
        !             4: Permission to use, copy, modify, and distribute this software
        !             5: and its documentation for any purpose and without fee is hereby
        !             6: granted, provided that the above copyright notice appear in all
        !             7: copies and that both that the copyright notice and this
        !             8: permission notice and warranty disclaimer appear in supporting
        !             9: documentation, and that the names of AT&T Bell Laboratories or
        !            10: Bellcore or any of their entities not be used in advertising or
        !            11: publicity pertaining to distribution of the software without
        !            12: specific, written prior permission.
        !            13: 
        !            14: AT&T and Bellcore disclaim all warranties with regard to this
        !            15: software, including all implied warranties of merchantability
        !            16: and fitness.  In no event shall AT&T or Bellcore be liable for
        !            17: any special, indirect or consequential damages or any damages
        !            18: whatsoever resulting from loss of use, data or profits, whether
        !            19: in an action of contract, negligence or other tortious action,
        !            20: arising out of or in connection with the use or performance of
        !            21: this software.
        !            22: ****************************************************************/
        !            23: 
        !            24: /*
        !            25:  * INTERMEDIATE CODE GENERATION PROCEDURES COMMON TO BOTH
        !            26:  * JOHNSON (PORTABLE) AND RITCHIE FAMILIES OF SECOND PASSES
        !            27: */
        !            28: 
        !            29: #include "defs.h"
        !            30: #include "names.h"             /* For LOCAL_CONST_NAME */
        !            31: #include "pccdefs.h"
        !            32: #include "p1defs.h"
        !            33: 
        !            34: /* Definitions for   putconst()   */
        !            35: 
        !            36: #define LIT_CHAR 1
        !            37: #define LIT_FLOAT 2
        !            38: #define LIT_INT 3
        !            39: 
        !            40: 
        !            41: /*
        !            42: char *ops [ ] =
        !            43:        {
        !            44:        "??", "+", "-", "*", "/", "**", "-",
        !            45:        "OR", "AND", "EQV", "NEQV", "NOT",
        !            46:        "CONCAT",
        !            47:        "<", "==", ">", "<=", "!=", ">=",
        !            48:        " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
        !            49:        " , ", " ? ", " : "
        !            50:        " abs ", " min ", " max ", " addr ", " indirect ",
        !            51:        " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ",
        !            52:        };
        !            53: */
        !            54: 
        !            55: /* Each of these values is defined in   pccdefs   */
        !            56: 
        !            57: int ops2 [ ] =
        !            58: {
        !            59:        P2BAD, P2PLUS, P2MINUS, P2STAR, P2SLASH, P2BAD, P2NEG,
        !            60:        P2OROR, P2ANDAND, P2EQ, P2NE, P2NOT,
        !            61:        P2BAD,
        !            62:        P2LT, P2EQ, P2GT, P2LE, P2NE, P2GE,
        !            63:        P2CALL, P2CALL, P2ASSIGN, P2PLUSEQ, P2STAREQ, P2CONV, P2LSHIFT, P2MOD,
        !            64:        P2COMOP, P2QUEST, P2COLON,
        !            65:        1, P2BAD, P2BAD, P2BAD, P2BAD,
        !            66:        P2BITOR, P2BITAND, P2BITXOR, P2BITNOT, P2RSHIFT,
        !            67:        P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD,
        !            68:        P2BAD, P2BAD, P2BAD, P2BAD,
        !            69:        1,1,1,1,1, /* OPNEG1, OPDMIN, OPDMAX, OPASSIGNI, OPIDENTITY */
        !            70:        1,1,1,1 /* OPCHARCAST, OPDABS, OPMIN2, OPMAX2 */
        !            71: };
        !            72: 
        !            73: 
        !            74: setlog()
        !            75: {
        !            76:        typesize[TYLOGICAL] = typesize[tylogical];
        !            77:        typealign[TYLOGICAL] = typealign[tylogical];
        !            78: }
        !            79: 
        !            80: 
        !            81: putexpr(p)
        !            82: expptr p;
        !            83: {
        !            84: /* Write the expression to the p1 file */
        !            85: 
        !            86:        p = (expptr) putx (fixtype (p));
        !            87:        p1_expr (p);
        !            88: }
        !            89: 
        !            90: 
        !            91: 
        !            92: 
        !            93: 
        !            94: expptr putassign(lp, rp)
        !            95: expptr lp, rp;
        !            96: {
        !            97:        return putx(fixexpr((Exprp)mkexpr(OPASSIGN, lp, rp)));
        !            98: }
        !            99: 
        !           100: 
        !           101: 
        !           102: 
        !           103: void puteq(lp, rp)
        !           104: expptr lp, rp;
        !           105: {
        !           106:        putexpr(mkexpr(OPASSIGN, lp, rp) );
        !           107: }
        !           108: 
        !           109: 
        !           110: 
        !           111: 
        !           112: /* put code for  a *= b */
        !           113: 
        !           114: expptr putsteq(a, b)
        !           115: Addrp a, b;
        !           116: {
        !           117:        return putx( fixexpr((Exprp)
        !           118:                mkexpr(OPSTAREQ, cpexpr((expptr)a), cpexpr((expptr)b))));
        !           119: }
        !           120: 
        !           121: 
        !           122: 
        !           123: 
        !           124: Addrp mkfield(res, f, ty)
        !           125: register Addrp res;
        !           126: char *f;
        !           127: int ty;
        !           128: {
        !           129:     res -> vtype = ty;
        !           130:     res -> Field = f;
        !           131:     return res;
        !           132: } /* mkfield */
        !           133: 
        !           134: 
        !           135: Addrp realpart(p)
        !           136: register Addrp p;
        !           137: {
        !           138:        register Addrp q;
        !           139:        expptr mkrealcon();
        !           140: 
        !           141:        if (p->tag == TADDR
        !           142:         && p->uname_tag == UNAM_CONST
        !           143:         && ISCOMPLEX (p->vtype))
        !           144:                return (Addrp)mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
        !           145:                        p->user.kludge.vstg1 ? p->user.Const.cds[0]
        !           146:                                : cds(dtos(p->user.Const.cd[0]),CNULL));
        !           147: 
        !           148:        q = (Addrp) cpexpr((expptr) p);
        !           149:        if( ISCOMPLEX(p->vtype) )
        !           150:                q = mkfield (q, "r", p -> vtype + TYREAL - TYCOMPLEX);
        !           151: 
        !           152:        return(q);
        !           153: }
        !           154: 
        !           155: 
        !           156: 
        !           157: 
        !           158: expptr imagpart(p)
        !           159: register Addrp p;
        !           160: {
        !           161:        register Addrp q;
        !           162:        expptr mkrealcon();
        !           163: 
        !           164:        if( ISCOMPLEX(p->vtype) )
        !           165:        {
        !           166:                if (p->tag == TADDR && p->uname_tag == UNAM_CONST)
        !           167:                        return mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
        !           168:                                p->user.kludge.vstg1 ? p->user.Const.cds[1]
        !           169:                                : cds(dtos(p->user.Const.cd[1]),CNULL));
        !           170:                q = (Addrp) cpexpr((expptr) p);
        !           171:                q = mkfield (q, "i", p -> vtype + TYREAL - TYCOMPLEX);
        !           172:                return( (expptr) q );
        !           173:        }
        !           174:        else
        !           175: 
        !           176: /* Cast an integer type onto a Double Real type */
        !           177: 
        !           178:                return( mkrealcon( ISINT(p->vtype) ? TYDREAL : p->vtype , "0"));
        !           179: }
        !           180: 
        !           181: 
        !           182: 
        !           183: 
        !           184: 
        !           185: /* ncat -- computes the number of adjacent concatenation operations */
        !           186: 
        !           187: ncat(p)
        !           188: register expptr p;
        !           189: {
        !           190:        if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
        !           191:                return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
        !           192:        else    return(1);
        !           193: }
        !           194: 
        !           195: 
        !           196: 
        !           197: 
        !           198: /* lencat -- returns the length of the concatenated string.  Each
        !           199:    substring must have a static (i.e. compile-time) fixed length */
        !           200: 
        !           201: ftnint lencat(p)
        !           202: register expptr p;
        !           203: {
        !           204:        if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
        !           205:                return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
        !           206:        else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
        !           207:                return(p->headblock.vleng->constblock.Const.ci);
        !           208:        else if(p->tag==TADDR && p->addrblock.varleng!=0)
        !           209:                return(p->addrblock.varleng);
        !           210:        else
        !           211:        {
        !           212:                err("impossible element in concatenation");
        !           213:                return(0);
        !           214:        }
        !           215: }
        !           216: 
        !           217: /* putconst -- Creates a new Addrp value which maps onto the input
        !           218:    constant value.  The Addrp doesn't retain the value of the constant,
        !           219:    instead that value is copied into a table of constants (called
        !           220:    litpool,   for pool of literal values).  The only way to retrieve the
        !           221:    actual value of the constant is to look at the   memno   field of the
        !           222:    Addrp result.  You know that the associated literal is the one referred
        !           223:    to by   q   when   (q -> memno == litp -> litnum).
        !           224: */
        !           225: 
        !           226: Addrp putconst(p)
        !           227: register Constp p;
        !           228: {
        !           229:        register Addrp q;
        !           230:        struct Literal *litp, *lastlit;
        !           231:        int k, len, type;
        !           232:        int litflavor;
        !           233:        double cd[2];
        !           234:        ftnint nblanks;
        !           235:        char *strp;
        !           236:        char cdsbuf0[64], cdsbuf1[64], *ds[2];
        !           237: 
        !           238:        if (p->tag != TCONST)
        !           239:                badtag("putconst", p->tag);
        !           240: 
        !           241:        q = ALLOC(Addrblock);
        !           242:        q->tag = TADDR;
        !           243:        type = p->vtype;
        !           244:        q->vtype = ( type==TYADDR ? tyint : type );
        !           245:        q->vleng = (expptr) cpexpr(p->vleng);
        !           246:        q->vstg = STGCONST;
        !           247: 
        !           248: /* Create the new label for the constant.  This is wasteful of labels
        !           249:    because when the constant value already exists in the literal pool,
        !           250:    this label gets thrown away and is never reclaimed.  It might be
        !           251:    cleaner to move this down past the first   switch()   statement below */
        !           252: 
        !           253:        q->memno = newlabel();
        !           254:        q->memoffset = ICON(0);
        !           255:        q -> uname_tag = UNAM_CONST;
        !           256: 
        !           257: /* Copy the constant info into the Addrblock; do this by copying the
        !           258:    largest storage elts */
        !           259: 
        !           260:        q -> user.Const = p -> Const;
        !           261:        q->user.kludge.vstg1 = p->vstg; /* distinguish string from binary fp */
        !           262: 
        !           263:        /* check for value in literal pool, and update pool if necessary */
        !           264: 
        !           265:        k = 1;
        !           266:        switch(type)
        !           267:        {
        !           268:        case TYCHAR:
        !           269:                if (halign) {
        !           270:                        strp = p->Const.ccp;
        !           271:                        nblanks = p->Const.ccp1.blanks;
        !           272:                        len = p->vleng->constblock.Const.ci;
        !           273:                        litflavor = LIT_CHAR;
        !           274:                        goto loop;
        !           275:                        }
        !           276:                else
        !           277:                        q->memno = BAD_MEMNO;
        !           278:                break;
        !           279:        case TYCOMPLEX:
        !           280:        case TYDCOMPLEX:
        !           281:                k = 2;
        !           282:                if (p->vstg)
        !           283:                        cd[1] = atof(ds[1] = p->Const.cds[1]);
        !           284:                else
        !           285:                        ds[1] = cds(dtos(cd[1] = p->Const.cd[1]), cdsbuf1);
        !           286:        case TYREAL:
        !           287:        case TYDREAL:
        !           288:                litflavor = LIT_FLOAT;
        !           289:                if (p->vstg)
        !           290:                        cd[0] = atof(ds[0] = p->Const.cds[0]);
        !           291:                else
        !           292:                        ds[0] = cds(dtos(cd[0] = p->Const.cd[0]), cdsbuf0);
        !           293:                goto loop;
        !           294: 
        !           295:        case TYLOGICAL1:
        !           296:        case TYLOGICAL2:
        !           297:        case TYLOGICAL:
        !           298:                type = tylogical;
        !           299:                goto lit_int_flavor;
        !           300:        case TYLONG:
        !           301:                type = tyint;
        !           302:        case TYSHORT:
        !           303:        case TYINT1:
        !           304: #ifdef TYQUAD
        !           305:        case TYQUAD:
        !           306: #endif
        !           307:  lit_int_flavor:
        !           308:                litflavor = LIT_INT;
        !           309: 
        !           310: /* Scan the literal pool for this constant value.  If this same constant
        !           311:    has been assigned before, use the same label.  Note that this routine
        !           312:    does NOT consider two differently-typed constants with the same bit
        !           313:    pattern to be the same constant */
        !           314: 
        !           315:  loop:
        !           316:                lastlit = litpool + nliterals;
        !           317:                for(litp = litpool ; litp<lastlit ; ++litp)
        !           318: 
        !           319: /* Remove this type checking to ensure that all bit patterns are reused */
        !           320: 
        !           321:                        if(type == litp->littype) switch(litflavor)
        !           322:                        {
        !           323:                        case LIT_CHAR:
        !           324:                                if (len == (int)litp->litval.litival2[0]
        !           325:                                && nblanks == litp->litval.litival2[1]
        !           326:                                && !memcmp(strp, litp->cds[0], len)) {
        !           327:                                        q->memno = litp->litnum;
        !           328:                                        frexpr((expptr)p);
        !           329:                                        q->user.Const.ccp1.ccp0 = litp->cds[0];
        !           330:                                        return(q);
        !           331:                                        }
        !           332:                                break;
        !           333:                        case LIT_FLOAT:
        !           334:                                if(cd[0] == litp->litval.litdval[0]
        !           335:                                && !strcmp(ds[0], litp->cds[0])
        !           336:                                && (k == 1 ||
        !           337:                                    cd[1] == litp->litval.litdval[1]
        !           338:                                    && !strcmp(ds[1], litp->cds[1]))) {
        !           339: ret:
        !           340:                                        q->memno = litp->litnum;
        !           341:                                        frexpr((expptr)p);
        !           342:                                        return(q);
        !           343:                                        }
        !           344:                                break;
        !           345: 
        !           346:                        case LIT_INT:
        !           347:                                if(p->Const.ci == litp->litval.litival)
        !           348:                                        goto ret;
        !           349:                                break;
        !           350:                        }
        !           351: 
        !           352: /* If there's room in the literal pool, add this new value to the pool */
        !           353: 
        !           354:                if(nliterals < maxliterals)
        !           355:                {
        !           356:                        ++nliterals;
        !           357: 
        !           358:                        /* litp   now points to the next free elt */
        !           359: 
        !           360:                        litp->littype = type;
        !           361:                        litp->litnum = q->memno;
        !           362:                        switch(litflavor)
        !           363:                        {
        !           364:                        case LIT_CHAR:
        !           365:                                litp->litval.litival2[0] = len;
        !           366:                                litp->litval.litival2[1] = nblanks;
        !           367:                                q->user.Const.ccp = litp->cds[0] =
        !           368:                                        memcpy(gmem(len,0), strp, len);
        !           369:                                break;
        !           370: 
        !           371:                        case LIT_FLOAT:
        !           372:                                litp->litval.litdval[0] = cd[0];
        !           373:                                litp->cds[0] = copys(ds[0]);
        !           374:                                if (k == 2) {
        !           375:                                        litp->litval.litdval[1] = cd[1];
        !           376:                                        litp->cds[1] = copys(ds[1]);
        !           377:                                        }
        !           378:                                break;
        !           379: 
        !           380:                        case LIT_INT:
        !           381:                                litp->litval.litival = p->Const.ci;
        !           382:                                break;
        !           383:                        } /* switch (litflavor) */
        !           384:                }
        !           385:                else
        !           386:                        many("literal constants", 'L', maxliterals);
        !           387: 
        !           388:                break;
        !           389:        case TYADDR:
        !           390:            break;
        !           391:        default:
        !           392:                badtype ("putconst", p -> vtype);
        !           393:                break;
        !           394:        } /* switch */
        !           395: 
        !           396:        if (type != TYCHAR || halign)
        !           397:            frexpr((expptr)p);
        !           398:        return( q );
        !           399: }

unix.superglobalmegacorp.com

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