Annotation of 40BSD/cmd/as/ascode.c, revision 1.1.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.