home *** CD-ROM | disk | FTP | other *** search
- /*
- ** mit.c -- machine instruction table functions
- **
- ** mitndx[] mitptr[] mitnxt[]
- ** _____ _____ _____
- ** |__|__| |__|__| |__|__|
- ** |__|__| |__|__| |__|__|<-+
- ** hash -> |__|__| -> |__|__| |__|__| |
- ** |__|__| |__|__| |__|__|--+
- ** |__|__| |__|__| |__|__|
- ** |
- ** v
- ** mnemonic variant..
- ** __ |
- ** |__|...00 vlen optr fmt obj...
- ** __ _____ _____ __
- ** format bits (<-) |__| |__|__| |__|__| |__|...
- ** 3-bit instr length (-1) |
- ** field types v
- ** 0 = obj byte operand pattern
- ** 001 = 8-bit expr __
- ** 011 = 8-bit pc rel expr | |...00
- ** 101 = 16-bit expr --
- ** 111 = 16-bit pc rel expr
- **
- */
- #include <stdio.h>
- #include "mac.h" /* must be included first */
- /*
- #define NOCCARGC
- */
- int
- opadj, /* operation code adjustment */
- hashval; /* global hash value for speed */
- char
- expbuf[MAXLINE]; /* buffer for operand expressions */
-
- extern int
- mitable, /* machine instruction table (size) */
- mitndx[], /* mit indices ( hash -> which */
- mitnxt[], /* mit synonym chain */
- mitptr[]; /* mnemonic syntax ptrs */
-
- extern char
- mitbuf; /* instruction syntax buffer */
-
- extern int
- looks; /* number of looks to find it */
-
- hash(ptr, cnt) char *ptr; int cnt; { /* calculate hash value */
- hashval = 0;
- while(*ptr > ' ' && atend(*ptr) == 0)
- hashval = (hashval << 1) + toupper(*ptr++);
- return (hashval % cnt);
- }
-
- find(inst) char *inst; { /* search for instr in mit */
- char *mit;
- int h, ndx;
- looks = 0;
- ndx = mitndx[h = hash(inst, MICOUNT)]; /* calc hash index */
- while(ndx != EOF) {
- ++looks;
- if(fldcmp(inst, mit = mitptr[ndx]) == 0) { /* mnemonic matches */
- inst = skip(2, inst); /* instr operand field */
- mit += strlen(mit) + 1; /* first variant */
- while(*mit++) { /* another variant? */
- ++looks;
- if(match(inst, getint(mit))) return (mit);
- mit += *(mit - 1); /* next variant */
- }
- return (0);
- }
- if((h = mitnxt[h]) == EOF) return (0);
- ndx = mitndx[h];
- }
- return (0);
- }
-
- match(inst, mit) char *inst, *mit; { /* match operands to mit */
- char *backup, *exp; int nest;
- opadj = 0;
- backup = inst;
- if(mit == 0) {
- if(atend(*inst)) return (YES);
- return (NO);
- }
- exp = expbuf; /* init expr buffer */
- while(YES) {
- while(isspace(*inst)) ++inst;
- while(isspace(*mit)) ++mit;
- if(atend(*inst)) {
- if(atend(*mit) || *mit == ANOTHER) return (YES);
- goto next;
- }
- if(atend(*mit)) return (NO);
- if(islower(*mit)) { /* expression */
- ++mit; /* bump past x or y */
- nest = 0;
- while(!atend(*inst)) { /* bypass expression */
- if(*inst == ',') break;
- if(*inst == ')' && nest == 0) break;
- switch(*inst) {
- case '(': ++nest; break;
- case ')': --nest;
- }
- *exp++ = *inst++; /* extract expressions */
- }
- *exp++ = ','; *exp = NULL; /* terminate expression */
- continue;
- }
- if(lexorder(*inst++, *mit++)) {
- next:
- while(*mit) {
- if(*mit == ANOTHER) { /* end of syntax for this try */
- ++opadj; /* bump opcode adjustment */
- ++mit; inst = backup; /* setup next try */
- exp = expbuf; /* reset expr buffer pointer */
- break;
- }
- ++mit;
- }
- if(atend(*mit)) return (NO);
- }
- }
- }
- buf; /