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

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

unix.superglobalmegacorp.com

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