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