|
|
1.1.1.3 root 1: /*
1.1 root 2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68000 emulation generator
5: *
1.1.1.3 root 6: * This is a fairly stupid program that generates a lot of case labels that
1.1 root 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().
1.1.1.3 root 13: * The generated code is sometimes sub-optimal, an optimizing compiler should
1.1 root 14: * take care of this.
1.1.1.3 root 15: *
1.1.1.11 root 16: * The source for the insn timings is Markt & Technik's Amiga Magazin 8/1992.
17: *
18: * Copyright 1995, 1996, 1997, 1998, 1999, 2000 Bernd Schmidt
1.1 root 19: */
20:
21: #include "sysconfig.h"
22: #include "sysdeps.h"
23: #include <ctype.h>
24:
25: #include "readcpu.h"
26:
27: #define BOOL_TYPE "int"
28:
1.1.1.3 root 29: static FILE *headerfile;
30: static FILE *stblfile;
31:
32: static int using_prefetch;
33: static int using_exception_3;
1.1.1.17 root 34: static int using_ce = 0;
1.1.1.3 root 35: static int cpu_level;
36:
1.1.1.17 root 37: /* Flags for genamode. */
38: #define GF_APDI 1
39: #define GF_AD8R 2
40: #define GF_PC8R 4
41: #define GF_AA 7
42: #define GF_NOREFILL 8
43: #define GF_PREFETCH 16
44:
1.1.1.3 root 45: /* For the current opcode, the next lower level that will have different code.
46: * Initialized to -1 for each opcode. If it remains unchanged, indicates we
47: * are done with that opcode. */
48: static int next_cpu_level;
1.1 root 49:
1.1.1.3 root 50: static int *opcode_map;
51: static int *opcode_next_clev;
52: static int *opcode_last_postfix;
53: static unsigned long *counts;
54:
1.1.1.21! root 55: static int generate_stbl;
! 56:
1.1.1.5 root 57: static void read_counts (void)
1.1 root 58: {
59: FILE *file;
1.1.1.5 root 60: unsigned long opcode, count, total;
1.1 root 61: char name[20];
1.1.1.5 root 62: int nr = 0;
1.1.1.3 root 63: memset (counts, 0, 65536 * sizeof *counts);
1.1 root 64:
1.1.1.3 root 65: file = fopen ("frequent.68k", "r");
66: if (file) {
67: fscanf (file, "Total: %lu\n", &total);
1.1.1.5 root 68: while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) {
1.1.1.21! root 69: opcode_next_clev[nr] = 6;
1.1.1.3 root 70: opcode_last_postfix[nr] = -1;
71: opcode_map[nr++] = opcode;
72: counts[opcode] = count;
73: }
74: fclose (file);
75: }
76: if (nr == nr_cpuop_funcs)
77: return;
78: for (opcode = 0; opcode < 0x10000; opcode++) {
79: if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
80: && counts[opcode] == 0)
1.1 root 81: {
1.1.1.21! root 82: opcode_next_clev[nr] = 6;
1.1.1.3 root 83: opcode_last_postfix[nr] = -1;
84: opcode_map[nr++] = opcode;
85: counts[opcode] = count;
1.1 root 86: }
87: }
1.1.1.3 root 88: if (nr != nr_cpuop_funcs)
89: abort ();
1.1 root 90: }
91:
1.1.1.3 root 92: static char endlabelstr[80];
93: static int endlabelno = 0;
1.1.1.5 root 94: static int need_endlabel;
1.1 root 95:
96: static int n_braces = 0;
1.1.1.3 root 97: static int m68k_pc_offset = 0;
1.1.1.5 root 98: static int insn_n_cycles;
1.1 root 99:
1.1.1.17 root 100: static void returncycles (char *s, int cycles)
101: {
1.1.1.21! root 102: if (using_ce)
! 103: return;
! 104: printf ("%sreturn CYCLE_UNIT / 2 * %d;\n", s, cycles);
! 105: }
! 106:
! 107: static void addcycles (int cycles)
! 108: {
! 109: if (using_ce)
! 110: printf ("\tdo_cycles_ce (%d * CYCLE_UNIT / 2);\n", cycles);
! 111: else
! 112: insn_n_cycles += cycles;
! 113: }
! 114: static void addcycles2 (char *s, int cycles)
! 115: {
! 116: if (using_ce)
! 117: printf ("%sdo_cycles_ce (%d * CYCLE_UNIT / 2);\n", s, cycles);
! 118: else
! 119: insn_n_cycles += cycles;
! 120: }
! 121: static void addcycles3 (char *s)
! 122: {
! 123: if (!using_ce) return;
! 124: printf ("%sif (cycles > 0) do_cycles_ce (cycles);\n", s);
1.1.1.17 root 125: }
126:
127: static int isreg (amodes mode)
128: {
129: if (mode == Dreg || mode == Areg)
130: return 1;
131: return 0;
132: }
133:
1.1.1.5 root 134: static void start_brace (void)
1.1 root 135: {
136: n_braces++;
1.1.1.3 root 137: printf ("{");
1.1 root 138: }
139:
1.1.1.5 root 140: static void close_brace (void)
1.1 root 141: {
142: assert (n_braces > 0);
143: n_braces--;
1.1.1.3 root 144: printf ("}");
1.1 root 145: }
146:
1.1.1.5 root 147: static void finish_braces (void)
1.1 root 148: {
149: while (n_braces > 0)
1.1.1.5 root 150: close_brace ();
1.1 root 151: }
152:
1.1.1.5 root 153: static void pop_braces (int to)
1.1 root 154: {
155: while (n_braces > to)
1.1.1.5 root 156: close_brace ();
1.1 root 157: }
158:
1.1.1.5 root 159: static int bit_size (int size)
1.1 root 160: {
1.1.1.5 root 161: switch (size) {
162: case sz_byte: return 8;
163: case sz_word: return 16;
164: case sz_long: return 32;
165: default: abort ();
1.1 root 166: }
167: return 0;
168: }
169:
1.1.1.5 root 170: static const char *bit_mask (int size)
1.1 root 171: {
1.1.1.5 root 172: switch (size) {
1.1.1.3 root 173: case sz_byte: return "0xff";
174: case sz_word: return "0xffff";
175: case sz_long: return "0xffffffff";
1.1.1.5 root 176: default: abort ();
1.1 root 177: }
178: return 0;
179: }
180:
1.1.1.17 root 181: static void gen_nextilong (char *type, char *name, int norefill)
1.1.1.3 root 182: {
183: int r = m68k_pc_offset;
184: m68k_pc_offset += 4;
1.1.1.5 root 185:
1.1.1.17 root 186: if (using_ce) {
1.1.1.18 root 187: printf ("\t%s %s;\n", type, name);
1.1.1.17 root 188: /* we must do this because execution order of (something | something2) is not defined */
189: if (norefill) {
190: printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2);
191: printf ("\t%s |= regs.irc;\n", name);
192: } else {
193: printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2);
194: printf ("\t%s |= get_word_ce_prefetch (%d);\n", name, r + 4);
195: }
196: } else {
1.1.1.18 root 197: if (using_prefetch) {
1.1.1.17 root 198: if (norefill) {
1.1.1.18 root 199: printf ("\t%s %s;\n", type, name);
1.1.1.17 root 200: printf ("\t%s = get_word_prefetch (%d) << 16;\n", name, r + 2);
201: printf ("\t%s |= regs.irc;\n", name);
202: insn_n_cycles += 4;
203: } else
204: printf ("\t%s %s = get_long_prefetch (%d);\n", type, name, r + 2);
205: insn_n_cycles += 8;
206: } else {
207: insn_n_cycles += 8;
208: printf ("\t%s %s = get_ilong (%d);\n", type, name, r);
209: }
210: }
1.1.1.3 root 211: }
212:
1.1.1.17 root 213: static const char *gen_nextiword (int norefill)
1.1.1.3 root 214: {
215: static char buffer[80];
216: int r = m68k_pc_offset;
217: m68k_pc_offset += 2;
1.1.1.5 root 218:
1.1.1.17 root 219: if (using_ce) {
220: if (norefill)
221: strcpy (buffer, "regs.irc");
222: else
223: sprintf (buffer, "get_word_ce_prefetch (%d)", r + 2);
224: } else {
225: if (using_prefetch) {
226: if (norefill) {
227: sprintf (buffer, "regs.irc", r);
228: } else {
229: sprintf (buffer, "get_word_prefetch (%d)", r + 2);
230: insn_n_cycles += 4;
231: }
232: } else {
233: sprintf (buffer, "get_iword (%d)", r);
1.1.1.18 root 234: insn_n_cycles += 4;
1.1.1.17 root 235: }
236: }
1.1.1.3 root 237: return buffer;
238: }
239:
1.1.1.17 root 240: static const char *gen_nextibyte (int norefill)
1.1.1.3 root 241: {
242: static char buffer[80];
243: int r = m68k_pc_offset;
244: m68k_pc_offset += 2;
1.1.1.5 root 245:
1.1.1.17 root 246: if (using_ce) {
247: if (norefill)
248: strcpy (buffer, "(uae_u8)regs.irc");
249: else
250: sprintf (buffer, "(uae_u8)get_word_ce_prefetch (%d)", r + 2);
251: } else {
1.1.1.18 root 252: insn_n_cycles += 4;
1.1.1.17 root 253: if (using_prefetch) {
254: if (norefill) {
255: sprintf (buffer, "(uae_u8)regs.irc", r);
256: } else {
257: sprintf (buffer, "(uae_u8)get_word_prefetch (%d)", r + 2);
1.1.1.18 root 258: insn_n_cycles += 4;
1.1.1.17 root 259: }
260: } else {
261: sprintf (buffer, "get_ibyte (%d)", r);
1.1.1.18 root 262: insn_n_cycles += 4;
1.1.1.17 root 263: }
264: }
265: return buffer;
266: }
1.1.1.5 root 267:
1.1.1.17 root 268: static void irc2ir (void)
269: {
270: if (!using_prefetch)
271: return;
272: printf ("\tregs.ir = regs.irc;\n");
273: }
274:
275: static int did_prefetch;
276:
277: static void fill_prefetch_2 (void)
278: {
279: if (!using_prefetch)
280: return;
281: if (using_ce)
282: printf ("\tget_word_ce_prefetch (%d);\n", m68k_pc_offset + 2);
1.1.1.5 root 283: else
1.1.1.17 root 284: printf ("\tget_word_prefetch (%d);\n", m68k_pc_offset + 2);
285: did_prefetch = 1;
286: insn_n_cycles += 4;
287: }
288:
1.1.1.21! root 289: static void fill_prefetch_1 (int o)
1.1.1.17 root 290: {
291: if (!using_prefetch)
292: return;
293: if (using_ce) {
1.1.1.21! root 294: printf ("\tget_word_ce_prefetch (%d);\n", o);
1.1.1.17 root 295: } else {
296: printf ("\tget_word_prefetch (%d);\n", o);
297: }
298: did_prefetch = 1;
299: insn_n_cycles += 4;
300: }
301:
302: static void fill_prefetch_full (void)
303: {
1.1.1.21! root 304: fill_prefetch_1 (0);
1.1.1.17 root 305: irc2ir ();
1.1.1.21! root 306: fill_prefetch_1 (2);
1.1.1.3 root 307: }
308:
309: static void fill_prefetch_0 (void)
310: {
1.1.1.17 root 311: if (!using_prefetch)
312: return;
313: if (using_ce)
314: printf ("\tget_word_ce_prefetch (0);\n");
315: else
316: printf ("\tget_word_prefetch (0);\n");
317: did_prefetch = 1;
318: insn_n_cycles += 4;
1.1.1.19 root 319: }
1.1.1.17 root 320:
1.1.1.21! root 321: static void fill_prefetch_next_1 (void)
1.1.1.17 root 322: {
323: irc2ir ();
1.1.1.21! root 324: fill_prefetch_1 (m68k_pc_offset + 2);
1.1.1.19 root 325: }
1.1.1.17 root 326:
327: static void fill_prefetch_next (void)
328: {
1.1.1.21! root 329: fill_prefetch_next_1 ();
1.1.1.17 root 330: }
331:
332: static void fill_prefetch_finish (void)
333: {
334: if (did_prefetch || !using_prefetch)
335: return;
1.1.1.21! root 336: fill_prefetch_1 (m68k_pc_offset);
1.1.1.3 root 337: }
338:
339: static void sync_m68k_pc (void)
340: {
341: if (m68k_pc_offset == 0)
342: return;
1.1.1.17 root 343: printf ("\tm68k_incpc (%d);\n", m68k_pc_offset);
1.1.1.3 root 344: m68k_pc_offset = 0;
345: }
346:
347: /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
1.1.1.14 root 348: * the calling routine handles Apdi and Aipi modes.
349: * gb-- movem == 2 means the same thing but for a MOVE16 instruction */
1.1.1.17 root 350: static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags)
1.1 root 351: {
1.1.1.17 root 352: char namea[100];
353: int m68k_pc_offset_last = m68k_pc_offset;
354:
355: sprintf (namea, "%sa", name);
356:
1.1.1.6 root 357: start_brace ();
1.1.1.5 root 358: switch (mode) {
1.1.1.11 root 359: case Dreg:
1.1 root 360: if (movem)
1.1.1.5 root 361: abort ();
1.1.1.3 root 362: if (getv == 1)
1.1.1.5 root 363: switch (size) {
1.1.1.11 root 364: case sz_byte:
1.1.1.8 root 365: #if defined(AMIGA) && !defined(WARPUP)
1.1.1.2 root 366: /* sam: I don't know why gcc.2.7.2.1 produces a code worse */
367: /* if it is not done like that: */
1.1.1.21! root 368: printf ("\tuae_s8 %s = ((uae_u8*)&m68k_dreg (regs, %s))[3];\n", name, reg);
1.1.1.2 root 369: #else
1.1.1.21! root 370: printf ("\tuae_s8 %s = m68k_dreg (regs, %s);\n", name, reg);
1.1.1.2 root 371: #endif
1.1 root 372: break;
1.1.1.11 root 373: case sz_word:
1.1.1.8 root 374: #if defined(AMIGA) && !defined(WARPUP)
1.1.1.21! root 375: printf ("\tuae_s16 %s = ((uae_s16*)&m68k_dreg (regs, %s))[1];\n", name, reg);
1.1.1.2 root 376: #else
1.1.1.21! root 377: printf ("\tuae_s16 %s = m68k_dreg (regs, %s);\n", name, reg);
1.1.1.2 root 378: #endif
1.1 root 379: break;
1.1.1.11 root 380: case sz_long:
1.1.1.21! root 381: printf ("\tuae_s32 %s = m68k_dreg (regs, %s);\n", name, reg);
1.1 root 382: break;
1.1.1.11 root 383: default:
1.1.1.5 root 384: abort ();
1.1 root 385: }
1.1.1.3 root 386: return;
1.1.1.11 root 387: case Areg:
1.1 root 388: if (movem)
1.1.1.5 root 389: abort ();
1.1.1.3 root 390: if (getv == 1)
1.1.1.5 root 391: switch (size) {
1.1.1.11 root 392: case sz_word:
1.1.1.21! root 393: printf ("\tuae_s16 %s = m68k_areg (regs, %s);\n", name, reg);
1.1 root 394: break;
1.1.1.11 root 395: case sz_long:
1.1.1.21! root 396: printf ("\tuae_s32 %s = m68k_areg (regs, %s);\n", name, reg);
1.1 root 397: break;
1.1.1.11 root 398: default:
1.1.1.5 root 399: abort ();
1.1 root 400: }
1.1.1.3 root 401: return;
1.1.1.11 root 402: case Aind:
1.1.1.21! root 403: printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg);
1.1 root 404: break;
1.1.1.11 root 405: case Aipi:
1.1.1.21! root 406: printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg);
1.1 root 407: break;
1.1.1.11 root 408: case Apdi:
1.1.1.5 root 409: switch (size) {
1.1.1.11 root 410: case sz_byte:
1.1.1.3 root 411: if (movem)
1.1.1.21! root 412: printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg);
1.1.1.3 root 413: else
1.1.1.21! root 414: printf ("\tuaecptr %sa = m68k_areg (regs, %s) - areg_byteinc[%s];\n", name, reg, reg);
1.1 root 415: break;
1.1.1.11 root 416: case sz_word:
1.1.1.21! root 417: printf ("\tuaecptr %sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 2);
1.1 root 418: break;
1.1.1.11 root 419: case sz_long:
1.1.1.21! root 420: printf ("\tuaecptr %sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 4);
1.1 root 421: break;
1.1.1.11 root 422: default:
1.1.1.5 root 423: abort ();
1.1 root 424: }
425: break;
1.1.1.21! root 426: if (!(flags & GF_APDI)) {
! 427: addcycles (2);
! 428: }
1.1.1.11 root 429: case Ad16:
1.1.1.21! root 430: printf ("\tuaecptr %sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags & GF_NOREFILL));
1.1 root 431: break;
1.1.1.11 root 432: case Ad8r:
1.1.1.3 root 433: if (cpu_level > 1) {
434: if (next_cpu_level < 1)
435: next_cpu_level = 1;
1.1.1.5 root 436: sync_m68k_pc ();
437: start_brace ();
1.1.1.11 root 438: /* This would ordinarily be done in gen_nextiword, which we bypass. */
439: insn_n_cycles += 4;
1.1.1.21! root 440: printf ("\tuaecptr %sa = get_disp_ea_020(m68k_areg (regs, %s), next_iword());\n", name, reg);
1.1.1.6 root 441: } else
1.1.1.21! root 442: printf ("\tuaecptr %sa = get_disp_ea_000(m68k_areg (regs, %s), %s);\n", name, reg, gen_nextiword (flags & GF_NOREFILL));
1.1.1.6 root 443:
1.1.1.21! root 444: if (!(flags & GF_AD8R)) {
! 445: addcycles (2);
! 446: }
1.1 root 447: break;
1.1.1.11 root 448: case PC16:
1.1.1.6 root 449: printf ("\tuaecptr %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset);
1.1.1.17 root 450: printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL));
1.1 root 451: break;
1.1.1.11 root 452: case PC8r:
1.1.1.3 root 453: if (cpu_level > 1) {
454: if (next_cpu_level < 1)
455: next_cpu_level = 1;
1.1.1.5 root 456: sync_m68k_pc ();
457: start_brace ();
1.1.1.11 root 458: /* This would ordinarily be done in gen_nextiword, which we bypass. */
459: insn_n_cycles += 4;
1.1.1.21! root 460: printf ("\tuaecptr tmppc = m68k_getpc ();\n");
1.1.1.3 root 461: printf ("\tuaecptr %sa = get_disp_ea_020(tmppc, next_iword());\n", name);
462: } else {
1.1.1.21! root 463: printf ("\tuaecptr tmppc = m68k_getpc () + %d;\n", m68k_pc_offset);
1.1.1.17 root 464: printf ("\tuaecptr %sa = get_disp_ea_000(tmppc, %s);\n", name, gen_nextiword (flags & GF_NOREFILL));
1.1 root 465: }
1.1.1.3 root 466:
1.1.1.21! root 467: if (!(flags & GF_PC8R)) {
! 468: addcycles (2);
! 469: }
1.1 root 470: break;
1.1.1.11 root 471: case absw:
1.1.1.17 root 472: printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags & GF_NOREFILL));
1.1 root 473: break;
1.1.1.11 root 474: case absl:
1.1.1.17 root 475: gen_nextilong ("uaecptr", namea, flags & GF_NOREFILL);
1.1 root 476: break;
1.1.1.11 root 477: case imm:
1.1.1.3 root 478: if (getv != 1)
479: abort ();
1.1.1.5 root 480: switch (size) {
1.1.1.11 root 481: case sz_byte:
1.1.1.17 root 482: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL));
1.1.1.3 root 483: break;
1.1.1.11 root 484: case sz_word:
1.1.1.17 root 485: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL));
1.1.1.3 root 486: break;
1.1.1.11 root 487: case sz_long:
1.1.1.17 root 488: gen_nextilong ("uae_s32", name, flags & GF_NOREFILL);
1.1.1.3 root 489: break;
1.1.1.11 root 490: default:
1.1.1.5 root 491: abort ();
1.1.1.3 root 492: }
493: return;
1.1.1.11 root 494: case imm0:
1.1.1.5 root 495: if (getv != 1)
496: abort ();
1.1.1.17 root 497: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL));
1.1.1.3 root 498: return;
1.1.1.11 root 499: case imm1:
1.1.1.5 root 500: if (getv != 1)
501: abort ();
1.1.1.17 root 502: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL));
1.1.1.3 root 503: return;
1.1.1.11 root 504: case imm2:
1.1.1.5 root 505: if (getv != 1)
506: abort ();
1.1.1.17 root 507: gen_nextilong ("uae_s32", name, flags & GF_NOREFILL);
1.1.1.3 root 508: return;
1.1.1.11 root 509: case immi:
1.1.1.5 root 510: if (getv != 1)
511: abort ();
1.1.1.3 root 512: printf ("\tuae_u32 %s = %s;\n", name, reg);
513: return;
1.1.1.11 root 514: default:
1.1.1.5 root 515: abort ();
1.1.1.3 root 516: }
517:
518: /* We get here for all non-reg non-immediate addressing modes to
519: * actually fetch the value. */
520:
1.1.1.19 root 521: if (using_prefetch && using_exception_3 && getv != 0 && size != sz_byte) {
1.1.1.17 root 522: printf ("\tif (%sa & 1) {\n", name);
523: if (using_prefetch)
1.1.1.21! root 524: printf ("\t\texception3 (opcode, m68k_getpc () + %d, %sa);\n", m68k_pc_offset + 2, name);
1.1.1.17 root 525: else
1.1.1.21! root 526: printf ("\t\texception3 (opcode, m68k_getpc () + %d, %sa);\n", m68k_pc_offset_last, name);
1.1.1.3 root 527: printf ("\t\tgoto %s;\n", endlabelstr);
528: printf ("\t}\n");
1.1.1.5 root 529: need_endlabel = 1;
1.1.1.3 root 530: start_brace ();
531: }
1.1.1.6 root 532:
1.1.1.17 root 533: if (flags & GF_PREFETCH)
534: fill_prefetch_next ();
535:
1.1.1.6 root 536: if (getv == 1) {
537: switch (size) {
1.1.1.11 root 538: case sz_byte: insn_n_cycles += 4; break;
539: case sz_word: insn_n_cycles += 4; break;
540: case sz_long: insn_n_cycles += 8; break;
541: default: abort ();
1.1.1.6 root 542: }
543: start_brace ();
544: switch (size) {
1.1.1.21! root 545: case sz_byte: printf ("\tuae_s8 %s = get_byte (%sa);\n", name, name); break;
! 546: case sz_word: printf ("\tuae_s16 %s = get_word (%sa);\n", name, name); break;
! 547: case sz_long: printf ("\tuae_s32 %s = get_long (%sa);\n", name, name); break;
1.1.1.11 root 548: default: abort ();
1.1.1.6 root 549: }
550: }
551:
1.1.1.3 root 552: /* We now might have to fix up the register for pre-dec or post-inc
553: * addressing modes. */
554: if (!movem)
555: switch (mode) {
1.1.1.11 root 556: case Aipi:
1.1.1.5 root 557: switch (size) {
1.1.1.11 root 558: case sz_byte:
1.1.1.21! root 559: printf ("\tm68k_areg (regs, %s) += areg_byteinc[%s];\n", reg, reg);
1.1 root 560: break;
1.1.1.11 root 561: case sz_word:
1.1.1.21! root 562: printf ("\tm68k_areg (regs, %s) += 2;\n", reg);
1.1 root 563: break;
1.1.1.11 root 564: case sz_long:
1.1.1.21! root 565: printf ("\tm68k_areg (regs, %s) += 4;\n", reg);
1.1 root 566: break;
1.1.1.11 root 567: default:
1.1.1.5 root 568: abort ();
1.1 root 569: }
1.1.1.3 root 570: break;
1.1.1.11 root 571: case Apdi:
1.1.1.3 root 572: printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name);
573: break;
1.1.1.11 root 574: default:
1.1.1.3 root 575: break;
576: }
1.1 root 577: }
578:
1.1.1.3 root 579: static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to)
1.1 root 580: {
1.1.1.5 root 581: switch (mode) {
1.1 root 582: case Dreg:
1.1.1.5 root 583: switch (size) {
1.1 root 584: case sz_byte:
1.1.1.21! root 585: printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from);
1.1 root 586: break;
587: case sz_word:
1.1.1.21! root 588: printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from);
1.1 root 589: break;
590: case sz_long:
1.1.1.21! root 591: printf ("\tm68k_dreg (regs, %s) = (%s);\n", reg, from);
1.1 root 592: break;
1.1.1.5 root 593: default:
594: abort ();
1.1 root 595: }
596: break;
597: case Areg:
1.1.1.5 root 598: switch (size) {
1.1 root 599: case sz_word:
1.1.1.16 root 600: write_log ("Foo\n");
1.1.1.21! root 601: printf ("\tm68k_areg (regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from);
1.1 root 602: break;
603: case sz_long:
1.1.1.21! root 604: printf ("\tm68k_areg (regs, %s) = (%s);\n", reg, from);
1.1 root 605: break;
1.1.1.5 root 606: default:
607: abort ();
1.1 root 608: }
609: break;
610: case Aind:
611: case Aipi:
612: case Apdi:
613: case Ad16:
614: case Ad8r:
615: case absw:
616: case absl:
617: case PC16:
618: case PC8r:
1.1.1.3 root 619: if (using_prefetch)
1.1.1.5 root 620: sync_m68k_pc ();
621: switch (size) {
1.1 root 622: case sz_byte:
1.1.1.11 root 623: insn_n_cycles += 4;
1.1.1.21! root 624: printf ("\tput_byte (%sa,%s);\n", to, from);
1.1 root 625: break;
626: case sz_word:
1.1.1.11 root 627: insn_n_cycles += 4;
1.1.1.5 root 628: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
629: abort ();
1.1.1.21! root 630: printf ("\tput_word (%sa,%s);\n", to, from);
1.1 root 631: break;
632: case sz_long:
1.1.1.11 root 633: insn_n_cycles += 8;
1.1.1.5 root 634: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
635: abort ();
1.1.1.21! root 636: printf ("\tput_long (%sa,%s);\n", to, from);
1.1 root 637: break;
1.1.1.5 root 638: default:
639: abort ();
1.1 root 640: }
641: break;
642: case imm:
643: case imm0:
644: case imm1:
645: case imm2:
646: case immi:
1.1.1.5 root 647: abort ();
1.1 root 648: break;
1.1.1.3 root 649: default:
1.1.1.5 root 650: abort ();
1.1 root 651: }
652: }
653:
1.1.1.5 root 654: static void genmovemel (uae_u16 opcode)
1.1 root 655: {
656: char getcode[100];
657: int size = table68k[opcode].size == sz_long ? 4 : 2;
1.1.1.3 root 658:
659: if (table68k[opcode].size == sz_long) {
1.1.1.21! root 660: strcpy (getcode, "get_long (srca)");
1.1.1.3 root 661: } else {
1.1.1.21! root 662: strcpy (getcode, "(uae_s32)(uae_s16)get_word (srca)");
1.1 root 663: }
1.1.1.3 root 664:
1.1.1.17 root 665: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1.1.1.3 root 666: printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1.1.1.17 root 667: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0);
1.1.1.5 root 668: start_brace ();
1.1.1.21! root 669: printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask]; }\n",
1.1.1.5 root 670: getcode, size);
1.1.1.21! root 671: printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask]; }\n",
1.1.1.5 root 672: getcode, size);
1.1 root 673:
674: if (table68k[opcode].dmode == Aipi)
1.1.1.21! root 675: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
1.1 root 676: }
677:
1.1.1.5 root 678: static void genmovemle (uae_u16 opcode)
1.1 root 679: {
680: char putcode[100];
681: int size = table68k[opcode].size == sz_long ? 4 : 2;
682: if (table68k[opcode].size == sz_long) {
1.1.1.21! root 683: strcpy (putcode, "put_long (srca,");
1.1.1.3 root 684: } else {
1.1.1.21! root 685: strcpy (putcode, "put_word (srca,");
1.1 root 686: }
1.1.1.3 root 687:
1.1.1.17 root 688: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
689: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0);
1.1.1.3 root 690: if (using_prefetch)
1.1.1.5 root 691: sync_m68k_pc ();
1.1.1.3 root 692:
1.1.1.5 root 693: start_brace ();
1.1 root 694: if (table68k[opcode].dmode == Apdi) {
1.1.1.3 root 695: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
1.1.1.21! root 696: printf ("\twhile (amask) { srca -= %d; %s m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
1.1.1.5 root 697: size, putcode);
1.1.1.21! root 698: printf ("\twhile (dmask) { srca -= %d; %s m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
1.1.1.5 root 699: size, putcode);
1.1.1.21! root 700: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
1.1.1.2 root 701: } else {
1.1.1.3 root 702: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1.1.1.21! root 703: printf ("\twhile (dmask) { %s m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
1.1.1.5 root 704: putcode, size);
1.1.1.21! root 705: printf ("\twhile (amask) { %s m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
1.1.1.5 root 706: putcode, size);
1.1 root 707: }
708: }
709:
1.1.1.17 root 710: static void duplicate_carry (int n)
1.1.1.7 root 711: {
1.1.1.17 root 712: while (n-- != 0)
713: printf ("\t");
714: printf ("COPY_CARRY;\n");
1.1.1.7 root 715: }
716:
1.1.1.12 root 717: typedef enum
718: {
719: flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn,
720: flag_av, flag_sv
721: }
722: flagtypes;
1.1 root 723:
1.1.1.5 root 724: static void genflags_normal (flagtypes type, wordsizes size, char *value, char *src, char *dst)
1.1 root 725: {
1.1.1.5 root 726: char vstr[100], sstr[100], dstr[100];
727: char usstr[100], udstr[100];
728: char unsstr[100], undstr[100];
1.1 root 729:
1.1.1.5 root 730: switch (size) {
1.1 root 731: case sz_byte:
1.1.1.5 root 732: strcpy (vstr, "((uae_s8)(");
733: strcpy (usstr, "((uae_u8)(");
1.1 root 734: break;
735: case sz_word:
1.1.1.5 root 736: strcpy (vstr, "((uae_s16)(");
737: strcpy (usstr, "((uae_u16)(");
1.1 root 738: break;
739: case sz_long:
1.1.1.5 root 740: strcpy (vstr, "((uae_s32)(");
741: strcpy (usstr, "((uae_u32)(");
1.1 root 742: break;
743: default:
1.1.1.5 root 744: abort ();
1.1 root 745: }
1.1.1.5 root 746: strcpy (unsstr, usstr);
1.1 root 747:
1.1.1.5 root 748: strcpy (sstr, vstr);
749: strcpy (dstr, vstr);
750: strcat (vstr, value);
751: strcat (vstr, "))");
752: strcat (dstr, dst);
753: strcat (dstr, "))");
754: strcat (sstr, src);
755: strcat (sstr, "))");
756:
757: strcpy (udstr, usstr);
758: strcat (udstr, dst);
759: strcat (udstr, "))");
760: strcat (usstr, src);
761: strcat (usstr, "))");
762:
763: strcpy (undstr, unsstr);
764: strcat (unsstr, "-");
765: strcat (undstr, "~");
766: strcat (undstr, dst);
767: strcat (undstr, "))");
768: strcat (unsstr, src);
769: strcat (unsstr, "))");
1.1 root 770:
771: switch (type) {
1.1.1.7 root 772: case flag_logical_noclobber:
1.1 root 773: case flag_logical:
774: case flag_zn:
775: case flag_av:
776: case flag_sv:
777: case flag_addx:
778: case flag_subx:
779: break;
1.1.1.3 root 780:
1.1 root 781: case flag_add:
1.1.1.5 root 782: start_brace ();
1.1.1.3 root 783: printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr);
1.1 root 784: break;
785: case flag_sub:
786: case flag_cmp:
1.1.1.5 root 787: start_brace ();
1.1.1.3 root 788: printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr);
1.1 root 789: break;
790: }
791:
792: switch (type) {
1.1.1.7 root 793: case flag_logical_noclobber:
1.1 root 794: case flag_logical:
795: case flag_zn:
796: break;
1.1.1.3 root 797:
1.1 root 798: case flag_add:
799: case flag_sub:
800: case flag_addx:
801: case flag_subx:
802: case flag_cmp:
803: case flag_av:
804: case flag_sv:
1.1.1.5 root 805: start_brace ();
806: printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr);
807: printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr);
808: printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr);
1.1 root 809: break;
810: }
1.1.1.3 root 811:
1.1.1.5 root 812: switch (type) {
1.1 root 813: case flag_logical:
1.1.1.7 root 814: printf ("\tCLEAR_CZNV;\n");
815: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
816: printf ("\tSET_NFLG (%s < 0);\n", vstr);
817: break;
818: case flag_logical_noclobber:
819: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
820: printf ("\tSET_NFLG (%s < 0);\n", vstr);
1.1 root 821: break;
822: case flag_av:
1.1.1.7 root 823: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
1.1 root 824: break;
825: case flag_sv:
1.1.1.7 root 826: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
1.1 root 827: break;
828: case flag_zn:
1.1.1.7 root 829: printf ("\tSET_ZFLG (GET_ZFLG & (%s == 0));\n", vstr);
830: printf ("\tSET_NFLG (%s < 0);\n", vstr);
1.1 root 831: break;
832: case flag_add:
1.1.1.7 root 833: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
1.1.1.8 root 834: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
1.1.1.7 root 835: printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr);
1.1.1.17 root 836: duplicate_carry (0);
1.1.1.7 root 837: printf ("\tSET_NFLG (flgn != 0);\n");
1.1 root 838: break;
839: case flag_sub:
1.1.1.7 root 840: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
841: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
842: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
1.1.1.17 root 843: duplicate_carry (0);
1.1.1.7 root 844: printf ("\tSET_NFLG (flgn != 0);\n");
1.1 root 845: break;
846: case flag_addx:
1.1.1.7 root 847: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */
848: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */
1.1.1.17 root 849: duplicate_carry (0);
1.1 root 850: break;
851: case flag_subx:
1.1.1.7 root 852: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */
853: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */
1.1.1.17 root 854: duplicate_carry (0);
1.1 root 855: break;
856: case flag_cmp:
1.1.1.7 root 857: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
858: printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n");
859: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
860: printf ("\tSET_NFLG (flgn != 0);\n");
1.1 root 861: break;
862: }
863: }
864:
1.1.1.5 root 865: static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst)
1.1 root 866: {
1.1.1.11 root 867: /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have
868: them in the appropriate m68k.h files and use just one copy of this
869: code here. The API can be changed if necessary. */
870: #ifdef OPTIMIZED_FLAGS
1.1 root 871: switch (type) {
1.1.1.5 root 872: case flag_add:
873: case flag_sub:
874: start_brace ();
1.1.1.3 root 875: printf ("\tuae_u32 %s;\n", value);
1.1 root 876: break;
877:
1.1.1.3 root 878: default:
1.1 root 879: break;
880: }
881:
1.1.1.3 root 882: /* At least some of those casts are fairly important! */
1.1.1.5 root 883: switch (type) {
1.1.1.7 root 884: case flag_logical_noclobber:
1.1.1.11 root 885: printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n");
1.1.1.7 root 886: if (strcmp (value, "0") == 0) {
1.1.1.11 root 887: printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n");
1.1.1.7 root 888: } else {
889: switch (size) {
1.1.1.11 root 890: case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break;
891: case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break;
892: case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break;
1.1.1.7 root 893: }
1.1.1.11 root 894: printf ("\tIOR_CZNV (oldcznv);\n");
1.1.1.7 root 895: }
896: printf ("\t}\n");
897: return;
1.1 root 898: case flag_logical:
1.1.1.5 root 899: if (strcmp (value, "0") == 0) {
1.1.1.11 root 900: printf ("\tSET_CZNV (FLAGVAL_Z);\n");
1.1 root 901: } else {
1.1.1.5 root 902: switch (size) {
1.1.1.11 root 903: case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break;
904: case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break;
905: case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break;
1.1 root 906: }
907: }
908: return;
909:
910: case flag_add:
1.1.1.5 root 911: switch (size) {
1.1.1.11 root 912: case sz_byte: printf ("\toptflag_addb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
913: case sz_word: printf ("\toptflag_addw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
914: case sz_long: printf ("\toptflag_addl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
1.1 root 915: }
916: return;
917:
918: case flag_sub:
1.1.1.5 root 919: switch (size) {
1.1.1.11 root 920: case sz_byte: printf ("\toptflag_subb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
921: case sz_word: printf ("\toptflag_subw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
922: case sz_long: printf ("\toptflag_subl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
1.1 root 923: }
924: return;
925:
926: case flag_cmp:
1.1.1.5 root 927: switch (size) {
1.1.1.11 root 928: case sz_byte: printf ("\toptflag_cmpb ((uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
929: case sz_word: printf ("\toptflag_cmpw ((uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
930: case sz_long: printf ("\toptflag_cmpl ((uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
1.1 root 931: }
932: return;
1.1.1.19 root 933:
1.1.1.3 root 934: default:
935: break;
1.1 root 936: }
937: #endif
1.1.1.11 root 938:
1.1.1.5 root 939: genflags_normal (type, size, value, src, dst);
1.1 root 940: }
1.1.1.3 root 941:
1.1.1.7 root 942: static void force_range_for_rox (const char *var, wordsizes size)
943: {
944: /* Could do a modulo operation here... which one is faster? */
945: switch (size) {
946: case sz_long:
947: printf ("\tif (%s >= 33) %s -= 33;\n", var, var);
948: break;
949: case sz_word:
950: printf ("\tif (%s >= 34) %s -= 34;\n", var, var);
951: printf ("\tif (%s >= 17) %s -= 17;\n", var, var);
952: break;
953: case sz_byte:
954: printf ("\tif (%s >= 36) %s -= 36;\n", var, var);
955: printf ("\tif (%s >= 18) %s -= 18;\n", var, var);
956: printf ("\tif (%s >= 9) %s -= 9;\n", var, var);
957: break;
958: }
959: }
960:
961: static const char *cmask (wordsizes size)
962: {
963: switch (size) {
964: case sz_byte: return "0x80";
965: case sz_word: return "0x8000";
966: case sz_long: return "0x80000000";
967: default: abort ();
968: }
969: }
970:
971: static int source_is_imm1_8 (struct instr *i)
972: {
973: return i->stype == 3;
974: }
975:
1.1.1.5 root 976: static void gen_opcode (unsigned long int opcode)
1.1 root 977: {
1.1.1.7 root 978: struct instr *curi = table68k + opcode;
1.1.1.21! root 979: insn_n_cycles = using_prefetch ? 0 : 4;
1.1.1.5 root 980:
1.1 root 981: start_brace ();
1.1.1.3 root 982: #if 0
983: printf ("uae_u8 *m68k_pc = regs.pc_p;\n");
984: #endif
985: m68k_pc_offset = 2;
1.1.1.7 root 986: switch (curi->plev) {
1.1.1.11 root 987: case 0: /* not privileged */
1.1 root 988: break;
1.1.1.11 root 989: case 1: /* unprivileged only on 68000 */
1.1.1.3 root 990: if (cpu_level == 0)
1.1 root 991: break;
1.1.1.3 root 992: if (next_cpu_level < 0)
993: next_cpu_level = 0;
994:
1.1.1.5 root 995: /* fall through */
1.1.1.11 root 996: case 2: /* priviledged */
1.1.1.3 root 997: printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr);
1.1.1.5 root 998: need_endlabel = 1;
999: start_brace ();
1.1 root 1000: break;
1.1.1.11 root 1001: case 3: /* privileged if size == word */
1.1.1.7 root 1002: if (curi->size == sz_byte)
1.1 root 1003: break;
1.1.1.3 root 1004: printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr);
1.1.1.5 root 1005: need_endlabel = 1;
1006: start_brace ();
1.1 root 1007: break;
1008: }
1.1.1.7 root 1009: switch (curi->mnemo) {
1.1.1.11 root 1010: case i_OR:
1011: case i_AND:
1012: case i_EOR:
1.1.1.17 root 1013: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1014: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.7 root 1015: printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^');
1016: genflags (flag_logical, curi->size, "src", "", "");
1.1.1.17 root 1017: if (curi->size == sz_long && isreg (curi->dmode))
1.1.1.21! root 1018: addcycles (curi->mnemo == i_AND ? 2 : 4);
! 1019: fill_prefetch_next ();
1.1.1.7 root 1020: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1021: break;
1.1.1.11 root 1022: case i_ORSR:
1023: case i_EORSR:
1.1.1.3 root 1024: printf ("\tMakeSR();\n");
1.1.1.17 root 1025: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.7 root 1026: if (curi->size == sz_byte) {
1.1.1.3 root 1027: printf ("\tsrc &= 0xFF;\n");
1.1 root 1028: }
1.1.1.21! root 1029: addcycles (4);
! 1030: fill_prefetch_next ();
1.1.1.7 root 1031: printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
1.1.1.3 root 1032: printf ("\tMakeFromSR();\n");
1.1 root 1033: break;
1.1.1.11 root 1034: case i_ANDSR:
1.1.1.3 root 1035: printf ("\tMakeSR();\n");
1.1.1.17 root 1036: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.7 root 1037: if (curi->size == sz_byte) {
1.1.1.3 root 1038: printf ("\tsrc |= 0xFF00;\n");
1.1 root 1039: }
1.1.1.21! root 1040: addcycles (4);
! 1041: fill_prefetch_next ();
1.1.1.3 root 1042: printf ("\tregs.sr &= src;\n");
1043: printf ("\tMakeFromSR();\n");
1.1 root 1044: break;
1.1.1.11 root 1045: case i_SUB:
1.1.1.17 root 1046: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1047: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1048: if (isreg (curi->dmode)) {
1049: if (curi->dmode == Dreg && curi->size == sz_long)
1.1.1.21! root 1050: addcycles ((curi->smode == imm || curi->smode == immi) ? 4 : 2);
1.1.1.17 root 1051: }
1.1.1.21! root 1052: fill_prefetch_next ();
1.1 root 1053: start_brace ();
1.1.1.7 root 1054: genflags (flag_sub, curi->size, "newv", "src", "dst");
1055: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1056: break;
1.1.1.11 root 1057: case i_SUBA:
1.1.1.17 root 1058: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1059: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1060: if (isreg (curi->dmode) && curi->dmode == Areg) {
1.1.1.21! root 1061: int tmpc = curi->size == sz_long ? 2 : 4;
1.1.1.17 root 1062: if (curi->size == sz_long)
1063: tmpc += (isreg (curi->smode) || curi->smode == imm) ? 2 : 0;
1.1.1.21! root 1064: addcycles (tmpc);
1.1.1.17 root 1065: }
1.1.1.21! root 1066: fill_prefetch_next ();
1.1 root 1067: start_brace ();
1.1.1.3 root 1068: printf ("\tuae_u32 newv = dst - src;\n");
1.1.1.7 root 1069: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1.1 root 1070: break;
1.1.1.11 root 1071: case i_SUBX:
1.1.1.17 root 1072: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1073: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1074: if ((isreg (curi->smode) && curi->size == sz_long) || !isreg (curi->smode))
1.1.1.21! root 1075: addcycles (2);
! 1076: fill_prefetch_next ();
1.1 root 1077: start_brace ();
1.1.1.7 root 1078: printf ("\tuae_u32 newv = dst - src - (GET_XFLG ? 1 : 0);\n");
1079: genflags (flag_subx, curi->size, "newv", "src", "dst");
1080: genflags (flag_zn, curi->size, "newv", "", "");
1081: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1082: break;
1.1.1.11 root 1083: case i_SBCD:
1.1.1.17 root 1084: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1085: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1.1.1.18 root 1086: fill_prefetch_next ();
1.1 root 1087: start_brace ();
1.1.1.7 root 1088: printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG ? 1 : 0);\n");
1.1.1.3 root 1089: printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n");
1.1.1.14 root 1090: printf ("\tuae_u16 newv, tmp_newv;\n");
1091: printf ("\tint bcd = 0;\n");
1092: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n");
1093: printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n");
1094: printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n");
1095: printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG ? 1 : 0)) & 0x300) > 0xFF);\n");
1.1.1.17 root 1096: duplicate_carry (0);
1.1.1.7 root 1097: genflags (flag_zn, curi->size, "newv", "", "");
1.1.1.14 root 1098: printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
1.1.1.7 root 1099: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1100: break;
1.1.1.11 root 1101: case i_ADD:
1.1.1.17 root 1102: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1103: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1104: if (isreg (curi->dmode)) {
1105: if (curi->dmode == Dreg && curi->size == sz_long)
1.1.1.21! root 1106: addcycles ((curi->smode == imm || curi->smode == immi) ? 4 : 2);
1.1.1.17 root 1107: }
1.1.1.21! root 1108: fill_prefetch_next ();
1.1 root 1109: start_brace ();
1.1.1.7 root 1110: genflags (flag_add, curi->size, "newv", "src", "dst");
1111: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1112: break;
1.1.1.11 root 1113: case i_ADDA:
1.1.1.17 root 1114: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1115: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1116: if (isreg (curi->dmode) && curi->dmode == Areg) {
1.1.1.21! root 1117: int tmpc = curi->size == sz_long ? 2 : 4;
1.1.1.17 root 1118: if (curi->size == sz_long)
1119: tmpc += (isreg (curi->smode) || curi->smode == imm) ? 2 : 0;
1.1.1.21! root 1120: addcycles (tmpc);
1.1.1.17 root 1121: }
1.1.1.21! root 1122: fill_prefetch_next ();
1.1 root 1123: start_brace ();
1.1.1.3 root 1124: printf ("\tuae_u32 newv = dst + src;\n");
1.1.1.7 root 1125: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1.1 root 1126: break;
1.1.1.11 root 1127: case i_ADDX:
1.1.1.17 root 1128: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1129: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1130: if ((isreg (curi->smode) && curi->size == sz_long) || !isreg (curi->smode))
1.1.1.21! root 1131: addcycles (2);
! 1132: fill_prefetch_next ();
1.1 root 1133: start_brace ();
1.1.1.7 root 1134: printf ("\tuae_u32 newv = dst + src + (GET_XFLG ? 1 : 0);\n");
1135: genflags (flag_addx, curi->size, "newv", "src", "dst");
1136: genflags (flag_zn, curi->size, "newv", "", "");
1137: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1138: break;
1.1.1.11 root 1139: case i_ABCD:
1.1.1.17 root 1140: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1141: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1.1.1.18 root 1142: fill_prefetch_next ();
1.1 root 1143: start_brace ();
1.1.1.7 root 1144: printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG ? 1 : 0);\n");
1.1.1.3 root 1145: printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
1.1.1.14 root 1146: printf ("\tuae_u16 newv, tmp_newv;\n");
1.1.1.7 root 1147: printf ("\tint cflg;\n");
1.1.1.14 root 1148: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;");
1149: printf ("\tif (newv_lo > 9) { newv += 6; }\n");
1150: printf ("\tcflg = (newv & 0x3F0) > 0x90;\n");
1151: printf ("\tif (cflg) newv += 0x60;\n");
1.1.1.12 root 1152: printf ("\tSET_CFLG (cflg);\n");
1.1.1.17 root 1153: duplicate_carry (0);
1.1.1.7 root 1154: genflags (flag_zn, curi->size, "newv", "", "");
1.1.1.14 root 1155: printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
1.1.1.7 root 1156: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1157: break;
1.1.1.11 root 1158: case i_NEG:
1.1.1.17 root 1159: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.21! root 1160: if (isreg (curi->smode) && curi->size == sz_long)
! 1161: addcycles (2);
! 1162: fill_prefetch_next ();
1.1 root 1163: start_brace ();
1.1.1.7 root 1164: genflags (flag_sub, curi->size, "dst", "src", "0");
1165: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1.1 root 1166: break;
1.1.1.11 root 1167: case i_NEGX:
1.1.1.17 root 1168: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.21! root 1169: if (isreg (curi->smode) && curi->size == sz_long)
! 1170: addcycles (2);
! 1171: fill_prefetch_next ();
1.1 root 1172: start_brace ();
1.1.1.7 root 1173: printf ("\tuae_u32 newv = 0 - src - (GET_XFLG ? 1 : 0);\n");
1174: genflags (flag_subx, curi->size, "newv", "src", "0");
1175: genflags (flag_zn, curi->size, "newv", "", "");
1176: genastore ("newv", curi->smode, "srcreg", curi->size, "src");
1.1 root 1177: break;
1.1.1.11 root 1178: case i_NBCD:
1.1.1.17 root 1179: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.21! root 1180: if (isreg (curi->smode))
! 1181: addcycles (2);
! 1182: fill_prefetch_next ();
1.1 root 1183: start_brace ();
1.1.1.7 root 1184: printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG ? 1 : 0);\n");
1.1.1.3 root 1185: printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n");
1186: printf ("\tuae_u16 newv;\n");
1.1.1.7 root 1187: printf ("\tint cflg;\n");
1.1.1.14 root 1188: printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
1189: printf ("\tnewv = newv_hi + newv_lo;");
1190: printf ("\tcflg = (newv & 0x1F0) > 0x90;\n");
1191: printf ("\tif (cflg) newv -= 0x60;\n");
1.1.1.12 root 1192: printf ("\tSET_CFLG (cflg);\n");
1.1.1.17 root 1193: duplicate_carry (0);
1.1.1.7 root 1194: genflags (flag_zn, curi->size, "newv", "", "");
1195: genastore ("newv", curi->smode, "srcreg", curi->size, "src");
1.1 root 1196: break;
1.1.1.11 root 1197: case i_CLR:
1.1.1.17 root 1198: genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
1.1.1.21! root 1199: if (isreg (curi->smode) && curi->size == sz_long)
! 1200: addcycles (2);
! 1201: fill_prefetch_next ();
1.1.1.7 root 1202: genflags (flag_logical, curi->size, "0", "", "");
1203: genastore ("0", curi->smode, "srcreg", curi->size, "src");
1.1 root 1204: break;
1.1.1.11 root 1205: case i_NOT:
1.1.1.17 root 1206: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.21! root 1207: if (isreg (curi->smode) && curi->size == sz_long)
! 1208: addcycles (2);
! 1209: fill_prefetch_next ();
1.1 root 1210: start_brace ();
1.1.1.3 root 1211: printf ("\tuae_u32 dst = ~src;\n");
1.1.1.7 root 1212: genflags (flag_logical, curi->size, "dst", "", "");
1213: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1.1 root 1214: break;
1.1.1.11 root 1215: case i_TST:
1.1.1.17 root 1216: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.18 root 1217: fill_prefetch_next ();
1.1.1.7 root 1218: genflags (flag_logical, curi->size, "src", "", "");
1.1 root 1219: break;
1.1.1.11 root 1220: case i_BTST:
1.1.1.17 root 1221: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1222: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.21! root 1223: if (isreg (curi->dmode))
! 1224: addcycles (2);
! 1225: fill_prefetch_next ();
1.1.1.7 root 1226: if (curi->size == sz_byte)
1.1.1.3 root 1227: printf ("\tsrc &= 7;\n");
1.1 root 1228: else
1.1.1.3 root 1229: printf ("\tsrc &= 31;\n");
1.1.1.7 root 1230: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1.1 root 1231: break;
1.1.1.11 root 1232: case i_BCHG:
1.1.1.17 root 1233: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1234: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.21! root 1235: if (isreg (curi->dmode))
! 1236: addcycles (4);
! 1237: fill_prefetch_next ();
1.1.1.7 root 1238: if (curi->size == sz_byte)
1.1.1.3 root 1239: printf ("\tsrc &= 7;\n");
1.1 root 1240: else
1.1.1.3 root 1241: printf ("\tsrc &= 31;\n");
1242: printf ("\tdst ^= (1 << src);\n");
1.1.1.9 root 1243: printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n");
1.1.1.7 root 1244: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1245: break;
1.1.1.11 root 1246: case i_BCLR:
1.1.1.17 root 1247: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1248: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.21! root 1249: if (isreg (curi->dmode))
! 1250: addcycles (4);
! 1251: fill_prefetch_next ();
1.1.1.7 root 1252: if (curi->size == sz_byte)
1.1.1.3 root 1253: printf ("\tsrc &= 7;\n");
1.1 root 1254: else
1.1.1.3 root 1255: printf ("\tsrc &= 31;\n");
1.1.1.7 root 1256: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1.1.1.3 root 1257: printf ("\tdst &= ~(1 << src);\n");
1.1.1.7 root 1258: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1259: break;
1.1.1.11 root 1260: case i_BSET:
1.1.1.17 root 1261: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1262: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.21! root 1263: if (isreg (curi->dmode))
! 1264: addcycles (4);
! 1265: fill_prefetch_next ();
1.1.1.7 root 1266: if (curi->size == sz_byte)
1.1.1.3 root 1267: printf ("\tsrc &= 7;\n");
1.1 root 1268: else
1.1.1.3 root 1269: printf ("\tsrc &= 31;\n");
1.1.1.7 root 1270: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
1.1.1.3 root 1271: printf ("\tdst |= (1 << src);\n");
1.1.1.7 root 1272: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1273: break;
1.1.1.11 root 1274: case i_CMPM:
1.1.1.17 root 1275: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
1276: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1.1.1.18 root 1277: fill_prefetch_next ();
1.1.1.17 root 1278: start_brace ();
1279: genflags (flag_cmp, curi->size, "newv", "src", "dst");
1280: break;
1.1.1.11 root 1281: case i_CMP:
1.1.1.17 root 1282: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1283: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1284: if (isreg (curi->dmode)) {
1285: if (curi->dmode == Areg || (curi->dmode == Dreg && curi->size == sz_long))
1.1.1.21! root 1286: addcycles (2);
1.1.1.17 root 1287: }
1.1.1.21! root 1288: fill_prefetch_next ();
1.1 root 1289: start_brace ();
1.1.1.7 root 1290: genflags (flag_cmp, curi->size, "newv", "src", "dst");
1.1 root 1291: break;
1.1.1.11 root 1292: case i_CMPA:
1.1.1.17 root 1293: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1294: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1295: if (isreg (curi->dmode)) {
1296: if (curi->dmode == Areg || (curi->dmode == Dreg && curi->size == sz_long))
1.1.1.21! root 1297: addcycles (2);
1.1.1.17 root 1298: }
1.1.1.21! root 1299: fill_prefetch_next ();
1.1 root 1300: start_brace ();
1.1.1.5 root 1301: genflags (flag_cmp, sz_long, "newv", "src", "dst");
1.1 root 1302: break;
1303: /* The next two are coded a little unconventional, but they are doing
1304: * weird things... */
1.1.1.11 root 1305: case i_MVPRM:
1.1.1.17 root 1306: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.21! root 1307: printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
1.1.1.18 root 1308: fill_prefetch_next ();
1.1.1.7 root 1309: if (curi->size == sz_word) {
1.1.1.21! root 1310: printf ("\tput_byte (memp, src >> 8); put_byte (memp + 2, src);\n");
1.1 root 1311: } else {
1.1.1.21! root 1312: printf ("\tput_byte (memp, src >> 24); put_byte (memp + 2, src >> 16);\n");
! 1313: printf ("\tput_byte (memp + 4, src >> 8); put_byte (memp + 6, src);\n");
1.1 root 1314: }
1315: break;
1.1.1.11 root 1316: case i_MVPMR:
1.1.1.21! root 1317: printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
1.1.1.17 root 1318: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
1.1.1.7 root 1319: if (curi->size == sz_word) {
1.1.1.21! root 1320: printf ("\tuae_u16 val = (get_byte (memp) << 8) + get_byte (memp + 2);\n");
1.1 root 1321: } else {
1.1.1.21! root 1322: printf ("\tuae_u32 val = (get_byte (memp) << 24) + (get_byte (memp + 2) << 16)\n");
! 1323: printf (" + (get_byte (memp + 4) << 8) + get_byte (memp + 6);\n");
1.1 root 1324: }
1.1.1.17 root 1325: fill_prefetch_next ();
1.1.1.7 root 1326: genastore ("val", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1327: break;
1.1.1.11 root 1328: case i_MOVE:
1.1.1.17 root 1329: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1330: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_APDI);
1.1.1.7 root 1331: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1.1.1.17 root 1332: genflags (flag_logical, curi->size, "src", "", "");
1333: sync_m68k_pc ();
1334: fill_prefetch_next ();
1.1 root 1335: break;
1.1.1.11 root 1336: case i_MOVEA:
1.1.1.17 root 1337: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1338: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_APDI);
1.1.1.7 root 1339: if (curi->size == sz_word) {
1.1.1.3 root 1340: printf ("\tuae_u32 val = (uae_s32)(uae_s16)src;\n");
1.1 root 1341: } else {
1.1.1.3 root 1342: printf ("\tuae_u32 val = src;\n");
1.1 root 1343: }
1.1.1.18 root 1344: fill_prefetch_next ();
1.1.1.7 root 1345: genastore ("val", curi->dmode, "dstreg", sz_long, "dst");
1.1 root 1346: break;
1.1.1.11 root 1347: case i_MVSR2:
1.1.1.17 root 1348: genamode (curi->smode, "srcreg", sz_word, "src", 2, 0, 0);
1.1.1.21! root 1349: if (isreg (curi->smode))
! 1350: addcycles (2);
! 1351: fill_prefetch_next ();
1.1.1.3 root 1352: printf ("\tMakeSR();\n");
1.1.1.7 root 1353: if (curi->size == sz_byte)
1354: genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src");
1.1 root 1355: else
1.1.1.7 root 1356: genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src");
1.1 root 1357: break;
1.1.1.11 root 1358: case i_MV2SR:
1.1.1.17 root 1359: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
1360: if (curi->size == sz_byte) {
1.1.1.21! root 1361: addcycles (8);
! 1362: printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
1.1.1.17 root 1363: } else {
1.1.1.21! root 1364: addcycles (4);
1.1.1.3 root 1365: printf ("\tregs.sr = src;\n");
1.1 root 1366: }
1.1.1.21! root 1367: fill_prefetch_next ();
! 1368: printf ("\tMakeFromSR ();\n");
1.1 root 1369: break;
1.1.1.11 root 1370: case i_SWAP:
1.1.1.17 root 1371: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
1.1.1.18 root 1372: fill_prefetch_next ();
1.1 root 1373: start_brace ();
1.1.1.3 root 1374: printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
1.1.1.5 root 1375: genflags (flag_logical, sz_long, "dst", "", "");
1.1.1.7 root 1376: genastore ("dst", curi->smode, "srcreg", sz_long, "src");
1.1 root 1377: break;
1.1.1.11 root 1378: case i_EXG:
1.1.1.17 root 1379: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1380: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.21! root 1381: addcycles (2);
! 1382: fill_prefetch_next ();
1.1.1.7 root 1383: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
1384: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1385: break;
1.1.1.11 root 1386: case i_EXT:
1.1.1.17 root 1387: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
1.1.1.18 root 1388: fill_prefetch_next ();
1.1 root 1389: start_brace ();
1.1.1.7 root 1390: switch (curi->size) {
1.1.1.11 root 1391: case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break;
1392: case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break;
1393: case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break;
1394: default: abort ();
1.1 root 1395: }
1.1.1.5 root 1396: genflags (flag_logical,
1.1.1.7 root 1397: curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
1398: genastore ("dst", curi->smode, "srcreg",
1399: curi->size == sz_word ? sz_word : sz_long, "src");
1.1 root 1400: break;
1.1.1.11 root 1401: case i_MVMEL:
1.1.1.5 root 1402: genmovemel (opcode);
1.1.1.18 root 1403: fill_prefetch_next ();
1.1 root 1404: break;
1.1.1.11 root 1405: case i_MVMLE:
1.1.1.5 root 1406: genmovemle (opcode);
1.1.1.18 root 1407: fill_prefetch_next ();
1.1 root 1408: break;
1.1.1.11 root 1409: case i_TRAP:
1.1.1.17 root 1410: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.5 root 1411: sync_m68k_pc ();
1.1.1.3 root 1412: printf ("\tException(src+32,0);\n");
1.1.1.17 root 1413: did_prefetch = 1;
1.1.1.3 root 1414: m68k_pc_offset = 0;
1.1 root 1415: break;
1.1.1.11 root 1416: case i_MVR2USP:
1.1.1.17 root 1417: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.18 root 1418: fill_prefetch_next ();
1.1.1.3 root 1419: printf ("\tregs.usp = src;\n");
1.1 root 1420: break;
1.1.1.11 root 1421: case i_MVUSP2R:
1.1.1.17 root 1422: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0, 0);
1.1.1.18 root 1423: fill_prefetch_next ();
1.1.1.7 root 1424: genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src");
1.1 root 1425: break;
1.1.1.11 root 1426: case i_RESET:
1.1.1.18 root 1427: fill_prefetch_next ();
1.1.1.17 root 1428: printf ("\tcpureset();\n");
1.1 root 1429: break;
1.1.1.11 root 1430: case i_NOP:
1.1.1.18 root 1431: fill_prefetch_next ();
1.1 root 1432: break;
1.1.1.11 root 1433: case i_STOP:
1.1.1.17 root 1434: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.3 root 1435: printf ("\tregs.sr = src;\n");
1436: printf ("\tMakeFromSR();\n");
1437: printf ("\tm68k_setstopped(1);\n");
1.1.1.17 root 1438: sync_m68k_pc ();
1439: fill_prefetch_full ();
1.1 root 1440: break;
1.1.1.11 root 1441: case i_RTE:
1.1.1.3 root 1442: if (cpu_level == 0) {
1.1.1.17 root 1443: genamode (Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
1444: genamode (Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
1445: printf ("\tregs.sr = sr; m68k_setpc (pc);\n");
1.1.1.3 root 1446: printf ("\tMakeFromSR();\n");
1447: } else {
1.1 root 1448: int old_brace_level = n_braces;
1.1.1.3 root 1449: if (next_cpu_level < 0)
1450: next_cpu_level = 0;
1451: printf ("\tuae_u16 newsr; uae_u32 newpc; for (;;) {\n");
1.1.1.17 root 1452: genamode (Aipi, "7", sz_word, "sr", 1, 0, 0);
1453: genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
1454: genamode (Aipi, "7", sz_word, "format", 1, 0, 0);
1.1.1.3 root 1455: printf ("\tnewsr = sr; newpc = pc;\n");
1456: printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n");
1457: printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n");
1.1.1.21! root 1458: printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg (regs, 7) += 4; break; }\n");
! 1459: printf ("\telse if ((format & 0xF000) == 0x7000) { m68k_areg (regs, 7) += 52; break; }\n");
! 1460: printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg (regs, 7) += 50; break; }\n");
! 1461: printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg (regs, 7) += 12; break; }\n");
! 1462: printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg (regs, 7) += 24; break; }\n");
! 1463: printf ("\telse if ((format & 0xF000) == 0xb000) { m68k_areg (regs, 7) += 84; break; }\n");
1.1.1.3 root 1464: printf ("\telse { Exception(14,0); goto %s; }\n", endlabelstr);
1465: printf ("\tregs.sr = newsr; MakeFromSR();\n}\n");
1.1 root 1466: pop_braces (old_brace_level);
1.1.1.3 root 1467: printf ("\tregs.sr = newsr; MakeFromSR();\n");
1.1.1.17 root 1468: printf ("\tif (newpc & 1)\n");
1.1.1.21! root 1469: printf ("\t\texception3 (0x%04.4X, m68k_getpc (), newpc);\n", opcode);
1.1.1.17 root 1470: printf ("\telse\n");
1471: printf ("\t\tm68k_setpc (newpc);\n");
1.1.1.5 root 1472: need_endlabel = 1;
1.1 root 1473: }
1.1.1.3 root 1474: /* PC is set and prefetch filled. */
1475: m68k_pc_offset = 0;
1.1.1.17 root 1476: fill_prefetch_full ();
1.1 root 1477: break;
1.1.1.11 root 1478: case i_RTD:
1.1.1.17 root 1479: genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
1480: genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0);
1.1.1.21! root 1481: printf ("\tm68k_areg (regs, 7) += offs;\n");
1.1.1.18 root 1482: printf ("\tif (pc & 1)\n");
1.1.1.21! root 1483: printf ("\t\texception3 (0x%04.4X, m68k_getpc (), pc);\n", opcode);
1.1.1.18 root 1484: printf ("\telse\n");
1.1.1.17 root 1485: printf ("\t\tm68k_setpc (pc);\n");
1.1.1.3 root 1486: /* PC is set and prefetch filled. */
1487: m68k_pc_offset = 0;
1.1.1.17 root 1488: fill_prefetch_full ();
1.1 root 1489: break;
1.1.1.11 root 1490: case i_LINK:
1.1.1.17 root 1491: genamode (Apdi, "7", sz_long, "old", 2, 0, 0);
1492: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
1.1.1.3 root 1493: genastore ("src", Apdi, "7", sz_long, "old");
1.1.1.21! root 1494: genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src");
1.1.1.17 root 1495: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0);
1.1.1.21! root 1496: printf ("\tm68k_areg (regs, 7) += offs;\n");
1.1.1.18 root 1497: fill_prefetch_next ();
1.1 root 1498: break;
1.1.1.11 root 1499: case i_UNLK:
1.1.1.17 root 1500: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.21! root 1501: printf ("\tm68k_areg (regs, 7) = src;\n");
1.1.1.17 root 1502: genamode (Aipi, "7", sz_long, "old", 1, 0, 0);
1.1.1.18 root 1503: fill_prefetch_next ();
1.1.1.7 root 1504: genastore ("old", curi->smode, "srcreg", curi->size, "src");
1.1 root 1505: break;
1.1.1.11 root 1506: case i_RTS:
1.1.1.3 root 1507: printf ("\tm68k_do_rts();\n");
1508: m68k_pc_offset = 0;
1.1.1.17 root 1509: fill_prefetch_full ();
1.1 root 1510: break;
1.1.1.11 root 1511: case i_TRAPV:
1.1.1.3 root 1512: sync_m68k_pc ();
1.1.1.17 root 1513: printf ("\tif (GET_VFLG) {\n");
1514: printf ("\t\tException (7, m68k_getpc ());\n");
1515: printf ("\t\tgoto %s;\n", endlabelstr);
1516: printf ("\t}\n");
1.1.1.18 root 1517: fill_prefetch_next ();
1.1.1.5 root 1518: need_endlabel = 1;
1.1 root 1519: break;
1.1.1.11 root 1520: case i_RTR:
1.1.1.3 root 1521: printf ("\tMakeSR();\n");
1.1.1.17 root 1522: genamode (Aipi, "7", sz_word, "sr", 1, 0, 0);
1523: genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
1.1.1.3 root 1524: printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
1.1.1.21! root 1525: printf ("\tregs.sr |= sr; m68k_setpc (pc);\n");
1.1.1.3 root 1526: printf ("\tMakeFromSR();\n");
1527: m68k_pc_offset = 0;
1.1.1.17 root 1528: fill_prefetch_full ();
1.1 root 1529: break;
1.1.1.11 root 1530: case i_JSR:
1.1.1.17 root 1531: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
1532: start_brace ();
1.1.1.21! root 1533: printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset);
1.1.1.17 root 1534: if (using_exception_3) {
1535: printf ("\tif (srca & 1) {\n");
1536: printf ("\t\texception3i (opcode, oldpc, srca);\n");
1537: printf ("\t\tgoto %s;\n", endlabelstr);
1538: printf ("\t}\n");
1539: need_endlabel = 1;
1540: }
1541: printf ("\tm68k_setpc (srca);\n");
1.1.1.3 root 1542: m68k_pc_offset = 0;
1.1.1.21! root 1543: fill_prefetch_1 (0);
1.1.1.18 root 1544: printf("\tm68k_areg (regs, 7) -= 4;\n");
1.1.1.17 root 1545: printf("\tput_long (m68k_areg (regs, 7), oldpc);\n");
1.1.1.18 root 1546: fill_prefetch_next ();
1.1.1.3 root 1547: break;
1.1.1.11 root 1548: case i_JMP:
1.1.1.17 root 1549: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
1550: if (using_exception_3) {
1551: printf ("\tif (srca & 1) {\n");
1.1.1.21! root 1552: printf ("\t\texception3i (opcode, m68k_getpc () + 6, srca);\n");
1.1.1.17 root 1553: printf ("\t\tgoto %s;\n", endlabelstr);
1554: printf ("\t}\n");
1555: need_endlabel = 1;
1556: }
1.1.1.21! root 1557: if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r)
! 1558: addcycles (2);
! 1559: printf ("\tm68k_setpc (srca);\n");
1.1.1.3 root 1560: m68k_pc_offset = 0;
1.1.1.17 root 1561: fill_prefetch_full ();
1.1 root 1562: break;
1.1.1.11 root 1563: case i_BSR:
1.1.1.17 root 1564: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL);
1.1.1.3 root 1565: printf ("\tuae_s32 s = (uae_s32)src + 2;\n");
1566: if (using_exception_3) {
1567: printf ("\tif (src & 1) {\n");
1.1.1.21! root 1568: printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + s);\n");
1.1.1.17 root 1569: printf ("\t\tgoto %s;\n", endlabelstr);
1.1.1.3 root 1570: printf ("\t}\n");
1.1.1.5 root 1571: need_endlabel = 1;
1.1.1.3 root 1572: }
1.1.1.21! root 1573: addcycles (2);
! 1574: printf ("\tm68k_do_bsr(m68k_getpc () + %d, s);\n", m68k_pc_offset);
1.1.1.3 root 1575: m68k_pc_offset = 0;
1.1.1.17 root 1576: fill_prefetch_full ();
1.1 root 1577: break;
1.1.1.11 root 1578: case i_Bcc:
1.1.1.7 root 1579: if (curi->size == sz_long) {
1.1.1.3 root 1580: if (cpu_level < 2) {
1.1.1.21! root 1581: addcycles (2);
1.1.1.17 root 1582: printf ("\tif (cctrue(%d)) {\n", curi->cc, endlabelstr);
1.1.1.21! root 1583: printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n");
1.1.1.17 root 1584: printf ("\t\tgoto %s;\n", endlabelstr);
1585: printf ("\t}\n");
1586: sync_m68k_pc ();
1.1.1.18 root 1587: irc2ir ();
1.1.1.17 root 1588: fill_prefetch_2 ();
1589: printf ("\tgoto %s;\n", endlabelstr);
1.1.1.5 root 1590: need_endlabel = 1;
1.1.1.3 root 1591: } else {
1592: if (next_cpu_level < 1)
1593: next_cpu_level = 1;
1594: }
1595: }
1.1.1.21! root 1596: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
! 1597: addcycles (2);
1.1.1.7 root 1598: printf ("\tif (!cctrue(%d)) goto didnt_jump;\n", curi->cc);
1.1.1.3 root 1599: if (using_exception_3) {
1600: printf ("\tif (src & 1) {\n");
1.1.1.21! root 1601: printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)src);\n");
1.1.1.17 root 1602: printf ("\t\tgoto %s;\n", endlabelstr);
1.1.1.3 root 1603: printf ("\t}\n");
1.1.1.5 root 1604: need_endlabel = 1;
1.1.1.3 root 1605: }
1.1.1.17 root 1606: if (using_prefetch) {
1607: if (curi->size == sz_byte) {
1608: printf ("\tm68k_incpc ((uae_s32)src + 2);\n");
1609: } else {
1610: printf ("\tm68k_incpc ((uae_s32)src + 2);\n");
1611: }
1612: fill_prefetch_full ();
1613: if (using_ce)
1614: printf ("\treturn;\n");
1615: else
1.1.1.21! root 1616: printf ("\treturn 10 * CYCLE_UNIT / 2;\n");
1.1.1.17 root 1617: } else {
1618: printf ("\tm68k_incpc ((uae_s32)src + 2);\n");
1619: returncycles ("\t", 10);
1620: }
1.1.1.3 root 1621: printf ("didnt_jump:;\n");
1.1.1.5 root 1622: need_endlabel = 1;
1.1.1.17 root 1623: sync_m68k_pc ();
1624: if (curi->size == sz_byte) {
1.1.1.21! root 1625: addcycles (2);
1.1.1.17 root 1626: irc2ir ();
1627: fill_prefetch_2 ();
1628: } else
1629: fill_prefetch_full ();
1.1.1.11 root 1630: insn_n_cycles = curi->size == sz_byte ? 8 : 12;
1.1 root 1631: break;
1.1.1.11 root 1632: case i_LEA:
1.1.1.17 root 1633: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
1634: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
1635: if (curi->smode == Ad8r || curi->smode == PC8r)
1.1.1.21! root 1636: addcycles (4);
! 1637: fill_prefetch_next ();
1.1.1.7 root 1638: genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
1.1 root 1639: break;
1.1.1.11 root 1640: case i_PEA:
1.1.1.17 root 1641: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
1642: genamode (Apdi, "7", sz_long, "dst", 2, 0, GF_AA);
1643: if (curi->smode == Ad8r || curi->smode == PC8r)
1.1.1.21! root 1644: addcycles (4);
! 1645: if (!(curi->smode == absw || curi->smode == absl))
! 1646: fill_prefetch_next ();
1.1.1.3 root 1647: genastore ("srca", Apdi, "7", sz_long, "dst");
1.1.1.21! root 1648: if ((curi->smode == absw || curi->smode == absl))
! 1649: fill_prefetch_next ();
1.1 root 1650: break;
1.1.1.11 root 1651: case i_DBcc:
1.1.1.17 root 1652: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL);
1653: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA|GF_NOREFILL);
1.1.1.3 root 1654:
1.1.1.21! root 1655: printf ("\tuaecptr oldpc = m68k_getpc ();\n");
! 1656: addcycles (2);
1.1.1.7 root 1657: printf ("\tif (!cctrue(%d)) {\n", curi->cc);
1.1.1.21! root 1658: printf ("\t\tm68k_incpc ((uae_s32)offs + 2);\n");
! 1659: printf ("\t"); fill_prefetch_1 (0);
1.1.1.17 root 1660: printf ("\t"); genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src");
1.1.1.3 root 1661:
1662: printf ("\t\tif (src) {\n");
1663: if (using_exception_3) {
1664: printf ("\t\t\tif (offs & 1) {\n");
1.1.1.21! root 1665: printf ("\t\t\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)offs + 2);\n");
1.1.1.17 root 1666: printf ("\t\t\t\tgoto %s;\n", endlabelstr);
1667: printf ("\t\t\t}\n");
1.1.1.5 root 1668: need_endlabel = 1;
1.1.1.3 root 1669: }
1.1.1.17 root 1670: irc2ir ();
1.1.1.21! root 1671: fill_prefetch_1 (2);
1.1.1.17 root 1672: returncycles ("\t\t\t", 12);
1.1.1.3 root 1673: printf ("\t\t}\n");
1.1.1.17 root 1674: printf ("\t} else {\n");
1.1.1.21! root 1675: addcycles2 ("\t\t", 2);
1.1.1.3 root 1676: printf ("\t}\n");
1.1.1.17 root 1677: printf ("\tm68k_setpc (oldpc + %d);\n", m68k_pc_offset);
1678: m68k_pc_offset = 0;
1679: fill_prefetch_full ();
1.1.1.11 root 1680: insn_n_cycles = 12;
1.1.1.5 root 1681: need_endlabel = 1;
1.1 root 1682: break;
1.1.1.11 root 1683: case i_Scc:
1.1.1.17 root 1684: genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
1.1 root 1685: start_brace ();
1.1.1.21! root 1686: fill_prefetch_next ();
1.1.1.7 root 1687: printf ("\tint val = cctrue(%d) ? 0xff : 0;\n", curi->cc);
1688: genastore ("val", curi->smode, "srcreg", curi->size, "src");
1.1 root 1689: break;
1.1.1.11 root 1690: case i_DIVU:
1.1.1.21! root 1691: printf ("\tuaecptr oldpc = m68k_getpc ();\n");
1.1.1.17 root 1692: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
1693: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1694: printf ("\tCLEAR_CZNV;\n");
1695: printf ("\tif (src == 0) {\n");
1696: if (cpu_level > 0) {
1697: /* 68020 sets V when dividing by zero and N if dst is negative
1698: * 68000 clears both
1699: */
1700: printf("\t\tSET_VFLG (1);\n");
1701: printf("\t\tif (dst < 0) SET_NFLG (1);\n");
1.1.1.19 root 1702: }
1.1.1.21! root 1703: printf ("\t\tm68k_incpc (%d);\n", m68k_pc_offset);
1.1.1.17 root 1704: printf ("\t\tException (5, oldpc);\n");
1705: printf ("\t\tgoto %s;\n", endlabelstr);
1706: printf ("\t} else {\n");
1707: printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
1708: printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n");
1709: if (using_ce) {
1.1.1.21! root 1710: printf ("\t\tint cycles = 138 * CYCLE_UNIT / 2 - lostcycles;\n");
1.1.1.17 root 1711: }
1.1 root 1712: /* The N flag appears to be set each time there is an overflow.
1.1.1.17 root 1713: * Weird. but 68020 only sets N when dst is negative.. */
1714: printf ("\t\tif (newv > 0xffff) {\n");
1715: printf ("\t\t\tSET_VFLG (1);\n");
1716: #ifdef UNDEF68020
1717: if (cpu_level >= 2)
1718: printf ("\t\t\tif (currprefs.cpu_level == 0 || dst < 0) SET_NFLG (1);\n");
1719: else /* ??? some 68000 revisions may not set NFLG when overflow happens.. */
1720: #endif
1721: printf ("\t\t\tSET_NFLG (1);\n");
1722: printf ("\t\t} else {\n");
1723: printf ("\t\t"); genflags (flag_logical, sz_word, "newv", "", "");
1724: printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
1725: printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1726: printf ("\t\t}\n");
1.1.1.21! root 1727: fill_prefetch_next ();
! 1728: sync_m68k_pc ();
1.1.1.3 root 1729: printf ("\t}\n");
1.1.1.11 root 1730: insn_n_cycles += 136;
1.1.1.5 root 1731: need_endlabel = 1;
1.1.1.3 root 1732: break;
1.1.1.11 root 1733: case i_DIVS:
1.1.1.21! root 1734: printf ("\tuaecptr oldpc = m68k_getpc ();\n");
1.1.1.17 root 1735: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
1736: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1737: printf ("\tCLEAR_CZNV;\n");
1738: printf ("\tif (src == 0) {\n");
1739: if (cpu_level > 0) {
1740: /* 68020 sets V when dividing by zero. Z is also set.
1741: * 68000 clears both
1742: */
1743: printf("\t\tSET_VFLG (1);\n");
1744: printf("\t\tSET_ZFLG (1);\n");
1745: }
1.1.1.21! root 1746: printf ("\t\tm68k_incpc (%d);\n", m68k_pc_offset);
1.1.1.17 root 1747: printf ("\t\tException (5, oldpc);\n");
1748: printf ("\t\tgoto %s;\n", endlabelstr);
1749: printf ("\t} else {\n");
1750: printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
1751: printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
1752: if (using_ce) {
1.1.1.21! root 1753: printf ("\t\tint cycles = 156 * CYCLE_UNIT / 2 - lostcycles;\n");
1.1.1.17 root 1754: }
1755: printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n");
1756: printf ("\t\t\tSET_VFLG (1);\n");
1757: #ifdef UNDEF68020
1758: if (cpu_level > 0)
1759: printf ("\t\t\tif (currprefs.cpu_level == 0) SET_NFLG (1);\n");
1760: else
1761: #endif
1762: printf ("\t\t\tSET_NFLG (1);\n");
1763: printf ("\t\t} else {\n");
1764: printf ("\t\t\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n");
1.1.1.5 root 1765: genflags (flag_logical, sz_word, "newv", "", "");
1.1.1.17 root 1766: printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
1767: printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1768: printf ("\t\t}\n");
1.1.1.21! root 1769: fill_prefetch_next ();
! 1770: sync_m68k_pc ();
1.1.1.3 root 1771: printf ("\t}\n");
1.1.1.11 root 1772: insn_n_cycles += 154;
1.1.1.5 root 1773: need_endlabel = 1;
1.1.1.3 root 1774: break;
1.1.1.11 root 1775: case i_MULU:
1.1.1.17 root 1776: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
1777: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0);
1.1.1.21! root 1778: fill_prefetch_next ();
1.1 root 1779: start_brace ();
1.1.1.3 root 1780: printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
1.1.1.5 root 1781: genflags (flag_logical, sz_long, "newv", "", "");
1.1.1.7 root 1782: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1.1.1.17 root 1783: sync_m68k_pc ();
1.1.1.11 root 1784: insn_n_cycles += 66;
1.1 root 1785: break;
1.1.1.11 root 1786: case i_MULS:
1.1.1.17 root 1787: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
1788: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0);
1.1.1.21! root 1789: fill_prefetch_next ();
1.1 root 1790: start_brace ();
1.1.1.3 root 1791: printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
1.1.1.5 root 1792: genflags (flag_logical, sz_long, "newv", "", "");
1.1.1.7 root 1793: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
1.1.1.11 root 1794: insn_n_cycles += 66;
1.1 root 1795: break;
1.1.1.11 root 1796: case i_CHK:
1.1.1.21! root 1797: printf ("\tuaecptr oldpc = m68k_getpc ();\n");
1.1.1.17 root 1798: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1799: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1800: sync_m68k_pc ();
1.1.1.21! root 1801: addcycles (6);
! 1802: fill_prefetch_next ();
1.1.1.17 root 1803: printf ("\tif ((uae_s32)dst < 0) {\n");
1804: printf ("\t\tSET_NFLG (1);\n");
1805: printf ("\t\tException (6, oldpc);\n");
1806: printf ("\t\tgoto %s;\n", endlabelstr);
1807: printf ("\t} else if (dst > src) {\n");
1808: printf ("\t\tSET_NFLG (0);\n");
1809: printf ("\t\tException (6, oldpc);\n");
1810: printf ("\t\tgoto %s;\n", endlabelstr);
1811: printf ("\t}\n");
1.1.1.5 root 1812: need_endlabel = 1;
1.1 root 1813: break;
1.1.1.3 root 1814:
1.1.1.11 root 1815: case i_CHK2:
1.1.1.21! root 1816: printf ("\tuaecptr oldpc = m68k_getpc ();\n");
1.1.1.17 root 1817: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1818: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
1.1.1.18 root 1819: fill_prefetch_0 ();
1.1.1.3 root 1820: printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
1.1.1.7 root 1821: switch (curi->size) {
1.1.1.11 root 1822: case sz_byte:
1.1.1.21! root 1823: printf ("\tlower=(uae_s32)(uae_s8)get_byte (dsta); upper = (uae_s32)(uae_s8)get_byte (dsta+1);\n");
1.1.1.3 root 1824: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n");
1825: break;
1.1.1.11 root 1826: case sz_word:
1.1.1.21! root 1827: printf ("\tlower=(uae_s32)(uae_s16)get_word (dsta); upper = (uae_s32)(uae_s16)get_word (dsta+2);\n");
1.1.1.3 root 1828: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n");
1829: break;
1.1.1.11 root 1830: case sz_long:
1.1.1.21! root 1831: printf ("\tlower=get_long (dsta); upper = get_long (dsta+4);\n");
1.1.1.3 root 1832: break;
1.1.1.11 root 1833: default:
1.1.1.5 root 1834: abort ();
1.1.1.3 root 1835: }
1.1.1.7 root 1836: printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
1837: printf ("\tSET_CFLG (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
1838: printf ("\tif ((extra & 0x800) && GET_CFLG) { Exception(6,oldpc); goto %s; }\n}\n", endlabelstr);
1.1.1.5 root 1839: need_endlabel = 1;
1.1.1.3 root 1840: break;
1841:
1.1.1.11 root 1842: case i_ASR:
1.1.1.17 root 1843: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
1844: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 1845: fill_prefetch_next ();
1.1.1.3 root 1846: start_brace ();
1.1.1.7 root 1847: switch (curi->size) {
1.1.1.11 root 1848: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
1849: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
1850: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1851: default: abort ();
1.1 root 1852: }
1.1.1.7 root 1853: printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1);
1.1.1.3 root 1854: printf ("\tcnt &= 63;\n");
1.1.1.7 root 1855: printf ("\tCLEAR_CZNV;\n");
1856: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1857: printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size));
1858: printf ("\t\tSET_CFLG (sign);\n");
1.1.1.17 root 1859: duplicate_carry (0);
1.1.1.7 root 1860: if (source_is_imm1_8 (curi))
1861: printf ("\t} else {\n");
1862: else
1863: printf ("\t} else if (cnt > 0) {\n");
1864: printf ("\t\tval >>= cnt - 1;\n");
1865: printf ("\t\tSET_CFLG (val & 1);\n");
1.1.1.17 root 1866: duplicate_carry (0);
1.1.1.7 root 1867: printf ("\t\tval >>= 1;\n");
1868: printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n",
1869: bit_mask (curi->size),
1870: bit_size (curi->size));
1871: printf ("\t\tval &= %s;\n", bit_mask (curi->size));
1872: printf ("\t}\n");
1873: genflags (flag_logical_noclobber, curi->size, "val", "", "");
1874: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 1875: break;
1.1.1.11 root 1876: case i_ASL:
1.1.1.17 root 1877: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
1878: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 1879: fill_prefetch_next ();
1.1 root 1880: start_brace ();
1.1.1.7 root 1881: switch (curi->size) {
1.1.1.11 root 1882: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
1883: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
1884: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1885: default: abort ();
1.1 root 1886: }
1.1.1.3 root 1887: printf ("\tcnt &= 63;\n");
1.1.1.7 root 1888: printf ("\tCLEAR_CZNV;\n");
1889: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1890: printf ("\t\tSET_VFLG (val != 0);\n");
1891: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
1892: bit_size (curi->size));
1.1.1.17 root 1893: duplicate_carry (0);
1.1.1.3 root 1894: printf ("\t\tval = 0;\n");
1.1.1.7 root 1895: if (source_is_imm1_8 (curi))
1896: printf ("\t} else {\n");
1897: else
1898: printf ("\t} else if (cnt > 0) {\n");
1.1.1.3 root 1899: printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n",
1.1.1.7 root 1900: bit_mask (curi->size),
1901: bit_size (curi->size) - 1,
1902: bit_mask (curi->size));
1903: printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n");
1904: printf ("\t\tval <<= cnt - 1;\n");
1905: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1.1.1.17 root 1906: duplicate_carry (0);
1.1.1.7 root 1907: printf ("\t\tval <<= 1;\n");
1908: printf ("\t\tval &= %s;\n", bit_mask (curi->size));
1909: printf ("\t}\n");
1910: genflags (flag_logical_noclobber, curi->size, "val", "", "");
1911: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 1912: break;
1.1.1.11 root 1913: case i_LSR:
1.1.1.17 root 1914: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
1915: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 1916: fill_prefetch_next ();
1.1 root 1917: start_brace ();
1.1.1.7 root 1918: switch (curi->size) {
1.1.1.11 root 1919: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
1920: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
1921: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1922: default: abort ();
1.1 root 1923: }
1.1.1.3 root 1924: printf ("\tcnt &= 63;\n");
1.1.1.7 root 1925: printf ("\tCLEAR_CZNV;\n");
1926: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1927: printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n",
1928: bit_size (curi->size), bit_size (curi->size) - 1);
1.1.1.17 root 1929: duplicate_carry (0);
1.1.1.3 root 1930: printf ("\t\tval = 0;\n");
1.1.1.7 root 1931: if (source_is_imm1_8 (curi))
1932: printf ("\t} else {\n");
1933: else
1934: printf ("\t} else if (cnt > 0) {\n");
1935: printf ("\t\tval >>= cnt - 1;\n");
1936: printf ("\t\tSET_CFLG (val & 1);\n");
1.1.1.17 root 1937: duplicate_carry (0);
1.1.1.7 root 1938: printf ("\t\tval >>= 1;\n");
1939: printf ("\t}\n");
1940: genflags (flag_logical_noclobber, curi->size, "val", "", "");
1941: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 1942: break;
1.1.1.11 root 1943: case i_LSL:
1.1.1.17 root 1944: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
1945: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 1946: fill_prefetch_next ();
1.1 root 1947: start_brace ();
1.1.1.7 root 1948: switch (curi->size) {
1.1.1.11 root 1949: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
1950: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
1951: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1952: default: abort ();
1.1 root 1953: }
1.1.1.3 root 1954: printf ("\tcnt &= 63;\n");
1.1.1.7 root 1955: printf ("\tCLEAR_CZNV;\n");
1956: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
1957: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
1958: bit_size (curi->size));
1.1.1.17 root 1959: duplicate_carry (0);
1.1.1.3 root 1960: printf ("\t\tval = 0;\n");
1.1.1.7 root 1961: if (source_is_imm1_8 (curi))
1962: printf ("\t} else {\n");
1963: else
1964: printf ("\t} else if (cnt > 0) {\n");
1965: printf ("\t\tval <<= (cnt - 1);\n");
1966: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1.1.1.17 root 1967: duplicate_carry (0);
1.1.1.7 root 1968: printf ("\t\tval <<= 1;\n");
1969: printf ("\tval &= %s;\n", bit_mask (curi->size));
1970: printf ("\t}\n");
1971: genflags (flag_logical_noclobber, curi->size, "val", "", "");
1972: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 1973: break;
1.1.1.11 root 1974: case i_ROL:
1.1.1.17 root 1975: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
1976: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 1977: fill_prefetch_next ();
1.1 root 1978: start_brace ();
1.1.1.7 root 1979: switch (curi->size) {
1.1.1.11 root 1980: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
1981: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
1982: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1983: default: abort ();
1.1 root 1984: }
1.1.1.3 root 1985: printf ("\tcnt &= 63;\n");
1.1.1.7 root 1986: printf ("\tCLEAR_CZNV;\n");
1987: if (source_is_imm1_8 (curi))
1988: printf ("{");
1989: else
1990: printf ("\tif (cnt > 0) {\n");
1991: printf ("\tuae_u32 loval;\n");
1992: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
1993: printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size));
1994: printf ("\tval <<= cnt;\n");
1995: printf ("\tval |= loval;\n");
1996: printf ("\tval &= %s;\n", bit_mask (curi->size));
1997: printf ("\tSET_CFLG (val & 1);\n");
1998: printf ("}\n");
1999: genflags (flag_logical_noclobber, curi->size, "val", "", "");
2000: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 2001: break;
1.1.1.11 root 2002: case i_ROR:
1.1.1.17 root 2003: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2004: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 2005: fill_prefetch_next ();
1.1 root 2006: start_brace ();
1.1.1.7 root 2007: switch (curi->size) {
1.1.1.11 root 2008: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2009: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2010: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2011: default: abort ();
1.1 root 2012: }
1.1.1.3 root 2013: printf ("\tcnt &= 63;\n");
1.1.1.7 root 2014: printf ("\tCLEAR_CZNV;\n");
2015: if (source_is_imm1_8 (curi))
2016: printf ("{");
2017: else
2018: printf ("\tif (cnt > 0) {");
2019: printf ("\tuae_u32 hival;\n");
2020: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
2021: printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size));
2022: printf ("\tval >>= cnt;\n");
2023: printf ("\tval |= hival;\n");
2024: printf ("\tval &= %s;\n", bit_mask (curi->size));
2025: printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
1.1.1.3 root 2026: printf ("\t}\n");
1.1.1.7 root 2027: genflags (flag_logical_noclobber, curi->size, "val", "", "");
2028: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 2029: break;
1.1.1.11 root 2030: case i_ROXL:
1.1.1.17 root 2031: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2032: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 2033: fill_prefetch_next ();
1.1 root 2034: start_brace ();
1.1.1.7 root 2035: switch (curi->size) {
1.1.1.11 root 2036: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2037: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2038: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2039: default: abort ();
1.1 root 2040: }
1.1.1.3 root 2041: printf ("\tcnt &= 63;\n");
1.1.1.7 root 2042: printf ("\tCLEAR_CZNV;\n");
2043: if (source_is_imm1_8 (curi))
2044: printf ("{");
1.1.1.12 root 2045: else {
2046: force_range_for_rox ("cnt", curi->size);
1.1.1.7 root 2047: printf ("\tif (cnt > 0) {\n");
1.1.1.12 root 2048: }
1.1.1.7 root 2049: printf ("\tcnt--;\n");
2050: printf ("\t{\n\tuae_u32 carry;\n");
2051: printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1);
2052: printf ("\tcarry = loval & 1;\n");
2053: printf ("\tval = (((val << 1) | GET_XFLG) << cnt) | (loval >> 1);\n");
2054: printf ("\tSET_XFLG (carry);\n");
2055: printf ("\tval &= %s;\n", bit_mask (curi->size));
2056: printf ("\t} }\n");
2057: printf ("\tSET_CFLG (GET_XFLG);\n");
2058: genflags (flag_logical_noclobber, curi->size, "val", "", "");
2059: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 2060: break;
1.1.1.11 root 2061: case i_ROXR:
1.1.1.17 root 2062: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
2063: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
1.1.1.21! root 2064: fill_prefetch_next ();
1.1 root 2065: start_brace ();
1.1.1.7 root 2066: switch (curi->size) {
1.1.1.11 root 2067: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2068: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2069: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2070: default: abort ();
1.1 root 2071: }
1.1.1.3 root 2072: printf ("\tcnt &= 63;\n");
1.1.1.7 root 2073: printf ("\tCLEAR_CZNV;\n");
2074: if (source_is_imm1_8 (curi))
2075: printf ("{");
1.1.1.12 root 2076: else {
2077: force_range_for_rox ("cnt", curi->size);
1.1.1.7 root 2078: printf ("\tif (cnt > 0) {\n");
1.1.1.12 root 2079: }
1.1.1.7 root 2080: printf ("\tcnt--;\n");
2081: printf ("\t{\n\tuae_u32 carry;\n");
2082: printf ("\tuae_u32 hival = (val << 1) | GET_XFLG;\n");
2083: printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1);
2084: printf ("\tval >>= cnt;\n");
2085: printf ("\tcarry = val & 1;\n");
2086: printf ("\tval >>= 1;\n");
2087: printf ("\tval |= hival;\n");
2088: printf ("\tSET_XFLG (carry);\n");
2089: printf ("\tval &= %s;\n", bit_mask (curi->size));
2090: printf ("\t} }\n");
2091: printf ("\tSET_CFLG (GET_XFLG);\n");
2092: genflags (flag_logical_noclobber, curi->size, "val", "", "");
2093: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
1.1 root 2094: break;
1.1.1.11 root 2095: case i_ASRW:
1.1.1.17 root 2096: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2097: fill_prefetch_next ();
1.1 root 2098: start_brace ();
1.1.1.7 root 2099: switch (curi->size) {
1.1.1.11 root 2100: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2101: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2102: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2103: default: abort ();
1.1 root 2104: }
1.1.1.7 root 2105: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
2106: printf ("\tuae_u32 cflg = val & 1;\n");
2107: printf ("\tval = (val >> 1) | sign;\n");
2108: genflags (flag_logical, curi->size, "val", "", "");
2109: printf ("\tSET_CFLG (cflg);\n");
1.1.1.17 root 2110: duplicate_carry (0);
1.1.1.7 root 2111: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2112: break;
1.1.1.11 root 2113: case i_ASLW:
1.1.1.17 root 2114: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2115: fill_prefetch_next ();
1.1 root 2116: start_brace ();
1.1.1.7 root 2117: switch (curi->size) {
1.1.1.11 root 2118: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2119: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2120: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2121: default: abort ();
1.1 root 2122: }
1.1.1.7 root 2123: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
2124: printf ("\tuae_u32 sign2;\n");
2125: printf ("\tval <<= 1;\n");
2126: genflags (flag_logical, curi->size, "val", "", "");
2127: printf ("\tsign2 = %s & val;\n", cmask (curi->size));
2128: printf ("\tSET_CFLG (sign != 0);\n");
1.1.1.17 root 2129: duplicate_carry (0);
1.1.1.7 root 2130:
2131: printf ("\tSET_VFLG (GET_VFLG | (sign2 != sign));\n");
2132: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2133: break;
1.1.1.11 root 2134: case i_LSRW:
1.1.1.17 root 2135: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2136: fill_prefetch_next ();
1.1 root 2137: start_brace ();
1.1.1.7 root 2138: switch (curi->size) {
1.1.1.11 root 2139: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
2140: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
2141: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2142: default: abort ();
1.1 root 2143: }
1.1.1.7 root 2144: printf ("\tuae_u32 carry = val & 1;\n");
1.1.1.3 root 2145: printf ("\tval >>= 1;\n");
1.1.1.7 root 2146: genflags (flag_logical, curi->size, "val", "", "");
2147: printf ("SET_CFLG (carry);\n");
1.1.1.17 root 2148: duplicate_carry (0);
1.1.1.7 root 2149: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2150: break;
1.1.1.11 root 2151: case i_LSLW:
1.1.1.17 root 2152: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2153: fill_prefetch_next ();
1.1 root 2154: start_brace ();
1.1.1.7 root 2155: switch (curi->size) {
1.1.1.11 root 2156: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2157: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2158: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2159: default: abort ();
1.1 root 2160: }
1.1.1.7 root 2161: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
1.1.1.3 root 2162: printf ("\tval <<= 1;\n");
1.1.1.7 root 2163: genflags (flag_logical, curi->size, "val", "", "");
2164: printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
1.1.1.17 root 2165: duplicate_carry (0);
1.1.1.7 root 2166: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2167: break;
1.1.1.11 root 2168: case i_ROLW:
1.1.1.17 root 2169: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2170: fill_prefetch_next ();
1.1 root 2171: start_brace ();
1.1.1.7 root 2172: switch (curi->size) {
1.1.1.11 root 2173: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2174: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2175: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2176: default: abort ();
1.1 root 2177: }
1.1.1.7 root 2178: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
1.1.1.3 root 2179: printf ("\tval <<= 1;\n");
1.1.1.7 root 2180: printf ("\tif (carry) val |= 1;\n");
2181: genflags (flag_logical, curi->size, "val", "", "");
2182: printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
2183: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2184: break;
1.1.1.11 root 2185: case i_RORW:
1.1.1.17 root 2186: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2187: fill_prefetch_next ();
1.1 root 2188: start_brace ();
1.1.1.7 root 2189: switch (curi->size) {
1.1.1.11 root 2190: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2191: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2192: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2193: default: abort ();
1.1 root 2194: }
1.1.1.7 root 2195: printf ("\tuae_u32 carry = val & 1;\n");
1.1.1.3 root 2196: printf ("\tval >>= 1;\n");
1.1.1.7 root 2197: printf ("\tif (carry) val |= %s;\n", cmask (curi->size));
2198: genflags (flag_logical, curi->size, "val", "", "");
2199: printf ("SET_CFLG (carry);\n");
2200: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2201: break;
1.1.1.11 root 2202: case i_ROXLW:
1.1.1.17 root 2203: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2204: fill_prefetch_next ();
1.1 root 2205: start_brace ();
1.1.1.7 root 2206: switch (curi->size) {
1.1.1.11 root 2207: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2208: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2209: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2210: default: abort ();
1.1 root 2211: }
1.1.1.7 root 2212: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
1.1.1.3 root 2213: printf ("\tval <<= 1;\n");
1.1.1.7 root 2214: printf ("\tif (GET_XFLG) val |= 1;\n");
2215: genflags (flag_logical, curi->size, "val", "", "");
2216: printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
1.1.1.17 root 2217: duplicate_carry (0);
1.1.1.7 root 2218: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2219: break;
1.1.1.11 root 2220: case i_ROXRW:
1.1.1.17 root 2221: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0);
2222: fill_prefetch_next ();
1.1 root 2223: start_brace ();
1.1.1.7 root 2224: switch (curi->size) {
1.1.1.11 root 2225: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
2226: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
2227: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
2228: default: abort ();
1.1 root 2229: }
1.1.1.7 root 2230: printf ("\tuae_u32 carry = val & 1;\n");
1.1.1.3 root 2231: printf ("\tval >>= 1;\n");
1.1.1.7 root 2232: printf ("\tif (GET_XFLG) val |= %s;\n", cmask (curi->size));
2233: genflags (flag_logical, curi->size, "val", "", "");
2234: printf ("SET_CFLG (carry);\n");
1.1.1.17 root 2235: duplicate_carry (0);
1.1.1.7 root 2236: genastore ("val", curi->smode, "srcreg", curi->size, "data");
1.1 root 2237: break;
1.1.1.11 root 2238: case i_MOVEC2:
1.1.1.17 root 2239: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2240: fill_prefetch_next ();
1.1.1.5 root 2241: start_brace ();
1.1.1.3 root 2242: printf ("\tint regno = (src >> 12) & 15;\n");
2243: printf ("\tuae_u32 *regp = regs.regs + regno;\n");
1.1.1.9 root 2244: printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
1.1 root 2245: break;
1.1.1.11 root 2246: case i_MOVE2C:
1.1.1.17 root 2247: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2248: fill_prefetch_next ();
1.1.1.5 root 2249: start_brace ();
1.1.1.3 root 2250: printf ("\tint regno = (src >> 12) & 15;\n");
2251: printf ("\tuae_u32 *regp = regs.regs + regno;\n");
1.1.1.9 root 2252: printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
1.1 root 2253: break;
1.1.1.11 root 2254: case i_CAS:
2255: {
2256: int old_brace_level;
1.1.1.17 root 2257: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
2258: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
2259: fill_prefetch_0 ();
1.1.1.11 root 2260: start_brace ();
2261: printf ("\tint ru = (src >> 6) & 7;\n");
2262: printf ("\tint rc = src & 7;\n");
1.1.1.21! root 2263: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, rc)", "dst");
1.1.1.11 root 2264: printf ("\tif (GET_ZFLG)");
2265: old_brace_level = n_braces;
2266: start_brace ();
1.1.1.21! root 2267: genastore ("(m68k_dreg (regs, ru))", curi->dmode, "dstreg", curi->size, "dst");
1.1.1.11 root 2268: pop_braces (old_brace_level);
2269: printf ("else");
2270: start_brace ();
1.1.1.21! root 2271: printf ("m68k_dreg (regs, rc) = dst;\n");
1.1.1.11 root 2272: pop_braces (old_brace_level);
2273: }
2274: break;
2275: case i_CAS2:
1.1.1.17 root 2276: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.8 root 2277: printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n");
2278: printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n");
1.1.1.7 root 2279: if (curi->size == sz_word) {
1.1.1.5 root 2280: int old_brace_level = n_braces;
1.1.1.21! root 2281: printf ("\tuae_u16 dst1 = get_word (rn1), dst2 = get_word (rn2);\n");
! 2282: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1");
1.1.1.7 root 2283: printf ("\tif (GET_ZFLG) {\n");
1.1.1.21! root 2284: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2");
1.1.1.7 root 2285: printf ("\tif (GET_ZFLG) {\n");
1.1.1.21! root 2286: printf ("\tput_word (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n");
! 2287: printf ("\tput_word (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n");
1.1.1.5 root 2288: printf ("\t}}\n");
2289: pop_braces (old_brace_level);
1.1.1.7 root 2290: printf ("\tif (! GET_ZFLG) {\n");
1.1.1.21! root 2291: printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = (m68k_dreg (regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
! 2292: printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = (m68k_dreg (regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
1.1.1.5 root 2293: printf ("\t}\n");
1.1 root 2294: } else {
1.1.1.5 root 2295: int old_brace_level = n_braces;
1.1.1.21! root 2296: printf ("\tuae_u32 dst1 = get_long (rn1), dst2 = get_long (rn2);\n");
! 2297: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1");
1.1.1.7 root 2298: printf ("\tif (GET_ZFLG) {\n");
1.1.1.21! root 2299: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2");
1.1.1.7 root 2300: printf ("\tif (GET_ZFLG) {\n");
1.1.1.21! root 2301: printf ("\tput_long (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n");
! 2302: printf ("\tput_long (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n");
1.1.1.5 root 2303: printf ("\t}}\n");
2304: pop_braces (old_brace_level);
1.1.1.7 root 2305: printf ("\tif (! GET_ZFLG) {\n");
1.1.1.21! root 2306: printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = dst1;\n");
! 2307: printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = dst2;\n");
1.1.1.5 root 2308: printf ("\t}\n");
1.1 root 2309: }
2310: break;
1.1.1.11 root 2311: case i_MOVES: /* ignore DFC and SFC because we have no MMU */
2312: {
2313: int old_brace_level;
1.1.1.17 root 2314: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.11 root 2315: printf ("\tif (extra & 0x800)\n");
2316: old_brace_level = n_braces;
2317: start_brace ();
2318: printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
1.1.1.17 root 2319: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
1.1.1.11 root 2320: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
2321: pop_braces (old_brace_level);
2322: printf ("else");
2323: start_brace ();
1.1.1.17 root 2324: genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0, 0);
1.1.1.11 root 2325: printf ("\tif (extra & 0x8000) {\n");
2326: switch (curi->size) {
1.1.1.21! root 2327: case sz_byte: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break;
! 2328: case sz_word: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break;
! 2329: case sz_long: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = src;\n"); break;
1.1.1.11 root 2330: default: abort ();
1.1 root 2331: }
1.1.1.11 root 2332: printf ("\t} else {\n");
2333: genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, "");
2334: printf ("\t}\n");
2335: pop_braces (old_brace_level);
2336: }
2337: break;
2338: case i_BKPT: /* only needed for hardware emulators */
1.1.1.5 root 2339: sync_m68k_pc ();
1.1.1.3 root 2340: printf ("\top_illg(opcode);\n");
1.1 root 2341: break;
1.1.1.11 root 2342: case i_CALLM: /* not present in 68030 */
1.1.1.5 root 2343: sync_m68k_pc ();
1.1.1.3 root 2344: printf ("\top_illg(opcode);\n");
1.1 root 2345: break;
1.1.1.11 root 2346: case i_RTM: /* not present in 68030 */
1.1.1.5 root 2347: sync_m68k_pc ();
1.1.1.3 root 2348: printf ("\top_illg(opcode);\n");
1.1 root 2349: break;
1.1.1.11 root 2350: case i_TRAPcc:
1.1.1.7 root 2351: if (curi->smode != am_unknown && curi->smode != am_illg)
1.1.1.17 root 2352: genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
2353: fill_prefetch_0 ();
1.1.1.21! root 2354: printf ("\tif (cctrue(%d)) { Exception(7,m68k_getpc ()); goto %s; }\n", curi->cc, endlabelstr);
1.1.1.5 root 2355: need_endlabel = 1;
1.1 root 2356: break;
1.1.1.11 root 2357: case i_DIVL:
1.1.1.3 root 2358: sync_m68k_pc ();
2359: start_brace ();
1.1.1.21! root 2360: printf ("\tuaecptr oldpc = m68k_getpc ();\n");
1.1.1.17 root 2361: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
2362: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.5 root 2363: sync_m68k_pc ();
1.1.1.3 root 2364: printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n");
1.1 root 2365: break;
1.1.1.11 root 2366: case i_MULL:
1.1.1.17 root 2367: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
2368: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.5 root 2369: sync_m68k_pc ();
1.1.1.3 root 2370: printf ("\tm68k_mull(opcode, dst, extra);\n");
1.1 root 2371: break;
1.1.1.11 root 2372: case i_BFTST:
2373: case i_BFEXTU:
2374: case i_BFCHG:
2375: case i_BFEXTS:
2376: case i_BFCLR:
2377: case i_BFFFO:
2378: case i_BFSET:
2379: case i_BFINS:
1.1.1.17 root 2380: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
2381: genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0);
1.1.1.5 root 2382: start_brace ();
1.1.1.21! root 2383: printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg (regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n");
! 2384: printf ("\tint width = (((extra & 0x20 ? m68k_dreg (regs, extra & 7) : extra) -1) & 0x1f) +1;\n");
1.1.1.7 root 2385: if (curi->dmode == Dreg) {
1.1.1.21! root 2386: printf ("\tuae_u32 tmp = m68k_dreg (regs, dstreg) << (offset & 0x1f);\n");
1.1.1.3 root 2387: } else {
2388: printf ("\tuae_u32 tmp,bf0,bf1;\n");
2389: printf ("\tdsta += (offset >> 3) | (offset & 0x80000000 ? ~0x1fffffff : 0);\n");
1.1.1.21! root 2390: printf ("\tbf0 = get_long (dsta);bf1 = get_byte (dsta+4) & 0xff;\n");
1.1.1.3 root 2391: printf ("\ttmp = (bf0 << (offset & 7)) | (bf1 >> (8 - (offset & 7)));\n");
2392: }
2393: printf ("\ttmp >>= (32 - width);\n");
1.1.1.7 root 2394: printf ("\tSET_NFLG (tmp & (1 << (width-1)) ? 1 : 0);\n");
2395: printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n");
2396: switch (curi->mnemo) {
1.1.1.11 root 2397: case i_BFTST:
1.1.1.3 root 2398: break;
1.1.1.11 root 2399: case i_BFEXTU:
1.1.1.21! root 2400: printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = tmp;\n");
1.1.1.3 root 2401: break;
1.1.1.11 root 2402: case i_BFCHG:
1.1.1.3 root 2403: printf ("\ttmp = ~tmp;\n");
2404: break;
1.1.1.11 root 2405: case i_BFEXTS:
1.1.1.7 root 2406: printf ("\tif (GET_NFLG) tmp |= width == 32 ? 0 : (-1 << width);\n");
1.1.1.21! root 2407: printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = tmp;\n");
1.1.1.3 root 2408: break;
1.1.1.11 root 2409: case i_BFCLR:
1.1.1.3 root 2410: printf ("\ttmp = 0;\n");
2411: break;
1.1.1.11 root 2412: case i_BFFFO:
1.1.1.3 root 2413: printf ("\t{ uae_u32 mask = 1 << (width-1);\n");
2414: printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n");
1.1.1.21! root 2415: printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = offset;\n");
1.1.1.3 root 2416: break;
1.1.1.11 root 2417: case i_BFSET:
1.1.1.3 root 2418: printf ("\ttmp = 0xffffffff;\n");
2419: break;
1.1.1.11 root 2420: case i_BFINS:
1.1.1.21! root 2421: printf ("\ttmp = m68k_dreg (regs, (extra >> 12) & 7);\n");
1.1.1.15 root 2422: printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n");
2423: printf ("\tSET_ZFLG (tmp == 0);\n");
1.1.1.3 root 2424: break;
1.1.1.11 root 2425: default:
1.1.1.3 root 2426: break;
1.1 root 2427: }
1.1.1.7 root 2428: if (curi->mnemo == i_BFCHG
2429: || curi->mnemo == i_BFCLR
2430: || curi->mnemo == i_BFSET
2431: || curi->mnemo == i_BFINS)
1.1.1.11 root 2432: {
2433: printf ("\ttmp <<= (32 - width);\n");
2434: if (curi->dmode == Dreg) {
1.1.1.21! root 2435: printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & ((offset & 0x1f) == 0 ? 0 :\n");
1.1.1.11 root 2436: printf ("\t\t(0xffffffff << (32 - (offset & 0x1f))))) |\n");
2437: printf ("\t\t(tmp >> (offset & 0x1f)) |\n");
2438: printf ("\t\t(((offset & 0x1f) + width) >= 32 ? 0 :\n");
1.1.1.21! root 2439: printf (" (m68k_dreg (regs, dstreg) & ((uae_u32)0xffffffff >> ((offset & 0x1f) + width))));\n");
1.1.1.11 root 2440: } else {
2441: printf ("\tbf0 = (bf0 & (0xff000000 << (8 - (offset & 7)))) |\n");
2442: printf ("\t\t(tmp >> (offset & 7)) |\n");
2443: printf ("\t\t(((offset & 7) + width) >= 32 ? 0 :\n");
2444: printf ("\t\t (bf0 & ((uae_u32)0xffffffff >> ((offset & 7) + width))));\n");
1.1.1.21! root 2445: printf ("\tput_long (dsta,bf0 );\n");
1.1.1.11 root 2446: printf ("\tif (((offset & 7) + width) > 32) {\n");
2447: printf ("\t\tbf1 = (bf1 & (0xff >> (width - 32 + (offset & 7)))) |\n");
2448: printf ("\t\t\t(tmp << (8 - (offset & 7)));\n");
1.1.1.21! root 2449: printf ("\t\tput_byte (dsta+4,bf1);\n");
1.1.1.11 root 2450: printf ("\t}\n");
2451: }
1.1.1.5 root 2452: }
1.1 root 2453: break;
1.1.1.11 root 2454: case i_PACK:
1.1.1.7 root 2455: if (curi->smode == Dreg) {
1.1.1.21! root 2456: printf ("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0));
! 2457: printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
1.1.1.3 root 2458: } else {
2459: printf ("\tuae_u16 val;\n");
1.1.1.21! root 2460: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
! 2461: printf ("\tval = (uae_u16)get_byte (m68k_areg (regs, srcreg));\n");
! 2462: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
! 2463: printf ("\tval = (val | ((uae_u16)get_byte (m68k_areg (regs, srcreg)) << 8)) + %s;\n", gen_nextiword (0));
! 2464: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
! 2465: printf ("\tput_byte (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n");
1.1 root 2466: }
2467: break;
1.1.1.11 root 2468: case i_UNPK:
1.1.1.7 root 2469: if (curi->smode == Dreg) {
1.1.1.21! root 2470: printf ("\tuae_u16 val = m68k_dreg (regs, srcreg);\n");
1.1.1.17 root 2471: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
1.1.1.21! root 2472: printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffff0000) | (val & 0xffff);\n");
1.1.1.3 root 2473: } else {
2474: printf ("\tuae_u16 val;\n");
1.1.1.21! root 2475: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
! 2476: printf ("\tval = (uae_u16)get_byte (m68k_areg (regs, srcreg));\n");
1.1.1.17 root 2477: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
1.1.1.21! root 2478: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
! 2479: printf ("\tput_byte (m68k_areg (regs, dstreg),val);\n");
! 2480: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
! 2481: printf ("\tput_byte (m68k_areg (regs, dstreg),val >> 8);\n");
1.1 root 2482: }
2483: break;
1.1.1.11 root 2484: case i_TAS:
1.1.1.17 root 2485: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.7 root 2486: genflags (flag_logical, curi->size, "src", "", "");
1.1.1.17 root 2487: if (!isreg (curi->smode))
1.1.1.21! root 2488: addcycles (2);
! 2489: fill_prefetch_next ();
1.1.1.3 root 2490: printf ("\tsrc |= 0x80;\n");
1.1.1.7 root 2491: genastore ("src", curi->smode, "srcreg", curi->size, "src");
1.1 root 2492: break;
1.1.1.11 root 2493: case i_FPP:
1.1.1.17 root 2494: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.5 root 2495: sync_m68k_pc ();
1.1.1.3 root 2496: printf ("\tfpp_opp(opcode,extra);\n");
1.1 root 2497: break;
1.1.1.11 root 2498: case i_FDBcc:
1.1.1.17 root 2499: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.5 root 2500: sync_m68k_pc ();
1.1.1.3 root 2501: printf ("\tfdbcc_opp(opcode,extra);\n");
1.1 root 2502: break;
1.1.1.11 root 2503: case i_FScc:
1.1.1.17 root 2504: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.5 root 2505: sync_m68k_pc ();
1.1.1.3 root 2506: printf ("\tfscc_opp(opcode,extra);\n");
1.1 root 2507: break;
1.1.1.11 root 2508: case i_FTRAPcc:
1.1.1.5 root 2509: sync_m68k_pc ();
2510: start_brace ();
1.1.1.21! root 2511: printf ("\tuaecptr oldpc = m68k_getpc ();\n");
1.1.1.7 root 2512: if (curi->smode != am_unknown && curi->smode != am_illg)
1.1.1.17 root 2513: genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
1.1.1.5 root 2514: sync_m68k_pc ();
1.1.1.3 root 2515: printf ("\tftrapcc_opp(opcode,oldpc);\n");
1.1 root 2516: break;
1.1.1.11 root 2517: case i_FBcc:
1.1.1.5 root 2518: sync_m68k_pc ();
2519: start_brace ();
1.1.1.21! root 2520: printf ("\tuaecptr pc = m68k_getpc ();\n");
1.1.1.17 root 2521: genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.5 root 2522: sync_m68k_pc ();
1.1.1.3 root 2523: printf ("\tfbcc_opp(opcode,pc,extra);\n");
1.1 root 2524: break;
1.1.1.11 root 2525: case i_FSAVE:
1.1.1.5 root 2526: sync_m68k_pc ();
1.1.1.3 root 2527: printf ("\tfsave_opp(opcode);\n");
1.1 root 2528: break;
1.1.1.11 root 2529: case i_FRESTORE:
1.1.1.5 root 2530: sync_m68k_pc ();
1.1.1.3 root 2531: printf ("\tfrestore_opp(opcode);\n");
1.1 root 2532: break;
1.1.1.12 root 2533:
2534: case i_CINVL:
2535: case i_CINVP:
2536: case i_CINVA:
2537: case i_CPUSHL:
2538: case i_CPUSHP:
2539: case i_CPUSHA:
2540: break;
2541: case i_MOVE16:
1.1.1.14 root 2542: if ((opcode & 0xfff8) == 0xf620) {
2543: /* MOVE16 (Ax)+,(Ay)+ */
1.1.1.21! root 2544: printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
1.1.1.17 root 2545: printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
1.1.1.21! root 2546: printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
! 2547: printf ("\tput_long (memd, get_long (mems));\n");
! 2548: printf ("\tput_long (memd+4, get_long (mems+4));\n");
! 2549: printf ("\tput_long (memd+8, get_long (mems+8));\n");
! 2550: printf ("\tput_long (memd+12, get_long (mems+12));\n");
1.1.1.14 root 2551: printf ("\tif (srcreg != dstreg)\n");
1.1.1.21! root 2552: printf ("\tm68k_areg (regs, srcreg) += 16;\n");
! 2553: printf ("\tm68k_areg (regs, dstreg) += 16;\n");
1.1.1.14 root 2554: } else {
2555: /* Other variants */
1.1.1.17 root 2556: genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
2557: genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
1.1.1.14 root 2558: printf ("\tmemsa &= ~15;\n");
2559: printf ("\tmemda &= ~15;\n");
1.1.1.21! root 2560: printf ("\tput_long (memda, get_long (memsa));\n");
! 2561: printf ("\tput_long (memda+4, get_long (memsa+4));\n");
! 2562: printf ("\tput_long (memda+8, get_long (memsa+8));\n");
! 2563: printf ("\tput_long (memda+12, get_long (memsa+12));\n");
1.1.1.14 root 2564: if ((opcode & 0xfff8) == 0xf600)
1.1.1.21! root 2565: printf ("\tm68k_areg (regs, srcreg) += 16;\n");
1.1.1.14 root 2566: else if ((opcode & 0xfff8) == 0xf608)
1.1.1.21! root 2567: printf ("\tm68k_areg (regs, dstreg) += 16;\n");
1.1.1.14 root 2568: }
2569: break;
1.1.1.12 root 2570:
1.1.1.11 root 2571: case i_MMUOP:
1.1.1.17 root 2572: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.5 root 2573: sync_m68k_pc ();
1.1.1.21! root 2574: printf ("\tmmu_op (opcode, extra);\n");
! 2575: break;
! 2576: case i_MMUOP30A:
! 2577: printf ("\tuaecptr pc = m68k_getpc ();\n");
! 2578: if (curi->smode == Areg || curi->smode == Dreg)
! 2579: printf("\tuae_u16 extraa = 0;\n");
! 2580: else
! 2581: genamode (curi->smode, "srcreg", curi->size, "extra", 0, 0, 0);
! 2582: sync_m68k_pc ();
! 2583: printf ("\tmmu_op30 (pc, opcode, 1, extraa);\n");
! 2584: break;
! 2585: case i_MMUOP30B:
! 2586: printf ("\tuaecptr pc = m68k_getpc ();\n");
! 2587: genamode (curi->smode, "srcreg", curi->size, "extra", 0, 0, 0);
! 2588: sync_m68k_pc ();
! 2589: printf ("\tmmu_op30 (pc, opcode, 0, 0);\n");
1.1 root 2590: break;
1.1.1.11 root 2591: default:
1.1.1.5 root 2592: abort ();
1.1 root 2593: break;
1.1.1.5 root 2594: }
1.1 root 2595: finish_braces ();
1.1.1.17 root 2596: fill_prefetch_finish ();
1.1.1.3 root 2597: sync_m68k_pc ();
1.1.1.17 root 2598: did_prefetch = 0;
1.1 root 2599: }
2600:
1.1.1.5 root 2601: static void generate_includes (FILE * f)
1.1.1.3 root 2602: {
2603: fprintf (f, "#include \"sysconfig.h\"\n");
2604: fprintf (f, "#include \"sysdeps.h\"\n");
2605: fprintf (f, "#include \"options.h\"\n");
2606: fprintf (f, "#include \"memory.h\"\n");
2607: fprintf (f, "#include \"custom.h\"\n");
2608: fprintf (f, "#include \"newcpu.h\"\n");
1.1.1.17 root 2609: fprintf (f, "#include \"cpu_prefetch.h\"\n");
1.1.1.3 root 2610: fprintf (f, "#include \"cputbl.h\"\n");
1.1.1.19 root 2611:
1.1.1.12 root 2612: fprintf (f, "#define CPUFUNC(x) x##_ff\n"
2613: "#ifdef NOFLAGS\n"
2614: "#include \"noflags.h\"\n"
2615: "#endif\n");
1.1.1.3 root 2616: }
2617:
2618: static int postfix;
2619:
2620: static void generate_one_opcode (int rp)
1.1 root 2621: {
2622: int i;
1.1.1.3 root 2623: uae_u16 smsk, dmsk;
2624: long int opcode = opcode_map[rp];
1.1 root 2625:
1.1.1.3 root 2626: if (table68k[opcode].mnemo == i_ILLG
2627: || table68k[opcode].clev > cpu_level)
2628: return;
1.1 root 2629:
1.1.1.5 root 2630: for (i = 0; lookuptab[i].name[0]; i++) {
1.1.1.3 root 2631: if (table68k[opcode].mnemo == lookuptab[i].mnemo)
2632: break;
2633: }
1.1 root 2634:
1.1.1.3 root 2635: if (table68k[opcode].handler != -1)
2636: return;
1.1 root 2637:
1.1.1.21! root 2638: if (generate_stbl) {
! 2639: if (opcode_next_clev[rp] != cpu_level) {
! 2640: fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp],
! 2641: opcode, lookuptab[i].name);
! 2642: return;
! 2643: }
! 2644: fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
1.1.1.3 root 2645: }
1.1.1.12 root 2646: fprintf (headerfile, "extern cpuop_func op_%lx_%d_nf;\n", opcode, postfix);
2647: fprintf (headerfile, "extern cpuop_func op_%lx_%d_ff;\n", opcode, postfix);
2648: printf ("unsigned long REGPARAM2 CPUFUNC(op_%lx_%d)(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
1.1.1.3 root 2649:
2650: switch (table68k[opcode].stype) {
1.1.1.14 root 2651: case 0: smsk = 7; break;
2652: case 1: smsk = 255; break;
2653: case 2: smsk = 15; break;
2654: case 3: smsk = 7; break;
2655: case 4: smsk = 7; break;
2656: case 5: smsk = 63; break;
2657: case 7: smsk = 3; break;
2658: default: abort ();
1.1.1.3 root 2659: }
2660: dmsk = 7;
2661:
2662: next_cpu_level = -1;
2663: if (table68k[opcode].suse
1.1.1.5 root 2664: && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
1.1.1.3 root 2665: && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
2666: && table68k[opcode].smode != absw && table68k[opcode].smode != absl
2667: && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
2668: {
2669: if (table68k[opcode].spos == -1) {
1.1.1.5 root 2670: if (((int) table68k[opcode].sreg) >= 128)
2671: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
1.1.1.3 root 2672: else
1.1.1.5 root 2673: printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg);
1.1.1.3 root 2674: } else {
2675: char source[100];
1.1.1.6 root 2676: int pos = table68k[opcode].spos;
1.1.1.5 root 2677:
1.1.1.6 root 2678: if (pos)
2679: sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
1.1.1.3 root 2680: else
1.1.1.5 root 2681: sprintf (source, "(opcode & %d)", smsk);
2682:
1.1.1.3 root 2683: if (table68k[opcode].stype == 3)
2684: printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
2685: else if (table68k[opcode].stype == 1)
2686: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
2687: else
2688: printf ("\tuae_u32 srcreg = %s;\n", source);
1.1 root 2689: }
1.1.1.3 root 2690: }
2691: if (table68k[opcode].duse
2692: /* Yes, the dmode can be imm, in case of LINK or DBcc */
1.1.1.5 root 2693: && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
1.1.1.3 root 2694: && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
1.1.1.5 root 2695: && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
2696: {
1.1.1.3 root 2697: if (table68k[opcode].dpos == -1) {
1.1.1.5 root 2698: if (((int) table68k[opcode].dreg) >= 128)
2699: printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
1.1.1.3 root 2700: else
1.1.1.5 root 2701: printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg);
1.1.1.3 root 2702: } else {
1.1.1.5 root 2703: int pos = table68k[opcode].dpos;
1.1.1.6 root 2704: #if 0
1.1.1.5 root 2705: /* Check that we can do the little endian optimization safely. */
1.1.1.6 root 2706: if (pos < 8 && (dmsk >> (8 - pos)) != 0)
1.1.1.5 root 2707: abort ();
1.1.1.19 root 2708: #endif
1.1.1.5 root 2709: if (pos)
1.1.1.3 root 2710: printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
1.1.1.5 root 2711: pos, dmsk);
1.1.1.3 root 2712: else
2713: printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
1.1 root 2714: }
2715: }
1.1.1.5 root 2716: need_endlabel = 0;
1.1.1.3 root 2717: endlabelno++;
2718: sprintf (endlabelstr, "endlabel%d", endlabelno);
2719: gen_opcode (opcode);
1.1.1.5 root 2720: if (need_endlabel)
1.1.1.6 root 2721: printf ("%s: ;\n", endlabelstr);
1.1.1.21! root 2722: printf ("return %d * CYCLE_UNIT / 2;\n", insn_n_cycles);
1.1.1.3 root 2723: printf ("}\n");
2724: opcode_next_clev[rp] = next_cpu_level;
2725: opcode_last_postfix[rp] = postfix;
1.1 root 2726: }
2727:
1.1.1.3 root 2728: static void generate_func (void)
1.1 root 2729: {
1.1.1.5 root 2730: int i, j, rp;
1.1 root 2731:
1.1.1.3 root 2732: using_prefetch = 0;
2733: using_exception_3 = 0;
1.1.1.21! root 2734: for (i = 0; i < 7; i++) {
! 2735: cpu_level = 6 - i;
! 2736: if (i == 6) {
1.1.1.3 root 2737: cpu_level = 0;
2738: using_prefetch = 1;
2739: using_exception_3 = 1;
2740: for (rp = 0; rp < nr_cpuop_funcs; rp++)
2741: opcode_next_clev[rp] = 0;
2742: }
1.1.1.12 root 2743:
1.1.1.3 root 2744: postfix = i;
1.1.1.21! root 2745: generate_stbl = i != 5;
! 2746: if (generate_stbl) {
! 2747: fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix);
! 2748:
! 2749: /* sam: this is for people with low memory (eg. me :)) */
! 2750: printf ("\n"
! 2751: "#if !defined(PART_1) && !defined(PART_2) && "
1.1.1.19 root 2752: "!defined(PART_3) && !defined(PART_4) && "
1.1.1.5 root 2753: "!defined(PART_5) && !defined(PART_6) && "
2754: "!defined(PART_7) && !defined(PART_8)"
1.1.1.21! root 2755: "\n"
! 2756: "#define PART_1 1\n"
! 2757: "#define PART_2 1\n"
! 2758: "#define PART_3 1\n"
! 2759: "#define PART_4 1\n"
! 2760: "#define PART_5 1\n"
! 2761: "#define PART_6 1\n"
! 2762: "#define PART_7 1\n"
! 2763: "#define PART_8 1\n"
! 2764: "#endif\n\n");
! 2765: }
1.1.1.5 root 2766: rp = 0;
1.1.1.18 root 2767: for(j = 1; j <= 8; ++j) {
1.1.1.21! root 2768: int k = (j * nr_cpuop_funcs) / 8;
! 2769: printf ("#ifdef PART_%d\n",j);
! 2770: for (; rp < k; rp++)
! 2771: generate_one_opcode (rp);
! 2772: printf ("#endif\n\n");
1.1.1.5 root 2773: }
2774:
1.1.1.21! root 2775: if (generate_stbl)
! 2776: fprintf (stblfile, "{ 0, 0, 0 }};\n");
1.1 root 2777: }
2778: }
2779:
1.1.1.3 root 2780: int main (int argc, char **argv)
1.1.1.5 root 2781: {
1.1 root 2782: read_table68k ();
2783: do_merges ();
1.1.1.3 root 2784:
1.1.1.5 root 2785: opcode_map = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
2786: opcode_last_postfix = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
2787: opcode_next_clev = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
2788: counts = (unsigned long *) xmalloc (65536 * sizeof (unsigned long));
2789: read_counts ();
1.1.1.3 root 2790:
2791: /* It would be a lot nicer to put all in one file (we'd also get rid of
2792: * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
2793: * I don't dare to touch the 68k version. */
1.1.1.5 root 2794:
1.1.1.3 root 2795: headerfile = fopen ("cputbl.h", "wb");
2796: stblfile = fopen ("cpustbl.c", "wb");
2797: freopen ("cpuemu.c", "wb", stdout);
2798:
2799: generate_includes (stdout);
2800: generate_includes (stblfile);
2801:
2802: generate_func ();
2803:
2804: free (table68k);
1.1 root 2805: return 0;
2806: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.