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