home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <string.h>
- #include "ytab.h"
- #include "global.h"
-
- #define HASH_SIZE 1009
- #define NUMOF(a) (sizeof(a)/sizeof((a)[0]))
-
- char *ops[] =
- {
- "abcdS", "addaS", "addiS", "addqS", "addxS", "addS", "andiS", "andS",
- "aslS", "aslS", "bchgS", "bclrS", "bC", "bsetS", "bsrS", "btstS",
- "chkS", "clrS", "cmpaS", "cmpiS", "cmpmS", "cmpS", "dbC", "dbfS",
- "dbtS", "divsS", "divuS", "eoriS", "eorS", "exgS", "extS", "jmpS",
- "jsrS", "jC", "leaS", "link", "lslS", "lsrS", "moveaS", "movemS",
- "movepS", "moveqS", "moveS", "movaS", "movmS", "movpS", "movqS", "movS",
- "mulsS", "muluS", "nbcdS", "negxS", "negS", "nop", "notS", "oriS", "orS",
- "peaS", "reset", "rolS", "rorS", "roxlS", "roxrS", "rte", "rtr",
- "rts", "sC", "sfS", "sfS", "sbcdS", "stop", "subaS", "subiS",
- "subqS", "subxS", "subS", "swapS", "tasS", "trap", "trapv", "tstS",
- "unlk"
- }, *ccodes[] =
- {"ra", "eq", "ne", "ge", "gt", "le", "lt", "cc", "hi", "ls", "cs",
- "hs", "lo", "mi", "pl", "vc", "vs"};
- Hash directives[] =
- {
- {".abort", "", D_UNS, 0},
- {".align", "", D_UNS, 0},
- {".ascii", ".dc.b", D_SLIST, 0},
- {".asciz", ".dc.b", D_SLIST, 0},
- {".byte", ".dc.b", D_ELIST, 0},
- {".comm", ".comm", D_COMM, 0},
- {".data", ".data", D_OPTINT, 0},
- {".desc", "", D_UNS, 0},
- {".double", "", D_UNS, 0},
- {".even", ".even", D_NONE, 0},
- {".file", "", D_UNS, 0},
- {".line", "", D_UNS, 0},
- {".fill", "", D_UNS, 0},
- {".float", "", D_UNS, 0},
- {".globl", ".globl", D_IDLIST, 0},
- {".global", ".globl", D_IDLIST, 0},
- {".int", ".dc.l", D_ELIST, 0},
- {".lcomm", ".ds.b", D_LCOMM, 0},
- {".long", ".dc.l", D_ELIST, 0},
- {".lsym", "", D_UNS, 0},
- {".octa", "", D_UNS, 0},
- {".org", ".org", D_ORG, 0},
- {".set", ".equ", D_COMM, 0},
- {".short", ".dc.w", D_ELIST, 0},
- {".space", "", D_UNS, 0},
- {".text", ".text", D_OPTINT, 0},
- {".word", ".dc.w", D_ELIST, 0}
- };
-
- static Hash *htable[HASH_SIZE];
-
- static unsigned int
- hash(s)
- register char *s;
- {
- register unsigned int t = 0;
-
- for (; *s; s++)
- t = (t * 33 + (*s)) % HASH_SIZE;
- return t;
- }
-
- void
- mkhash(tok, map, type)
- char *tok, *map;
- int type;
- {
- Hash *h, *H;
- unsigned int i;
- h = (Hash *)malloc(sizeof (Hash));
-
- h->htext = strdup(tok);
- h->mapto = strdup(map);
- h->htype = type;
- h->next = 0;
- i = hash(tok);
- if (!htable[i])
- htable[i] = h;
- else {
- for (H = htable[i]; H->next; H = H->next) ;
- H->next = h;
- }
- }
-
- static void
- do_S(s)
- char *s;
- {
- static char buf1[12], buf2[12];
- char *s1, *s2, *s0 = s;
- int type = OP;
-
- for (s1 = buf1, s2 = buf2; *s != 'S';)
- *s1++ = *s2++ = *s++;
- if (*s0 == 'j' && !(s0[1] == 'm' || s0[1] == 's'))
- *buf2 = 'b';
- if (*s0 == 'm' && s0[1] == 'o') {
- if (s0[3] != 'e') {
- buf2[3] = 'e';
- s2 = buf2 + 4;
- if (s0[3] != 'S')
- *s2++ = s0[3];
- }
- if (s2[-1] == 'm')
- type = OP_MREG;
- }
- *s1 = *s2 = '\0';
- mkhash(buf1, buf2, type);
- *s2++ = '.';
- *(s1 + 1) = *(s2 + 1) = '\0';
- *s1 = *s2 = 'b';
- mkhash(buf1, buf2, type);
- *s1 = *s2 = 'w';
- mkhash(buf1, buf2, type);
- *s1 = *s2 = 'l';
- mkhash(buf1, buf2, type);
- }
-
- static void
- do_C(s)
- char *s;
- {
- static char buf[12];
- int i;
- char *s1;
-
- for (s1 = buf; *s != 'C';)
- *s1++ = *s++;
- *(s1 + 2) = 'S';
- *(s1 + 3) = '\0';
- for (i = 0; i < NUMOF(ccodes); i++) {
- *s1 = ccodes[i][0];
- *(s1 + 1) = ccodes[i][1];
- do_S(buf);
- }
- }
-
- static void
- do_ops()
- {
- int i;
- char c;
-
- for (i = 0; i < NUMOF(ops); i++) {
- c = ops[i][strlen(ops[i]) - 1];
- if (c == 'C')
- do_C(ops[i]);
- else if (c == 'S')
- do_S(ops[i]);
- else
- mkhash(ops[i], ops[i], OP);
- }
- }
-
- void
- init_hash()
- {
- int i;
- char buf[3];
-
- for (i = 0; i < HASH_SIZE; i++)
- htable[i] = 0;
- for (i = 0; i < NUMOF(directives); i++)
- mkhash(directives[i].htext, directives[i].mapto, directives[i].htype);
- do_ops();
- for (buf[0] = 'd', buf[1] = '0', buf[2] = '\0'; buf[1] <= '7'; buf[1]++)
- mkhash(buf, buf, REG);
- for (buf[0] = 'a', buf[1] = '0'; buf[1] <= '7'; buf[1]++)
- mkhash(buf, buf, REG);
- mkhash("pc", "pc", REG);
- mkhash("sp", "sp", REG);
- mkhash("usp", "usp", REG);
- mkhash("sr", "sr", REG);
- mkhash("ccr", "ccr", REG);
- }
-
- int
- lookup(tag, subst)
- char *tag, *subst;
- {
- Hash *h;
-
- for (h = htable[hash(tag)]; h; h = h->next)
- if (!strcmp(tag, h->htext)) {
- strcpy(subst, h->mapto);
- return h->htype;
- }
- return 0;
- }
-
- void
- clear_hash()
- {
- Hash *h, *q;
- int i;
-
- for (i = 0; i < HASH_SIZE; i++)
- for (h = htable[i]; h; h = q) {
- q = h->next;
- free(h->htext);
- free(h->mapto);
- free(h);
- }
- }
-