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