1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Read 68000 CPU specs from file "table68k" and build table68k.c
5 *
6 * Copyright 1995,1996 Bernd Schmidt
7 */
8
9 #include "sysconfig.h"
10 #include "sysdeps.h"
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <assert.h>
15 #include <ctype.h>
16
17 #define TCHAR char
18
19 #include "readcpu.h"
20
21 static FILE *tablef;
22 static int nextch = 0;
23
getnextch(void)24 static void getnextch(void)
25 {
26 do {
27 nextch = fgetc(tablef);
28 if (nextch == '%') {
29 do {
30 nextch = fgetc(tablef);
31 } while (nextch != EOF && nextch != '\n');
32 }
33 } while (nextch != EOF && isspace(nextch));
34 }
35
nextchtohex(void)36 static int nextchtohex(void)
37 {
38 switch (isupper (nextch) ? tolower (nextch) : nextch) {
39 case '0': return 0;
40 case '1': return 1;
41 case '2': return 2;
42 case '3': return 3;
43 case '4': return 4;
44 case '5': return 5;
45 case '6': return 6;
46 case '7': return 7;
47 case '8': return 8;
48 case '9': return 9;
49 case 'a': return 10;
50 case 'b': return 11;
51 case 'c': return 12;
52 case 'd': return 13;
53 case 'e': return 14;
54 case 'f': return 15;
55 default: abort();
56 }
57 }
58
main(int argc,char ** argv)59 int main(int argc, char **argv)
60 {
61 int no_insns = 0;
62
63 printf ("#include \"sysconfig.h\"\n");
64 printf ("#include \"sysdeps.h\"\n");
65 printf ("#include \"readcpu.h\"\n");
66 printf ("struct instr_def defs68k[] = {\n");
67 #if 0
68 tablef = fopen("table68k","r");
69 if (tablef == NULL) {
70 fprintf(stderr, "table68k not found\n");
71 exit(1);
72 }
73 #else
74 tablef = stdin;
75 #endif
76 getnextch();
77 while (nextch != EOF) {
78 int cpulevel, uncpulevel, plevel, sduse;
79 int i;
80
81 char opcstr[256];
82 int bitpos[16];
83 int flagset[5], flaguse[5];
84
85 unsigned int bitmask,bitpattern;
86 int n_variable;
87
88 int head = 0, tail = 0, clocks = 0, fetchmode = 0;
89
90 n_variable = 0;
91 bitmask = bitpattern = 0;
92 memset (bitpos, 0, sizeof(bitpos));
93 for(i=0; i<16; i++) {
94 int currbit;
95 bitmask <<= 1;
96 bitpattern <<= 1;
97
98 switch (nextch) {
99 case '0': currbit = bit0; bitmask |= 1; break;
100 case '1': currbit = bit1; bitmask |= 1; bitpattern |= 1; break;
101 case 'c': currbit = bitc; break;
102 case 'C': currbit = bitC; break;
103 case 'f': currbit = bitf; break;
104 case 'i': currbit = biti; break;
105 case 'I': currbit = bitI; break;
106 case 'j': currbit = bitj; break;
107 case 'J': currbit = bitJ; break;
108 case 'k': currbit = bitk; break;
109 case 'K': currbit = bitK; break;
110 case 's': currbit = bits; break;
111 case 'S': currbit = bitS; break;
112 case 'd': currbit = bitd; break;
113 case 'D': currbit = bitD; break;
114 case 'r': currbit = bitr; break;
115 case 'R': currbit = bitR; break;
116 case 'z': currbit = bitz; break;
117 case 'p': currbit = bitp; break;
118 default: abort();
119 }
120 if (!(bitmask & 1)) {
121 bitpos[n_variable] = currbit;
122 n_variable++;
123 }
124
125 if (nextch == '0' || nextch == '1')
126 bitmask |= 1;
127 if (nextch == '1')
128 bitpattern |= 1;
129 getnextch();
130 }
131
132 while (isspace(nextch) || nextch == ':') /* Get CPU level, unimplemented level, and privilege level */
133 getnextch();
134
135 switch (nextch) {
136 case '0': cpulevel = 0; break;
137 case '1': cpulevel = 1; break;
138 case '2': cpulevel = 2; break;
139 case '3': cpulevel = 3; break;
140 case '4': cpulevel = 4; break;
141 case '5': cpulevel = 5; break;
142 case '6': cpulevel = 6; break;
143 case '7': cpulevel = 7; break;
144 default: abort();
145 }
146 getnextch();
147
148 switch (nextch) {
149 case '0': uncpulevel = 0; break;
150 case '1': uncpulevel = 1; break;
151 case '2': uncpulevel = 2; break;
152 case '3': uncpulevel = 3; break;
153 case '4': uncpulevel = 4; break;
154 case '5': uncpulevel = 5; break;
155 case '6': uncpulevel = 6; break;
156 case '7': uncpulevel = 7; break;
157 default: abort();
158 }
159 getnextch();
160
161 switch (nextch) {
162 case '0': plevel = 0; break;
163 case '1': plevel = 1; break;
164 case '2': plevel = 2; break;
165 case '3': plevel = 3; break;
166 default: abort();
167 }
168 getnextch();
169
170 while (isspace(nextch)) /* Get flag set information */
171 getnextch();
172
173 if (nextch != ':')
174 abort();
175
176 for(i = 0; i < 5; i++) {
177 getnextch();
178 switch(nextch){
179 case '-': flagset[i] = fa_unset; break;
180 case '/': flagset[i] = fa_isjmp; break;
181 case '+': flagset[i] = fa_isbranch; break;
182 case '0': flagset[i] = fa_zero; break;
183 case '1': flagset[i] = fa_one; break;
184 case 'x': flagset[i] = fa_dontcare; break;
185 case '?': flagset[i] = fa_unknown; break;
186 default: flagset[i] = fa_set; break;
187 }
188 }
189
190 getnextch();
191 while (isspace(nextch))
192 getnextch();
193
194 if (nextch != ':') /* Get flag used information */
195 abort();
196
197 for(i = 0; i < 5; i++) {
198 getnextch();
199 switch(nextch){
200 case '-': flaguse[i] = fu_unused; break;
201 case '/': flaguse[i] = fu_isjmp; break;
202 case '+': flaguse[i] = fu_maybecc; break;
203 case '?': flaguse[i] = fu_unknown; break;
204 default: flaguse[i] = fu_used; break;
205 }
206 }
207
208 getnextch();
209 while (isspace(nextch))
210 getnextch();
211
212 if (nextch != ':') /* Get source/dest usage information */
213 abort();
214
215 getnextch();
216 sduse = nextchtohex() << 4;
217 getnextch();
218 sduse |= nextchtohex();
219
220 getnextch();
221 while (isspace(nextch))
222 getnextch();
223
224 if (nextch != ':')
225 abort();
226
227 if (fgets(opcstr, 250, tablef) != opcstr) {
228 abort();
229 }
230 getnextch();
231
232 if (nextch == '-') {
233 int neg;
234 char fm[20];
235 getnextch();
236 while (isspace(nextch))
237 getnextch();
238 neg = 1;
239 if (nextch == '-') {
240 neg = -1;
241 getnextch();
242 }
243 for (;;) {
244 if (nextch < '0' || nextch > '9')
245 break;
246 head *= 10;
247 head += nextch - '0';
248 nextch = fgetc (tablef);
249 }
250 head *= neg;
251 while (isspace(nextch))
252 getnextch();
253 for (;;) {
254 if (nextch < '0' || nextch > '9')
255 break;
256 tail *= 10;
257 tail += nextch - '0';
258 nextch = fgetc (tablef);
259 }
260 while (isspace(nextch))
261 getnextch();
262 for (;;) {
263 if (nextch < '0' || nextch > '9')
264 break;
265 clocks *= 10;
266 clocks += nextch - '0';
267 nextch = fgetc (tablef);
268 }
269 if (nextch == ' ') {
270 if (fgets(fm, sizeof fm, tablef) != fm) {
271 abort();
272 }
273 if (!strnicmp(fm, "fea", 3))
274 fetchmode = 1;
275 if (!strnicmp(fm, "cea", 3))
276 fetchmode = 2;
277 if (!strnicmp(fm, "fiea", 4))
278 fetchmode = 3;
279 if (!strnicmp(fm, "ciea", 4))
280 fetchmode = 4;
281 if (!strnicmp(fm, "jea", 3))
282 fetchmode = 5;
283 }
284 getnextch();
285 }
286
287 int j;
288 /* Remove superfluous spaces from the string */
289 char *opstrp = opcstr, *osendp;
290 char tmp[100], *p;
291 int slen = 0;
292
293 while (isspace(*opstrp))
294 opstrp++;
295
296 osendp = opstrp;
297 while (*osendp) {
298 if (!isspace (*osendp))
299 slen = osendp - opstrp + 1;
300 osendp++;
301 }
302 opstrp[slen] = 0;
303
304 if (no_insns > 0)
305 printf(",\n");
306 no_insns++;
307 strcpy (tmp, opstrp);
308 strcat (tmp, " ");
309 p = tmp;
310 while (!isspace(*p++));
311 *p = 0;
312 printf("/* %s */\n", tmp);
313 printf("{0x%04X,%2d,{", bitpattern, n_variable);
314 for (j = 0; j < 16; j++) {
315 printf("%2d", bitpos[j]);
316 if (j < 15)
317 printf(",");
318 }
319 printf ("},0x%04X,%d,%d,%d,{", bitmask, cpulevel, uncpulevel, plevel);
320 for(i = 0; i < 5; i++) {
321 printf("{%d,%d}%s", flaguse[i], flagset[i], i == 4 ? "" : ",");
322 }
323 printf("},0x%02x,_T(\"%s\"),%2d,%2d,%2d,%2d}", sduse, opstrp, head, tail, clocks, fetchmode);
324 }
325 printf("};\nint n_defs68k = %d;\n", no_insns);
326 return 0;
327 }
328