home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / smmaclnk.ark / MIT.C < prev    next >
Text File  |  1987-09-10  |  4KB  |  127 lines

  1. /*
  2. ** mit.c -- machine instruction table functions
  3. **
  4. **         mitndx[]      mitptr[]      mitnxt[]
  5. **          _____         _____         _____
  6. **         |__|__|       |__|__|       |__|__|
  7. **         |__|__|       |__|__|       |__|__|<-+
  8. ** hash -> |__|__|   ->  |__|__|       |__|__|  |
  9. **         |__|__|       |__|__|       |__|__|--+
  10. **         |__|__|       |__|__|       |__|__|
  11. **                           |
  12. **                           v
  13. **                           mnemonic  variant..
  14. **                           __        |
  15. **                          |__|...00  vlen   optr    fmt    obj...
  16. **                                      __   _____   _____   __
  17. **    format bits (<-)                 |__| |__|__| |__|__| |__|...
  18. **      3-bit instr length (-1)                |
  19. **      field types                            v
  20. **        0 = obj byte                         operand pattern
  21. **      001 = 8-bit expr                       __
  22. **      011 = 8-bit pc rel expr               |  |...00
  23. **      101 = 16-bit expr                      --
  24. **      111 = 16-bit pc rel expr
  25. **
  26. */
  27. #include <stdio.h>
  28. #include "mac.h"    /* must be included first */
  29. /*
  30. #define NOCCARGC
  31. */
  32. int
  33.   opadj,            /* operation code adjustment */
  34.   hashval;            /* global hash value for speed */
  35. char
  36.   expbuf[MAXLINE];        /* buffer for operand expressions */
  37.  
  38. extern int
  39.   mitable,            /* machine instruction table (size) */
  40.   mitndx[],            /* mit indices ( hash -> which */
  41.   mitnxt[],            /* mit synonym chain */
  42.   mitptr[];            /* mnemonic syntax ptrs */
  43.  
  44. extern char
  45.   mitbuf;            /* instruction syntax buffer */
  46.  
  47. extern int
  48.   looks;            /* number of looks to find it */
  49.  
  50. hash(ptr, cnt) char *ptr; int cnt; {     /* calculate hash value */
  51.   hashval = 0;
  52.   while(*ptr > ' ' && atend(*ptr) == 0)
  53.     hashval = (hashval << 1) + toupper(*ptr++);
  54.   return (hashval % cnt);
  55.   }
  56.  
  57. find(inst) char *inst; {    /* search for instr in mit */
  58.   char *mit;
  59.   int h, ndx;
  60.   looks = 0;
  61.   ndx = mitndx[h = hash(inst, MICOUNT)];    /* calc hash index */
  62.   while(ndx != EOF) {
  63.     ++looks;
  64.     if(fldcmp(inst, mit = mitptr[ndx]) == 0) {    /* mnemonic matches */
  65.       inst = skip(2, inst);            /* instr operand field */
  66.       mit += strlen(mit) + 1;            /* first variant */
  67.       while(*mit++) {                /* another variant? */
  68.     ++looks;
  69.     if(match(inst, getint(mit))) return (mit);
  70.     mit += *(mit - 1);            /* next variant */
  71.     }
  72.       return (0);
  73.       }
  74.     if((h = mitnxt[h]) == EOF) return (0);
  75.     ndx = mitndx[h];
  76.     }
  77.   return (0);
  78.   }
  79.  
  80. match(inst, mit) char *inst, *mit; {    /* match operands to mit */
  81.   char *backup, *exp; int nest;
  82.   opadj = 0;
  83.   backup = inst;
  84.   if(mit == 0) {
  85.     if(atend(*inst)) return (YES);
  86.     return (NO);
  87.     }
  88.   exp = expbuf;                /* init expr buffer */
  89.   while(YES) {
  90.     while(isspace(*inst)) ++inst;
  91.     while(isspace(*mit)) ++mit;
  92.     if(atend(*inst)) {
  93.       if(atend(*mit) || *mit == ANOTHER) return (YES);
  94.       goto next;
  95.       }
  96.     if(atend(*mit)) return (NO);
  97.     if(islower(*mit)) {            /* expression */
  98.       ++mit;                /* bump past x or y */
  99.       nest = 0;
  100.       while(!atend(*inst)) {        /* bypass expression */
  101.     if(*inst == ',') break;
  102.     if(*inst == ')' && nest == 0) break;
  103.     switch(*inst) {
  104.       case '(': ++nest; break;
  105.       case ')': --nest;
  106.       }
  107.     *exp++ = *inst++;        /* extract expressions */
  108.     }
  109.       *exp++ = ','; *exp = NULL;    /* terminate expression */
  110.       continue;
  111.       }
  112.     if(lexorder(*inst++, *mit++)) {
  113.       next:
  114.       while(*mit) {
  115.     if(*mit == ANOTHER) {        /* end of syntax for this try */
  116.       ++opadj;            /* bump opcode adjustment */
  117.       ++mit; inst = backup;        /* setup next try */
  118.       exp = expbuf;            /* reset expr buffer pointer */
  119.       break;
  120.       }
  121.     ++mit;
  122.     }
  123.       if(atend(*mit)) return (NO);
  124.       }
  125.     }
  126.   }
  127. buf;            /