Annotation of 42BSD/bin/as/ascode.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     Copyright (c) 1982 Regents of the University of California
                      3:  */
                      4: #ifndef lint
                      5: static char sccsid[] = "@(#)ascode.c 4.11 6/30/83";
                      6: #endif not lint
                      7: 
                      8: #include <stdio.h>
                      9: #include "as.h"
                     10: #include "assyms.h"
                     11: 
                     12: insout(opcode, ap, nact)
                     13:        struct  Opcode  opcode;
                     14:        struct  arg     *ap;
                     15:        int     nact;
                     16: {
                     17:        int     jxxflg;
                     18:        reg     struct  instab  *ip;            /* the instruction */
                     19:        reg     struct  arg     *ap_walk;       /* actual param walk */
                     20:        reg     int     i;
                     21:        reg     int     ap_type;                /* actual param type */
                     22:        reg     int     ap_type_mask;           /* masked actual param */
                     23: 
                     24:        jxxflg = nact;
                     25:        if (nact < 0)
                     26:                nact = -nact;
                     27:        if (passno == 1) {
                     28:                if (!(ITABCHECK(opcode)))
                     29:                        panic("Botched reference into itab");
                     30:                ip = ITABFETCH(opcode);
                     31:                if (nact < ip->i_nargs)
                     32:                        yyerror("Too few arguments");
                     33:                if (nact > ip->i_nargs) {
                     34:                        yyerror("Too many arguments");
                     35:                        nact = ip->i_nargs;
                     36:                }
                     37:            /*
                     38:             *  Check argument compatability with instruction template
                     39:             */
                     40:            for (ap_walk = ap, i = 1; i <= nact; ap_walk++, i++){
                     41:                ap_type = ap_walk->a_atype;
                     42:                ap_type_mask = ap_type & AMASK;
                     43:                /*
                     44:                 *      The switch value is >> by TYPLG so that the switch
                     45:                 *      code is dense, not implemented as a sequence
                     46:                 *      of branches but implemented as a casel.
                     47:                 *      In addition, cases ACCI and ACCR are added to force
                     48:                 *      dense switch code.
                     49:                 *      switch on the type of fp
                     50:                 */
                     51:                switch( ((fetcharg(ip, i-1)) & ACCESSMASK) >> TYPLG){
                     52:                case ACCI >> TYPLG:
                     53:                case ACCR >> TYPLG:
                     54:                        break;
                     55:                case ACCB >> TYPLG:
                     56:                        if ( !((ap_type_mask == AEXP) || (ap_type_mask == AIMM)) ){
                     57:                                yyerror("arg %d, branch displacement must be an expression",i);
                     58:                                return;
                     59:                        }
                     60:                        break;
                     61:                case ACCA >> TYPLG:
                     62:                        switch(ap_type_mask){
                     63:                        case AREG:      yyerror("arg %d, addressing a register",i);
                     64:                                        return;
                     65:                        case AIMM:      if ( !(ap_type & ASTAR) ){
                     66:                                         yyerror("arg %d, addressing an immediate operand",i);
                     67:                                         return;
                     68:                                        }
                     69:                        }
                     70:                        break;
                     71:                case ACCM >> TYPLG:
                     72:                case ACCW >> TYPLG:
                     73:                        switch(ap_type_mask){
                     74:                        case AIMM:      if (!(ap_type&ASTAR)) {
                     75:                                         yyerror("arg %d, modifying a constant",i);
                     76:                                         return;
                     77:                                        }
                     78:                        }
                     79:                        break;
                     80:                }       /* end of the switch on fp_type */
                     81:                if (ap_type & AINDX) {
                     82:                        if (ap_walk->a_areg2==0xF) {
                     83:                                yyerror("arg %d, PC used as index",i);
                     84:                                return;
                     85:                        }
                     86:                        switch(ap_type_mask){
                     87:                        case AREG:      yyerror("arg %d, indexing the register file",i);
                     88:                                        return;
                     89:                        case AIMM:      yyerror("arg %d, indexing a constant",i);
                     90:                                        return;
                     91:                        case ADECR:
                     92:                        case AINCR:     if (ap_walk->a_areg1==ap_walk->a_areg2) {
                     93:                                                yyerror("arg %d, indexing with modified register",i);
                     94:                                                return;
                     95:                                        }
                     96:                                        break;
                     97:                        }       /* end of switch on ap_type_mask */
                     98:                } /* end of AINDX */
                     99:           }
                    100:        } /* both passes here */
                    101:        if (jxxflg < 0)
                    102:                ijxout(opcode, ap, nact);
                    103:        else
                    104:                putins(opcode, ap, nact);
                    105: }
                    106: 
                    107: extern int d124;
                    108: 
                    109: putins(opcode, ap, n)
                    110:        struct  Opcode  opcode;
                    111:        register struct arg *ap;
                    112:        int     n;                      /* Must be positive */
                    113: {
                    114:        reg     struct exp      *xp;
                    115:        reg     int     argtype;
                    116:                int     i;
                    117:                int     reloc_how;
                    118:                int     value;
                    119: 
                    120: #ifdef DEBUG
                    121:        fflush(stdout);
                    122: #endif
                    123:        if (passno == 2)
                    124:                goto PASS2;
                    125: 
                    126:        dotp->e_xvalue += n;            /* at least one byte per arg */
                    127:        switch(opcode.Op_eopcode){
                    128:        case NEW:
                    129:        case CORE:
                    130:                dotp->e_xvalue += 1;    /* 1 byte opcode */
                    131:                break;
                    132:        case ESCD:
                    133:        case ESCF:
                    134:                dotp->e_xvalue += 2;    /* 2 byte opcode */
                    135:                break;
                    136:        default:
                    137:                panic("Bad escape opcode");
                    138:        }
                    139: 
                    140:        for (i=0; i<n; i++,ap++) {      /* some args take more than 1 byte */
                    141:            argtype = ap->a_atype;
                    142:            if (argtype & AINDX)
                    143:                dotp->e_xvalue++;
                    144:            /*
                    145:             *  This switch has been fixed by enumerating the no action
                    146:             *  alternatives (those that have 1 one byte of code)
                    147:             *  so that a casel instruction is emitted.
                    148:             */
                    149:            switch (argtype&~(AINDX|ASTAR)) {
                    150:                case AREG:
                    151:                case ABASE:
                    152:                case ADECR:
                    153:                case AINCR:
                    154:                        break;
                    155:                case AEXP: 
                    156:                        argtype = fetcharg(ITABFETCH(opcode), i);
                    157:                        if (argtype == A_BB)
                    158:                                break;
                    159:                        if (argtype == A_BW){
                    160:                                dotp->e_xvalue++;
                    161:                                break;
                    162:                        }
                    163:                        /*
                    164:                         *      Reduces to PC relative
                    165:                         */
                    166:                        dotp->e_xvalue += ap->a_dispsize;
                    167:                        break;
                    168:                
                    169:                case ADISP: 
                    170:                        xp=ap->a_xp;
                    171:                        if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){
                    172:                                dotp->e_xvalue += ap->a_dispsize;
                    173:                                break;
                    174:                        }
                    175:                        if (xp->e_xvalue==0 && !(argtype&ASTAR))
                    176:                                break;
                    177:                        dotp->e_xvalue += 1;
                    178:                        if (ISBYTE(xp->e_xvalue))
                    179:                                break;
                    180:                        dotp->e_xvalue += 1;
                    181:                        if (ISWORD(xp->e_xvalue))
                    182:                                break;
                    183:                        dotp->e_xvalue += 2;
                    184:                        break;
                    185: 
                    186:                case AIMM: 
                    187:                        if (ap->a_atype&ASTAR) {
                    188:                                argtype=TYPL;
                    189:                        } else {
                    190:                                argtype = fetcharg(ITABFETCH(opcode), i);
                    191:                                if (argtype&ACCA)
                    192:                                        argtype = TYPL;
                    193:                                else
                    194:                                        argtype &= TYPMASK;
                    195:                                xp = ap->a_xp;
                    196:                                if (immconstant(ap->a_xp, argtype, &value))
                    197:                                        break;
                    198:                        }
                    199:                        dotp->e_xvalue += ty_nbyte[argtype];
                    200:            }   /*end of the switch on the type*/
                    201:        }       /*end of looping for all arguments*/
                    202:        return;
                    203: 
                    204: PASS2:
                    205:        /*
                    206:         *      Output the opcode
                    207:         */
                    208:        switch(opcode.Op_eopcode){
                    209:        case NEW:
                    210:                nnewopcodes++;
                    211:                break;
                    212:        case ESCD:
                    213:        case ESCF:
                    214:                nGHopcodes++;
                    215:                Outb(opcode.Op_eopcode);
                    216:                break;
                    217:        case CORE:
                    218:                break;
                    219:        default:
                    220:                panic("Bad escape opcode");
                    221:        }
                    222:        Outb(opcode.Op_popcode);
                    223: 
                    224:        for (i=0; i<n; i++,ap++) {/* now for the arguments */
                    225:                argtype=ap->a_atype;
                    226:                xp=ap->a_xp;
                    227:                reloc_how = TYPNONE;
                    228:                if (argtype&AINDX) {
                    229:                        { Outb(0x40 | ap->a_areg2); }
                    230:                        argtype &= ~AINDX;
                    231:                }
                    232:                if (argtype&ASTAR) {
                    233:                        ap->a_areg1 |= 0x10;
                    234:                        argtype &= ~ASTAR;
                    235:                }
                    236:                switch (argtype) {
                    237:                case AREG:              /* %r */
                    238:                        ap->a_areg1 |= 0x50;
                    239:                        break; 
                    240:                case ABASE:             /* (%r) */
                    241:                        ap->a_areg1 |= 0x60;
                    242:                        break; 
                    243:                case ADECR:             /* -(%r) */
                    244:                        ap->a_areg1 |= 0x70;
                    245:                        break; 
                    246:                case AINCR:             /* (%r)+ */
                    247:                        ap->a_areg1 |= 0x80;
                    248:                        break;
                    249:                case AEXP: /* expr */
                    250:                        argtype = fetcharg(ITABFETCH(opcode), i);
                    251:                        if (argtype == A_BB) {
                    252:                                ap->a_areg1 = argtype = 
                    253:                                        xp->e_xvalue - (dotp->e_xvalue + 1);
                    254:                                if (xp->e_xtype & XXTRN)
                    255:                                        yywarning("%s: destination label is external",
                    256:                                                FETCHNAME(ITABFETCH(opcode)));
                    257:                                if (!ISBYTE(argtype))
                    258:                                        yyerror("%s: Branch too far(%db): try -J flag",
                    259:                                                FETCHNAME(ITABFETCH(opcode)),
                    260:                                                argtype);
                    261:                                break;
                    262:                        }
                    263:                        if (argtype == A_BW) {
                    264:                                ap->a_areg1 = argtype = xp->e_xvalue
                    265:                                        -= dotp->e_xvalue + 2;
                    266:                                if (xp->e_xtype & XXTRN)
                    267:                                        yywarning("%s: destination label is external",
                    268:                                                FETCHNAME(ITABFETCH(opcode)));
                    269:                                xp->e_xtype = XABS;
                    270:                                if (!ISWORD(argtype))
                    271:                                        yyerror("%s: Branch too far(%db): try -J flag",
                    272:                                                FETCHNAME(ITABFETCH(opcode)),
                    273:                                                argtype);
                    274:                                xp->e_xvalue = argtype>>8;
                    275:                                reloc_how = TYPB;
                    276:                                break;
                    277:                        }
                    278:                        /* reduces to expr(pc) mode */
                    279:                        ap->a_areg1 |= (0xAF + mod124[ap->a_dispsize]);
                    280:                        reloc_how = type_124[ap->a_dispsize] + RELOC_PCREL;
                    281:                        break;
                    282:                
                    283:                case ADISP: /* expr(%r) */
                    284:                        ap->a_areg1 |= 0xA0;
                    285:                        if ((xp->e_xtype&XTYPE)!=XABS || xp->e_xtype&XFORW){
                    286:                                ap->a_areg1 += mod124[ap->a_dispsize];
                    287:                                reloc_how = type_124[ap->a_dispsize];
                    288:                                break;
                    289:                        }
                    290:                        if (xp->e_xvalue==0 && !(ap->a_areg1&0x10)) {
                    291:                                ap->a_areg1 ^= 0xC0;
                    292:                                break;
                    293:                        }
                    294:                        reloc_how = TYPB;
                    295:                        if (ISBYTE(xp->e_xvalue))
                    296:                                break;
                    297:                        ap->a_areg1 += 0x20;
                    298:                        reloc_how = TYPW;
                    299:                        if (ISWORD(xp->e_xvalue))
                    300:                                break;
                    301:                        ap->a_areg1 += 0x20;
                    302:                        reloc_how = TYPL;
                    303:                        break;
                    304:                
                    305:                case AIMM:  /* $expr */
                    306:                        if (ap->a_atype&ASTAR) {
                    307:                                argtype=TYPL;
                    308:                        } else {
                    309:                                argtype = fetcharg(ITABFETCH(opcode), i);
                    310:                                if (argtype&ACCA)
                    311:                                        argtype = TYPL;
                    312:                                else
                    313:                                        argtype &= TYPMASK;
                    314:                                if (immconstant(xp, argtype, &value)){
                    315:                                        reloc_how = TYPNONE;
                    316:                                        ap->a_areg1 = value;
                    317:                                        break;
                    318:                                }
                    319:                        }
                    320:                        ap->a_areg1 |= 0x8F;
                    321:                        reloc_how = argtype;
                    322:                        break;
                    323:                
                    324:                }       /*end of the switch on argtype*/
                    325:                /*
                    326:                 *      use the first byte to describe the argument
                    327:                 */
                    328:                Outb(ap->a_areg1);
                    329:                if (reloc_how != TYPNONE) 
                    330:                        outrel(xp, reloc_how);
                    331:        }       /*end of the for to pick up all arguments*/
                    332: }
                    333: /*
                    334:  *     Is xp an immediate constant?
                    335:  *     argtype: how the instruction will interpret the bytes
                    336:  *     xp->e_number.num_tag ("numtype"): the kind of number given
                    337:  *
                    338:  *     Use the following table:
                    339:  *     float: TYPF, TYPD, TYPG, TYPH
                    340:  *     quad: TYPQ, TYPO
                    341:  *     int: TYPG, TYPW, TYPL
                    342:  *
                    343:  *                             numtype
                    344:  *     argtype         float   quad    int
                    345:  *     
                    346:  *     float           slitflt slitflt slitflt
                    347:  *     quad            0       0       0
                    348:  *     int             0..63   0       0..63
                    349:  *
                    350:  *     Where the table entry implies the predicate to return.
                    351:  */
                    352: #define        IMMFLT  1               /* these flags are not used by anybody (yet) */
                    353: #define        IMMINT  2
                    354: 
                    355: int immconstant(xp, argtype, valuep)
                    356:        reg     struct  exp     *xp;
                    357:                int     argtype;
                    358:                int     *valuep;
                    359: {
                    360:        reg     int     back = 0;
                    361:                int     numtype;
                    362:        reg     int     fits;
                    363: 
                    364:        if ((xp->e_xtype & XTYPE) != XABS)
                    365:                return(0);
                    366:        if ((xp->e_xtype & XFORW) != 0)
                    367:                return(0);
                    368:        numtype = xp->e_number.num_tag;
                    369: 
                    370:        fits = 1;
                    371:        if (passno == 2) switch(argtype){
                    372:        case TYPB:
                    373:                switch(numtype){
                    374:                default:        fits = 0; break;
                    375:                case TYPB:      fits = 1; break;
                    376:                case TYPW:      
                    377:                case TYPL:
                    378:                        fits = ISBYTE(xp->e_xvalue) || ISUBYTE(xp->e_xvalue);
                    379:                        break;
                    380:                }
                    381:                break;
                    382:        case TYPW:
                    383:                switch(numtype){
                    384:                default:        fits = 0; break;
                    385:                case TYPB:
                    386:                case TYPW:      fits = 1; break;
                    387:                case TYPL:
                    388:                        fits = ISWORD(xp->e_xvalue) || ISUWORD(xp->e_xvalue);
                    389:                        break;
                    390:                }
                    391:                break;
                    392:        case TYPF:
                    393:                if (numtype == TYPD){   /* same format for first 32 bits */
                    394:                        fits = 1;
                    395:                        break;
                    396:                }
                    397:                /*FALLTHROUGH*/
                    398:        default:
                    399:                fits = ty_nbyte[argtype] >= ty_nbyte[numtype];
                    400:        }
                    401:        if (!fits){
                    402:          yywarning("Immediate constant type %s mismatches instruction type %s",
                    403:                ty_string[numtype],
                    404:                ty_string[argtype]);
                    405:        }
                    406: 
                    407:        switch(argtype){
                    408:        case TYPF:
                    409:        case TYPG:
                    410:        case TYPD:
                    411:        case TYPH:
                    412:                back = slitflt(xp->e_number, argtype, valuep);
                    413:                break;
                    414:        case TYPO:
                    415:        case TYPQ:
                    416:                back = 0;
                    417:                break;
                    418:        case TYPB:
                    419:        case TYPW:
                    420:        case TYPL:
                    421:                switch(numtype){
                    422:                case TYPO:
                    423:                case TYPQ:
                    424:                        back = 0;
                    425:                        break;
                    426:                default:
                    427:                        *valuep = xp->e_xvalue;
                    428:                        back = ISLIT(xp->e_xvalue);
                    429:                        break;
                    430:                }
                    431:                break;
                    432:        }
                    433:        return(back);
                    434: }

unix.superglobalmegacorp.com

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