|
|
1.1.1.4 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68000 emulation generator
5: *
6: * This is a fairly stupid program that generates a lot of case labels that
7: * can be #included in a switch statement.
8: * As an alternative, it can generate functions that handle specific
9: * MC68000 instructions, plus a prototype header file and a function pointer
10: * array to look up the function for an opcode.
11: * Error checking is bad, an illegal table68k file will cause the program to
12: * call abort().
13: * The generated code is sometimes sub-optimal, an optimizing compiler should
14: * take care of this.
15: *
16: * 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
19: */
20:
21: #include "sysconfig.h"
22: #include "sysdeps.h"
23: #include <ctype.h>
24: #include <string.h>
25:
26: #include "readcpu.h"
1.1.1.7 root 27:
28: char *ua (const char *s) {
29: return strdup(s);
30: }
1.1.1.4 root 31:
32: #define BOOL_TYPE "int"
33: /* Define the minimal 680x0 where NV flags are not affected by xBCD instructions. */
34: #define xBCD_KEEPS_NV_FLAGS 4
35:
36: static FILE *headerfile;
37: static FILE *stblfile;
38:
39: static int using_prefetch, using_indirect, using_mmu;
1.1.1.7 root 40: static int using_prefetch_020, using_ce020;
1.1.1.4 root 41: static int using_exception_3;
1.1.1.7 root 42: static int using_bus_error;
1.1.1.4 root 43: static int using_ce;
1.1.1.7 root 44: static int using_tracer;
45: static int using_waitstates;
46: static int using_simple_cycles;
1.1.1.8 ! root 47: static int cpu_level, cpu_generic;
1.1.1.4 root 48: static int count_read, count_write, count_cycles, count_ncycles;
1.1.1.7 root 49: static int count_cycles_ce020;
1.1.1.4 root 50: static int count_read_ea, count_write_ea, count_cycles_ea;
1.1.1.5 root 51: static const char *mmu_postfix;
1.1.1.7 root 52: static int memory_cycle_cnt;
53: static int did_prefetch;
54: static int ipl_fetched;
1.1.1.4 root 55:
56: static int optimized_flags;
57:
1.1.1.7 root 58: #ifdef WINUAE_FOR_HATARI
1.1.1.8 ! root 59: static long nCurInstrCycPos; /* Hatari only : Stores where we have to patch in the current cycles value */
1.1.1.7 root 60: #endif
1.1.1.4 root 61:
62: #define GF_APDI 1
63: #define GF_AD8R 2
64: #define GF_PC8R 4
65: #define GF_AA 7
66: #define GF_NOREFILL 8
67: #define GF_PREFETCH 16
68: #define GF_FC 32
69: #define GF_MOVE 64
1.1.1.7 root 70: #define GF_IR2IRC 128
71: #define GF_LRMW 256
72: #define GF_NOFAULTPC 512
73: #define GF_RMW 1024
74: #define GF_OPCE020 2048
1.1.1.4 root 75:
76: /* For the current opcode, the next lower level that will have different code.
77: * Initialized to -1 for each opcode. If it remains unchanged, indicates we
78: * are done with that opcode. */
79: static int next_cpu_level;
80:
81: static int *opcode_map;
82: static int *opcode_next_clev;
83: static int *opcode_last_postfix;
84: static unsigned long *counts;
85: static int generate_stbl;
1.1.1.7 root 86: static int mmufixupcnt;
87: static int mmufixupstate;
88: static int disp020cnt;
89: static bool candormw;
90: static bool genastore_done;
91: static char rmw_varname[100];
1.1.1.4 root 92:
93: #define GENA_GETV_NO_FETCH 0
94: #define GENA_GETV_FETCH 1
95: #define GENA_GETV_FETCH_ALIGN 2
96: #define GENA_MOVEM_DO_INC 0
97: #define GENA_MOVEM_NO_INC 1
98: #define GENA_MOVEM_MOVE16 2
99:
1.1.1.7 root 100: static const char *srcl, *dstl;
101: static const char *srcw, *dstw;
102: static const char *srcb, *dstb;
103: static const char *srcblrmw, *srcwlrmw, *srcllrmw;
104: static const char *dstblrmw, *dstwlrmw, *dstllrmw;
105: static const char *srcbrmw, *srcwrmw, *srclrmw;
106: static const char *dstbrmw, *dstwrmw, *dstlrmw;
107: static const char *prefetch_long, *prefetch_word;
108: static const char *srcli, *srcwi, *srcbi, *nextl, *nextw;
109: static const char *srcld, *dstld;
110: static const char *srcwd, *dstwd;
111: static const char *do_cycles, *disp000, *disp020, *getpc;
112:
113: #define fetchmode_fea 1
114: #define fetchmode_cea 2
115: #define fetchmode_fiea 3
116: #define fetchmode_ciea 4
117: #define fetchmode_jea 5
118:
119: NORETURN static void term (void)
120: {
121: printf("Abort!\n");
122: abort ();
123: }
124: NORETURN static void term_err (const char *err)
125: {
126: printf ("%s\n", err);
127: term ();
128: }
1.1.1.4 root 129:
130: static void read_counts (void)
131: {
132: FILE *file;
1.1.1.7 root 133: unsigned int opcode, count, total;
1.1.1.4 root 134: char name[20];
135: int nr = 0;
136: memset (counts, 0, 65536 * sizeof *counts);
137:
138: count = 0;
139: file = fopen ("frequent.68k", "r");
140: if (file) {
1.1.1.7 root 141: if (fscanf (file, "Total: %u\n", &total) == 0) {
142: abort ();
1.1.1.6 root 143: }
1.1.1.7 root 144: while (fscanf (file, "%x: %u %s\n", &opcode, &count, name) == 3) {
1.1.1.4 root 145: opcode_next_clev[nr] = 5;
146: opcode_last_postfix[nr] = -1;
147: opcode_map[nr++] = opcode;
148: counts[opcode] = count;
149: }
150: fclose (file);
151: }
152: if (nr == nr_cpuop_funcs)
153: return;
154: for (opcode = 0; opcode < 0x10000; opcode++) {
155: if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
156: && counts[opcode] == 0)
157: {
158: opcode_next_clev[nr] = 5;
159: opcode_last_postfix[nr] = -1;
160: opcode_map[nr++] = opcode;
161: counts[opcode] = count;
162: }
163: }
164: if (nr != nr_cpuop_funcs)
1.1.1.7 root 165: term ();
1.1.1.4 root 166: }
167:
168: static char endlabelstr[80];
169: static int endlabelno = 0;
170: static int need_endlabel;
1.1.1.8 ! root 171: static int genamode_cnt, genamode8r_offset[2];
1.1.1.4 root 172:
173: static int n_braces, limit_braces;
1.1.1.7 root 174: static int m68k_pc_offset, m68k_pc_offset_old;
175: static int m68k_pc_total;
176: static int branch_inst;
1.1.1.4 root 177: static int insn_n_cycles, insn_n_cycles020;
1.1.1.7 root 178: static int ir2irc;
179:
180: static int tail_ce020, total_ce020, head_in_ea_ce020;
181: static bool head_ce020_cycs_done, tail_ce020_done;
182: static int subhead_ce020;
183: static struct instr *curi_ce020;
184: static bool no_prefetch_ce020;
185: static bool got_ea_ce020;
1.1.1.4 root 186:
187: static void fpulimit (void)
188: {
189: if (limit_braces)
190: return;
191: printf ("\n#ifdef FPUEMU\n");
192: limit_braces = n_braces;
193: n_braces = 0;
194: }
1.1.1.7 root 195: #ifndef WINUAE_FOR_HATARI
196: static void cpulimit (void)
197: {
198: printf ("#ifndef CPUEMU_68000_ONLY\n");
199: }
200: #endif
1.1.1.4 root 201:
1.1.1.7 root 202: static int s_count_read, s_count_write, s_count_cycles, s_count_ncycles;
203:
204: static void push_ins_cnt(void)
1.1.1.4 root 205: {
1.1.1.7 root 206: s_count_read = count_read;
207: s_count_write = count_write;
208: s_count_cycles = count_cycles;
209: s_count_ncycles = count_ncycles;
210: }
211: static void pop_ins_cnt(void)
212: {
213: count_read = s_count_read;
214: count_write = s_count_write;
215: count_cycles = s_count_cycles;
216: count_ncycles = s_count_ncycles;
217: }
218:
219: static bool isce020(void)
220: {
221: if (!using_ce020)
222: return false;
223: if (using_ce020 >= 3)
224: return false;
225: return true;
226: }
227: static bool isprefetch020(void)
228: {
229: if (!using_prefetch_020)
230: return false;
231: if (using_prefetch_020 >= 3)
232: return false;
233: return true;
234: }
235:
236: static void addcycles_ce020_2 (int cycles, const char *s)
237: {
238: if (!isce020())
1.1.1.4 root 239: return;
1.1.1.7 root 240: if (cycles > 0) {
241: if (s == NULL)
242: printf ("\t%s (%d);\n", do_cycles, cycles);
243: else
244: printf ("\t%s (%d); /* %s */\n", do_cycles, cycles, s);
245: }
246: count_cycles += cycles;
247: count_cycles_ce020 += cycles;
248: }
249: static void addcycles_ce020 (int cycles)
250: {
251: addcycles_ce020_2 (cycles, NULL);
252: }
1.1.1.4 root 253:
1.1.1.7 root 254: static void get_prefetch_020 (void)
255: {
256: if (!isprefetch020() || no_prefetch_ce020)
257: return;
258: printf ("\tregs.irc = %s (%d);\n", prefetch_word, m68k_pc_offset);
259: }
260: static void get_prefetch_020_continue(void)
261: {
262: if (!isprefetch020())
263: return;
264: if (using_ce020)
265: printf("\tcontinue_ce020_prefetch();\n");
266: else
267: printf ("\tcontinue_020_prefetch();\n");
268: }
269:
270: static void returntail (bool iswrite)
271: {
272: if (!isce020()) {
273: if (isprefetch020()) {
274: if (!tail_ce020_done) {
275: if (!did_prefetch)
276: get_prefetch_020 ();
277: did_prefetch = 1;
278: tail_ce020_done = true;
279: }
1.1.1.4 root 280: }
1.1.1.7 root 281: return;
282: }
283: if (!tail_ce020_done) {
284: total_ce020 -= 2;
285: #if 0
286: if (iswrite) {
287: printf("\t/* C - %d = %d */\n", memory_cycle_cnt, total_ce020 - memory_cycle_cnt);
288: total_ce020 -= memory_cycle_cnt;
289: } else {
290: printf("\t/* C = %d */\n", total_ce020);
291: }
292: #endif
293: if (0 && total_ce020 <= 0) {
294: printf ("\t/* C was zero */\n");
295: total_ce020 = 1;
296: }
297: if (!did_prefetch)
298: get_prefetch_020 ();
299: if (total_ce020 > 0)
300: addcycles_ce020 (total_ce020);
301:
302: //printf ("\tregs.irc = %s;\n", prefetch_word);
303: if (0 && total_ce020 >= 2) {
304: printf ("\top_cycles = get_cycles () - op_cycles;\n");
305: printf ("\top_cycles /= cpucycleunit;\n");
306: printf ("\tif (op_cycles < %d) {\n", total_ce020);
307: printf ("\t\tdo_cycles_ce020 ((%d) - op_cycles);\n", total_ce020);
308: printf ("\t}\n");
309: }
310: #if 0
311: if (tail_ce020 > 0) {
312: printf ("\tregs.ce020_tail = %d * cpucycleunit;\n", tail_ce020);
313: printf ("\tregs.ce020_tail_cycles = get_cycles () + regs.ce020_tail;\n");
314: } else {
315: printf ("\tregs.ce020_tail = 0;\n");
1.1.1.4 root 316: }
1.1.1.7 root 317: #endif
318: tail_ce020_done = true;
319: }
320: }
321:
1.1.1.4 root 322:
1.1.1.7 root 323: static void returncycles (const char *s, int cycles)
324: {
325: if (using_ce || using_ce020) {
326: #if 0
327: if (tail_ce020 == 0)
328: printf ("\tregs.ce020memcycles -= 2 * cpucycleunit; /* T=0 */ \n");
329: else if (tail_ce020 == 1)
330: printf ("\tregs.ce020memcycles -= 1 * cpucycleunit; /* T=1 */ \n");
331: else if (tail_ce020 == 2)
332: printf ("\tregs.ce020memcycles -= 0 * cpucycleunit; /* T=2 */\n");
333: #endif
334: printf ("%sreturn;\n", s);
335: return;
1.1.1.4 root 336: }
1.1.1.7 root 337: if (using_simple_cycles)
338: printf ("%sreturn %d * CYCLE_UNIT / 2 + count_cycles;\n", s, cycles);
1.1.1.4 root 339: else
340: printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles);
341: }
342:
1.1.1.7 root 343: static void addcycles_ce020_4 (const char *name, int head, int tail, int cycles)
1.1.1.4 root 344: {
1.1.1.7 root 345: if (!isce020())
346: return;
347: if (!head && !tail && !cycles)
348: return;
349: printf ("\t/* %s H:%d,T:%d,C:%d */\n", name, head, tail, cycles);
350: }
351: static void addcycles_ce020_5 (const char *name, int head, int tail, int cycles, int ophead)
352: {
353: if (!isce020())
354: return;
355: if (!head && !tail && !cycles && !ophead) {
356: printf ("\t/* OP zero */\n");
1.1.1.4 root 357: return;
358: }
1.1.1.7 root 359: count_cycles += cycles;
360: if (!ophead) {
361: addcycles_ce020_4 (name, head, tail, cycles);
362: } else if (ophead > 0) {
363: printf ("\t/* %s H:%d-,T:%d,C:%d */\n", name, head, tail, cycles);
364: } else {
365: printf ("\t/* %s H:%d+,T:%d,C:%d */\n", name, head, tail, cycles);
366: }
367: }
368:
369: static void addcycles000_nonces(const char *s, const char *sc)
370: {
371: if (using_simple_cycles) {
372: printf("%scount_cycles += (%s) * CYCLE_UNIT / 2;\n", s, sc);
373: count_ncycles++;
374: }
375: }
376: static void addcycles000_nonce(const char *s, int c)
377: {
378: if (using_simple_cycles) {
379: printf("%scount_cycles += %d * CYCLE_UNIT / 2;\n", s, c);
380: count_ncycles++;
381: }
382: }
383:
384: static void addcycles000_onlyce (int cycles)
385: {
386: if (using_ce) {
387: printf ("\t%s (%d);\n", do_cycles, cycles);
388: }
1.1.1.4 root 389: }
390:
391: static void addcycles000 (int cycles)
392: {
1.1.1.7 root 393: if (using_ce) {
394: printf ("\t%s (%d);\n", do_cycles, cycles);
395: }
1.1.1.4 root 396: count_cycles += cycles;
397: }
1.1.1.7 root 398:
399: #ifndef WINUAE_FOR_HATARI
1.1.1.4 root 400: static void addcycles000_2 (const char *s, int cycles)
401: {
1.1.1.7 root 402: if (using_ce) {
403: printf ("%s%s (%d);\n", s, do_cycles, cycles);
404: }
1.1.1.4 root 405: count_cycles += cycles;
406: }
1.1.1.7 root 407: #endif
408:
1.1.1.4 root 409:
410: static void addcycles000_3 (const char *s)
411: {
1.1.1.7 root 412: if (using_ce) {
413: printf ("%sif (cycles > 0) %s (cycles);\n", s, do_cycles);
414: }
1.1.1.4 root 415: count_ncycles++;
416: }
417:
418: static int isreg (amodes mode)
419: {
420: if (mode == Dreg || mode == Areg)
421: return 1;
422: return 0;
423: }
424:
425: static void start_brace (void)
426: {
427: n_braces++;
428: printf ("{");
429: }
430:
431: static void close_brace (void)
432: {
433: assert (n_braces > 0);
434: n_braces--;
435: printf ("}");
436: }
437:
438: static void finish_braces (void)
439: {
440: while (n_braces > 0)
441: close_brace ();
442: }
443:
444: static void pop_braces (int to)
445: {
446: while (n_braces > to)
447: close_brace ();
448: }
449:
450: static int bit_size (int size)
451: {
452: switch (size) {
453: case sz_byte: return 8;
454: case sz_word: return 16;
455: case sz_long: return 32;
1.1.1.7 root 456: default: term ();
1.1.1.4 root 457: }
458: return 0;
459: }
460:
461: static const char *bit_mask (int size)
462: {
463: switch (size) {
464: case sz_byte: return "0xff";
465: case sz_word: return "0xffff";
466: case sz_long: return "0xffffffff";
1.1.1.7 root 467: default: term ();
1.1.1.4 root 468: }
469: return 0;
470: }
471:
1.1.1.7 root 472: static void add_mmu040_movem (int movem)
473: {
474: if (movem != 3)
475: return;
476: printf ("\tif (mmu040_movem) {\n");
477: printf ("\t\tsrca = mmu040_movem_ea;\n");
478: printf ("\t} else\n");
479: start_brace ();
480: }
1.1.1.4 root 481:
1.1.1.7 root 482: static void gen_nextilong2 (const char *type, const char *name, int flags, int movem)
1.1.1.4 root 483: {
484: int r = m68k_pc_offset;
485: m68k_pc_offset += 4;
486:
1.1.1.7 root 487: printf ("\t%s %s;\n", type, name);
488: add_mmu040_movem (movem);
1.1.1.4 root 489: if (using_ce020) {
1.1.1.7 root 490: if (flags & GF_NOREFILL)
491: printf("\t%s = %s (%d);\n", name, prefetch_long, r);
492: else
493: printf("\t%s = %s (%d);\n", name, prefetch_long, r);
1.1.1.4 root 494: count_read += 2;
495: } else if (using_ce) {
496: /* we must do this because execution order of (something | something2) is not defined */
497: if (flags & GF_NOREFILL) {
1.1.1.7 root 498: printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2);
1.1.1.4 root 499: count_read++;
500: printf ("\t%s |= regs.irc;\n", name);
501: } else {
1.1.1.7 root 502: printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2);
1.1.1.4 root 503: count_read++;
1.1.1.7 root 504: printf ("\t%s |= %s (%d);\n", name, prefetch_word, r + 4);
1.1.1.4 root 505: count_read++;
506: }
507: } else {
508: if (using_prefetch) {
509: if (flags & GF_NOREFILL) {
1.1.1.7 root 510: printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2);
1.1.1.4 root 511: count_read++;
512: printf ("\t%s |= regs.irc;\n", name);
513: insn_n_cycles += 4;
514: } else {
1.1.1.7 root 515: printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2);
516: count_read += 2;
517: printf ("\t%s |= %s (%d);\n", name, prefetch_word, r + 4);
1.1.1.4 root 518: insn_n_cycles += 8;
519: }
520: } else {
521: insn_n_cycles += 8;
1.1.1.7 root 522: printf ("\t%s = %s (%d);\n", name, prefetch_long, r);
1.1.1.4 root 523: }
524: }
525: }
1.1.1.7 root 526: static void gen_nextilong (const char *type, const char *name, int flags)
527: {
528: gen_nextilong2 (type, name, flags, 0);
529: }
1.1.1.4 root 530:
531: static const char *gen_nextiword (int flags)
532: {
533: static char buffer[80];
534: int r = m68k_pc_offset;
535: m68k_pc_offset += 2;
536:
537: if (using_ce020) {
1.1.1.7 root 538: if (flags & GF_NOREFILL)
539: sprintf(buffer, "%s (%d)", prefetch_word, r);
540: else
541: sprintf(buffer, "%s (%d)", prefetch_word, r);
1.1.1.4 root 542: count_read++;
543: } else if (using_ce) {
544: if (flags & GF_NOREFILL) {
545: strcpy (buffer, "regs.irc");
546: } else {
1.1.1.7 root 547: sprintf (buffer, "%s (%d)", prefetch_word, r + 2);
1.1.1.4 root 548: count_read++;
549: }
550: } else {
551: if (using_prefetch) {
552: if (flags & GF_NOREFILL) {
1.1.1.7 root 553: strcpy (buffer, "regs.irc");
1.1.1.4 root 554: } else {
1.1.1.7 root 555: sprintf (buffer, "%s (%d)", prefetch_word, r + 2);
1.1.1.4 root 556: count_read++;
557: insn_n_cycles += 4;
558: }
559: } else {
1.1.1.7 root 560: sprintf (buffer, "%s (%d)", prefetch_word, r);
1.1.1.4 root 561: insn_n_cycles += 4;
562: }
563: }
564: return buffer;
565: }
566:
567: static const char *gen_nextibyte (int flags)
568: {
569: static char buffer[80];
570: int r = m68k_pc_offset;
571: m68k_pc_offset += 2;
572:
1.1.1.7 root 573: if (using_ce020 || using_prefetch_020) {
574: if (flags & GF_NOREFILL)
575: sprintf(buffer, "(uae_u8)%s (%d)", prefetch_word, r);
576: else
577: sprintf(buffer, "(uae_u8)%s (%d)", prefetch_word, r);
1.1.1.4 root 578: count_read++;
579: } else if (using_ce) {
580: if (flags & GF_NOREFILL) {
581: strcpy (buffer, "(uae_u8)regs.irc");
582: } else {
1.1.1.7 root 583: sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r + 2);
1.1.1.4 root 584: count_read++;
585: }
586: } else {
587: insn_n_cycles += 4;
588: if (using_prefetch) {
589: if (flags & GF_NOREFILL) {
1.1.1.7 root 590: strcpy (buffer, "(uae_u8)regs.irc");
1.1.1.4 root 591: } else {
1.1.1.7 root 592: sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r + 2);
1.1.1.4 root 593: insn_n_cycles += 4;
594: count_read++;
595: }
596: } else {
1.1.1.7 root 597: sprintf (buffer, "%s (%d)", srcbi, r);
1.1.1.4 root 598: insn_n_cycles += 4;
599: }
600: }
601: return buffer;
602: }
603:
1.1.1.7 root 604: static void makefromsr (void)
1.1.1.4 root 605: {
1.1.1.7 root 606: printf ("\tMakeFromSR();\n");
607: if (using_ce || isce020())
608: printf ("\tregs.ipl_pin = intlev ();\n");
609: }
610:
611: static void check_ipl (void)
612: {
613: if (ipl_fetched)
614: return;
615: if (using_ce || isce020())
616: printf ("\tipl_fetch ();\n");
617: ipl_fetched = 1;
618: }
619:
620: static void single_check_ipl(void)
621: {
622: check_ipl();
623: ipl_fetched = 2;
624:
625: }
626: /* this is not true, it seems to be microcode controller */
627:
628: /* Apparently interrupt state is sampled
629: * during any memory access. Because we don't
630: * know if there are future memory accesses,
631: * we'll check each memory access after prefetch
632: * and recheck interrupt state again.
633: */
634: static void check_ipl_again (void)
635: {
636: if (ipl_fetched != 1)
1.1.1.4 root 637: return;
638: if (using_ce)
639: printf ("\tipl_fetch ();\n");
640: }
641:
1.1.1.7 root 642: static void irc2ir_2 (bool dozero)
643: {
644: if (!using_prefetch)
645: return;
646: if (ir2irc)
647: return;
648: ir2irc = 1;
649: printf ("\tregs.ir = regs.irc;\n");
650: if (dozero)
651: printf ("\tregs.irc = 0;\n");
652: check_ipl ();
653: }
654: static void irc2ir (void)
655: {
656: irc2ir_2 (false);
657: }
1.1.1.4 root 658:
659: static void fill_prefetch_2 (void)
660: {
661: if (!using_prefetch)
662: return;
1.1.1.7 root 663: printf ("\t%s (%d);\n", prefetch_word, m68k_pc_offset + 2);
1.1.1.4 root 664: did_prefetch = 1;
1.1.1.7 root 665: ir2irc = 0;
1.1.1.4 root 666: count_read++;
667: insn_n_cycles += 4;
668: }
669:
670: static void fill_prefetch_1 (int o)
671: {
1.1.1.7 root 672: if (using_prefetch) {
673: printf ("\t%s (%d);\n", prefetch_word, o);
674: did_prefetch = 1;
675: ir2irc = 0;
676: count_read++;
677: insn_n_cycles += 4;
1.1.1.4 root 678: }
679: }
680:
681: static void fill_prefetch_full (void)
682: {
1.1.1.7 root 683: if (using_prefetch) {
684: fill_prefetch_1 (0);
685: irc2ir ();
686: fill_prefetch_1 (2);
687: } else if (isprefetch020()) {
688: did_prefetch = 2;
689: total_ce020 -= 4;
690: returntail (false);
691: if (cpu_level >= 3)
692: printf ("\tfill_prefetch_030 ();\n");
693: else if (cpu_level == 2)
694: printf ("\tfill_prefetch_020 ();\n");
695: }
696: }
697:
698: // 68000 and 68010 only
699: static void fill_prefetch_full_000 (void)
700: {
701: if (!using_prefetch)
702: return;
703: fill_prefetch_full ();
704: }
705:
706: // 68020+
707: static void fill_prefetch_full_020 (void)
708: {
709: if (!using_prefetch_020)
710: return;
711: fill_prefetch_full ();
1.1.1.4 root 712: }
713:
714: static void fill_prefetch_0 (void)
715: {
716: if (!using_prefetch)
717: return;
1.1.1.7 root 718: printf ("\t%s (0);\n", prefetch_word);
1.1.1.4 root 719: did_prefetch = 1;
1.1.1.7 root 720: ir2irc = 0;
1.1.1.4 root 721: count_read++;
722: insn_n_cycles += 4;
723: }
724:
1.1.1.7 root 725: #ifndef WINUAE_FOR_HATARI
1.1.1.4 root 726: static void dummy_prefetch (void)
727: {
728: int o = m68k_pc_offset + 2;
729: if (!using_prefetch)
730: return;
1.1.1.7 root 731: printf ("\t%s (%d);\n", srcwi, o);
1.1.1.4 root 732: count_read++;
733: insn_n_cycles += 4;
734: }
1.1.1.7 root 735: #endif
1.1.1.4 root 736:
737: static void fill_prefetch_next_1 (void)
738: {
739: irc2ir ();
740: fill_prefetch_1 (m68k_pc_offset + 2);
741: }
742:
743: static void fill_prefetch_next (void)
744: {
1.1.1.7 root 745: if (using_prefetch) {
746: fill_prefetch_next_1 ();
1.1.1.4 root 747: }
1.1.1.7 root 748: // if (using_prefetch_020) {
749: // printf ("\t%s (%d);\n", prefetch_word, m68k_pc_offset);
750: // did_prefetch = 1;
751: // }
1.1.1.4 root 752: }
753:
754: static void fill_prefetch_finish (void)
755: {
1.1.1.7 root 756: if (did_prefetch)
1.1.1.4 root 757: return;
1.1.1.7 root 758: if (using_prefetch) {
759: fill_prefetch_1 (m68k_pc_offset);
760: }
761: if (using_prefetch_020) {
762: did_prefetch = 1;
763: }
1.1.1.4 root 764: }
765:
766: static void setpc (const char *format, ...)
767: {
768: va_list parms;
769: char buffer[1000];
770:
771: va_start (parms, format);
772: _vsnprintf (buffer, 1000 - 1, format, parms);
773: va_end (parms);
774:
1.1.1.7 root 775: if (using_mmu || using_prefetch || using_prefetch_020)
776: printf ("\tm68k_setpci (%s);\n", buffer);
1.1.1.4 root 777: else
778: printf ("\tm68k_setpc (%s);\n", buffer);
779: }
780:
781: static void incpc (const char *format, ...)
782: {
783: va_list parms;
784: char buffer[1000];
785:
786: va_start (parms, format);
787: _vsnprintf (buffer, 1000 - 1, format, parms);
788: va_end (parms);
789:
1.1.1.7 root 790: if (using_mmu || using_prefetch || using_prefetch_020)
1.1.1.4 root 791: printf ("\tm68k_incpci (%s);\n", buffer);
792: else
793: printf ("\tm68k_incpc (%s);\n", buffer);
794: }
795:
796: static void sync_m68k_pc (void)
797: {
1.1.1.7 root 798: m68k_pc_offset_old = m68k_pc_offset;
1.1.1.4 root 799: if (m68k_pc_offset == 0)
800: return;
801: incpc ("%d", m68k_pc_offset);
1.1.1.7 root 802: m68k_pc_total += m68k_pc_offset;
1.1.1.4 root 803: m68k_pc_offset = 0;
804: }
805:
1.1.1.7 root 806: static void clear_m68k_offset(void)
807: {
808: m68k_pc_total += m68k_pc_offset;
809: m68k_pc_offset = 0;
810: }
811:
812: static void sync_m68k_pc_noreset (void)
813: {
814: sync_m68k_pc ();
815: m68k_pc_offset = m68k_pc_offset_old;
816: }
817:
818: static void addmmufixup (const char *reg)
1.1.1.4 root 819: {
820: if (!using_mmu)
821: return;
1.1.1.7 root 822: if (using_mmu == 68040 && (mmufixupstate || mmufixupcnt > 0))
823: return;
824: printf ("\tmmufixup[%d].reg = %s;\n", mmufixupcnt, reg);
825: printf ("\tmmufixup[%d].value = m68k_areg (regs, %s);\n", mmufixupcnt, reg);
826: mmufixupstate |= 1 << mmufixupcnt;
827: mmufixupcnt++;
828: }
829:
830: static void clearmmufixup (int cnt)
831: {
832: if (mmufixupstate & (1 << cnt)) {
833: printf ("\tmmufixup[%d].reg = -1;\n", cnt);
834: mmufixupstate &= ~(1 << cnt);
835: }
836: }
837:
838: static void gen_set_fault_pc (void)
839: {
840: if (using_mmu != 68040)
841: return;
1.1.1.4 root 842: sync_m68k_pc ();
1.1.1.7 root 843: printf ("\tregs.instruction_pc = %s;\n", getpc);
844: printf ("\tmmu_restart = false;\n");
1.1.1.4 root 845: m68k_pc_offset = 0;
1.1.1.7 root 846: clearmmufixup (0);
1.1.1.4 root 847: }
848:
849: static void syncmovepc (int getv, int flags)
850: {
851: #if 0
852: if (!(flags & GF_MOVE))
853: return;
854: if (getv == 1) {
855: sync_m68k_pc ();
856: //fill_prefetch_next ();
857: }
858: #endif
859: }
860:
1.1.1.7 root 861: static void head_cycs (int h)
862: {
863: if (head_ce020_cycs_done)
864: return;
865: if (h < 0)
866: return;
867: //printf ("\tdo_sync_tail (%d);\n", h);
868: //printf ("\tdo_head_cycles_ce020 (%d);\n", h);
869: head_ce020_cycs_done = true;
870: tail_ce020 = -1;
871: }
1.1.1.4 root 872:
1.1.1.7 root 873: static void add_head_cycs (int h)
874: {
875: if (!isce020())
876: return;
877: head_ce020_cycs_done = false;
878: head_cycs (h);
879: }
1.1.1.4 root 880:
1.1.1.7 root 881: static void addopcycles_ce20 (int h, int t, int c, int subhead)
1.1.1.4 root 882: {
1.1.1.7 root 883: head_cycs (h);
1.1.1.4 root 884:
1.1.1.7 root 885: //c = 0;
886: #if 0
887: if (tail_ce020 == 1)
888: printf ("\tregs.ce020memcycles -= 1 * cpucycleunit; /* T=1 */ \n");
889: else if (tail_ce020 == 2)
890: printf ("\tregs.ce020memcycles -= 2 * cpucycleunit; /* T=2 */\n");
891: #endif
892: if (1 && !subhead && (h > 0 || t > 0 || c > 0) && got_ea_ce020) {
893: if (!did_prefetch) {
894: get_prefetch_020 ();
895: did_prefetch = 1;
896: }
897: if (1) {
898: if (h > 0) {
899: printf ("\tif (regs.ce020memcycles > %d * cpucycleunit)\n", h);
900: printf ("\t\tregs.ce020memcycles = %d * cpucycleunit;\n", h);
901: } else {
902: printf ("\tregs.ce020memcycles = 0;\n");
903: }
904: }
905: }
1.1.1.4 root 906:
1.1.1.7 root 907: #if 0
908: if (tail_ce020 >= 0 && h >= 0 && head_in_ea_ce020 == 0) {
909: int largest = tail_ce020 > h ? tail_ce020: h;
910: if (tail_ce020 != h) {
911: //printf ("\tdo_cycles_ce020 (%d - %d);\n", tail_ce020 > h ? tail_ce020 : h, tail_ce020 > h ? h : tail_ce020);
912: //printf ("\tdo_cycles_ce020 (%d - %d);\n", tail_ce020 > h ? tail_ce020 : h, tail_ce020 > h ? h : tail_ce020);
913: if (h) {
914: printf ("\tregs.ce020memcycles -= %d * cpucycleunit;\n", h);
915: printf ("\tif (regs.ce020memcycles < 0) {\n");
916: //printf ("\t\tx_do_cycles (-regs.ce020memcycles);\n");
917: printf ("\t\tregs.ce020memcycles = 0;\n");
918: printf ("\t}\n");
919: } else {
920: printf ("\tregs.ce020memcycles = 0;\n");
921: }
922: //printf ("\tregs.ce020memcycles = 0;\n");
923:
924: #if 0
925: if (tail_ce020)
926: printf ("\tregs.ce020_tail = get_cycles () - regs.ce020_tail;\n");
927: else
928: printf ("\tregs.ce020_tail = 0;\n");
929: printf ("\tif (regs.ce020_tail < %d * cpucycleunit)\n", largest);
930: printf ("\t\tx_do_cycles (%d * cpucycleunit - regs.ce020_tail);\n", largest);
931: #endif
932: } else if (h) {
933: printf ("\t/* ea tail == op head (%d) */\n", h);
934:
935: printf ("\tregs.ce020memcycles -= %d * cpucycleunit;\n", h);
936: printf ("\tif (regs.ce020memcycles < 0) {\n");
937: //printf ("\t\tx_do_cycles (-regs.ce020memcycles);\n");
938: printf ("\t\tregs.ce020memcycles = 0;\n");
939: printf ("\t}\n");
940: }
941: }
942: #endif
943:
944: if (h < 0)
945: h = 0;
946:
947: //c = 0;
948:
949: // c = internal cycles needed after head cycles and before tail cycles. Not total cycles.
950: addcycles_ce020_5 ("op", h, t, c - h - t, -subhead);
951: //printf ("\tregs.irc = get_word_ce020_prefetch (%d);\n", m68k_pc_offset);
952: #if 0
953: if (c - h - t > 0) {
954: printf ("\t%s (%d);\n", do_cycles, c - h - t);
955: count_cycles_ce020 += c;
956: count_cycles += c;
957: }
958: #endif
959: //printf ("\tregs.ce020_tail = 0;\n");
960: total_ce020 = c;
961: tail_ce020 = t;
962: // if (total_ce020 >= 2)
963: // printf ("\tint op_cycles = get_cycles ();\n");
964: }
965:
966: static void addop_ce020 (struct instr *curi, int subhead)
967: {
968: if (!isce020())
969: return;
970: int h = curi->head;
971: int t = curi->tail;
972: int c = curi->clocks;
973: #if 0
974: if ((((curi->sduse & 2) && !isreg (curi->smode)) || (((curi->sduse >> 4) & 2) && !isreg (curi->dmode))) && using_waitstates) {
975: t += using_waitstates;
976: c += using_waitstates;
977: }
978: #endif
979: addopcycles_ce20 (h, t, c, -subhead);
980: }
981:
982: static void addcycles_ea_ce020_5 (const char *ea, int h, int t, int c, int oph)
983: {
984: head_cycs (h + oph);
985:
986: // if (!h && !h && !c && !oph)
987: // return;
988:
989: c = c - h - t;
990:
991: //c = 0;
992:
993: if (!oph) {
994: printf ("\t/* ea H:%d,T:%d,C:%d %s */\n", h, t, c, ea);
995: } else {
996: if (oph && t)
997: term_err ("Both op head and tail can't be non-zero");
998: if (oph > 0) {
999: printf ("\t/* ea H:%d+%d=%d,T:%d,C:%d %s */\n", h, oph, h + oph, t, c, ea);
1000: h += oph;
1001: } else {
1002: printf ("\t/* ea H:%d-%d=%d,T:%d,C:%d %s */\n", h, -oph, h + oph, t, c, ea);
1003: h += oph;
1004: }
1005: }
1006:
1007: if (h) {
1008: printf ("\tif (regs.ce020memcycles > %d * cpucycleunit)\n", h);
1009: printf ("\t\tregs.ce020memcycles = %d * cpucycleunit;\n", h);
1010: } else {
1011: printf ("\tregs.ce020memcycles = 0;\n");
1012: }
1013:
1014: if (1 && c > 0) {
1015: printf ("\t%s (%d);\n", do_cycles, c);
1016: count_cycles += c;
1017: }
1018: tail_ce020 = t;
1019: head_in_ea_ce020 = oph;
1020: got_ea_ce020 = true;
1021: // if (t > 0)
1022: // printf ("\tregs.ce020_tail = get_cycles () + %d * cpucycleunit;\n", t);
1023: }
1024: static void addcycles_ea_ce020_4 (const char *ea, int h, int t, int c)
1025: {
1026: addcycles_ea_ce020_5 (ea, h, t, c, 0);
1027: }
1028:
1029: #define SETCE020(h2,t2,c2) { h = h2; t = t2; c = c2; }
1030: #define SETCE020H(h2,t2,c2) { h = h2; oph = curi ? curi->head : 0; t = t2; c = c2; }
1031:
1032: static int gence020cycles_fiea (struct instr *curi, wordsizes ssize, amodes dmode)
1033: {
1034: bool l = ssize == sz_long;
1035: int h = 0, t = 0, c = 0, oph = 0;
1036: switch ((int)dmode)
1037: {
1038: case Dreg:
1039: case Areg:
1040: if (!l)
1041: SETCE020H(2, 0, 2)
1042: else
1043: SETCE020H(4, 0, 4)
1044: break;
1045: case Aind: // (An)
1046: if (!l)
1047: SETCE020(1, 1, 3)
1048: else
1049: SETCE020(1, 0, 4)
1050: break;
1051: case Aipi: // (An)+
1052: if (!l)
1053: SETCE020(2, 1, 5)
1054: else
1055: SETCE020(4, 1, 7)
1056: break;
1057: case Apdi: // -(An)
1058: if (!l)
1059: SETCE020(2, 2, 4)
1060: else
1061: SETCE020(2, 0, 4)
1062: break;
1063: case Ad8r: // (d8,An,Xn)
1064: case PC8r: // (d8,PC,Xn)
1065: if (!l)
1066: SETCE020(6, 2, 8)
1067: else
1068: SETCE020(8, 2, 10)
1069: break;
1070: case Ad16: // (d16,An)
1071: case PC16: // (d16,PC)
1072: if (!l)
1073: SETCE020(2, 0, 4)
1074: else
1075: SETCE020(4, 0, 6)
1076: break;
1077: case absw:
1078: if (!l)
1079: SETCE020(4, 2, 6)
1080: else
1081: SETCE020(6, 2, 8)
1082: break;
1083: case absl:
1084: if (!l)
1085: SETCE020(3, 0, 6)
1086: else
1087: SETCE020(5, 0, 8)
1088: break;
1089: }
1090: addcycles_ea_ce020_5 ("fiea", h, t, c, oph);
1091: return oph;
1092: }
1093:
1094:
1095: static int gence020cycles_ciea (struct instr *curi, wordsizes ssize, amodes dmode)
1096: {
1097: int h = 0, t = 0, c = 0, oph = 0;
1098: bool l = ssize == sz_long;
1099: switch ((int)dmode)
1100: {
1101: case Dreg:
1102: case Areg:
1103: if (!l)
1104: SETCE020H(2, 0, 2)
1105: else
1106: SETCE020H(4, 0, 4)
1107: break;
1108: case Aind: // (An)
1109: if (!l)
1110: SETCE020H(2, 0, 2)
1111: else
1112: SETCE020H(4, 0, 4)
1113: break;
1114: case Aipi: // (An)+
1115: if (!l)
1116: SETCE020(2, 0, 4)
1117: else
1118: SETCE020(4, 0, 6)
1119: break;
1120: case Apdi: // -(An)
1121: if (!l)
1122: SETCE020H(2, 0, 2)
1123: else
1124: SETCE020H(4, 0, 4)
1125: break;
1126: case Ad8r: // (d8,An,Xn)
1127: case PC8r: // (d8,PC,Xn)
1128: if (!l)
1129: SETCE020H(6, 0, 6)
1130: else
1131: SETCE020H(8, 0, 8)
1132: break;
1133: case Ad16: // (d16,An)
1134: case PC16: // (d16,PC)
1135: if (!l)
1136: SETCE020H(4, 0, 4)
1137: else
1138: SETCE020H(6, 0, 6)
1139: break;
1140: case absw:
1141: if (!l)
1142: SETCE020H(4, 0, 4)
1143: else
1144: SETCE020H(6, 0, 6)
1145: break;
1146: case absl:
1147: if (!l)
1148: SETCE020H(6, 0, 6)
1149: else
1150: SETCE020H(8, 0, 8)
1151: break;
1152: }
1153: addcycles_ea_ce020_5 ("ciea", h, t, c, oph);
1154: return oph;
1155: }
1156:
1157:
1158: static int gence020cycles_fea (amodes mode)
1159: {
1160: int h = 0, t = 0, c = 0, ws = 0;
1161: switch ((int)mode)
1162: {
1163: case Dreg:
1164: case Areg:
1165: SETCE020(0, 0, 0)
1166: break;
1167: case Aind: // (An)
1168: ws++;
1169: SETCE020(1, 1, 3)
1170: break;
1171: case Aipi: // (An)+
1172: ws++;
1173: SETCE020(0, 1, 3)
1174: break;
1175: case Apdi: // -(An)
1176: ws++;
1177: SETCE020(2, 2, 4)
1178: break;
1179: case Ad8r: // (d8,An,Xn)
1180: case PC8r: // (d8,PC,Xn)
1181: ws++;
1182: SETCE020(4, 2, 6)
1183: break;
1184: case Ad16: // (d16,An)
1185: case PC16: // (d16,PC)
1186: ws++;
1187: SETCE020(2, 2, 4)
1188: break;
1189: case absw:
1190: ws++;
1191: SETCE020(2, 2, 4)
1192: break;
1193: case absl:
1194: ws++;
1195: SETCE020(1, 0, 4)
1196: break;
1197: }
1198: #if 0
1199: if (using_waitstates) {
1200: t += ws * using_waitstates;
1201: c += ws * using_waitstates;
1202: }
1203: #endif
1204: addcycles_ea_ce020_4 ("fea", h, t, c);
1205: return 0;
1206: }
1207:
1208: static int gence020cycles_cea (struct instr *curi, amodes mode)
1209: {
1210: int h = 0, t = 0, c = 0, oph = 0;
1211: switch ((int)mode)
1212: {
1213: case Dreg:
1214: case Areg:
1215: SETCE020(0, 0, 0);
1216: break;
1217: case Aind: // (An)
1218: SETCE020H(2 + h, 0, 2);
1219: break;
1220: case Aipi: // (An)+
1221: SETCE020(0, 0, 2);
1222: break;
1223: case Apdi: // -(An)
1224: SETCE020H(2, 0, 2)
1225: break;
1226: case Ad8r: // (d8,An,Xn)
1227: case PC8r: // (d8,PC,Xn)
1228: SETCE020H(4, 0, 4)
1229: break;
1230: case Ad16: // (d16,An)
1231: case PC16: // (d16,PC)
1232: SETCE020H(2, 0, 2)
1233: break;
1234: case absw:
1235: SETCE020H(2, 0, 2)
1236: break;
1237: case absl:
1238: SETCE020H(4, 0, 4)
1239: break;
1240: }
1241: addcycles_ea_ce020_5 ("cea", h, t, c, oph);
1242: return oph;
1243: }
1244:
1245: static int gence020cycles_jea (struct instr *curi, amodes mode)
1246: {
1247: int h = 0, t = 0, c = 0, oph = 0;
1248: switch ((int)mode)
1249: {
1250: case Aind: // (An)
1251: SETCE020H(2, 0, 2)
1252: break;
1253: case Ad16: // (d16,An)
1254: case PC16: // (d16,PC)
1255: SETCE020H(4, 0, 4)
1256: break;
1257: case absw:
1258: SETCE020H(2, 0, 2)
1259: break;
1260: case absl:
1261: SETCE020H(2, 0, 2)
1262: break;
1263: }
1264: addcycles_ea_ce020_5 ("jea", h, t, c, oph);
1265: return oph;
1266: }
1267:
1268: static void next_level_000 (void)
1269: {
1270: if (next_cpu_level < 0)
1271: next_cpu_level = 0;
1272: }
1273:
1274: static void maybeaddop_ce020 (int flags)
1275: {
1276: if (flags & GF_OPCE020)
1277: addop_ce020 (curi_ce020, subhead_ce020);
1278: }
1279:
1280:
1281: /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
1282: * the calling routine handles Apdi and Aipi modes.
1283: * gb-- movem == 2 means the same thing but for a MOVE16 instruction */
1284:
1285: /* fixup indicates if we want to fix up adress registers in pre decrement
1286: * or post increment mode now (0) or later (1). A value of 2 will then be
1287: * used to do the actual fix up. This allows to do all memory readings
1288: * before any register is modified, and so to rerun operation without
1289: * side effect in case a bus fault is generated by any memory access.
1290: * XJ - 2006/11/13 */
1291:
1292: static void genamode2x (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags, int fetchmode)
1293: {
1294: char namea[100];
1295: bool rmw = false;
1296: int pc_68000_offset = m68k_pc_offset;
1297: int pc_68000_offset_fetch = 0;
1298: int pc_68000_offset_store = 0;
1299:
1300: sprintf (namea, "%sa", name);
1301: if ((flags & GF_RMW) && using_mmu == 68060) {
1302: strcpy (rmw_varname, name);
1303: candormw = true;
1304: rmw = true;
1305: }
1306:
1307: if (mode == Ad8r || mode == PC8r) {
1308: genamode8r_offset[genamode_cnt] = m68k_pc_total + m68k_pc_offset;
1309: genamode_cnt++;
1310: }
1311:
1312: start_brace ();
1313:
1314: switch (mode) {
1315: case Dreg:
1316: if (movem)
1317: term ();
1.1.1.4 root 1318: if (getv == 1)
1319: switch (size) {
1320: case sz_byte:
1321: #ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION
1322: /* This causes the target compiler to generate better code on few systems */
1323: printf ("\tuae_s8 %s = ((uae_u8*)&m68k_dreg (regs, %s))[3];\n", name, reg);
1324: #else
1325: printf ("\tuae_s8 %s = m68k_dreg (regs, %s);\n", name, reg);
1326: #endif
1327: break;
1328: case sz_word:
1329: #ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION
1330: printf ("\tuae_s16 %s = ((uae_s16*)&m68k_dreg (regs, %s))[1];\n", name, reg);
1331: #else
1332: printf ("\tuae_s16 %s = m68k_dreg (regs, %s);\n", name, reg);
1333: #endif
1334: break;
1335: case sz_long:
1336: printf ("\tuae_s32 %s = m68k_dreg (regs, %s);\n", name, reg);
1337: break;
1338: default:
1.1.1.7 root 1339: term ();
1.1.1.4 root 1340: }
1.1.1.7 root 1341: maybeaddop_ce020 (flags);
1.1.1.4 root 1342: syncmovepc (getv, flags);
1343: return;
1344: case Areg:
1345: if (movem)
1.1.1.7 root 1346: term ();
1.1.1.4 root 1347: if (getv == 1)
1348: switch (size) {
1349: case sz_word:
1350: printf ("\tuae_s16 %s = m68k_areg (regs, %s);\n", name, reg);
1351: break;
1352: case sz_long:
1353: printf ("\tuae_s32 %s = m68k_areg (regs, %s);\n", name, reg);
1354: break;
1355: default:
1.1.1.7 root 1356: term ();
1.1.1.4 root 1357: }
1.1.1.7 root 1358: maybeaddop_ce020 (flags);
1.1.1.4 root 1359: syncmovepc (getv, flags);
1360: return;
1361: case Aind: // (An)
1.1.1.7 root 1362: switch (fetchmode)
1363: {
1364: case fetchmode_fea:
1365: addcycles_ce020 (1);
1366: break;
1367: case fetchmode_cea:
1368: addcycles_ce020 (2);
1369: break;
1370: case fetchmode_jea:
1371: addcycles_ce020 (2);
1372: break;
1373: }
1374: printf ("\tuaecptr %sa;\n", name);
1375: add_mmu040_movem (movem);
1376: printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg);
1.1.1.4 root 1377: break;
1378: case Aipi: // (An)+
1.1.1.7 root 1379: switch (fetchmode)
1380: {
1381: case fetchmode_fea:
1382: addcycles_ce020 (1);
1383: break;
1384: case fetchmode_cea:
1385: break;
1386: }
1387: printf ("\tuaecptr %sa;\n", name);
1388: add_mmu040_movem (movem);
1389: printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg);
1.1.1.4 root 1390: break;
1391: case Apdi: // -(An)
1.1.1.7 root 1392: switch (fetchmode)
1393: {
1394: case fetchmode_fea:
1395: case fetchmode_cea:
1396: addcycles_ce020 (2);
1397: break;
1398: }
1.1.1.4 root 1399: printf ("\tuaecptr %sa;\n", name);
1.1.1.7 root 1400: add_mmu040_movem (movem);
1.1.1.4 root 1401: switch (size) {
1402: case sz_byte:
1403: if (movem)
1404: printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg);
1405: else
1406: printf ("\t%sa = m68k_areg (regs, %s) - areg_byteinc[%s];\n", name, reg, reg);
1407: break;
1408: case sz_word:
1409: printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 2);
1410: break;
1411: case sz_long:
1412: printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 4);
1413: break;
1414: default:
1.1.1.7 root 1415: term ();
1.1.1.4 root 1416: }
1417: if (!(flags & GF_APDI)) {
1418: addcycles000 (2);
1419: insn_n_cycles += 2;
1420: count_cycles_ea += 2;
1.1.1.7 root 1421: pc_68000_offset_fetch += 2;
1.1.1.4 root 1422: }
1423: break;
1424: case Ad16: // (d16,An)
1.1.1.7 root 1425: printf ("\tuaecptr %sa;\n", name);
1426: add_mmu040_movem (movem);
1427: printf ("\t%sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags));
1428: count_read_ea++;
1429: break;
1430: case PC16: // (d16,PC)
1431: printf ("\tuaecptr %sa;\n", name);
1432: add_mmu040_movem (movem);
1433: printf ("\t%sa = %s + %d;\n", name, getpc, m68k_pc_offset);
1434: printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags));
1.1.1.4 root 1435: break;
1436: case Ad8r: // (d8,An,Xn)
1.1.1.7 root 1437: switch (fetchmode)
1438: {
1439: case fetchmode_fea:
1440: addcycles_ce020 (4);
1441: break;
1442: case fetchmode_cea:
1443: case fetchmode_jea:
1444: break;
1445: }
1.1.1.4 root 1446: printf ("\tuaecptr %sa;\n", name);
1447: if (cpu_level > 1) {
1448: if (next_cpu_level < 1)
1449: next_cpu_level = 1;
1450: sync_m68k_pc ();
1.1.1.7 root 1451: add_mmu040_movem (movem);
1.1.1.4 root 1452: start_brace ();
1453: /* This would ordinarily be done in gen_nextiword, which we bypass. */
1454: insn_n_cycles += 4;
1.1.1.7 root 1455: printf ("\t%sa = %s (m68k_areg (regs, %s), %d);\n", name, disp020, reg, disp020cnt++);
1.1.1.4 root 1456: } else {
1457: if (!(flags & GF_AD8R)) {
1458: addcycles000 (2);
1459: insn_n_cycles += 2;
1460: count_cycles_ea += 2;
1.1.1.7 root 1461: #ifdef WINUAE_FOR_HATARI
1462: /* Hatari : on 68000 ST, Ad8r causes an unaligned memory prefetch and take 2 cycles more */
1463: /* JSR, JMP, LEA and PEA are handled separately */
1464: /* We add 2 cycles only in 68000 prefetch mode, 68000 CE mode is handled at the memory access level */
1465: if ( using_prefetch && !using_ce )
1466: printf ("\tBusCyclePenalty += 2;\n");
1467: #endif
1.1.1.4 root 1468: }
1.1.1.7 root 1469: if ((flags & GF_NOREFILL) && using_prefetch) {
1470: printf ("\t%sa = %s (m68k_areg (regs, %s), regs.irc);\n", name, disp000, reg);
1471: } else {
1472: printf ("\t%sa = %s (m68k_areg (regs, %s), %s);\n", name, disp000, reg, gen_nextiword (flags));
1473: }
1474: count_read_ea++;
1.1.1.4 root 1475: }
1476: break;
1477: case PC8r: // (d8,PC,Xn)
1.1.1.7 root 1478: switch (fetchmode)
1479: {
1480: case fetchmode_fea:
1481: addcycles_ce020 (4);
1482: break;
1483: case fetchmode_cea:
1484: case fetchmode_jea:
1485: break;
1486: }
1.1.1.4 root 1487: printf ("\tuaecptr tmppc;\n");
1488: printf ("\tuaecptr %sa;\n", name);
1489: if (cpu_level > 1) {
1490: if (next_cpu_level < 1)
1491: next_cpu_level = 1;
1492: sync_m68k_pc ();
1.1.1.7 root 1493: add_mmu040_movem (movem);
1.1.1.4 root 1494: start_brace ();
1495: /* This would ordinarily be done in gen_nextiword, which we bypass. */
1496: insn_n_cycles += 4;
1.1.1.7 root 1497: printf ("\ttmppc = %s;\n", getpc);
1498: printf ("\t%sa = %s (tmppc, %d);\n", name, disp020, disp020cnt++);
1.1.1.4 root 1499: } else {
1.1.1.7 root 1500: printf ("\ttmppc = %s + %d;\n", getpc, m68k_pc_offset);
1.1.1.4 root 1501: if (!(flags & GF_PC8R)) {
1502: addcycles000 (2);
1503: insn_n_cycles += 2;
1504: count_cycles_ea += 2;
1.1.1.7 root 1505: #ifdef WINUAE_FOR_HATARI
1506: /* Hatari : on 68000 ST, Ad8r causes an unaligned memory prefetch and take 2 cycles more */
1507: /* JSR, JMP, LEA and PEA are handled separately */
1508: /* We add 2 cycles only in 68000 prefetch mode, 68000 CE mode is handled at the memory access level */
1509: if ( using_prefetch && !using_ce )
1510: printf ("\tBusCyclePenalty += 2;\n");
1511: #endif
1512: }
1513: if ((flags & GF_NOREFILL) && using_prefetch) {
1514: printf ("\t%sa = %s (tmppc, regs.irc);\n", name, disp000);
1515: } else {
1516: printf ("\t%sa = %s (tmppc, %s);\n", name, disp000, gen_nextiword (flags));
1.1.1.4 root 1517: }
1518: }
1519:
1520: break;
1521: case absw:
1.1.1.7 root 1522: printf ("\tuaecptr %sa;\n", name);
1523: add_mmu040_movem (movem);
1524: printf ("\t%sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags));
1525: pc_68000_offset_fetch += 2;
1.1.1.4 root 1526: break;
1527: case absl:
1.1.1.7 root 1528: gen_nextilong2 ("uaecptr", namea, flags, movem);
1.1.1.4 root 1529: count_read_ea += 2;
1.1.1.7 root 1530: pc_68000_offset_fetch += 4;
1531: pc_68000_offset_store += 2;
1.1.1.4 root 1532: break;
1533: case imm:
1.1.1.7 root 1534: // fetch immediate address
1.1.1.4 root 1535: if (getv != 1)
1.1.1.7 root 1536: term ();
1.1.1.4 root 1537: insn_n_cycles020++;
1538: switch (size) {
1539: case sz_byte:
1540: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags));
1541: count_read_ea++;
1542: break;
1543: case sz_word:
1544: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags));
1545: count_read_ea++;
1546: break;
1547: case sz_long:
1548: gen_nextilong ("uae_s32", name, flags);
1549: count_read_ea += 2;
1550: break;
1551: default:
1.1.1.7 root 1552: term ();
1.1.1.4 root 1553: }
1.1.1.7 root 1554: maybeaddop_ce020 (flags);
1.1.1.4 root 1555: syncmovepc (getv, flags);
1556: return;
1557: case imm0:
1558: if (getv != 1)
1.1.1.7 root 1559: term ();
1.1.1.4 root 1560: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags));
1561: count_read_ea++;
1.1.1.7 root 1562: maybeaddop_ce020 (flags);
1.1.1.4 root 1563: syncmovepc (getv, flags);
1564: return;
1565: case imm1:
1566: if (getv != 1)
1.1.1.7 root 1567: term ();
1.1.1.4 root 1568: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags));
1569: count_read_ea++;
1.1.1.7 root 1570: maybeaddop_ce020 (flags);
1.1.1.4 root 1571: syncmovepc (getv, flags);
1572: return;
1573: case imm2:
1574: if (getv != 1)
1.1.1.7 root 1575: term ();
1.1.1.4 root 1576: gen_nextilong ("uae_s32", name, flags);
1577: count_read_ea += 2;
1.1.1.7 root 1578: maybeaddop_ce020 (flags);
1.1.1.4 root 1579: syncmovepc (getv, flags);
1580: return;
1581: case immi:
1582: if (getv != 1)
1.1.1.7 root 1583: term ();
1.1.1.4 root 1584: printf ("\tuae_u32 %s = %s;\n", name, reg);
1.1.1.7 root 1585: maybeaddop_ce020 (flags);
1.1.1.4 root 1586: syncmovepc (getv, flags);
1587: return;
1588: default:
1.1.1.7 root 1589: term ();
1.1.1.4 root 1590: }
1591:
1592: syncmovepc (getv, flags);
1.1.1.7 root 1593: maybeaddop_ce020 (flags);
1.1.1.4 root 1594:
1595: /* We get here for all non-reg non-immediate addressing modes to
1596: * actually fetch the value. */
1597:
1.1.1.7 root 1598: int exception_pc_offset = 0;
1599: if (getv == 2) {
1600: // store
1601: if (pc_68000_offset) {
1602: exception_pc_offset = pc_68000_offset + pc_68000_offset_store + 2;
1.1.1.4 root 1603: }
1.1.1.7 root 1604: } else {
1605: // fetch
1606: pc_68000_offset_fetch += 2;
1607: exception_pc_offset = pc_68000_offset_fetch;
1608: }
1609:
1610: if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte) {
1.1.1.4 root 1611: printf ("\tif (%sa & 1) {\n", name);
1.1.1.7 root 1612: if (exception_pc_offset)
1613: incpc("%d", exception_pc_offset);
1614: printf ("\t\texception3_%s(opcode, %sa);\n", getv == 2 ? "write" : "read", name);
1.1.1.4 root 1615: printf ("\t\tgoto %s;\n", endlabelstr);
1616: printf ("\t}\n");
1617: need_endlabel = 1;
1618: start_brace ();
1619: }
1620:
1.1.1.7 root 1621: if ((using_prefetch || using_ce) && using_bus_error && getv != 0) {
1622: if (exception_pc_offset)
1623: printf("\tbus_error_offset = %d;\n", exception_pc_offset);
1624: }
1625:
1.1.1.4 root 1626: if (flags & GF_PREFETCH)
1627: fill_prefetch_next ();
1.1.1.7 root 1628: else if (flags & GF_IR2IRC)
1629: irc2ir_2 (true);
1.1.1.4 root 1630:
1631: if (getv == 1) {
1632: start_brace ();
1.1.1.7 root 1633: if (using_ce020 || using_prefetch_020) {
1.1.1.4 root 1634: switch (size) {
1635: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break;
1636: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break;
1637: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srcl, name); count_read += 2; break;
1.1.1.7 root 1638: default: term ();
1.1.1.4 root 1639: }
1.1.1.7 root 1640: } else if (using_ce || using_prefetch) {
1.1.1.4 root 1641: switch (size) {
1.1.1.7 root 1642: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break;
1643: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break;
1644: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa) << 16; %s |= %s (%sa + 2);\n", name, srcw, name, name, srcw, name); count_read += 2; break;
1645: default: term ();
1.1.1.4 root 1646: }
1647: } else if (using_mmu) {
1648: if (flags & GF_FC) {
1649: switch (size) {
1.1.1.5 root 1650: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = sfc%s_get_byte (%sa);\n", name, mmu_postfix, name); break;
1651: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = sfc%s_get_word (%sa);\n", name, mmu_postfix, name); break;
1652: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = sfc%s_get_long (%sa);\n", name, mmu_postfix, name); break;
1.1.1.7 root 1653: default: term ();
1.1.1.4 root 1654: }
1655: } else {
1656: switch (size) {
1.1.1.7 root 1657: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcblrmw : (rmw ? srcbrmw : srcb), name); break;
1658: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcwlrmw : (rmw ? srcwrmw : srcw), name); break;
1659: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcllrmw : (rmw ? srclrmw : srcl), name); break;
1660: default: term ();
1.1.1.4 root 1661: }
1662: }
1663: } else {
1664: switch (size) {
1.1.1.7 root 1665: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break;
1666: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break;
1667: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srcl, name); count_read += 2; break;
1668: default: term ();
1.1.1.4 root 1669: }
1670: }
1671: }
1672:
1673: /* We now might have to fix up the register for pre-dec or post-inc
1674: * addressing modes. */
1675: if (!movem)
1676: switch (mode) {
1677: case Aipi:
1.1.1.7 root 1678: addmmufixup (reg);
1.1.1.4 root 1679: switch (size) {
1680: case sz_byte:
1681: printf ("\tm68k_areg (regs, %s) += areg_byteinc[%s];\n", reg, reg);
1682: break;
1683: case sz_word:
1684: printf ("\tm68k_areg (regs, %s) += 2;\n", reg);
1685: break;
1686: case sz_long:
1687: printf ("\tm68k_areg (regs, %s) += 4;\n", reg);
1688: break;
1689: default:
1.1.1.7 root 1690: term ();
1.1.1.4 root 1691: }
1692: break;
1693: case Apdi:
1.1.1.7 root 1694: addmmufixup (reg);
1.1.1.4 root 1695: printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name);
1696: break;
1697: default:
1698: break;
1699: }
1.1.1.7 root 1700:
1701: if (movem == 3) {
1702: close_brace ();
1703: }
1.1.1.4 root 1704: }
1705:
1.1.1.7 root 1706: static void genamode2 (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags)
1.1.1.4 root 1707: {
1.1.1.7 root 1708: genamode2x (mode, reg, size, name, getv, movem, flags, -1);
1.1.1.4 root 1709: }
1710:
1.1.1.7 root 1711: static void genamode (struct instr *curi, amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags)
1.1.1.4 root 1712: {
1.1.1.7 root 1713: int oldfixup = mmufixupstate;
1714: int subhead = 0;
1715: if (isce020() && curi) {
1716: switch (curi->fetchmode)
1717: {
1718: case fetchmode_fea:
1719: subhead = gence020cycles_fea (mode);
1720: break;
1721: case fetchmode_cea:
1722: subhead = gence020cycles_cea (curi, mode);
1723: break;
1724: case fetchmode_jea:
1725: subhead = gence020cycles_jea (curi, mode);
1726: break;
1727: }
1728: genamode2x (mode, reg, size, name, getv, movem, flags, curi->fetchmode);
1729: } else {
1730: genamode2 (mode, reg, size, name, getv, movem, flags);
1731: }
1732: if (using_mmu == 68040 && (oldfixup & 1)) {
1733: // we have fixup already active = this genamode call is destination mode and we can now clear previous source fixup.
1734: clearmmufixup (0);
1735: }
1736: if (isce020() && curi)
1737: addop_ce020 (curi, subhead);
1.1.1.4 root 1738: }
1.1.1.7 root 1739:
1740: static void genamode3 (struct instr *curi, amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags)
1.1.1.4 root 1741: {
1.1.1.7 root 1742: int oldfixup = mmufixupstate;
1743: genamode2x (mode, reg, size, name, getv, movem, flags, curi ? curi->fetchmode : -1);
1744: if (using_mmu == 68040 && (oldfixup & 1)) {
1745: // we have fixup already active = this genamode call is destination mode and we can now clear previous source fixup.
1746: clearmmufixup (0);
1747: }
1.1.1.4 root 1748: }
1.1.1.7 root 1749:
1750: static void genamodedual (struct instr *curi, amodes smode, const char *sreg, wordsizes ssize, const char *sname, int sgetv, int sflags,
1751: amodes dmode, const char *dreg, wordsizes dsize, const char *dname, int dgetv, int dflags)
1.1.1.4 root 1752: {
1.1.1.7 root 1753: int subhead = 0;
1754: bool eadmode = false;
1755:
1756: if (isce020()) {
1757: switch (curi->fetchmode)
1758: {
1759: case fetchmode_fea:
1760: if (smode >= imm || isreg (smode)) {
1761: subhead = gence020cycles_fea (dmode);
1762: eadmode = true;
1763: } else {
1764: subhead = gence020cycles_fea (smode);
1765: }
1766: break;
1767: case fetchmode_cea:
1768: subhead = gence020cycles_cea (curi, smode);
1769: break;
1770: case fetchmode_fiea:
1771: subhead = gence020cycles_fiea (curi, ssize, dmode);
1772: break;
1773: case fetchmode_ciea:
1774: subhead = gence020cycles_ciea (curi, ssize, dmode);
1775: break;
1776: case fetchmode_jea:
1777: subhead = gence020cycles_jea (curi, smode);
1778: break;
1779: default:
1780: printf ("\t/* No EA */\n");
1781: break;
1782: }
1783: }
1784: subhead_ce020 = subhead;
1785: curi_ce020 = curi;
1786: genamode3 (curi, smode, sreg, ssize, sname, sgetv, 0, sflags);
1787: genamode3 (NULL, dmode, dreg, dsize, dname, dgetv, 0, dflags | (eadmode == true ? GF_OPCE020 : 0));
1788: if (eadmode == false)
1789: maybeaddop_ce020 (GF_OPCE020);
1.1.1.4 root 1790: }
1791:
1792: static void genastore_2 (const char *from, amodes mode, const char *reg, wordsizes size, const char *to, int store_dir, int flags)
1793: {
1.1.1.7 root 1794: if (candormw) {
1795: if (strcmp (rmw_varname, to) != 0)
1796: candormw = false;
1797: }
1798: genastore_done = true;
1799: returntail (mode != Dreg && mode != Areg);
1800:
1.1.1.4 root 1801: switch (mode) {
1802: case Dreg:
1803: switch (size) {
1804: case sz_byte:
1805: printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from);
1806: break;
1807: case sz_word:
1808: printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from);
1809: break;
1810: case sz_long:
1811: printf ("\tm68k_dreg (regs, %s) = (%s);\n", reg, from);
1812: break;
1813: default:
1.1.1.7 root 1814: term ();
1.1.1.4 root 1815: }
1816: break;
1817: case Areg:
1818: switch (size) {
1819: case sz_word:
1820: printf ("\tm68k_areg (regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from);
1821: break;
1822: case sz_long:
1823: printf ("\tm68k_areg (regs, %s) = (%s);\n", reg, from);
1824: break;
1825: default:
1.1.1.7 root 1826: term ();
1.1.1.4 root 1827: }
1828: break;
1829: case Aind:
1830: case Aipi:
1831: case Apdi:
1832: case Ad16:
1833: case Ad8r:
1834: case absw:
1835: case absl:
1836: case PC16:
1837: case PC8r:
1.1.1.7 root 1838: if (!(flags & GF_NOFAULTPC))
1839: gen_set_fault_pc ();
1840: if (using_ce020 || using_prefetch_020) {
1.1.1.4 root 1841: switch (size) {
1842: case sz_byte:
1843: printf ("\t%s (%sa, %s);\n", dstb, to, from);
1844: count_write++;
1845: break;
1846: case sz_word:
1847: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1848: term ();
1.1.1.4 root 1849: printf ("\t%s (%sa, %s);\n", dstw, to, from);
1850: count_write++;
1851: break;
1852: case sz_long:
1853: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1854: term ();
1.1.1.4 root 1855: printf ("\t%s (%sa, %s);\n", dstl, to, from);
1856: count_write += 2;
1857: break;
1858: default:
1.1.1.7 root 1859: term ();
1.1.1.4 root 1860: }
1861: } else if (using_ce) {
1862: switch (size) {
1863: case sz_byte:
1.1.1.7 root 1864: check_ipl_again();
1865: printf ("\tx_put_byte (%sa, %s);\n", to, from);
1.1.1.4 root 1866: count_write++;
1867: break;
1868: case sz_word:
1869: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1870: term ();
1871: check_ipl_again();
1872: printf ("\tx_put_word (%sa, %s);\n", to, from);
1.1.1.4 root 1873: count_write++;
1874: break;
1875: case sz_long:
1876: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1877: term ();
1878: if (store_dir) {
1879: printf ("\t%s (%sa + 2, %s);\n", dstw, to, from);
1880: check_ipl_again();
1881: printf ("%s (%sa, %s >> 16);\n", dstw, to, from);
1882: } else {
1883: printf ("\t%s (%sa, %s >> 16);\n", dstw, to, from);
1884: check_ipl_again();
1885: printf ("\t%s (%sa + 2, %s);\n", dstw, to, from);
1886: }
1.1.1.4 root 1887: count_write += 2;
1888: break;
1889: default:
1.1.1.7 root 1890: term ();
1.1.1.4 root 1891: }
1892: } else if (using_mmu) {
1893: switch (size) {
1894: case sz_byte:
1895: insn_n_cycles += 4;
1896: if (flags & GF_FC)
1.1.1.5 root 1897: printf ("\tdfc%s_put_byte (%sa, %s);\n", mmu_postfix, to, from);
1.1.1.4 root 1898: else
1.1.1.7 root 1899: printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstblrmw : (candormw ? dstbrmw : dstb), to, from);
1.1.1.4 root 1900: break;
1901: case sz_word:
1902: insn_n_cycles += 4;
1903: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1904: term ();
1.1.1.4 root 1905: if (flags & GF_FC)
1.1.1.5 root 1906: printf ("\tdfc%s_put_word (%sa, %s);\n", mmu_postfix, to, from);
1.1.1.4 root 1907: else
1.1.1.7 root 1908: printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstwlrmw : (candormw ? dstwrmw : dstw), to, from);
1.1.1.4 root 1909: break;
1910: case sz_long:
1911: insn_n_cycles += 8;
1912: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1913: term ();
1.1.1.4 root 1914: if (flags & GF_FC)
1.1.1.5 root 1915: printf ("\tdfc%s_put_long (%sa, %s);\n", mmu_postfix, to, from);
1.1.1.4 root 1916: else
1.1.1.7 root 1917: printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstllrmw : (candormw ? dstlrmw : dstl), to, from);
1918: break;
1919: default:
1920: term ();
1921: }
1922: } else if (using_prefetch) {
1923: switch (size) {
1924: case sz_byte:
1925: insn_n_cycles += 4;
1926: printf ("\t%s (%sa, %s);\n", dstb, to, from);
1927: count_write++;
1928: break;
1929: case sz_word:
1930: insn_n_cycles += 4;
1931: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1932: term ();
1933: printf ("\t%s (%sa, %s);\n", dstw, to, from);
1934: count_write++;
1935: break;
1936: case sz_long:
1937: insn_n_cycles += 8;
1938: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1939: term ();
1940: if (store_dir)
1941: printf ("\t%s (%sa + 2, %s); %s (%sa, %s >> 16);\n", dstw, to, from, dstw, to, from);
1942: else
1943: printf ("\t%s (%sa, %s >> 16); %s (%sa + 2, %s);\n", dstw, to, from, dstw, to, from);
1944: count_write += 2;
1.1.1.4 root 1945: break;
1946: default:
1.1.1.7 root 1947: term ();
1.1.1.4 root 1948: }
1949: } else {
1950: switch (size) {
1951: case sz_byte:
1952: insn_n_cycles += 4;
1.1.1.7 root 1953: printf ("\t%s (%sa, %s);\n", dstb, to, from);
1.1.1.4 root 1954: count_write++;
1955: break;
1956: case sz_word:
1957: insn_n_cycles += 4;
1958: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1959: term ();
1960: printf ("\t%s (%sa, %s);\n", dstw, to, from);
1.1.1.4 root 1961: count_write++;
1962: break;
1963: case sz_long:
1964: insn_n_cycles += 8;
1965: if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
1.1.1.7 root 1966: term ();
1967: printf ("\t%s (%sa, %s);\n", dstl, to, from);
1.1.1.4 root 1968: count_write += 2;
1969: break;
1970: default:
1.1.1.7 root 1971: term ();
1.1.1.4 root 1972: }
1973: }
1974: break;
1975: case imm:
1976: case imm0:
1977: case imm1:
1978: case imm2:
1979: case immi:
1.1.1.7 root 1980: term ();
1.1.1.4 root 1981: break;
1982: default:
1.1.1.7 root 1983: term ();
1.1.1.4 root 1984: }
1985: }
1986:
1987: static void genastore (const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
1988: {
1989: genastore_2 (from, mode, reg, size, to, 0, 0);
1990: }
1.1.1.7 root 1991: static void genastore_tas (const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
1992: {
1993: genastore_2 (from, mode, reg, size, to, 0, GF_LRMW);
1994: }
1995: static void genastore_cas (const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
1996: {
1997: genastore_2 (from, mode, reg, size, to, 0, GF_LRMW | GF_NOFAULTPC);
1998: }
1.1.1.4 root 1999: static void genastore_rev (const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
2000: {
2001: genastore_2 (from, mode, reg, size, to, 1, 0);
2002: }
2003: static void genastore_fc (const char *from, amodes mode, const char *reg, wordsizes size, const char *to)
2004: {
2005: genastore_2 (from, mode, reg, size, to, 1, GF_FC);
2006: }
2007:
1.1.1.7 root 2008: static void movem_mmu060 (const char *code, int size, bool put, bool aipi, bool apdi)
2009: {
2010: const char *index;
2011: int dphase;
2012: int i;
2013: if (apdi) {
2014: dphase = 1;
2015: index = "movem_index2";
2016: } else {
2017: dphase = 0;
2018: index = "movem_index1";
2019: }
2020:
2021: if (!put) {
2022: printf("\tuae_u32 tmp[16];\n");
2023: printf("\tint tmpreg[16];\n");
2024: printf("\tint idx = 0;\n");
2025: for (i = 0; i < 2; i++) {
2026: char reg;
2027: if (i == dphase)
2028: reg = 'd';
2029: else
2030: reg = 'a';
2031: printf ("\twhile (%cmask) {\n", reg);
2032: if (apdi)
2033: printf ("\t\tsrca -= %d;\n", size);
2034: printf ("\t\ttmpreg[idx] = %s[%cmask] + %d;\n", index, reg, i == dphase ? 0 : 8);
2035: printf ("\t\ttmp[idx++] = %s;\n", code);
2036: if (!apdi)
2037: printf ("\t\tsrca += %d;\n", size);
2038: printf ("\t\t%cmask = movem_next[%cmask];\n", reg, reg);
2039: printf ("\t}\n");
2040: }
2041: if (aipi || apdi)
2042: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2043: printf ("\twhile (--idx >= 0) {\n");
2044: printf ("\t\tregs.regs[tmpreg[idx]] = tmp[idx];\n");
2045: printf ("\t}\n");
2046: } else {
2047: for (i = 0; i < 2; i++) {
2048: char reg;
2049: if (i == dphase)
2050: reg = 'd';
2051: else
2052: reg = 'a';
2053: printf ("\twhile (%cmask) {\n", reg);
2054: if (apdi)
2055: printf ("\t\tsrca -= %d;\n", size);
2056: if (put) {
2057: printf ("\t\t%s, m68k_%creg (regs, %s[%cmask]));\n", code, reg, index, reg);
2058: } else {
2059: printf ("\t\tm68k_%creg (regs, %s[%cmask]) = %s;\n", reg, index, reg, code);
2060: }
2061: if (!apdi)
2062: printf ("\t\tsrca += %d;\n", size);
2063: printf ("\t\t%cmask = movem_next[%cmask];\n", reg, reg);
2064: printf ("\t}\n");
2065: }
2066: if (aipi || apdi)
2067: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2068: }
2069: }
2070:
2071: static bool mmu040_special_movem (uae_u16 opcode)
2072: {
2073: if (using_mmu != 68040)
2074: return false;
2075: return true;
2076: // return (((((opcode >> 3) & 7) == 7) && ((opcode & 7) == 2 || (opcode & 7) == 3)) || ((opcode >> 3) & 7) == 6);
2077: }
2078:
2079: static void movem_mmu040 (const char *code, int size, bool put, bool aipi, bool apdi, uae_u16 opcode)
2080: {
2081: const char *index;
2082: int dphase;
2083: int i;
2084:
2085: if (apdi) {
2086: dphase = 1;
2087: index = "movem_index2";
2088: } else {
2089: dphase = 0;
2090: index = "movem_index1";
2091: }
2092:
2093: printf ("\tmmu040_movem = 1;\n");
2094: printf ("\tmmu040_movem_ea = srca;\n");
2095:
2096: for (i = 0; i < 2; i++) {
2097: char reg;
2098: if (i == dphase)
2099: reg = 'd';
2100: else
2101: reg = 'a';
2102: printf ("\twhile (%cmask) {\n", reg);
2103: if (apdi)
2104: printf ("\t\tsrca -= %d;\n", size);
2105: if (put) {
2106: printf ("\t\t%s, m68k_%creg (regs, %s[%cmask]));\n", code, reg, index, reg);
2107: } else {
2108: printf ("\t\tm68k_%creg (regs, %s[%cmask]) = %s;\n", reg, index, reg, code);
2109: }
2110: if (!apdi)
2111: printf ("\t\tsrca += %d;\n", size);
2112: printf ("\t\t%cmask = movem_next[%cmask];\n", reg, reg);
2113: printf ("\t}\n");
2114: }
2115: if (aipi || apdi)
2116: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2117: printf ("\tmmu040_movem = 0;\n");
2118: }
2119:
2120: /* 68030 MMU does not restore register state if it bus faults.
2121: * (also there wouldn't be enough space in stack frame to store all registers)
2122: */
2123: static void movem_mmu030 (const char *code, int size, bool put, bool aipi, bool apdi)
2124: {
2125: const char *index;
2126: int dphase;
2127: int i;
2128: if (apdi) {
2129: dphase = 1;
2130: index = "movem_index2";
2131: } else {
2132: dphase = 0;
2133: index = "movem_index1";
2134: }
2135: printf ("\tmmu030_state[1] |= MMU030_STATEFLAG1_MOVEM1;\n");
2136: printf ("\tint movem_cnt = 0;\n");
2137: if (!put) {
2138: printf ("\tuae_u32 val;\n");
2139: printf ("\tif (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2)\n");
2140: printf ("\t\tsrca = mmu030_ad[mmu030_idx].val;\n");
2141: printf ("\telse\n");
2142: printf ("\t\tmmu030_ad[mmu030_idx].val = srca;\n");
2143: }
2144: for (i = 0; i < 2; i++) {
2145: char reg;
2146: if (i == dphase)
2147: reg = 'd';
2148: else
2149: reg = 'a';
2150: printf ("\twhile (%cmask) {\n", reg);
2151: if (apdi)
2152: printf ("\t\tsrca -= %d;\n", size);
2153: printf ("\t\tif (mmu030_state[0] == movem_cnt) {\n");
2154: printf ("\t\t\tif (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {\n");
2155: printf ("\t\t\t\tmmu030_state[1] &= ~MMU030_STATEFLAG1_MOVEM2;\n");
2156: if (!put)
2157: printf ("\t\t\t\tval = %smmu030_data_buffer;\n", size == 2 ? "(uae_s32)(uae_s16)" : "");
2158: printf ("\t\t\t} else {\n");
2159: if (put)
2160: printf ("\t\t\t\t%s, (mmu030_data_buffer = m68k_%creg (regs, %s[%cmask])));\n", code, reg, index, reg);
2161: else
2162: printf ("\t\t\t\tval = %s;\n", code);
2163: printf ("\t\t\t}\n");
2164: if (!put) {
2165: printf ("\t\t\tm68k_%creg (regs, %s[%cmask]) = val;\n", reg, index, reg);
2166: }
2167: printf ("\t\t\tmmu030_state[0]++;\n");
2168: printf ("\t\t}\n");
2169: if (!apdi)
2170: printf ("\t\tsrca += %d;\n", size);
2171: printf ("\t\tmovem_cnt++;\n");
2172: printf ("\t\t%cmask = movem_next[%cmask];\n", reg, reg);
2173: printf ("\t}\n");
2174: }
2175: if (aipi || apdi)
2176: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2177: }
2178:
1.1.1.4 root 2179: static void genmovemel (uae_u16 opcode)
2180: {
2181: char getcode[100];
2182: int size = table68k[opcode].size == sz_long ? 4 : 2;
2183:
2184: if (table68k[opcode].size == sz_long) {
1.1.1.7 root 2185: sprintf (getcode, "%s (srca)", srcld);
1.1.1.4 root 2186: } else {
1.1.1.7 root 2187: sprintf (getcode, "(uae_s32)(uae_s16)%s (srca)", srcwd);
1.1.1.4 root 2188: }
2189: count_read += table68k[opcode].size == sz_long ? 2 : 1;
2190: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1.1.1.7 root 2191: printf ("\tuae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
2192: genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, GF_MOVE);
2193: addcycles_ce020 (8 - 2);
1.1.1.4 root 2194: start_brace ();
1.1.1.7 root 2195: if (using_mmu == 68030) {
2196: movem_mmu030 (getcode, size, false, table68k[opcode].dmode == Aipi, false);
2197: } else if (using_mmu == 68060) {
2198: movem_mmu060 (getcode, size, false, table68k[opcode].dmode == Aipi, false);
2199: } else if (using_mmu == 68040) {
2200: movem_mmu040 (getcode, size, false, table68k[opcode].dmode == Aipi, false, opcode);
2201: } else {
2202: printf ("\twhile (dmask) {\n");
2203: printf ("\t\tm68k_dreg (regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask];\n", getcode, size);
2204: //addcycles_ce020 (1);
2205: printf ("\t}\n");
2206: printf ("\twhile (amask) {\n");
2207: printf ("\t\tm68k_areg (regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask];\n", getcode, size);
2208: //addcycles_ce020 (1);
2209: printf ("\t}\n");
2210: if (table68k[opcode].dmode == Aipi) {
2211: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2212: count_read++;
2213: }
1.1.1.4 root 2214: }
2215: count_ncycles++;
2216: fill_prefetch_next ();
1.1.1.7 root 2217: get_prefetch_020 ();
1.1.1.4 root 2218: }
2219:
2220: static void genmovemel_ce (uae_u16 opcode)
2221: {
2222: int size = table68k[opcode].size == sz_long ? 4 : 2;
2223: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1.1.1.7 root 2224: printf ("\tuae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1.1.1.4 root 2225: printf ("\tuae_u32 v;\n");
2226: if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
2227: addcycles000 (2);
1.1.1.7 root 2228: genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA | GF_MOVE);
1.1.1.4 root 2229: start_brace ();
2230: if (table68k[opcode].size == sz_long) {
1.1.1.7 root 2231: printf ("\twhile (dmask) {\n");
2232: printf ("\t\tv = %s (srca) << 16;\n", srcw);
2233: printf ("\t\tv |= %s (srca + 2);\n", srcw);
2234: printf ("\t\tm68k_dreg (regs, movem_index1[dmask]) = v;\n");
2235: printf ("\t\tsrca += %d;\n", size);
2236: printf ("\t\tdmask = movem_next[dmask];\n");
2237: addcycles000_nonce("\t\t", 8);
2238: printf ("\t}\n");
2239: printf ("\twhile (amask) {\n");
2240: printf ("\t\tv = %s (srca) << 16;\n", srcw);
2241: printf ("\t\tv |= %s (srca + 2);\n", srcw);
2242: printf ("\t\tm68k_areg (regs, movem_index1[amask]) = v;\n");
2243: printf ("\t\tsrca += %d;\n", size);
2244: printf ("\t\tamask = movem_next[amask];\n");
2245: addcycles000_nonce("\t\t", 8);
2246: printf ("\t}\n");
1.1.1.4 root 2247: } else {
1.1.1.7 root 2248: printf ("\twhile (dmask) {\n");
2249: printf ("\t\tm68k_dreg (regs, movem_index1[dmask]) = (uae_s32)(uae_s16)%s (srca);\n", srcw);
2250: printf ("\t\tsrca += %d;\n", size);
2251: printf ("\t\tdmask = movem_next[dmask];\n");
2252: addcycles000_nonce("\t\t", 4);
2253: printf ("\t}\n");
2254: printf ("\twhile (amask) {\n");
2255: printf ("\t\tm68k_areg (regs, movem_index1[amask]) = (uae_s32)(uae_s16)%s (srca);\n", srcw);
2256: printf ("\t\tsrca += %d;\n", size);
2257: printf ("\t\tamask = movem_next[amask];\n");
2258: addcycles000_nonce("\t\t", 4);
2259: printf ("\t}\n");
1.1.1.4 root 2260: }
1.1.1.7 root 2261: printf ("\t%s (srca);\n", srcw); // and final extra word fetch that goes nowhere..
1.1.1.4 root 2262: count_read++;
2263: if (table68k[opcode].dmode == Aipi)
2264: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2265: count_ncycles++;
2266: fill_prefetch_next ();
2267: }
2268:
2269: static void genmovemle (uae_u16 opcode)
2270: {
2271: char putcode[100];
2272: int size = table68k[opcode].size == sz_long ? 4 : 2;
2273:
2274: if (table68k[opcode].size == sz_long) {
1.1.1.7 root 2275: sprintf (putcode, "%s (srca", dstld);
1.1.1.4 root 2276: } else {
1.1.1.7 root 2277: sprintf (putcode, "%s (srca", dstwd);
1.1.1.4 root 2278: }
2279: count_write += table68k[opcode].size == sz_long ? 2 : 1;
2280:
2281: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
1.1.1.7 root 2282: genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, GF_MOVE);
2283: addcycles_ce020 (4 - 2);
1.1.1.4 root 2284: start_brace ();
1.1.1.7 root 2285: if (using_mmu >= 68030) {
2286: if (table68k[opcode].dmode == Apdi)
2287: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
2288: else
2289: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
2290: if (using_mmu == 68030)
2291: movem_mmu030 (putcode, size, true, false, table68k[opcode].dmode == Apdi);
2292: else if (using_mmu == 68060)
2293: movem_mmu060 (putcode, size, true, false, table68k[opcode].dmode == Apdi);
2294: else if (using_mmu == 68040)
2295: movem_mmu040 (putcode, size, true, false, table68k[opcode].dmode == Apdi, opcode);
1.1.1.4 root 2296: } else {
1.1.1.7 root 2297: if (table68k[opcode].dmode == Apdi) {
2298: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
2299: if (!using_mmu)
2300: printf ("\tint type = get_cpu_model () >= 68020;\n");
2301: printf ("\twhile (amask) {\n");
2302: printf ("\t\tsrca -= %d;\n", size);
2303:
2304: printf ("\t\tif (!type || movem_index2[amask] != dstreg)\n");
2305: printf ("\t\t\t%s, m68k_areg (regs, movem_index2[amask]));\n", putcode);
2306: printf ("\t\telse\n");
2307: printf ("\t\t\t%s, m68k_areg (regs, movem_index2[amask]) - %d);\n", putcode, size);
1.1.1.4 root 2308:
1.1.1.7 root 2309: printf ("\t\tamask = movem_next[amask];\n");
2310: printf ("\t}\n");
2311: printf ("\twhile (dmask) { srca -= %d; %s, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
2312: size, putcode);
2313: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2314: } else {
2315: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
2316: printf ("\twhile (dmask) { %s, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
2317: putcode, size);
2318: printf ("\twhile (amask) { %s, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
2319: putcode, size);
2320: }
1.1.1.4 root 2321: }
1.1.1.7 root 2322: count_ncycles++;
1.1.1.4 root 2323: fill_prefetch_next ();
1.1.1.7 root 2324: get_prefetch_020 ();
1.1.1.4 root 2325: }
2326:
2327: static void genmovemle_ce (uae_u16 opcode)
2328: {
2329: int size = table68k[opcode].size == sz_long ? 4 : 2;
2330:
1.1.1.7 root 2331: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
2332: if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
1.1.1.4 root 2333: addcycles000 (2);
1.1.1.7 root 2334: genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA | GF_MOVE);
1.1.1.4 root 2335: start_brace ();
2336: if (table68k[opcode].size == sz_long) {
2337: if (table68k[opcode].dmode == Apdi) {
2338: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
1.1.1.7 root 2339: printf ("\twhile (amask) {\n");
2340: printf ("\t\tsrca -= %d;\n", size);
2341: printf ("\t\t%s (srca, m68k_areg (regs, movem_index2[amask]) >> 16);\n", dstw);
2342: printf ("\t\t%s (srca + 2, m68k_areg (regs, movem_index2[amask]));\n", dstw);
2343: printf ("\t\tamask = movem_next[amask];\n");
2344: addcycles000_nonce("\t\t", 8);
2345: printf ("\t}\n");
2346: printf ("\twhile (dmask) {\n");
2347: printf ("\t\tsrca -= %d;\n", size);
2348: printf ("\t\t%s (srca, m68k_dreg (regs, movem_index2[dmask]) >> 16);\n", dstw);
2349: printf ("\t\t%s (srca + 2, m68k_dreg (regs, movem_index2[dmask]));\n", dstw);
2350: printf ("\t\tdmask = movem_next[dmask];\n");
2351: addcycles000_nonce("\t\t", 8);
2352: printf ("\t}\n");
1.1.1.4 root 2353: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2354: } else {
2355: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1.1.1.7 root 2356: printf ("\twhile (dmask) {\n");
2357: printf ("\t\t%s (srca, m68k_dreg (regs, movem_index1[dmask]) >> 16);\n", dstw);
2358: printf ("\t\t%s (srca + 2, m68k_dreg (regs, movem_index1[dmask]));\n", dstw);
2359: printf ("\t\tsrca += %d;\n", size);
2360: printf ("\t\tdmask = movem_next[dmask];\n");
2361: addcycles000_nonce("\t\t", 8);
2362: printf ("\t}\n");
2363: printf ("\twhile (amask) {\n");
2364: printf ("\t\t%s (srca, m68k_areg (regs, movem_index1[amask]) >> 16);\n", dstw);
2365: printf ("\t\t%s (srca + 2, m68k_areg (regs, movem_index1[amask]));\n", dstw);
2366: printf ("\t\tsrca += %d;\n", size);
2367: printf ("\t\tamask = movem_next[amask];\n");
2368: addcycles000_nonce("\t\t", 8);
2369: printf ("\t}\n");
1.1.1.4 root 2370: }
2371: } else {
2372: if (table68k[opcode].dmode == Apdi) {
2373: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
1.1.1.7 root 2374: printf ("\twhile (amask) {\n");
2375: printf ("\t\tsrca -= %d;\n", size);
2376: printf ("\t\t%s (srca, m68k_areg (regs, movem_index2[amask]));\n", dstw);
2377: printf ("\tamask = movem_next[amask];\n");
2378: addcycles000_nonce("\t\t", 4);
2379: printf ("\t}\n");
2380: printf ("\twhile (dmask) {\n");
2381: printf ("\t\tsrca -= %d;\n", size);
2382: printf ("\t\t%s (srca, m68k_dreg (regs, movem_index2[dmask]));\n", dstw);
2383: printf ("\t\tdmask = movem_next[dmask];\n");
2384: addcycles000_nonce("\t\t", 4);
2385: printf ("\t}\n");
1.1.1.4 root 2386: printf ("\tm68k_areg (regs, dstreg) = srca;\n");
2387: } else {
2388: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
1.1.1.7 root 2389: printf ("\twhile (dmask) {\n");
2390: printf ("\t\t%s (srca, m68k_dreg (regs, movem_index1[dmask]));\n", dstw);
2391: printf ("\t\tsrca += %d;\n", size);
2392: printf ("\t\tdmask = movem_next[dmask];\n");
2393: addcycles000_nonce("\t\t", 4);
2394: printf ("\t}\n");
2395: printf ("\twhile (amask) {\n");
2396: printf ("\t\t%s (srca, m68k_areg (regs, movem_index1[amask]));\n", dstw);
2397: printf ("\t\tsrca += %d;\n", size);
2398: printf ("\t\tamask = movem_next[amask];\n");
2399: addcycles000_nonce("\t\t", 4);
2400: printf ("\t}\n");
1.1.1.4 root 2401: }
2402: }
2403: count_ncycles++;
2404: fill_prefetch_next ();
2405: }
2406:
2407: static void duplicate_carry (int n)
2408: {
2409: int i;
2410: for (i = 0; i <= n; i++)
2411: printf ("\t");
2412: printf ("COPY_CARRY ();\n");
2413: }
2414:
2415: typedef enum
2416: {
2417: flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn,
2418: flag_av, flag_sv
2419: }
2420: flagtypes;
2421:
2422: static void genflags_normal (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
2423: {
2424: char vstr[100], sstr[100], dstr[100];
2425: char usstr[100], udstr[100];
2426: char unsstr[100], undstr[100];
2427:
2428: switch (size) {
2429: case sz_byte:
2430: strcpy (vstr, "((uae_s8)(");
2431: strcpy (usstr, "((uae_u8)(");
2432: break;
2433: case sz_word:
2434: strcpy (vstr, "((uae_s16)(");
2435: strcpy (usstr, "((uae_u16)(");
2436: break;
2437: case sz_long:
2438: strcpy (vstr, "((uae_s32)(");
2439: strcpy (usstr, "((uae_u32)(");
2440: break;
2441: default:
1.1.1.7 root 2442: term ();
1.1.1.4 root 2443: }
2444: strcpy (unsstr, usstr);
2445:
2446: strcpy (sstr, vstr);
2447: strcpy (dstr, vstr);
2448: strcat (vstr, value);
2449: strcat (vstr, "))");
2450: strcat (dstr, dst);
2451: strcat (dstr, "))");
2452: strcat (sstr, src);
2453: strcat (sstr, "))");
2454:
2455: strcpy (udstr, usstr);
2456: strcat (udstr, dst);
2457: strcat (udstr, "))");
2458: strcat (usstr, src);
2459: strcat (usstr, "))");
2460:
2461: strcpy (undstr, unsstr);
2462: strcat (unsstr, "-");
2463: strcat (undstr, "~");
2464: strcat (undstr, dst);
2465: strcat (undstr, "))");
2466: strcat (unsstr, src);
2467: strcat (unsstr, "))");
2468:
2469: switch (type) {
2470: case flag_logical_noclobber:
2471: case flag_logical:
2472: case flag_z:
2473: case flag_zn:
2474: case flag_av:
2475: case flag_sv:
2476: case flag_addx:
2477: case flag_subx:
2478: break;
2479:
2480: case flag_add:
2481: start_brace ();
1.1.1.7 root 2482: printf ("uae_u32 %s = %s + %s;\n", value, udstr, usstr);
1.1.1.4 root 2483: break;
2484: case flag_sub:
2485: case flag_cmp:
2486: start_brace ();
1.1.1.7 root 2487: printf ("uae_u32 %s = %s - %s;\n", value, udstr, usstr);
1.1.1.4 root 2488: break;
2489: }
2490:
2491: switch ((int)type) {
2492: case flag_logical_noclobber:
2493: case flag_logical:
2494: case flag_zn:
2495: break;
2496:
2497: case flag_add:
2498: case flag_sub:
2499: case flag_addx:
2500: case flag_subx:
2501: case flag_cmp:
2502: case flag_av:
2503: case flag_sv:
2504: start_brace ();
2505: printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr);
2506: printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr);
2507: printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr);
2508: break;
2509: }
2510:
2511: switch (type) {
2512: case flag_logical:
2513: printf ("\tCLEAR_CZNV ();\n");
1.1.1.7 root 2514: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
2515: printf ("\tSET_NFLG (%s < 0);\n", vstr);
1.1.1.4 root 2516: break;
2517: case flag_logical_noclobber:
2518: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
2519: printf ("\tSET_NFLG (%s < 0);\n", vstr);
2520: break;
2521: case flag_av:
2522: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
2523: break;
2524: case flag_sv:
2525: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
2526: break;
2527: case flag_z:
2528: printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
2529: break;
2530: case flag_zn:
2531: printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr);
2532: printf ("\tSET_NFLG (%s < 0);\n", vstr);
2533: break;
2534: case flag_add:
2535: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
2536: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n");
2537: printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr);
2538: duplicate_carry (0);
2539: printf ("\tSET_NFLG (flgn != 0);\n");
2540: break;
2541: case flag_sub:
2542: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
2543: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n");
2544: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
2545: duplicate_carry (0);
2546: printf ("\tSET_NFLG (flgn != 0);\n");
2547: break;
2548: case flag_addx:
2549: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */
2550: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */
2551: duplicate_carry (0);
2552: break;
2553: case flag_subx:
2554: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */
2555: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */
2556: duplicate_carry (0);
2557: break;
2558: case flag_cmp:
2559: printf ("\tSET_ZFLG (%s == 0);\n", vstr);
2560: printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n");
2561: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr);
2562: printf ("\tSET_NFLG (flgn != 0);\n");
2563: break;
2564: }
2565: }
2566:
2567: static void genflags (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst)
2568: {
2569: /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have
2570: them in the appropriate m68k.h files and use just one copy of this
2571: code here. The API can be changed if necessary. */
2572: if (optimized_flags) {
2573: switch (type) {
2574: case flag_add:
2575: case flag_sub:
2576: start_brace ();
2577: printf ("\tuae_u32 %s;\n", value);
2578: break;
2579:
2580: default:
2581: break;
2582: }
2583:
2584: /* At least some of those casts are fairly important! */
2585: switch (type) {
2586: case flag_logical_noclobber:
2587: printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n");
2588: if (strcmp (value, "0") == 0) {
2589: printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n");
2590: } else {
1.1.1.7 root 2591: switch ((int)size) {
1.1.1.4 root 2592: case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
2593: case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
2594: case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
2595: }
2596: printf ("\tIOR_CZNV (oldcznv);\n");
2597: }
2598: printf ("\t}\n");
2599: return;
2600: case flag_logical:
2601: if (strcmp (value, "0") == 0) {
2602: printf ("\tSET_CZNV (FLAGVAL_Z);\n");
2603: } else {
1.1.1.7 root 2604: switch ((int)size) {
1.1.1.4 root 2605: case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break;
2606: case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break;
2607: case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break;
2608: }
2609: }
2610: return;
2611:
2612: case flag_add:
1.1.1.7 root 2613: switch ((int)size) {
1.1.1.4 root 2614: case sz_byte: printf ("\toptflag_addb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
2615: case sz_word: printf ("\toptflag_addw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
2616: case sz_long: printf ("\toptflag_addl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
2617: }
2618: return;
2619:
2620: case flag_sub:
1.1.1.7 root 2621: switch ((int)size) {
1.1.1.4 root 2622: case sz_byte: printf ("\toptflag_subb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
2623: case sz_word: printf ("\toptflag_subw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
2624: case sz_long: printf ("\toptflag_subl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
2625: }
2626: return;
2627:
2628: case flag_cmp:
1.1.1.7 root 2629: switch ((int)size) {
1.1.1.4 root 2630: case sz_byte: printf ("\toptflag_cmpb (regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
2631: case sz_word: printf ("\toptflag_cmpw (regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
2632: case sz_long: printf ("\toptflag_cmpl (regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
2633: }
2634: return;
2635:
2636: default:
2637: break;
2638: }
2639: }
2640:
2641: genflags_normal (type, size, value, src, dst);
2642: }
2643:
2644: static void force_range_for_rox (const char *var, wordsizes size)
2645: {
2646: /* Could do a modulo operation here... which one is faster? */
1.1.1.7 root 2647: switch ((int)size) {
1.1.1.4 root 2648: case sz_long:
2649: printf ("\tif (%s >= 33) %s -= 33;\n", var, var);
2650: break;
2651: case sz_word:
2652: printf ("\tif (%s >= 34) %s -= 34;\n", var, var);
2653: printf ("\tif (%s >= 17) %s -= 17;\n", var, var);
2654: break;
2655: case sz_byte:
2656: printf ("\tif (%s >= 36) %s -= 36;\n", var, var);
2657: printf ("\tif (%s >= 18) %s -= 18;\n", var, var);
2658: printf ("\tif (%s >= 9) %s -= 9;\n", var, var);
2659: break;
2660: }
2661: }
2662:
2663: static const char *cmask (wordsizes size)
2664: {
2665: switch (size) {
2666: case sz_byte: return "0x80";
2667: case sz_word: return "0x8000";
2668: case sz_long: return "0x80000000";
1.1.1.7 root 2669: default: term ();
1.1.1.4 root 2670: }
2671: }
2672:
2673: static int source_is_imm1_8 (struct instr *i)
2674: {
2675: return i->stype == 3;
2676: }
2677:
2678: static void shift_ce (amodes dmode, int size)
2679: {
1.1.1.7 root 2680: if (isreg (dmode)) {
1.1.1.4 root 2681: int c = size == sz_long ? 4 : 2;
1.1.1.7 root 2682: if (using_ce) {
2683: printf ("\t{\n");
2684: printf ("\t\tint cycles = %d;\n", c);
2685: printf ("\t\tcycles += 2 * ccnt;\n");
2686: addcycles000_3 ("\t\t");
2687: printf ("\t}\n");
2688: }
2689: addcycles000_nonces("\t", "2 * ccnt");
1.1.1.4 root 2690: count_cycles += c;
1.1.1.7 root 2691: count_ncycles++;
1.1.1.4 root 2692: }
2693: }
2694:
1.1.1.7 root 2695: // BCHG/BSET/BCLR Dx,Dx or #xx,Dx adds 2 cycles if bit number > 15
1.1.1.4 root 2696: static void bsetcycles (struct instr *curi)
2697: {
2698: if (curi->size == sz_byte) {
2699: printf ("\tsrc &= 7;\n");
2700: } else {
2701: printf ("\tsrc &= 31;\n");
2702: if (isreg (curi->dmode)) {
2703: addcycles000 (2);
1.1.1.7 root 2704: if (curi->mnemo != i_BTST) {
2705: if (using_ce)
2706: printf ("\tif (src > 15) %s (2);\n", do_cycles);
2707: addcycles000_nonce("\tif (src > 15) ", 2);
1.1.1.4 root 2708: count_ncycles++;
2709: }
2710: }
2711: }
2712: }
2713:
2714: static int islongimm (struct instr *curi)
2715: {
1.1.1.7 root 2716: return (curi->size == sz_long && (curi->smode == Dreg || curi->smode == imm || curi->smode == Areg));
1.1.1.4 root 2717: }
2718:
2719:
1.1.1.7 root 2720: static void resetvars (void)
2721: {
1.1.1.4 root 2722: insn_n_cycles = using_prefetch ? 0 : 4;
1.1.1.7 root 2723: insn_n_cycles020 = 0;
2724: genamode_cnt = 0;
2725: genamode8r_offset[0] = genamode8r_offset[1] = 0;
2726: m68k_pc_total = 0;
2727: branch_inst = 0;
2728:
2729: ir2irc = 0;
2730: mmufixupcnt = 0;
2731: mmufixupstate = 0;
2732: disp020cnt = 0;
2733: candormw = false;
2734: genastore_done = false;
2735: rmw_varname[0] = 0;
2736: tail_ce020 = 0;
2737: total_ce020 = 0;
2738: tail_ce020_done = false;
2739: head_in_ea_ce020 = 0;
2740: head_ce020_cycs_done = false;
2741: no_prefetch_ce020 = false;
2742: got_ea_ce020 = false;
2743:
2744: prefetch_long = NULL;
2745: srcli = NULL;
2746: srcbi = NULL;
2747: disp000 = "get_disp_ea_000";
2748: disp020 = "get_disp_ea_020";
2749: nextw = NULL;
2750: nextl = NULL;
2751: do_cycles = "do_cycles";
2752: srcwd = srcld = NULL;
2753: dstwd = dstld = NULL;
2754: srcblrmw = NULL;
2755: srcwlrmw = NULL;
2756: srcllrmw = NULL;
2757: dstblrmw = NULL;
2758: dstwlrmw = NULL;
2759: dstllrmw = NULL;
2760: getpc = "m68k_getpc ()";
2761:
1.1.1.8 ! root 2762: if (using_indirect > 0) {
1.1.1.7 root 2763: // tracer
2764: getpc = "m68k_getpci ()";
2765: if (!using_ce020 && !using_prefetch_020 && !using_ce) {
2766: // generic + indirect
2767: disp020 = "x_get_disp_ea_020";
2768: prefetch_long = "get_iilong_jit";
2769: prefetch_word = "get_iiword_jit";
2770: nextw = "next_iiword_jit";
2771: nextl = "next_iilong_jit";
2772: srcli = "get_iilong_jit";
2773: srcwi = "get_iiword_jit";
2774: srcbi = "get_iibyte_jit";
2775: srcl = "x_get_long";
2776: dstl = "x_put_long";
2777: srcw = "x_get_word";
2778: dstw = "x_put_word";
2779: srcb = "x_get_byte";
2780: dstb = "x_put_byte";
2781: getpc = "m68k_getpc()"; // special jit support
2782: } else if (!using_ce020 && !using_prefetch_020) {
2783: prefetch_word = "get_word_ce000_prefetch";
2784: srcli = "x_get_ilong";
2785: srcwi = "x_get_iword";
2786: srcbi = "x_get_ibyte";
2787: srcl = "x_get_long";
2788: dstl = "x_put_long";
2789: srcw = "x_get_word";
2790: dstw = "x_put_word";
2791: srcb = "x_get_byte";
2792: dstb = "x_put_byte";
2793: do_cycles = "do_cycles_ce000_internal";
2794: } else if (using_ce020 == 1) {
2795: /* x_ not used if it redirects to
2796: * get_word_ce020_prefetch()
2797: */
2798: disp020 = "x_get_disp_ea_ce020";
2799: prefetch_word = "get_word_ce020_prefetch";
2800: prefetch_long = "get_long_ce020_prefetch";
2801: srcli = "x_get_ilong";
2802: srcwi = "x_get_iword";
2803: srcbi = "x_get_ibyte";
2804: srcl = "x_get_long";
2805: dstl = "x_put_long";
2806: srcw = "x_get_word";
2807: dstw = "x_put_word";
2808: srcb = "x_get_byte";
2809: dstb = "x_put_byte";
2810: do_cycles = "do_cycles_ce020_internal";
2811: nextw = "next_iword_020ce";
2812: nextl = "next_ilong_020ce";
2813: } else if (using_ce020 == 2) {
2814: // 68030 CE
2815: disp020 = "x_get_disp_ea_ce030";
2816: prefetch_long = "get_long_ce030_prefetch";
2817: prefetch_word = "get_word_ce030_prefetch";
2818: srcli = "x_get_ilong";
2819: srcwi = "x_get_iword";
2820: srcbi = "x_get_ibyte";
2821: srcl = "x_get_long";
2822: dstl = "x_put_long";
2823: srcw = "x_get_word";
2824: dstw = "x_put_word";
2825: srcb = "x_get_byte";
2826: dstb = "x_put_byte";
2827: do_cycles = "do_cycles_ce020_internal";
2828: nextw = "next_iword_030ce";
2829: nextl = "next_ilong_030ce";
2830: } else if (using_ce020 == 3) {
2831: // 68040/060 CE
2832: disp020 = "x_get_disp_ea_040";
2833: prefetch_long = "get_ilong_cache_040";
2834: prefetch_word = "get_iword_cache_040";
2835: srcli = "x_get_ilong";
2836: srcwi = "x_get_iword";
2837: srcbi = "x_get_ibyte";
2838: srcl = "x_get_long";
2839: dstl = "x_put_long";
2840: srcw = "x_get_word";
2841: dstw = "x_put_word";
2842: srcb = "x_get_byte";
2843: dstb = "x_put_byte";
2844: do_cycles = "do_cycles_ce020_internal";
2845: nextw = "next_iword_cache040";
2846: nextl = "next_ilong_cache040";
2847: } else if (using_prefetch_020 == 1) {
2848: disp020 = "x_get_disp_ea_020";
2849: prefetch_word = "get_word_020_prefetch";
2850: prefetch_long = "get_long_020_prefetch";
2851: srcli = "x_get_ilong";
2852: srcwi = "x_get_iword";
2853: srcbi = "x_get_ibyte";
2854: srcl = "x_get_long";
2855: dstl = "x_put_long";
2856: srcw = "x_get_word";
2857: dstw = "x_put_word";
2858: srcb = "x_get_byte";
2859: dstb = "x_put_byte";
2860: nextw = "next_iword_020_prefetch";
2861: nextl = "next_ilong_020_prefetch";
2862: } else if (using_prefetch_020 == 2) {
2863: disp020 = "x_get_disp_ea_020";
2864: prefetch_word = "get_word_030_prefetch";
2865: prefetch_long = "get_long_030_prefetch";
2866: srcli = "x_get_ilong";
2867: srcwi = "x_get_iword";
2868: srcbi = "x_get_ibyte";
2869: srcl = "x_get_long";
2870: dstl = "x_put_long";
2871: srcw = "x_get_word";
2872: dstw = "x_put_word";
2873: srcb = "x_get_byte";
2874: dstb = "x_put_byte";
2875: nextw = "next_iword_030_prefetch";
2876: nextl = "next_ilong_030_prefetch";
2877: }
2878: #if 0
2879: } else if (using_ce020) {
2880: disp020 = "x_get_disp_ea_020";
2881: do_cycles = "do_cycles_ce020";
1.1.1.4 root 2882: if (using_ce020 == 2) {
1.1.1.7 root 2883: // 68030/40/60 CE
2884: prefetch_long = "get_long_ce030_prefetch";
2885: prefetch_word = "get_word_ce030_prefetch";
2886: nextw = "next_iword_030ce";
2887: nextl = "next_ilong_030ce";
2888: srcli = "get_word_ce030_prefetch";
2889: srcwi = "get_long_ce030_prefetch";
1.1.1.4 root 2890: srcl = "get_long_ce030";
2891: dstl = "put_long_ce030";
2892: srcw = "get_word_ce030";
2893: dstw = "put_word_ce030";
2894: srcb = "get_byte_ce030";
2895: dstb = "put_byte_ce030";
2896: } else {
1.1.1.7 root 2897: // 68020 CE
2898: prefetch_long = "get_long_ce020_prefetch";
2899: prefetch_word = "get_word_ce020_prefetch";
2900: nextw = "next_iword_020ce";
2901: nextl = "next_ilong_020ce";
2902: srcli = "get_word_ce020_prefetch";
2903: srcwi = "get_long_ce020_prefetch";
1.1.1.4 root 2904: srcl = "get_long_ce020";
2905: dstl = "put_long_ce020";
2906: srcw = "get_word_ce020";
2907: dstw = "put_word_ce020";
2908: srcb = "get_byte_ce020";
2909: dstb = "put_byte_ce020";
2910: }
1.1.1.7 root 2911: #endif
2912: } else if (using_mmu == 68030) {
2913: // 68030 MMU
2914: disp020 = "get_disp_ea_020_mmu030";
2915: prefetch_long = "get_ilong_mmu030_state";
2916: prefetch_word = "get_iword_mmu030_state";
2917: nextw = "next_iword_mmu030_state";
2918: nextl = "next_ilong_mmu030_state";
2919: srcli = "get_ilong_mmu030_state";
2920: srcwi = "get_iword_mmu030_state";
2921: srcbi = "get_ibyte_mmu030_state";
2922: srcl = "get_long_mmu030_state";
2923: dstl = "put_long_mmu030_state";
2924: srcw = "get_word_mmu030_state";
2925: dstw = "put_word_mmu030_state";
2926: srcb = "get_byte_mmu030_state";
2927: dstb = "put_byte_mmu030_state";
2928: srcblrmw = "get_lrmw_byte_mmu030_state";
2929: srcwlrmw = "get_lrmw_word_mmu030_state";
2930: srcllrmw = "get_lrmw_long_mmu030_state";
2931: dstblrmw = "put_lrmw_byte_mmu030_state";
2932: dstwlrmw = "put_lrmw_word_mmu030_state";
2933: dstllrmw = "put_lrmw_long_mmu030_state";
2934: srcld = "get_long_mmu030";
2935: srcwd = "get_word_mmu030";
2936: dstld = "put_long_mmu030";
2937: dstwd = "put_word_mmu030";
2938: getpc = "m68k_getpci ()";
2939: } else if (using_mmu == 68040) {
2940: // 68040 MMU
2941: disp020 = "x_get_disp_ea_020";
2942: prefetch_long = "get_ilong_mmu040";
2943: prefetch_word = "get_iword_mmu040";
2944: nextw = "next_iword_mmu040";
2945: nextl = "next_ilong_mmu040";
2946: srcli = "get_ilong_mmu040";
2947: srcwi = "get_iword_mmu040";
2948: srcbi = "get_ibyte_mmu040";
2949: srcl = "get_long_mmu040";
2950: dstl = "put_long_mmu040";
2951: srcw = "get_word_mmu040";
2952: dstw = "put_word_mmu040";
2953: srcb = "get_byte_mmu040";
2954: dstb = "put_byte_mmu040";
2955: srcblrmw = "get_lrmw_byte_mmu040";
2956: srcwlrmw = "get_lrmw_word_mmu040";
2957: srcllrmw = "get_lrmw_long_mmu040";
2958: dstblrmw = "put_lrmw_byte_mmu040";
2959: dstwlrmw = "put_lrmw_word_mmu040";
2960: dstllrmw = "put_lrmw_long_mmu040";
2961: getpc = "m68k_getpci ()";
1.1.1.4 root 2962: } else if (using_mmu) {
1.1.1.7 root 2963: // 68060 MMU
2964: disp020 = "x_get_disp_ea_020";
2965: prefetch_long = "get_ilong_mmu060";
2966: prefetch_word = "get_iword_mmu060";
2967: nextw = "next_iword_mmu060";
2968: nextl = "next_ilong_mmu060";
2969: srcli = "get_ilong_mmu060";
2970: srcwi = "get_iword_mmu060";
2971: srcbi = "get_ibyte_mmu060";
2972: srcl = "get_long_mmu060";
2973: dstl = "put_long_mmu060";
2974: srcw = "get_word_mmu060";
2975: dstw = "put_word_mmu060";
2976: srcb = "get_byte_mmu060";
2977: dstb = "put_byte_mmu060";
2978: srcblrmw = "get_lrmw_byte_mmu060";
2979: srcwlrmw = "get_lrmw_word_mmu060";
2980: srcllrmw = "get_lrmw_long_mmu060";
2981: dstblrmw = "put_lrmw_byte_mmu060";
2982: dstwlrmw = "put_lrmw_word_mmu060";
2983: dstllrmw = "put_lrmw_long_mmu060";
2984: // 68060 only: also non-locked read-modify-write accesses are reported
2985: srcbrmw = "get_rmw_byte_mmu060";
2986: srcwrmw = "get_rmw_word_mmu060";
2987: srclrmw = "get_rmw_long_mmu060";
2988: dstbrmw = "put_rmw_byte_mmu060";
2989: dstwrmw = "put_rmw_word_mmu060";
2990: dstlrmw = "put_rmw_long_mmu060";
2991: getpc = "m68k_getpci ()";
1.1.1.4 root 2992: } else if (using_ce) {
1.1.1.7 root 2993: // 68000 ce
2994: prefetch_word = "get_word_ce000_prefetch";
2995: srcwi = "get_wordi_ce000";
2996: srcl = "get_long_ce000";
2997: dstl = "put_long_ce000";
2998: srcw = "get_word_ce000";
2999: dstw = "put_word_ce000";
3000: srcb = "get_byte_ce000";
3001: dstb = "put_byte_ce000";
3002: do_cycles = "do_cycles_ce000";
3003: getpc = "m68k_getpci ()";
3004: } else if (using_prefetch) {
3005: // 68000 prefetch
1.1.1.8 ! root 3006: prefetch_word = "get_word_000_prefetch";
! 3007: prefetch_long = "get_long_000_prefetch";
! 3008: srcwi = "get_wordi_000";
! 3009: srcl = "get_long_000";
! 3010: dstl = "put_long_000";
! 3011: srcw = "get_word_000";
! 3012: dstw = "put_word_000";
! 3013: srcb = "get_byte_000";
! 3014: dstb = "put_byte_000";
1.1.1.7 root 3015: getpc = "m68k_getpci ()";
1.1.1.4 root 3016: } else {
1.1.1.7 root 3017: // generic + direct
3018: prefetch_long = "get_dilong";
3019: prefetch_word = "get_diword";
3020: nextw = "next_diword";
3021: nextl = "next_dilong";
3022: srcli = "get_dilong";
3023: srcwi = "get_diword";
3024: srcbi = "get_dibyte";
1.1.1.8 ! root 3025: if (using_indirect < 0) {
! 3026: srcl = "get_long_jit";
! 3027: dstl = "put_long_jit";
! 3028: srcw = "get_word_jit";
! 3029: dstw = "put_word_jit";
! 3030: srcb = "get_byte_jit";
! 3031: dstb = "put_byte_jit";
! 3032: } else {
! 3033: srcl = "get_long";
! 3034: dstl = "put_long";
! 3035: srcw = "get_word";
! 3036: dstw = "put_word";
! 3037: srcb = "get_byte";
! 3038: dstb = "put_byte";
! 3039: }
1.1.1.4 root 3040: }
1.1.1.7 root 3041: if (!dstld)
3042: dstld = dstl;
3043: if (!dstwd)
3044: dstwd = dstw;
3045: if (!srcld)
3046: srcld = srcl;
3047: if (!srcwd)
3048: srcwd = srcw;
3049: if (!srcblrmw) {
3050: srcblrmw = srcb;
3051: srcwlrmw = srcw;
3052: srcllrmw = srcl;
3053: dstblrmw = dstb;
3054: dstwlrmw = dstw;
3055: dstllrmw = dstl;
3056: }
1.1.1.4 root 3057:
1.1.1.7 root 3058: }
3059:
3060: static void gen_opcode (unsigned int opcode)
3061: {
3062: struct instr *curi = table68k + opcode;
3063:
3064: resetvars ();
3065:
3066: #ifdef WINUAE_FOR_HATARI
3067: /* Hatari : Store the family of the instruction (used to check for pairing on ST,
3068: * for non-CPU cycles calculation and profiling)
3069: */
3070: printf ("\tOpcodeFamily = %d;\n", curi->mnemo);
3071: /* leave some space for patching in the current cycles later */
3072: if (!using_ce020) {
3073: printf("\tCurrentInstrCycles = \n");
3074: nCurInstrCycPos = ftell(stdout) - 5;
3075: }
3076: #endif
1.1.1.4 root 3077:
3078: start_brace ();
1.1.1.7 root 3079:
1.1.1.4 root 3080: m68k_pc_offset = 2;
1.1.1.7 root 3081:
1.1.1.8 ! root 3082: // do not unnecessarily create useless mmuop030
! 3083: // functions when CPU is not 68030
! 3084: if (curi->mnemo == i_MMUOP030 && cpu_level != 3 && !cpu_generic) {
! 3085: printf("\top_illg (opcode);\n");
! 3086: did_prefetch = -1;
! 3087: goto end;
! 3088: }
! 3089:
1.1.1.4 root 3090: switch (curi->plev) {
3091: case 0: /* not privileged */
3092: break;
3093: case 1: /* unprivileged only on 68000 */
3094: if (cpu_level == 0)
3095: break;
3096: if (next_cpu_level < 0)
3097: next_cpu_level = 0;
3098:
3099: /* fall through */
3100: case 2: /* priviledged */
1.1.1.7 root 3101: printf ("if (!regs.s) { Exception (8); goto %s; }\n", endlabelstr);
1.1.1.4 root 3102: need_endlabel = 1;
3103: start_brace ();
3104: break;
3105: case 3: /* privileged if size == word */
3106: if (curi->size == sz_byte)
3107: break;
1.1.1.7 root 3108: printf ("if (!regs.s) { Exception (8); goto %s; }\n", endlabelstr);
1.1.1.4 root 3109: need_endlabel = 1;
3110: start_brace ();
3111: break;
3112: }
3113: switch (curi->mnemo) {
3114: case i_OR:
3115: case i_AND:
3116: case i_EOR:
3117: {
1.1.1.7 root 3118: // documentaion error: and.l #imm,dn = 2 idle, not 1 idle (same as OR and EOR)
1.1.1.4 root 3119: int c = 0;
1.1.1.7 root 3120: genamodedual (curi,
3121: curi->smode, "srcreg", curi->size, "src", 1, 0,
3122: curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
3123: // genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3124: // genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
1.1.1.4 root 3125: printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^');
3126: genflags (flag_logical, curi->size, "src", "", "");
3127: if (curi->dmode == Dreg && curi->size == sz_long) {
3128: c += 2;
3129: if (curi->smode == imm || curi->smode == Dreg)
3130: c += 2;
3131: }
3132: fill_prefetch_next ();
3133: if (c > 0)
3134: addcycles000 (c);
3135: genastore_rev ("src", curi->dmode, "dstreg", curi->size, "dst");
3136: break;
3137: }
1.1.1.7 root 3138: // all SR/CCR modifications does full prefetch
1.1.1.4 root 3139: case i_ORSR:
3140: case i_EORSR:
3141: printf ("\tMakeSR ();\n");
1.1.1.7 root 3142: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3143: if (curi->size == sz_byte) {
3144: printf ("\tsrc &= 0xFF;\n");
3145: }
3146: addcycles000 (8);
1.1.1.7 root 3147: if (cpu_level <= 1) {
3148: sync_m68k_pc ();
3149: fill_prefetch_full ();
3150: } else {
3151: fill_prefetch_next ();
3152: }
1.1.1.4 root 3153: printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
1.1.1.7 root 3154: makefromsr ();
1.1.1.4 root 3155: break;
3156: case i_ANDSR:
3157: printf ("\tMakeSR ();\n");
1.1.1.7 root 3158: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3159: if (curi->size == sz_byte) {
3160: printf ("\tsrc |= 0xFF00;\n");
3161: }
3162: addcycles000 (8);
1.1.1.7 root 3163: if (cpu_level <= 1) {
3164: sync_m68k_pc ();
3165: fill_prefetch_full ();
3166: } else {
3167: fill_prefetch_next ();
3168: }
1.1.1.4 root 3169: printf ("\tregs.sr &= src;\n");
1.1.1.7 root 3170: makefromsr ();
1.1.1.4 root 3171: break;
3172: case i_SUB:
3173: {
3174: int c = 0;
1.1.1.7 root 3175: genamodedual (curi,
3176: curi->smode, "srcreg", curi->size, "src", 1, 0,
3177: curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
3178: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3179: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
1.1.1.4 root 3180: if (curi->dmode == Dreg) {
3181: if (curi->size == sz_long) {
3182: c += 2;
1.1.1.7 root 3183: if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg)
1.1.1.4 root 3184: c += 2;
3185: }
3186: }
3187: fill_prefetch_next ();
3188: if (c > 0)
3189: addcycles000 (c);
3190: start_brace ();
3191: genflags (flag_sub, curi->size, "newv", "src", "dst");
3192: genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst");
3193: break;
3194: }
3195: case i_SUBA:
3196: {
3197: int c = 0;
1.1.1.7 root 3198: genamodedual (curi,
3199: curi->smode, "srcreg", curi->size, "src", 1, 0,
3200: curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW);
3201: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3202: //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
1.1.1.4 root 3203: if (curi->smode == immi) {
3204: // SUBAQ.x is always 8 cycles
3205: c += 4;
3206: } else {
3207: c = curi->size == sz_long ? 2 : 4;
3208: if (islongimm (curi))
3209: c += 2;
3210: }
3211: fill_prefetch_next ();
3212: if (c > 0)
3213: addcycles000 (c);
3214: start_brace ();
3215: printf ("\tuae_u32 newv = dst - src;\n");
3216: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
3217: break;
3218: }
3219: case i_SUBX:
3220: if (!isreg (curi->smode))
3221: addcycles000 (2);
1.1.1.7 root 3222: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
3223: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
1.1.1.4 root 3224: fill_prefetch_next ();
3225: if (curi->size == sz_long && isreg (curi->smode))
3226: addcycles000 (4);
3227: start_brace ();
3228: printf ("\tuae_u32 newv = dst - src - (GET_XFLG () ? 1 : 0);\n");
3229: genflags (flag_subx, curi->size, "newv", "src", "dst");
3230: genflags (flag_zn, curi->size, "newv", "", "");
3231: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
3232: break;
3233: case i_SBCD:
3234: if (!isreg (curi->smode))
3235: addcycles000 (2);
1.1.1.7 root 3236: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
3237: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
1.1.1.4 root 3238: fill_prefetch_next ();
3239: start_brace ();
3240: printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n");
3241: printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n");
3242: printf ("\tuae_u16 newv, tmp_newv;\n");
3243: printf ("\tint bcd = 0;\n");
3244: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n");
3245: printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n");
3246: printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG () ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n");
3247: printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG () ? 1 : 0)) & 0x300) > 0xFF);\n");
3248: duplicate_carry (0);
3249: /* Manual says bits NV are undefined though a real 68040/060 don't change them */
3250: if (cpu_level >= xBCD_KEEPS_NV_FLAGS) {
3251: if (next_cpu_level < xBCD_KEEPS_NV_FLAGS)
3252: next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1;
3253: genflags (flag_z, curi->size, "newv", "", "");
3254: } else {
3255: genflags (flag_zn, curi->size, "newv", "", "");
3256: printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
3257: }
1.1.1.7 root 3258: if (isreg (curi->smode)) {
1.1.1.4 root 3259: addcycles000 (2);
1.1.1.7 root 3260: }
1.1.1.4 root 3261: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
3262: break;
3263: case i_ADD:
3264: {
3265: int c = 0;
1.1.1.7 root 3266: genamodedual (curi,
3267: curi->smode, "srcreg", curi->size, "src", 1, 0,
3268: curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
3269: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3270: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
1.1.1.4 root 3271: if (curi->dmode == Dreg) {
3272: if (curi->size == sz_long) {
3273: c += 2;
1.1.1.7 root 3274: if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg || curi->smode == Areg)
1.1.1.4 root 3275: c += 2;
3276: }
3277: }
3278: fill_prefetch_next ();
3279: if (c > 0)
3280: addcycles000 (c);
3281: start_brace ();
3282: genflags (flag_add, curi->size, "newv", "src", "dst");
3283: genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst");
3284: break;
3285: }
3286: case i_ADDA:
3287: {
3288: int c = 0;
1.1.1.7 root 3289: genamodedual (curi,
3290: curi->smode, "srcreg", curi->size, "src", 1, 0,
3291: curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW);
3292: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3293: //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
1.1.1.4 root 3294: if (curi->smode == immi) {
3295: // ADDAQ.x is always 8 cycles
3296: c += 4;
3297: } else {
3298: c = curi->size == sz_long ? 2 : 4;
3299: if (islongimm (curi))
3300: c += 2;
3301: }
3302: fill_prefetch_next ();
3303: if (c > 0)
3304: addcycles000 (c);
3305: start_brace ();
3306: printf ("\tuae_u32 newv = dst + src;\n");
3307: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
3308: break;
3309: }
3310: case i_ADDX:
3311: if (!isreg (curi->smode))
3312: addcycles000 (2);
1.1.1.7 root 3313: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
3314: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
1.1.1.4 root 3315: fill_prefetch_next ();
3316: if (curi->size == sz_long && isreg (curi->smode))
3317: addcycles000 (4);
3318: start_brace ();
3319: printf ("\tuae_u32 newv = dst + src + (GET_XFLG () ? 1 : 0);\n");
3320: genflags (flag_addx, curi->size, "newv", "src", "dst");
3321: genflags (flag_zn, curi->size, "newv", "", "");
3322: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
3323: break;
3324: case i_ABCD:
3325: if (!isreg (curi->smode))
3326: addcycles000 (2);
1.1.1.7 root 3327: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
3328: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
1.1.1.4 root 3329: fill_prefetch_next ();
3330: start_brace ();
3331: printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG () ? 1 : 0);\n");
3332: printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
3333: printf ("\tuae_u16 newv, tmp_newv;\n");
3334: printf ("\tint cflg;\n");
3335: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;");
3336: printf ("\tif (newv_lo > 9) { newv += 6; }\n");
3337: printf ("\tcflg = (newv & 0x3F0) > 0x90;\n");
3338: printf ("\tif (cflg) newv += 0x60;\n");
3339: printf ("\tSET_CFLG (cflg);\n");
3340: duplicate_carry (0);
3341: /* Manual says bits NV are undefined though a real 68040 don't change them */
3342: if (cpu_level >= xBCD_KEEPS_NV_FLAGS) {
3343: if (next_cpu_level < xBCD_KEEPS_NV_FLAGS)
3344: next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1;
3345: genflags (flag_z, curi->size, "newv", "", "");
3346: }
3347: else {
3348: genflags (flag_zn, curi->size, "newv", "", "");
3349: printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
3350: }
1.1.1.7 root 3351: if (isreg (curi->smode)) {
1.1.1.4 root 3352: addcycles000 (2);
1.1.1.7 root 3353: }
1.1.1.4 root 3354: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
3355: break;
3356: case i_NEG:
1.1.1.7 root 3357: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
1.1.1.4 root 3358: fill_prefetch_next ();
3359: if (isreg (curi->smode) && curi->size == sz_long)
3360: addcycles000 (2);
3361: start_brace ();
3362: genflags (flag_sub, curi->size, "dst", "src", "0");
3363: genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
3364: break;
3365: case i_NEGX:
1.1.1.7 root 3366: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
1.1.1.4 root 3367: fill_prefetch_next ();
3368: if (isreg (curi->smode) && curi->size == sz_long)
3369: addcycles000 (2);
3370: start_brace ();
3371: printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n");
3372: genflags (flag_subx, curi->size, "newv", "src", "0");
3373: genflags (flag_zn, curi->size, "newv", "", "");
3374: genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src");
3375: break;
3376: case i_NBCD:
1.1.1.7 root 3377: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
1.1.1.4 root 3378: if (isreg (curi->smode))
3379: addcycles000 (2);
3380: fill_prefetch_next ();
3381: start_brace ();
3382: printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n");
3383: printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n");
3384: printf ("\tuae_u16 newv;\n");
1.1.1.7 root 3385: #ifndef WINUAE_FOR_HATARI
3386: printf ("\tint cflg, tmp_newv;\n");
1.1.1.4 root 3387: printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
1.1.1.7 root 3388: printf ("\ttmp_newv = newv = newv_hi + newv_lo;\n");
3389: #else
3390: /* Hatari : use 2 cases to avoid 'tmp_newv' set but not used */
3391: if (cpu_level >= xBCD_KEEPS_NV_FLAGS) {
3392: printf ("\tint cflg;\n");
3393: printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
3394: printf ("\tnewv = newv_hi + newv_lo;\n");
3395: }
3396: else {
3397: printf ("\tint cflg, tmp_newv;\n");
3398: printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n");
3399: printf ("\ttmp_newv = newv = newv_hi + newv_lo;\n");
3400: }
3401: #endif
1.1.1.4 root 3402: printf ("\tcflg = (newv & 0x1F0) > 0x90;\n");
3403: printf ("\tif (cflg) newv -= 0x60;\n");
3404: printf ("\tSET_CFLG (cflg);\n");
3405: duplicate_carry(0);
3406: /* Manual says bits NV are undefined though a real 68040 don't change them */
3407: if (cpu_level >= xBCD_KEEPS_NV_FLAGS) {
3408: if (next_cpu_level < xBCD_KEEPS_NV_FLAGS)
3409: next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1;
3410: genflags (flag_z, curi->size, "newv", "", "");
3411: }
3412: else {
3413: genflags (flag_zn, curi->size, "newv", "", "");
1.1.1.7 root 3414: printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
1.1.1.4 root 3415: }
3416: genastore ("newv", curi->smode, "srcreg", curi->size, "src");
3417: break;
3418: case i_CLR:
1.1.1.7 root 3419: next_level_000 ();
3420: genamode (curi, curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
1.1.1.4 root 3421: fill_prefetch_next ();
3422: if (isreg (curi->smode) && curi->size == sz_long)
3423: addcycles000 (2);
3424: genflags (flag_logical, curi->size, "0", "", "");
3425: genastore_rev ("0", curi->smode, "srcreg", curi->size, "src");
3426: break;
3427: case i_NOT:
1.1.1.7 root 3428: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
1.1.1.4 root 3429: fill_prefetch_next ();
3430: if (isreg (curi->smode) && curi->size == sz_long)
3431: addcycles000 (2);
3432: start_brace ();
3433: printf ("\tuae_u32 dst = ~src;\n");
3434: genflags (flag_logical, curi->size, "dst", "", "");
3435: genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
3436: break;
3437: case i_TST:
1.1.1.7 root 3438: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3439: fill_prefetch_next ();
3440: genflags (flag_logical, curi->size, "src", "", "");
3441: break;
3442: case i_BTST:
1.1.1.7 root 3443: genamodedual (curi,
3444: curi->smode, "srcreg", curi->size, "src", 1, 0,
3445: curi->dmode, "dstreg", curi->size, "dst", 1, 0);
3446: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3447: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC);
1.1.1.4 root 3448: fill_prefetch_next ();
3449: bsetcycles (curi);
3450: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
3451: break;
3452: case i_BCHG:
3453: case i_BCLR:
3454: case i_BSET:
1.1.1.7 root 3455: // on 68000 these have weird side-effect, if EA points to write-only custom register
3456: //during instruction's read access CPU data lines appear as zero to outside world,
3457: // (normally previously fetched data appears in data lines if reading write-only register)
3458: // this allows stupid things like bset #2,$dff096 to work "correctly"
3459: // NOTE: above can't be right.
3460: genamodedual (curi,
3461: curi->smode, "srcreg", curi->size, "src", 1, 0,
3462: curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
3463: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3464: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC | GF_RMW);
1.1.1.4 root 3465: fill_prefetch_next ();
3466: bsetcycles (curi);
3467: // bclr needs 1 extra cycle
3468: if (curi->mnemo == i_BCLR && curi->dmode == Dreg)
3469: addcycles000 (2);
3470: if (curi->mnemo == i_BCHG) {
3471: printf ("\tdst ^= (1 << src);\n");
3472: printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n");
3473: } else if (curi->mnemo == i_BCLR) {
3474: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
3475: printf ("\tdst &= ~(1 << src);\n");
3476: } else if (curi->mnemo == i_BSET) {
3477: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
3478: printf ("\tdst |= (1 << src);\n");
3479: }
3480: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst");
3481: break;
3482: case i_CMPM:
3483: // confirmed
1.1.1.7 root 3484: genamodedual (curi,
3485: curi->smode, "srcreg", curi->size, "src", 1, GF_AA,
3486: curi->dmode, "dstreg", curi->size, "dst", 1, GF_AA);
3487: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
3488: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
1.1.1.4 root 3489: fill_prefetch_next ();
3490: start_brace ();
3491: genflags (flag_cmp, curi->size, "newv", "src", "dst");
3492: break;
3493: case i_CMP:
1.1.1.7 root 3494: genamodedual (curi,
3495: curi->smode, "srcreg", curi->size, "src", 1, 0,
3496: curi->dmode, "dstreg", curi->size, "dst", 1, 0);
3497: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3498: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.4 root 3499: fill_prefetch_next ();
3500: if (curi->dmode == Dreg && curi->size == sz_long)
3501: addcycles000 (2);
3502: start_brace ();
3503: genflags (flag_cmp, curi->size, "newv", "src", "dst");
3504: break;
3505: case i_CMPA:
1.1.1.7 root 3506: genamodedual (curi,
3507: curi->smode, "srcreg", curi->size, "src", 1, 0,
3508: curi->dmode, "dstreg", sz_long, "dst", 1, 0);
3509: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3510: //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
1.1.1.4 root 3511: fill_prefetch_next ();
3512: addcycles000 (2);
3513: start_brace ();
3514: genflags (flag_cmp, sz_long, "newv", "src", "dst");
3515: break;
3516: /* The next two are coded a little unconventional, but they are doing
3517: * weird things... */
3518: case i_MVPRM: // MOVEP R->M
1.1.1.7 root 3519: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3520: printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
3521: if (curi->size == sz_word) {
1.1.1.7 root 3522: printf ("\t%s (memp, src >> 8);\n\t%s (memp + 2, src);\n", dstb, dstb);
1.1.1.4 root 3523: count_write += 2;
3524: } else {
1.1.1.7 root 3525: printf ("\t%s (memp, src >> 24);\n\t%s (memp + 2, src >> 16);\n", dstb, dstb);
3526: printf ("\t%s (memp + 4, src >> 8);\n\t%s (memp + 6, src);\n", dstb, dstb);
3527: count_write += 4;
3528: }
1.1.1.4 root 3529: fill_prefetch_next ();
3530: break;
3531: case i_MVPMR: // MOVEP M->R
3532: printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
1.1.1.7 root 3533: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
3534: if (curi->size == sz_word) {
3535: printf ("\tuae_u16 val = ((%s (memp) & 0xff) << 8) + (%s (memp + 2) & 0xff);\n", srcb, srcb);
3536: count_read += 2;
3537: } else {
3538: printf ("\tuae_u32 val = ((%s (memp) & 0xff) << 24) + ((%s (memp + 2) & 0xff) << 16)\n", srcb, srcb);
3539: printf (" + ((%s (memp + 4) & 0xff) << 8) + (%s (memp + 6) & 0xff);\n", srcb, srcb);
3540: count_read += 4;
3541: }
1.1.1.4 root 3542: fill_prefetch_next ();
3543: genastore ("val", curi->dmode, "dstreg", curi->size, "dst");
3544: break;
3545: case i_MOVE:
3546: case i_MOVEA:
3547: {
3548: /* 2 MOVE instruction variants have special prefetch sequence:
3549: * - MOVE <ea>,-(An) = prefetch is before writes (Apdi)
3550: * - MOVE memory,(xxx).L = 2 prefetches after write
1.1.1.7 root 3551: * - move.x #imm = prefetch is done before write
1.1.1.4 root 3552: * - all others = prefetch is done after writes
3553: *
3554: * - move.x xxx,[at least 1 extension word here] = fetch 1 extension word before (xxx)
3555: *
3556: */
1.1.1.7 root 3557: if (isce020()) {
3558: // MOVE is too complex to handle in table68k
3559: int h = 0, t = 0, c = 0, subhead = 0;
3560: bool fea = false;
3561: if (curi->smode == immi && isreg (curi->dmode)) {
3562: // MOVEQ
3563: h = 2; t = 0; c = 0;
3564: } else if (isreg (curi->smode) && isreg (curi->dmode)) {
3565: // MOVE Rn,Rn
3566: h = 2; t = 0; c = 2;
3567: } else if (isreg (curi->dmode)) {
3568: // MOVE EA,Rn
3569: h = 0; t = 0; c = 2;
3570: fea = true;
3571: } else if (curi->dmode == Aind) {
3572: if (isreg (curi->smode)) {
3573: // MOVE Rn,(An)
3574: h = 0; t = 1; c = 3;
3575: } else {
3576: // MOVE SOURCE,(An)
3577: h = 2; t = 0; c = 4;
3578: fea = true;
3579: }
3580: } else if (curi->dmode == Aipi) {
3581: if (isreg (curi->smode)) {
3582: // MOVE Rn,(An)+
3583: h = 0; t = 1; c = 3;
3584: } else {
3585: // MOVE SOURCE,(An)+
3586: h = 2; t = 0; c = 4;
3587: fea = true;
3588: }
3589: } else if (curi->dmode == Apdi) {
3590: if (isreg (curi->smode)) {
3591: // MOVE Rn,-(An)
3592: h = 0; t = 2; c = 4;
3593: } else {
3594: // MOVE SOURCE,-(An)
3595: h = 2; t = 0; c = 4;
3596: fea = true;
3597: }
3598: } else if (curi->dmode == Ad16) {
3599: // MOVE EA,(d16,An)
3600: h = 2; t = 0; c = 4;
3601: fea = true;
3602: } else if (curi->dmode == Ad8r) {
3603: h = 4; t = 0; c = 6;
3604: fea = true;
3605: } else if (curi->dmode == absw) {
3606: // MOVE EA,xxx.W
3607: h = 2; t = 0; c = 4;
3608: fea = true;
3609: } else if (curi->dmode == absl) {
3610: // MOVE EA,xxx.L
3611: h = 0; t = 0; c = 6;
3612: fea = true;
3613: } else {
3614: h = 4; t = 0; c = 6;
3615: fea = true;
3616: }
3617: if (fea) {
3618: if (curi->smode == imm)
3619: subhead = gence020cycles_fiea (curi, curi->size, Dreg);
3620: else
3621: subhead = gence020cycles_fea (curi->smode);
3622: }
3623: genamode2x (curi->smode, "srcreg", curi->size, "src", 1, 0, 0, fea ? fetchmode_fea : -1);
3624: genamode2 (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_MOVE);
3625: addopcycles_ce20 (h, t, c, -subhead);
3626: if (curi->mnemo == i_MOVEA && curi->size == sz_word)
3627: printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
3628: if (curi->mnemo == i_MOVE)
3629: genflags (flag_logical, curi->size, "src", "", "");
3630: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
3631: sync_m68k_pc ();
3632:
3633: } else {
3634: int prefetch_done = 0, flags;
3635: int dualprefetch = curi->dmode == absl && (curi->smode != Dreg && curi->smode != Areg && curi->smode != imm);
3636: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3637: flags = GF_MOVE | GF_APDI;
3638: //if (curi->size == sz_long && (curi->smode == Dreg || curi->smode == Areg))
3639: // flags &= ~GF_APDI;
3640: flags |= dualprefetch ? GF_NOREFILL : 0;
3641: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, flags);
3642: if (curi->mnemo == i_MOVEA && curi->size == sz_word)
3643: printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
3644: if (curi->dmode == Apdi) {
3645: fill_prefetch_next ();
3646: prefetch_done = 1;
3647: }
3648: if (curi->mnemo == i_MOVE)
3649: genflags (flag_logical, curi->size, "src", "", "");
3650:
3651: if (curi->size == sz_long) {
3652: if ((curi->dmode == Ad16 || curi->dmode == PC16) && curi->smode == imm) {
3653: // lots more needed..
3654: // move.l x,absl
3655: // move.l (an),x(an)
3656: single_check_ipl();
3657: }
3658: }
3659: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
3660: sync_m68k_pc ();
3661: if (dualprefetch) {
3662: fill_prefetch_full_000 ();
3663: prefetch_done = 1;
3664: }
3665: if (!prefetch_done)
3666: fill_prefetch_next ();
1.1.1.4 root 3667: }
3668: }
3669: break;
3670: case i_MVSR2: // MOVE FROM SR
1.1.1.7 root 3671: genamode (curi, curi->smode, "srcreg", sz_word, "src", 2, 0, 0);
3672: if (isreg (curi->smode)) {
3673: fill_prefetch_next ();
1.1.1.4 root 3674: addcycles000 (2);
1.1.1.7 root 3675: } else {
3676: // write to memory, dummy write to same address, X-flag seems to be always set
3677: if (cpu_level <= 1 && curi->size == sz_word) {
3678: printf ("\t%s (srca, regs.sr | 0x0010);\n", dstw);
3679: count_write++;
3680: }
3681: fill_prefetch_next ();
3682: }
1.1.1.4 root 3683: printf ("\tMakeSR ();\n");
1.1.1.7 root 3684: // real write
1.1.1.4 root 3685: if (curi->size == sz_byte)
3686: genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src");
3687: else
3688: genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src");
3689: break;
3690: case i_MV2SR: // MOVE TO SR
1.1.1.7 root 3691: genamode (curi, curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
1.1.1.4 root 3692: if (curi->size == sz_byte) {
3693: // MOVE TO CCR
3694: addcycles000 (4);
3695: printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
3696: } else {
3697: // MOVE TO SR
3698: addcycles000 (4);
3699: printf ("\tregs.sr = src;\n");
3700: }
1.1.1.7 root 3701: makefromsr ();
3702: if (cpu_level <= 1) {
3703: // 68000 does 2xprefetch
3704: sync_m68k_pc ();
3705: fill_prefetch_full ();
3706: } else {
3707: fill_prefetch_next ();
3708: }
1.1.1.4 root 3709: break;
3710: case i_SWAP:
1.1.1.7 root 3711: genamode (curi, curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
1.1.1.4 root 3712: fill_prefetch_next ();
3713: start_brace ();
3714: printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
3715: genflags (flag_logical, sz_long, "dst", "", "");
3716: genastore ("dst", curi->smode, "srcreg", sz_long, "src");
3717: break;
3718: case i_EXG:
3719: // confirmed
1.1.1.7 root 3720: genamodedual (curi,
3721: curi->smode, "srcreg", curi->size, "src", 1, 0,
3722: curi->dmode, "dstreg", curi->size, "dst", 1, 0);
3723: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3724: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.4 root 3725: fill_prefetch_next ();
3726: addcycles000 (2);
3727: genastore ("dst", curi->smode, "srcreg", curi->size, "src");
3728: genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
3729: break;
3730: case i_EXT:
3731: // confirmed
1.1.1.7 root 3732: genamode (curi, curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
1.1.1.4 root 3733: fill_prefetch_next ();
3734: start_brace ();
3735: switch (curi->size) {
3736: case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break;
3737: case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break;
3738: case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break;
1.1.1.7 root 3739: default: term ();
1.1.1.4 root 3740: }
3741: genflags (flag_logical,
3742: curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
3743: genastore ("dst", curi->smode, "srcreg",
3744: curi->size == sz_word ? sz_word : sz_long, "src");
3745: break;
3746: case i_MVMEL:
3747: // confirmed
1.1.1.7 root 3748: if (using_ce || using_prefetch)
1.1.1.4 root 3749: genmovemel_ce (opcode);
3750: else
3751: genmovemel (opcode);
1.1.1.7 root 3752: tail_ce020_done = true;
1.1.1.4 root 3753: break;
3754: case i_MVMLE:
3755: // confirmed
1.1.1.7 root 3756: if (using_ce || using_prefetch)
1.1.1.4 root 3757: genmovemle_ce (opcode);
3758: else
3759: genmovemle (opcode);
1.1.1.7 root 3760: tail_ce020_done = true;
1.1.1.4 root 3761: break;
3762: case i_TRAP:
1.1.1.7 root 3763: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3764: gen_set_fault_pc ();
3765: sync_m68k_pc ();
1.1.1.7 root 3766: printf ("\tException (src + 32);\n");
1.1.1.4 root 3767: did_prefetch = 1;
1.1.1.7 root 3768: clear_m68k_offset();
1.1.1.4 root 3769: break;
3770: case i_MVR2USP:
1.1.1.7 root 3771: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3772: fill_prefetch_next ();
3773: printf ("\tregs.usp = src;\n");
3774: break;
3775: case i_MVUSP2R:
1.1.1.7 root 3776: genamode (curi, curi->smode, "srcreg", curi->size, "src", 2, 0, 0);
1.1.1.4 root 3777: fill_prefetch_next ();
3778: genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src");
3779: break;
3780: case i_RESET:
3781: fill_prefetch_next ();
3782: printf ("\tcpureset ();\n");
1.1.1.7 root 3783: sync_m68k_pc ();
1.1.1.4 root 3784: addcycles000 (128);
1.1.1.7 root 3785: if (using_prefetch) {
3786: printf ("\t%s (2);\n", prefetch_word);
3787: clear_m68k_offset();
3788: }
1.1.1.4 root 3789: break;
3790: case i_NOP:
3791: fill_prefetch_next ();
3792: break;
3793: case i_STOP:
3794: if (using_prefetch) {
3795: printf ("\tregs.sr = regs.irc;\n");
3796: m68k_pc_offset += 2;
3797: } else {
1.1.1.7 root 3798: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3799: printf ("\tregs.sr = src;\n");
3800: }
1.1.1.8 ! root 3801: addcycles000(2 * 4);
1.1.1.7 root 3802: makefromsr ();
1.1.1.4 root 3803: printf ("\tm68k_setstopped ();\n");
3804: sync_m68k_pc ();
3805: // STOP does not prefetch anything
3806: did_prefetch = -1;
3807: break;
3808: case i_LPSTOP: /* 68060 */
1.1.1.7 root 3809: printf ("\tuae_u16 sw = %s (2);\n", srcwi);
1.1.1.4 root 3810: printf ("\tuae_u16 sr;\n");
1.1.1.7 root 3811: printf ("\tif (sw != (0x100|0x80|0x40)) { Exception (4); goto %s; }\n", endlabelstr);
3812: printf ("\tsr = %s (4);\n", srcwi);
3813: printf ("\tif (!(sr & 0x8000)) { Exception (8); goto %s; }\n", endlabelstr);
1.1.1.4 root 3814: printf ("\tregs.sr = sr;\n");
1.1.1.7 root 3815: makefromsr ();
1.1.1.4 root 3816: printf ("\tm68k_setstopped();\n");
3817: m68k_pc_offset += 4;
3818: sync_m68k_pc ();
3819: fill_prefetch_full ();
3820: break;
3821: case i_RTE:
1.1.1.7 root 3822: addop_ce020 (curi, 0);
3823: next_level_000 ();
1.1.1.4 root 3824: if (cpu_level == 0) {
1.1.1.7 root 3825: genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
3826: genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
1.1.1.4 root 3827: printf ("\tregs.sr = sr;\n");
1.1.1.7 root 3828: printf ("\tif (pc & 1) {\n");
3829: printf ("\t\texception3i (0x%04X, pc);\n", opcode);
3830: printf ("\t\tgoto %s;\n", endlabelstr);
3831: printf ("\t}\n");
1.1.1.4 root 3832: setpc ("pc");
1.1.1.7 root 3833: makefromsr ();
3834: } else if (cpu_level == 1 && using_prefetch) {
3835: int old_brace_level = n_braces;
3836: printf ("\tuae_u16 newsr; uae_u32 newpc;\n");
3837: printf ("\tfor (;;) {\n");
3838: printf ("\t\tuaecptr a = m68k_areg (regs, 7);\n");
3839: printf ("\t\tuae_u16 sr = %s (a);\n", srcw);
3840: count_read++;
3841: printf ("\t\tuae_u32 pc = %s (a + 2) << 16; pc |= %s (a + 4);\n", srcw, srcw);
3842: count_read += 2;
3843: printf ("\t\tuae_u16 format = %s (a + 2 + 4);\n", srcw);
3844: count_read++;
3845: printf ("\t\tint frame = format >> 12;\n");
3846: printf ("\t\tint offset = 8;\n");
3847: printf ("\t\tnewsr = sr; newpc = pc;\n");
3848: printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n");
3849: printf ("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n");
3850: printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
3851: printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
3852: pop_braces (old_brace_level);
3853: printf ("\tregs.sr = newsr;\n");
3854: makefromsr ();
3855: printf ("\tif (newpc & 1) {\n");
3856: printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
3857: printf ("\t\tgoto %s;\n", endlabelstr);
3858: printf ("\t}\n");
3859: setpc ("newpc");
3860: check_ipl ();
3861: need_endlabel = 1;
1.1.1.4 root 3862: } else {
1.1 root 3863: int old_brace_level = n_braces;
3864: printf ("\tuae_u16 newsr; uae_u32 newpc;\n");
3865: printf ("\tfor (;;) {\n");
3866: printf ("\t\tuaecptr a = m68k_areg (regs, 7);\n");
1.1.1.5 root 3867: printf ("\t\tuae_u16 sr = %s (a);\n", srcw);
1.1.1.7 root 3868: count_read++;
1.1.1.5 root 3869: printf ("\t\tuae_u32 pc = %s (a + 2);\n", srcl);
1.1.1.7 root 3870: count_read += 2;
1.1.1.5 root 3871: printf ("\t\tuae_u16 format = %s (a + 2 + 4);\n", srcw);
1.1.1.7 root 3872: count_read++;
1.1 root 3873: printf ("\t\tint frame = format >> 12;\n");
3874: printf ("\t\tint offset = 8;\n");
3875: printf ("\t\tnewsr = sr; newpc = pc;\n");
1.1.1.7 root 3876: addcycles_ce020 (6);
1.1 root 3877: printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n");
3878: printf ("\t\telse if (frame == 0x1) { m68k_areg (regs, 7) += offset; }\n");
3879: printf ("\t\telse if (frame == 0x2) { m68k_areg (regs, 7) += offset + 4; break; }\n");
1.1.1.7 root 3880: if (using_mmu == 68060) {
3881: printf ("\t\telse if (frame == 0x4) { m68k_do_rte_mmu060 (a); m68k_areg (regs, 7) += offset + 8; break; }\n");
1.1.1.8 ! root 3882: } else if (cpu_level >= 4) {
1.1.1.7 root 3883: printf ("\t\telse if (frame == 0x4) { m68k_areg (regs, 7) += offset + 8; break; }\n");
3884: }
1.1.1.8 ! root 3885: if (cpu_level == 1) // 68010 only
! 3886: printf ("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n");
1.1.1.7 root 3887: if (using_mmu == 68040) {
3888: printf ("\t\telse if (frame == 0x7) { m68k_do_rte_mmu040 (a); m68k_areg (regs, 7) += offset + 52; break; }\n");
1.1.1.8 ! root 3889: } else if (cpu_level >= 4) {
1.1.1.7 root 3890: printf ("\t\telse if (frame == 0x7) { m68k_areg (regs, 7) += offset + 52; break; }\n");
3891: }
3892: printf ("\t\telse if (frame == 0x9) { m68k_areg (regs, 7) += offset + 12; break; }\n");
3893: if (using_mmu == 68030) {
3894: printf ("\t\telse if (frame == 0xa) { m68k_do_rte_mmu030 (a); break; }\n");
3895: printf ("\t\telse if (frame == 0xb) { m68k_do_rte_mmu030 (a); break; }\n");
3896: } else {
3897: printf ("\t\telse if (frame == 0xa) { m68k_areg (regs, 7) += offset + 24; break; }\n");
3898: printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n");
3899: }
3900: printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
3901: printf ("\t\tregs.sr = newsr;\n");
3902: makefromsr ();
3903: printf ("}\n");
1.1 root 3904: pop_braces (old_brace_level);
1.1.1.7 root 3905: printf ("\tregs.sr = newsr;\n");
3906: addcycles_ce020 (4);
3907: makefromsr ();
1.1 root 3908: printf ("\tif (newpc & 1) {\n");
1.1.1.7 root 3909: printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
1.1 root 3910: printf ("\t\tgoto %s;\n", endlabelstr);
3911: printf ("\t}\n");
1.1.1.7 root 3912: setpc ("newpc");
3913: check_ipl ();
1.1 root 3914: need_endlabel = 1;
1.1.1.4 root 3915: }
3916: /* PC is set and prefetch filled. */
1.1.1.7 root 3917: clear_m68k_offset();
3918: tail_ce020_done = true;
1.1.1.4 root 3919: fill_prefetch_full ();
1.1.1.7 root 3920: branch_inst = 1;
1.1.1.4 root 3921: break;
3922: case i_RTD:
1.1.1.7 root 3923: addop_ce020 (curi, 0);
1.1.1.4 root 3924: if (using_mmu) {
1.1.1.7 root 3925: genamode (curi, curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
3926: genamode (NULL, Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
1.1.1.4 root 3927: printf ("\tm68k_areg(regs, 7) += offs;\n");
3928: } else {
1.1.1.7 root 3929: genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
3930: genamode (curi, curi->smode, "srcreg", curi->size, "offs", 1, 0, 0);
1.1.1.4 root 3931: printf ("\tm68k_areg (regs, 7) += offs;\n");
3932: }
1.1 root 3933: printf ("\tif (pc & 1) {\n");
1.1.1.7 root 3934: printf ("\t\texception3i (0x%04X, pc);\n", opcode);
1.1 root 3935: printf ("\t\tgoto %s;\n", endlabelstr);
3936: printf ("\t}\n");
1.1.1.4 root 3937: setpc ("pc");
3938: /* PC is set and prefetch filled. */
1.1.1.7 root 3939: clear_m68k_offset();
3940: tail_ce020_done = true;
1.1.1.4 root 3941: fill_prefetch_full ();
1.1 root 3942: need_endlabel = 1;
1.1.1.7 root 3943: branch_inst = 1;
1.1.1.4 root 3944: break;
3945: case i_LINK:
3946: // ce confirmed
3947: if (using_mmu) {
1.1.1.7 root 3948: addmmufixup ("srcreg");
3949: genamode (NULL, curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
3950: genamode (NULL, Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0);
3951: genamode (NULL, curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
1.1.1.4 root 3952: genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src");
3953: printf ("\tm68k_areg(regs, 7) += offs;\n");
3954: genastore ("src", Apdi, "7", sz_long, "old");
3955: } else {
1.1.1.7 root 3956: addop_ce020 (curi, 0);
3957: genamode (NULL, Apdi, "7", sz_long, "old", 2, 0, GF_AA);
3958: genamode (NULL, curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA);
3959: genamode (NULL, curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0);
1.1.1.4 root 3960: genastore ("src", Apdi, "7", sz_long, "old");
3961: genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src");
3962: printf ("\tm68k_areg (regs, 7) += offs;\n");
3963: fill_prefetch_next ();
3964: }
3965: break;
3966: case i_UNLK:
3967: // ce confirmed
3968: if (using_mmu) {
1.1.1.7 root 3969: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
3970: printf ("\tuae_s32 old = %s (src);\n", srcl);
1.1 root 3971: printf ("\tm68k_areg (regs, 7) = src + 4;\n");
3972: printf ("\tm68k_areg (regs, srcreg) = old;\n");
1.1.1.4 root 3973: } else {
1.1.1.7 root 3974: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 3975: printf ("\tm68k_areg (regs, 7) = src;\n");
1.1.1.7 root 3976: genamode (NULL, Aipi, "7", sz_long, "old", 1, 0, 0);
1.1.1.4 root 3977: fill_prefetch_next ();
3978: genastore ("old", curi->smode, "srcreg", curi->size, "src");
3979: }
3980: break;
3981: case i_RTS:
1.1.1.7 root 3982: addop_ce020 (curi, 0);
3983: printf ("\tuaecptr pc = %s;\n", getpc);
1.1.1.8 ! root 3984: if (using_indirect > 0 && !using_ce020 && !using_prefetch_020 && !using_ce) {
1.1.1.7 root 3985: printf("\tm68k_do_rtsi_jit ();\n");
3986: } else if (using_ce020 == 1) {
3987: add_head_cycs (1);
1.1.1.4 root 3988: printf ("\tm68k_do_rts_ce020 ();\n");
1.1.1.7 root 3989: } else if (using_ce020 == 2) {
3990: add_head_cycs (1);
1.1.1.4 root 3991: printf ("\tm68k_do_rts_ce030 ();\n");
1.1.1.7 root 3992: } else if (using_ce) {
1.1.1.4 root 3993: printf ("\tm68k_do_rts_ce ();\n");
1.1.1.7 root 3994: } else if (using_mmu) {
1.1.1.5 root 3995: printf ("\tm68k_do_rts_mmu%s ();\n", mmu_postfix);
1.1.1.7 root 3996: } else if (using_prefetch || using_prefetch_020) {
3997: printf ("\tm68k_do_rtsi ();\n");
3998: } else {
1.1.1.4 root 3999: printf ("\tm68k_do_rts ();\n");
1.1.1.7 root 4000: }
4001: printf ("\tif (%s & 1) {\n", getpc);
4002: printf ("\t\tuaecptr faultpc = %s;\n", getpc);
4003: setpc ("pc");
4004: printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
1.1 root 4005: printf ("\t\tgoto %s;\n", endlabelstr);
4006: printf ("\t}\n");
1.1.1.4 root 4007: count_read += 2;
1.1.1.7 root 4008: clear_m68k_offset();
1.1.1.4 root 4009: fill_prefetch_full ();
1.1 root 4010: need_endlabel = 1;
1.1.1.7 root 4011: branch_inst = 1;
1.1.1.4 root 4012: break;
4013: case i_TRAPV:
4014: sync_m68k_pc ();
4015: fill_prefetch_next ();
4016: printf ("\tif (GET_VFLG ()) {\n");
1.1.1.7 root 4017: printf ("\t\tException (7);\n");
1.1.1.4 root 4018: printf ("\t\tgoto %s;\n", endlabelstr);
4019: printf ("\t}\n");
4020: need_endlabel = 1;
4021: break;
4022: case i_RTR:
1.1.1.7 root 4023: printf ("\tuaecptr oldpc = %s;\n", getpc);
1.1.1.4 root 4024: printf ("\tMakeSR ();\n");
1.1.1.7 root 4025: genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, 0);
4026: genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
1.1.1.4 root 4027: printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
4028: printf ("\tregs.sr |= sr;\n");
4029: setpc ("pc");
1.1.1.7 root 4030: makefromsr ();
4031: printf ("\tif (%s & 1) {\n", getpc);
4032: printf ("\t\tuaecptr faultpc = %s;\n", getpc);
4033: setpc ("oldpc");
4034: printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
4035: printf ("\t\tgoto %s;\n", endlabelstr);
4036: printf ("\t}\n");
4037: clear_m68k_offset();
1.1.1.4 root 4038: fill_prefetch_full ();
1.1.1.7 root 4039: need_endlabel = 1;
4040: branch_inst = 1;
4041: tail_ce020_done = true;
1.1.1.4 root 4042: break;
1.1.1.7 root 4043: case i_JSR:
4044: // possible idle cycle, prefetch from new address, stack high return addr, stack low, prefetch
4045: no_prefetch_ce020 = true;
4046: genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
1.1.1.4 root 4047: start_brace ();
1.1.1.7 root 4048: printf ("\tuaecptr oldpc = %s + %d;\n", getpc, m68k_pc_offset);
1.1.1.4 root 4049: if (using_exception_3) {
4050: printf ("\tif (srca & 1) {\n");
1.1.1.7 root 4051: printf ("\t\texception3i (opcode, srca);\n");
1.1.1.4 root 4052: printf ("\t\tgoto %s;\n", endlabelstr);
4053: printf ("\t}\n");
4054: need_endlabel = 1;
4055: }
4056: if (using_mmu) {
4057: printf ("\t%s (m68k_areg (regs, 7) - 4, oldpc);\n", dstl);
4058: printf ("\tm68k_areg (regs, 7) -= 4;\n");
4059: setpc ("srca");
1.1.1.7 root 4060: clear_m68k_offset();
1.1.1.4 root 4061: } else {
4062: if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16)
4063: addcycles000 (2);
1.1.1.7 root 4064: if (curi->smode == Ad8r || curi->smode == PC8r) {
4065: addcycles000 (6);
4066: #ifdef WINUAE_FOR_HATARI
4067: /* Hatari : JSR in Ad8r and PC8r mode takes 22 cycles, but on ST it takes 24 cycles */
4068: /* because of an unaligned memory prefetch in this EA mode */
4069: /* We add 2 cycles only in 68000 prefetch mode, 68000 CE mode is handled at the memory access level */
4070: if ( using_prefetch && !using_ce )
4071: addcycles000 (2);
4072: #endif
4073: if (cpu_level <= 1 && using_prefetch)
4074: printf ("\toldpc += 2;\n");
4075: }
1.1.1.4 root 4076: setpc ("srca");
1.1.1.7 root 4077: clear_m68k_offset();
1.1.1.4 root 4078: fill_prefetch_1 (0);
4079: printf ("\tm68k_areg (regs, 7) -= 4;\n");
1.1.1.7 root 4080: if (using_ce || using_prefetch) {
4081: printf ("\t%s (m68k_areg (regs, 7), oldpc >> 16);\n", dstw);
4082: printf ("\t%s (m68k_areg (regs, 7) + 2, oldpc);\n", dstw);
1.1.1.4 root 4083: } else {
4084: printf ("\t%s (m68k_areg (regs, 7), oldpc);\n", dstl);
4085: }
4086: }
4087: count_write += 2;
1.1.1.7 root 4088: fill_prefetch_full_020 ();
1.1.1.4 root 4089: fill_prefetch_next ();
1.1.1.7 root 4090: branch_inst = 1;
1.1.1.4 root 4091: break;
4092: case i_JMP:
1.1.1.7 root 4093: no_prefetch_ce020 = true;
4094: genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
1.1.1.4 root 4095: if (using_exception_3) {
4096: printf ("\tif (srca & 1) {\n");
1.1.1.7 root 4097: printf ("\t\texception3i (opcode, srca);\n");
1.1.1.4 root 4098: printf ("\t\tgoto %s;\n", endlabelstr);
4099: printf ("\t}\n");
4100: need_endlabel = 1;
4101: }
1.1.1.7 root 4102: if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16)
1.1.1.4 root 4103: addcycles000 (2);
1.1.1.7 root 4104: if (curi->smode == Ad8r || curi->smode == PC8r) {
4105: addcycles000 (6);
4106: #ifdef WINUAE_FOR_HATARI
4107: /* Hatari : JMP in Ad8r and PC8r mode takes 22 cycles, but on ST it takes 24 cycles */
4108: /* because of an unaligned memory prefetch in this EA mode */
4109: /* We add 2 cycles only in 68000 prefetch mode, 68000 CE mode is handled at the memory access level */
4110: if ( using_prefetch && !using_ce )
4111: addcycles000 (2);
4112: #endif
4113: }
1.1.1.4 root 4114: setpc ("srca");
1.1.1.7 root 4115: clear_m68k_offset();
1.1.1.4 root 4116: fill_prefetch_full ();
1.1.1.7 root 4117: branch_inst = 1;
1.1.1.4 root 4118: break;
4119: case i_BSR:
1.1.1.7 root 4120: // .b/.w = idle cycle, store high, store low, 2xprefetch
4121: if (isce020())
4122: no_prefetch_ce020 = true;
1.1.1.4 root 4123: printf ("\tuae_s32 s;\n");
1.1.1.7 root 4124: if (curi->size == sz_long) {
4125: if (next_cpu_level < 1)
4126: next_cpu_level = 1;
4127: }
4128: if (curi->size == sz_long && cpu_level < 2) {
4129: printf ("\tuae_u32 src = 0xffffffff;\n");
4130: } else {
4131: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL);
4132: }
1.1.1.4 root 4133: printf ("\ts = (uae_s32)src + 2;\n");
4134: if (using_exception_3) {
4135: printf ("\tif (src & 1) {\n");
1.1.1.7 root 4136: printf ("\t\texception3b (opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc);
1.1.1.4 root 4137: printf ("\t\tgoto %s;\n", endlabelstr);
4138: printf ("\t}\n");
4139: need_endlabel = 1;
4140: }
4141: addcycles000 (2);
1.1.1.8 ! root 4142: if (using_indirect > 0 && !using_ce020 && !using_prefetch_020 && !using_ce) {
1.1.1.7 root 4143: printf("\tm68k_do_bsri_jit (%s + %d, s);\n", getpc, m68k_pc_offset);
4144: } else if (using_ce020 == 1) {
4145: printf ("\tm68k_do_bsr_ce020 (%s + %d, s);\n", getpc, m68k_pc_offset);
1.1.1.4 root 4146: } else if (using_ce020 == 2) {
1.1.1.7 root 4147: printf ("\tm68k_do_bsr_ce030 (%s + %d, s);\n", getpc, m68k_pc_offset);
1.1.1.4 root 4148: } else if (using_ce) {
1.1.1.7 root 4149: printf ("\tm68k_do_bsr_ce (%s + %d, s);\n", getpc, m68k_pc_offset);
1.1.1.4 root 4150: } else if (using_mmu) {
1.1.1.7 root 4151: printf ("\tm68k_do_bsr_mmu%s (%s + %d, s);\n", mmu_postfix, getpc, m68k_pc_offset);
4152: } else if (using_prefetch || using_prefetch_020) {
4153: printf ("\tm68k_do_bsri (%s + %d, s);\n", getpc, m68k_pc_offset);
1.1.1.4 root 4154: } else {
1.1.1.7 root 4155: printf ("\tm68k_do_bsr (%s + %d, s);\n", getpc, m68k_pc_offset);
1.1.1.4 root 4156: }
4157: count_write += 2;
1.1.1.7 root 4158: clear_m68k_offset();
1.1.1.4 root 4159: fill_prefetch_full ();
1.1.1.7 root 4160: branch_inst = 1;
1.1.1.4 root 4161: break;
4162: case i_Bcc:
1.1.1.7 root 4163: tail_ce020_done = true;
1.1.1.4 root 4164: if (curi->size == sz_long) {
4165: if (cpu_level < 2) {
4166: addcycles000 (2);
4167: printf ("\tif (cctrue (%d)) {\n", curi->cc);
1.1.1.7 root 4168: printf ("\t\texception3i (opcode, %s + 1);\n", getpc);
1.1.1.4 root 4169: printf ("\t\tgoto %s;\n", endlabelstr);
4170: printf ("\t}\n");
4171: sync_m68k_pc ();
1.1.1.7 root 4172: addcycles000 (2);
1.1.1.4 root 4173: irc2ir ();
4174: fill_prefetch_2 ();
4175: need_endlabel = 1;
1.1.1.7 root 4176: goto bccl_not68020;
1.1.1.4 root 4177: } else {
4178: if (next_cpu_level < 1)
4179: next_cpu_level = 1;
4180: }
4181: }
1.1.1.7 root 4182: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | (cpu_level < 2 ? GF_NOREFILL : 0));
1.1.1.4 root 4183: addcycles000 (2);
4184: printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc);
4185: if (using_exception_3) {
4186: printf ("\tif (src & 1) {\n");
1.1.1.7 root 4187: printf ("\t\texception3i (opcode, %s + 2 + (uae_s32)src);\n", getpc);
1.1.1.4 root 4188: printf ("\t\tgoto %s;\n", endlabelstr);
4189: printf ("\t}\n");
4190: need_endlabel = 1;
4191: }
1.1.1.7 root 4192: push_ins_cnt();
1.1.1.4 root 4193: if (using_prefetch) {
4194: incpc ("(uae_s32)src + 2");
1.1.1.7 root 4195: fill_prefetch_full_000 ();
1.1.1.4 root 4196: if (using_ce)
4197: printf ("\treturn;\n");
4198: else
4199: printf ("\treturn 10 * CYCLE_UNIT / 2;\n");
4200: } else {
4201: incpc ("(uae_s32)src + 2");
1.1.1.7 root 4202: add_head_cycs (6);
4203: fill_prefetch_full_020 ();
4204: returncycles ("\t", 10);
1.1.1.4 root 4205: }
1.1.1.7 root 4206: pop_ins_cnt();
1.1.1.4 root 4207: printf ("didnt_jump:;\n");
4208: need_endlabel = 1;
4209: sync_m68k_pc ();
1.1.1.7 root 4210: addcycles000 (2);
4211: get_prefetch_020_continue ();
1.1.1.4 root 4212: if (curi->size == sz_byte) {
4213: irc2ir ();
1.1.1.7 root 4214: add_head_cycs (4);
1.1.1.4 root 4215: fill_prefetch_2 ();
4216: } else if (curi->size == sz_word) {
1.1.1.7 root 4217: add_head_cycs (6);
4218: fill_prefetch_full_000 ();
1.1.1.4 root 4219: } else {
1.1.1.7 root 4220: add_head_cycs (6);
4221: fill_prefetch_full_000 ();
1.1.1.4 root 4222: }
4223: insn_n_cycles = curi->size == sz_byte ? 8 : 12;
1.1.1.7 root 4224: branch_inst = 1;
4225: bccl_not68020:
1.1.1.4 root 4226: break;
4227: case i_LEA:
4228: if (curi->smode == Ad8r || curi->smode == PC8r)
4229: addcycles000 (2);
1.1.1.7 root 4230: genamodedual (curi,
4231: curi->smode, "srcreg", curi->size, "src", 0, GF_AA,
4232: curi->dmode, "dstreg", curi->size, "dst", 2, GF_AA);
4233: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
4234: //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
4235: if (curi->smode == Ad8r || curi->smode == PC8r) {
1.1.1.4 root 4236: addcycles000 (2);
1.1.1.7 root 4237: #ifdef WINUAE_FOR_HATARI
4238: /* Hatari : LEA in Ad8r and PC8r mode takes 12 cycles, but on ST it takes 14 cycles */
4239: /* because of an unaligned memory prefetch in this EA mode */
4240: /* We add 2 cycles only in 68000 prefetch mode, 68000 CE mode is handled at the memory access level */
4241: if ( using_prefetch && !using_ce )
4242: addcycles000 (2);
4243: #endif
4244: }
4245: fill_prefetch_next ();
1.1.1.4 root 4246: genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
4247: break;
4248: case i_PEA:
4249: if (curi->smode == Ad8r || curi->smode == PC8r)
4250: addcycles000 (2);
1.1.1.7 root 4251: genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
4252: genamode (NULL, Apdi, "7", sz_long, "dst", 2, 0, GF_AA);
1.1.1.4 root 4253: if (!(curi->smode == absw || curi->smode == absl))
4254: fill_prefetch_next ();
1.1.1.7 root 4255: if (curi->smode == Ad8r || curi->smode == PC8r) {
1.1.1.4 root 4256: addcycles000 (2);
1.1.1.7 root 4257: #ifdef WINUAE_FOR_HATARI
4258: /* Hatari : PEA in Ad8r and PC8r mode takes 20 cycles, but on ST it takes 22 cycles */
4259: /* because of an unaligned memory prefetch in this EA mode */
4260: /* We add 2 cycles only in 68000 prefetch mode, 68000 CE mode is handled at the memory access level */
4261: if ( using_prefetch && !using_ce )
4262: addcycles000 (2);
4263: #endif
4264: }
1.1.1.4 root 4265: genastore ("srca", Apdi, "7", sz_long, "dst");
4266: if ((curi->smode == absw || curi->smode == absl))
4267: fill_prefetch_next ();
4268: break;
4269: case i_DBcc:
1.1.1.7 root 4270: // cc true: idle cycle, prefetch
4271: // cc false, counter expired: idle cycle, prefetch (from branch address), 2xprefetch (from next address)
4272: // cc false, counter not expired: idle cycle, prefetch
4273: tail_ce020_done = true;
4274: genamodedual (curi,
4275: curi->smode, "srcreg", curi->size, "src", 1, GF_AA | (cpu_level < 2 ? GF_NOREFILL : 0),
4276: curi->dmode, "dstreg", curi->size, "offs", 1, GF_AA | (cpu_level < 2 ? GF_NOREFILL : 0));
4277: //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
4278: //genamode (curi, curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL);
4279: printf ("\tuaecptr oldpc = %s;\n", getpc);
1.1.1.4 root 4280: addcycles000 (2);
1.1.1.7 root 4281: push_ins_cnt();
1.1.1.4 root 4282: printf ("\tif (!cctrue (%d)) {\n", curi->cc);
1.1.1.7 root 4283: incpc ("(uae_s32)offs + 2");
4284: printf ("\t");
1.1.1.4 root 4285: fill_prefetch_1 (0);
1.1.1.7 root 4286: printf ("\t");
4287: genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src");
1.1.1.4 root 4288:
4289: printf ("\t\tif (src) {\n");
4290: if (using_exception_3) {
4291: printf ("\t\t\tif (offs & 1) {\n");
1.1.1.7 root 4292: printf ("\t\t\t\texception3i (opcode, %s + 2 + (uae_s32)offs + 2);\n", getpc);
1.1.1.4 root 4293: printf ("\t\t\t\tgoto %s;\n", endlabelstr);
4294: printf ("\t\t\t}\n");
4295: need_endlabel = 1;
4296: }
4297: irc2ir ();
1.1.1.7 root 4298: add_head_cycs (6);
1.1.1.4 root 4299: fill_prefetch_1 (2);
1.1.1.7 root 4300: fill_prefetch_full_020 ();
1.1.1.8 ! root 4301: returncycles ("\t\t\t", 10);
1.1.1.4 root 4302: printf ("\t\t}\n");
1.1.1.7 root 4303: add_head_cycs (10);
1.1.1.8 ! root 4304: addcycles000_nonce("\t\t", 2 + 2);
1.1.1.4 root 4305: printf ("\t} else {\n");
1.1.1.7 root 4306: addcycles000_onlyce(2);
4307: addcycles000_nonce("\t\t", 2);
1.1.1.4 root 4308: printf ("\t}\n");
1.1.1.7 root 4309: pop_ins_cnt();
1.1.1.4 root 4310: setpc ("oldpc + %d", m68k_pc_offset);
1.1.1.7 root 4311: clear_m68k_offset();
4312: get_prefetch_020_continue ();
4313: fill_prefetch_full_000 ();
1.1.1.4 root 4314: insn_n_cycles = 12;
4315: need_endlabel = 1;
1.1.1.7 root 4316: branch_inst = 1;
1.1.1.4 root 4317: break;
4318: case i_Scc:
4319: // confirmed
1.1.1.7 root 4320: next_level_000 ();
4321: genamode (curi, curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
1.1.1.4 root 4322: start_brace ();
4323: fill_prefetch_next();
4324: start_brace ();
4325: printf ("\tint val = cctrue (%d) ? 0xff : 0;\n", curi->cc);
1.1.1.7 root 4326: if (isreg (curi->smode)) {
4327: if (using_ce)
4328: printf ("\tint cycles = val ? 2 : 0;\n");
1.1.1.4 root 4329: addcycles000_3 ("\t");
1.1.1.7 root 4330: addcycles000_nonces("\t", "(val ? 2 : 0)");
1.1.1.4 root 4331: }
4332: genastore ("val", curi->smode, "srcreg", curi->size, "src");
4333: break;
4334: case i_DIVU:
1.1.1.7 root 4335: tail_ce020_done = true;
4336: genamodedual (curi,
4337: curi->smode, "srcreg", sz_word, "src", 1, 0,
4338: curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1.1.1.4 root 4339: printf ("\tCLEAR_CZNV ();\n");
4340: printf ("\tif (src == 0) {\n");
1.1.1.7 root 4341: if (cpu_level > 1)
4342: printf ("\t\tdivbyzero_special (0, dst);\n");
1.1.1.4 root 4343: incpc ("%d", m68k_pc_offset);
1.1.1.7 root 4344: printf ("\t\tException (5);\n");
1.1.1.4 root 4345: printf ("\t\tgoto %s;\n", endlabelstr);
4346: printf ("\t} else {\n");
4347: printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
4348: printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n");
4349: if (using_ce) {
4350: start_brace ();
1.1.1.7 root 4351: printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src)) - 4;\n");
1.1.1.4 root 4352: addcycles000_3 ("\t\t");
4353: }
1.1.1.7 root 4354: addcycles000_nonces("\t\t", "(getDivu68kCycles((uae_u32)dst, (uae_u16)src)) - 4");
4355: fill_prefetch_next ();
1.1.1.4 root 4356: /* The N flag appears to be set each time there is an overflow.
1.1.1.7 root 4357: * Weird. but 68020 only sets N when dst is negative.. */
1.1.1.4 root 4358: printf ("\t\tif (newv > 0xffff) {\n");
4359: printf ("\t\t\tSET_VFLG (1);\n");
4360: #ifdef UNDEF68020
4361: if (cpu_level >= 2)
4362: printf ("\t\t\tif (currprefs.cpu_level == 0 || dst < 0) SET_NFLG (®s, 1);\n");
4363: else /* ??? some 68000 revisions may not set NFLG when overflow happens.. */
4364: #endif
4365: printf ("\t\t\tSET_NFLG (1);\n");
4366: printf ("\t\t} else {\n");
4367: printf ("\t\t"); genflags (flag_logical, sz_word, "newv", "", "");
4368: printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
4369: printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
4370: printf ("\t\t}\n");
4371: sync_m68k_pc ();
4372: printf ("\t}\n");
4373: count_ncycles++;
4374: insn_n_cycles += 136 - (136 - 76) / 2; /* average */
4375: need_endlabel = 1;
1.1.1.7 root 4376: tail_ce020_done = false;
4377: returntail (false);
1.1.1.4 root 4378: break;
4379: case i_DIVS:
1.1.1.7 root 4380: tail_ce020_done = true;
4381: genamodedual (curi,
4382: curi->smode, "srcreg", sz_word, "src", 1, 0,
4383: curi->dmode, "dstreg", sz_long, "dst", 1, 0);
1.1.1.4 root 4384: printf ("\tif (src == 0) {\n");
1.1.1.7 root 4385: if (cpu_level > 1)
4386: printf ("\t\tdivbyzero_special (1, dst);\n");
1.1.1.4 root 4387: incpc ("%d", m68k_pc_offset);
1.1.1.7 root 4388: printf ("\t\tException (5);\n");
1.1.1.4 root 4389: printf ("\t\tgoto %s;\n", endlabelstr);
1.1.1.7 root 4390: printf ("\t}\n");
4391: printf ("\tCLEAR_CZNV ();\n");
1.1.1.4 root 4392: if (using_ce) {
4393: start_brace ();
1.1.1.7 root 4394: printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src)) - 4;\n");
1.1.1.4 root 4395: addcycles000_3 ("\t\t");
4396: }
1.1.1.7 root 4397: addcycles000_nonces("\t\t", "(getDivs68kCycles((uae_s32)dst, (uae_s16)src)) - 4");
4398: fill_prefetch_next ();
4399: printf ("\tif (dst == 0x80000000 && src == -1) {\n");
4400: printf ("\t\tSET_VFLG (1);\n");
4401: printf ("\t\tSET_NFLG (1);\n");
4402: printf ("\t} else {\n");
4403: printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
4404: printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
1.1.1.4 root 4405: printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n");
4406: printf ("\t\t\tSET_VFLG (1);\n");
4407: #ifdef UNDEF68020
4408: if (cpu_level > 0)
4409: printf ("\t\t\tif (currprefs.cpu_level == 0) SET_NFLG (®s, 1);\n");
4410: else
4411: #endif
4412: printf ("\t\t\tSET_NFLG (1);\n");
4413: printf ("\t\t} else {\n");
4414: printf ("\t\t\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n");
4415: genflags (flag_logical, sz_word, "newv", "", "");
4416: printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
4417: printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
4418: printf ("\t\t}\n");
4419: printf ("\t}\n");
1.1.1.7 root 4420: sync_m68k_pc ();
1.1.1.4 root 4421: count_ncycles++;
4422: insn_n_cycles += 156 - (156 - 120) / 2; /* average */
4423: need_endlabel = 1;
1.1.1.7 root 4424: tail_ce020_done = false;
4425: returntail (false);
1.1.1.4 root 4426: break;
4427: case i_MULU:
1.1.1.7 root 4428: genamodedual (curi,
4429: curi->smode, "srcreg", sz_word, "src", 1, 0,
4430: curi->dmode, "dstreg", sz_word, "dst", 1, 0);
1.1.1.4 root 4431: fill_prefetch_next();
4432: start_brace ();
4433: printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
4434: if (using_ce)
4435: printf ("\tint cycles = 38 - 4, bits;\n");
1.1.1.7 root 4436: else if (using_prefetch)
4437: printf ("\tint bits;\n");
1.1.1.4 root 4438: genflags (flag_logical, sz_long, "newv", "", "");
4439: if (using_ce) {
4440: printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n");
4441: printf ("\t\tif (src & 1) cycles += 2;\n");
4442: addcycles000_3 ("\t");
4443: }
1.1.1.7 root 4444: addcycles000_nonce("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n\t\tif (src & 1) ", 2);
1.1.1.4 root 4445: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
4446: sync_m68k_pc ();
4447: count_cycles += 38 - 4;
4448: count_ncycles++;
4449: insn_n_cycles += (70 - 38) / 2 + 38; /* average */
4450: break;
4451: case i_MULS:
1.1.1.7 root 4452: genamodedual (curi,
4453: curi->smode, "srcreg", sz_word, "src", 1, 0,
4454: curi->dmode, "dstreg", sz_word, "dst", 1, 0);
1.1.1.4 root 4455: fill_prefetch_next();
4456: start_brace ();
4457: printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
4458: if (using_ce) {
4459: printf ("\tint cycles = 38 - 4, bits;\n");
4460: printf ("\tuae_u32 usrc;\n");
1.1.1.7 root 4461: } else if (using_prefetch) {
4462: printf ("\tint bits;\n");
4463: printf ("\tuae_u32 usrc;\n");
1.1.1.4 root 4464: }
4465: genflags (flag_logical, sz_long, "newv", "", "");
4466: if (using_ce) {
4467: printf ("\tusrc = ((uae_u32)src) << 1;\n");
4468: printf ("\tfor(bits = 0; bits < 16 && usrc; bits++, usrc >>= 1)\n");
4469: printf ("\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) cycles += 2;\n");
4470: addcycles000_3 ("\t");
4471: }
1.1.1.7 root 4472: addcycles000_nonce("\tusrc = ((uae_u32)src) << 1;\n\tfor(bits = 0; bits < 16 && usrc; bits++, usrc >>= 1)\n\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) ", 2);
1.1.1.4 root 4473: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
4474: count_cycles += 38 - 4;
4475: count_ncycles++;
4476: insn_n_cycles += (70 - 38) / 2 + 38; /* average */
4477: break;
4478: case i_CHK:
1.1.1.7 root 4479: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
4480: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.4 root 4481: sync_m68k_pc ();
4482: addcycles000 (4);
4483: printf ("\tif (dst > src) {\n");
4484: printf ("\t\tSET_NFLG (0);\n");
1.1.1.7 root 4485: printf ("\t\tException (6);\n");
1.1.1.4 root 4486: printf ("\t\tgoto %s;\n", endlabelstr);
4487: printf ("\t}\n");
4488: addcycles000 (2);
4489: printf ("\tif ((uae_s32)dst < 0) {\n");
4490: printf ("\t\tSET_NFLG (1);\n");
1.1.1.7 root 4491: printf ("\t\tException (6);\n");
1.1.1.4 root 4492: printf ("\t\tgoto %s;\n", endlabelstr);
4493: printf ("\t}\n");
4494: fill_prefetch_next ();
4495: need_endlabel = 1;
4496: break;
4497: case i_CHK2:
1.1.1.7 root 4498: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
4499: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
1.1.1.4 root 4500: fill_prefetch_0 ();
4501: printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
4502: switch (curi->size) {
4503: case sz_byte:
4504: printf ("\tlower = (uae_s32)(uae_s8)%s (dsta); upper = (uae_s32)(uae_s8)%s (dsta + 1);\n", srcb, srcb);
4505: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n");
4506: break;
4507: case sz_word:
4508: printf ("\tlower = (uae_s32)(uae_s16)%s (dsta); upper = (uae_s32)(uae_s16)%s (dsta + 2);\n", srcw, srcw);
4509: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n");
4510: break;
4511: case sz_long:
4512: printf ("\tlower = %s (dsta); upper = %s (dsta + 4);\n", srcl, srcl);
4513: break;
4514: default:
1.1.1.7 root 4515: term ();
1.1.1.4 root 4516: }
4517: printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
4518: printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
1.1.1.7 root 4519: printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6); goto %s; }\n}\n", endlabelstr);
4520: need_endlabel = 1;
1.1.1.4 root 4521: break;
4522:
4523: case i_ASR:
1.1.1.7 root 4524: genamodedual (curi,
4525: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4526: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4527: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4528: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4529: fill_prefetch_next();
4530: start_brace ();
4531: switch (curi->size) {
4532: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4533: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4534: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4535: default: term ();
1.1.1.4 root 4536: }
4537: printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1);
4538: printf ("\tint ccnt = cnt & 63;\n");
4539: printf ("\tcnt &= 63;\n");
4540: printf ("\tCLEAR_CZNV ();\n");
4541: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
4542: printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size));
4543: printf ("\t\tSET_CFLG (sign);\n");
4544: duplicate_carry (1);
4545: if (source_is_imm1_8 (curi))
4546: printf ("\t} else {\n");
1.1.1.7 root 4547: else
1.1.1.4 root 4548: printf ("\t} else if (cnt > 0) {\n");
4549: printf ("\t\tval >>= cnt - 1;\n");
4550: printf ("\t\tSET_CFLG (val & 1);\n");
4551: duplicate_carry (1);
4552: printf ("\t\tval >>= 1;\n");
4553: printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n",
4554: bit_mask (curi->size),
4555: bit_size (curi->size));
4556: printf ("\t\tval &= %s;\n", bit_mask (curi->size));
4557: printf ("\t}\n");
4558: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4559: shift_ce (curi->dmode, curi->size);
4560: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4561: break;
4562: case i_ASL:
1.1.1.7 root 4563: genamodedual (curi,
4564: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4565: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4566: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4567: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4568: fill_prefetch_next();
4569: start_brace ();
4570: switch (curi->size) {
4571: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4572: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4573: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4574: default: term ();
1.1.1.4 root 4575: }
4576: printf ("\tint ccnt = cnt & 63;\n");
4577: printf ("\tcnt &= 63;\n");
4578: printf ("\tCLEAR_CZNV ();\n");
4579: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
4580: printf ("\t\tSET_VFLG (val != 0);\n");
4581: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n",
4582: bit_size (curi->size));
4583: duplicate_carry (1);
4584: printf ("\t\tval = 0;\n");
4585: if (source_is_imm1_8 (curi))
4586: printf ("\t} else {\n");
4587: else
4588: printf ("\t} else if (cnt > 0) {\n");
4589: printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n",
4590: bit_mask (curi->size),
4591: bit_size (curi->size) - 1,
4592: bit_mask (curi->size));
4593: printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n");
4594: printf ("\t\tval <<= cnt - 1;\n");
4595: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
4596: duplicate_carry (1);
4597: printf ("\t\tval <<= 1;\n");
4598: printf ("\t\tval &= %s;\n", bit_mask (curi->size));
4599: printf ("\t}\n");
4600: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4601: shift_ce (curi->dmode, curi->size);
4602: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4603: break;
4604: case i_LSR:
1.1.1.7 root 4605: genamodedual (curi,
4606: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4607: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4608: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4609: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4610: fill_prefetch_next();
4611: start_brace ();
4612: switch (curi->size) {
4613: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4614: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4615: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4616: default: term ();
1.1.1.4 root 4617: }
4618: printf ("\tint ccnt = cnt & 63;\n");
4619: printf ("\tcnt &= 63;\n");
4620: printf ("\tCLEAR_CZNV ();\n");
4621: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
4622: printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n",
4623: bit_size (curi->size), bit_size (curi->size) - 1);
4624: duplicate_carry (1);
4625: printf ("\t\tval = 0;\n");
4626: if (source_is_imm1_8 (curi))
4627: printf ("\t} else {\n");
1.1.1.7 root 4628: else
1.1.1.4 root 4629: printf ("\t} else if (cnt > 0) {\n");
4630: printf ("\t\tval >>= cnt - 1;\n");
4631: printf ("\t\tSET_CFLG (val & 1);\n");
4632: duplicate_carry (1);
4633: printf ("\t\tval >>= 1;\n");
4634: printf ("\t}\n");
4635: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4636: shift_ce (curi->dmode, curi->size);
4637: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4638: break;
4639: case i_LSL:
1.1.1.7 root 4640: genamodedual (curi,
4641: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4642: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4643: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4644: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4645: fill_prefetch_next();
4646: start_brace ();
4647: switch (curi->size) {
4648: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4649: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4650: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4651: default: term ();
1.1.1.4 root 4652: }
4653: printf ("\tint ccnt = cnt & 63;\n");
4654: printf ("\tcnt &= 63;\n");
4655: printf ("\tCLEAR_CZNV ();\n");
4656: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size));
4657: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size (curi->size));
4658: duplicate_carry (1);
4659: printf ("\t\tval = 0;\n");
4660: if (source_is_imm1_8 (curi))
4661: printf ("\t} else {\n");
1.1.1.7 root 4662: else
1.1.1.4 root 4663: printf ("\t} else if (cnt > 0) {\n");
4664: printf ("\t\tval <<= (cnt - 1);\n");
4665: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
4666: duplicate_carry (1);
4667: printf ("\t\tval <<= 1;\n");
4668: printf ("\tval &= %s;\n", bit_mask (curi->size));
4669: printf ("\t}\n");
4670: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4671: shift_ce (curi->dmode, curi->size);
4672: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4673: break;
4674: case i_ROL:
1.1.1.7 root 4675: genamodedual (curi,
4676: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4677: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4678: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4679: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4680: fill_prefetch_next ();
4681: start_brace ();
4682: switch (curi->size) {
4683: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4684: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4685: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4686: default: term ();
1.1.1.4 root 4687: }
4688: printf ("\tint ccnt = cnt & 63;\n");
4689: printf ("\tcnt &= 63;\n");
4690: printf ("\tCLEAR_CZNV ();\n");
4691: if (source_is_imm1_8 (curi))
4692: printf ("{");
4693: else
4694: printf ("\tif (cnt > 0) {\n");
4695: printf ("\tuae_u32 loval;\n");
4696: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
4697: printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size));
4698: printf ("\tval <<= cnt;\n");
4699: printf ("\tval |= loval;\n");
4700: printf ("\tval &= %s;\n", bit_mask (curi->size));
4701: printf ("\tSET_CFLG (val & 1);\n");
4702: printf ("}\n");
4703: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4704: shift_ce (curi->dmode, curi->size);
4705: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4706: break;
4707: case i_ROR:
1.1.1.7 root 4708: genamodedual (curi,
4709: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4710: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4711: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4712: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4713: fill_prefetch_next ();
4714: start_brace ();
4715: switch (curi->size) {
4716: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4717: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4718: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4719: default: term ();
1.1.1.4 root 4720: }
4721: printf ("\tint ccnt = cnt & 63;\n");
4722: printf ("\tcnt &= 63;\n");
4723: printf ("\tCLEAR_CZNV ();\n");
4724: if (source_is_imm1_8 (curi))
4725: printf ("{");
4726: else
4727: printf ("\tif (cnt > 0) {");
4728: printf ("\tuae_u32 hival;\n");
4729: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1);
4730: printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size));
4731: printf ("\tval >>= cnt;\n");
4732: printf ("\tval |= hival;\n");
4733: printf ("\tval &= %s;\n", bit_mask (curi->size));
4734: printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1);
4735: printf ("\t}\n");
4736: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4737: shift_ce (curi->dmode, curi->size);
4738: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4739: break;
4740: case i_ROXL:
1.1.1.7 root 4741: genamodedual (curi,
4742: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4743: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4744: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4745: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4746: fill_prefetch_next ();
4747: start_brace ();
4748: switch (curi->size) {
4749: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4750: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4751: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4752: default: term ();
1.1.1.4 root 4753: }
4754: printf ("\tint ccnt = cnt & 63;\n");
4755: printf ("\tcnt &= 63;\n");
4756: printf ("\tCLEAR_CZNV ();\n");
4757: if (source_is_imm1_8 (curi))
4758: printf ("{");
4759: else {
4760: force_range_for_rox ("cnt", curi->size);
4761: printf ("\tif (cnt > 0) {\n");
4762: }
4763: printf ("\tcnt--;\n");
4764: printf ("\t{\n\tuae_u32 carry;\n");
4765: printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1);
4766: printf ("\tcarry = loval & 1;\n");
4767: printf ("\tval = (((val << 1) | GET_XFLG ()) << cnt) | (loval >> 1);\n");
4768: printf ("\tSET_XFLG (carry);\n");
4769: printf ("\tval &= %s;\n", bit_mask (curi->size));
4770: printf ("\t} }\n");
4771: printf ("\tSET_CFLG (GET_XFLG ());\n");
4772: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4773: shift_ce (curi->dmode, curi->size);
4774: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4775: break;
4776: case i_ROXR:
1.1.1.7 root 4777: genamodedual (curi,
4778: curi->smode, "srcreg", curi->size, "cnt", 1, 0,
4779: curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
4780: //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
4781: //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4782: fill_prefetch_next ();
4783: start_brace ();
4784: switch (curi->size) {
4785: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4786: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4787: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4788: default: term ();
1.1.1.4 root 4789: }
4790: printf ("\tint ccnt = cnt & 63;\n");
4791: printf ("\tcnt &= 63;\n");
4792: printf ("\tCLEAR_CZNV ();\n");
4793: if (source_is_imm1_8 (curi))
4794: printf ("{");
4795: else {
4796: force_range_for_rox ("cnt", curi->size);
4797: printf ("\tif (cnt > 0) {\n");
4798: }
4799: printf ("\tcnt--;\n");
4800: printf ("\t{\n\tuae_u32 carry;\n");
4801: printf ("\tuae_u32 hival = (val << 1) | GET_XFLG ();\n");
4802: printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1);
4803: printf ("\tval >>= cnt;\n");
4804: printf ("\tcarry = val & 1;\n");
4805: printf ("\tval >>= 1;\n");
4806: printf ("\tval |= hival;\n");
4807: printf ("\tSET_XFLG (carry);\n");
4808: printf ("\tval &= %s;\n", bit_mask (curi->size));
4809: printf ("\t} }\n");
4810: printf ("\tSET_CFLG (GET_XFLG ());\n");
4811: genflags (flag_logical_noclobber, curi->size, "val", "", "");
4812: shift_ce (curi->dmode, curi->size);
4813: genastore ("val", curi->dmode, "dstreg", curi->size, "data");
4814: break;
4815: case i_ASRW:
1.1.1.7 root 4816: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4817: fill_prefetch_next ();
4818: start_brace ();
4819: switch (curi->size) {
4820: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4821: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4822: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4823: default: term ();
1.1.1.4 root 4824: }
4825: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
4826: printf ("\tuae_u32 cflg = val & 1;\n");
4827: printf ("\tval = (val >> 1) | sign;\n");
4828: genflags (flag_logical, curi->size, "val", "", "");
4829: printf ("\tSET_CFLG (cflg);\n");
4830: duplicate_carry (0);
4831: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4832: break;
4833: case i_ASLW:
1.1.1.7 root 4834: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4835: fill_prefetch_next ();
4836: start_brace ();
4837: switch (curi->size) {
4838: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4839: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4840: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4841: default: term ();
1.1.1.4 root 4842: }
4843: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
4844: printf ("\tuae_u32 sign2;\n");
4845: printf ("\tval <<= 1;\n");
4846: genflags (flag_logical, curi->size, "val", "", "");
4847: printf ("\tsign2 = %s & val;\n", cmask (curi->size));
4848: printf ("\tSET_CFLG (sign != 0);\n");
4849: duplicate_carry (0);
4850: printf ("\tSET_VFLG (GET_VFLG () | (sign2 != sign));\n");
4851: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4852: break;
4853: case i_LSRW:
1.1.1.7 root 4854: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4855: fill_prefetch_next ();
4856: start_brace ();
4857: switch (curi->size) {
4858: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
4859: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
4860: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4861: default: term ();
1.1.1.4 root 4862: }
4863: printf ("\tuae_u32 carry = val & 1;\n");
4864: printf ("\tval >>= 1;\n");
4865: genflags (flag_logical, curi->size, "val", "", "");
4866: printf ("\tSET_CFLG (carry);\n");
4867: duplicate_carry (0);
4868: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4869: break;
4870: case i_LSLW:
1.1.1.7 root 4871: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4872: fill_prefetch_next ();
4873: start_brace ();
4874: switch (curi->size) {
4875: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
4876: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
4877: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4878: default: term ();
1.1.1.4 root 4879: }
4880: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
4881: printf ("\tval <<= 1;\n");
4882: genflags (flag_logical, curi->size, "val", "", "");
4883: printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
4884: duplicate_carry (0);
4885: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4886: break;
4887: case i_ROLW:
1.1.1.7 root 4888: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4889: fill_prefetch_next ();
4890: start_brace ();
4891: switch (curi->size) {
4892: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
4893: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
4894: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4895: default: term ();
1.1.1.4 root 4896: }
4897: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
4898: printf ("\tval <<= 1;\n");
4899: printf ("\tif (carry) val |= 1;\n");
4900: genflags (flag_logical, curi->size, "val", "", "");
4901: printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
4902: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4903: break;
4904: case i_RORW:
1.1.1.7 root 4905: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4906: fill_prefetch_next ();
4907: start_brace ();
4908: switch (curi->size) {
4909: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
4910: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
4911: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4912: default: term ();
1.1.1.4 root 4913: }
4914: printf ("\tuae_u32 carry = val & 1;\n");
4915: printf ("\tval >>= 1;\n");
4916: printf ("\tif (carry) val |= %s;\n", cmask (curi->size));
4917: genflags (flag_logical, curi->size, "val", "", "");
4918: printf ("\tSET_CFLG (carry);\n");
4919: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4920: break;
4921: case i_ROXLW:
1.1.1.7 root 4922: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4923: fill_prefetch_next ();
4924: start_brace ();
4925: switch (curi->size) {
4926: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
4927: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
4928: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4929: default: term ();
1.1.1.4 root 4930: }
4931: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
4932: printf ("\tval <<= 1;\n");
4933: printf ("\tif (GET_XFLG ()) val |= 1;\n");
4934: genflags (flag_logical, curi->size, "val", "", "");
4935: printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1);
4936: duplicate_carry (0);
4937: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4938: break;
4939: case i_ROXRW:
1.1.1.7 root 4940: genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
1.1.1.4 root 4941: fill_prefetch_next ();
4942: start_brace ();
4943: switch (curi->size) {
4944: case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
4945: case sz_word: printf ("\tuae_u16 val = data;\n"); break;
4946: case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.7 root 4947: default: term ();
1.1.1.4 root 4948: }
4949: printf ("\tuae_u32 carry = val & 1;\n");
4950: printf ("\tval >>= 1;\n");
4951: printf ("\tif (GET_XFLG ()) val |= %s;\n", cmask (curi->size));
4952: genflags (flag_logical, curi->size, "val", "", "");
4953: printf ("\tSET_CFLG (carry);\n");
4954: duplicate_carry (0);
4955: genastore ("val", curi->smode, "srcreg", curi->size, "data");
4956: break;
4957: case i_MOVEC2:
1.1.1.7 root 4958: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 4959: fill_prefetch_next ();
4960: start_brace ();
4961: printf ("\tint regno = (src >> 12) & 15;\n");
4962: printf ("\tuae_u32 *regp = regs.regs + regno;\n");
4963: printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
4964: break;
4965: case i_MOVE2C:
1.1.1.7 root 4966: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
1.1.1.4 root 4967: fill_prefetch_next ();
4968: start_brace ();
4969: printf ("\tint regno = (src >> 12) & 15;\n");
4970: printf ("\tuae_u32 *regp = regs.regs + regno;\n");
4971: printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
4972: break;
4973: case i_CAS:
4974: {
4975: int old_brace_level;
1.1.1.7 root 4976: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_LRMW);
4977: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_LRMW);
4978: if (cpu_level == 5 && curi->size > 0) {
4979: printf ("\tif ((dsta & %d) && currprefs.int_no_unimplemented && get_cpu_model () == 68060) {\n", curi->size == 1 ? 1 : 3);
4980: if (curi->dmode == Aipi || curi->dmode == Apdi)
4981: printf ("\t\tm68k_areg (regs, dstreg) %c= %d;\n", curi->dmode == Aipi ? '-' : '+', 1 << curi->size);
4982: sync_m68k_pc_noreset ();
4983: printf ("\t\top_unimpl (opcode);\n");
4984: printf ("\t\tgoto %s;\n", endlabelstr);
4985: printf ("\t}\n");
4986: need_endlabel = 1;
4987: }
1.1.1.4 root 4988: fill_prefetch_0 ();
4989: start_brace ();
4990: printf ("\tint ru = (src >> 6) & 7;\n");
4991: printf ("\tint rc = src & 7;\n");
4992: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, rc)", "dst");
1.1.1.7 root 4993: gen_set_fault_pc ();
4994: printf ("\tif (GET_ZFLG ()) ");
1.1.1.4 root 4995: old_brace_level = n_braces;
4996: start_brace ();
1.1.1.7 root 4997: printf ("\n\t");
4998: genastore_cas ("(m68k_dreg (regs, ru))", curi->dmode, "dstreg", curi->size, "dst");
4999: printf ("\t");
1.1.1.4 root 5000: pop_braces (old_brace_level);
5001: printf ("else");
5002: start_brace ();
1.1.1.7 root 5003: printf ("\n");
5004: get_prefetch_020 ();
5005: if (cpu_level >= 4) {
5006: // apparently 68040/060 needs to always write at the end of RMW cycle
5007: printf ("\t");
5008: genastore_cas ("dst", curi->dmode, "dstreg", curi->size, "dst");
5009: }
5010: switch (curi->size) {
5011: case sz_byte:
5012: printf ("\t\tm68k_dreg(regs, rc) = (m68k_dreg(regs, rc) & ~0xff) | (dst & 0xff);\n");
5013: break;
5014: case sz_word:
5015: printf ("\t\tm68k_dreg(regs, rc) = (m68k_dreg(regs, rc) & ~0xffff) | (dst & 0xffff);\n");
5016: break;
5017: default:
5018: printf ("\t\tm68k_dreg(regs, rc) = dst;\n");
5019: break;
5020: }
1.1.1.4 root 5021: pop_braces (old_brace_level);
5022: }
5023: break;
5024: case i_CAS2:
1.1.1.7 root 5025: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, GF_LRMW);
1.1.1.4 root 5026: printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n");
5027: printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n");
5028: if (curi->size == sz_word) {
5029: int old_brace_level = n_braces;
1.1.1.7 root 5030: printf ("\tuae_u16 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcwlrmw, srcwlrmw);
1.1.1.4 root 5031: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1");
5032: printf ("\tif (GET_ZFLG ()) {\n");
5033: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2");
5034: printf ("\tif (GET_ZFLG ()) {\n");
1.1.1.7 root 5035: printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstwlrmw);
5036: printf ("\t%s (rn2, m68k_dreg (regs, (extra >> 6) & 7));\n", dstwlrmw);
1.1.1.4 root 5037: printf ("\t}}\n");
5038: pop_braces (old_brace_level);
5039: printf ("\tif (! GET_ZFLG ()) {\n");
1.1.1.8 ! root 5040: printf ("\tm68k_dreg (regs, (extra >> 0) & 7) = (m68k_dreg (regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
! 5041: printf ("\tm68k_dreg (regs, (extra >> 16) & 7) = (m68k_dreg (regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
1.1.1.4 root 5042: printf ("\t}\n");
5043: } else {
5044: int old_brace_level = n_braces;
1.1.1.7 root 5045: printf ("\tuae_u32 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcllrmw, srcllrmw);
1.1.1.4 root 5046: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1");
5047: printf ("\tif (GET_ZFLG ()) {\n");
5048: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2");
5049: printf ("\tif (GET_ZFLG ()) {\n");
1.1.1.7 root 5050: printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstllrmw);
5051: printf ("\t%s (rn2, m68k_dreg (regs, (extra >> 6) & 7));\n", dstllrmw);
1.1.1.4 root 5052: printf ("\t}}\n");
5053: pop_braces (old_brace_level);
5054: printf ("\tif (! GET_ZFLG ()) {\n");
1.1.1.8 ! root 5055: printf ("\tm68k_dreg (regs, (extra >> 0) & 7) = dst2;\n");
! 5056: printf ("\tm68k_dreg (regs, (extra >> 16) & 7) = dst1;\n");
1.1.1.4 root 5057: printf ("\t}\n");
5058: }
5059: break;
5060: case i_MOVES: /* ignore DFC and SFC when using_mmu == false */
5061: {
5062: int old_brace_level;
1.1.1.7 root 5063: tail_ce020_done = true;
5064: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.4 root 5065: printf ("\tif (extra & 0x800)\n");
5066: {
5067: int old_m68k_pc_offset = m68k_pc_offset;
5068: old_brace_level = n_braces;
5069: start_brace ();
5070: printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
1.1.1.7 root 5071: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
1.1.1.4 root 5072: genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst");
5073: pop_braces (old_brace_level);
5074: m68k_pc_offset = old_m68k_pc_offset;
5075: }
5076: printf ("else");
5077: {
5078: start_brace ();
1.1.1.7 root 5079: genamode (curi, curi->dmode, "dstreg", curi->size, "src", 1, 0, GF_FC);
1.1.1.4 root 5080: printf ("\tif (extra & 0x8000) {\n");
5081: switch (curi->size) {
5082: case sz_byte: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break;
5083: case sz_word: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break;
5084: case sz_long: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = src;\n"); break;
1.1.1.7 root 5085: default: term ();
1.1.1.4 root 5086: }
5087: printf ("\t} else {\n");
5088: genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, "");
5089: printf ("\t}\n");
1.1.1.7 root 5090: if (using_mmu == 68040)
5091: sync_m68k_pc ();
1.1.1.4 root 5092: pop_braces (old_brace_level);
5093: }
1.1.1.7 root 5094: tail_ce020_done = false;
5095: returntail (false);
1.1.1.4 root 5096: }
5097: break;
5098: case i_BKPT: /* only needed for hardware emulators */
5099: sync_m68k_pc ();
5100: printf ("\top_illg (opcode);\n");
1.1.1.8 ! root 5101: did_prefetch = -1;
1.1.1.4 root 5102: break;
5103: case i_CALLM: /* not present in 68030 */
5104: sync_m68k_pc ();
5105: printf ("\top_illg (opcode);\n");
1.1.1.8 ! root 5106: did_prefetch = -1;
1.1.1.4 root 5107: break;
5108: case i_RTM: /* not present in 68030 */
5109: sync_m68k_pc ();
5110: printf ("\top_illg (opcode);\n");
1.1.1.8 ! root 5111: did_prefetch = -1;
1.1.1.4 root 5112: break;
5113: case i_TRAPcc:
5114: if (curi->smode != am_unknown && curi->smode != am_illg)
1.1.1.7 root 5115: genamode (curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
1.1.1.4 root 5116: fill_prefetch_0 ();
1.1.1.7 root 5117: printf ("\tif (cctrue (%d)) { Exception (7); goto %s; }\n", curi->cc, endlabelstr);
1.1.1.4 root 5118: need_endlabel = 1;
5119: break;
5120: case i_DIVL:
1.1.1.7 root 5121: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
5122: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.4 root 5123: sync_m68k_pc ();
1.1.1.7 root 5124: printf ("\tif (!m68k_divl(opcode, dst, extra)) goto %s;\n", endlabelstr);
5125: need_endlabel = 1;
1.1.1.4 root 5126: break;
5127: case i_MULL:
1.1.1.7 root 5128: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
5129: genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
1.1.1.4 root 5130: sync_m68k_pc ();
1.1.1.7 root 5131: printf ("\tif (!m68k_mull(opcode, dst, extra)) goto %s;\n", endlabelstr);
5132: need_endlabel = 1;
1.1.1.4 root 5133: break;
5134: case i_BFTST:
5135: case i_BFEXTU:
5136: case i_BFCHG:
5137: case i_BFEXTS:
5138: case i_BFCLR:
5139: case i_BFFFO:
5140: case i_BFSET:
5141: case i_BFINS:
5142: {
5143: const char *getb, *putb;
5144:
1.1.1.7 root 5145: if (using_mmu == 68060 && (curi->mnemo == i_BFCHG || curi->mnemo == i_BFCLR || curi->mnemo == i_BFSET || curi->mnemo == i_BFINS)) {
5146: getb = "mmu060_get_rmw_bitfield";
5147: putb = "mmu060_put_rmw_bitfield";
1.1.1.8 ! root 5148: } else if (using_mmu || using_ce020 || using_indirect > 0) {
1.1.1.4 root 5149: getb = "x_get_bitfield";
5150: putb = "x_put_bitfield";
5151: } else {
5152: getb = "get_bitfield";
5153: putb = "put_bitfield";
5154: }
5155:
1.1.1.7 root 5156: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
5157: genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0);
1.1.1.4 root 5158: start_brace ();
5159: printf ("\tuae_u32 bdata[2];\n");
5160: printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n");
5161: printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n");
1.1.1.8 ! root 5162: if (curi->mnemo == i_BFFFO)
! 5163: printf("\tuae_u32 offset2 = offset;\n");
1.1.1.4 root 5164: if (curi->dmode == Dreg) {
5165: printf ("\tuae_u32 tmp = m68k_dreg(regs, dstreg);\n");
5166: printf ("\toffset &= 0x1f;\n");
5167: printf ("\ttmp = (tmp << offset) | (tmp >> (32 - offset));\n");
5168: printf ("\tbdata[0] = tmp & ((1 << (32 - width)) - 1);\n");
5169: } else {
5170: printf ("\tuae_u32 tmp;\n");
5171: printf ("\tdsta += offset >> 3;\n");
5172: printf ("\ttmp = %s (dsta, bdata, offset, width);\n", getb);
5173: }
5174: printf ("\tSET_NFLG_ALWAYS (((uae_s32)tmp) < 0 ? 1 : 0);\n");
5175: if (curi->mnemo == i_BFEXTS)
5176: printf ("\ttmp = (uae_s32)tmp >> (32 - width);\n");
5177: else
5178: printf ("\ttmp >>= (32 - width);\n");
5179: printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n");
5180: switch (curi->mnemo) {
5181: case i_BFTST:
5182: break;
5183: case i_BFEXTU:
5184: case i_BFEXTS:
5185: printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = tmp;\n");
5186: break;
5187: case i_BFCHG:
5188: printf ("\ttmp = tmp ^ (0xffffffffu >> (32 - width));\n");
5189: break;
5190: case i_BFCLR:
5191: printf ("\ttmp = 0;\n");
5192: break;
5193: case i_BFFFO:
5194: printf ("\t{ uae_u32 mask = 1 << (width - 1);\n");
1.1.1.8 ! root 5195: printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset2++; }}\n");
! 5196: printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = offset2;\n");
1.1.1.4 root 5197: break;
5198: case i_BFSET:
5199: printf ("\ttmp = 0xffffffffu >> (32 - width);\n");
5200: break;
5201: case i_BFINS:
5202: printf ("\ttmp = m68k_dreg (regs, (extra >> 12) & 7);\n");
5203: printf ("\ttmp = tmp & (0xffffffffu >> (32 - width));\n");
5204: printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n");
5205: printf ("\tSET_ZFLG (tmp == 0);\n");
5206: break;
5207: default:
5208: break;
5209: }
5210: if (curi->mnemo == i_BFCHG
5211: || curi->mnemo == i_BFCLR
5212: || curi->mnemo == i_BFSET
5213: || curi->mnemo == i_BFINS) {
5214: if (curi->dmode == Dreg) {
5215: printf ("\ttmp = bdata[0] | (tmp << (32 - width));\n");
5216: printf ("\tm68k_dreg(regs, dstreg) = (tmp >> offset) | (tmp << (32 - offset));\n");
5217: } else {
5218: printf ("\t%s(dsta, bdata, tmp, offset, width);\n", putb);
5219: }
5220: }
5221: }
5222: break;
5223: case i_PACK:
5224: if (curi->smode == Dreg) {
5225: printf ("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0));
5226: printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
5227: } else {
5228: printf ("\tuae_u16 val;\n");
1.1.1.7 root 5229: addmmufixup ("srcreg");
1.1.1.4 root 5230: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
1.1.1.7 root 5231: printf ("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff);\n", srcb);
1.1.1.4 root 5232: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
1.1.1.7 root 5233: printf ("\tval = (val | ((uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff) << 8)) + %s;\n", srcb, gen_nextiword (0));
5234: addmmufixup ("dstreg");
1.1.1.4 root 5235: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
5236: gen_set_fault_pc ();
5237: printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb);
5238: }
5239: break;
5240: case i_UNPK:
5241: if (curi->smode == Dreg) {
5242: printf ("\tuae_u16 val = m68k_dreg (regs, srcreg);\n");
5243: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
5244: printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffff0000) | (val & 0xffff);\n");
5245: } else {
5246: printf ("\tuae_u16 val;\n");
1.1.1.7 root 5247: addmmufixup ("srcreg");
1.1.1.4 root 5248: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n");
1.1.1.7 root 5249: printf ("\tval = (uae_u16)(%s (m68k_areg (regs, srcreg)) & 0xff);\n", srcb);
1.1.1.4 root 5250: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0));
1.1.1.7 root 5251: addmmufixup ("dstreg");
1.1.1.4 root 5252: if (cpu_level >= 2) {
5253: printf ("\tm68k_areg (regs, dstreg) -= 2 * areg_byteinc[dstreg];\n");
5254: printf ("\t%s (m68k_areg (regs, dstreg) + areg_byteinc[dstreg], val);\n", dstb);
5255: printf ("\t%s (m68k_areg (regs, dstreg), val >> 8);\n", dstb);
5256: } else {
5257: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
5258: printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb);
5259: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n");
5260: gen_set_fault_pc ();
5261: printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb);
5262: }
5263: }
5264: break;
5265: case i_TAS:
1.1.1.7 root 5266: genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_LRMW);
1.1.1.4 root 5267: genflags (flag_logical, curi->size, "src", "", "");
5268: if (!isreg (curi->smode))
5269: addcycles000 (2);
5270: fill_prefetch_next ();
5271: printf ("\tsrc |= 0x80;\n");
5272: if (cpu_level >= 2 || curi->smode == Dreg || !using_ce) {
5273: if (next_cpu_level < 2)
5274: next_cpu_level = 2 - 1;
1.1.1.7 root 5275: genastore_tas ("src", curi->smode, "srcreg", curi->size, "src");
1.1.1.4 root 5276: } else {
5277: printf ("\tif (!is_cycle_ce ()) {\n");
5278: genastore ("src", curi->smode, "srcreg", curi->size, "src");
5279: printf ("\t} else {\n");
1.1.1.7 root 5280: printf ("\t\t%s (4);\n", do_cycles);
5281: addcycles000_nonce("\t\t", 4);
1.1.1.4 root 5282: printf ("\t}\n");
5283: }
5284: break;
5285: case i_FPP:
5286: fpulimit();
1.1.1.7 root 5287: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.4 root 5288: sync_m68k_pc ();
5289: printf ("\tfpuop_arithmetic(opcode, extra);\n");
1.1.1.7 root 5290: if (using_prefetch || using_prefetch_020) {
5291: printf ("\tif (regs.fp_exception) goto %s;\n", endlabelstr);
5292: need_endlabel = 1;
5293: }
1.1.1.4 root 5294: break;
5295: case i_FDBcc:
5296: fpulimit();
1.1.1.7 root 5297: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.4 root 5298: sync_m68k_pc ();
5299: printf ("\tfpuop_dbcc (opcode, extra);\n");
1.1.1.7 root 5300: if (using_prefetch || using_prefetch_020) {
5301: printf ("\tif (regs.fp_exception) goto %s;\n", endlabelstr);
5302: printf ("\tif (regs.fp_branch) {\n");
5303: printf ("\t\tregs.fp_branch = false;\n");
5304: printf ("\t\tfill_prefetch();\n");
5305: printf ("\t\tgoto %s;\n", endlabelstr);
5306: printf ("\t}\n");
5307: need_endlabel = 1;
5308: }
1.1.1.4 root 5309: break;
5310: case i_FScc:
5311: fpulimit();
1.1.1.7 root 5312: genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.4 root 5313: sync_m68k_pc ();
5314: printf ("\tfpuop_scc (opcode, extra);\n");
1.1.1.7 root 5315: if (using_prefetch || using_prefetch_020) {
5316: printf ("\tif (regs.fp_exception) goto %s;\n", endlabelstr);
5317: need_endlabel = 1;
5318: }
1.1.1.4 root 5319: break;
5320: case i_FTRAPcc:
5321: fpulimit();
1.1.1.7 root 5322: printf ("\tuaecptr oldpc = %s;\n", getpc);
1.1.1.4 root 5323: printf ("\tuae_u16 extra = %s;\n", gen_nextiword (0));
5324: if (curi->smode != am_unknown && curi->smode != am_illg)
1.1.1.7 root 5325: genamode (curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
1.1.1.4 root 5326: sync_m68k_pc ();
5327: printf ("\tfpuop_trapcc (opcode, oldpc, extra);\n");
1.1.1.7 root 5328: if (using_prefetch || using_prefetch_020) {
5329: printf ("\tif (regs.fp_exception) goto %s;\n", endlabelstr);
5330: need_endlabel = 1;
5331: }
1.1.1.4 root 5332: break;
5333: case i_FBcc:
5334: fpulimit();
5335: sync_m68k_pc ();
5336: start_brace ();
1.1.1.7 root 5337: printf ("\tuaecptr pc = %s;\n", getpc);
5338: genamode (curi, curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0);
1.1.1.4 root 5339: sync_m68k_pc ();
5340: printf ("\tfpuop_bcc (opcode, pc,extra);\n");
1.1.1.7 root 5341: if (using_prefetch || using_prefetch_020) {
5342: printf ("\tif (regs.fp_exception) goto %s;\n", endlabelstr);
5343: printf ("\tif (regs.fp_branch) {\n");
5344: printf ("\t\tregs.fp_branch = false;\n");
5345: printf ("\t\tfill_prefetch();\n");
5346: printf ("\t\tgoto %s;\n", endlabelstr);
5347: printf ("\t}\n");
5348: need_endlabel = 1;
5349: }
1.1.1.4 root 5350: break;
5351: case i_FSAVE:
5352: fpulimit();
5353: sync_m68k_pc ();
5354: printf ("\tfpuop_save (opcode);\n");
1.1.1.7 root 5355: if (using_prefetch || using_prefetch_020) {
5356: printf ("\tif (regs.fp_exception) goto %s;\n", endlabelstr);
5357: need_endlabel = 1;
5358: }
1.1.1.4 root 5359: break;
5360: case i_FRESTORE:
5361: fpulimit();
5362: sync_m68k_pc ();
5363: printf ("\tfpuop_restore (opcode);\n");
1.1.1.7 root 5364: if (using_prefetch || using_prefetch_020) {
5365: printf ("\tif (regs.fp_exception) goto %s;\n", endlabelstr);
5366: need_endlabel = 1;
5367: }
1.1.1.4 root 5368: break;
5369:
5370: case i_CINVL:
5371: case i_CINVP:
5372: case i_CINVA:
5373: case i_CPUSHL:
5374: case i_CPUSHP:
5375: case i_CPUSHA:
1.1.1.7 root 5376: printf ("\tflush_cpu_caches_040(opcode);\n");
1.1.1.4 root 5377: if (using_mmu)
1.1.1.5 root 5378: printf ("\tflush_mmu%s(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n", mmu_postfix);
1.1.1.4 root 5379: printf ("\tif (opcode & 0x80)\n");
5380: printf ("\t\tflush_icache(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n");
5381: break;
5382:
5383: case i_MOVE16:
5384: {
5385: if ((opcode & 0xfff8) == 0xf620) {
5386: /* MOVE16 (Ax)+,(Ay)+ */
1.1.1.7 root 5387: printf ("\tuae_u32 v[4];\n");
1.1.1.4 root 5388: printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
5389: printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
5390: printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
1.1.1.7 root 5391: if (using_mmu >= 68040) {
5392: printf ("\tget_move16_mmu (mems, v);\n");
5393: printf ("\tput_move16_mmu (memd, v);\n");
5394: } else {
5395: printf ("\tv[0] = %s (mems);\n", srcl);
5396: printf ("\tv[1] = %s (mems + 4);\n", srcl);
5397: printf ("\tv[2] = %s (mems + 8);\n", srcl);
5398: printf ("\tv[3] = %s (mems + 12);\n", srcl);
5399: printf ("\t%s (memd , v[0]);\n", dstl);
5400: printf ("\t%s (memd + 4, v[1]);\n", dstl);
5401: printf ("\t%s (memd + 8, v[2]);\n", dstl);
5402: printf ("\t%s (memd + 12, v[3]);\n", dstl);
5403: }
1.1.1.4 root 5404: printf ("\tif (srcreg != dstreg)\n");
5405: printf ("\t\tm68k_areg (regs, srcreg) += 16;\n");
5406: printf ("\tm68k_areg (regs, dstreg) += 16;\n");
5407: } else {
5408: /* Other variants */
1.1.1.7 root 5409: printf ("\tuae_u32 v[4];\n");
5410: genamode (curi, curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
5411: genamode (curi, curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
5412: if (using_mmu == 68040) {
5413: printf ("\tget_move16_mmu (memsa, mmu040_move16);\n");
5414: printf ("\tput_move16_mmu (memda, mmu040_move16);\n");
5415: } else if (using_mmu == 68060) {
5416: printf ("\tget_move16_mmu (memsa, v);\n");
5417: printf ("\tput_move16_mmu (memda, v);\n");
5418: } else {
5419: printf ("\tmemsa &= ~15;\n");
5420: printf ("\tmemda &= ~15;\n");
5421: printf ("\tv[0] = %s (memsa);\n", srcl);
5422: printf ("\tv[1] = %s (memsa + 4);\n", srcl);
5423: printf ("\tv[2] = %s (memsa + 8);\n", srcl);
5424: printf ("\tv[3] = %s (memsa + 12);\n", srcl);
5425: printf ("\t%s (memda , v[0]);\n", dstl);
5426: printf ("\t%s (memda + 4, v[1]);\n", dstl);
5427: printf ("\t%s (memda + 8, v[2]);\n", dstl);
5428: printf ("\t%s (memda + 12, v[3]);\n", dstl);
5429: }
1.1.1.4 root 5430: if ((opcode & 0xfff8) == 0xf600)
5431: printf ("\tm68k_areg (regs, srcreg) += 16;\n");
5432: else if ((opcode & 0xfff8) == 0xf608)
5433: printf ("\tm68k_areg (regs, dstreg) += 16;\n");
5434: }
5435: }
5436: break;
5437:
5438: case i_PFLUSHN:
5439: case i_PFLUSH:
5440: case i_PFLUSHAN:
5441: case i_PFLUSHA:
5442: case i_PLPAR:
5443: case i_PLPAW:
5444: case i_PTESTR:
5445: case i_PTESTW:
5446: sync_m68k_pc ();
5447: printf ("\tmmu_op (opcode, 0);\n");
5448: break;
5449: case i_MMUOP030:
1.1.1.8 ! root 5450: printf("\tuaecptr pc = %s;\n", getpc);
! 5451: printf("\tuae_u16 extra = %s (2);\n", prefetch_word);
1.1.1.4 root 5452: m68k_pc_offset += 2;
1.1.1.8 ! root 5453: sync_m68k_pc();
1.1.1.4 root 5454: if (curi->smode == Areg || curi->smode == Dreg)
5455: printf("\tuae_u16 extraa = 0;\n");
5456: else
1.1.1.8 ! root 5457: genamode(curi, curi->smode, "srcreg", curi->size, "extra", 0, 0, 0);
! 5458: sync_m68k_pc();
1.1.1.7 root 5459: if (using_ce020 || using_prefetch_020) {
1.1.1.8 ! root 5460: printf("\tif (mmu_op30 (pc, opcode, extra, extraa)) goto %s;\n", endlabelstr);
1.1.1.7 root 5461: need_endlabel = 1;
5462: } else {
1.1.1.8 ! root 5463: printf("\tmmu_op30 (pc, opcode, extra, extraa);\n");
1.1.1.7 root 5464: }
1.1.1.4 root 5465: break;
5466: default:
1.1.1.7 root 5467: term ();
1.1.1.4 root 5468: break;
5469: }
1.1.1.8 ! root 5470: end:
1.1.1.7 root 5471: if (!genastore_done)
5472: returntail (0);
1.1.1.4 root 5473: finish_braces ();
5474: if (limit_braces) {
5475: printf ("\n#endif\n");
5476: n_braces = limit_braces;
5477: limit_braces = 0;
5478: finish_braces ();
5479: }
5480: if (did_prefetch >= 0)
5481: fill_prefetch_finish ();
5482: sync_m68k_pc ();
5483: did_prefetch = 0;
1.1.1.7 root 5484: ipl_fetched = 0;
1.1.1.4 root 5485: }
5486:
1.1.1.7 root 5487: static void generate_includes (FILE * f, int id)
1.1.1.4 root 5488: {
1.1.1.8 ! root 5489: fprintf (f, "#include \"main.h\"\n");
1.1.1.7 root 5490: // fprintf (f, "#include \"sysconfig.h\"\n");
1.1.1.4 root 5491: fprintf (f, "#include \"sysdeps.h\"\n");
1.1.1.7 root 5492: // fprintf (f, "#include \"options.h\"\n");
1.1.1.8 ! root 5493: fprintf (f, "#include \"hatari-glue.h\"\n");
! 5494: fprintf (f, "#include \"maccess.h\"\n");
1.1.1.4 root 5495: fprintf (f, "#include \"memory.h\"\n");
5496: fprintf (f, "#include \"custom.h\"\n");
1.1.1.7 root 5497: // fprintf (f, "#include \"events.h\"\n");
1.1.1.4 root 5498: fprintf (f, "#include \"newcpu.h\"\n");
5499: fprintf (f, "#include \"cpu_prefetch.h\"\n");
5500: fprintf (f, "#include \"cputbl.h\"\n");
1.1.1.7 root 5501: if (id == 31 || id == 33)
5502: fprintf (f, "#include \"cpummu.h\"\n");
5503: else if (id == 32)
5504: fprintf (f, "#include \"cpummu030.h\"\n");
1.1.1.4 root 5505:
5506: fprintf (f, "#define CPUFUNC(x) x##_ff\n"
5507: "#define SET_CFLG_ALWAYS(x) SET_CFLG(x)\n"
5508: "#define SET_NFLG_ALWAYS(x) SET_NFLG(x)\n"
5509: "#ifdef NOFLAGS\n"
5510: "#include \"noflags.h\"\n"
5511: "#endif\n");
5512: }
5513:
5514: static int postfix;
5515:
5516:
5517: static char *decodeEA (amodes mode, wordsizes size)
5518: {
5519: static char buffer[80];
5520:
5521: buffer[0] = 0;
5522: switch (mode){
5523: case Dreg:
5524: strcpy (buffer,"Dn");
5525: break;
5526: case Areg:
5527: strcpy (buffer,"An");
5528: break;
5529: case Aind:
5530: strcpy (buffer,"(An)");
5531: break;
5532: case Aipi:
5533: strcpy (buffer,"(An)+");
5534: break;
5535: case Apdi:
5536: strcpy (buffer,"-(An)");
5537: break;
5538: case Ad16:
5539: strcpy (buffer,"(d16,An)");
5540: break;
5541: case Ad8r:
5542: strcpy (buffer,"(d8,An,Xn)");
5543: break;
5544: case PC16:
5545: strcpy (buffer,"(d16,PC)");
5546: break;
5547: case PC8r:
5548: strcpy (buffer,"(d8,PC,Xn)");
5549: break;
5550: case absw:
5551: strcpy (buffer,"(xxx).W");
5552: break;
5553: case absl:
5554: strcpy (buffer,"(xxx).L");
5555: break;
5556: case imm:
5557: switch (size){
5558: case sz_byte:
5559: strcpy (buffer,"#<data>.B");
5560: break;
5561: case sz_word:
5562: strcpy (buffer,"#<data>.W");
5563: break;
5564: case sz_long:
5565: strcpy (buffer,"#<data>.L");
5566: break;
5567: default:
5568: break;
5569: }
5570: break;
5571: case imm0:
5572: strcpy (buffer,"#<data>.B");
5573: break;
5574: case imm1:
5575: strcpy (buffer,"#<data>.W");
5576: break;
5577: case imm2:
5578: strcpy (buffer,"#<data>.L");
5579: break;
5580: case immi:
5581: strcpy (buffer,"#<data>");
5582: break;
5583:
5584: default:
5585: break;
5586: }
5587: return buffer;
5588: }
5589:
1.1.1.7 root 5590: static const char *m68k_cc[] = {
5591: "T",
5592: "F",
5593: "HI",
5594: "LS",
5595: "CC",
5596: "CS",
5597: "NE",
5598: "EQ",
5599: "VC",
5600: "VS",
5601: "PL",
5602: "MI",
5603: "GE",
5604: "LT",
5605: "GT",
5606: "LE"
5607: };
5608:
1.1.1.4 root 5609: static char *outopcode (int opcode)
5610: {
5611: static char out[100];
5612: struct instr *ins;
5613: int i;
5614:
5615: ins = &table68k[opcode];
5616: for (i = 0; lookuptab[i].name[0]; i++) {
5617: if (ins->mnemo == lookuptab[i].mnemo)
5618: break;
5619: }
5620: {
1.1.1.7 root 5621: char *s = ua (lookuptab[i].name);
1.1.1.4 root 5622: strcpy (out, s);
1.1.1.7 root 5623: xfree (s);
1.1.1.4 root 5624: }
5625: if (ins->smode == immi)
5626: strcat (out, "Q");
5627: if (ins->size == sz_byte)
5628: strcat (out,".B");
5629: if (ins->size == sz_word)
5630: strcat (out,".W");
5631: if (ins->size == sz_long)
5632: strcat (out,".L");
5633: strcat (out," ");
5634: if (ins->suse)
5635: strcat (out, decodeEA (ins->smode, ins->size));
5636: if (ins->duse) {
5637: if (ins->suse) strcat (out,",");
5638: strcat (out, decodeEA (ins->dmode, ins->size));
5639: }
1.1.1.7 root 5640: if (ins->mnemo == i_DBcc || ins->mnemo == i_Scc || ins->mnemo == i_Bcc || ins->mnemo == i_TRAPcc) {
5641: strcat (out, " (");
5642: strcat (out, m68k_cc[table68k[opcode].cc]);
5643: strcat (out, ")");
5644: }
5645:
1.1.1.4 root 5646: return out;
5647: }
5648:
1.1.1.7 root 5649: struct cputbl_tmp
5650: {
5651: uae_s16 length;
5652: uae_s8 disp020[2];
5653: uae_u8 branch;
5654: };
5655: static struct cputbl_tmp cputbltmp[65536];
5656:
5657: static void generate_one_opcode (int rp, const char *extra)
1.1.1.4 root 5658: {
5659: int idx;
5660: uae_u16 smsk, dmsk;
1.1.1.7 root 5661: unsigned int opcode = opcode_map[rp];
1.1.1.4 root 5662: int i68000 = table68k[opcode].clev > 0;
5663:
5664: if (table68k[opcode].mnemo == i_ILLG
5665: || table68k[opcode].clev > cpu_level)
5666: return;
5667:
5668: for (idx = 0; lookuptab[idx].name[0]; idx++) {
5669: if (table68k[opcode].mnemo == lookuptab[idx].mnemo)
5670: break;
5671: }
5672:
5673: if (table68k[opcode].handler != -1)
5674: return;
5675:
5676: if (opcode_next_clev[rp] != cpu_level) {
1.1.1.7 root 5677: char *name = ua (lookuptab[idx].name);
1.1.1.4 root 5678: if (generate_stbl)
1.1.1.7 root 5679: fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, { %d, %d }, %d }, /* %s */\n",
5680: (using_ce || using_ce020) ? "(cpuop_func*)" : "",
5681: opcode, opcode_last_postfix[rp],
5682: extra, opcode,
5683: cputbltmp[opcode].length, cputbltmp[opcode].disp020[0], cputbltmp[opcode].disp020[1], cputbltmp[opcode].branch, name);
5684: xfree (name);
1.1.1.4 root 5685: return;
5686: }
1.1.1.7 root 5687: fprintf (headerfile, "extern %s op_%04x_%d%s_nf;\n",
5688: (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix, extra);
5689: fprintf (headerfile, "extern %s op_%04x_%d%s_ff;\n",
5690: (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix, extra);
1.1.1.4 root 5691: printf ("/* %s */\n", outopcode (opcode));
5692: if (i68000)
5693: printf("#ifndef CPUEMU_68000_ONLY\n");
1.1.1.7 root 5694: printf ("%s REGPARAM2 CPUFUNC(op_%04x_%d%s)(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "uae_u32", opcode, postfix, extra);
5695: if (using_simple_cycles)
5696: printf("\tint count_cycles = 0;\n");
1.1.1.4 root 5697:
5698: switch (table68k[opcode].stype) {
5699: case 0: smsk = 7; break;
5700: case 1: smsk = 255; break;
5701: case 2: smsk = 15; break;
5702: case 3: smsk = 7; break;
5703: case 4: smsk = 7; break;
5704: case 5: smsk = 63; break;
5705: case 7: smsk = 3; break;
1.1.1.7 root 5706: default: term ();
1.1.1.4 root 5707: }
5708: dmsk = 7;
5709:
5710: next_cpu_level = -1;
5711: if (table68k[opcode].suse
5712: && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
5713: && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
5714: && table68k[opcode].smode != absw && table68k[opcode].smode != absl
5715: && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
5716: {
5717: if (table68k[opcode].spos == -1) {
5718: if (((int) table68k[opcode].sreg) >= 128)
5719: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
5720: else
5721: printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg);
5722: } else {
5723: char source[100];
5724: int pos = table68k[opcode].spos;
5725:
5726: if (pos)
5727: sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
5728: else
5729: sprintf (source, "(opcode & %d)", smsk);
5730:
5731: if (table68k[opcode].stype == 3)
5732: printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
5733: else if (table68k[opcode].stype == 1)
5734: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
5735: else
5736: printf ("\tuae_u32 srcreg = %s;\n", source);
5737: }
5738: }
5739: if (table68k[opcode].duse
5740: /* Yes, the dmode can be imm, in case of LINK or DBcc */
5741: && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
5742: && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
5743: && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
5744: {
5745: if (table68k[opcode].dpos == -1) {
5746: if (((int) table68k[opcode].dreg) >= 128)
5747: printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
5748: else
5749: printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg);
5750: } else {
5751: int pos = table68k[opcode].dpos;
5752: if (pos)
5753: printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
5754: pos, dmsk);
5755: else
5756: printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
5757: }
5758: }
5759: need_endlabel = 0;
5760: endlabelno++;
1.1.1.7 root 5761: sprintf (endlabelstr, "l_%d", endlabelno);
1.1.1.4 root 5762: count_read = count_write = count_ncycles = count_cycles = 0;
1.1.1.7 root 5763: count_cycles_ce020 = 0;
1.1.1.4 root 5764: count_read_ea = count_write_ea = count_cycles_ea = 0;
5765: gen_opcode (opcode);
5766: if (need_endlabel)
5767: printf ("%s: ;\n", endlabelstr);
1.1.1.7 root 5768: clearmmufixup (0);
5769: clearmmufixup (1);
1.1.1.4 root 5770: if (using_ce || using_prefetch) {
5771: if (count_read + count_write + count_cycles == 0)
5772: count_cycles = 4;
1.1.1.7 root 5773: returncycles ("", (count_read + count_write) * 4 + count_cycles);
5774: printf ("}");
1.1.1.4 root 5775: printf (" /* %d%s (%d/%d)",
5776: (count_read + count_write) * 4 + count_cycles, count_ncycles ? "+" : "", count_read, count_write);
5777: printf (" */\n");
1.1.1.7 root 5778: #ifdef WINUAE_FOR_HATARI
5779: insn_n_cycles = (count_read + count_write) * 4 + count_cycles;
5780: #endif
5781: //printf ( "pom_%d %s %x %d\n" , postfix , lookuptab[idx].name , opcode , (count_read + count_write) * 4 + count_cycles );
5782: } else if (count_read + count_write) {
5783: returncycles ("", (count_read + count_write) * 4 + count_cycles);
5784: printf ("}");
5785: printf("\n");
5786: #ifdef WINUAE_FOR_HATARI
5787: insn_n_cycles = (count_read + count_write) * 4 + count_cycles;
5788: #endif
5789: //printf ( "pom_%d %s %x %d\n" , postfix , lookuptab[idx].name , opcode , (count_read + count_write) * 4 + count_cycles );
1.1.1.4 root 5790: } else {
1.1.1.7 root 5791: returncycles ("", insn_n_cycles);
5792: printf ("}");
1.1.1.4 root 5793: printf("\n");
1.1.1.7 root 5794: //printf ( "pom_%d %s %x %d\n" , postfix , lookuptab[idx].name , opcode , insn_n_cycles );
1.1.1.4 root 5795: }
5796: printf ("\n");
5797: if (i68000)
5798: printf("#endif\n");
5799: opcode_next_clev[rp] = next_cpu_level;
5800: opcode_last_postfix[rp] = postfix;
5801:
1.1.1.7 root 5802: if ((opcode & 0xf000) == 0xf000)
5803: m68k_pc_total = -1;
5804: cputbltmp[opcode].length = m68k_pc_total;
5805:
5806: cputbltmp[opcode].disp020[0] = 0;
5807: if (genamode8r_offset[0] > 0)
5808: cputbltmp[opcode].disp020[0] = m68k_pc_total - genamode8r_offset[0] + 2;
5809: cputbltmp[opcode].disp020[1] = 0;
5810: if (genamode8r_offset[1] > 0)
5811: cputbltmp[opcode].disp020[1] = m68k_pc_total - genamode8r_offset[1] + 2;
5812:
5813: cputbltmp[opcode].branch = branch_inst;
5814:
5815: #ifdef WINUAE_FOR_HATARI
5816: /* Hatari only : Now patch in the instruction cycles at the beginning of the function: */
1.1.1.4 root 5817: if (!using_ce020) {
5818: fseek(stdout, nCurInstrCycPos, SEEK_SET);
5819: printf("%d;", insn_n_cycles);
5820: fseek(stdout, 0, SEEK_END);
5821: }
1.1.1.7 root 5822: #endif
1.1.1.4 root 5823:
5824: if (generate_stbl) {
1.1.1.7 root 5825: char *name = ua (lookuptab[idx].name);
1.1.1.4 root 5826: if (i68000)
5827: fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
1.1.1.7 root 5828: fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), 0x%04x, %d, { %d, %d }, %d }, /* %s */\n",
1.1.1.4 root 5829: (using_ce || using_ce020) ? "(cpuop_func*)" : "",
1.1.1.7 root 5830: opcode, postfix, extra, opcode,
5831: cputbltmp[opcode].length, cputbltmp[opcode].disp020[0], cputbltmp[opcode].disp020[1], cputbltmp[opcode].branch, name);
1.1.1.4 root 5832: if (i68000)
5833: fprintf (stblfile, "#endif\n");
1.1.1.7 root 5834: xfree (name);
1.1.1.4 root 5835: }
5836: }
5837:
1.1.1.7 root 5838: static void generate_func (const char *extra)
1.1.1.4 root 5839: {
5840: int j, rp;
5841:
5842: /* sam: this is for people with low memory (eg. me :)) */
5843: printf ("\n"
5844: "#if !defined(PART_1) && !defined(PART_2) && "
5845: "!defined(PART_3) && !defined(PART_4) && "
5846: "!defined(PART_5) && !defined(PART_6) && "
5847: "!defined(PART_7) && !defined(PART_8)"
5848: "\n"
5849: "#define PART_1 1\n"
5850: "#define PART_2 1\n"
5851: "#define PART_3 1\n"
5852: "#define PART_4 1\n"
5853: "#define PART_5 1\n"
5854: "#define PART_6 1\n"
5855: "#define PART_7 1\n"
5856: "#define PART_8 1\n"
5857: "#endif\n\n");
5858:
5859: rp = 0;
5860: for(j = 1; j <= 8; ++j) {
5861: int k = (j * nr_cpuop_funcs) / 8;
5862: printf ("#ifdef PART_%d\n",j);
5863: for (; rp < k; rp++)
1.1.1.7 root 5864: generate_one_opcode (rp, extra);
1.1.1.4 root 5865: printf ("#endif\n\n");
5866: }
5867:
5868: if (generate_stbl)
5869: fprintf (stblfile, "{ 0, 0 }};\n");
5870: }
5871:
1.1.1.7 root 5872: static void generate_cpu (int id, int mode)
1.1.1.4 root 5873: {
5874: char fname[100];
1.1.1.7 root 5875: const char *extra, *extraup;
5876: static int postfix2 = -1;
5877: int rp;
5878:
5879: using_tracer = mode;
5880: extra = "";
5881: extraup = "";
5882: if (using_tracer) {
5883: extra = "_t";
5884: extraup = "_T";
5885: }
5886:
5887: postfix = id;
1.1.1.8 ! root 5888: if (id == 0 || id == 11 || id == 13 || id == 20 || id == 21 || id == 22 || id == 23 || id == 24 || id == 31 || id == 32 || id == 33 || id == 40 || id == 50) {
1.1.1.7 root 5889: if (generate_stbl)
5890: fprintf (stblfile, "#ifdef CPUEMU_%d%s\n", postfix, extraup);
5891: postfix2 = postfix;
5892: sprintf (fname, "cpuemu_%d%s.c", postfix, extra);
5893: if (freopen (fname, "wb", stdout) == NULL) {
5894: abort ();
5895: }
5896: generate_includes (stdout, id);
5897: }
5898:
5899: using_exception_3 = 1;
5900: using_prefetch = 0;
5901: using_prefetch_020 = 0;
5902: using_ce = 0;
5903: using_ce020 = 0;
5904: using_mmu = 0;
5905: using_waitstates = 0;
5906: memory_cycle_cnt = 4;
5907: mmu_postfix = "";
5908: using_simple_cycles = 0;
1.1.1.8 ! root 5909: using_indirect = 0;
! 5910: cpu_generic = false;
1.1.1.7 root 5911:
5912: #ifdef WINUAE_FOR_HATARI
5913: using_bus_error = 1; /* Enable code to handle bus error */
5914: #endif
5915:
5916: if (id == 11 || id == 12) { // 11 = 68010 prefetch, 12 = 68000 prefetch
5917: cpu_level = id == 11 ? 1 : 0;
5918: using_prefetch = 1;
5919: using_exception_3 = 1;
5920: using_simple_cycles = 1;
5921: if (id == 11) {
5922: read_counts ();
5923: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5924: opcode_next_clev[rp] = cpu_level;
5925: }
5926: } else if (id == 13 || id == 14) { // 13 = 68010 cycle-exact, 14 = 68000 cycle-exact
5927: cpu_level = id == 13 ? 1 : 0;
5928: using_prefetch = 1;
5929: using_exception_3 = 1;
5930: using_ce = 1;
5931: if (id == 13) {
5932: read_counts ();
5933: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5934: opcode_next_clev[rp] = cpu_level;
5935: }
5936: } else if (id == 20) { // 68020 prefetch
5937: cpu_level = 2;
5938: using_prefetch_020 = 1;
5939: read_counts ();
5940: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5941: opcode_next_clev[rp] = cpu_level;
5942: } else if (id == 21) { // 68020 cycle-exact
5943: cpu_level = 2;
5944: using_ce020 = 1;
5945: using_prefetch_020 = 1;
5946: // timing tables are from 030 which has 2
5947: // clock memory accesses, 68020 has 3 clock
5948: // memory accesses
5949: using_waitstates = 1;
5950: memory_cycle_cnt = 3;
5951: read_counts ();
5952: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5953: opcode_next_clev[rp] = cpu_level;
5954: } else if (id == 22) { // 68030 prefetch
5955: cpu_level = 3;
5956: using_prefetch_020 = 2;
5957: read_counts ();
5958: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5959: opcode_next_clev[rp] = cpu_level;
5960: } else if (id == 23) { // 68030 "cycle-exact"
5961: cpu_level = 3;
5962: using_ce020 = 2;
5963: using_prefetch_020 = 2;
5964: memory_cycle_cnt = 2;
5965: read_counts ();
5966: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5967: opcode_next_clev[rp] = cpu_level;
5968: } else if (id == 24 || id == 25) { // 68040/060 "cycle-exact"
5969: cpu_level = id == 24 ? 5 : 4;
5970: using_ce020 = 3;
5971: using_prefetch_020 = 3;
5972: memory_cycle_cnt = 0;
5973: if (id == 24) {
5974: read_counts();
5975: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5976: opcode_next_clev[rp] = cpu_level;
5977: }
5978: } else if (id == 31) { // 31 = 68040 MMU
5979: mmu_postfix = "040";
5980: cpu_level = 4;
5981: using_mmu = 68040;
5982: read_counts ();
5983: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5984: opcode_next_clev[rp] = cpu_level;
5985: } else if (id == 32) { // 32 = 68030 MMU
5986: mmu_postfix = "030";
5987: cpu_level = 3;
5988: using_mmu = 68030;
5989: read_counts ();
5990: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5991: opcode_next_clev[rp] = cpu_level;
5992: } else if (id == 33) { // 33 = 68060 MMU
5993: mmu_postfix = "060";
5994: cpu_level = 5;
5995: using_mmu = 68060;
5996: read_counts ();
5997: for (rp = 0; rp < nr_cpuop_funcs; rp++)
5998: opcode_next_clev[rp] = cpu_level;
5999: } else if (id < 6) {
1.1.1.8 ! root 6000: cpu_level = 5 - (id - 0); // "generic"
! 6001: cpu_generic = true;
1.1.1.7 root 6002: } else if (id >= 40 && id < 46) {
1.1.1.8 ! root 6003: cpu_level = 5 - (id - 40); // "generic" + direct
! 6004: cpu_generic = true;
1.1.1.7 root 6005: if (id == 40) {
6006: read_counts();
6007: for (rp = 0; rp < nr_cpuop_funcs; rp++)
6008: opcode_next_clev[rp] = cpu_level;
6009: }
1.1.1.8 ! root 6010: using_indirect = -1;
! 6011: } else if (id >= 50 && id < 56) {
! 6012: cpu_level = 5 - (id - 50); // "generic" + indirect
! 6013: cpu_generic = true;
! 6014: if (id == 50) {
! 6015: read_counts();
! 6016: for (rp = 0; rp < nr_cpuop_funcs; rp++)
! 6017: opcode_next_clev[rp] = cpu_level;
! 6018: }
! 6019: }
! 6020:
! 6021: if (!using_indirect)
! 6022: using_indirect = using_ce || using_ce020 || using_prefetch_020 || id >= 50;
1.1.1.7 root 6023:
6024: if (generate_stbl) {
1.1.1.8 ! root 6025: if ((id > 0 && id < 6) || (id >= 20 && id < 40) || (id > 40 && id < 46) || (id > 50 && id < 56))
1.1.1.7 root 6026: fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
6027: fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d%s)[] = {\n", postfix, extra);
6028: }
6029: endlabelno = id * 10000;
6030: generate_func (extra);
6031: if (generate_stbl) {
1.1.1.8 ! root 6032: if ((id > 0 && id < 6) || (id >= 20 && id < 40) || (id > 40 && id < 46) || (id > 50 && id < 56))
1.1.1.7 root 6033: fprintf (stblfile, "#endif /* CPUEMU_68000_ONLY */\n");
6034: if (postfix2 >= 0)
6035: fprintf (stblfile, "#endif /* CPUEMU_%d%s */\n", postfix2, extraup);
6036: }
6037: postfix2 = -1;
6038: }
6039:
6040: int main(int argc, char *argv[])
6041: {
6042: int i;
1.1.1.4 root 6043:
6044: read_table68k ();
6045: do_merges ();
6046:
6047: opcode_map = xmalloc (int, nr_cpuop_funcs);
6048: opcode_last_postfix = xmalloc (int, nr_cpuop_funcs);
6049: opcode_next_clev = xmalloc (int, nr_cpuop_funcs);
6050: counts = xmalloc (unsigned long, 65536);
6051: read_counts ();
6052:
6053: /* It would be a lot nicer to put all in one file (we'd also get rid of
6054: * cputbl.h that way), but cpuopti can't cope. That could be fixed, but
6055: * I don't dare to touch the 68k version. */
6056:
6057: headerfile = fopen ("cputbl.h", "wb");
6058:
6059: stblfile = fopen ("cpustbl.c", "wb");
1.1.1.7 root 6060: generate_includes (stblfile, 0);
1.1.1.4 root 6061:
1.1.1.8 ! root 6062: for (i = 0; i <= 55; i++) {
1.1.1.7 root 6063: if ((i >= 6 && i < 11) || (i > 14 && i < 20) || (i > 25 && i < 31) || (i > 33 && i < 40))
1.1.1.4 root 6064: continue;
6065: generate_stbl = 1;
1.1.1.7 root 6066: generate_cpu (i, 0);
1.1.1.4 root 6067: }
6068:
6069: free (table68k);
6070: return 0;
6071: }
6072:
6073: void write_log (const TCHAR *format,...)
6074: {
6075: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.