Annotation of 41BSD/cmd/as/ascode.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1980 Regents of the University of California */
        !             2: static char sccsid[] = "@(#)ascode.c 4.7 11/5/80";
        !             3: #include <stdio.h>
        !             4: #include "as.h"
        !             5: #include "assyms.h"
        !             6: 
        !             7: /*
        !             8:  *     Loader reference types  (plust PCREL) to bytes and lg bytes
        !             9:  */
        !            10: /*             LEN1    LEN1+PC LEN2    LEN2+PC LEN4    LEN4+PC LEN8    LEN8+PC*/
        !            11: int    reflen[] =      /* {LEN*+PCREL} ==> number of bytes */
        !            12: {0,    0,      1,      1,      2,      2,      4,      4,      8,      8};     
        !            13: int    lgreflen[] =    /* {LEN*+PCREL} ==> lg number of bytes */ 
        !            14: {-1,   -1,     0,      0,      1,      1,      2,      2,      3,      3};
        !            15: 
        !            16: /*
        !            17:  *     Sizes to Loader reference types and type flags
        !            18:  */
        !            19: /*0    1       2       3       4       5       6       7       8*/
        !            20: int    len124[] =      /* {1,2,4,8} ==> {LEN1, LEN2, LEN4, LEN8} */
        !            21: {0,    LEN1,   LEN2,   0,      LEN4,   0,      0,      0,      LEN8};
        !            22: char   mod124[] =      /* {1,2,4,8} ==> {bits to construct operands */
        !            23: {0,    0x00,   0x20,   0,      0x40,   0,      0,      0,      0};
        !            24: int    type_124[] =    /* {1,2,4,8} ==> {TYPB, TYPW, TYPL, TYPQ} */
        !            25: {0,     TYPB,  TYPW,    0,      TYPL,   0,      0,      0,      TYPQ};
        !            26: 
        !            27: /*
        !            28:  *     type flags to Loader reference and byte lengths
        !            29:  */
        !            30: /*TYPB TYPW    TYPL    TYPQ    TYPF    TYPD*/
        !            31: int    ty_NORELOC[] =  /* {TYPB..TYPD} ==> {1 if relocation not OK */
        !            32: {0,    0,      0,      1,      1,      1};
        !            33: int    ty_LEN[] =      /* {TYPB..TYPD} ==> {LEN1..LEN8} */
        !            34: {LEN1, LEN2,   LEN4,   LEN8,   LEN4,   LEN8};
        !            35: int    ty_nbyte[] =    /* {TYPB..TYPD} ==> {1,2,4,8} */
        !            36: {1,    2,      4,      8,      4,      8};
        !            37: int    ty_nlg[] =      /* {TYPB..TYPD} ==> lg{1,2,4,8} */
        !            38: {0,    1,      2,      3,      2,      3};
        !            39: 
        !            40: insout(op, ap, nact)
        !            41:        struct arg *ap;
        !            42: {
        !            43:        int             jxxflg;
        !            44:        register        struct  instab  *ip;            /* the instruction */
        !            45:        register        struct  arg     *ap_walk;       /* actual param walk */
        !            46:        register        int     i;
        !            47:        register        int     ap_type;                /* actual param type */
        !            48:        register        int     ap_type_mask;           /* masked actual param */
        !            49:        op &= 0xFF;
        !            50:        jxxflg = nact;
        !            51:        if (nact < 0)
        !            52:                nact = -nact;
        !            53:        if (passno == 1) {
        !            54:            ip = itab[op];
        !            55:            if (nact < ip->i_nargs)
        !            56:                yyerror("Too few arguments");
        !            57:            if (nact > ip->i_nargs) {
        !            58:                yyerror("Too many arguments");
        !            59:                nact = ip->i_nargs;
        !            60:            }
        !            61:            /*
        !            62:             *  Check argument compatability with instruction template
        !            63:             */
        !            64:            for (ap_walk = ap, i = 1; i <= nact; ap_walk++, i++){
        !            65:                ap_type = ap_walk->a_atype;
        !            66:                ap_type_mask = ap_type & AMASK;
        !            67:                /*
        !            68:                 *      The switch value is >> by 3 so that the switch
        !            69:                 *      code is dense, not implemented as a sequence
        !            70:                 *      of branches but implemented as a casel.
        !            71:                 *      In addition, cases ACCI and ACCR are added to force
        !            72:                 *      dense switch code.
        !            73:                 */
        !            74:                switch( ((fetcharg(ip, i-1)) & ACCESSMASK)>>3){ /* type of fp */
        !            75:                case ACCI >> 3:
        !            76:                case ACCR >> 3:
        !            77:                        break;
        !            78:                case ACCB >> 3:
        !            79:                        if ( !((ap_type_mask == AEXP) || (ap_type_mask == AIMM)) ){
        !            80:                                yyerror("arg %d, branch displacement must be an expression",i);
        !            81:                                return;
        !            82:                        }
        !            83:                        break;
        !            84:                case ACCA >> 3:
        !            85:                        switch(ap_type_mask){
        !            86:                        case AREG:      yyerror("arg %d, addressing a register",i);
        !            87:                                        return;
        !            88:                        case AIMM:      if ( !(ap_type & ASTAR) ){
        !            89:                                         yyerror("arg %d, addressing an immediate operand",i);
        !            90:                                         return;
        !            91:                                        }
        !            92:                        }
        !            93:                        break;
        !            94:                case ACCM >> 3:
        !            95:                case ACCW >> 3:
        !            96:                        switch(ap_type_mask){
        !            97:                        case AIMM:      if (!(ap_type&ASTAR)) {
        !            98:                                         yyerror("arg %d, modifying a constant",i);
        !            99:                                         return;
        !           100:                                        }
        !           101:                        }
        !           102:                        break;
        !           103:                }       /* end of the switch on fp_type */
        !           104:                if (ap_type & AINDX) {
        !           105:                        if (ap_walk->a_areg2==0xF) {
        !           106:                                yyerror("arg %d, PC used as index",i);
        !           107:                                return;
        !           108:                        }
        !           109:                        switch(ap_type_mask){
        !           110:                        case AREG:      yyerror("arg %d, indexing the register file",i);
        !           111:                                        return;
        !           112:                        case AIMM:      yyerror("arg %d, indexing a constant",i);
        !           113:                                        return;
        !           114:                        case ADECR:
        !           115:                        case AINCR:     if (ap_walk->a_areg1==ap_walk->a_areg2) {
        !           116:                                                yyerror("arg %d, indexing with modified register",i);
        !           117:                                                return;
        !           118:                                        }
        !           119:                                        break;
        !           120:                        }       /* end of switch on ap_type_mask */
        !           121:                } /* end of AINDX */
        !           122:           }
        !           123:        } /* both passes here */
        !           124:        if (jxxflg < 0)
        !           125:                ijxout(op, ap, nact);
        !           126:        else putins(op, ap, nact);
        !           127: }
        !           128: 
        !           129: extern int d124;
        !           130: 
        !           131: putins(op, ap, n)
        !           132:        /*
        !           133:         *      n had better be positive
        !           134:         */
        !           135:        register struct arg *ap;
        !           136: {
        !           137:        register struct exp     *xp;
        !           138:        register int            argtype;
        !           139:        int                     i;
        !           140:        int                     reloc_how;
        !           141: 
        !           142: #ifdef DEBUG
        !           143:        fflush(stdout);
        !           144: #endif
        !           145:        if (passno == 2)
        !           146:                goto PASS2;
        !           147: 
        !           148:        dotp->e_xvalue += n+1;          /* 1 for the opcode, at least 1 per arg */
        !           149:        for (i=0; i<n; i++,ap++) {      /* some args take more than 1 byte */
        !           150:            argtype = ap->a_atype;
        !           151:            if (argtype & AINDX)
        !           152:                dotp->e_xvalue++;
        !           153:            /*
        !           154:             *  This switch has been fixed by enumerating the no action
        !           155:             *  alternatives (those that have 1 one byte of code)
        !           156:             *  so that a casel instruction is emitted.
        !           157:             */
        !           158:            switch (argtype&~(AINDX|ASTAR)) {
        !           159:                case AREG:
        !           160:                case ABASE:
        !           161:                case ADECR:
        !           162:                case AINCR:
        !           163:                        break;
        !           164:                case AEXP: 
        !           165:                        argtype = fetcharg(itab[op], i);
        !           166:                        if (argtype == ACCB+TYPB)
        !           167:                                break;
        !           168:                        if (argtype==ACCB+TYPW){
        !           169:                                dotp->e_xvalue++;
        !           170:                                break;
        !           171:                        }
        !           172:                        /*
        !           173:                         *      Reduces to PC relative
        !           174:                         */
        !           175:                        dotp->e_xvalue += ap->a_dispsize;
        !           176:                        break;
        !           177:                
        !           178:                case ADISP: 
        !           179:                        xp=ap->a_xp;
        !           180:                        if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){
        !           181:                                dotp->e_xvalue += ap->a_dispsize;
        !           182:                                break;
        !           183:                        }
        !           184:                        if (xp->e_xvalue==0 && !(argtype&ASTAR))
        !           185:                                break;
        !           186:                        dotp->e_xvalue++;
        !           187:                        if ((xp->e_xvalue<MINBYTE) || (xp->e_xvalue>MAXBYTE))
        !           188:                                dotp->e_xvalue++;
        !           189:                        if ((xp->e_xvalue<MINWORD) || (xp->e_xvalue>MAXWORD))
        !           190:                                dotp->e_xvalue += 2;
        !           191:                        break;
        !           192: 
        !           193:                case AIMM: 
        !           194:                        if (ap->a_atype&ASTAR) argtype=TYPL;
        !           195:                        else {
        !           196:                                argtype = fetcharg(itab[op], i);
        !           197:                                if (argtype&ACCA)
        !           198:                                        argtype = TYPL;
        !           199:                                else
        !           200:                                        argtype &= TYPMASK;
        !           201:                                xp = ap->a_xp;
        !           202:                                if (   ((xp->e_xtype&XTYPE)==XABS)
        !           203:                                    && (!(xp->e_xtype&XFORW))
        !           204:                                    && (xp->e_xvalue>=0)
        !           205:                                    && (xp->e_xvalue<=63) 
        !           206:                                    && (xp->e_yvalue == 0)
        !           207:                                    && (argtype != TYPD)
        !           208:                                    && (argtype != TYPF)
        !           209:                                )
        !           210:                                                break;
        !           211:                        }
        !           212:                        switch (argtype) {
        !           213:                        case TYPD:
        !           214:                        case TYPF:
        !           215:                                if (   !(((xp->e_xtype&XTYPE)==XABS)
        !           216:                                    && (!(xp->e_xtype&XFORW))
        !           217:                                    && (slitflt(xp)))
        !           218:                                ){
        !           219:                                /* it is NOT short */
        !           220:                                        dotp->e_xvalue += ((argtype==TYPF)?
        !           221:                                                4 : 8);
        !           222:                                }
        !           223:                                break;
        !           224:                        case TYPQ: 
        !           225:                                dotp->e_xvalue += 8;break;
        !           226:                        case TYPL:
        !           227:                                dotp->e_xvalue += 4;break;
        !           228:                        case TYPW: 
        !           229:                                dotp->e_xvalue += 2;break;
        !           230:                        case TYPB: 
        !           231:                                dotp->e_xvalue += 1;break;
        !           232:                        }       /*end of the switch on argtype*/
        !           233:            }   /*end of the switch on the type*/
        !           234:        }       /*end of looping for all arguments*/
        !           235:        return;
        !           236: 
        !           237: PASS2:
        !           238: 
        !           239: #ifdef UNIX
        !           240:        outb(op); /* the opcode */
        !           241: #endif UNIX
        !           242: #ifdef VMS
        !           243:        *vms_obj_ptr++ = -1; *vms_obj_ptr++ = (char)op;
        !           244:        dotp->e_xvalue += 1;
        !           245: #endif VMS
        !           246: 
        !           247:        for (i=0; i<n; i++,ap++) {/* now for the arguments */
        !           248:                argtype=ap->a_atype;
        !           249:                xp=ap->a_xp;
        !           250:                reloc_how = TYPNONE;
        !           251:                if (argtype&AINDX) {
        !           252: #ifdef UNIX
        !           253:                        { outb(0x40 | ap->a_areg2); }
        !           254: #endif UNIX
        !           255: #ifdef VMS
        !           256:                        { *vms_obj_ptr++ = -1;
        !           257:                          *vms_obj_ptr++ = (0x40 | ap->a_areg2);
        !           258:                          dotp->e_xvalue += 1; }
        !           259: #endif VMS
        !           260:                        argtype &= ~AINDX;
        !           261:                }
        !           262:                if (argtype&ASTAR) {
        !           263:                        ap->a_areg1 |= 0x10;
        !           264:                        argtype &= ~ASTAR;
        !           265:                }
        !           266:                switch (argtype) {
        !           267:                case AREG:              /* %r */
        !           268:                        ap->a_areg1 |= 0x50;
        !           269:                        break; 
        !           270:                case ABASE:             /* (%r) */
        !           271:                        ap->a_areg1 |= 0x60;
        !           272:                        break; 
        !           273:                case ADECR:             /* -(%r) */
        !           274:                        ap->a_areg1 |= 0x70;
        !           275:                        break; 
        !           276:                case AINCR:             /* (%r)+ */
        !           277:                        ap->a_areg1 |= 0x80;
        !           278:                        break;
        !           279:                case AEXP: /* expr */
        !           280:                        argtype = fetcharg(itab[op], i);
        !           281:                        if (argtype == ACCB+TYPB) {
        !           282:                                ap->a_areg1 = argtype = 
        !           283:                                        xp->e_xvalue - (dotp->e_xvalue + 1);
        !           284:                                if (argtype<MINBYTE || argtype>MAXBYTE)
        !           285:                                        yyerror("Branch too far"); break;
        !           286:                        }
        !           287:                        if (argtype == ACCB+TYPW) {
        !           288:                                ap->a_areg1 = argtype = xp->e_xvalue
        !           289:                                        -= dotp->e_xvalue + 2;
        !           290:                                xp->e_xtype = XABS;
        !           291:                                if (argtype<MINWORD || argtype>MAXWORD) 
        !           292:                                        yyerror("Branch too far");
        !           293:                                xp->e_xvalue = argtype>>8;
        !           294:                                reloc_how = TYPB;
        !           295:                                break;
        !           296:                        }
        !           297:                        /* reduces to expr(pc) mode */
        !           298:                        ap->a_areg1 |= (0xAF + mod124[ap->a_dispsize]);
        !           299:                        reloc_how = type_124[ap->a_dispsize] + RELOC_PCREL;
        !           300:                        break;
        !           301:                
        !           302:                case ADISP: /* expr(%r) */
        !           303:                        ap->a_areg1 |= 0xA0;
        !           304:                        if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){
        !           305:                                ap->a_areg1 += mod124[ap->a_dispsize];
        !           306:                                reloc_how = type_124[ap->a_dispsize];
        !           307:                                break;
        !           308:                        }
        !           309:                        if (xp->e_xvalue==0 && !(ap->a_areg1&0x10)) {
        !           310:                                ap->a_areg1 ^= 0xC0;
        !           311:                                break;
        !           312:                        }
        !           313:                        reloc_how = TYPB;
        !           314:                        if ((xp->e_xvalue<MINBYTE) || (xp->e_xvalue>MAXBYTE)){
        !           315:                                ap->a_areg1 += 0x20;
        !           316:                                reloc_how = TYPW;
        !           317:                        }
        !           318:                        if ((xp->e_xvalue<MINWORD) || (xp->e_xvalue>MAXWORD)){
        !           319:                                ap->a_areg1 += 0x20;
        !           320:                                reloc_how = TYPL;
        !           321:                        }
        !           322:                        break;
        !           323:                
        !           324:                case AIMM:  /* $expr */
        !           325:                        if (ap->a_atype&ASTAR)
        !           326:                                argtype=TYPL;
        !           327:                        else {
        !           328:                                argtype = fetcharg(itab[op], i);
        !           329:                                if (argtype&ACCA)
        !           330:                                        argtype=TYPL;
        !           331:                                else
        !           332:                                        argtype &= TYPMASK;
        !           333:                                if (    ( (xp->e_xtype&XTYPE) == XABS) 
        !           334:                                    && !(xp->e_xtype&XFORW)
        !           335:                                    &&  (xp->e_xvalue >= 0)
        !           336:                                    &&  (xp->e_xvalue <= 63)
        !           337:                                    &&  (xp->e_yvalue == 0)
        !           338:                                    &&  (argtype != TYPF)
        !           339:                                    &&  (argtype != TYPD) ) {
        !           340:                                        ap->a_areg1 = xp->e_xvalue;
        !           341:                                        break;
        !           342:                                }
        !           343:                        }
        !           344:                        ap->a_areg1 |= 0x8F;
        !           345:                        reloc_how = argtype;
        !           346:                        if (reloc_how == TYPD || reloc_how == TYPF){
        !           347:                                if (   ((xp->e_xtype&XTYPE)==XABS)
        !           348:                                    && (!(xp->e_xtype&XFORW))
        !           349:                                    && (slitflt(xp))
        !           350:                                ){
        !           351:                                        reloc_how = TYPNONE;
        !           352:                                        ap->a_areg1=extlitflt(xp);
        !           353:                                }
        !           354:                        }       
        !           355:                        break;
        !           356:                
        !           357:                }       /*end of the switch on argtype*/
        !           358:                /*
        !           359:                 *      use the first byte to describe the argument
        !           360:                 */
        !           361: #ifdef UNIX
        !           362:                outb(ap->a_areg1);
        !           363: #endif UNIX
        !           364: #ifdef VMS
        !           365:                *vms_obj_ptr++ = -1; *vms_obj_ptr++ = (char)(ap->a_areg1);
        !           366:                dotp->e_xvalue += 1;
        !           367:                if ((vms_obj_ptr-sobuf) > 400) {
        !           368:                        write(objfil,sobuf,vms_obj_ptr-sobuf);
        !           369:                        vms_obj_ptr=sobuf+1;
        !           370:                }
        !           371: #endif VMS
        !           372:                if (reloc_how != TYPNONE) 
        !           373:                        outrel(xp, reloc_how);
        !           374:        }       /*end of the for to pick up all arguments*/
        !           375: }

unix.superglobalmegacorp.com

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