Annotation of coherent/b/bin/as/tabbld.c.exp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Build code tables for 80386 assembler.
        !             3:  * Also build .h file and assembler test file.
        !             4:  */
        !             5: #include <misc.h>
        !             6: #include <ctype.h>
        !             7: #include "asflags.h"
        !             8: 
        !             9: typedef struct opts opts;
        !            10: typedef struct funs funs;
        !            11: typedef struct regs regs;
        !            12: typedef struct oper oper;
        !            13: 
        !            14: char *allntab;         /* all names table */
        !            15: short allnct, allnlen;
        !            16: 
        !            17: short *htab;           /* hash table */
        !            18: 
        !            19: struct oper {  /* operand types for test builder */
        !            20:        char *name;
        !            21:        int  base;              /* != 0 if equate must be built for this type */
        !            22:        short flag;             /* flag bits */
        !            23:        unsigned goodct;        /* number of good items on this list */
        !            24:        char *goodlist;         /* valid productions for this type */
        !            25:        unsigned badct;         /* number of bad items on this list */
        !            26:        char *badlist;          /* bad productions to test error checking */
        !            27: } *opertab;
        !            28: short operct, operlen;
        !            29: 
        !            30: /* oper flags */
        !            31: #define X_LARGE        1       /* contains 386 mode stuff */
        !            32: #define X_SMALL 2      /* contains 286 mode stuff */
        !            33: 
        !            34: struct opts {          /* opcode table */
        !            35:        char *name;
        !            36:        short opcode;
        !            37:        short hash;
        !            38:        short gen;              /* index into gentab */
        !            39:        short pt;               /* index into alltab */
        !            40:        short len;              /* length in alltab */
        !            41:        short fun;              /* index into fun */
        !            42:        short count;            /* count of items with this name */
        !            43:        short lineno;           /* line number on source table */
        !            44: } *optab;
        !            45: short opct, oplen;
        !            46: 
        !            47: struct funs {
        !            48:        char *name;
        !            49:        char *type;     /* yacc type */
        !            50:        short opt;      /* generation type */
        !            51:        char operands;  /* operand ct */
        !            52:        char ap[3];     /* operands */
        !            53: } *funtab;
        !            54: short funct, funlen;
        !            55: 
        !            56: struct regs {
        !            57:        char *name;
        !            58:        char *ytype;
        !            59:        short loc;
        !            60:        short len;
        !            61: } *regtab;
        !            62: short regct, reglen;
        !            63: 
        !            64: #define START(n, m) n##tab = alloc((n##len = m) * sizeof(*n##tab))
        !            65: 
        !            66: /* expander for tables */
        !            67: #define EXPAND(n) if((n##len <= (++n##ct)) \
        !            68:  && (NULL == (n##tab = realloc(n##tab, ((n##len += 10) * sizeof(*n##tab)))))) \
        !            69:        outSpace(__LINE__)
        !            70: 
        !            71: /* expander for allnames */
        !            72: #define NEWN(n, r) if((n##len <= (n##ct += r)) \
        !            73:  && (NULL == (n##tab = realloc(n##tab, n##len += 10)))) \
        !            74:        outSpace(__LINE__)
        !            75: 
        !            76: extern char *realloc(), *strstr(), *getline(), *newcpy();
        !            77: extern unsigned short hash();
        !            78: extern char *comment;  /* from getline() */
        !            79: 
        !            80: static FILE *ofp, *ohp, *otp, *odp;    /* output files */
        !            81: static char *line;     /* input line */
        !            82: static int lineno = 1; /* line number */
        !            83: static int state;      /* opcodes, registers commands */
        !            84: static int curgen;     /* index to current general name */
        !            85: static unsigned nameCt;        /* name count */
        !            86: static int lastp;      /* last entry on prefTab */
        !            87: static short ct, opcode, opt;
        !            88: static unsigned long optDoc;
        !            89: static char fname[22], opc[10], op1[10], op2[10], op3[10], cmd[10], yt[10];
        !            90: static char thisGen[10];
        !            91: static errors;         /* error count */
        !            92: 
        !            93: /* test selector switches */
        !            94: static unsigned tmask = 0;             /* reject any not on this mask */
        !            95: static unsigned nmask = 0;             /* take any on this mask */
        !            96: static unsigned lswitch;               /* do large ops only */
        !            97: static unsigned sswitch;               /* do small ops only */
        !            98: static unsigned bswitch;               /* produce error test */
        !            99: 
        !           100: /*
        !           101:  * Report error.
        !           102:  */
        !           103: error(s)
        !           104: char *s;
        !           105: {
        !           106:        fprintf(stderr, "%d: %r\n", lineno, &s);
        !           107:        errors++;
        !           108: }
        !           109: 
        !           110: /*
        !           111:  * Out of space. or normal end.
        !           112:  */
        !           113: outSpace(line)
        !           114: {
        !           115:        if (line)
        !           116:                fprintf(stderr, "Out of space at %d\n", line);
        !           117:        showStats(1);
        !           118: }
        !           119: 
        !           120: /*
        !           121:  * Show generation statistics and exit.
        !           122:  */
        !           123: showStats(n)
        !           124: {
        !           125:        fprintf(stderr, "opct = %d, funct = %d, lineno = %d, ",
        !           126:                opct, funct, lineno);
        !           127:        fprintf(stderr, "regct = %d, operct = %d, allnct = %d\n",
        !           128:                regct, operct, allnct);
        !           129:        exit(n);
        !           130: }
        !           131: 
        !           132: /*
        !           133:  * Build test alternatives.
        !           134:  * Line starts with [.bB] for base type [!eE] for extra type.
        !           135:  * Caps for 386 productions, lower for 286 productions, punctuation for mixed.
        !           136:  * Base types are the operand types actually on opcodes.
        !           137:  * ? delimits bad choices.
        !           138:  */
        !           139: void
        !           140: buildTst()
        !           141: {
        !           142:        register struct oper *this;
        !           143:        register char *p;
        !           144:        static int base;
        !           145:        int state, c;
        !           146: 
        !           147:        EXPAND(oper);
        !           148:        this = opertab + operct - 1;
        !           149: 
        !           150:        switch (line[0]) {      /* mark base and extra */
        !           151:        case '.':
        !           152:                this->base = ++base;
        !           153:        case '!':
        !           154:                this->flag = (X_LARGE|X_SMALL);
        !           155:                break;
        !           156:        case 'B':
        !           157:                this->base = ++base;
        !           158:        case 'E':
        !           159:                this->flag = X_LARGE;
        !           160:                break;
        !           161:        case 'b':
        !           162:                this->base = ++base;
        !           163:        case 'e':
        !           164:                this->flag = X_SMALL;
        !           165:                break;
        !           166:        default:
        !           167:                operct--;
        !           168:                error("Bad test line");
        !           169:                return;
        !           170:        }
        !           171: 
        !           172:        for (p = line + 2; (c = *p) && !isspace(c); p++)
        !           173:                ;
        !           174:        *p++ = '\0';
        !           175:        this->name = newcpy(line + 2);
        !           176: 
        !           177:        /* Count the valid productions on the line */
        !           178:        this->goodlist = p;
        !           179:        for (state = 0; c = *p; p++) {
        !           180:                if (state) {    /* in a production */
        !           181:                        if (!isspace(c)) {
        !           182:                                if ('?' == c)
        !           183:                                        break;
        !           184:                                continue;
        !           185:                        }
        !           186:                        state = 0;
        !           187:                        continue;
        !           188:                }
        !           189:                if (isspace(c))
        !           190:                        continue;
        !           191:                if ('?' == c)
        !           192:                        break;
        !           193:                this->goodct++;
        !           194:                state = 1;
        !           195:        }
        !           196:        *p++ = '\0';
        !           197:        this->goodlist = newcpy(this->goodlist);
        !           198:        if (!c)
        !           199:                return;
        !           200: 
        !           201:        /* count the invalid productions on the line */
        !           202:        this->badlist = p;
        !           203:        for (state = this->badct = 0; c = *p; p++) {
        !           204:                if (state) {
        !           205:                        if (!isspace(c))
        !           206:                                continue;
        !           207:                        state = 0;
        !           208:                        continue;
        !           209:                }
        !           210:                if (isspace(c))
        !           211:                        continue;
        !           212:                this->badct++;
        !           213:                state = 1;
        !           214:        }
        !           215:        this->badlist = newcpy(this->badlist);
        !           216: }
        !           217: 
        !           218: /*
        !           219:  * Build assembler directives.
        !           220:  */
        !           221: buildDir()
        !           222: {
        !           223:        register funs *f;
        !           224:        register opts *this;
        !           225:        int i, j;
        !           226: 
        !           227:        sscanf(line, "%d %s %s %s", &opcode, opc, cmd, yt);
        !           228:        sprintf(fname, "S_%s", cmd);
        !           229: 
        !           230:        for (j = 0; j < funct; j++)
        !           231:                if (!strcmp(funtab[j].name, fname))
        !           232:                        break;
        !           233: 
        !           234:        if (j == funct) {       /* not found build one */
        !           235:                EXPAND(fun);
        !           236:                f = funtab + j;
        !           237:                f->name = newcpy(fname);
        !           238:                f->opt = f->operands = 0;
        !           239:                f->type = newcpy(yt);
        !           240:        }
        !           241: 
        !           242: 
        !           243:        if (!strcmp(opc, "-"))  /* no opcode generated */
        !           244:                return;
        !           245: 
        !           246:        i = opct;
        !           247:        EXPAND(op);
        !           248:        this = optab + i;
        !           249:        this->name = newcpy(opc);
        !           250:        this->fun = j;
        !           251:        this->opcode = opcode;
        !           252:        this->gen = -1;
        !           253:        this->hash = -2;
        !           254:        this->lineno = lineno;
        !           255: }
        !           256: 
        !           257: /*
        !           258:  * Build register name entrys.
        !           259:  */
        !           260: void
        !           261: buildReg()
        !           262: {
        !           263:        register regs *new;
        !           264:        char name[20], ytype[20];
        !           265: 
        !           266:        EXPAND(reg);
        !           267:        new = regtab + regct - 1;
        !           268: 
        !           269:        sscanf(line,
        !           270:                 "%s %s %d %d",
        !           271:                 name, ytype, &new->loc, &new->len);
        !           272:        new->name  = newcpy(name);
        !           273:        new->ytype = newcpy(ytype);
        !           274: }
        !           275: 
        !           276: /*
        !           277:  * Read and preprocess opcode
        !           278:  */
        !           279: void
        !           280: buildOp()
        !           281: {
        !           282:        register opts *this;
        !           283:        char optf[8], *p;
        !           284: 
        !           285:        optDoc = opc[0] = op1[0] = op2[0] = op3[0] = '\0';
        !           286:        sscanf(line, "%s %s", optf, opc);
        !           287: 
        !           288:        if ('G' == optf[0]) {   /* general opcode */
        !           289:                curgen = -1;
        !           290:                if(opc[0]) {
        !           291:                        for (curgen = 0; curgen < opct; curgen++) {
        !           292:                                if (!strcmp(opc, optab[curgen].name)) {
        !           293:                                        error("Dup Gen %s", opc);
        !           294:                                        return;
        !           295:                                }
        !           296:                        }
        !           297:                        strcpy(thisGen, opc);
        !           298: 
        !           299:                        fprintf(odp, "%s %d 0!", opc, lineno);
        !           300:                        fprintf(odp, "\t\\fB%s\\fR\t\t%s\n",
        !           301:                                 opc, comment);
        !           302: 
        !           303:                        EXPAND(op);
        !           304:                        this = optab + curgen;
        !           305:                        this->name = newcpy(opc);
        !           306:                        this->fun = -1;
        !           307:                        this->hash = -1;
        !           308:                        this->gen = curgen; /* self pointing */
        !           309:                        this->lineno = lineno;
        !           310:                }
        !           311:                return;
        !           312:        }                       
        !           313: 
        !           314:        if (!opc[0])
        !           315:                error("Null name");
        !           316: 
        !           317:        sscanf(line, "%s %x %s %s %s %s", optf, &opcode, opc, op1, op2, op3);
        !           318: 
        !           319:        for (p = optf; ; p++) {
        !           320:                switch(*p) {
        !           321:                case 0:
        !           322:                case '-':
        !           323:                        opt = optDoc;
        !           324:                        opBld();                return;
        !           325:                case 'A':
        !           326:                        optDoc |= AMBIG_MATCH;  break;
        !           327:                case 'i':
        !           328:                        optDoc |= INDEF_JMP;    break;
        !           329:                case 'w':
        !           330:                        optDoc |= WORD_MODE;    break;
        !           331:                case 'd':
        !           332:                        optDoc |= LONG_MODE;    break;
        !           333:                case 'F':
        !           334:                        optDoc |= FLOAT_ESC;    break;
        !           335:                case 'f':
        !           336:                        optDoc |= FLOAT_PFX;    break;
        !           337:                case 'p':
        !           338:                        optDoc |= PFX_0F;       break;
        !           339:                case 'm':
        !           340:                        optDoc |= MODRM_BYTE;   break;
        !           341:                case 'a':
        !           342:                        optDoc |= ADD_REG;      break;
        !           343:                case 'L':
        !           344:                        optDoc |= LOCK_OP;      break;
        !           345:                case 'l':
        !           346:                        optDoc |= AFTER_LOCK;   break;
        !           347:                case 'R':
        !           348:                        optDoc |= REP_INSTR;    break;
        !           349:                case 'r':
        !           350:                        optDoc |= AFTER_REP;    break;
        !           351:                case 'X':
        !           352:                        optDoc |= XTENDS;       break;
        !           353:                case 't':
        !           354:                        optDoc |= TWO_OP_MULT;  break;
        !           355:                case 'P':
        !           356:                        optDoc |= USE_REG;      break;
        !           357:                default:
        !           358:                        error("Illegal flag %x in '%s'", *p, optf);
        !           359:                        return;
        !           360:                }
        !           361:        }
        !           362: }
        !           363: 
        !           364: /* 
        !           365:  * pick a random production. 
        !           366:  * may retry if random production is wrong mode.
        !           367:  */
        !           368: static int
        !           369: pickRand(this)
        !           370: register oper *this;
        !           371: {
        !           372:        int i;
        !           373:        char c, *p, state, work[20];
        !           374: 
        !           375:        if (bswitch && this->badct) {
        !           376:                p = this->badlist;
        !           377:                i = randl() % this->badct;
        !           378:        }
        !           379:        else {
        !           380:                p = this->goodlist;
        !           381:                i = randl() % this->goodct;
        !           382:        }
        !           383: 
        !           384:        for (state = 0; c = *p; p++) {
        !           385:                if (state) {
        !           386:                        if (isspace(c))
        !           387:                                state = 0;
        !           388:                        continue;
        !           389:                }
        !           390:                if (isspace(c))
        !           391:                        continue;
        !           392:                if (!i--)
        !           393:                        break;
        !           394:                state = 1;
        !           395:        }
        !           396: 
        !           397:        if (!c)
        !           398:                error("Logic error in produce");
        !           399: 
        !           400:        /* put it out finding any internal productions */
        !           401:        for (i = 0;;) {
        !           402:                if (('%' == (c = *p++)) || isalnum(c)) {
        !           403:                        work[i++] = c;
        !           404:                        continue;
        !           405:                }
        !           406:                if (i) {        /* we have a word */
        !           407:                        work[i] = '\0';
        !           408:                        i = 0;
        !           409:                        if(!produce(work))
        !           410:                                return (0);
        !           411:                }
        !           412:                if (!c || isspace(c))
        !           413:                        break;
        !           414:                fputc(c, otp);
        !           415:                if (',' == c)
        !           416:                        fputc(' ', otp);
        !           417:        }
        !           418:        return (1);
        !           419: }
        !           420: 
        !           421: /*
        !           422:  * Produce an operand. Returns 1 on success 0 for a wrong
        !           423:  * production for a limited test. That is if we are testing
        !           424:  * all small stuff this returns 0 is asked to produce %eax
        !           425:  */
        !           426: static int
        !           427: produce(n)
        !           428: char *n;
        !           429: {
        !           430:        register int j;
        !           431:        register oper *this;
        !           432: 
        !           433: #ifdef TRACE
        !           434:        fprintf(otp, "{%s}", n);
        !           435: #endif
        !           436:        for (j = 0; j < operct; j++) {
        !           437:                this = opertab + j;
        !           438: 
        !           439:                if (!strcmp(n, this->name)) {
        !           440:                        if (lswitch && !(this->flag & X_LARGE))
        !           441:                                return (0);     /* fail */
        !           442:                        if (sswitch && !(this->flag & X_SMALL))
        !           443:                                return (0);     /* fail */
        !           444: 
        !           445:                        while (!pickRand(this))
        !           446:                                ;
        !           447:                        return (1);
        !           448:                }
        !           449:        }
        !           450: 
        !           451:        if (sswitch && ('%' == n[0])) /* remove % from regs is small tst */
        !           452:                n++;
        !           453: 
        !           454:        fprintf(otp, "%s", n);
        !           455:        return (1);
        !           456: }
        !           457: 
        !           458: /*
        !           459:  * make test file entrys.
        !           460:  */
        !           461: static void
        !           462: makeTst(n, j)
        !           463: char *n;
        !           464: {
        !           465:        register funs *f;
        !           466:        register opts *this;
        !           467:        register int i;
        !           468: 
        !           469: 
        !           470:        this = optab + j;
        !           471:        f = funtab + this->fun;
        !           472: 
        !           473:        /* can we do this */
        !           474:        if (lswitch)    /* large only test */
        !           475:                for (i = 0; i < f->operands; i++)
        !           476:                        if (!(opertab[f->ap[i]].flag & X_LARGE))
        !           477:                                return;
        !           478: 
        !           479:        if (sswitch)    /* small only test */
        !           480:                for (i = 0; i < f->operands; i++)
        !           481:                        if (!(opertab[f->ap[i]].flag & X_SMALL))
        !           482:                                return;
        !           483: 
        !           484:        if ((tmask && !(f->opt & tmask)) || (f->opt & nmask))
        !           485:                return;
        !           486: 
        !           487:        fprintf(otp, "\t%s\t", n);
        !           488:        if (sswitch) {  /* reverse operands */
        !           489:                for (i = f->operands; i--; ) {
        !           490:                        if (1 != (f->operands - i))
        !           491:                                fprintf(otp, ", ");
        !           492:                        produce(opertab[f->ap[i]].name);
        !           493:                }
        !           494:        }
        !           495:        else {          
        !           496:                for (i = 0; i < f->operands; i++) {
        !           497:                        if (i)
        !           498:                                fprintf(otp, ", ");
        !           499:                        produce(opertab[f->ap[i]].name);
        !           500:                }
        !           501:        }
        !           502:        fprintf(otp, "\t/ %04x %04x\n", opt, opcode);
        !           503: }
        !           504: 
        !           505: /*
        !           506:  * Produce Document lines.
        !           507:  */
        !           508: void
        !           509: makeDoc(f)
        !           510: register funs *f;
        !           511: {
        !           512:        int i;
        !           513: 
        !           514:        if (-1 == curgen)
        !           515:                fprintf(odp, "%s %d 2!", opc, lineno);
        !           516:        else
        !           517:                fprintf(odp, "%s %d 1!", thisGen, lineno);
        !           518: 
        !           519:        if (optDoc & PFX_0F)
        !           520:                fprintf(odp, "0F ");
        !           521: 
        !           522:        if (optDoc & FLOAT_PFX)
        !           523:                fprintf(odp, "9B ");
        !           524: 
        !           525:        if ((opcode & 0xff00) || (optDoc & MODRM_BYTE))
        !           526:                fprintf(odp, "%02x ", (opcode >> 8) & 255);
        !           527: 
        !           528:        if (optDoc & MODRM_BYTE)
        !           529:                fprintf(odp, "/%o", opcode & 7);
        !           530:        else
        !           531:                fprintf(odp, "%02x", opcode & 255);
        !           532: 
        !           533:        if (optDoc & USE_REG)
        !           534:                fprintf(odp, " /r");
        !           535: 
        !           536:        if (optDoc & ADD_REG)
        !           537:                fprintf(odp, " +r");
        !           538: 
        !           539:        fprintf(odp, "\t\\fB%s\\fR", opc);
        !           540: 
        !           541:        if (f->operands) {
        !           542:                fprintf(odp, "\t\\fI");
        !           543:                for (i = 0; i < f->operands; i++) {
        !           544:                        char *n = opertab[f->ap[i]].name;
        !           545: 
        !           546:                        if (i)
        !           547:                                fprintf(odp, ",");
        !           548: 
        !           549:                        fprintf(odp, "%s", strcmp(n, "atdx") ? n : "(dx)");
        !           550:                }
        !           551:                fprintf(odp, "\\fR");
        !           552:        }
        !           553:        if (*comment) {
        !           554:                if (!f->operands)
        !           555:                        fprintf(odp, "\t");
        !           556:                fprintf(odp, "\t%s", comment);
        !           557:        }
        !           558:        fputc('\n', odp);
        !           559: }
        !           560: 
        !           561: /*
        !           562:  * Build opcode and function entrys.
        !           563:  */
        !           564: opBld()
        !           565: {
        !           566:        char operand[3][10];
        !           567:        register opts *this;
        !           568:        register funs *f;
        !           569:        int i, j, k;
        !           570: 
        !           571:        /* m[0-9]+ are all really m at this level */
        !           572:        strcpy(operand[0], op1);
        !           573:        strcpy(operand[1], op2);
        !           574:        strcpy(operand[2], op3);
        !           575:        for (i = 0; i < 3; i++) {
        !           576:                if ('m' == operand[i][0] && 
        !           577:                    '0' <= operand[i][1] &&
        !           578:                    '9' >= operand[i][1])
        !           579:                        strcpy(operand[i], "m8");
        !           580:        }
        !           581: 
        !           582:        if (operand[2][0]) {
        !           583:                ct = 3;
        !           584:                sprintf(fname, "S_%04x_%s_%s_%s",
        !           585:                        opt, operand[0], operand[1], operand[2]);
        !           586:        }
        !           587:        else if (operand[1][0]) {
        !           588:                ct = 2;
        !           589:                sprintf(fname, "S_%04x_%s_%s", opt, operand[0], operand[1]);
        !           590:        }
        !           591:        else if (operand[0][0]) {
        !           592:                ct = 1;
        !           593:                sprintf(fname, "S_%04x_%s", opt, operand[0]);
        !           594:        }
        !           595:        else {
        !           596:                ct = 0;
        !           597:                sprintf(fname, "S_%04x", opt);
        !           598:        }
        !           599: 
        !           600:        for (j = 0; j < funct; j++)
        !           601:                if (!strcmp(funtab[j].name, fname)) {
        !           602:                        f = funtab + j;
        !           603:                        break;
        !           604:                }
        !           605: 
        !           606:        if (j == funct) {       /* not found build one */
        !           607:                EXPAND(fun);
        !           608:                f = funtab + j;
        !           609:                f->name = newcpy(fname);
        !           610:                f->opt = opt;
        !           611:                f->operands = ct;
        !           612:                f->type = "OP";
        !           613:                f->ap[0] = findOpr(operand[0]);
        !           614:                f->ap[1] = findOpr(operand[1]);
        !           615:                f->ap[2] = findOpr(operand[2]);
        !           616:        }
        !           617: 
        !           618:        i = opct;
        !           619:        EXPAND(op);
        !           620:        this = optab + i;
        !           621: 
        !           622:        for (k = 0; k < i; k++) {
        !           623:                if (!strcmp(optab[k].name, opc)) {
        !           624:                        this->name = optab[k].name;
        !           625:                        break;
        !           626:                }
        !           627:        }
        !           628: 
        !           629:        if (k == i)
        !           630:                this->name = newcpy(opc);
        !           631: 
        !           632:        this->fun = j;
        !           633:        this->opcode = opcode;
        !           634:        this->gen = curgen;
        !           635:        this->hash = -2;
        !           636:        this->lineno = lineno;
        !           637: 
        !           638:        if (!(opt & AMBIG_MATCH)) {
        !           639:                makeTst(opc, i);
        !           640:                makeDoc(f);
        !           641:        }
        !           642: }
        !           643: 
        !           644: /*
        !           645:  * Find operand on table or report error.
        !           646:  */
        !           647: findOpr(name)
        !           648: char *name;
        !           649: {
        !           650:        int i;
        !           651: 
        !           652:        if (!name[0])
        !           653:                return (-1);
        !           654: 
        !           655:        for (i = 0; i < operct; i++)
        !           656:                if (!strcmp(opertab[i].name, name))
        !           657:                        return (i);
        !           658: 
        !           659:        error("undefined operand %s", name);
        !           660: }
        !           661: 
        !           662: /*
        !           663:  * Comparison routine by inverse name length, then name, then order given.
        !           664:  */
        !           665: compr1(p1, p2)
        !           666: register opts *p1, *p2;
        !           667: {
        !           668:        register i;
        !           669: 
        !           670:        /* long names then short */
        !           671:        if (i = strlen(p2->name) - strlen(p1->name))
        !           672:                return (i);
        !           673: 
        !           674:        /* alpha order */
        !           675:        if (i = strcmp(p1->name, p2->name))
        !           676:                return(i);
        !           677: 
        !           678:        return (p1->lineno - p2->lineno); /* in order given */
        !           679: }
        !           680: 
        !           681: /*
        !           682:  * Comparison routine by name length, then name, then input position.
        !           683:  */
        !           684: compr2(p1, p2)
        !           685: register opts *p1, *p2;
        !           686: {
        !           687:        register i;
        !           688: 
        !           689:        /* short names then long */
        !           690:        if (i = strlen(p1->name) - strlen(p2->name))
        !           691:                return (i);
        !           692: 
        !           693:        /* alpha order */
        !           694:        if (i = strcmp(p1->name, p2->name))
        !           695:                return (i);
        !           696: 
        !           697:        return (p1->lineno - p2->lineno); /* in order given */
        !           698: }
        !           699: 
        !           700: /*
        !           701:  * Organize tables.
        !           702:  */
        !           703: reorgData()
        !           704: {
        !           705:        register opts *this, *that, *last;
        !           706:        char *p;
        !           707:        int i, j, k;
        !           708: 
        !           709:        /* sort for creating allntab */
        !           710:        qsort(optab, opct, sizeof(*optab), compr1);
        !           711: 
        !           712:        for (i = 0; i < opct; i++) { /* scan opcodes */
        !           713:                this = optab + i;
        !           714: 
        !           715:                this->len = k = strlen(this->name);
        !           716:                if (NULL == (p = strstr(allntab, this->name))) {
        !           717:                        /* if name not on list build */
        !           718:                        j = allnct;
        !           719:                        NEWN(alln, k);
        !           720:                        strcpy(allntab + j, this->name);
        !           721:                }
        !           722:                else
        !           723:                        j = p - allntab;
        !           724: 
        !           725:                this->pt = j;
        !           726:        }
        !           727: 
        !           728:        /* sort for creating prefTab */
        !           729:        qsort(optab, opct, sizeof(*optab), compr2);
        !           730: 
        !           731:        for (last = optab, nameCt = i = 0; i < opct; i++) { /* scan opcodes */
        !           732:                this = optab + i;
        !           733:                this->lineno = -1;
        !           734:                this->count  = 0;
        !           735:                if (-1 == this->fun) { /* general name */
        !           736:                        /* scan for reference */
        !           737:                        for (j = 0; j < opct; j++) {
        !           738:                                that = optab + j;
        !           739:                                if (-2 != that->hash ||
        !           740:                                    this->gen != that->gen)
        !           741:                                        continue;
        !           742:                                that->gen = i;  /* general ref marked */
        !           743:                                that->hash = -1;
        !           744:                                this->count++;
        !           745:                                if (!strcmp(this->name, that->name))
        !           746:                                        that->hash = -3; /* no unique name */
        !           747:                        }
        !           748:                }
        !           749: 
        !           750:                /* 
        !           751:                 * count names and mark first name in seq
        !           752:                 * by leaving its pointer and count intact.
        !           753:                 */
        !           754:                if (strcmp(last->name, this->name)) {
        !           755:                        if (!last->count)
        !           756:                                last->count = this - last;
        !           757:                        last = this;
        !           758:                        nameCt++;
        !           759:                }
        !           760:                else
        !           761:                        this->pt = this->len = 0;
        !           762:        }
        !           763:        last->count = (this - last) + 1;
        !           764: }
        !           765: 
        !           766: /*
        !           767:  * Output all tables.
        !           768:  */
        !           769: outData()
        !           770: {
        !           771:        register opts *this, *that;
        !           772:        register funs *f;
        !           773:        regs *r;
        !           774:        char *p, work[20];
        !           775:        int i, j, k, l;
        !           776: 
        !           777:        fprintf(ohp, "/*\n");
        !           778:        fprintf(ohp, " * 80386 assembler header file.\n");
        !           779:        fprintf(ohp, " * Generated by tabbld\n");
        !           780:        fprintf(ohp, " */\n\n");
        !           781: 
        !           782:        fprintf(ofp, "/*\n");
        !           783:        fprintf(ofp, " * 80386 assembler table file.\n");
        !           784:        fprintf(ofp, " * Generated by tabbld\n");
        !           785:        fprintf(ofp, " */\n");
        !           786:        fprintf(ofp, "#include <stdio.h>\n");
        !           787:        fprintf(ofp, "#include <asm.h>\n");
        !           788:        fprintf(ofp, "#include <y_tab.h>\n");
        !           789:        fprintf(ofp, "#include <symtab.h>\n\n");
        !           790: 
        !           791:        fprintf(ohp, "/* operand types */\n");
        !           792:        /* dump base operand types */
        !           793:        for (i = 0; i < operct; i++)
        !           794:                if (j = opertab[i].base)
        !           795:                        fprintf(ohp, "#define %-9s %2d\n", opertab[i].name, j);
        !           796: 
        !           797:        /* dump function table */
        !           798:        fprintf(ohp, "\n/* instruction types */\n");
        !           799:        fprintf(ofp, "readonly symt typTab[] = {\n");
        !           800:        for (i = 0; i < funct;) {
        !           801:                f = funtab + i;
        !           802:                fprintf(ohp, "#define %-21s %2d\n", f->name, i);
        !           803:                fprintf(ofp, " /* %-21s */ { %10s, 0x%04x, %d",
        !           804:                        f->name,
        !           805:                        f->type,
        !           806:                        f->opt & 0xffff,
        !           807:                        f->operands);
        !           808:                for (j = 0; j < f->operands; j++)
        !           809:                        fprintf(ofp, ", %s", opertab[f->ap[j]].name);
        !           810:                fprintf(ofp, " }%s\n", ((++i < funct) ? "," : ""));
        !           811:        }
        !           812:        fprintf(ofp, "};\n\n");
        !           813: 
        !           814:        /* dump the name hash */
        !           815:        fprintf(ofp, "readonly char charLump[] = {");
        !           816:        i = 0;
        !           817:        for (p = allntab; *p;) {
        !           818:                switch (i++) {
        !           819:                case 0:
        !           820:                        fprintf(ofp, "\n\t");
        !           821:                        break;
        !           822:                case 10:
        !           823:                        i = 0;
        !           824:                default:
        !           825:                        fprintf(ofp, " ");
        !           826:                }
        !           827:                fprintf(ofp, "'%c'", *p++);
        !           828:                if (*p)
        !           829:                        fprintf(ofp, ",");
        !           830:        }
        !           831:        fprintf(ofp, "\n};\n\n");
        !           832: 
        !           833:        /*
        !           834:         * dump preftab first generic opcodes then regular.
        !           835:         * opcode is now used to point to the preftab address.
        !           836:         * for generic opcodes.
        !           837:         * lineno is now used tp point to the preftab address
        !           838:         * for processed opcodes that need hash pointers
        !           839:         * and zero for other processed opcodes.
        !           840:         */
        !           841:        fprintf(ofp, "readonly opc prefTab[] = {\n");
        !           842:        for (lastp = i = 0; i < opct; i++) {
        !           843:                this = optab + i;
        !           844:                if (this->fun != -1)    /* non generic opcode */
        !           845:                        continue;
        !           846: 
        !           847:                work[0] = '\0';
        !           848:                this->opcode = lastp;
        !           849: 
        !           850:                fputc('\n', ofp);
        !           851:                for (j = 0; j < opct; j++) {
        !           852:                        that = optab + j;
        !           853:                        if (that->gen != i || that->fun == -1)
        !           854:                                continue;
        !           855:                        that->lineno = 0;
        !           856:                        /* remember first of each name */
        !           857:                        if(strcmp(work, that->name)) {
        !           858:                                k = j;
        !           859:                                optab[k].lineno = l = lastp;
        !           860:                                strcpy(work, that->name);
        !           861:                        }
        !           862:                        fprintf(ofp,
        !           863:                                "\t{ 0x%04x, %21s },\t/* %-10s %d */\n",
        !           864:                                that->opcode & 0xffff,
        !           865:                                funtab[that->fun].name,
        !           866:                                that->name,
        !           867:                                lastp);
        !           868:                        lastp++;
        !           869:                }
        !           870:        }
        !           871:        fputc('\n', ofp);
        !           872: 
        !           873:        /* do non generic opcodes */
        !           874:        for (i = 0; i < opct; i++) {
        !           875:                this = optab + i;
        !           876:                /* regular first opcode */
        !           877:                if (this->fun != -1 && this->len) {
        !           878:                        if (-1 != this->lineno) { /* matches end of generic */
        !           879:                                this->opcode = this->lineno;
        !           880:                                continue;
        !           881:                        }
        !           882:                        k = lastp;      /* save lastp */
        !           883:                        for (j = i; j < opct;) {
        !           884:                                that = optab + j;
        !           885:                                if (strcmp(this->name, that->name))
        !           886:                                        break;
        !           887:                                if (-1 == that->fun) {
        !           888:                                        errors++;
        !           889:                                        fprintf(stderr, "odd order %s",
        !           890:                                                that->name);
        !           891:                                        break;
        !           892:                                }
        !           893:                                fprintf(ofp,
        !           894:                                   "\t{ 0x%04x, %21s }%s\t/* %-10s %d */\n",
        !           895:                                        that->opcode & 0xffff,
        !           896:                                        funtab[that->fun].name,
        !           897:                                        ((++j != opct) ? "," : ""),
        !           898:                                        that->name,
        !           899:                                        lastp);
        !           900:                                lastp++;
        !           901:                        }
        !           902:                        this->opcode = k;
        !           903:                }
        !           904:        }
        !           905:        fprintf(ofp, "};\n\n");
        !           906: 
        !           907:        free(funtab);
        !           908: 
        !           909:        /* set up hash table to mark */
        !           910:        htab = alloc(nameCt * sizeof(*htab));
        !           911:        fprintf(ohp, "#define OPCOUNT %d /* count of opcodes */\n", nameCt);
        !           912: 
        !           913:        for (i = 0; i < nameCt; i++)
        !           914:                htab[i] = -1;
        !           915: 
        !           916:        /* mark all items that hash direct */
        !           917:        for (i = 0; i < opct; i++) {
        !           918:                this = optab + i;
        !           919: 
        !           920:                this->hash = -2;
        !           921:                if (!this->len)
        !           922:                        continue;
        !           923:                memcpy(work, allntab + this->pt, this->len);
        !           924:                work[this->len] = '\0';
        !           925:                j = hash(work) % nameCt;
        !           926: 
        !           927:                if (htab[j] != -1) {    /* hole taken get it next pass */
        !           928:                        this->hash = -1;
        !           929:                        continue;
        !           930:                }
        !           931:                htab[j] = i;    /* hash table points to entry */
        !           932:        }
        !           933: 
        !           934:        /* mark items that hash indirect */
        !           935:        for (i = 0; i < opct; i++) {
        !           936:                this = optab + i;
        !           937:                if (-1 != this->hash)   /* pass unmarked items */
        !           938:                        continue;
        !           939: 
        !           940:                 /* find a hole */
        !           941:                for (k = 0;(k < nameCt) && (htab[k] != -1); k++)
        !           942:                        ;
        !           943:                if (k == nameCt) {
        !           944:                        errors++;
        !           945:                        fprintf(stderr, "Insufficient holes in table");
        !           946:                        continue;
        !           947:                }
        !           948:                htab[k] = i;    /* hash table points to entry */
        !           949: 
        !           950:                /* where does this hash to */
        !           951:                memcpy(work, allntab + this->pt, this->len);
        !           952:                work[this->len] = '\0';
        !           953:                j = hash(work) % nameCt;
        !           954: 
        !           955:                /* find the end of the chain */
        !           956:                while(-2 != (j = (that = optab + htab[j])->hash))
        !           957:                        ;
        !           958: 
        !           959:                that->hash = k;
        !           960:                this->hash = -2;
        !           961:        }
        !           962: 
        !           963:        fprintf(ofp, "readonly nhash hashCodes[] = {\n");
        !           964:        for (i = 0; i < nameCt;) {
        !           965:                j = htab[i++];
        !           966:                if (j < 0 || j > opct) {
        !           967:                        errors++;
        !           968:                        fprintf(stderr, "Unplaned hole in table");
        !           969:                        fprintf(ofp, "\t{-1, 0, 0, 0, 0 }, /* JUNK */\n");
        !           970:                        continue;
        !           971:                }
        !           972:                this = optab + j;
        !           973: 
        !           974:                memcpy(work, allntab + this->pt, this->len);
        !           975:                work[this->len] = '\0';
        !           976:                fprintf(ofp, "\t{%4d, %4d, %2d, %2d, %4d }%c /* %-12s %d */\n",
        !           977:                        ((this->hash < 0) ? -1 : this->hash),
        !           978:                        this->pt,
        !           979:                        this->len,
        !           980:                        this->count,    /* entries on pref table */
        !           981:                        this->opcode,   /* entry on pref table */
        !           982:                        ((i == nameCt) ? ' ' : ','),
        !           983:                        work,
        !           984:                        i - 1);
        !           985:        }
        !           986:        fprintf(ofp, "};\n\n");
        !           987: 
        !           988:        fprintf(ohp,
        !           989:                "#define SYMCOUNT %d\t/* count of predefined symbols */\n",
        !           990:                regct + 1);
        !           991: 
        !           992:        fprintf(ofp, "psym symtab[] = {\n");
        !           993:        fprintf(ofp,    /* too fancy for the basic mechinism */
        !           994:                "\t{NULL, IDENTIFIER, 0, 0, 1, 0, symtab, 0, 0, \".\" },\n");
        !           995:        for (i = 0; i < regct; ) {
        !           996:                r = regtab + i++;
        !           997: 
        !           998:                j = 0;
        !           999:                if (NULL == strstr(r->ytype, "REG"))
        !          1000:                        strcpy(work, r->name);
        !          1001:                else {
        !          1002:                        sprintf(work, "%%%s", r->name);
        !          1003:                        switch(r->ytype[0]) {
        !          1004:                        case 'S':       /* SEG_REG */
        !          1005:                                j = 0x800;
        !          1006:                                break;
        !          1007:                        case 'C':       /* CTL_REG */
        !          1008:                                j = 0x400;
        !          1009:                                break;
        !          1010:                        case 'D':       /* DEB_REG */
        !          1011:                                j = 0x200;
        !          1012:                                break;
        !          1013:                        case 'T':       /* TST_REG */
        !          1014:                                j = 0x100;
        !          1015:                                break;
        !          1016:                        }
        !          1017:                        r->ytype = "REG";
        !          1018:                }
        !          1019:                fprintf(ofp,
        !          1020:                  "\t{ NULL, %10s, %d, %d, 0, %d, NULL, 0, 0, \"%s\" }%s\n",
        !          1021:                  r->ytype,
        !          1022:                  r->loc,
        !          1023:                  r->len,
        !          1024:                  j,
        !          1025:                  work,
        !          1026:                  ((i < regct) ? "," : ""));
        !          1027:        }
        !          1028:        fprintf(ofp, "};\n");
        !          1029: }
        !          1030: 
        !          1031: /*
        !          1032:  * Process opcode files.
        !          1033:  */
        !          1034: main(argc, argv)
        !          1035: char *argv[];
        !          1036: {
        !          1037:        int c, subtest;
        !          1038:        extern char *optarg;
        !          1039:        extern int optind;
        !          1040: 
        !          1041:        for (subtest = 0; EOF != (c = getopt(argc, argv, "blst:n:?"));) {
        !          1042:                subtest = 1;    /* any options are a subtest */
        !          1043:                switch (c) {
        !          1044:                case 'b':
        !          1045:                        bswitch = 1;
        !          1046:                        break;
        !          1047:                case 'l':
        !          1048:                        lswitch = 1;
        !          1049:                        break;
        !          1050:                case 's':
        !          1051:                        sswitch = 1;
        !          1052:                        break;
        !          1053:                case 't':
        !          1054:                        sscanf(optarg, "%x", &tmask);
        !          1055:                        break;
        !          1056:                case 'n':
        !          1057:                        sscanf(optarg, "%x", &nmask);
        !          1058:                        break;
        !          1059:                case '?':
        !          1060:                default:
        !          1061:                        fprintf(stderr,
        !          1062:         "usage: tabbld [-bls] [-t bits_to_match] [-n bits_not_to_match]\n");
        !          1063:                        exit (1);
        !          1064:                }
        !          1065:        }
        !          1066:                        
        !          1067:        /*
        !          1068:         * These are nessisary as long as this runs small model.
        !          1069:         * otherwise this thing runs out of space.
        !          1070:         */
        !          1071:        START(op,  1000);
        !          1072:        START(fun, 250);
        !          1073:        START(oper, 100);
        !          1074:        START(alln, 2000);
        !          1075:        START(reg, 100);
        !          1076: 
        !          1077:        otp = xopen("test.s", "w");
        !          1078:        if (subtest) {
        !          1079:                fprintf(otp, "\t.ttl\tSubtest of asm 386 ");
        !          1080:                if (bswitch | lswitch | sswitch)
        !          1081:                        fputc('-', otp);
        !          1082:                if (bswitch)
        !          1083:                        fputc('b', otp);
        !          1084:                if (lswitch)
        !          1085:                        fputc('t', otp);
        !          1086:                if (sswitch)
        !          1087:                        fputc('s', otp);
        !          1088:                if (tmask)
        !          1089:                        fprintf(otp, " -t %x", tmask);
        !          1090:                if (nmask)
        !          1091:                        fprintf(otp, " -n %x", nmask);
        !          1092:                fputc('\n', otp);
        !          1093:                odp = ohp = ofp = xopen("/dev/null", "w");
        !          1094:        }
        !          1095:        else {
        !          1096:                fprintf(otp, "\t.ttl\tFull test of asm 386\n");
        !          1097:                ofp = xopen("symtab.c", "w");   /* symbol table */
        !          1098:                ohp = xopen("symtab.h", "w");   /* header file */
        !          1099:                odp = xopen("document", "w");   /* document file */
        !          1100:        }
        !          1101:        fprintf(otp, "\t.llen\t100\n");
        !          1102:        fprintf(otp, "abc:\n");
        !          1103:        
        !          1104:        /*
        !          1105:         * Process file.
        !          1106:         */
        !          1107:        while (NULL != (line = getline(stdin, &lineno))) {
        !          1108:                switch (*line) {
        !          1109:                case '+':
        !          1110:                        sscanf(line + 2, "%d", &state);
        !          1111:                        continue;
        !          1112:                case 0:
        !          1113:                        if (1 == state) {       /* pass through comments */
        !          1114:                                if (-1 == curgen)
        !          1115:                                        fprintf(odp, "%s %d 2!\t%s\n",
        !          1116:                                                ((optDoc & INDEF_JMP) ? "ja" : opc),
        !          1117:                                                lineno, comment);
        !          1118:                                else
        !          1119:                                        fprintf(odp, "%s %d 1!\t%s\n",
        !          1120:                                                thisGen, lineno, comment);
        !          1121:                        }
        !          1122:                        continue;
        !          1123:                }
        !          1124:                switch(state) {
        !          1125:                case 0: /* test stream directives. */
        !          1126:                        buildTst();
        !          1127:                        break;
        !          1128:                case 1: /* opcodes */
        !          1129:                        buildOp();
        !          1130:                        break;
        !          1131:                case 2: /* registers */
        !          1132:                        buildReg();
        !          1133:                        break;
        !          1134:                case 3: /* assembler directives */
        !          1135:                        buildDir();
        !          1136:                }
        !          1137:        }
        !          1138:        fclose(otp);
        !          1139: 
        !          1140:        if (subtest)
        !          1141:                return (0);
        !          1142: 
        !          1143:        reorgData();
        !          1144:        outData();
        !          1145:        if (errors)
        !          1146:                fprintf(stderr, "%d error%c detected\n", errors, 
        !          1147:                        (1 == errors) ? ' ' : 's');
        !          1148:        showStats(errors ? 1 : 0);
        !          1149: 
        !          1150:        return (0);
        !          1151: }

unix.superglobalmegacorp.com

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