📄 gencode.c
字号:
expand_opcode (shift, val, i, s) int shift; int val; int i; char *s;{ int j; if (*s == 0) { table[val] = i; } else { switch (s[0]) { case '0': case '1': { int m, mv; val |= bton (s) << shift; if (s[2] == '0' || s[2] == '1') expand_opcode (shift - 4, val, i, s + 4); else if (s[2] == 'N') for (j = 0; j < 4; j++) expand_opcode (shift - 4, val | (j << shift), i, s + 4); else if (s[2] == 'x') for (j = 0; j < 4; j += 2) for (m = 0; m < 32; m++) { /* Ignore illegal nopy */ if ((m & 7) == 0 && m != 0) continue; mv = m & 3 | (m & 4) << 2 | (m & 8) << 3 | (m & 16) << 4; expand_opcode (shift - 4, val | mv | (j << shift), i, s + 4); } else if (s[2] == 'y') for (j = 0; j < 2; j++) expand_opcode (shift - 4, val | (j << shift), i, s + 4); break; } case 'n': case 'm': for (j = 0; j < 16; j++) { expand_opcode (shift - 4, val | (j << shift), i, s + 4); } break; case 'M': /* A1, A0,X0,X1,Y0,Y1,M0,A1G,M1,M1G */ for (j = 5; j < 16; j++) if (j != 6) expand_opcode (shift - 4, val | (j << shift), i, s + 4); break; case 'G': /* A1G, A0G: */ for (j = 13; j <= 15; j +=2) expand_opcode (shift - 4, val | (j << shift), i, s + 4); break; case 's': /* System registers mach, macl, pr: */ for (j = 0; j < 3; j++) expand_opcode (shift - 4, val | (j << shift), i, s + 4); /* System registers fpul, fpscr/dsr, a0, x0, x1, y0, y1: */ for (j = 5; j < 12; j++) expand_opcode (shift - 4, val | (j << shift), i, s + 4); break; case 'X': case 'a': val |= bton (s) << shift; for (j = 0; j < 16; j += 8) expand_opcode (shift - 4, val | (j << shift), i, s + 4); break; case 'Y': case 'A': val |= bton (s) << shift; for (j = 0; j < 8; j += 4) expand_opcode (shift - 4, val | (j << shift), i, s + 4); break; default: for (j = 0; j < (1 << (shift + 4)); j++) { table[val | j] = i; } } }}/* Print the jump table used to index an opcode into a switch statement entry. */static voiddumptable (name, size, start) char *name; int size; int start;{ int lump = 256; int online = 16; int i = start; printf ("unsigned char %s[%d]={\n", name, size); while (i < start + size) { int j = 0; printf ("/* 0x%x */\n", i); while (j < lump) { int k = 0; while (k < online) { printf ("%2d", table[i + j + k]); if (j + k < lump) printf (","); k++; } j += k; printf ("\n"); } i += j; } printf ("};\n");}static voidfilltable (p) op *p;{ static int index = 1; sorttab (); for (; p->name; p++) { p->index = index++; expand_opcode (12, 0, p->index, p->code); }}/* Table already contais all the switch case tags for 16-bit opcode double data transfer (ddt) insns, and the switch case tag for processing parallel processing insns (ppi) for code 0xf800 (ppi nopx nopy). Copy the latter tag to represent all combinations of ppi with ddt. */static voidppi_moves (){ int i; for (i = 0xf000; i < 0xf400; i++) if (table[i]) table[i + 0x800] = table[0xf800];}static voidgensim_caselist (p) op *p;{ for (; p->name; p++) { int j; int sextbit = -1; int needm = 0; int needn = 0; char *s = p->code; printf (" /* %s %s */\n", p->name, p->code); printf (" case %d: \n", p->index); printf (" {\n"); while (*s) { switch (*s) { case '0': case '1': s += 2; break; case '.': s += 4; break; case 'n': printf (" int n = (iword >>8) & 0xf;\n"); needn = 1; s += 4; break; case 'N': printf (" int n = (((iword >> 8) - 2) & 0x3) + 2;\n"); s += 2; break; case 'x': printf (" int n = ((iword >> 9) & 1) + 4;\n"); needn = 1; s += 2; break; case 'y': printf (" int n = ((iword >> 8) & 1) + 4;\n"); needn = 1; s += 2; break; case 'm': needm = 1; case 's': case 'M': case 'G': printf (" int m = (iword >>4) & 0xf;\n"); s += 4; break; case 'X': printf (" int m = ((iword >> 7) & 1) + 8;\n"); s += 2; break; case 'a': printf (" int m = 7 - ((iword >> 6) & 2);\n"); s += 2; break; case 'Y': printf (" int m = ((iword >> 6) & 1) + 10;\n"); s += 2; break; case 'A': printf (" int m = 7 - ((iword >> 5) & 2);\n"); s += 2; break; case 'i': printf (" int i = (iword & 0x"); switch (s[1]) { case '4': printf ("f"); break; case '8': printf ("ff"); break; case '1': sextbit = 12; printf ("fff"); break; } printf (")"); switch (s[3]) { case '1': break; case '2': printf ("<<1"); break; case '4': printf ("<<2"); break; } printf (";\n"); s += 4; } } if (sextbit > 0) { printf (" i = (i ^ (1<<%d))-(1<<%d);\n", sextbit - 1, sextbit - 1); } if (needm && needn) printf (" TB(m,n);\n"); else if (needm) printf (" TL(m);\n"); else if (needn) printf (" TL(n);\n"); { /* Do the refs */ char *r; for (r = p->refs; *r; r++) { if (*r == '0') printf(" CREF(0);\n"); if (*r == '8') printf(" CREF(8);\n"); if (*r == '9') printf(" CREF(9);\n"); if (*r == 'n') printf(" CREF(n);\n"); if (*r == 'm') printf(" CREF(m);\n"); } } printf (" {\n"); for (j = 0; j < MAX_NR_STUFF; j++) { if (p->stuff[j]) { printf (" %s\n", p->stuff[j]); } } printf (" }\n"); { /* Do the defs */ char *r; for (r = p->defs; *r; r++) { if (*r == '0') printf(" CDEF(0);\n"); if (*r == 'n') printf(" CDEF(n);\n"); if (*r == 'm') printf(" CDEF(m);\n"); } } printf (" break;\n"); printf (" }\n"); }}static voidgensim (){ printf ("{\n"); printf (" switch (jump_table[iword]) {\n"); gensim_caselist (tab); gensim_caselist (movsxy_tab); printf (" default:\n"); printf (" {\n"); printf (" RAISE_EXCEPTION (SIGILL);\n"); printf (" }\n"); printf (" }\n"); printf ("}\n");}static voidgendefines (){ op *p; filltable (tab); for (p = tab; p->name; p++) { char *s = p->name; printf ("#define OPC_"); while (*s) { if (isupper(*s)) *s = tolower(*s); if (isalpha(*s)) printf("%c", *s); if (*s == ' ') printf("_"); if (*s == '@') printf("ind_"); if (*s == ',') printf("_"); s++; } printf(" %d\n",p->index); }}static int ppi_index;/* Take an ppi code, expand all varying fields in it and fill all the right entries in 'table' with the opcode index. */static voidexpand_ppi_code (val, i, s) int val; int i; char *s;{ int j; for (;;) { switch (s[0]) { /* The last eight bits are disregarded for the switch table. */ case 'm': case 'x': case '.': table[val] = i; return; case '0': val += val; s++; break; case '1': val += val + 1; s++; break; case 'i': case 'e': case 'f': val += val; s++; expand_ppi_code (val, i, s); val++; break; case 'c': val <<= 2; s += 2; val++; expand_ppi_code (val, ppi_index++, s); val++; expand_ppi_code (val, i, s); val++; break; } }}static voidppi_filltable (){ op *p; ppi_index = 1; for (p = ppi_tab; p->name; p++) { p->index = ppi_index++; expand_ppi_code (0, p->index, p->code); }}static voidppi_gensim (){ op *p = ppi_tab; printf ("#define DSR_MASK_G 0x80\n"); printf ("#define DSR_MASK_Z 0x40\n"); printf ("#define DSR_MASK_N 0x20\n"); printf ("#define DSR_MASK_V 0x10\n"); printf ("\n"); printf ("#define COMPUTE_OVERFLOW do {\\\n"); printf (" overflow = res_grd != SIGN32 (res) ? DSR_MASK_V : 0; \\\n"); printf (" if (overflow && S) \\\n"); printf (" { \\\n"); printf (" if (res_grd & 0x80) \\\n"); printf (" { \\\n"); printf (" res = 0x80000000; \\\n"); printf (" res_grd |= 0xff; \\\n"); printf (" } \\\n"); printf (" else \\\n"); printf (" { \\\n"); printf (" res = 0x7fffffff; \\\n"); printf (" res_grd &= ~0xff; \\\n"); printf (" } \\\n"); printf (" overflow = 0; \\\n"); printf (" } \\\n"); printf ("} while (0)\n"); printf ("\n"); printf ("#define ADD_SUB_GE \\\n"); printf (" (greater_equal = ~(overflow << 3 & res_grd) & DSR_MASK_G)\n"); printf ("\n"); printf ("static void\n"); printf ("ppi_insn (iword)\n"); printf (" int iword;\n"); printf ("{\n"); printf (" static char e_tab[] = { 8, 9, 10, 5};\n"); printf (" static char f_tab[] = {10, 11, 8, 5};\n"); printf (" static char x_tab[] = { 8, 9, 7, 5};\n"); printf (" static char y_tab[] = {10, 11, 12, 14};\n"); printf (" static char g_tab[] = {12, 14, 7, 5};\n"); printf (" static char u_tab[] = { 8, 10, 7, 5};\n"); printf ("\n"); printf (" int z;\n"); printf (" int res, res_grd;\n"); printf (" int carry, overflow, greater_equal;\n"); printf ("\n"); printf (" switch (ppi_table[iword >> 8]) {\n"); for (; p->name; p++) { int shift, j; int cond = 0; int havedecl = 0; char *s = p->code; printf (" /* %s %s */\n", p->name, p->code); printf (" case %d: \n", p->index); printf (" {\n"); for (shift = 16; *s; ) { switch (*s) { case 'i': printf (" int i = (iword >> 4) & 0x7f;\n"); s += 6; break; case 'e': case 'f': case 'x': case 'y': case 'g': case 'u': shift -= 2; printf (" int %c = %c_tab[(iword >> %d) & 3];\n", *s, *s, shift); havedecl = 1; s += 2; break; case 'c': printf (" if ((((iword >> 8) ^ DSR) & 1) == 0)\n"); printf ("\tbreak;\n"); printf (" }\n"); printf (" case %d: \n", p->index + 1); printf (" {\n"); cond = 1; case '0': case '1': case '.': shift -= 2; s += 2; break; case 'z': if (havedecl) printf ("\n"); printf (" z = iword & 0xf;\n"); havedecl = 2; s += 4; break; } } if (havedecl == 1) printf ("\n"); else if (havedecl == 2) printf (" {\n"); for (j = 0; j < MAX_NR_STUFF; j++) { if (p->stuff[j]) { printf (" %s%s\n", (havedecl == 2 ? " " : ""), p->stuff[j]); } } if (havedecl == 2) printf (" }\n"); if (cond) { printf (" if (iword & 0x200)\n"); printf (" goto assign_z;\n"); } printf (" break;\n"); printf (" }\n"); } printf (" default:\n"); printf (" {\n"); printf (" RAISE_EXCEPTION (SIGILL);\n"); printf (" return;\n"); printf (" }\n"); printf (" }\n"); printf (" DSR &= ~0xf1;\n"); printf (" if (res || res_grd)\n"); printf (" DSR |= greater_equal | res_grd >> 2 & DSR_MASK_N | overflow;\n"); printf (" else\n"); printf (" DSR |= DSR_MASK_Z | overflow;\n"); printf (" assign_dc:\n"); printf (" switch (DSR >> 1 & 7)\n"); printf (" {\n"); printf (" case 0: /* Carry Mode */\n"); printf (" DSR |= carry;\n"); printf (" case 1: /* Negative Value Mode */\n"); printf (" DSR |= res_grd >> 7 & 1;\n"); printf (" case 2: /* Zero Value Mode */\n"); printf (" DSR |= DSR >> 6 & 1;\n"); printf (" case 3: /* Overflow mode\n"); printf (" DSR |= overflow >> 4;\n"); printf (" case 4: /* Signed Greater Than Mode */\n"); printf (" DSR |= DSR >> 7 & 1;\n"); printf (" case 4: /* Signed Greater Than Or Equal Mode */\n"); printf (" DSR |= greater_equal >> 7;\n"); printf (" }\n"); printf (" assign_z:\n"); printf (" if (0xa05f >> z & 1)\n"); printf (" {\n"); printf (" RAISE_EXCEPTION (SIGILL);\n"); printf (" return;\n"); printf (" }\n"); printf (" DSP_R (z) = res;\n"); printf (" DSP_GRD (z) = res_grd;\n"); printf ("}\n");}intmain (ac, av) int ac; char **av;{ /* verify the table before anything else */ { op *p; for (p = tab; p->name; p++) { /* check that the code field contains 16 bits */ if (strlen (p->code) != 16) { fprintf (stderr, "Code `%s' length wrong (%d) for `%s'\n", p->code, strlen (p->code), p->name); abort (); } } } /* now generate the requested data */ if (ac > 1) { if (strcmp (av[1], "-t") == 0) { gengastab (); } else if (strcmp (av[1], "-d") == 0) { gendefines (); } else if (strcmp (av[1], "-s") == 0) { filltable (tab); dumptable ("sh_jump_table", 1 << 16, 0); memset (table, 0, sizeof table); filltable (movsxy_tab); ppi_moves (); dumptable ("sh_dsp_table", 1 << 12, 0xf000); memset (table, 0, sizeof table); ppi_filltable (); dumptable ("ppi_table", 1 << 8, 0); } else if (strcmp (av[1], "-x") == 0) { filltable (tab); filltable (movsxy_tab); gensim (); } else if (strcmp (av[1], "-p") == 0) { ppi_filltable (); ppi_gensim (); } } else fprintf (stderr, "Opcode table generation no longer supported.\n"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -