|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68000 emulation generator
5: *
6: * This is a fairly stupid program that generates a lot of case labels that
7: * can be #included in a switch statement.
8: * As an alternative, it can generate functions that handle specific
9: * MC68000 instructions, plus a prototype header file and a function pointer
10: * array to look up the function for an opcode.
11: * Error checking is bad, an illegal table68k file will cause the program to
12: * call abort().
13: * The generated code is sometimes sub-optimal, an optimizing compiler should
14: * take care of this.
15: *
16: * (c) 1995 Bernd Schmidt
17: *
18: */
19:
20: #include <assert.h>
21: #include <string.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <ctype.h>
25:
26: #include "config.h"
27: #include "amiga.h"
28:
29: typedef enum {
30: Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r,
31: absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg
32: } amodes;
33:
34: FILE *tablef;
35: int nextch = 0;
36:
37: typedef enum {
38: i_ILLG,
39:
40: i_OR, i_AND, i_EOR, i_ORSR, i_ANDSR, i_EORSR,
41: i_SUB, i_SUBA, i_SUBX, i_SBCD,
42: i_ADD, i_ADDA, i_ADDX, i_ABCD,
43: i_NEG, i_NEGX, i_NBCD, i_CLR, i_NOT, i_TST,
44: i_BTST, i_BCHG, i_BCLR, i_BSET,
45: i_CMP, i_CMPM, i_CMPA,
46: i_MOVEP, i_MOVE, i_MOVEA, i_MVSR2, i_MV2SR,
47: i_SWAP, i_EXG, i_EXT, i_MVMEL, i_MVMLE,
48: i_TRAP, i_MVR2USP, i_MVUSP2R, i_RESET, i_NOP, i_STOP, i_RTE, i_RTD,
49: i_LINK, i_UNLK,
50: i_RTS, i_TRAPV, i_RTR,
51: i_JSR, i_JMP, i_BSR, i_Bcc,
52: i_LEA, i_PEA, i_DBcc, i_Scc,
53: i_DIVU, i_DIVS, i_MULU, i_MULS,
54: i_ASR, i_ASL, i_LSR, i_LSL, i_ROL, i_ROR, i_ROXL, i_ROXR,
55: i_ASRW, i_ASLW, i_LSRW, i_LSLW, i_ROLW, i_RORW, i_ROXLW, i_ROXRW
56: } instrmnem;
57:
58: struct mnemolookup {
59: instrmnem mnemo;
60: char name[10];
61: } lookuptab[] = {
62: { i_OR, "OR" },
63: { i_AND, "AND" },
64: { i_EOR, "EOR" },
65: { i_ORSR, "ORSR" },
66: { i_ANDSR, "ANDSR" },
67: { i_EORSR, "EORSR" },
68: { i_SUB, "SUB" },
69: { i_SUBA, "SUBA" },
70: { i_SUBX, "SUBX" },
71: { i_SBCD, "SBCD" },
72: { i_ADD, "ADD" },
73: { i_ADDA, "ADDA" },
74: { i_ADDX, "ADDX" },
75: { i_ABCD, "ABCD" },
76: { i_NEG, "NEG" },
77: { i_NEGX, "NEGX" },
78: { i_NBCD, "NBCD" },
79: { i_CLR, "CLR" },
80: { i_NOT, "NOT" },
81: { i_TST, "TST" },
82: { i_BTST, "BTST" },
83: { i_BCHG, "BCHG" },
84: { i_BCLR, "BCLR" },
85: { i_BSET, "BSET" },
86: { i_CMP, "CMP" },
87: { i_CMPM, "CMPM" },
88: { i_CMPA, "CMPA" },
89: { i_MOVEP, "MOVEP" },
90: { i_MOVE, "MOVE" },
91: { i_MOVEA, "MOVEA" },
92: { i_MVSR2, "MVSR2" },
93: { i_MV2SR, "MV2SR" },
94: { i_SWAP, "SWAP" },
95: { i_EXG, "EXG" },
96: { i_EXT, "EXT" },
97: { i_MVMEL, "MVMEL" },
98: { i_MVMLE, "MVMLE" },
99: { i_TRAP, "TRAP" },
100: { i_MVR2USP, "MVR2USP" },
101: { i_MVUSP2R, "MVUSP2R" },
102: { i_RESET, "RESET" },
103: { i_NOP, "NOP" },
104: { i_STOP, "STOP" },
105: { i_RTE, "RTE" },
106: { i_RTD, "RTD" },
107: { i_LINK, "LINK" },
108: { i_UNLK, "UNLK" },
109: { i_RTS, "RTS" },
110: { i_TRAPV, "TRAPV" },
111: { i_RTR, "RTR" },
112: { i_JSR, "JSR" },
113: { i_JMP, "JMP" },
114: { i_BSR, "BSR" },
115: { i_Bcc, "Bcc" },
116: { i_LEA, "LEA" },
117: { i_PEA, "PEA" },
118: { i_DBcc, "DBcc" },
119: { i_Scc, "Scc" },
120: { i_DIVU, "DIVU" },
121: { i_DIVS, "DIVS" },
122: { i_MULU, "MULU" },
123: { i_MULS, "MULS" },
124: { i_ASR, "ASR" },
125: { i_ASL, "ASL" },
126: { i_LSR, "LSR" },
127: { i_LSL, "LSL" },
128: { i_ROL, "ROL" },
129: { i_ROR, "ROR" },
130: { i_ROXL, "ROXL" },
131: { i_ROXR, "ROXR" },
132: { i_ASRW, "ASRW" },
133: { i_ASLW, "ASLW" },
134: { i_LSRW, "LSRW" },
135: { i_LSLW, "LSLW" },
136: { i_ROLW, "ROLW" },
137: { i_RORW, "RORW" },
138: { i_ROXLW, "ROXLW" },
139: { i_ROXRW, "ROXRW" }
140: };
141:
142: char patbits[16];
143: char opcstr[256];
144:
145: UWORD bitmask,bitpattern;
146:
147: typedef enum {
148: bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bits, bitS, bitd, bitD, bitr, bitR, bitz, lastbit
149: } bitvals;
150:
151: typedef enum {
152: sz_unknown, sz_byte, sz_word, sz_long
153: } wordsizes;
154:
155: struct instr {
156: instrmnem mnemo;
157: wordsizes size;
158: amodes dmode, smode;
159: unsigned char dreg;
160: unsigned char sreg;
161: unsigned int suse:1;
162: unsigned int duse:1;
163: unsigned int sbtarg:1;
164: unsigned int generated:1;
165: unsigned int cc:4;
166: signed char dpos;
167: signed char spos;
168: UWORD handler;
169: } *table;
170:
171: #ifdef DEBUG
172: static void myabort(void)
173: {
174: abort();
175: }
176: #else
177: #define myabort abort
178: #endif
179: static void getnextch(void)
180: {
181: do {
182: nextch = fgetc(tablef);
183: if (nextch == '%') {
184: do {
185: nextch = fgetc(tablef);
186: } while (nextch != EOF && nextch != '\n');
187: }
188: } while (nextch != EOF && isspace(nextch));
189: }
190:
191: static void get_bits(void)
192: {
193: int i;
194:
195: bitmask = bitpattern = 0;
196: for(i=0; i<16; i++) {
197: bitmask <<= 1;
198: bitpattern <<= 1;
199: if (nextch == '0' || nextch == '1') bitmask |= 1;
200: if (nextch == '1') bitpattern |= 1;
201: patbits[i] = nextch;
202: getnextch();
203: }
204: }
205:
206: static amodes mode_from_str(char *str)
207: {
208: if (strncmp(str,"Dreg",4) == 0) return Dreg;
209: if (strncmp(str,"Areg",4) == 0) return Areg;
210: if (strncmp(str,"Aind",4) == 0) return Aind;
211: if (strncmp(str,"Apdi",4) == 0) return Apdi;
212: if (strncmp(str,"Aipi",4) == 0) return Aipi;
213: if (strncmp(str,"Ad16",4) == 0) return Ad16;
214: if (strncmp(str,"Ad8r",4) == 0) return Ad8r;
215: if (strncmp(str,"absw",4) == 0) return absw;
216: if (strncmp(str,"absl",4) == 0) return absl;
217: if (strncmp(str,"PC16",4) == 0) return PC16;
218: if (strncmp(str,"PC8r",4) == 0) return PC8r;
219: if (strncmp(str,"Immd",4) == 0) return imm;
220: myabort();
221: }
222:
223: static amodes mode_from_mr(int mode, int reg)
224: {
225: switch(mode) {
226: case 0: return Dreg;
227: case 1: return Areg;
228: case 2: return Aind;
229: case 3: return Aipi;
230: case 4: return Apdi;
231: case 5: return Ad16;
232: case 6: return Ad8r;
233: case 7:
234: switch(reg) {
235: case 0: return absw;
236: case 1: return absl;
237: case 2: return PC16;
238: case 3: return PC8r;
239: case 4: return imm;
240: case 5:
241: case 6:
242: case 7: return am_illg;
243: }
244: }
245: myabort();
246: }
247:
248: static void get_strs(void)
249: {
250: fgets(opcstr, 250, tablef);
251: getnextch();
252: }
253:
254: static void parse_bits(void)
255: {
256: int find;
257: long int opc;
258:
259: for(opc = 0; opc < 65536; opc ++) {
260: if ((opc & bitmask) == bitpattern) {
261: int bitcnt[lastbit];
262: int bitval[lastbit];
263: int bitpos[lastbit];
264: int i,j;
265:
266: UWORD msk = 0x8000;
267:
268: int pos = 0;
269:
270: int mnp = 0;
271: char mnemonic[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
272: wordsizes sz = sz_unknown;
273: bool srcgather = false, dstgather = false;
274: bool usesrc = false, usedst = false;
275: bool srcbtarg = false;
276: int srcpos, dstpos;
277:
278: amodes srcmode = am_unknown, destmode = am_unknown;
279: int srcreg, destreg;
280:
281: for(i=0; i < lastbit; i++) bitcnt[i] = bitval[i] = 0;
282:
283: for(j=0; j < 16; j++, msk >>= 1) {
284: bitvals currbit;
285: switch(patbits[j]) {
286: case '0': currbit = bit0; break;
287: case '1': currbit = bit1; break;
288: case 'c': currbit = bitc; break;
289: case 'C': currbit = bitC; break;
290: case 'f': currbit = bitf; break;
291: case 'i': currbit = biti; break;
292: case 'I': currbit = bitI; break;
293: case 'j': currbit = bitj; break;
294: case 'J': currbit = bitJ; break;
295: case 's': currbit = bits; break;
296: case 'S': currbit = bitS; break;
297: case 'd': currbit = bitd; break;
298: case 'D': currbit = bitD; break;
299: case 'r': currbit = bitr; break;
300: case 'R': currbit = bitR; break;
301: case 'z': currbit = bitz; break;
302: default: myabort();
303: }
304: bitpos[currbit] = 15 - j;
305: bitcnt[currbit]++;
306: bitval[currbit] = (bitval[currbit] << 1) | ((opc & msk) ? 1 : 0);
307: }
308: if (bitval[bitj] == 0) bitval[bitj] = 8;
309: /* first check whether this one does not match after all */
310: if (bitval[bitz] == 3) continue;
311: if (bitval[bitC] == 1) continue;
312: if (bitcnt[bitI] && bitval[bitI] == 0) continue;
313:
314: /* bitI and bitC get copied to biti and bitc */
315: if (bitcnt[bitI]) { bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; }
316: if (bitcnt[bitC]) bitval[bitc] = bitval[bitC];
317:
318: while (isspace(opcstr[pos]) || opcstr[pos] == ':') pos++;
319: while (!isspace(opcstr[pos])) {
320: if (opcstr[pos] == '.') {
321: pos++;
322: switch(opcstr[pos]) {
323:
324: case 'B': sz = sz_byte; break;
325: case 'W': sz = sz_word; break;
326: case 'L': sz = sz_long; break;
327: case 'z':
328: switch(bitval[bitz]) {
329: case 0: sz = sz_byte; break;
330: case 1: sz = sz_word; break;
331: case 2: sz = sz_long; break;
332: default: myabort();
333: }
334: break;
335: default: myabort();
336: }
337: } else {
338: mnemonic[mnp] = opcstr[pos];
339: if(mnemonic[mnp] == 'f') {
340: switch(bitval[bitf]) {
341: case 0: mnemonic[mnp] = 'R'; break;
342: case 1: mnemonic[mnp] = 'L'; break;
343: default: myabort();
344: }
345: }
346: mnp++;
347: }
348: pos++;
349: }
350:
351: /* now, we have read the mnemonic and the size */
352: while (isspace(opcstr[pos])) pos++;
353:
354: /* A goto a day keeps the D******a away. */
355: if (opcstr[pos] == 0 || opcstr[pos] == ':') goto endofline;
356:
357: /* parse the source address */
358: usesrc = true;
359: switch(opcstr[pos++]) {
360: case 'D':
361: srcmode = Dreg;
362: switch (opcstr[pos++]) {
363: case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break;
364: case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break;
365: default: myabort();
366: }
367:
368: break;
369: case 'A':
370: srcmode = Areg;
371: switch (opcstr[pos++]) {
372: case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break;
373: case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break;
374: default: myabort();
375: }
376: switch (opcstr[pos]) {
377: case 'p': srcmode = Apdi; pos++; break;
378: case 'P': srcmode = Aipi; pos++; break;
379: }
380: break;
381: case '#':
382: switch(opcstr[pos++]) {
383: case 'z': srcmode = imm; break;
384: case '0': srcmode = imm0; break;
385: case '1': srcmode = imm1; break;
386: case '2': srcmode = imm2; break;
387: case 'i': srcmode = immi; srcreg = (LONG)(BYTE)bitval[biti]; srcbtarg = true; srcgather = true; srcpos = bitpos[biti]; break;
388: case 'j': srcmode = immi; srcreg = bitval[bitj]; break;
389: case 'J': srcmode = immi; srcreg = bitval[bitJ]; break;
390: default: myabort();
391: }
392: break;
393: case 'd':
394: srcreg = bitval[bitD];
395: srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
396: if (srcmode == am_illg) continue;
397: if (srcmode == Areg || srcmode == Dreg || srcmode == Aind
398: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
399: || srcmode == Apdi)
400: {
401: srcgather = true; srcpos = bitpos[bitD];
402: }
403: if (opcstr[pos] == '[') {
404: pos++;
405: if (opcstr[pos] == '!') {
406: /* exclusion */
407: do {
408: pos++;
409: if (mode_from_str(opcstr+pos) == srcmode) goto nomatch;
410: pos += 4;
411: } while (opcstr[pos] == ',');
412: pos++;
413: } else {
414: if (opcstr[pos+4] == '-') {
415: /* replacement */
416: if (mode_from_str(opcstr+pos) == srcmode)
417: srcmode = mode_from_str(opcstr+pos+5);
418: else
419: goto nomatch;
420: pos += 10;
421: } else {
422: /* normal */
423: while(mode_from_str(opcstr+pos) != srcmode) {
424: pos += 4;
425: if (opcstr[pos] == ']') goto nomatch;
426: pos++;
427: }
428: while(opcstr[pos] != ']') pos++;
429: pos++;
430: break;
431: }
432: }
433: }
434: /* Some addressing modes are invalid as destination */
435: if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
436: goto nomatch;
437: break;
438: case 's':
439: srcreg = bitval[bitS];
440: srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
441:
442: if(srcmode == am_illg) continue;
443: if (srcmode == Areg || srcmode == Dreg || srcmode == Aind
444: || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
445: || srcmode == Apdi)
446: {
447: srcgather = true; srcpos = bitpos[bitS];
448: }
449: if (opcstr[pos] == '[') {
450: pos++;
451: if (opcstr[pos] == '!') {
452: /* exclusion */
453: do {
454: pos++;
455: if (mode_from_str(opcstr+pos) == srcmode) goto nomatch;
456: pos += 4;
457: } while (opcstr[pos] == ',');
458: pos++;
459: } else {
460: if (opcstr[pos+4] == '-') {
461: /* replacement */
462: if (mode_from_str(opcstr+pos) == srcmode)
463: srcmode = mode_from_str(opcstr+pos+5);
464: else
465: goto nomatch;
466: pos += 10;
467: } else {
468: /* normal */
469: while(mode_from_str(opcstr+pos) != srcmode) {
470: pos += 4;
471: if (opcstr[pos] == ']') goto nomatch;
472: pos++;
473: }
474: while(opcstr[pos] != ']') pos++;
475: pos++;
476: }
477: }
478: }
479: break;
480: default: myabort();
481: }
482: /* safety check - might have changed */
483: if (srcmode != Areg && srcmode != Dreg && srcmode != Aind
484: && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
485: && srcmode != Apdi && srcmode != immi)
486: {
487: srcgather = false;
488: }
489: if (srcmode == Areg && sz == sz_byte)
490: goto nomatch;
491:
492: if (opcstr[pos] != ',') goto endofline;
493: pos++;
494:
495: /* parse the destination address */
496: usedst = true;
497: switch(opcstr[pos++]) {
498: case 'D':
499: destmode = Dreg;
500: switch (opcstr[pos++]) {
501: case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break;
502: case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break;
503: default: myabort();
504: }
505: break;
506: case 'A':
507: destmode = Areg;
508: switch (opcstr[pos++]) {
509: case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break;
510: case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break;
511: default: myabort();
512: }
513: switch (opcstr[pos]) {
514: case 'p': destmode = Apdi; pos++; break;
515: case 'P': destmode = Aipi; pos++; break;
516: }
517: break;
518: case '#':
519: switch(opcstr[pos++]) {
520: case 'z': destmode = imm; break;
521: case '0': destmode = imm0; break;
522: case '1': destmode = imm1; break;
523: case '2': destmode = imm2; break;
524: case 'i': destmode = immi; destreg = (LONG)(BYTE)bitval[biti]; break;
525: case 'j': destmode = immi; destreg = bitval[bitj]; break;
526: case 'J': destmode = immi; destreg = bitval[bitJ]; break;
527: default: myabort();
528: }
529: break;
530: case 'd':
531: destreg = bitval[bitD];
532: destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
533: if(destmode == am_illg) continue;
534: if (destmode == Areg || destmode == Dreg || destmode == Aind
535: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
536: || destmode == Apdi)
537: {
538: dstgather = true; dstpos = bitpos[bitD];
539: }
540:
541: if (opcstr[pos] == '[') {
542: pos++;
543: if (opcstr[pos] == '!') {
544: /* exclusion */
545: do {
546: pos++;
547: if (mode_from_str(opcstr+pos) == destmode) goto nomatch;
548: pos += 4;
549: } while (opcstr[pos] == ',');
550: pos++;
551: } else {
552: if (opcstr[pos+4] == '-') {
553: /* replacement */
554: if (mode_from_str(opcstr+pos) == destmode)
555: destmode = mode_from_str(opcstr+pos+5);
556: else
557: goto nomatch;
558: pos += 10;
559: } else {
560: /* normal */
561: while(mode_from_str(opcstr+pos) != destmode) {
562: pos += 4;
563: if (opcstr[pos] == ']') goto nomatch;
564: pos++;
565: }
566: while(opcstr[pos] != ']') pos++;
567: pos++;
568: break;
569: }
570: }
571: }
572: /* Some addressing modes are invalid as destination */
573: if (destmode == imm || destmode == PC16 || destmode == PC8r)
574: goto nomatch;
575: break;
576: case 's':
577: destreg = bitval[bitS];
578: destmode = mode_from_mr(bitval[bits],bitval[bitS]);
579:
580: if(destmode == am_illg) continue;
581: if (destmode == Areg || destmode == Dreg || destmode == Aind
582: || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
583: || destmode == Apdi)
584: {
585: dstgather = true; dstpos = bitpos[bitS];
586: }
587:
588: if (opcstr[pos] == '[') {
589: pos++;
590: if (opcstr[pos] == '!') {
591: /* exclusion */
592: do {
593: pos++;
594: if (mode_from_str(opcstr+pos) == destmode) goto nomatch;
595: pos += 4;
596: } while (opcstr[pos] == ',');
597: pos++;
598: } else {
599: if (opcstr[pos+4] == '-') {
600: /* replacement */
601: if (mode_from_str(opcstr+pos) == destmode)
602: destmode = mode_from_str(opcstr+pos+5);
603: else
604: goto nomatch;
605: pos += 10;
606: } else {
607: /* normal */
608: while(mode_from_str(opcstr+pos) != destmode) {
609: pos += 4;
610: if (opcstr[pos] == ']') goto nomatch;
611: pos++;
612: }
613: while(opcstr[pos] != ']') pos++;
614: pos++;
615: }
616: }
617: }
618: break;
619: default: myabort();
620: }
621: /* safety check - might have changed */
622: if (destmode != Areg && destmode != Dreg && destmode != Aind
623: && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
624: && destmode != Apdi)
625: {
626: dstgather = false;
627: }
628:
629: if (destmode == Areg && sz == sz_byte)
630: goto nomatch;
631: #if 0
632: if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
633: dstgather = false;
634: }
635: #endif
636: endofline:
637: /* now, we have a match */
638: if (table[opc].mnemo != i_ILLG)
639: fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
640: for(find = 0;; find++) {
641: if (strcmp(mnemonic, lookuptab[find].name) == 0) {
642: table[opc].mnemo = lookuptab[find].mnemo;
643: break;
644: }
645: if (strlen(lookuptab[find].name) == 0) myabort();
646: }
647: table[opc].cc = bitval[bitc];
648: if (table[opc].mnemo == i_BTST
649: || table[opc].mnemo == i_BSET
650: || table[opc].mnemo == i_BCLR
651: || table[opc].mnemo == i_BCHG)
652: {
653: sz = destmode == Dreg ? sz_long : sz_byte;
654: }
655: table[opc].generated = false;
656: table[opc].size = sz;
657: table[opc].sreg = srcreg;
658: table[opc].dreg = destreg;
659: table[opc].smode = srcmode;
660: table[opc].dmode = destmode;
661: table[opc].spos = srcgather ? srcpos : -1;
662: table[opc].dpos = dstgather ? dstpos : -1;
663: table[opc].suse = usesrc;
664: table[opc].duse = usedst;
665: table[opc].sbtarg = srcbtarg;
666: nomatch:
667: /* FOO! */;
668: }
669: }
670: }
671:
672: static int n_braces = 0;
673:
674: static void start_brace(void)
675: {
676: n_braces++;
677: printf("{");
678: }
679:
680: static void close_brace(void)
681: {
682: assert (n_braces > 0);
683: n_braces--;
684: printf("}");
685: }
686:
687: static void finish_braces(void)
688: {
689: while (n_braces > 0)
690: close_brace();
691: }
692:
693: static void pop_braces(int to)
694: {
695: while (n_braces > to)
696: close_brace();
697: }
698:
699: static void genamode(amodes mode, char *reg, wordsizes size, char *name, bool getv, bool movem)
700: {
701: start_brace ();
702: switch(mode) {
703: case Dreg:
704: if (movem)
705: abort();
706: if (getv)
707: switch(size) {
708: case sz_byte:
709: printf("\tBYTE %s = regs.d[%s];\n", name, reg);
710: break;
711: case sz_word:
712: printf("\tWORD %s = regs.d[%s];\n", name, reg);
713: break;
714: case sz_long:
715: printf("\tLONG %s = regs.d[%s];\n", name, reg);
716: break;
717: default: myabort();
718: }
719: break;
720: case Areg:
721: if (movem)
722: abort();
723: if (getv)
724: switch(size) {
725: case sz_word:
726: printf("\tWORD %s = regs.a[%s];\n", name, reg);
727: break;
728: case sz_long:
729: printf("\tLONG %s = regs.a[%s];\n", name, reg);
730: break;
731: default: myabort();
732: }
733: break;
734: case Aind:
735: printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
736: if (getv)
737: switch(size) {
738: case sz_byte:
739: printf("\tBYTE %s = get_byte(%sa);\n", name, name);
740: break;
741: case sz_word:
742: printf("\tWORD %s = get_word(%sa);\n", name, name);
743: break;
744: case sz_long:
745: printf("\tLONG %s = get_long(%sa);\n", name, name);
746: break;
747: default: myabort();
748: }
749: break;
750: case Aipi:
751: printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
752: switch(size) {
753: case sz_byte:
754: if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
755: if (!movem) {
756: start_brace();
757: printf("\tregs.a[%s] += (%s == 7) ? 2 : 1;\n", reg, reg);
758: }
759: break;
760: case sz_word:
761: if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
762: if (!movem) {
763: start_brace();
764: printf("\tregs.a[%s] += 2;\n", reg);
765: }
766: break;
767: case sz_long:
768: if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
769: if (!movem) {
770: start_brace();
771: printf("\tregs.a[%s] += 4;\n", reg);
772: }
773: break;
774: default: myabort();
775: }
776: break;
777: case Apdi:
778: switch(size) {
779: case sz_byte:
780: if (!movem) printf("\tregs.a[%s] -= (%s == 7) ? 2 : 1;\n", reg, reg);
781: start_brace();
782: printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
783: if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
784: break;
785: case sz_word:
786: if (!movem) printf("\tregs.a[%s] -= 2;\n", reg);
787: start_brace();
788: printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
789: if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
790: break;
791: case sz_long:
792: if (!movem) printf("\tregs.a[%s] -= 4;\n", reg);
793: start_brace();
794: printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
795: if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
796: break;
797: default: myabort();
798: }
799: break;
800: case Ad16:
801: printf("\tCPTR %sa = regs.a[%s] + (LONG)(WORD)nextiword();\n", name, reg);
802: if (getv)
803: switch(size) {
804: case sz_byte:
805: printf("\tBYTE %s = get_byte(%sa);\n", name, name);
806: break;
807: case sz_word:
808: printf("\tWORD %s = get_word(%sa);\n", name, name);
809: break;
810: case sz_long:
811: printf("\tLONG %s = get_long(%sa);\n", name, name);
812: break;
813: default: myabort();
814: }
815: break;
816: case Ad8r:
817: printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
818: printf("\tUWORD %sdp = nextiword();\n", name);
819: printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
820: start_brace();
821: printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
822: printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
823: printf("\t%sa += %sdpr;\n", name, name);
824: if (getv) {
825: start_brace();
826: switch(size) {
827: case sz_byte:
828: printf("\tBYTE %s = get_byte(%sa);\n", name, name);
829: break;
830: case sz_word:
831: printf("\tWORD %s = get_word(%sa);\n", name, name);
832: break;
833: case sz_long:
834: printf("\tLONG %s = get_long(%sa);\n", name, name);
835: break;
836: default: myabort();
837: }
838: }
839: break;
840: case PC16:
841: printf("\tCPTR %sa = m68k_getpc();\n", name);
842: printf("\t%sa += (LONG)(WORD)nextiword();\n", name);
843: if (getv) {
844: start_brace();
845: switch(size) {
846: case sz_byte:
847: printf("\tBYTE %s = get_byte(%sa);\n", name, name);
848: break;
849: case sz_word:
850: printf("\tWORD %s = get_word(%sa);\n", name, name);
851: break;
852: case sz_long:
853: printf("\tLONG %s = get_long(%sa);\n", name, name);
854: break;
855: default: myabort();
856: }
857: }
858: break;
859: case PC8r:
860: printf("\tCPTR %sa = m68k_getpc();\n", name);
861: printf("\tUWORD %sdp = nextiword();\n", name);
862: printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
863: start_brace();
864: printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
865: printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
866: printf("\t%sa += %sdpr;\n", name, name);
867: if (getv) {
868: start_brace();
869: switch(size) {
870: case sz_byte:
871: printf("\tBYTE %s = get_byte(%sa);\n", name, name);
872: break;
873: case sz_word:
874: printf("\tWORD %s = get_word(%sa);\n", name, name);
875: break;
876: case sz_long:
877: printf("\tLONG %s = get_long(%sa);\n", name, name);
878: break;
879: default: myabort();
880: }
881: }
882: break;
883: case absw:
884: printf("\tCPTR %sa = (LONG)(WORD)nextiword();\n", name);
885: if (getv)
886: switch(size) {
887: case sz_byte:
888: printf("\tBYTE %s = get_byte(%sa);\n", name, name);
889: break;
890: case sz_word:
891: printf("\tWORD %s = get_word(%sa);\n", name, name);
892: break;
893: case sz_long:
894: printf("\tLONG %s = get_long(%sa);\n", name, name);
895: break;
896: default: myabort();
897: }
898: break;
899: case absl:
900: printf("\tCPTR %sa = nextilong();\n", name);
901: if (getv)
902: switch(size) {
903: case sz_byte:
904: printf("\tBYTE %s = get_byte(%sa);\n", name, name);
905: break;
906: case sz_word:
907: printf("\tWORD %s = get_word(%sa);\n", name, name);
908: break;
909: case sz_long:
910: printf("\tLONG %s = get_long(%sa);\n", name, name);
911: break;
912: default: myabort();
913: }
914: break;
915: case imm:
916: if (getv)
917: switch(size) {
918: case sz_byte:
919: printf("\tBYTE %s = nextiword();\n", name);
920: break;
921: case sz_word:
922: printf("\tWORD %s = nextiword();\n", name);
923: break;
924: case sz_long:
925: printf("\tLONG %s = nextilong();\n", name);
926: break;
927: default: myabort();
928: }
929: break;
930: case imm0:
931: if (!getv) myabort();
932: printf("\tBYTE %s = nextiword();\n", name);
933: break;
934: case imm1:
935: if (!getv) myabort();
936: printf("\tWORD %s = nextiword();\n", name);
937: break;
938: case imm2:
939: if (!getv) myabort();
940: printf("\tLONG %s = nextilong();\n", name);
941: break;
942: case immi:
943: if (!getv) myabort();
944: printf("\tULONG %s = %s;\n", name, reg);
945: break;
946: default:
947: myabort();
948: }
949: }
950:
951: static void genastore(char *from, amodes mode, char *reg, wordsizes size, char *to)
952: {
953: switch(mode) {
954: case Dreg:
955: switch(size) {
956: case sz_byte:
957: printf("\tregs.d[%s] &= ~0xff; regs.d[%s] |= (%s) & 0xff;\n", reg, reg, from);
958: break;
959: case sz_word:
960: printf("\tregs.d[%s] &= ~0xffff; regs.d[%s] |= (%s) & 0xffff;\n", reg, reg, from);
961: break;
962: case sz_long:
963: printf("\tregs.d[%s] = (%s);\n", reg, from);
964: break;
965: default: myabort();
966: }
967: break;
968: case Areg:
969: switch(size) {
970: case sz_word:
971: printf("\tregs.a[%s] = (LONG)(WORD)(%s);\n", reg, from);
972: break;
973: case sz_long:
974: printf("\tregs.a[%s] = (%s);\n", reg, from);
975: break;
976: default: myabort();
977: }
978: break;
979: case Aind:
980: case Aipi:
981: case Apdi:
982: case Ad16:
983: case Ad8r:
984: case absw:
985: case absl:
986: switch(size) {
987: case sz_byte:
988: printf("\tput_byte(%sa,%s);\n", to, from);
989: break;
990: case sz_word:
991: printf("\tput_word(%sa,%s);\n", to, from);
992: break;
993: case sz_long:
994: printf("\tput_long(%sa,%s);\n", to, from);
995: break;
996: default: myabort();
997: }
998: break;
999: case PC16:
1000: case PC8r:
1001: switch(size) {
1002: case sz_byte:
1003: printf("\tput_byte(%sa,%s);\n", to, from);
1004: break;
1005: /* These are only used for byte-sized bit ops */
1006: default: myabort();
1007: }
1008: break;
1009: case imm:
1010: case imm0:
1011: case imm1:
1012: case imm2:
1013: case immi:
1014: myabort();
1015: break;
1016: default:
1017: myabort();
1018: }
1019: }
1020:
1021: static void genmovemel(UWORD opcode)
1022: {
1023: char getcode[100];
1024: int size = table[opcode].size == sz_long ? 4 : 2;
1025:
1026: if (table[opcode].size == sz_long) {
1027: strcpy(getcode, "get_long(srca)");
1028: } else {
1029: strcpy(getcode, "(LONG)(WORD)get_word(srca)");
1030: }
1031:
1032: printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
1033: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true);
1034: start_brace();
1035: printf("\tint i, bitcnt = 0;\n");
1036: printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
1037:
1038: printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.d[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
1039: printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.a[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
1040:
1041: if (table[opcode].smode == Aipi)
1042: printf("\tregs.a[srcreg] = srca;\n");
1043: }
1044:
1045: static void genmovemle(UWORD opcode)
1046: {
1047: char putcode[100], shiftcode[] = ">>";
1048: int size = table[opcode].size == sz_long ? 4 : 2;
1049: int mask = 1;
1050: if (table[opcode].size == sz_long) {
1051: strcpy(putcode, "put_long(srca,");
1052: } else {
1053: strcpy(putcode, "put_word(srca,");
1054: }
1055:
1056: printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
1057: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true);
1058: start_brace();
1059: printf("\tint i, bitcnt = 0;\n");
1060: printf("\tULONG rd[8], ra[8];\n");
1061: printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
1062: printf("\tfor(i=0;i<8;i++) { rd[i] = regs.d[i]; ra[i] = regs.a[i]; }\n");
1063: if (table[opcode].smode == Apdi) {
1064: printf("\tsrca -= %d*bitcnt;\n", size);
1065: printf("\tregs.a[srcreg] = srca;\n");
1066: strcpy(shiftcode, "<<");
1067: mask = 0x8000;
1068: }
1069:
1070: printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s rd[i]); srca += %d; } mask %s= 1; }\n",
1071: mask, putcode, size, shiftcode);
1072: printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s ra[i]); srca += %d; } mask %s= 1; }\n",
1073: mask, putcode, size, shiftcode);
1074: }
1075:
1076: typedef enum {
1077: flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn
1078: } flagtypes;
1079:
1080: static void genflags(flagtypes type, wordsizes size, char *value, char *src, char *dst)
1081: {
1082: char vstr[100],sstr[100],dstr[100];
1083: char usstr[100],udstr[100];
1084: char unsstr[100],undstr[100];
1085: ULONG mask;
1086: switch(size) {
1087: case sz_byte: mask = 0xFF; break;
1088: case sz_word: mask = 0xFFFF; break;
1089: case sz_long: mask = 0xFFFFFFFF; break;
1090: default: myabort();
1091: }
1092: #ifndef NO_INLINE_FLAGS
1093: switch(size) {
1094: case sz_byte:
1095: strcpy(vstr, "((BYTE)(");
1096: strcpy(usstr, "((UBYTE)(");
1097: break;
1098: case sz_word:
1099: strcpy(vstr, "((WORD)(");
1100: strcpy(usstr, "((UWORD)(");
1101: break;
1102: case sz_long:
1103: strcpy(vstr, "((LONG)(");
1104: strcpy(usstr, "((ULONG)(");
1105: break;
1106: default:
1107: myabort();
1108: }
1109: strcpy(unsstr, usstr);
1110:
1111: strcpy(sstr, vstr);
1112: strcpy(dstr, vstr);
1113: strcat(vstr, value); strcat(vstr,"))");
1114: strcat(dstr, dst); strcat(dstr,"))");
1115: strcat(sstr, src); strcat(sstr,"))");
1116:
1117: strcpy(udstr, usstr);
1118: strcat(udstr, dst); strcat(udstr,"))");
1119: strcat(usstr, src); strcat(usstr,"))");
1120:
1121: strcpy(undstr, unsstr);
1122: strcat(unsstr, "-");
1123: strcat(undstr, "~");
1124: strcat(undstr, dst); strcat(undstr,"))");
1125: strcat(unsstr, src); strcat(unsstr,"))");
1126:
1127: switch(type) {
1128: case flag_logical:
1129: printf("\tregs.v = regs.c = 0;\n");
1130: /* fall through */
1131: case flag_zn:
1132: switch(size) {
1133: case sz_byte:
1134: printf("\tregs.z = %s == 0;\n", vstr);
1135: printf("\tregs.n = %s < 0;\n", vstr);
1136: break;
1137: case sz_word:
1138: printf("\tregs.z = %s == 0;\n", vstr);
1139: printf("\tregs.n = %s < 0;\n", vstr);
1140: break;
1141: case sz_long:
1142: printf("\tregs.z = %s == 0;\n", vstr);
1143: printf("\tregs.n = %s < 0;\n", vstr);
1144: break;
1145: default:
1146: myabort();
1147: }
1148: break;
1149: case flag_add:
1150: start_brace();
1151: printf("\tbool flgs = %s < 0;\n", sstr);
1152: printf("\tbool flgo = %s < 0;\n", dstr);
1153: printf("\tbool flgn = %s < 0;\n", vstr);
1154: printf("\tregs.z = %s == 0;\n", vstr);
1155: printf("\tregs.v = (flgs == flgo) && (flgn != flgo);\n");
1156: printf("\tregs.c = regs.x = %s < %s;\n", undstr, usstr);
1157: printf("\tregs.n = flgn != 0;\n");
1158: break;
1159: case flag_sub:
1160: start_brace();
1161: printf("\tbool flgs = %s < 0;\n", sstr);
1162: printf("\tbool flgo = %s < 0;\n", dstr);
1163: printf("\tbool flgn = %s < 0;\n", vstr);
1164: printf("\tregs.z = %s == 0;\n", vstr);
1165: printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n");
1166: printf("\tregs.c = regs.x = %s > %s;\n", usstr, udstr);
1167: printf("\tregs.n = flgn != 0;\n");
1168: break;
1169: case flag_addx:
1170: start_brace();
1171: printf("\tbool flgs = %s < 0;\n", sstr);
1172: printf("\tbool flgo = %s < 0;\n", dstr);
1173: printf("\tbool flgn = %s < 0;\n", vstr);
1174: printf("\tif ((flgs && flgo && !flgn) || (!flgs && !flgo && flgn)) regs.v = 1;\n");
1175: printf("\tif ((flgs && flgo) || (!flgn && (flgo || flgs))) regs.c = regs.x = 1;\n");
1176: break;
1177: case flag_subx:
1178: start_brace();
1179: printf("\tbool flgs = %s < 0;\n", sstr);
1180: printf("\tbool flgo = %s < 0;\n", dstr);
1181: printf("\tbool flgn = %s < 0;\n", vstr);
1182: printf("\tif ((!flgs && flgo && !flgn) || (flgs && !flgo && flgn)) regs.v = 1;\n");
1183: printf("\tif ((flgs && !flgo) || (flgn && (!flgo || flgs))) regs.c = regs.x = 1;\n");
1184: break;
1185: case flag_cmp:
1186: start_brace();
1187: printf("\tbool flgs = %s < 0;\n", sstr);
1188: printf("\tbool flgo = %s < 0;\n", dstr);
1189: printf("\tbool flgn = %s < 0;\n", vstr);
1190: printf("\tregs.z = %s == 0;\n", vstr);
1191: printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n");
1192: printf("\tregs.c = %s > %s;\n", usstr, udstr);
1193: printf("\tregs.n = flgn != 0;\n");
1194: break;
1195: }
1196: #else
1197: switch(type) {
1198: case flag_logical:
1199: printf("\tsetflags_logical(%s,%s);\n", value, mask);
1200: break;
1201: case flag_add:
1202: printf("\tsetflags_add(%s,%s,%s);\n", src, dest, value);
1203: break;
1204: case flag_sub:
1205: printf("\tsetflags_sub(%s,%s,%s);\n", src, dest, value);
1206: break;
1207: case flag_addx:
1208: printf("\tsetflags_addx(%s,%s,%s);\n", src, dest, value);
1209: break;
1210: case flag_subx:
1211: printf("\tsetflags_subx(%s,%s,%s);\n", src, dest, value);
1212: break;
1213: case flag_cmp:
1214: printf("\tsetflags_cmp(%s,%s,%s);\n", src, dest, value);
1215: break;
1216: }
1217: #endif
1218: }
1219:
1220: static void gen_opcode(unsigned long int opcode)
1221: {
1222: start_brace ();
1223: switch(table[opcode].mnemo) {
1224: case i_OR:
1225: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1226: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1227: printf("\tsrc |= dst;\n");
1228: genflags(flag_logical, table[opcode].size, "src", "", "");
1229: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1230: break;
1231: case i_AND:
1232: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1233: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1234: printf("\tsrc &= dst;\n");
1235: genflags(flag_logical, table[opcode].size, "src", "", "");
1236: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1237: break;
1238: case i_EOR:
1239: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1240: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1241: printf("\tsrc ^= dst;\n");
1242: genflags(flag_logical, table[opcode].size, "src", "", "");
1243: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1244: break;
1245: case i_ORSR:
1246: if (table[opcode].size != sz_byte) {
1247: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
1248: }
1249: start_brace ();
1250: printf("\tMakeSR();\n");
1251: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1252: if (table[opcode].size == sz_byte) {
1253: printf("\tsrc &= 0xFF;\n");
1254: }
1255: printf("\tregs.sr |= src;\n");
1256: printf("\tMakeFromSR();\n");
1257: break;
1258: case i_ANDSR:
1259: if (table[opcode].size != sz_byte) {
1260: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
1261: }
1262: start_brace();
1263:
1264: printf("\tMakeSR();\n");
1265: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1266: if (table[opcode].size == sz_byte) {
1267: printf("\tsrc |= 0xFF00;\n");
1268: }
1269: printf("\tregs.sr &= src;\n");
1270: printf("\tMakeFromSR();\n");
1271: break;
1272: case i_EORSR:
1273: if (table[opcode].size != sz_byte) {
1274: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
1275: }
1276: start_brace ();
1277: printf("\tMakeSR();\n");
1278: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1279: if (table[opcode].size == sz_byte) {
1280: printf("\tsrc &= 0xFF;\n");
1281: }
1282: printf("\tregs.sr ^= src;\n");
1283: printf("\tMakeFromSR();\n");
1284: break;
1285: case i_SUB:
1286: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1287: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1288: start_brace ();
1289: printf("\tULONG newv = dst - src;\n");
1290: genflags(flag_sub, table[opcode].size, "newv", "src", "dst");
1291: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1292: break;
1293: case i_SUBA:
1294: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1295: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
1296: start_brace ();
1297: printf("\tULONG newv = dst - src;\n");
1298: genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst");
1299: break;
1300: case i_SUBX:
1301: {
1302: int old_brace_level;
1303: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1304: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1305: start_brace ();
1306: printf("\tbool xflg = regs.x;\n");
1307: printf("\tregs.v = regs.c = regs.x = 0;\n");
1308: start_brace ();
1309: printf("\tULONG newv = dst - src;\n");
1310: genflags(flag_subx, table[opcode].size, "newv", "src", "dst");
1311: /* FIXME: I'm not entirely sure how to handle this */
1312: printf("\tif (xflg)\n");
1313: old_brace_level = n_braces;
1314: start_brace ();
1315: genflags(flag_subx, table[opcode].size, "(newv-1)", "1", "newv");
1316: printf("\tnewv--;\n");
1317: pop_braces(old_brace_level);
1318:
1319: genflags(flag_zn, table[opcode].size, "newv", "", "");
1320: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1321: }
1322: break;
1323: case i_SBCD:
1324: /* Let's hope this works... */
1325: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1326: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1327: start_brace ();
1328: printf("\tUWORD newv = dst - src - regs.x;\n");
1329: printf("\tif ((newv & 0xF) > 9) newv-=6;\n");
1330: printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
1331: printf("\tif (regs.c) newv -= 0x60;\n");
1332: printf("\tif (newv != 0) regs.z = 0;\n");
1333: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1334: break;
1335: case i_ADD:
1336: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1337: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1338: start_brace ();
1339: printf("\tULONG newv = dst + src;\n");
1340: genflags(flag_add, table[opcode].size, "newv", "src", "dst");
1341: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1342: break;
1343: case i_ADDA:
1344: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1345: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
1346: start_brace ();
1347: printf("\tULONG newv = dst + src;\n");
1348: genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst");
1349: break;
1350: case i_ADDX:
1351: {
1352: int old_brace_level;
1353: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1354: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1355: start_brace ();
1356: printf("\tbool xflg = regs.x;\n");
1357: printf("\tregs.v = regs.c = regs.x = 0;\n");
1358: start_brace ();
1359: printf("\tULONG newv = dst + src;\n");
1360: genflags(flag_addx, table[opcode].size, "newv", "src", "dst");
1361: printf("\tif (xflg)\n");
1362: old_brace_level = n_braces;
1363: start_brace ();
1364: genflags(flag_addx, table[opcode].size, "(newv+1)", "newv", "1");
1365: printf("\tnewv++;\n");
1366: pop_braces(old_brace_level);
1367: genflags(flag_zn, table[opcode].size, "newv", "", "");
1368: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1369: }
1370: break;
1371: case i_ABCD:
1372: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1373: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1374: start_brace ();
1375: printf("\tUWORD newv = src + dst + regs.x;\n");
1376: printf("\tif ((newv & 0xF) > 9) newv+=6;\n");
1377: printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
1378: printf("\tif (regs.c) newv += 0x60;\n");
1379: printf("\tif (newv != 0) regs.z = 0;\n");
1380: genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1381: break;
1382: case i_NEG:
1383: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1384: start_brace ();
1385: printf("\tULONG dst = -src;\n");
1386: genflags(flag_sub, table[opcode].size, "dst", "src", "0");
1387: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
1388: break;
1389: case i_NEGX:
1390: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1391: start_brace ();
1392: printf("\tULONG dst = -src-regs.x;\n");
1393: genflags(flag_sub, table[opcode].size, "dst", "src", "0");
1394: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
1395: break;
1396: case i_NBCD:
1397: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1398: start_brace ();
1399: printf("\tUWORD newv = - src - regs.x;\n");
1400: printf("\tif ((newv & 0xF) > 9) newv-=6;\n");
1401: printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
1402: printf("\tif (regs.c) newv -= 0x60;\n");
1403: printf("\tif (newv != 0) regs.z = 0;\n");
1404: genastore("newv", table[opcode].smode, "srcreg", table[opcode].size, "src");
1405: break;
1406: case i_CLR:
1407: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1408: genflags(flag_logical, table[opcode].size, "0", "", "");
1409: genastore("0",table[opcode].smode, "srcreg", table[opcode].size, "src");
1410: break;
1411: case i_NOT:
1412: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1413: start_brace ();
1414: printf("\tULONG dst = ~src;\n");
1415: genflags(flag_logical, table[opcode].size, "dst", "", "");
1416: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
1417: break;
1418: case i_TST:
1419: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1420: genflags(flag_logical, table[opcode].size, "src", "", "");
1421: break;
1422: case i_BTST:
1423: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1424: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1425: if (table[opcode].size == sz_byte)
1426: printf("\tsrc &= 7;\n");
1427: else
1428: printf("\tsrc &= 31;\n");
1429: printf("\tregs.z = !(dst & (1 << src));\n");
1430: break;
1431: case i_BCHG:
1432: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1433: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1434: if (table[opcode].size == sz_byte)
1435: printf("\tsrc &= 7;\n");
1436: else
1437: printf("\tsrc &= 31;\n");
1438: printf("\tregs.z = !(dst & (1 << src));\n");
1439: printf("\tdst ^= (1 << src);\n");
1440: genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1441: break;
1442: case i_BCLR:
1443: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1444: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1445: if (table[opcode].size == sz_byte)
1446: printf("\tsrc &= 7;\n");
1447: else
1448: printf("\tsrc &= 31;\n");
1449: printf("\tregs.z = !(dst & (1 << src));\n");
1450: printf("\tdst &= ~(1 << src);\n");
1451: genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1452: break;
1453: case i_BSET:
1454: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1455: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1456: if (table[opcode].size == sz_byte)
1457: printf("\tsrc &= 7;\n");
1458: else
1459: printf("\tsrc &= 31;\n");
1460: printf("\tregs.z = !(dst & (1 << src));\n");
1461: printf("\tdst |= (1 << src);\n");
1462: genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1463: break;
1464: case i_CMPM:
1465: case i_CMP:
1466: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1467: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1468: start_brace ();
1469: printf("\tULONG newv = dst - src;\n");
1470: genflags(flag_cmp, table[opcode].size, "newv", "src", "dst");
1471: break;
1472: case i_CMPA:
1473: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1474: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
1475: start_brace ();
1476: printf("\tULONG newv = dst - src;\n");
1477: genflags(flag_cmp, sz_long, "newv", "src", "dst");
1478: break;
1479: case i_MOVEP:
1480: printf("\tfprintf(stderr, \"MOVEP\\n\");\n");
1481: break;
1482: case i_MOVE:
1483: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1484: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
1485: genflags(flag_logical, table[opcode].size, "src", "", "");
1486: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1487: break;
1488: case i_MOVEA:
1489: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1490: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
1491: genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1492: break;
1493: case i_MVSR2:
1494: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1495: printf("\tMakeSR();\n");
1496: genastore("regs.sr", table[opcode].smode, "srcreg", table[opcode].size, "src");
1497: break;
1498: case i_MV2SR:
1499: if (table[opcode].size != sz_byte) {
1500: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
1501: }
1502: start_brace ();
1503: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1504: if (table[opcode].size == sz_byte)
1505: printf("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
1506: else {
1507: printf("\tregs.sr = src;\n");
1508: }
1509: printf("\tMakeFromSR();\n");
1510: break;
1511: case i_SWAP:
1512: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1513: start_brace ();
1514: printf("\tULONG dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
1515: genflags(flag_logical, table[opcode].size, "dst", "", "");
1516: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
1517: break;
1518: case i_EXG:
1519: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1520: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
1521: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
1522: genastore("src",table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1523: break;
1524: case i_EXT:
1525: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1526: start_brace ();
1527: switch(table[opcode].size) {
1528: case sz_word: printf("\tULONG dst = (LONG)(BYTE)src;\n"); break;
1529: case sz_long: printf("\tULONG dst = (LONG)(WORD)src;\n"); break;
1530: default: myabort();
1531: }
1532: genflags(flag_logical, table[opcode].size, "dst", "", "");
1533: genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
1534: break;
1535: case i_MVMEL:
1536: genmovemel(opcode);
1537: break;
1538: case i_MVMLE:
1539: genmovemle(opcode);
1540: break;
1541: case i_TRAP:
1542: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1543: printf("\tException(src+32);\n");
1544: break;
1545: case i_MVR2USP:
1546: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
1547: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1548: printf("\tregs.usp = src;\n");
1549: printf("\t}\n");
1550: break;
1551: case i_MVUSP2R:
1552: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
1553: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1554: genastore("regs.usp", table[opcode].smode, "srcreg", table[opcode].size, "src");
1555: printf("\t}\n");
1556: break;
1557: case i_RESET:
1558: printf("\tcustomreset();\n");
1559: break;
1560: case i_NOP:
1561: break;
1562: case i_STOP:
1563: printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
1564: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1565: printf("\tregs.sr = src;\n");
1566: printf("\tMakeFromSR();\n");
1567: printf("\tm68k_setstopped(1);\n");
1568: printf("\t}\n");
1569: break;
1570: case i_RTE:
1571: genamode(Aipi, "7", sz_word, "sr", true, false);
1572: genamode(Aipi, "7", sz_long, "pc", true, false);
1573: printf("\tregs.sr = sr; m68k_setpc(pc);\n");
1574: printf("\tMakeFromSR();\n");
1575: break;
1576: case i_RTD:
1577: break;
1578: case i_LINK:
1579: genamode(Apdi, "7", sz_long, "old", false, false);
1580: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1581: genastore("src", Apdi, "7", sz_long, "old");
1582: genastore("regs.a[7]", table[opcode].smode, "srcreg", table[opcode].size, "src");
1583: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false);
1584: printf("\tregs.a[7] += offs;\n");
1585: break;
1586: case i_UNLK:
1587: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1588: printf("\tregs.a[7] = src;\n");
1589: genamode(Aipi, "7", sz_long, "old", true, false);
1590: genastore("old", table[opcode].smode, "srcreg", table[opcode].size, "src");
1591: break;
1592: case i_RTS:
1593: genamode(Aipi, "7", sz_long, "pc", true, false);
1594: printf("\tm68k_setpc(pc);\n");
1595: break;
1596: case i_TRAPV:
1597: printf("\tif(regs.v) Exception(7);\n");
1598: break;
1599: case i_RTR:
1600: printf("\tMakeSR();\n");
1601: genamode(Aipi, "7", sz_word, "sr", true, false);
1602: genamode(Aipi, "7", sz_long, "pc", true, false);
1603: printf("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
1604: printf("\tregs.sr |= sr; m68k_setpc(pc);\n");
1605: printf("\tMakeFromSR();\n");
1606: break;
1607: case i_JSR:
1608: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1609: genamode(Apdi, "7", sz_long, "sp", false, false);
1610: genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
1611: printf("\tm68k_setpc(srca);\n");
1612: break;
1613: case i_JMP:
1614: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1615: printf("\tm68k_setpc(srca);\n");
1616: break;
1617: case i_BSR:
1618: printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
1619: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1620: genamode(Apdi, "7", sz_long, "sp", false, false);
1621: genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
1622: printf("\tregs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n");
1623: break;
1624: case i_Bcc:
1625: printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
1626: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1627: printf("\tif (cctrue(%d)) regs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n", table[opcode].cc);
1628: break;
1629: case i_LEA:
1630: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1631: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
1632: genastore("srca", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
1633: break;
1634: case i_PEA:
1635: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1636: genamode(Apdi, "7", sz_long, "dst", false, false);
1637: genastore("srca", Apdi, "7", sz_long, "dst");
1638: break;
1639: case i_DBcc:
1640: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
1641: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false);
1642: printf("\tif (!cctrue(%d)) {\n", table[opcode].cc);
1643: printf("\tif (src--) regs.pc_p = (UWORD *)((char *)regs.pc_p + (LONG)offs - 2);\n");
1644: genastore("src", table[opcode].smode, "srcreg", table[opcode].size, "src");
1645: printf("\t}\n");
1646: break;
1647: case i_Scc:
1648: genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
1649: start_brace ();
1650: printf("\tint val = cctrue(%d) ? 0xff : 0;\n", table[opcode].cc);
1651: genastore("val",table[opcode].smode, "srcreg", table[opcode].size, "src");
1652: break;
1653: case i_DIVU:
1654: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
1655: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
1656: printf("\tif(src != 0){\n");
1657: printf("\tULONG newv = (ULONG)dst / (UWORD)src;\n");
1658: printf("\tULONG rem = (ULONG)dst %% (UWORD)src;\n");
1659: /* The N flag appears to be set each time there is an overflow.
1660: * Weird. */
1661: printf("\tif (newv > 0xffff) { regs.v = regs.n = 1; } else\n\t{\n");
1662: genflags(flag_logical, sz_word, "newv", "", "");
1663: printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
1664: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
1665: printf("\t}\n");
1666: printf("\t}\n");
1667: break;
1668: case i_DIVS:
1669: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
1670: genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
1671: printf("\tif(src != 0){\n");
1672: printf("\tLONG newv = (LONG)dst / (WORD)src;\n");
1673: printf("\tUWORD rem = (LONG)dst %% (WORD)src;\n");
1674: printf("\tif ((newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000) { regs.v = regs.n = 1; } else\n\t{\n");
1675: printf("\tif (((WORD)rem < 0) != ((LONG)dst < 0)) rem = -rem;\n");
1676: genflags(flag_logical, sz_word, "newv", "", "");
1677: printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
1678: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
1679: printf("\t}\n");
1680: printf("\t}\n");
1681: break;
1682: case i_MULU:
1683: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
1684: genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false);
1685: start_brace ();
1686: printf("\tULONG newv = (ULONG)(UWORD)dst * (ULONG)(UWORD)src;\n");
1687: genflags(flag_logical, sz_long, "newv", "", "");
1688: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
1689: #ifdef WANT_SLOW_MULTIPLY
1690: printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
1691: #endif
1692: break;
1693: case i_MULS:
1694: genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
1695: genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false);
1696: start_brace ();
1697: printf("\tULONG newv = (LONG)(WORD)dst * (LONG)(WORD)src;\n");
1698: genflags(flag_logical, sz_long, "newv", "", "");
1699: genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
1700: #ifdef WANT_SLOW_MULTIPLY
1701: printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
1702: #endif
1703: break;
1704: case i_ASR:
1705: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1706: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1707: start_brace ();
1708: switch(table[opcode].size) {
1709: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1710: case sz_word: printf("\tUWORD val = data;\n"); break;
1711: case sz_long: printf("\tULONG val = data;\n"); break;
1712: default: myabort();
1713: }
1714: printf("\tcnt &= 63;\n");
1715: printf("\tregs.v = 0;\n");
1716: start_brace ();
1717: switch(table[opcode].size) {
1718: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1719: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1720: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1721: default: myabort();
1722: }
1723: printf("\tULONG sign = cmask & val;\n");
1724: printf("\tfor(;cnt;--cnt){\n");
1725: printf("\tregs.c=regs.x=val&1; val = ((ULONG)val >> 1) | sign;\n");
1726: printf("\t}\n\tregs.n = sign != 0;\n");
1727: printf("\tregs.z = val == 0;\n");
1728: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1729: break;
1730: case i_ASL:
1731: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1732: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1733: start_brace ();
1734: switch(table[opcode].size) {
1735: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1736: case sz_word: printf("\tUWORD val = data;\n"); break;
1737: case sz_long: printf("\tULONG val = data;\n"); break;
1738: default: myabort();
1739: }
1740: printf("\tcnt &= 63;\n");
1741: printf("\tregs.v = 0;\n");
1742: start_brace ();
1743: switch(table[opcode].size) {
1744: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1745: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1746: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1747: default: myabort();
1748: }
1749: printf("\tULONG sign = cmask & val;\n");
1750: printf("\tfor(;cnt;--cnt){\n");
1751: printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n");
1752: printf("\tif ((val&cmask)!=sign)regs.v=1;\n");
1753: printf("\t}\n\tregs.n = (val&cmask) != 0;\n");
1754: printf("\tregs.z = val == 0;\n");
1755: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1756: break;
1757: case i_LSR:
1758: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1759: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1760: start_brace ();
1761: switch(table[opcode].size) {
1762: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1763: case sz_word: printf("\tUWORD val = data;\n"); break;
1764: case sz_long: printf("\tULONG val = data;\n"); break;
1765: default: myabort();
1766: }
1767: printf("\tcnt &= 63;\n");
1768: start_brace ();
1769: printf("\tint carry = 0;\n");
1770: printf("\tfor(;cnt;--cnt){\n");
1771: printf("\tcarry=val&1; val >>= 1;\n");
1772: printf("\t}\n");
1773: genflags(flag_logical, table[opcode].size, "val", "", "");
1774: printf("regs.c = regs.x = carry!=0;\n");
1775: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1776: break;
1777: case i_LSL:
1778: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1779: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1780: start_brace ();
1781: switch(table[opcode].size) {
1782: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1783: case sz_word: printf("\tUWORD val = data;\n"); break;
1784: case sz_long: printf("\tULONG val = data;\n"); break;
1785: default: myabort();
1786: }
1787: printf("\tcnt &= 63;\n");
1788: start_brace ();
1789: printf("\tint carry = 0;\n");
1790: switch(table[opcode].size) {
1791: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1792: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1793: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1794: default: myabort();
1795: }
1796: printf("\tfor(;cnt;--cnt){\n");
1797: printf("\tcarry=val&cmask; val <<= 1;\n");
1798: printf("\t}\n");
1799: genflags(flag_logical, table[opcode].size, "val", "", "");
1800: printf("regs.c = regs.x = carry!=0;\n");
1801: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1802: break;
1803: case i_ROL:
1804: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1805: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1806: start_brace ();
1807: switch(table[opcode].size) {
1808: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1809: case sz_word: printf("\tUWORD val = data;\n"); break;
1810: case sz_long: printf("\tULONG val = data;\n"); break;
1811: default: myabort();
1812: }
1813: printf("\tcnt &= 63;\n");
1814: start_brace ();
1815: printf("\tint carry = 0;\n");
1816: switch(table[opcode].size) {
1817: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1818: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1819: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1820: default: myabort();
1821: }
1822: printf("\tfor(;cnt;--cnt){\n");
1823: printf("\tcarry=val&cmask; val <<= 1;\n");
1824: printf("\tif(carry) val |= 1;\n");
1825: printf("\t}\n");
1826: genflags(flag_logical, table[opcode].size, "val", "", "");
1827: printf("regs.c = carry!=0;\n");
1828: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1829: break;
1830: case i_ROR:
1831: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1832: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1833: start_brace ();
1834: switch(table[opcode].size) {
1835: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1836: case sz_word: printf("\tUWORD val = data;\n"); break;
1837: case sz_long: printf("\tULONG val = data;\n"); break;
1838: default: myabort();
1839: }
1840:
1841: printf("\tcnt &= 63;\n");
1842: start_brace ();
1843: printf("\tint carry = 0;\n");
1844: switch(table[opcode].size) {
1845: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1846: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1847: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1848: default: myabort();
1849: }
1850: printf("\tfor(;cnt;--cnt){\n");
1851: printf("\tcarry=val&1; val = (ULONG)val >> 1;\n");
1852: printf("\tif(carry) val |= cmask;\n");
1853: printf("\t}\n");
1854: genflags(flag_logical, table[opcode].size, "val", "", "");
1855: printf("\tregs.c = carry!=0;\n");
1856: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1857: break;
1858: case i_ROXL:
1859: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1860: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1861: start_brace ();
1862: switch(table[opcode].size) {
1863: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1864: case sz_word: printf("\tUWORD val = data;\n"); break;
1865: case sz_long: printf("\tULONG val = data;\n"); break;
1866: default: myabort();
1867: }
1868: printf("\tcnt &= 63;\n");
1869: start_brace ();
1870: printf("\tint carry = 0;\n");
1871: switch(table[opcode].size) {
1872: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1873: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1874: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1875: default: myabort();
1876: }
1877: printf("\tfor(;cnt;--cnt){\n");
1878: printf("\tcarry=val&cmask; val <<= 1;\n");
1879: printf("\tif(regs.x) val |= 1;\n");
1880: printf("\tregs.x = carry != 0;\n");
1881: printf("\t}\n");
1882: genflags(flag_logical, table[opcode].size, "val", "", "");
1883: printf("\tregs.x = regs.c = carry!=0;\n");
1884: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1885: break;
1886: case i_ROXR:
1887: genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
1888: genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
1889: start_brace ();
1890: switch(table[opcode].size) {
1891: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1892: case sz_word: printf("\tUWORD val = data;\n"); break;
1893: case sz_long: printf("\tULONG val = data;\n"); break;
1894: default: myabort();
1895: }
1896: printf("\tcnt &= 63;\n");
1897: start_brace ();
1898: printf("\tint carry = 0;\n");
1899: switch(table[opcode].size) {
1900: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1901: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1902: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1903: default: myabort();
1904: }
1905: printf("\tfor(;cnt;--cnt){\n");
1906: printf("\tcarry=val&1; val >>= 1;\n");
1907: printf("\tif(regs.x) val |= cmask;\n");
1908: printf("\tregs.x = carry != 0;\n");
1909: printf("\t}\n");
1910: genflags(flag_logical, table[opcode].size, "val", "", "");
1911: printf("\tregs.x = regs.c = carry!=0;\n");
1912: genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
1913: break;
1914: case i_ASRW:
1915: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
1916: printf("\tregs.v = 0;\n");
1917: start_brace ();
1918: switch(table[opcode].size) {
1919: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1920: case sz_word: printf("\tUWORD val = data;\n"); break;
1921: case sz_long: printf("\tULONG val = data;\n"); break;
1922: default: myabort();
1923: }
1924: switch(table[opcode].size) {
1925: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1926: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1927: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1928: default: myabort();
1929: }
1930: printf("\tULONG sign = cmask & val;\n");
1931: printf("\tregs.c=regs.x=val&1; val = (val >> 1) | sign;\n");
1932: printf("\tregs.n = sign != 0;\n");
1933: printf("\tregs.z = val == 0;\n");
1934: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
1935: break;
1936: case i_ASLW:
1937: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
1938: printf("\tregs.v = 0;\n");
1939: start_brace ();
1940: switch(table[opcode].size) {
1941: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1942: case sz_word: printf("\tUWORD val = data;\n"); break;
1943: case sz_long: printf("\tULONG val = data;\n"); break;
1944: default: myabort();
1945: }
1946: switch(table[opcode].size) {
1947: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1948: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1949: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1950: default: myabort();
1951: }
1952: printf("\tULONG sign = cmask & val;\n");
1953: printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n");
1954: printf("\tif ((val&cmask)!=sign)regs.v=1;\n");
1955: printf("\tregs.n = (val&cmask) != 0;\n");
1956: printf("\tregs.z = val == 0;\n");
1957: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
1958: break;
1959: case i_LSRW:
1960: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
1961: start_brace ();
1962: switch(table[opcode].size) {
1963: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1964: case sz_word: printf("\tUWORD val = data;\n"); break;
1965: case sz_long: printf("\tULONG val = data;\n"); break;
1966: default: myabort();
1967: }
1968: printf("\tint carry = val&1;\n");
1969: printf("\tcarry=val&1; val >>= 1;\n");
1970: genflags(flag_logical, table[opcode].size, "val", "", "");
1971: printf("regs.c = regs.x = carry!=0;\n");
1972: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
1973: break;
1974: case i_LSLW:
1975: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
1976: start_brace ();
1977: switch(table[opcode].size) {
1978: case sz_byte: printf("\tUBYTE val = data;\n"); break;
1979: case sz_word: printf("\tUWORD val = data;\n"); break;
1980: case sz_long: printf("\tULONG val = data;\n"); break;
1981: default: myabort();
1982: }
1983: switch(table[opcode].size) {
1984: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
1985: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
1986: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1987: default: myabort();
1988: }
1989: printf("\tint carry = val&cmask;\n");
1990: printf("\tval <<= 1;\n");
1991: genflags(flag_logical, table[opcode].size, "val", "", "");
1992: printf("regs.c = regs.x = carry!=0;\n");
1993: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
1994: break;
1995: case i_ROLW:
1996: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
1997: start_brace ();
1998: switch(table[opcode].size) {
1999: case sz_byte: printf("\tUBYTE val = data;\n"); break;
2000: case sz_word: printf("\tUWORD val = data;\n"); break;
2001: case sz_long: printf("\tULONG val = data;\n"); break;
2002: default: myabort();
2003: }
2004: switch(table[opcode].size) {
2005: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
2006: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
2007: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
2008: default: myabort();
2009: }
2010: printf("\tint carry = val&cmask;\n");
2011: printf("\tval <<= 1;\n");
2012: printf("\tif(carry) val |= 1;\n");
2013: genflags(flag_logical, table[opcode].size, "val", "", "");
2014: printf("regs.c = carry!=0;\n");
2015: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
2016: break;
2017: case i_RORW:
2018: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
2019: start_brace ();
2020: switch(table[opcode].size) {
2021: case sz_byte: printf("\tUBYTE val = data;\n"); break;
2022: case sz_word: printf("\tUWORD val = data;\n"); break;
2023: case sz_long: printf("\tULONG val = data;\n"); break;
2024: default: myabort();
2025: }
2026: printf("\tint carry = val&1;\n");
2027: switch(table[opcode].size) {
2028: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
2029: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
2030: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
2031: default: myabort();
2032: }
2033: printf("\tval >>= 1;\n");
2034: printf("\tif(carry) val |= cmask;\n");
2035: genflags(flag_logical, table[opcode].size, "val", "", "");
2036: printf("regs.c = carry!=0;\n");
2037: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
2038: break;
2039: case i_ROXLW:
2040: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
2041: start_brace ();
2042: switch(table[opcode].size) {
2043: case sz_byte: printf("\tUBYTE val = data;\n"); break;
2044: case sz_word: printf("\tUWORD val = data;\n"); break;
2045: case sz_long: printf("\tULONG val = data;\n"); break;
2046: default: myabort();
2047: }
2048: switch(table[opcode].size) {
2049: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
2050: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
2051: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
2052: default: myabort();
2053: }
2054: printf("\tint carry = val&cmask;\n");
2055: printf("\tval <<= 1;\n");
2056: printf("\tif(regs.x) val |= 1;\n");
2057: printf("\tregs.x = carry != 0;\n");
2058: genflags(flag_logical, table[opcode].size, "val", "", "");
2059: printf("regs.x = regs.c = carry!=0;\n");
2060: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
2061: break;
2062: case i_ROXRW:
2063: genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
2064: start_brace ();
2065: switch(table[opcode].size) {
2066: case sz_byte: printf("\tUBYTE val = data;\n"); break;
2067: case sz_word: printf("\tUWORD val = data;\n"); break;
2068: case sz_long: printf("\tULONG val = data;\n"); break;
2069: default: myabort();
2070: }
2071: printf("\tint carry = val&1;\n");
2072: switch(table[opcode].size) {
2073: case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
2074: case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
2075: case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
2076: default: myabort();
2077: }
2078: printf("\tval >>= 1;\n");
2079: printf("\tif(regs.x) val |= cmask;\n");
2080: printf("\tregs.x = carry != 0;\n");
2081: genflags(flag_logical, table[opcode].size, "val", "", "");
2082: printf("regs.x = regs.c = carry!=0;\n");
2083: genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
2084: break;
2085: default:
2086: myabort();
2087: break;
2088: };
2089: finish_braces ();
2090: }
2091:
2092: static int mismatch;
2093:
2094: static void handle_merges(long int opcode)
2095: {
2096: UWORD smsk;
2097: UWORD dmsk;
2098: int sbitsrc, sbitdst;
2099: int srcreg, dstreg;
2100:
2101: smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos;
2102: dmsk = 7 << table[opcode].dpos;
2103: sbitsrc = table[opcode].spos == -1 ? 0 : 0;
2104: sbitdst = table[opcode].spos == -1 ? 1 : (table[opcode].sbtarg ? 256 : 8);
2105: for (srcreg=sbitsrc; srcreg < sbitdst; srcreg++) {
2106: for (dstreg=0; dstreg < (table[opcode].dpos == -1 ? 1 : 8); dstreg++) {
2107: UWORD code = opcode;
2108:
2109: if (table[opcode].spos != -1) code &= ~(smsk << table[opcode].spos);
2110: if (table[opcode].dpos != -1) code &= ~(dmsk << table[opcode].dpos);
2111:
2112: if (table[opcode].spos != -1) code |= srcreg << table[opcode].spos;
2113: if (table[opcode].dpos != -1) code |= dstreg << table[opcode].dpos;
2114:
2115: /* Check whether this is in fact the same instruction.
2116: * The instructions should never differ, except for the
2117: * Bcc.(BW) case. */
2118: if (table[code].mnemo != table[opcode].mnemo
2119: || table[code].size != table[opcode].size
2120: || table[code].suse != table[opcode].suse
2121: || table[code].duse != table[opcode].duse)
2122: {
2123: mismatch++; continue;
2124: }
2125: if (table[opcode].suse
2126: && (table[opcode].spos != table[code].spos
2127: || table[opcode].smode != table[code].smode
2128: || table[opcode].sbtarg != table[code].sbtarg))
2129: {
2130: mismatch++; continue;
2131: }
2132: if (table[opcode].duse
2133: && (table[opcode].dpos != table[code].dpos
2134: || table[opcode].dmode != table[code].dmode))
2135: {
2136: mismatch++; continue;
2137: }
2138:
2139: table[code].generated = true;
2140: table[code].handler = opcode;
2141: }
2142: }
2143: }
2144:
2145: static void generate_func(long int from, long int to)
2146: {
2147: int illg = 0;
2148: long int opcode;
2149: UWORD smsk;
2150: UWORD dmsk;
2151: mismatch = 0;
2152:
2153: printf("#include <stdlib.h>\n");
2154: printf("#include \"config.h\"\n");
2155: printf("#include \"amiga.h\"\n");
2156: printf("#include \"options.h\"\n");
2157: printf("#include \"memory.h\"\n");
2158: printf("#include \"custom.h\"\n");
2159: printf("#include \"newcpu.h\"\n");
2160: printf("#include \"cputbl.h\"\n");
2161: for(opcode=from; opcode < to; opcode++) {
2162: if (table[opcode].mnemo == i_ILLG) {
2163: illg++;
2164: continue;
2165: }
2166: if (table[opcode].generated) {
2167: continue;
2168: }
2169: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
2170:
2171: handle_merges (opcode);
2172:
2173: smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos;
2174: dmsk = 7 << table[opcode].dpos;
2175:
2176: printf("void op_%lx(UWORD opcode)\n{\n", opcode);
2177: if (table[opcode].suse
2178: && table[opcode].smode != imm && table[opcode].smode != imm0
2179: && table[opcode].smode != imm1 && table[opcode].smode != imm2
2180: && table[opcode].smode != absw && table[opcode].smode != absl
2181: && table[opcode].smode != PC8r && table[opcode].smode != PC16)
2182: {
2183: if (table[opcode].spos == -1) {
2184: printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg);
2185: } else {
2186: printf("\tULONG srcreg = (LONG)(BYTE)((opcode & %d) >> %d);\n", smsk, (int)table[opcode].spos);
2187: }
2188: }
2189: if (table[opcode].duse
2190: /* Yes, the dmode can be imm, in case of LINK or DBcc */
2191: && table[opcode].dmode != imm && table[opcode].dmode != imm0
2192: && table[opcode].dmode != imm1 && table[opcode].dmode != imm2
2193: && table[opcode].dmode != absw && table[opcode].dmode != absl) {
2194: if (table[opcode].dpos == -1) {
2195: printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg);
2196: } else {
2197: printf("\tULONG dstreg = (opcode & %d) >> %d;\n", dmsk, (int)table[opcode].dpos);
2198: }
2199: }
2200: #else
2201: printf("void op_%lx(UWORD opcode)\n{\n", opcode);
2202: if (table[opcode].suse)
2203: printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg);
2204: if (table[opcode].duse)
2205: printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg);
2206: #endif
2207: gen_opcode(opcode);
2208: printf("}\n");
2209: }
2210:
2211: fprintf (stderr, "%d illegals generated.\n", illg);
2212: if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
2213: }
2214:
2215: static void generate_table(void)
2216: {
2217: int illg = 0;
2218: long int opcode;
2219:
2220: mismatch = 0;
2221:
2222: printf("#include <stdlib.h>\n");
2223: printf("#include \"config.h\"\n");
2224: printf("#include \"amiga.h\"\n");
2225: printf("#include \"options.h\"\n");
2226: printf("#include \"memory.h\"\n");
2227: printf("#include \"custom.h\"\n");
2228: printf("#include \"newcpu.h\"\n");
2229: printf("#include \"cputbl.h\"\n");
2230:
2231: printf("cpuop_func *cpufunctbl[65536] = {\n");
2232: for(opcode=0; opcode < 65536; opcode++) {
2233: if (table[opcode].mnemo == i_ILLG) {
2234: printf("op_illg");
2235: illg++;
2236: goto loop_end;
2237: }
2238: if (table[opcode].generated) {
2239: printf("op_%x", table[opcode].handler);
2240: goto loop_end;
2241: }
2242: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
2243: handle_merges (opcode);
2244: #endif
2245: printf("op_%lx", opcode);
2246:
2247: loop_end:
2248: if (opcode < 65535) printf(",");
2249: if ((opcode & 7) == 7) printf("\n");
2250: }
2251: printf("\n};\n");
2252: fprintf (stderr, "%d illegals generated.\n", illg);
2253: if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
2254: }
2255:
2256: static void generate_header(void)
2257: {
2258: int illg = 0;
2259: long int opcode;
2260:
2261: mismatch = 0;
2262:
2263: printf("extern void op_illg(UWORD) REGPARAM;\n");
2264:
2265: for(opcode=0; opcode < 65536; opcode++) {
2266: if (table[opcode].mnemo == i_ILLG) {
2267: illg++;
2268: continue;
2269: }
2270: if (table[opcode].generated)
2271: continue;
2272:
2273: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
2274: handle_merges (opcode);
2275: #endif
2276: printf("extern cpuop_func op_%lx;\n", opcode);
2277: }
2278:
2279: fprintf (stderr, "%d illegals generated.\n", illg);
2280: if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
2281: }
2282:
2283: int main(int argc, char **argv)
2284: {
2285: long int range = -1;
2286: char mode = 'n';
2287: int i;
2288:
2289: if (argc == 2)
2290: mode = *argv[1];
2291:
2292: if (argc == 3) {
2293: range = atoi(argv[2]);
2294: mode = *argv[1];
2295: }
2296: tablef = fopen("table68k","r");
2297: if (tablef == NULL) {
2298: fprintf(stderr, "table68k not found\n");
2299: exit(1);
2300: }
2301: table = (struct instr *) malloc (sizeof(struct instr) * 65536);
2302: for(i = 0; i < 65536; i++) {
2303: table[i].mnemo = i_ILLG;
2304: }
2305: getnextch();
2306: while (nextch != EOF) {
2307: get_bits();
2308: get_strs();
2309: parse_bits();
2310: }
2311: switch(mode) {
2312: case 'f':
2313: generate_func(range * 0x1000, (range + 1) * 0x1000);
2314: break;
2315: case 'h':
2316: generate_header();
2317: break;
2318: case 't':
2319: generate_table();
2320: break;
2321: default:
2322: myabort();
2323: }
2324: fclose(tablef);
2325: free(table);
2326: return 0;
2327: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.