Annotation of coherent/b/bin/c/n0/i8086/bind.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This file contains the machine-specific parts of the parser.
        !             3:  * It is used in both the SMALL and the LARGE models of segmentation.
        !             4:  */
        !             5: #ifdef   vax
        !             6: #include "INC$LIB:cc0.h"
        !             7: #else
        !             8: #include "cc0.h"
        !             9: #endif
        !            10: 
        !            11: typedef        struct  locals  {
        !            12:        struct  locals *l_lstp;
        !            13:        int     l_lofs;
        !            14:        int     l_mask;
        !            15: }      LOCALS;
        !            16: 
        !            17: LOCALS *clstp;                 /* Local stack */
        !            18: int    clofs;                  /* Current local offset */
        !            19: int    cmask;                  /* Current mask */
        !            20: int    llofs;                  /* Last local offset reported */
        !            21: int    lmask;                  /* Last register mask reported */
        !            22: int    lastword = T_PTR;       /* Last 16 bit type */
        !            23: char   inbtr[]  = "identifier \"%s\" not bound to register";
        !            24: 
        !            25: /*
        !            26:  * This table is indexed by C type to obtain the size
        !            27:  * in bytes of a machine object.
        !            28:  * The T_PTR entry is 2; this is for ONLYSMALL.
        !            29:  * The entry is patched based on the model.
        !            30:  */
        !            31: int     mysizes[] = {
        !            32:        0,
        !            33:        1,      1,
        !            34:        2,      2,
        !            35:        2,      2,
        !            36:        2,
        !            37:        4,      4,
        !            38:        4,      8,
        !            39:        0,
        !            40:        0,      0,
        !            41:        0,      0,
        !            42:        0,      0
        !            43: };
        !            44: 
        !            45: /*
        !            46:  * This table is indexed by C type to obtain the machine type,
        !            47:  * as defined in 'mch.h'.
        !            48:  */
        !            49: char    mytypes[] = {
        !            50:        0,
        !            51:        S8,     U8,
        !            52:        S16,    U16,
        !            53:        S16,    U16,
        !            54:        SPTR,
        !            55:        S32,    U32,
        !            56:        F32,    F64,
        !            57:        S16,
        !            58:        BLK,    0,
        !            59:        BLK,    0,
        !            60:        0,      0
        !            61: };
        !            62: 
        !            63: /*
        !            64:  * main() calls this routine to perform machine-dependent setup.
        !            65:  * On the i8086, it changes the size of a pointer and some other things
        !            66:  * that alter the allocation of register variables.
        !            67:  */
        !            68: vinit()
        !            69: {
        !            70: #if !ONLYSMALL
        !            71:        lastword = T_PTR;
        !            72:        mysizes[T_PTR] = 2;
        !            73:        mytypes[T_PTR] = SPTR;
        !            74:        if (notvariant(VSMALL)) {
        !            75:                lastword = T_UINT;
        !            76:                mysizes[T_PTR] = 4;
        !            77:                mytypes[T_PTR] = LPTR;
        !            78:        }
        !            79: #endif
        !            80: }
        !            81: 
        !            82: /*
        !            83:  * Empty the local binding stack and mark the registers usable
        !            84:  * for register variables (SI and DI) as available.
        !            85:  */
        !            86: initlocals()
        !            87: {
        !            88:        clstp = NULL;
        !            89:        clofs = 0;
        !            90:        cmask = BCS|BSS|BSP|BBP;
        !            91:        llofs = 0;
        !            92:        lmask = BCS|BSS|BSP|BBP;
        !            93:        bput(AUTOS);
        !            94:        iput((ival_t)clofs);
        !            95:        iput((ival_t)cmask);
        !            96: }
        !            97: 
        !            98: /*
        !            99:  * Save the current state of the local bindings.
        !           100:  */
        !           101: savelocals()
        !           102: {
        !           103:        register LOCALS *lstp;
        !           104: 
        !           105:        lstp = (LOCALS *) new(sizeof(LOCALS));
        !           106:        lstp->l_lstp = clstp;
        !           107:        lstp->l_lofs = clofs;
        !           108:        lstp->l_mask = cmask;
        !           109:        clstp = lstp;
        !           110: }
        !           111: 
        !           112: /*
        !           113:  * Restore locals.  Tell the code generator if it changes.
        !           114:  */
        !           115: restlocals()
        !           116: {
        !           117:        register LOCALS *lstp;
        !           118: 
        !           119:        if ((lstp=clstp) == NULL)
        !           120:                cbotch("restlocals");
        !           121:        clstp = lstp->l_lstp;
        !           122:        clofs = lstp->l_lofs;
        !           123:        cmask = lstp->l_mask;
        !           124:        putautos();
        !           125:        free((char *) lstp);
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * Bind locals to the correct place on the stack frame.
        !           130:  * Where things end up is a function of the model of compilation.
        !           131:  */
        !           132: bindlocal(sp)
        !           133: register SYM   *sp;
        !           134: {
        !           135:        register int    c, regno;
        !           136: 
        !           137:        if ((c=sp->s_class) == C_REG) {
        !           138:                if ((regno=grabreg(sp)) >= 0) {
        !           139:                        sp->s_value = regno;
        !           140:                        return;
        !           141:                }
        !           142:                sp->s_class = C_AUTO;
        !           143:                if (isvariant(VSNREG))
        !           144:                        cstrict(inbtr, sp->s_id);
        !           145:        }
        !           146:        if (c==C_AUTO || c==C_REG) {
        !           147:                clofs -= ssize(sp);
        !           148: #if    OMF286
        !           149:                /*
        !           150:                 * The 80287 does not function properly for arguments
        !           151:                 * on odd boundaries.
        !           152:                 * The OMF286 compiler therefore rounds up the offsets
        !           153:                 * of autos to keep them on even boundaries;
        !           154:                 * however, char and unsigned char autos are not word-aligned.
        !           155:                 * The compiler driver must also setvariant(VALIGN) to keep
        !           156:                 * the stack word-aligned.
        !           157:                 * fieldalign() should also keep structure members
        !           158:                 * on word boundaries within the struct, but it does not;
        !           159:                 * this is a kludge to maintain compatability with PL/M-286,
        !           160:                 * which does not word-align structure members.
        !           161:                 * The UDI interface routines fail if structure members
        !           162:                 * are forced to word boundaries.
        !           163:                 */
        !           164:                if (ssize(sp) != 1 && (clofs & 1) != 0)
        !           165:                        --clofs;
        !           166: #endif
        !           167:                sp->s_value = clofs;
        !           168:                if (clofs >= 0)
        !           169:                        cerror("auto \"%s\" is not addressable", sp->s_id);
        !           170:        }
        !           171: }
        !           172: 
        !           173: /*
        !           174:  * Attempt to get a register for symbol 'sp'.
        !           175:  * Only word things go in registers;
        !           176:  * this includes pointers in SMALL model.
        !           177:  */
        !           178: grabreg(sp)
        !           179: register SYM   *sp;
        !           180: {
        !           181:        register DIM    *dp;
        !           182:        register int    type;
        !           183: 
        !           184:        if ((dp=sp->s_dp) != NULL) {
        !           185: #if !ONLYSMALL
        !           186:                if (isvariant(VSMALL)) {
        !           187: #endif
        !           188:                        if (dp->d_type == D_PTR) {
        !           189:                                if ((cmask&BSI) == 0) {
        !           190:                                        cmask |= BSI;
        !           191:                                        return (SI);
        !           192:                                }
        !           193:                                if ((cmask&BDI) == 0) {
        !           194:                                        cmask |= BDI;
        !           195:                                        return (DI);
        !           196:                                }
        !           197:                        }
        !           198: #if !ONLYSMALL
        !           199:                }
        !           200: #endif
        !           201:                return (-1);
        !           202:        }
        !           203:        type = sp->s_type;
        !           204:        if (type>=T_SHORT && type<=lastword) {
        !           205:                if ((cmask&BSI) == 0) {
        !           206:                        cmask |= BSI;
        !           207:                        return (SI);
        !           208:                }
        !           209:                if ((cmask&BDI) == 0) {
        !           210:                        cmask |= BDI;
        !           211:                        return (DI);
        !           212:                }
        !           213:        }
        !           214:        return (-1);
        !           215: }
        !           216: 
        !           217: /*
        !           218:  * Bind arguments.
        !           219:  */
        !           220: bindargs()
        !           221: {
        !           222:        register SYM    *sp;
        !           223:        register int    i;
        !           224:        register sizeof_t offset;
        !           225: 
        !           226: #if !ONLYSMALL
        !           227:        if (isvariant(VSMALL))
        !           228:                offset = 8;
        !           229:        else
        !           230:                offset = 10;
        !           231: #else
        !           232:        offset = 8;
        !           233: #endif
        !           234:        for (i=0; i<nargs; ++i) {
        !           235:                sp = args[i];
        !           236:                if (sp->s_class != C_PREG)
        !           237:                        sp->s_class = C_PAUTO;
        !           238:                sp->s_value = offset;
        !           239:                offset += ssize(sp);
        !           240:                if (isvariant(VALIGN) && (offset & 1) != 0)
        !           241:                        ++offset;
        !           242:                if ((short)offset != offset)
        !           243:                    cerror("parameter \"%s\" is not addressible", sp->s_id);
        !           244:        }
        !           245: }
        !           246: 
        !           247: /*
        !           248:  * Copy register arguments from the stack into the register.
        !           249:  * Change class of the argument to plain register.
        !           250:  * Note that bindargs() has put the stack displacement
        !           251:  * into the 's_value' field of the argument symbol.
        !           252:  */
        !           253: loadargs()
        !           254: {
        !           255:        register SYM    *sp;
        !           256:        register int    i, r, v;
        !           257: 
        !           258:        for (i=0; i<nargs; ++i) {
        !           259:                sp = args[i];
        !           260:                if (sp->s_class == C_PREG) {
        !           261:                        if ((r=grabreg(sp)) >= 0) {
        !           262:                                v = sp->s_value;
        !           263:                                sp->s_class = C_REG;
        !           264:                                sp->s_value = r;
        !           265:                                loadreg(sp, v);
        !           266:                                continue;
        !           267:                        }
        !           268:                        sp->s_class = C_PAUTO;
        !           269:                        if (isvariant(VSNREG))
        !           270:                                cstrict(inbtr, sp->s_id);
        !           271:                }
        !           272:        }
        !           273: }
        !           274: 
        !           275: /*
        !           276:  * Load symbol 'sp' from offset 'offset' in the frame.
        !           277:  * Since register variables are always words,
        !           278:  * the type can always be setup to T_INT.
        !           279:  */
        !           280: loadreg(sp, offset)
        !           281: SYM    *sp;
        !           282: {
        !           283:        register TREE   *lp, *rp, *tp;
        !           284: 
        !           285:        newtree(sizeof(TREE));
        !           286:        lp = talloc();
        !           287:        lp->t_op = REG;
        !           288:        lp->t_type = T_INT;
        !           289:        lp->t_reg = sp->s_value;
        !           290:        rp = talloc();
        !           291:        rp->t_op = PID;
        !           292:        rp->t_type = T_INT;
        !           293:        rp->t_offs = offset;
        !           294:        tp = build(ASSIGN, lp, rp);
        !           295:        putautos();
        !           296:        tput(EEXPR, 0, tp);
        !           297: }
        !           298: 
        !           299: /*
        !           300:  * Inform the code generator (and perhaps the optimizer)
        !           301:  * about the current automatic variable allocation.
        !           302:  * Keep the stack word-aligned if isvariant(VALIGN).
        !           303:  */
        !           304: putautos()
        !           305: {
        !           306:        if (clofs != llofs || cmask != lmask) {
        !           307:                if (isvariant(VALIGN) && (clofs & 1) != 0)
        !           308:                        --clofs;
        !           309:                llofs = clofs;
        !           310:                lmask = cmask;
        !           311:                bput(AUTOS);
        !           312:                iput((ival_t)-clofs);
        !           313:                iput((ival_t)cmask);
        !           314:        }
        !           315: }
        !           316: 
        !           317: /*
        !           318:  * Look at type 't', DIM list 'dp' and field width 'w' (0 for non fields)
        !           319:  * and return the bit offset of the base of the structure member.
        !           320:  * The 'offset' argument is the current bit offset in the structure or union.
        !           321:  * Check for fields that are too wide, bad field base types, and arrange
        !           322:  * that the byte or word that spans the field can be grabbed in one grab.
        !           323:  * See comments in bindlocal() above concerning reals and bitfield alignment.
        !           324:  */
        !           325: long
        !           326: fieldalign(t, dp, ip, w, offset)
        !           327: register DIM   *dp;
        !           328: INFO           *ip;
        !           329: register int   w;
        !           330: long           offset;
        !           331: {
        !           332:        register int    maxwidth;
        !           333: 
        !           334:        if (w != 0) {                                   /* nonzero width */
        !           335:                if (dp != 0)
        !           336:                        cerror("non scalar field");
        !           337:                if ((maxwidth=8*mysizes[t]) > 16)       /* 8 for char, 16 for int */
        !           338:                        cerror("bad base type for field");
        !           339:                if (w > maxwidth)
        !           340:                        cerror("field too wide");
        !           341:                if ((offset&7)+w > maxwidth)
        !           342:                        offset = (offset+7) & ~7L;
        !           343:        } else {                                        /* zero width */
        !           344:                offset = (offset+7) & ~7L;
        !           345:        }
        !           346:        return (offset);
        !           347: }
        !           348: 
        !           349: /*
        !           350:  * Convert a tree into its low level form.
        !           351:  * Fill in the machine type byte looking at the C type
        !           352:  * and the segment information.
        !           353:  */
        !           354: TREE *
        !           355: transform(tp, why, above)
        !           356: register TREE  *tp;
        !           357: {
        !           358:        register TREE   *lp;
        !           359:        register int    t;
        !           360:        register int    wd;
        !           361: 
        !           362:        /*
        !           363:         * The way that this code looks at the DIM lists to decide
        !           364:         * what type of conversion is inserted makes me sick.
        !           365:         * The correct type of conversion node (MUL, DIV, etc.)
        !           366:         * should really be inserted when the tree is constructed,
        !           367:         * guided by a table.
        !           368:         */
        !           369:        if (tp->t_op == CONVERT) {
        !           370:                lp = tp->t_lp;
        !           371:                if (tp->t_dp!=NULL && lp->t_dp==NULL
        !           372:                &&  why!=REXPR) {
        !           373:                        tp->t_op = MUL;
        !           374:                        tp->t_dp = NULL;
        !           375:                        if (lp->t_type != T_INT)
        !           376:                                tp->t_lp = bconvert(lp, T_INT, NULL,NULL,NULL);
        !           377:                        tp->t_type = T_INT;
        !           378:                } else if (tp->t_dp==NULL && lp->t_dp!=NULL && tp->t_rp!=NULL) {
        !           379:                        tp->t_op = DIV;
        !           380:                        lp->t_dp = NULL;
        !           381:                        lp->t_type = T_INT;
        !           382:                }
        !           383:        }
        !           384:        /* Fixup any remaining ZCON's */
        !           385:        if (tp->t_op == ZCON) {
        !           386:                tp->t_op = ICON;
        !           387:                if (tp->t_zval > 0xFFFFL)
        !           388:                        cwarn("sizeof truncated to unsigned");
        !           389:                if (tp->t_zval < 0x8000L)
        !           390:                        tp->t_type = T_INT;
        !           391:                tp->t_ival = tp->t_zval;
        !           392:        }
        !           393:        if (tp->t_dp != NULL)
        !           394:                tp->t_type = mytypes[T_PTR];
        !           395:        else if ((t=tp->t_type)==T_FSTRUCT || t==T_FUNION || t==T_FENUM) {
        !           396:                unksize(t, tp->t_ip);
        !           397:                tp->t_type = S16;
        !           398:        } else {
        !           399:                if (t == T_ENUM)
        !           400:                        t = tp->t_ip->i_type;
        !           401:                tp->t_type = mytypes[t];
        !           402:        }
        !           403:        if (tp->t_op >= MIOBASE) {
        !           404:                wd = why;
        !           405:                if (why == REXPR)
        !           406:                        wd = EEXPR;
        !           407:                tp->t_lp = transform(tp->t_lp, wd, tp->t_op);
        !           408:                if (tp->t_op!=FIELD && tp->t_rp!=NULL)
        !           409:                        tp->t_rp = transform(tp->t_rp, wd, -1);
        !           410:                if (tp->t_op==CONVERT && tp->t_rp==NULL) {
        !           411:                        lp = tp->t_lp;
        !           412:                        if (tp->t_type == lp->t_type)
        !           413:                                tp = lp;
        !           414:                }
        !           415:        }
        !           416:        return (tp);
        !           417: }
        !           418: 
        !           419: /*
        !           420:  * Check if the operator 'op', when applied to C types 'lt' and 'rt'
        !           421:  * (which are outputs from tltype(), which means that all pointers
        !           422:  * have been converted to type T_PTR), involves no conversions.
        !           423:  * What this means is that the code generator
        !           424:  * has to be prepared to deal with the type mismatch.
        !           425:  * This code has been edited too many times; I am really
        !           426:  * quite ashamed of the number of bugs that have been
        !           427:  * tracked down to this code. It is no longer amusing.
        !           428:  */
        !           429: noconvert(op, lt, rt)
        !           430: register int   op;
        !           431: register int   lt;
        !           432: register int   rt;
        !           433: {
        !           434:        if (op==ASSIGN || op==CAST || (op>=EQ && op<=ULT)) {
        !           435:                if ((lt>=T_CHAR && lt<=T_UCHAR)
        !           436:                &&  (rt>=T_CHAR && rt<=T_UCHAR))
        !           437:                        return(1);
        !           438:                if ((lt>=T_SHORT && lt<=T_UINT) 
        !           439:                &&  (rt>=T_SHORT && rt<=T_UINT))
        !           440:                        return (1);
        !           441:                if ((lt>=T_LONG  && lt<=T_ULONG)
        !           442:                &&  (rt>=T_LONG  && rt<=T_ULONG))
        !           443:                        return (1);
        !           444:                if (lt==T_PTR && rt==T_PTR)
        !           445:                        return (1);
        !           446: #if !ONLYSMALL
        !           447:                if (notvariant(VSMALL)
        !           448:                &&   op != CAST) {
        !           449:                        if ((lt>=T_SHORT && lt<=T_ULONG)
        !           450:                        &&  (rt>=T_SHORT && rt<=T_ULONG)
        !           451:                        &&  (lt==T_PTR || rt==T_PTR))
        !           452:                                return (1);
        !           453:                } else if (isvariant(VSMALL)) {
        !           454: #endif
        !           455:                        if ((lt>=T_SHORT && lt<=T_PTR)
        !           456:                        &&  (rt>=T_SHORT && rt<=T_PTR))
        !           457:                                return (1);
        !           458: #if !ONLYSMALL
        !           459:                }
        !           460: #endif
        !           461:                if (op==CAST && lt==T_FLOAT && rt==T_DOUBLE)
        !           462:                        return (1);
        !           463:        }
        !           464:        return (0);
        !           465: }
        !           466: 
        !           467: /*
        !           468:  * Put out an ALIGN object of the correct flavor to align
        !           469:  * the location counter well enough for the object to which 'sp' points.
        !           470:  * On the i8086 there is only one type of alignment,
        !           471:  * so the argument is unused.
        !           472:  */
        !           473: align(sp)
        !           474: SYM    *sp;
        !           475: {
        !           476:        bput(ALIGN);
        !           477:        bput(0);
        !           478: }
        !           479: 
        !           480: /*
        !           481:  * Check object sizes for overflow.
        !           482:  */
        !           483: sizeof_t szcheck(n, a, s) sizeof_t n; int a; char *s;
        !           484: {
        !           485:        if (n < 0x10000L)
        !           486:                return n;
        !           487:        if (a == 0 || (n & ~MAXUV) != 0) {
        !           488:                cerror("size of %s too large", s);
        !           489:                return(0);
        !           490:        }
        !           491:        if (isvariant(VSLCON))
        !           492:                cstrict("size of %s overflows fsize_t", s);
        !           493:        return (n);
        !           494: }

unix.superglobalmegacorp.com

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