Annotation of coherent/b/bin/as/cmd.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * 80386 assembler commands.
                      3:  * ytype       function        args
                      4:  * CMD         docmd           parms
                      5:  * DCMD                docmd           names
                      6:  * ECMD                ecmd            name, expr
                      7:  * NCMD                docmd
                      8:  * ICMD                ncmd            expr
                      9:  * DATA                dcmd            data list
                     10:  */
                     11: #include <asm.h>
                     12: #include <symtab.h>
                     13: 
                     14: static unsigned short ct;
                     15: 
                     16: /*
                     17:  * Check parm count. Print msg if one required.
                     18:  */
                     19: static
                     20: ckCount(no)
                     21: {
                     22:        if(no == ct)
                     23:                return(0);
                     24:        yyerror("Found %d parms expected %d", ct, no); /**/
                     25:        return(1);
                     26: }
                     27: 
                     28: /*
                     29:  * Set up while
                     30:  */
                     31: static void
                     32: setUpWhile()
                     33: {
                     34:        register macro *tmp;
                     35:        macline *newl;
                     36: 
                     37:        newl = (macline *)alloc((unsigned)(sizeof(*newl) + strlen(lastL)));
                     38:        strcpy(newl->line, lastL);
                     39: 
                     40:        newLevel(INWDEF);
                     41: 
                     42:        tmp = new(macro);
                     43:        inMacDef = tmp;
                     44:        lastDef = inMacDef->first = newl;
                     45: }
                     46: 
                     47: /*
                     48:  * Do commands with name, expr.
                     49:  */
                     50: ecmd(label, op, p, item)
                     51: opc *op;
                     52: parm *label, *p;
                     53: data *item;
                     54: {
                     55:        long n = 0;
                     56: 
                     57:        labelIgnored(label);
                     58: 
                     59:        if (NULL != item) {
                     60:                switch (item->type) {
                     61:                case 'l':
                     62:                        n = item->d.l;
                     63:                        break;
                     64:                case 'y':
                     65:                        if (op->kind == S_SET)
                     66:                                break;
                     67:                default:
                     68:                        yyerror("Invalid operand type"); /**/
                     69:                        return;
                     70:                }
                     71:        }
                     72: 
                     73:        switch (op->kind) {
                     74:        case S_SEGMENT: /* change segments */
                     75:                segment(op, p, n);
                     76:                break;
                     77: 
                     78:        case S_COMM:    /* allocate data in a segment */
                     79:                comm(op, p, n);
                     80:                break;
                     81: 
                     82:        case S_SET:
                     83:                if(NULL == p)
                     84:                        yyerror("Name required");
                     85:                        /* The format of \fBset\fR is
                     86:                         * \fB.set name, value\fR */
                     87:                else if (!strcmp(p->str, "."))
                     88:                        doOrg(NULL, item);
                     89:                else if (item->type == 'l')
                     90:                        symLookUp(p->str, S_XSYM, n, 0);
                     91:                else
                     92:                        symLookUp(p->str, S_LOCAL, 
                     93:                                  item->d.y->loc, item->d.y->sg);
                     94:                break;
                     95: 
                     96:        }
                     97:        return 0;
                     98: }
                     99: 
                    100: /*
                    101:  * Do commands with string parms.
                    102:  */
                    103: docmd(label, op, p)
                    104: opc *op;
                    105: parm *p, *label;
                    106: {
                    107:        ct = countList(p);
                    108: 
                    109:        switch(op->kind) {
                    110:        /*
                    111:         * This may be name value in some formats to avoid syntax error
                    112:         * we bring it in as ytype CMD. We don't do dubug for those formats.
                    113:         */
                    114:        case S_DEF:
                    115:                labelIgnored(label);
                    116:                coffDef(p);
                    117:                break;
                    118: 
                    119:        case S_TAG:
                    120:                labelIgnored(label);
                    121:                coffTag(p);
                    122:                break;
                    123: 
                    124:        case S_FILE:
                    125:                labelIgnored(label);
                    126:                coffFile(p);            
                    127:                break;
                    128: 
                    129:        case S_ENDF:
                    130:                coffEndef();
                    131:                break;
                    132: 
                    133:        case S_INCLUDE:
                    134:                if(ckCount(1))
                    135:                        return(1);
                    136:                fileOpen(p->str);
                    137:                break;
                    138: 
                    139:        case S_MACRO:
                    140:                if(NULL == label) {
                    141:                        yyerror("Macro definition must have a label"); /**/
                    142:                        defMac("***", p, MACTYPE);
                    143:                }
                    144:                else
                    145:                        defMac(label->str, p, MACTYPE);
                    146:                break;
                    147: 
                    148:        case S_EQUS:
                    149:                defCt++;
                    150:                if(NULL == label) {
                    151:                        yyerror(".define must have a label"); /**/
                    152:                        defMac("***", p, MACSTR);
                    153:                }
                    154:                else
                    155:                        defMac(label->str, p, MACSTR);
                    156:                break;
                    157: 
                    158:        case S_UNDEFINE:        /* kill macro or define */
                    159:                for(; NULL != p; p = p->next) {
                    160:                        opDelete(p->str);
                    161:                        macDelete(p->str, MACSTR);
                    162:                        macDelete(p->str, MACTYPE);
                    163:                }
                    164:                break;
                    165: 
                    166:        case S_MEXIT: {
                    167:                macctl *m;
                    168: 
                    169:                if(NULL == trueMac) {
                    170:                        yyerror(".mexit not in macro"); /**/
                    171:                        break;
                    172:                }
                    173:                m = macExp;     /* break out of any whiles */
                    174:                do {
                    175:                        m->curr = NULL; /* no more lines */
                    176:                } while(m->type != MACTYPE);
                    177:                break;
                    178:                }
                    179: 
                    180:        case S_ENDM:
                    181:                yyerror("Unexpected .endm ignored"); /**/
                    182:                break;
                    183: 
                    184:        case S_MAC:
                    185:                {
                    186:                register macctl *tmp;
                    187: 
                    188:                umList(p);      /* dont trash parms at end of line */
                    189:                tmp = new(macctl);
                    190:                tmp->curr = macFound->first;
                    191:                tmp->parms = p;
                    192:                tmp->names = macFound->names;
                    193:                tmp->expno = ++macNo;   /* unique non zero macro expansion ct */
                    194:                tmp->type  = MACTYPE;
                    195:                tmp->prev = macExp;
                    196:                trueMac = macExp = tmp;
                    197:                if(NULL != label)
                    198:                        symLookUp(label->str, S_LOCAL, dot.loc, dot.sg);
                    199:                }
                    200:                break;
                    201: 
                    202:        case S_ERRATA:
                    203:                nswitch = op->code;
                    204:                break;
                    205: 
                    206:        case S_WARNINGS:
                    207:                wswitch = op->code;
                    208:                break;
                    209: 
                    210:        case S_OPORDER:
                    211:                fswitch = op->code;
                    212:                break;
                    213: 
                    214:        case S_BORDER:
                    215:                bswitch = op->code;
                    216:                break;
                    217: 
                    218:        case S_LMODE:
                    219:                longMode = op->code;
                    220:                break;
                    221: 
                    222:        case S_LIST:
                    223:                if (pass == 2)
                    224:                        lswitch = op->code & lswitchX;
                    225:                break;
                    226: 
                    227:        case S_ALIGNON:
                    228:                alignon = op->code;
                    229:                break;
                    230: 
                    231:        case S_EJECT:
                    232:                if (lswitch && (2 == pass) && pswitch)
                    233:                        while (linect) {
                    234:                                sTitle();
                    235:                                putchar('\n');
                    236:                        }
                    237:                break;
                    238: 
                    239:        case S_PAGE:
                    240:                pswitch = op->code;
                    241:                break;
                    242: 
                    243:        case S_MLIST:
                    244:                if (pass == 2) {
                    245:                        if(!strcmp("on", p->str))
                    246:                                mlistsw = 1;
                    247:                        else if(!strcmp("off", p->str))
                    248:                                mlistsw = 0;
                    249:                        else
                    250:                                yyerror(
                    251:                                "Invalid .mlist option must be on or off");
                    252:                                /**/
                    253:                }
                    254:                break;
                    255: 
                    256:        case S_ERROR:
                    257:                if (op->code)
                    258:                        yyerror("%s", p->str); /* NODOC */
                    259:                else
                    260:                        yywarn("%s", p->str); /* NODOC */
                    261:                break;
                    262: 
                    263:        case S_CMNT:    /* ident and version */
                    264:                if (2 == pass)
                    265:                        cmnt(op, p);
                    266:                break;
                    267: 
                    268:        case S_SECTION:
                    269:                if (!ct) {
                    270:                        yyerror(".section must have name");     /**/
                    271:                        return;
                    272:                }
                    273:                section(p->str);
                    274:                break;
                    275: 
                    276:        case S_TITLE: {
                    277:                static short i = 0;
                    278: 
                    279:                /* Ignore all but first title on pass 0 */
                    280:                if((2 == pass) || !i) {
                    281:                        pswitch = i = 1;
                    282:                        free(title);
                    283:                        title = scpy(p->str, 0);
                    284:                }
                    285:                break;
                    286:        }
                    287: 
                    288:        case S_ENDW:
                    289:                if((NULL != macExp) && (WHILETYPE == macExp->type))
                    290:                        macExp->curr = macExp->first;
                    291:                else
                    292:                        yyerror("Unexpected .endw"); /**/
                    293:                break;
                    294: 
                    295:        case S_ENDI:
                    296:                switch(logic->type) {
                    297:                case INIF1:
                    298:                        freeLevel();
                    299:                        break;
                    300:                case NORMAL:
                    301:                        yyerror("Unexpected .endi statement"); /**/
                    302:                        break;
                    303:                default:
                    304:                        fatal(".endi detected logic type %d", logic->type);
                    305:                        /* TECH */
                    306:                }
                    307:                break;
                    308: 
                    309:        case S_ELSE:
                    310:                switch(logic->type) {
                    311:                case INIF1:
                    312:                        logic->type = INIF0;
                    313:                        break;
                    314:                case NORMAL:
                    315:                        yyerror("Unexpected .else statement"); /**/
                    316:                        break;
                    317:                default:
                    318:                        fatal(".else detected logic type %d", logic->type);
                    319:                        /* TECH */
                    320:                }
                    321:                break;
                    322: 
                    323:        default:
                    324:                kindErr((unsigned short)op->kind);
                    325:        }
                    326: 
                    327:        return(0);
                    328: }
                    329: 
                    330: /*
                    331:  * Commands with a numexp as parm.
                    332:  */
                    333: ncmd(label, op, item)
                    334: parm *label;
                    335: opc *op;
                    336: data *item;
                    337: {
                    338:        long n;
                    339:        data oper;
                    340: 
                    341:        switch (item->type) {
                    342:        case 'l':
                    343:                n = item->d.l;
                    344:                break;
                    345:        case 'y':
                    346:                if ((op->kind == S_EQU) || (op->kind == S_VAL))
                    347:                        break;
                    348:        default:
                    349:                yyerror("Invalid operand type"); /* NODOC */
                    350:                return;
                    351:        }
                    352: 
                    353:        switch(op->kind) {
                    354:        case S_TYPE:
                    355:                coffType(n);
                    356:                break;          
                    357:        case S_VAL:
                    358:                coffVal(item);
                    359:                break;
                    360:        case S_LN:
                    361:                coffLn(n);
                    362:                break;
                    363:        case S_LINE:
                    364:                coffLine(n);
                    365:                break;
                    366:        case S_SIZE:
                    367:                coffSize(n);
                    368:                break;
                    369:        case S_SCL:
                    370:                coffScl(n);
                    371:                break;
                    372:        case S_ZERO:
                    373:                buildlab(label);
                    374:                while(n--)
                    375:                        outab(0);
                    376:                break;
                    377: 
                    378:        case S_BLKB:
                    379:                buildlab(label);
                    380:                oper.d.l = dot.loc + n;
                    381:                oper.type = 'l';
                    382:                doOrg(NULL, &oper);
                    383:                return;
                    384:        case S_SHIFT:
                    385:                doShift((short)n);
                    386:                break;
                    387:        case S_EQU:
                    388:                if (NULL == label)
                    389:                        yyerror("Label required"); /**/
                    390:                else if (!strcmp(label->str, "."))
                    391:                        doOrg(NULL, item);
                    392:                else if (item->type == 'l')
                    393:                        symLookUp(label->str, S_XSYM, n, 0);
                    394:                else {
                    395:                        symLookUp(label->str, S_LOCAL, 
                    396:                                  item->d.y->loc, item->d.y->sg);
                    397: 
                    398:                        /* forward equate make sure there is an extra pass */
                    399:                        if (!pass && (item->d.y->flag & S_UNDEF))
                    400:                                xpass = 1;
                    401: 
                    402:                        if (item->d.y->flag & (S_COMMON|S_EXREF))
                    403:                          yyerror("Cannot equate to externally defined symbol");
                    404:                          /* This would mean creating another symbol.
                    405:                           * Try using \fB.define\fR. */
                    406:                }
                    407:                return;
                    408:        case S_PLEN:    /* set page length */
                    409:                nlpp = n - 10;
                    410:                break;
                    411:        case S_LLEN:    /* set line length */
                    412:                lineSize = n;
                    413:                break;
                    414:        case S_IF:
                    415:                newLevel(n ? INIF1 : INIF0);
                    416:                break;
                    417:        case S_WHILE:
                    418:                if((NULL != macExp) &&
                    419:                   (WHILETYPE == macExp->type) &&
                    420:                   (macExp->curr == macExp->first->next)) {
                    421:                        if(!n) {
                    422:                                freeList((parm *)macExp->first);
                    423:                                macExp->curr = NULL;
                    424:                        }
                    425:                }
                    426:                else
                    427:                        setUpWhile();
                    428:                break;
                    429:        default:
                    430:                kindErr((unsigned short)op->kind);
                    431:        }
                    432: 
                    433:        labelIgnored(label);
                    434: }
                    435: /*
                    436:  * Make an expression for dataOut.
                    437:  */
                    438: expr *
                    439: makeExp(addr)
                    440: data *addr;
                    441: {
                    442:        static expr x;
                    443: 
                    444:        x.ref = addr->d.y;
                    445:        x.exp = x.ref->loc;
                    446:        if (x.ref->flag & (S_COMMON|S_EXREF))
                    447:                x.exp <<= 1;    /* double we will loose it back */
                    448:        return(&x);
                    449: }
                    450: 
                    451: /*
                    452:  * Data output for .byte .word .long .string .float .double
                    453:  */
                    454: static void
                    455: dataOut(op, oper)
                    456: opc *op;
                    457: data *oper;
                    458: {
                    459:        register char *str, c;
                    460:        union {
                    461:                long l[2];
                    462:                float f[2];
                    463:                double d;
                    464:        } u;
                    465: 
                    466:        if(op->code && (op->code != 5) && ('s' == oper->type)) {
                    467:                yyerror("String must be on .byte");
                    468:                /* For example:
                    469:                 * .DM
                    470:                 *      .byte "This is how we place a string", 0
                    471:                 * .DE */
                    472:                return;
                    473:        }
                    474:        while(oper->count--) {  /* honor repeat count */
                    475:                switch(op->code) {      /* set by option */
                    476:                case 5:                 /* .string */
                    477:                        if ('s' != oper->type) {
                    478:                                yyerror("Improper .string operand");
                    479:                                return;
                    480:                        }
                    481:                        for(str = oper->d.s; c = *str++; )
                    482:                                outab((unsigned short)c);
                    483:                        outab(0);
                    484:                        break;
                    485:                case 0:                 /* .byte */
                    486:                        switch(oper->type) {
                    487:                        case 's':
                    488:                                for(str = oper->d.s; c = *str++; )
                    489:                                        outab((unsigned short)c);
                    490:                                break;
                    491:                        case 'y':
                    492:                                outrb(makeExp(oper), 0);
                    493:                                break;
                    494:                        case 'l':
                    495:                                outab((unsigned)oper->d.l);
                    496:                                break;
                    497:                        case 'd':
                    498:                                outab((unsigned)oper->d.d);
                    499:                                break;
                    500:                        }
                    501:                        break;
                    502:                case 1:         /* .word or .value */
                    503:                        switch(oper->type) {
                    504:                        case 'y':
                    505:                                outrw(makeExp(oper), 0);
                    506:                                break;
                    507:                        case 'l':
                    508:                                outaw((unsigned)oper->d.l);
                    509:                                break;
                    510:                        case 'd':
                    511:                                outaw((unsigned)oper->d.d);
                    512:                                break;
                    513:                        }
                    514:                        break;
                    515:                case 2:         /* .long */
                    516:                        switch(oper->type) {
                    517:                        case 'y':
                    518:                                outrl(makeExp(oper), 0);
                    519:                                break;
                    520:                        case 'l':
                    521:                                outal(oper->d.l);
                    522:                                break;
                    523:                        case 'd':
                    524:                                outal((long)oper->d.d);
                    525:                                break;
                    526:                        }
                    527:                        break;
                    528:                case 3:         /* .float */
                    529:                        switch(oper->type) {
                    530:                        case 'y':
                    531:                                yyerror("Symbol may not be float");
                    532:                                /* You may not convert a symbol to
                    533:                                 * a floating-point value. */
                    534:                                return;
                    535:                        case 'l':
                    536:                                u.f[0] = oper->d.l;
                    537:                                break;
                    538:                        case 'd':
                    539:                                u.f[0] = oper->d.d;
                    540:                        }
                    541: #if _DECVAX
                    542:                        ieee_f(u.f, u.f);       /* DECVAX to IEEE */
                    543: #endif
                    544:                        outal(u.l[0]);
                    545:                        break;
                    546:                case 4:         /* .double */
                    547:                        switch(oper->type) {
                    548:                        case 'y':
                    549:                                yyerror("Symbol may not be double");
                    550:                                /* You may not convert a symbol to
                    551:                                 * a floating-point value. */
                    552:                                return;
                    553:                        case 'l':
                    554:                                u.d = oper->d.l;
                    555:                                break;
                    556:                        case 'd':
                    557:                                u.d = oper->d.d;
                    558:                        }
                    559: #if _DECVAX
                    560:                        ieee_d(&u.d, &u.d);     /* DECVAX to IEEE */
                    561: #endif
                    562:                        outal(u.l[0]);
                    563:                        outal(u.l[1]);
                    564: 
                    565:                        break;
                    566:                }
                    567:        }
                    568: }
                    569: 
                    570: /*
                    571:  * Output alignment bytes.
                    572:  */
                    573: static int
                    574: alignOut(seg, byte, n)
                    575: {
                    576:        int rv = 0;
                    577: 
                    578:        switch (seg) {
                    579:        case 0: /* fill selected by user */
                    580:                while (dot.loc & n) {
                    581:                        rv = 1;
                    582:                        outab(byte);
                    583:                }
                    584:                break;
                    585:        case 1: /* text */
                    586:                while (dot.loc & n) {
                    587:                        rv = 1;
                    588:                        outab(0x90);
                    589:                }
                    590:                break;
                    591:        case 2: /* data */
                    592:                while (dot.loc & n) {
                    593:                        rv = 1;
                    594:                        outab(0);
                    595:                }
                    596:                break;
                    597:        }
                    598:        return rv;
                    599: }
                    600: 
                    601: /*
                    602:  * Commands with a list of data as parm.
                    603:  */
                    604: dcmd(label, op, oper)
                    605: parm *label;
                    606: opc *op;
                    607: data *oper;
                    608: {
                    609:        register sym *sp = NULL;
                    610:        register sym *y;
                    611:        long start, n;
                    612:        char b, s;
                    613: 
                    614:        switch (op->kind) {
                    615:        case S_ORG:
                    616:                return(doOrg(label, oper));
                    617: 
                    618:        case S_EVEN:    /* this is here to fall into .align */
                    619:                s = dot.sg;
                    620:                n = 1;
                    621:                goto even;
                    622: 
                    623:        case S_ALIGN:
                    624:                if (NULL == oper) {
                    625:                        yyerror("Missing operand");
                    626:                        /* \fB\&.align\fR must have 1 or 2 operands */
                    627:                        return(1);
                    628:                }
                    629:                switch (oper->type) {
                    630:                case 'l':
                    631:                        n = oper->d.l;
                    632:                        break;
                    633:                default:
                    634:                        yyerror("Invalid operand type"); /* NODOC */
                    635:                        return(1);
                    636:                }
                    637:                if ((3 != (s = dot.sg)) && (NULL != (oper = oper->next))) {
                    638:                        switch (oper->type) {
                    639:                        case 'l':
                    640:                                s = 0;
                    641:                                b = oper->d.l;
                    642:                                break;
                    643:                        default:
                    644:                                yyerror("Invalid operand type"); /* NODOC */
                    645:                                return(1);
                    646:                        }
                    647:                }
                    648: 
                    649:                if (!--n)
                    650:                        return;
                    651:                if ((1 != n) && (3 != n)) {
                    652:                        yyerror(".align must be 1, 2 or 4");
                    653:                /* \fB\&.align\fR must work after the link.
                    654:                 * These are the only values for which this can be true. */
                    655:                        return(1);
                    656:                }
                    657: 
                    658:        even:   if (3 == dot.sg) {
                    659:                        oper.d.l = (dot.loc + n) & ~n;
                    660:                        oper.type = 'l';
                    661:                        doOrg(NULL, &oper);
                    662:                }
                    663:                else
                    664:                        alignOut(s, b, n);
                    665:                return(0);
                    666: 
                    667:        case S_DATA:
                    668:                /* If alignment on and data and not .string or .byte */
                    669:                if (!alignon)
                    670:                        break;
                    671:                switch (op->code) {
                    672:                case 1:
                    673:                        s = alignOut(dot.sg, 0, 1);
                    674:                        break;
                    675:                case 2:
                    676:                case 3:
                    677:                case 4:
                    678:                        s = alignOut(dot.sg, 0, 3);
                    679:                }
                    680:                if (s)  /* Alignment stuff went out */
                    681:                        outLine("", ' ');
                    682:        }
                    683: 
                    684:        if(NULL != label) {
                    685:                switch (op->kind) {
                    686:                case S_DATA:
                    687:                case S_UDATA:
                    688:                        sp = symLookUp(label->str, S_LOCAL,
                    689:                                (start = dot.loc), dot.sg);
                    690:                        break;
                    691:                default:
                    692:                        labelIgnored(label);
                    693:                }
                    694:        }
                    695: 
                    696:        for(b = 0; NULL != oper; oper = oper->next) {
                    697:                switch (op->kind) {
                    698:                case S_DATA:
                    699:                case S_UDATA:
                    700:                        dataOut(op, oper);
                    701:                        continue;
                    702:                case S_DIM:
                    703:                        if ('l' != oper->type) {
                    704:                                yyerror("Invalid data type, must be number");
                    705:                                         /**/
                    706:                                continue;
                    707:                        }
                    708:                        coffDim(oper->d.l, b++);
                    709:                        continue;
                    710:                case S_GLOBL:   /* .globl */
                    711:                        if('y' != oper->type) {
                    712:                                yyerror("Invalid data type, must be symbol");
                    713:                                         /**/
                    714:                                continue;
                    715:                        }
                    716:                        y = oper->d.y;
                    717:                        if(!(y->flag & S_ASYM)) {
                    718:                                yyerror("Illegal use of of predefined symbol %s.",
                    719:                                        (psym *)y->name); /**/
                    720:                                continue;
                    721:                        }
                    722:                        if (NULL != strchr(y->name, ';')) {
                    723:                                yyerror("Illegal use of local symbol"); /**/
                    724:                                continue;
                    725:                        }
                    726:                        if (y->flag & S_UNDEF) {
                    727:                                y->loc = 0;
                    728:                                y->sg = 0;
                    729:                                y->flag = S_EXREF;
                    730:                        }
                    731:                        else
                    732:                                y->flag |= S_EXDEF;
                    733:                        continue;
                    734:                        default:
                    735:                                kindErr((unsigned short)op->kind);
                    736:                                return(1);
                    737:                }
                    738:        }
                    739: 
                    740:        if(NULL != sp) /* finish label building */
                    741:                sp->size = dot.loc - start;
                    742:        return(0);
                    743: }

unix.superglobalmegacorp.com

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