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