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

unix.superglobalmegacorp.com

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