|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * MC68000 emulation generator ! 5: * ! 6: * This is a fairly stupid program that generates a lot of case labels that ! 7: * can be #included in a switch statement. ! 8: * As an alternative, it can generate functions that handle specific ! 9: * MC68000 instructions, plus a prototype header file and a function pointer ! 10: * array to look up the function for an opcode. ! 11: * Error checking is bad, an illegal table68k file will cause the program to ! 12: * call abort(). ! 13: * The generated code is sometimes sub-optimal, an optimizing compiler should ! 14: * take care of this. ! 15: * ! 16: * 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_ce020; ! 37: static int using_exception_3; ! 38: static int using_ce; ! 39: static int cpu_level; ! 40: static int count_read, count_write, count_cycles, count_ncycles; ! 41: static int count_read_ea, count_write_ea, count_cycles_ea; ! 42: ! 43: static int optimized_flags; ! 44: ! 45: #define GF_APDI 1 ! 46: #define GF_AD8R 2 ! 47: #define GF_PC8R 4 ! 48: #define GF_AA 7 ! 49: #define GF_NOREFILL 8 ! 50: #define GF_PREFETCH 16 ! 51: #define GF_FC 32 ! 52: #define GF_MOVE 64 ! 53: ! 54: /* For the current opcode, the next lower level that will have different code. ! 55: * Initialized to -1 for each opcode. If it remains unchanged, indicates we ! 56: * are done with that opcode. */ ! 57: static int next_cpu_level; ! 58: ! 59: static int *opcode_map; ! 60: static int *opcode_next_clev; ! 61: static int *opcode_last_postfix; ! 62: static unsigned long *counts; ! 63: static int generate_stbl; ! 64: static int fixupcnt; ! 65: ! 66: #define GENA_GETV_NO_FETCH 0 ! 67: #define GENA_GETV_FETCH 1 ! 68: #define GENA_GETV_FETCH_ALIGN 2 ! 69: #define GENA_MOVEM_DO_INC 0 ! 70: #define GENA_MOVEM_NO_INC 1 ! 71: #define GENA_MOVEM_MOVE16 2 ! 72: ! 73: static void read_counts (void) ! 74: { ! 75: FILE *file; ! 76: unsigned long opcode, count, total; ! 77: char name[20]; ! 78: int nr = 0; ! 79: int ret; ! 80: memset (counts, 0, 65536 * sizeof *counts); ! 81: ! 82: count = 0; ! 83: file = fopen ("frequent.68k", "r"); ! 84: if (file) { ! 85: ret = fscanf (file, "Total: %lu\n", &total); ! 86: while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) { ! 87: opcode_next_clev[nr] = 5; ! 88: opcode_last_postfix[nr] = -1; ! 89: opcode_map[nr++] = opcode; ! 90: counts[opcode] = count; ! 91: } ! 92: fclose (file); ! 93: } ! 94: if (nr == nr_cpuop_funcs) ! 95: return; ! 96: for (opcode = 0; opcode < 0x10000; opcode++) { ! 97: if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG ! 98: && counts[opcode] == 0) ! 99: { ! 100: opcode_next_clev[nr] = 5; ! 101: opcode_last_postfix[nr] = -1; ! 102: opcode_map[nr++] = opcode; ! 103: counts[opcode] = count; ! 104: } ! 105: } ! 106: if (nr != nr_cpuop_funcs) ! 107: abort (); ! 108: } ! 109: ! 110: static char endlabelstr[80]; ! 111: static int endlabelno = 0; ! 112: static int need_endlabel; ! 113: ! 114: static int n_braces, limit_braces; ! 115: static int m68k_pc_offset; ! 116: static int insn_n_cycles, insn_n_cycles020; ! 117: ! 118: static void fpulimit (void) ! 119: { ! 120: if (limit_braces) ! 121: return; ! 122: printf ("\n#ifdef FPUEMU\n"); ! 123: limit_braces = n_braces; ! 124: n_braces = 0; ! 125: } ! 126: static void cpulimit (void) ! 127: { ! 128: printf ("#ifndef CPUEMU_68000_ONLY\n"); ! 129: } ! 130: ! 131: static void returncycles (const char *s, int cycles) ! 132: { ! 133: if (using_ce) ! 134: return; ! 135: if (using_ce020) ! 136: printf ("%sreturn;\n", s); ! 137: else ! 138: printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles); ! 139: } ! 140: ! 141: static void addcycles_ce020 (int cycles) ! 142: { ! 143: if (!using_ce020) ! 144: return; ! 145: if (cycles > 0) ! 146: printf ("\tregs.ce020memcycles += %d * cpucycleunit;\n", cycles); ! 147: count_cycles += cycles; ! 148: } ! 149: static void addcycles000 (int cycles) ! 150: { ! 151: if (!using_ce) ! 152: return; ! 153: printf ("\tdo_cycles_ce000 (%d);\n", cycles); ! 154: count_cycles += cycles; ! 155: } ! 156: static void addcycles000_2 (const char *s, int cycles) ! 157: { ! 158: if (!using_ce) ! 159: return; ! 160: printf ("%sdo_cycles_ce000 (%d);\n", s, cycles); ! 161: count_cycles += cycles; ! 162: } ! 163: ! 164: static void addcycles000_3 (const char *s) ! 165: { ! 166: if (!using_ce) ! 167: return; ! 168: printf ("%sif (cycles > 0) do_cycles_ce000 (cycles);\n", s); ! 169: count_ncycles++; ! 170: } ! 171: ! 172: static int isreg (amodes mode) ! 173: { ! 174: if (mode == Dreg || mode == Areg) ! 175: return 1; ! 176: return 0; ! 177: } ! 178: ! 179: static void start_brace (void) ! 180: { ! 181: n_braces++; ! 182: printf ("{"); ! 183: } ! 184: ! 185: static void close_brace (void) ! 186: { ! 187: assert (n_braces > 0); ! 188: n_braces--; ! 189: printf ("}"); ! 190: } ! 191: ! 192: static void finish_braces (void) ! 193: { ! 194: while (n_braces > 0) ! 195: close_brace (); ! 196: } ! 197: ! 198: static void pop_braces (int to) ! 199: { ! 200: while (n_braces > to) ! 201: close_brace (); ! 202: } ! 203: ! 204: static int bit_size (int size) ! 205: { ! 206: switch (size) { ! 207: case sz_byte: return 8; ! 208: case sz_word: return 16; ! 209: case sz_long: return 32; ! 210: default: abort (); ! 211: } ! 212: return 0; ! 213: } ! 214: ! 215: static const char *bit_mask (int size) ! 216: { ! 217: switch (size) { ! 218: case sz_byte: return "0xff"; ! 219: case sz_word: return "0xffff"; ! 220: case sz_long: return "0xffffffff"; ! 221: default: abort (); ! 222: } ! 223: return 0; ! 224: } ! 225: ! 226: static const char *srcl, *dstl; ! 227: static const char *srcw, *dstw; ! 228: static const char *srcb, *dstb; ! 229: static const char *ce020_prefetch_long; ! 230: static const char *ce020_prefetch_word; ! 231: ! 232: static void gen_nextilong (const char *type, const char *name, int flags) ! 233: { ! 234: int r = m68k_pc_offset; ! 235: m68k_pc_offset += 4; ! 236: ! 237: if (using_ce020) { ! 238: printf ("\t%s %s = %s (%d);\n", type, name, ce020_prefetch_long, r); ! 239: count_read += 2; ! 240: } else if (using_ce) { ! 241: printf ("\t%s %s;\n", type, name); ! 242: /* we must do this because execution order of (something | something2) is not defined */ ! 243: if (flags & GF_NOREFILL) { ! 244: printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2); ! 245: count_read++; ! 246: printf ("\t%s |= regs.irc;\n", name); ! 247: } else { ! 248: printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2); ! 249: count_read++; ! 250: printf ("\t%s |= get_word_ce_prefetch (%d);\n", name, r + 4); ! 251: count_read++; ! 252: } ! 253: } else { ! 254: if (using_prefetch) { ! 255: if (flags & GF_NOREFILL) { ! 256: printf ("\t%s %s;\n", type, name); ! 257: printf ("\t%s = get_word_prefetch (%d) << 16;\n", name, r + 2); ! 258: count_read++; ! 259: printf ("\t%s |= regs.irc;\n", name); ! 260: insn_n_cycles += 4; ! 261: } else { ! 262: printf ("\t%s %s = get_long_prefetch (%d);\n", type, name, r + 2); ! 263: count_read++; ! 264: count_read++; ! 265: insn_n_cycles += 8; ! 266: } ! 267: } else if (using_indirect) { ! 268: insn_n_cycles += 8; ! 269: printf ("\t%s %s = get_ilongi (%d);\n", type, name, r); ! 270: } else if (using_mmu) { ! 271: insn_n_cycles += 8; ! 272: printf ("\t%s %s = get_ilong_mmu (%d);\n", type, name, r); ! 273: } else { ! 274: insn_n_cycles += 8; ! 275: printf ("\t%s %s = get_ilong (%d);\n", type, name, r); ! 276: } ! 277: } ! 278: } ! 279: ! 280: static const char *gen_nextiword (int flags) ! 281: { ! 282: static char buffer[80]; ! 283: int r = m68k_pc_offset; ! 284: m68k_pc_offset += 2; ! 285: ! 286: if (using_ce020) { ! 287: sprintf (buffer, "%s (%d)", ce020_prefetch_word, r); ! 288: count_read++; ! 289: } else if (using_ce) { ! 290: if (flags & GF_NOREFILL) { ! 291: strcpy (buffer, "regs.irc"); ! 292: } else { ! 293: sprintf (buffer, "get_word_ce_prefetch (%d)", r + 2); ! 294: count_read++; ! 295: } ! 296: } else { ! 297: if (using_prefetch) { ! 298: if (flags & GF_NOREFILL) { ! 299: sprintf (buffer, "regs.irc"/*, r*/); ! 300: } else { ! 301: sprintf (buffer, "get_word_prefetch (%d)", r + 2); ! 302: count_read++; ! 303: insn_n_cycles += 4; ! 304: } ! 305: } else if (using_indirect) { ! 306: sprintf (buffer, "get_iwordi(%d)", r); ! 307: insn_n_cycles += 4; ! 308: } else if (using_mmu) { ! 309: sprintf (buffer, "get_iword_mmu (%d)", r); ! 310: insn_n_cycles += 4; ! 311: } else { ! 312: sprintf (buffer, "get_iword (%d)", r); ! 313: insn_n_cycles += 4; ! 314: } ! 315: } ! 316: return buffer; ! 317: } ! 318: ! 319: static const char *gen_nextibyte (int flags) ! 320: { ! 321: static char buffer[80]; ! 322: int r = m68k_pc_offset; ! 323: m68k_pc_offset += 2; ! 324: ! 325: if (using_ce020) { ! 326: sprintf (buffer, "(uae_u8)%s (%d)", ce020_prefetch_word, r); ! 327: count_read++; ! 328: } else if (using_ce) { ! 329: if (flags & GF_NOREFILL) { ! 330: strcpy (buffer, "(uae_u8)regs.irc"); ! 331: } else { ! 332: sprintf (buffer, "(uae_u8)get_word_ce_prefetch (%d)", r + 2); ! 333: count_read++; ! 334: } ! 335: } else { ! 336: insn_n_cycles += 4; ! 337: if (using_prefetch) { ! 338: if (flags & GF_NOREFILL) { ! 339: sprintf (buffer, "(uae_u8)regs.irc"/*, r*/); ! 340: } else { ! 341: sprintf (buffer, "(uae_u8)get_word_prefetch (%d)", r + 2); ! 342: insn_n_cycles += 4; ! 343: count_read++; ! 344: } ! 345: } else if (using_indirect) { ! 346: sprintf (buffer, "get_ibytei (%d)", r); ! 347: insn_n_cycles += 4; ! 348: } else if (using_mmu) { ! 349: sprintf (buffer, "get_ibyte_mmu (%d)", r); ! 350: insn_n_cycles += 4; ! 351: } else { ! 352: sprintf (buffer, "get_ibyte (%d)", r); ! 353: insn_n_cycles += 4; ! 354: } ! 355: } ! 356: return buffer; ! 357: } ! 358: ! 359: static void irc2ir (void) ! 360: { ! 361: if (!using_prefetch) ! 362: return; ! 363: printf ("\tregs.ir = regs.irc;\n"); ! 364: if (using_ce) ! 365: printf ("\tipl_fetch ();\n"); ! 366: } ! 367: ! 368: static int did_prefetch; ! 369: ! 370: static void fill_prefetch_2 (void) ! 371: { ! 372: if (!using_prefetch) ! 373: return; ! 374: if (using_ce) ! 375: printf ("\tget_word_ce_prefetch (%d);\n", m68k_pc_offset + 2); ! 376: else ! 377: printf ("\tget_word_prefetch (%d);\n", m68k_pc_offset + 2); ! 378: did_prefetch = 1; ! 379: count_read++; ! 380: insn_n_cycles += 4; ! 381: } ! 382: ! 383: static void fill_prefetch_1 (int o) ! 384: { ! 385: if (!using_prefetch) ! 386: return; ! 387: if (using_ce) { ! 388: printf ("\tget_word_ce_prefetch (%d);\n", o); ! 389: } else { ! 390: printf ("\tget_word_prefetch (%d);\n", o); ! 391: } ! 392: did_prefetch = 1; ! 393: count_read++; ! 394: insn_n_cycles += 4; ! 395: } ! 396: ! 397: static void fill_prefetch_full (void) ! 398: { ! 399: fill_prefetch_1 (0); ! 400: irc2ir (); ! 401: fill_prefetch_1 (2); ! 402: } ! 403: ! 404: static void fill_prefetch_0 (void) ! 405: { ! 406: if (!using_prefetch) ! 407: return; ! 408: if (using_ce) ! 409: printf ("\tget_word_ce_prefetch (0);\n"); ! 410: else ! 411: printf ("\tget_word_prefetch (0);\n"); ! 412: did_prefetch = 1; ! 413: count_read++; ! 414: insn_n_cycles += 4; ! 415: } ! 416: ! 417: static void dummy_prefetch (void) ! 418: { ! 419: int o = m68k_pc_offset + 2; ! 420: if (!using_prefetch) ! 421: return; ! 422: if (using_ce) { ! 423: printf ("\tget_wordi_ce (m68k_getpc () + %d);\n", o); ! 424: } else { ! 425: printf ("\tget_wordi (m68k_getpc () + %d);\n", o); ! 426: } ! 427: count_read++; ! 428: insn_n_cycles += 4; ! 429: } ! 430: ! 431: static void fill_prefetch_next_1 (void) ! 432: { ! 433: irc2ir (); ! 434: fill_prefetch_1 (m68k_pc_offset + 2); ! 435: } ! 436: ! 437: static void fill_prefetch_next (void) ! 438: { ! 439: fill_prefetch_next_1 (); ! 440: } ! 441: ! 442: #if 0 ! 443: static void fill_prefetch_next_delay (int extracycles) ! 444: { ! 445: if (!using_prefetch) ! 446: return; ! 447: if (using_ce) { ! 448: if (extracycles > 0) { ! 449: printf("\t{\n"); ! 450: fill_prefetch_next (); ! 451: printf("\tif (%d > 0) do_cycles(%d * CYCLE_UNIT / 2);\n", ! 452: extracycles, extracycles); ! 453: printf("\t}\n"); ! 454: } else { ! 455: fill_prefetch_next (); ! 456: } ! 457: } else { ! 458: fill_prefetch_next (); ! 459: } ! 460: } ! 461: #endif ! 462: ! 463: static void fill_prefetch_finish (void) ! 464: { ! 465: if (did_prefetch || !using_prefetch) ! 466: return; ! 467: fill_prefetch_1 (m68k_pc_offset); ! 468: } ! 469: ! 470: static void setpc (const char *format, ...) ! 471: { ! 472: va_list parms; ! 473: char buffer[1000]; ! 474: ! 475: va_start (parms, format); ! 476: _vsnprintf (buffer, 1000 - 1, format, parms); ! 477: va_end (parms); ! 478: ! 479: if (using_mmu) ! 480: printf ("\tm68k_setpc_mmu (%s);\n", buffer); ! 481: else ! 482: printf ("\tm68k_setpc (%s);\n", buffer); ! 483: } ! 484: ! 485: static void incpc (const char *format, ...) ! 486: { ! 487: va_list parms; ! 488: char buffer[1000]; ! 489: ! 490: va_start (parms, format); ! 491: _vsnprintf (buffer, 1000 - 1, format, parms); ! 492: va_end (parms); ! 493: ! 494: if (using_mmu) ! 495: printf ("\tm68k_incpci (%s);\n", buffer); ! 496: else ! 497: printf ("\tm68k_incpc (%s);\n", buffer); ! 498: } ! 499: ! 500: static void sync_m68k_pc (void) ! 501: { ! 502: if (m68k_pc_offset == 0) ! 503: return; ! 504: incpc ("%d", m68k_pc_offset); ! 505: m68k_pc_offset = 0; ! 506: } ! 507: ! 508: static void gen_set_fault_pc (void) ! 509: { ! 510: if (!using_mmu) ! 511: return; ! 512: sync_m68k_pc (); ! 513: printf ("\tregs.fault_pc = m68k_getpci ();\n"); ! 514: m68k_pc_offset = 0; ! 515: } ! 516: ! 517: static void syncmovepc (int getv, int flags) ! 518: { ! 519: #if 0 ! 520: if (!(flags & GF_MOVE)) ! 521: return; ! 522: if (getv == 1) { ! 523: sync_m68k_pc (); ! 524: //fill_prefetch_next (); ! 525: } ! 526: #endif ! 527: } ! 528: ! 529: /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, ! 530: * the calling routine handles Apdi and Aipi modes. ! 531: * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ ! 532: ! 533: /* fixup indicates if we want to fix up adress registers in pre decrement ! 534: * or post increment mode now (0) or later (1). A value of 2 will then be ! 535: * used to do the actual fix up. This allows to do all memory readings ! 536: * before any register is modified, and so to rerun operation without ! 537: * side effect in case a bus fault is generated by any memory access. ! 538: * XJ - 2006/11/13 */ ! 539: ! 540: static void genamode2 (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags, int fixup) ! 541: { ! 542: char namea[100]; ! 543: int m68k_pc_offset_last = m68k_pc_offset; ! 544: ! 545: sprintf (namea, "%sa", name); ! 546: ! 547: start_brace (); ! 548: switch (mode) { ! 549: case Dreg: ! 550: if (movem) ! 551: abort (); ! 552: if (getv == 1) ! 553: switch (size) { ! 554: case sz_byte: ! 555: #ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION ! 556: /* This causes the target compiler to generate better code on few systems */ ! 557: printf ("\tuae_s8 %s = ((uae_u8*)&m68k_dreg (regs, %s))[3];\n", name, reg); ! 558: #else ! 559: printf ("\tuae_s8 %s = m68k_dreg (regs, %s);\n", name, reg); ! 560: #endif ! 561: break; ! 562: case sz_word: ! 563: #ifdef USE_DUBIOUS_BIGENDIAN_OPTIMIZATION ! 564: printf ("\tuae_s16 %s = ((uae_s16*)&m68k_dreg (regs, %s))[1];\n", name, reg); ! 565: #else ! 566: printf ("\tuae_s16 %s = m68k_dreg (regs, %s);\n", name, reg); ! 567: #endif ! 568: break; ! 569: case sz_long: ! 570: printf ("\tuae_s32 %s = m68k_dreg (regs, %s);\n", name, reg); ! 571: break; ! 572: default: ! 573: abort (); ! 574: } ! 575: syncmovepc (getv, flags); ! 576: return; ! 577: case Areg: ! 578: if (movem) ! 579: abort (); ! 580: if (getv == 1) ! 581: switch (size) { ! 582: case sz_word: ! 583: printf ("\tuae_s16 %s = m68k_areg (regs, %s);\n", name, reg); ! 584: break; ! 585: case sz_long: ! 586: printf ("\tuae_s32 %s = m68k_areg (regs, %s);\n", name, reg); ! 587: break; ! 588: default: ! 589: abort (); ! 590: } ! 591: syncmovepc (getv, flags); ! 592: return; ! 593: case Aind: // (An) ! 594: printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg); ! 595: break; ! 596: case Aipi: // (An)+ ! 597: printf ("\tuaecptr %sa = m68k_areg (regs, %s);\n", name, reg); ! 598: break; ! 599: case Apdi: // -(An) ! 600: printf ("\tuaecptr %sa;\n", name); ! 601: switch (size) { ! 602: case sz_byte: ! 603: if (movem) ! 604: printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg); ! 605: else ! 606: printf ("\t%sa = m68k_areg (regs, %s) - areg_byteinc[%s];\n", name, reg, reg); ! 607: break; ! 608: case sz_word: ! 609: printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 2); ! 610: break; ! 611: case sz_long: ! 612: printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 4); ! 613: break; ! 614: default: ! 615: abort (); ! 616: } ! 617: if (!(flags & GF_APDI)) { ! 618: addcycles000 (2); ! 619: insn_n_cycles += 2; ! 620: count_cycles_ea += 2; ! 621: } ! 622: break; ! 623: case Ad16: // (d16,An) ! 624: printf ("\tuaecptr %sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags)); ! 625: count_read_ea++; ! 626: break; ! 627: case Ad8r: // (d8,An,Xn) ! 628: printf ("\tuaecptr %sa;\n", name); ! 629: if (cpu_level > 1) { ! 630: if (next_cpu_level < 1) ! 631: next_cpu_level = 1; ! 632: sync_m68k_pc (); ! 633: start_brace (); ! 634: /* This would ordinarily be done in gen_nextiword, which we bypass. */ ! 635: insn_n_cycles += 4; ! 636: if (using_ce020 || using_mmu) ! 637: printf ("\t%sa = x_get_disp_ea_020 (m68k_areg (regs, %s), x_next_iword ());\n", name, reg); ! 638: else ! 639: printf ("\t%sa = get_disp_ea_020 (m68k_areg (regs, %s), next_iword ());\n", name, reg); ! 640: } else { ! 641: if (!(flags & GF_AD8R)) { ! 642: addcycles000 (2); ! 643: insn_n_cycles += 2; ! 644: count_cycles_ea += 2; ! 645: } ! 646: printf ("\t%sa = get_disp_ea_000 (m68k_areg (regs, %s), %s);\n", name, reg, gen_nextiword (flags)); ! 647: count_read_ea++; ! 648: } ! 649: break; ! 650: case PC16: // (d16,PC,Xn) ! 651: printf ("\tuaecptr %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset); ! 652: printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags)); ! 653: break; ! 654: case PC8r: // (d8,PC,Xn) ! 655: printf ("\tuaecptr tmppc;\n"); ! 656: printf ("\tuaecptr %sa;\n", name); ! 657: if (cpu_level > 1) { ! 658: if (next_cpu_level < 1) ! 659: next_cpu_level = 1; ! 660: sync_m68k_pc (); ! 661: start_brace (); ! 662: /* This would ordinarily be done in gen_nextiword, which we bypass. */ ! 663: insn_n_cycles += 4; ! 664: printf ("\ttmppc = m68k_getpc ();\n"); ! 665: if (using_ce020 || using_mmu) ! 666: printf ("\t%sa = x_get_disp_ea_020 (tmppc, x_next_iword ());\n", name); ! 667: else ! 668: printf ("\t%sa = get_disp_ea_020 (tmppc, next_iword ());\n", name); ! 669: } else { ! 670: printf ("\ttmppc = m68k_getpc () + %d;\n", m68k_pc_offset); ! 671: if (!(flags & GF_PC8R)) { ! 672: addcycles000 (2); ! 673: insn_n_cycles += 2; ! 674: count_cycles_ea += 2; ! 675: } ! 676: printf ("\t%sa = get_disp_ea_000 (tmppc, %s);\n", name, gen_nextiword (flags)); ! 677: } ! 678: ! 679: break; ! 680: case absw: ! 681: printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags)); ! 682: break; ! 683: case absl: ! 684: gen_nextilong ("uaecptr", namea, flags); ! 685: count_read_ea += 2; ! 686: break; ! 687: case imm: ! 688: if (getv != 1) ! 689: abort (); ! 690: insn_n_cycles020++; ! 691: switch (size) { ! 692: case sz_byte: ! 693: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags)); ! 694: count_read_ea++; ! 695: break; ! 696: case sz_word: ! 697: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags)); ! 698: count_read_ea++; ! 699: break; ! 700: case sz_long: ! 701: gen_nextilong ("uae_s32", name, flags); ! 702: count_read_ea += 2; ! 703: break; ! 704: default: ! 705: abort (); ! 706: } ! 707: syncmovepc (getv, flags); ! 708: return; ! 709: case imm0: ! 710: if (getv != 1) ! 711: abort (); ! 712: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags)); ! 713: count_read_ea++; ! 714: syncmovepc (getv, flags); ! 715: return; ! 716: case imm1: ! 717: if (getv != 1) ! 718: abort (); ! 719: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags)); ! 720: count_read_ea++; ! 721: syncmovepc (getv, flags); ! 722: return; ! 723: case imm2: ! 724: if (getv != 1) ! 725: abort (); ! 726: gen_nextilong ("uae_s32", name, flags); ! 727: count_read_ea += 2; ! 728: syncmovepc (getv, flags); ! 729: return; ! 730: case immi: ! 731: if (getv != 1) ! 732: abort (); ! 733: printf ("\tuae_u32 %s = %s;\n", name, reg); ! 734: syncmovepc (getv, flags); ! 735: return; ! 736: default: ! 737: abort (); ! 738: } ! 739: ! 740: syncmovepc (getv, flags); ! 741: ! 742: /* We get here for all non-reg non-immediate addressing modes to ! 743: * actually fetch the value. */ ! 744: ! 745: if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte) { ! 746: int offset = 0; ! 747: if (flags & GF_MOVE) { ! 748: offset = m68k_pc_offset; ! 749: if (getv == 2) ! 750: offset += 2; ! 751: } else { ! 752: offset = m68k_pc_offset_last; ! 753: } ! 754: printf ("\tif (%sa & 1) {\n", name); ! 755: printf ("\t\texception3 (opcode, m68k_getpc () + %d, %sa);\n", ! 756: offset, name); ! 757: printf ("\t\tgoto %s;\n", endlabelstr); ! 758: printf ("\t}\n"); ! 759: need_endlabel = 1; ! 760: start_brace (); ! 761: } ! 762: ! 763: if (flags & GF_PREFETCH) ! 764: fill_prefetch_next (); ! 765: ! 766: if (getv == 1) { ! 767: start_brace (); ! 768: if (using_ce020) { ! 769: switch (size) { ! 770: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break; ! 771: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break; ! 772: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srcl, name); count_read += 2; break; ! 773: default: abort (); ! 774: } ! 775: } else if (using_ce) { ! 776: switch (size) { ! 777: case sz_byte: printf ("\tuae_s8 %s = get_byte_ce (%sa);\n", name, name); count_read++; break; ! 778: case sz_word: printf ("\tuae_s16 %s = get_word_ce (%sa);\n", name, name); count_read++; break; ! 779: case sz_long: printf ("\tuae_s32 %s = get_word_ce (%sa) << 16; %s |= get_word_ce (%sa + 2);\n", name, name, name, name); count_read += 2; break; ! 780: default: abort (); ! 781: } ! 782: } else if (using_mmu) { ! 783: if (flags & GF_FC) { ! 784: switch (size) { ! 785: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = sfc_get_byte (%sa);\n", name, name); break; ! 786: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = sfc_get_word (%sa);\n", name, name); break; ! 787: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = sfc_get_long (%sa);\n", name, name); break; ! 788: default: abort (); ! 789: } ! 790: } else { ! 791: switch (size) { ! 792: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_mmu (%sa);\n", name, name); break; ! 793: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_mmu (%sa);\n", name, name); break; ! 794: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_mmu (%sa);\n", name, name); break; ! 795: default: abort (); ! 796: } ! 797: } ! 798: } else { ! 799: switch (size) { ! 800: case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte (%sa);\n", name, name); count_read++; break; ! 801: case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word (%sa);\n", name, name); count_read++; break; ! 802: case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long (%sa);\n", name, name); count_read += 2; break; ! 803: default: abort (); ! 804: } ! 805: } ! 806: } ! 807: ! 808: /* We now might have to fix up the register for pre-dec or post-inc ! 809: * addressing modes. */ ! 810: if (!movem) ! 811: switch (mode) { ! 812: case Aipi: ! 813: if (fixup == 1) { ! 814: printf ("\tmmufixup[%d].reg = %s;\n", fixupcnt, reg); ! 815: printf ("\tmmufixup[%d].value = m68k_areg (regs, %s);\n", fixupcnt, reg); ! 816: } ! 817: switch (size) { ! 818: case sz_byte: ! 819: printf ("\tm68k_areg (regs, %s) += areg_byteinc[%s];\n", reg, reg); ! 820: break; ! 821: case sz_word: ! 822: printf ("\tm68k_areg (regs, %s) += 2;\n", reg); ! 823: break; ! 824: case sz_long: ! 825: printf ("\tm68k_areg (regs, %s) += 4;\n", reg); ! 826: break; ! 827: default: ! 828: abort (); ! 829: } ! 830: break; ! 831: case Apdi: ! 832: if (fixup == 1) { ! 833: printf ("\tmmufixup[%d].reg = %s;\n", fixupcnt, reg); ! 834: printf ("\tmmufixup[%d].value = m68k_areg (regs, %s);\n", fixupcnt, reg); ! 835: } ! 836: printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name); ! 837: break; ! 838: default: ! 839: break; ! 840: } ! 841: } ! 842: ! 843: static void genamode_fixup (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags, int fixup) ! 844: { ! 845: if (fixup != 2) { ! 846: genamode2 (mode, reg, size, name, getv, movem, flags, fixup); ! 847: } else { ! 848: if (!movem) { ! 849: switch ((int)mode) ! 850: { ! 851: case Aipi: ! 852: case Apdi: ! 853: printf ("\tmmufixup[0].reg = -1;\n"/*, fixupcnt*/); ! 854: break; ! 855: } ! 856: } ! 857: } ! 858: } ! 859: ! 860: static void genamode (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags) ! 861: { ! 862: genamode2 (mode, reg, size, name, getv, movem, flags, 0); ! 863: } ! 864: static void genamode_pre (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags) ! 865: { ! 866: genamode_fixup (mode, reg, size, name, getv, movem, flags, using_mmu ? 1 : 0); ! 867: } ! 868: static void genamode_post (amodes mode, const char *reg, wordsizes size, const char *name, int getv, int movem, int flags) ! 869: { ! 870: if (using_mmu) ! 871: genamode_fixup (mode, reg, size, name, getv, movem, flags, 2); ! 872: } ! 873: ! 874: static void genastore_2 (const char *from, amodes mode, const char *reg, wordsizes size, const char *to, int store_dir, int flags) ! 875: { ! 876: switch (mode) { ! 877: case Dreg: ! 878: switch (size) { ! 879: case sz_byte: ! 880: printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from); ! 881: break; ! 882: case sz_word: ! 883: printf ("\tm68k_dreg (regs, %s) = (m68k_dreg (regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from); ! 884: break; ! 885: case sz_long: ! 886: printf ("\tm68k_dreg (regs, %s) = (%s);\n", reg, from); ! 887: break; ! 888: default: ! 889: abort (); ! 890: } ! 891: break; ! 892: case Areg: ! 893: switch (size) { ! 894: case sz_word: ! 895: printf ("\tm68k_areg (regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from); ! 896: break; ! 897: case sz_long: ! 898: printf ("\tm68k_areg (regs, %s) = (%s);\n", reg, from); ! 899: break; ! 900: default: ! 901: abort (); ! 902: } ! 903: break; ! 904: case Aind: ! 905: case Aipi: ! 906: case Apdi: ! 907: case Ad16: ! 908: case Ad8r: ! 909: case absw: ! 910: case absl: ! 911: case PC16: ! 912: case PC8r: ! 913: gen_set_fault_pc (); ! 914: if (using_ce020) { ! 915: switch (size) { ! 916: case sz_byte: ! 917: printf ("\t%s (%sa, %s);\n", dstb, to, from); ! 918: count_write++; ! 919: break; ! 920: case sz_word: ! 921: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 922: abort (); ! 923: printf ("\t%s (%sa, %s);\n", dstw, to, from); ! 924: count_write++; ! 925: break; ! 926: case sz_long: ! 927: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 928: abort (); ! 929: printf ("\t%s (%sa, %s);\n", dstl, to, from); ! 930: count_write += 2; ! 931: break; ! 932: default: ! 933: abort (); ! 934: } ! 935: } else if (using_ce) { ! 936: switch (size) { ! 937: case sz_byte: ! 938: printf ("\tput_byte_ce (%sa, %s);\n", to, from); ! 939: count_write++; ! 940: break; ! 941: case sz_word: ! 942: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 943: abort (); ! 944: printf ("\tput_word_ce (%sa, %s);\n", to, from); ! 945: count_write++; ! 946: break; ! 947: case sz_long: ! 948: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 949: abort (); ! 950: if (store_dir) ! 951: printf ("\tput_word_ce (%sa + 2, %s); put_word_ce (%sa, %s >> 16);\n", to, from, to, from); ! 952: else ! 953: printf ("\tput_word_ce (%sa, %s >> 16); put_word_ce (%sa + 2, %s);\n", to, from, to, from); ! 954: count_write += 2; ! 955: break; ! 956: default: ! 957: abort (); ! 958: } ! 959: } else if (using_mmu) { ! 960: switch (size) { ! 961: case sz_byte: ! 962: insn_n_cycles += 4; ! 963: if (flags & GF_FC) ! 964: printf ("\tdfc_put_byte (%sa, %s);\n", to, from); ! 965: else ! 966: printf ("\tput_byte_mmu (%sa, %s);\n", to, from); ! 967: break; ! 968: case sz_word: ! 969: insn_n_cycles += 4; ! 970: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 971: abort (); ! 972: if (flags & GF_FC) ! 973: printf ("\tdfc_put_word (%sa, %s);\n", to, from); ! 974: else ! 975: printf ("\tput_word_mmu (%sa, %s);\n", to, from); ! 976: break; ! 977: case sz_long: ! 978: insn_n_cycles += 8; ! 979: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 980: abort (); ! 981: if (flags & GF_FC) ! 982: printf ("\tdfc_put_long (%sa, %s);\n", to, from); ! 983: else ! 984: printf ("\tput_long_mmu (%sa, %s);\n", to, from); ! 985: break; ! 986: default: ! 987: abort (); ! 988: } ! 989: } else { ! 990: switch (size) { ! 991: case sz_byte: ! 992: insn_n_cycles += 4; ! 993: printf ("\tput_byte (%sa, %s);\n", to, from); ! 994: count_write++; ! 995: break; ! 996: case sz_word: ! 997: insn_n_cycles += 4; ! 998: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 999: abort (); ! 1000: printf ("\tput_word (%sa, %s);\n", to, from); ! 1001: count_write++; ! 1002: break; ! 1003: case sz_long: ! 1004: insn_n_cycles += 8; ! 1005: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 1006: abort (); ! 1007: printf ("\tput_long (%sa, %s);\n", to, from); ! 1008: count_write += 2; ! 1009: break; ! 1010: default: ! 1011: abort (); ! 1012: } ! 1013: } ! 1014: break; ! 1015: case imm: ! 1016: case imm0: ! 1017: case imm1: ! 1018: case imm2: ! 1019: case immi: ! 1020: abort (); ! 1021: break; ! 1022: default: ! 1023: abort (); ! 1024: } ! 1025: } ! 1026: ! 1027: static void genastore (const char *from, amodes mode, const char *reg, wordsizes size, const char *to) ! 1028: { ! 1029: genastore_2 (from, mode, reg, size, to, 0, 0); ! 1030: } ! 1031: static void genastore_rev (const char *from, amodes mode, const char *reg, wordsizes size, const char *to) ! 1032: { ! 1033: genastore_2 (from, mode, reg, size, to, 1, 0); ! 1034: } ! 1035: static void genastore_fc (const char *from, amodes mode, const char *reg, wordsizes size, const char *to) ! 1036: { ! 1037: genastore_2 (from, mode, reg, size, to, 1, GF_FC); ! 1038: } ! 1039: ! 1040: static void genmovemel (uae_u16 opcode) ! 1041: { ! 1042: char getcode[100]; ! 1043: int size = table68k[opcode].size == sz_long ? 4 : 2; ! 1044: ! 1045: if (table68k[opcode].size == sz_long) { ! 1046: sprintf (getcode, "%s (srca)", srcl); ! 1047: } else { ! 1048: sprintf (getcode, "(uae_s32)(uae_s16)%s (srca)", srcw); ! 1049: } ! 1050: count_read += table68k[opcode].size == sz_long ? 2 : 1; ! 1051: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); ! 1052: printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); ! 1053: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0); ! 1054: start_brace (); ! 1055: printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask]; }\n", ! 1056: getcode, size); ! 1057: printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask]; }\n", ! 1058: getcode, size); ! 1059: ! 1060: if (table68k[opcode].dmode == Aipi) { ! 1061: printf ("\tm68k_areg (regs, dstreg) = srca;\n"); ! 1062: count_read++; ! 1063: } ! 1064: count_ncycles++; ! 1065: fill_prefetch_next (); ! 1066: } ! 1067: ! 1068: static void genmovemel_ce (uae_u16 opcode) ! 1069: { ! 1070: int size = table68k[opcode].size == sz_long ? 4 : 2; ! 1071: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); ! 1072: printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); ! 1073: printf ("\tuae_u32 v;\n"); ! 1074: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA); ! 1075: if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) ! 1076: addcycles000 (2); ! 1077: start_brace (); ! 1078: if (table68k[opcode].size == sz_long) { ! 1079: printf ("\twhile (dmask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_dreg (regs, movem_index1[dmask]) = v; srca += %d; dmask = movem_next[dmask]; }\n", ! 1080: size); ! 1081: printf ("\twhile (amask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_areg (regs, movem_index1[amask]) = v; srca += %d; amask = movem_next[amask]; }\n", ! 1082: size); ! 1083: } else { ! 1084: printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; dmask = movem_next[dmask]; }\n", ! 1085: size); ! 1086: printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; amask = movem_next[amask]; }\n", ! 1087: size); ! 1088: } ! 1089: printf ("\tget_word_ce (srca);\n"); // and final extra word fetch that goes nowhere.. ! 1090: count_read++; ! 1091: if (table68k[opcode].dmode == Aipi) ! 1092: printf ("\tm68k_areg (regs, dstreg) = srca;\n"); ! 1093: count_ncycles++; ! 1094: fill_prefetch_next (); ! 1095: } ! 1096: ! 1097: static void genmovemle (uae_u16 opcode) ! 1098: { ! 1099: char putcode[100]; ! 1100: int size = table68k[opcode].size == sz_long ? 4 : 2; ! 1101: ! 1102: if (table68k[opcode].size == sz_long) { ! 1103: sprintf (putcode, "%s (srca", dstl); ! 1104: } else { ! 1105: sprintf (putcode, "%s (srca", dstw); ! 1106: } ! 1107: count_write += table68k[opcode].size == sz_long ? 2 : 1; ! 1108: ! 1109: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); ! 1110: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0); ! 1111: start_brace (); ! 1112: if (table68k[opcode].dmode == Apdi) { ! 1113: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); ! 1114: if (!using_mmu) ! 1115: printf ("\tint type = get_cpu_model() >= 68020;\n"); ! 1116: printf ("\twhile (amask) {\n"); ! 1117: printf ("\t\tsrca -= %d;\n", size); ! 1118: if (!using_mmu) ! 1119: printf ("\t\tif (type) m68k_areg (regs, dstreg) = srca;\n"); ! 1120: printf ("\t\t%s, m68k_areg (regs, movem_index2[amask]));\n", putcode); ! 1121: printf ("\t\tamask = movem_next[amask];\n"); ! 1122: printf ("\t}\n"); ! 1123: printf ("\twhile (dmask) { srca -= %d; %s, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", ! 1124: size, putcode); ! 1125: printf ("\tm68k_areg (regs, dstreg) = srca;\n"); ! 1126: } else { ! 1127: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); ! 1128: printf ("\twhile (dmask) { %s, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", ! 1129: putcode, size); ! 1130: printf ("\twhile (amask) { %s, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", ! 1131: putcode, size); ! 1132: } ! 1133: count_ncycles++; ! 1134: fill_prefetch_next (); ! 1135: } ! 1136: ! 1137: static void genmovemle_ce (uae_u16 opcode) ! 1138: { ! 1139: int size = table68k[opcode].size == sz_long ? 4 : 2; ! 1140: printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0)); ! 1141: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA); ! 1142: ! 1143: if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) { ! 1144: addcycles000 (2); ! 1145: } ! 1146: start_brace (); ! 1147: if (table68k[opcode].size == sz_long) { ! 1148: if (table68k[opcode].dmode == Apdi) { ! 1149: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); ! 1150: printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n", ! 1151: size); ! 1152: printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", ! 1153: size); ! 1154: printf ("\tm68k_areg (regs, dstreg) = srca;\n"); ! 1155: } else { ! 1156: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); ! 1157: printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", ! 1158: size); ! 1159: printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", ! 1160: size); ! 1161: } ! 1162: } else { ! 1163: if (table68k[opcode].dmode == Apdi) { ! 1164: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); ! 1165: printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n", ! 1166: size); ! 1167: printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n", ! 1168: size); ! 1169: printf ("\tm68k_areg (regs, dstreg) = srca;\n"); ! 1170: } else { ! 1171: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); ! 1172: printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n", ! 1173: size); ! 1174: printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n", ! 1175: size); ! 1176: } ! 1177: } ! 1178: count_ncycles++; ! 1179: fill_prefetch_next (); ! 1180: } ! 1181: ! 1182: static void duplicate_carry (int n) ! 1183: { ! 1184: int i; ! 1185: for (i = 0; i <= n; i++) ! 1186: printf ("\t"); ! 1187: printf ("COPY_CARRY ();\n"); ! 1188: } ! 1189: ! 1190: typedef enum ! 1191: { ! 1192: flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_z, flag_zn, ! 1193: flag_av, flag_sv ! 1194: } ! 1195: flagtypes; ! 1196: ! 1197: static void genflags_normal (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst) ! 1198: { ! 1199: char vstr[100], sstr[100], dstr[100]; ! 1200: char usstr[100], udstr[100]; ! 1201: char unsstr[100], undstr[100]; ! 1202: ! 1203: switch (size) { ! 1204: case sz_byte: ! 1205: strcpy (vstr, "((uae_s8)("); ! 1206: strcpy (usstr, "((uae_u8)("); ! 1207: break; ! 1208: case sz_word: ! 1209: strcpy (vstr, "((uae_s16)("); ! 1210: strcpy (usstr, "((uae_u16)("); ! 1211: break; ! 1212: case sz_long: ! 1213: strcpy (vstr, "((uae_s32)("); ! 1214: strcpy (usstr, "((uae_u32)("); ! 1215: break; ! 1216: default: ! 1217: abort (); ! 1218: } ! 1219: strcpy (unsstr, usstr); ! 1220: ! 1221: strcpy (sstr, vstr); ! 1222: strcpy (dstr, vstr); ! 1223: strcat (vstr, value); ! 1224: strcat (vstr, "))"); ! 1225: strcat (dstr, dst); ! 1226: strcat (dstr, "))"); ! 1227: strcat (sstr, src); ! 1228: strcat (sstr, "))"); ! 1229: ! 1230: strcpy (udstr, usstr); ! 1231: strcat (udstr, dst); ! 1232: strcat (udstr, "))"); ! 1233: strcat (usstr, src); ! 1234: strcat (usstr, "))"); ! 1235: ! 1236: strcpy (undstr, unsstr); ! 1237: strcat (unsstr, "-"); ! 1238: strcat (undstr, "~"); ! 1239: strcat (undstr, dst); ! 1240: strcat (undstr, "))"); ! 1241: strcat (unsstr, src); ! 1242: strcat (unsstr, "))"); ! 1243: ! 1244: switch (type) { ! 1245: case flag_logical_noclobber: ! 1246: case flag_logical: ! 1247: case flag_z: ! 1248: case flag_zn: ! 1249: case flag_av: ! 1250: case flag_sv: ! 1251: case flag_addx: ! 1252: case flag_subx: ! 1253: break; ! 1254: ! 1255: case flag_add: ! 1256: start_brace (); ! 1257: printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr); ! 1258: break; ! 1259: case flag_sub: ! 1260: case flag_cmp: ! 1261: start_brace (); ! 1262: printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr); ! 1263: break; ! 1264: } ! 1265: ! 1266: switch ((int)type) { ! 1267: case flag_logical_noclobber: ! 1268: case flag_logical: ! 1269: case flag_zn: ! 1270: break; ! 1271: ! 1272: case flag_add: ! 1273: case flag_sub: ! 1274: case flag_addx: ! 1275: case flag_subx: ! 1276: case flag_cmp: ! 1277: case flag_av: ! 1278: case flag_sv: ! 1279: start_brace (); ! 1280: printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr); ! 1281: printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr); ! 1282: printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr); ! 1283: break; ! 1284: } ! 1285: ! 1286: switch (type) { ! 1287: case flag_logical: ! 1288: printf ("\tCLEAR_CZNV ();\n"); ! 1289: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 1290: printf ("\tSET_NFLG (%s < 0);\n", vstr); ! 1291: break; ! 1292: case flag_logical_noclobber: ! 1293: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 1294: printf ("\tSET_NFLG (%s < 0);\n", vstr); ! 1295: break; ! 1296: case flag_av: ! 1297: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); ! 1298: break; ! 1299: case flag_sv: ! 1300: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); ! 1301: break; ! 1302: case flag_z: ! 1303: printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr); ! 1304: break; ! 1305: case flag_zn: ! 1306: printf ("\tSET_ZFLG (GET_ZFLG () & (%s == 0));\n", vstr); ! 1307: printf ("\tSET_NFLG (%s < 0);\n", vstr); ! 1308: break; ! 1309: case flag_add: ! 1310: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 1311: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); ! 1312: printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr); ! 1313: duplicate_carry (0); ! 1314: printf ("\tSET_NFLG (flgn != 0);\n"); ! 1315: break; ! 1316: case flag_sub: ! 1317: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 1318: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); ! 1319: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); ! 1320: duplicate_carry (0); ! 1321: printf ("\tSET_NFLG (flgn != 0);\n"); ! 1322: break; ! 1323: case flag_addx: ! 1324: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */ ! 1325: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */ ! 1326: duplicate_carry (0); ! 1327: break; ! 1328: case flag_subx: ! 1329: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */ ! 1330: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */ ! 1331: duplicate_carry (0); ! 1332: break; ! 1333: case flag_cmp: ! 1334: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 1335: printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n"); ! 1336: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); ! 1337: printf ("\tSET_NFLG (flgn != 0);\n"); ! 1338: break; ! 1339: } ! 1340: } ! 1341: ! 1342: static void genflags (flagtypes type, wordsizes size, const char *value, const char *src, const char *dst) ! 1343: { ! 1344: /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have ! 1345: them in the appropriate m68k.h files and use just one copy of this ! 1346: code here. The API can be changed if necessary. */ ! 1347: if (optimized_flags) { ! 1348: switch (type) { ! 1349: case flag_add: ! 1350: case flag_sub: ! 1351: start_brace (); ! 1352: printf ("\tuae_u32 %s;\n", value); ! 1353: break; ! 1354: ! 1355: default: ! 1356: break; ! 1357: } ! 1358: ! 1359: /* At least some of those casts are fairly important! */ ! 1360: switch (type) { ! 1361: case flag_logical_noclobber: ! 1362: printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n"); ! 1363: if (strcmp (value, "0") == 0) { ! 1364: printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n"); ! 1365: } else { ! 1366: switch (size) { ! 1367: case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break; ! 1368: case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break; ! 1369: case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break; ! 1370: } ! 1371: printf ("\tIOR_CZNV (oldcznv);\n"); ! 1372: } ! 1373: printf ("\t}\n"); ! 1374: return; ! 1375: case flag_logical: ! 1376: if (strcmp (value, "0") == 0) { ! 1377: printf ("\tSET_CZNV (FLAGVAL_Z);\n"); ! 1378: } else { ! 1379: switch (size) { ! 1380: case sz_byte: printf ("\toptflag_testb (regs, (uae_s8)(%s));\n", value); break; ! 1381: case sz_word: printf ("\toptflag_testw (regs, (uae_s16)(%s));\n", value); break; ! 1382: case sz_long: printf ("\toptflag_testl (regs, (uae_s32)(%s));\n", value); break; ! 1383: } ! 1384: } ! 1385: return; ! 1386: ! 1387: case flag_add: ! 1388: switch (size) { ! 1389: case sz_byte: printf ("\toptflag_addb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; ! 1390: case sz_word: printf ("\toptflag_addw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; ! 1391: case sz_long: printf ("\toptflag_addl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; ! 1392: } ! 1393: return; ! 1394: ! 1395: case flag_sub: ! 1396: switch (size) { ! 1397: case sz_byte: printf ("\toptflag_subb (regs, %s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; ! 1398: case sz_word: printf ("\toptflag_subw (regs, %s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; ! 1399: case sz_long: printf ("\toptflag_subl (regs, %s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; ! 1400: } ! 1401: return; ! 1402: ! 1403: case flag_cmp: ! 1404: switch (size) { ! 1405: case sz_byte: printf ("\toptflag_cmpb (regs, (uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break; ! 1406: case sz_word: printf ("\toptflag_cmpw (regs, (uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break; ! 1407: case sz_long: printf ("\toptflag_cmpl (regs, (uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break; ! 1408: } ! 1409: return; ! 1410: ! 1411: default: ! 1412: break; ! 1413: } ! 1414: } ! 1415: ! 1416: genflags_normal (type, size, value, src, dst); ! 1417: } ! 1418: ! 1419: static void force_range_for_rox (const char *var, wordsizes size) ! 1420: { ! 1421: /* Could do a modulo operation here... which one is faster? */ ! 1422: switch (size) { ! 1423: case sz_long: ! 1424: printf ("\tif (%s >= 33) %s -= 33;\n", var, var); ! 1425: break; ! 1426: case sz_word: ! 1427: printf ("\tif (%s >= 34) %s -= 34;\n", var, var); ! 1428: printf ("\tif (%s >= 17) %s -= 17;\n", var, var); ! 1429: break; ! 1430: case sz_byte: ! 1431: printf ("\tif (%s >= 36) %s -= 36;\n", var, var); ! 1432: printf ("\tif (%s >= 18) %s -= 18;\n", var, var); ! 1433: printf ("\tif (%s >= 9) %s -= 9;\n", var, var); ! 1434: break; ! 1435: } ! 1436: } ! 1437: ! 1438: static const char *cmask (wordsizes size) ! 1439: { ! 1440: switch (size) { ! 1441: case sz_byte: return "0x80"; ! 1442: case sz_word: return "0x8000"; ! 1443: case sz_long: return "0x80000000"; ! 1444: default: abort (); ! 1445: } ! 1446: } ! 1447: ! 1448: static int source_is_imm1_8 (struct instr *i) ! 1449: { ! 1450: return i->stype == 3; ! 1451: } ! 1452: ! 1453: static void shift_ce (amodes dmode, int size) ! 1454: { ! 1455: if (using_ce && isreg (dmode)) { ! 1456: int c = size == sz_long ? 4 : 2; ! 1457: printf ("\t{\n"); ! 1458: printf ("\t\tint cycles = %d;\n", c); ! 1459: printf ("\t\tcycles += 2 * ccnt;\n"); ! 1460: addcycles000_3 ("\t\t"); ! 1461: printf ("\t}\n"); ! 1462: count_cycles += c; ! 1463: } ! 1464: } ! 1465: ! 1466: // BCHG/BSET/BCLR Dx,Dx or #xx,Dx adds 2 cycles if bit number > 15 ! 1467: static void bsetcycles (struct instr *curi) ! 1468: { ! 1469: if (curi->size == sz_byte) { ! 1470: printf ("\tsrc &= 7;\n"); ! 1471: } else { ! 1472: printf ("\tsrc &= 31;\n"); ! 1473: if (isreg (curi->dmode)) { ! 1474: addcycles000 (2); ! 1475: if (curi->mnemo != i_BTST && using_ce) { ! 1476: printf ("\tif (src > 15) do_cycles_ce000 (2);\n"); ! 1477: count_ncycles++; ! 1478: } ! 1479: } ! 1480: } ! 1481: } ! 1482: ! 1483: static int islongimm (struct instr *curi) ! 1484: { ! 1485: return (curi->size == sz_long && (curi->smode == Dreg || curi->smode == imm)); ! 1486: } ! 1487: ! 1488: static void gen_opcode (unsigned long int opcode) ! 1489: { ! 1490: struct instr *curi = table68k + opcode; ! 1491: ! 1492: insn_n_cycles = using_prefetch ? 0 : 4; ! 1493: ! 1494: /* Store the family of the instruction (used to check for pairing on ST) ! 1495: * and leave some space for patching in the current cycles later */ ! 1496: printf ("\tOpcodeFamily = %d;\n", curi->mnemo); ! 1497: ! 1498: if (using_ce020) { ! 1499: if (using_ce020 == 2) { ! 1500: ce020_prefetch_long = "get_long_ce030_prefetch"; ! 1501: ce020_prefetch_word = "get_word_ce030_prefetch"; ! 1502: srcl = "get_long_ce030"; ! 1503: dstl = "put_long_ce030"; ! 1504: srcw = "get_word_ce030"; ! 1505: dstw = "put_word_ce030"; ! 1506: srcb = "get_byte_ce030"; ! 1507: dstb = "put_byte_ce030"; ! 1508: } else { ! 1509: ce020_prefetch_long = "get_long_ce020_prefetch"; ! 1510: ce020_prefetch_word = "get_word_ce020_prefetch"; ! 1511: srcl = "get_long_ce020"; ! 1512: dstl = "put_long_ce020"; ! 1513: srcw = "get_word_ce020"; ! 1514: dstw = "put_word_ce020"; ! 1515: srcb = "get_byte_ce020"; ! 1516: dstb = "put_byte_ce020"; ! 1517: } ! 1518: } else if (using_mmu) { ! 1519: srcl = "get_long_mmu"; ! 1520: dstl = "put_long_mmu"; ! 1521: srcw = "get_word_mmu"; ! 1522: dstw = "put_word_mmu"; ! 1523: srcb = "get_byte_mmu"; ! 1524: dstb = "put_byte_mmu"; ! 1525: } else if (using_ce) { ! 1526: srcl = "get_long_ce"; ! 1527: dstl = "put_long_ce"; ! 1528: srcw = "get_word_ce"; ! 1529: dstw = "put_word_ce"; ! 1530: srcb = "get_byte_ce"; ! 1531: dstb = "put_byte_ce"; ! 1532: } else { ! 1533: srcl = "get_long"; ! 1534: dstl = "put_long"; ! 1535: srcw = "get_word"; ! 1536: dstw = "put_word"; ! 1537: srcb = "get_byte"; ! 1538: dstb = "put_byte"; ! 1539: } ! 1540: ! 1541: insn_n_cycles020 = 0; ! 1542: ! 1543: start_brace (); ! 1544: m68k_pc_offset = 2; ! 1545: switch (curi->plev) { ! 1546: case 0: /* not privileged */ ! 1547: break; ! 1548: case 1: /* unprivileged only on 68000 */ ! 1549: if (cpu_level == 0) ! 1550: break; ! 1551: if (next_cpu_level < 0) ! 1552: next_cpu_level = 0; ! 1553: ! 1554: /* fall through */ ! 1555: case 2: /* priviledged */ ! 1556: printf ("if (!regs.s) { Exception (8, 0 ,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 1557: need_endlabel = 1; ! 1558: start_brace (); ! 1559: break; ! 1560: case 3: /* privileged if size == word */ ! 1561: if (curi->size == sz_byte) ! 1562: break; ! 1563: printf ("if (!regs.s) { Exception (8, 0 ,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 1564: need_endlabel = 1; ! 1565: start_brace (); ! 1566: break; ! 1567: } ! 1568: switch (curi->mnemo) { ! 1569: case i_OR: ! 1570: case i_AND: ! 1571: case i_EOR: ! 1572: { ! 1573: int c = 0; ! 1574: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1575: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 1576: printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^'); ! 1577: genflags (flag_logical, curi->size, "src", "", ""); ! 1578: if (curi->dmode == Dreg && curi->size == sz_long) { ! 1579: c += 2; ! 1580: if (curi->smode == imm || curi->smode == Dreg) ! 1581: c += 2; ! 1582: } ! 1583: fill_prefetch_next (); ! 1584: if (c > 0) ! 1585: addcycles000 (c); ! 1586: genastore_rev ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 1587: break; ! 1588: } ! 1589: // all SR/CCR modifications have dummy read access ! 1590: case i_ORSR: ! 1591: case i_EORSR: ! 1592: printf ("\tMakeSR ();\n"); ! 1593: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1594: dummy_prefetch (); ! 1595: if (curi->size == sz_byte) { ! 1596: printf ("\tsrc &= 0xFF;\n"); ! 1597: } ! 1598: addcycles000 (8); ! 1599: fill_prefetch_next (); ! 1600: printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|'); ! 1601: printf ("\tMakeFromSR ();\n"); ! 1602: break; ! 1603: case i_ANDSR: ! 1604: printf ("\tMakeSR ();\n"); ! 1605: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1606: dummy_prefetch (); ! 1607: if (curi->size == sz_byte) { ! 1608: printf ("\tsrc |= 0xFF00;\n"); ! 1609: } ! 1610: addcycles000 (8); ! 1611: fill_prefetch_next (); ! 1612: printf ("\tregs.sr &= src;\n"); ! 1613: printf ("\tMakeFromSR ();\n"); ! 1614: break; ! 1615: case i_SUB: ! 1616: { ! 1617: int c = 0; ! 1618: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1619: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 1620: if (curi->dmode == Dreg) { ! 1621: if (curi->size == sz_long) { ! 1622: c += 2; ! 1623: if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg) ! 1624: c += 2; ! 1625: } ! 1626: } ! 1627: fill_prefetch_next (); ! 1628: if (c > 0) ! 1629: addcycles000 (c); ! 1630: start_brace (); ! 1631: genflags (flag_sub, curi->size, "newv", "src", "dst"); ! 1632: genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1633: break; ! 1634: } ! 1635: case i_SUBA: ! 1636: { ! 1637: int c = 0; ! 1638: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1639: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); ! 1640: if (curi->smode == immi) { ! 1641: // SUBAQ.x is always 8 cycles ! 1642: c += 4; ! 1643: } else { ! 1644: c = curi->size == sz_long ? 2 : 4; ! 1645: if (islongimm (curi)) ! 1646: c += 2; ! 1647: } ! 1648: fill_prefetch_next (); ! 1649: if (c > 0) ! 1650: addcycles000 (c); ! 1651: start_brace (); ! 1652: printf ("\tuae_u32 newv = dst - src;\n"); ! 1653: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1654: break; ! 1655: } ! 1656: case i_SUBX: ! 1657: if (!isreg (curi->smode)) ! 1658: addcycles000 (2); ! 1659: genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1660: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); ! 1661: genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1662: fill_prefetch_next (); ! 1663: if (curi->size == sz_long && isreg (curi->smode)) ! 1664: addcycles000 (4); ! 1665: start_brace (); ! 1666: printf ("\tuae_u32 newv = dst - src - (GET_XFLG () ? 1 : 0);\n"); ! 1667: genflags (flag_subx, curi->size, "newv", "src", "dst"); ! 1668: genflags (flag_zn, curi->size, "newv", "", ""); ! 1669: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1670: break; ! 1671: case i_SBCD: ! 1672: if (!isreg (curi->smode)) ! 1673: addcycles000 (2); ! 1674: genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1675: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); ! 1676: genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1677: fill_prefetch_next (); ! 1678: start_brace (); ! 1679: printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n"); ! 1680: printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n"); ! 1681: printf ("\tuae_u16 newv, tmp_newv;\n"); ! 1682: printf ("\tint bcd = 0;\n"); ! 1683: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n"); ! 1684: printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n"); ! 1685: printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG () ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n"); ! 1686: printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG () ? 1 : 0)) & 0x300) > 0xFF);\n"); ! 1687: duplicate_carry (0); ! 1688: /* Manual says bits NV are undefined though a real 68040/060 don't change them */ ! 1689: if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { ! 1690: if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) ! 1691: next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; ! 1692: genflags (flag_z, curi->size, "newv", "", ""); ! 1693: } else { ! 1694: genflags (flag_zn, curi->size, "newv", "", ""); ! 1695: printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); ! 1696: } ! 1697: if (isreg (curi->smode)) ! 1698: addcycles000 (2); ! 1699: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1700: break; ! 1701: case i_ADD: ! 1702: { ! 1703: int c = 0; ! 1704: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1705: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 1706: if (curi->dmode == Dreg) { ! 1707: if (curi->size == sz_long) { ! 1708: c += 2; ! 1709: if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg) ! 1710: c += 2; ! 1711: } ! 1712: } ! 1713: fill_prefetch_next (); ! 1714: if (c > 0) ! 1715: addcycles000 (c); ! 1716: start_brace (); ! 1717: genflags (flag_add, curi->size, "newv", "src", "dst"); ! 1718: genastore_rev ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1719: break; ! 1720: } ! 1721: case i_ADDA: ! 1722: { ! 1723: int c = 0; ! 1724: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1725: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); ! 1726: if (curi->smode == immi) { ! 1727: // ADDAQ.x is always 8 cycles ! 1728: c += 4; ! 1729: } else { ! 1730: c = curi->size == sz_long ? 2 : 4; ! 1731: if (islongimm (curi)) ! 1732: c += 2; ! 1733: } ! 1734: fill_prefetch_next (); ! 1735: if (c > 0) ! 1736: addcycles000 (c); ! 1737: start_brace (); ! 1738: printf ("\tuae_u32 newv = dst + src;\n"); ! 1739: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1740: break; ! 1741: } ! 1742: case i_ADDX: ! 1743: if (!isreg (curi->smode)) ! 1744: addcycles000 (2); ! 1745: genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1746: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); ! 1747: genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1748: fill_prefetch_next (); ! 1749: if (curi->size == sz_long && isreg (curi->smode)) ! 1750: addcycles000 (4); ! 1751: start_brace (); ! 1752: printf ("\tuae_u32 newv = dst + src + (GET_XFLG () ? 1 : 0);\n"); ! 1753: genflags (flag_addx, curi->size, "newv", "src", "dst"); ! 1754: genflags (flag_zn, curi->size, "newv", "", ""); ! 1755: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1756: break; ! 1757: case i_ABCD: ! 1758: if (!isreg (curi->smode)) ! 1759: addcycles000 (2); ! 1760: genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1761: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); ! 1762: genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1763: fill_prefetch_next (); ! 1764: start_brace (); ! 1765: printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG () ? 1 : 0);\n"); ! 1766: printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n"); ! 1767: printf ("\tuae_u16 newv, tmp_newv;\n"); ! 1768: printf ("\tint cflg;\n"); ! 1769: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;"); ! 1770: printf ("\tif (newv_lo > 9) { newv += 6; }\n"); ! 1771: printf ("\tcflg = (newv & 0x3F0) > 0x90;\n"); ! 1772: printf ("\tif (cflg) newv += 0x60;\n"); ! 1773: printf ("\tSET_CFLG (cflg);\n"); ! 1774: duplicate_carry (0); ! 1775: /* Manual says bits NV are undefined though a real 68040 don't change them */ ! 1776: if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { ! 1777: if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) ! 1778: next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; ! 1779: genflags (flag_z, curi->size, "newv", "", ""); ! 1780: } ! 1781: else { ! 1782: genflags (flag_zn, curi->size, "newv", "", ""); ! 1783: printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); ! 1784: } ! 1785: if (isreg (curi->smode)) ! 1786: addcycles000 (2); ! 1787: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1788: break; ! 1789: case i_NEG: ! 1790: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1791: fill_prefetch_next (); ! 1792: if (isreg (curi->smode) && curi->size == sz_long) ! 1793: addcycles000 (2); ! 1794: start_brace (); ! 1795: genflags (flag_sub, curi->size, "dst", "src", "0"); ! 1796: genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1797: break; ! 1798: case i_NEGX: ! 1799: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1800: fill_prefetch_next (); ! 1801: if (isreg (curi->smode) && curi->size == sz_long) ! 1802: addcycles000 (2); ! 1803: start_brace (); ! 1804: printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n"); ! 1805: genflags (flag_subx, curi->size, "newv", "src", "0"); ! 1806: genflags (flag_zn, curi->size, "newv", "", ""); ! 1807: genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src"); ! 1808: break; ! 1809: case i_NBCD: ! 1810: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1811: if (isreg (curi->smode)) ! 1812: addcycles000 (2); ! 1813: fill_prefetch_next (); ! 1814: start_brace (); ! 1815: printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n"); ! 1816: printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n"); ! 1817: printf ("\tuae_u16 newv;\n"); ! 1818: printf ("\tint cflg;\n"); ! 1819: printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n"); ! 1820: printf ("\tnewv = newv_hi + newv_lo;"); ! 1821: printf ("\tcflg = (newv & 0x1F0) > 0x90;\n"); ! 1822: printf ("\tif (cflg) newv -= 0x60;\n"); ! 1823: printf ("\tSET_CFLG (cflg);\n"); ! 1824: duplicate_carry(0); ! 1825: /* Manual says bits NV are undefined though a real 68040 don't change them */ ! 1826: if (cpu_level >= xBCD_KEEPS_NV_FLAGS) { ! 1827: if (next_cpu_level < xBCD_KEEPS_NV_FLAGS) ! 1828: next_cpu_level = xBCD_KEEPS_NV_FLAGS - 1; ! 1829: genflags (flag_z, curi->size, "newv", "", ""); ! 1830: } ! 1831: else { ! 1832: genflags (flag_zn, curi->size, "newv", "", ""); ! 1833: } ! 1834: genastore ("newv", curi->smode, "srcreg", curi->size, "src"); ! 1835: break; ! 1836: case i_CLR: ! 1837: genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0); ! 1838: fill_prefetch_next (); ! 1839: if (isreg (curi->smode) && curi->size == sz_long) ! 1840: addcycles000 (2); ! 1841: genflags (flag_logical, curi->size, "0", "", ""); ! 1842: genastore_rev ("0", curi->smode, "srcreg", curi->size, "src"); ! 1843: break; ! 1844: case i_NOT: ! 1845: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1846: fill_prefetch_next (); ! 1847: if (isreg (curi->smode) && curi->size == sz_long) ! 1848: addcycles000 (2); ! 1849: start_brace (); ! 1850: printf ("\tuae_u32 dst = ~src;\n"); ! 1851: genflags (flag_logical, curi->size, "dst", "", ""); ! 1852: genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1853: break; ! 1854: case i_TST: ! 1855: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1856: fill_prefetch_next (); ! 1857: genflags (flag_logical, curi->size, "src", "", ""); ! 1858: break; ! 1859: case i_BTST: ! 1860: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1861: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 1862: fill_prefetch_next (); ! 1863: bsetcycles (curi); ! 1864: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); ! 1865: break; ! 1866: case i_BCHG: ! 1867: case i_BCLR: ! 1868: case i_BSET: ! 1869: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1870: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 1871: fill_prefetch_next (); ! 1872: bsetcycles (curi); ! 1873: // bclr needs 1 extra cycle ! 1874: if (curi->mnemo == i_BCLR && curi->dmode == Dreg) ! 1875: addcycles000 (2); ! 1876: if (curi->mnemo == i_BCHG) { ! 1877: printf ("\tdst ^= (1 << src);\n"); ! 1878: printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n"); ! 1879: } else if (curi->mnemo == i_BCLR) { ! 1880: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); ! 1881: printf ("\tdst &= ~(1 << src);\n"); ! 1882: } else if (curi->mnemo == i_BSET) { ! 1883: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); ! 1884: printf ("\tdst |= (1 << src);\n"); ! 1885: } ! 1886: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1887: break; ! 1888: case i_CMPM: ! 1889: // confirmed ! 1890: genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1891: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA); ! 1892: genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA); ! 1893: fill_prefetch_next (); ! 1894: start_brace (); ! 1895: genflags (flag_cmp, curi->size, "newv", "src", "dst"); ! 1896: break; ! 1897: case i_CMP: ! 1898: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1899: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 1900: fill_prefetch_next (); ! 1901: if (curi->dmode == Dreg && curi->size == sz_long) ! 1902: addcycles000 (2); ! 1903: start_brace (); ! 1904: genflags (flag_cmp, curi->size, "newv", "src", "dst"); ! 1905: break; ! 1906: case i_CMPA: ! 1907: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1908: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); ! 1909: fill_prefetch_next (); ! 1910: addcycles000 (2); ! 1911: start_brace (); ! 1912: genflags (flag_cmp, sz_long, "newv", "src", "dst"); ! 1913: break; ! 1914: /* The next two are coded a little unconventional, but they are doing ! 1915: * weird things... */ ! 1916: case i_MVPRM: // MOVEP R->M ! 1917: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1918: printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0)); ! 1919: if (curi->size == sz_word) { ! 1920: printf ("\t%s (memp, src >> 8); %s (memp + 2, src);\n", dstb, dstb); ! 1921: count_write += 2; ! 1922: } else { ! 1923: printf ("\t%s (memp, src >> 24); %s (memp + 2, src >> 16);\n", dstb, dstb); ! 1924: printf ("\t%s (memp + 4, src >> 8); %s (memp + 6, src);\n", dstb, dstb); ! 1925: count_write += 4; ! 1926: } ! 1927: fill_prefetch_next (); ! 1928: break; ! 1929: case i_MVPMR: // MOVEP M->R ! 1930: printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0)); ! 1931: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); ! 1932: if (curi->size == sz_word) { ! 1933: printf ("\tuae_u16 val = (%s (memp) << 8) + %s (memp + 2);\n", srcb, srcb); ! 1934: count_read += 2; ! 1935: } else { ! 1936: printf ("\tuae_u32 val = (%s (memp) << 24) + (%s (memp + 2) << 16)\n", srcb, srcb); ! 1937: printf (" + (%s (memp + 4) << 8) + %s (memp + 6);\n", srcb, srcb); ! 1938: count_read += 4; ! 1939: } ! 1940: fill_prefetch_next (); ! 1941: genastore ("val", curi->dmode, "dstreg", curi->size, "dst"); ! 1942: break; ! 1943: case i_MOVE: ! 1944: case i_MOVEA: ! 1945: { ! 1946: /* 2 MOVE instruction variants have special prefetch sequence: ! 1947: * - MOVE <ea>,-(An) = prefetch is before writes (Apdi) ! 1948: * - MOVE memory,(xxx).L = 2 prefetches after write ! 1949: * - all others = prefetch is done after writes ! 1950: * ! 1951: * - move.x xxx,[at least 1 extension word here] = fetch 1 extension word before (xxx) ! 1952: * ! 1953: */ ! 1954: int prefetch_done = 0, flags; ! 1955: int dualprefetch = curi->dmode == absl && (curi->smode != Dreg && curi->smode != Areg && curi->smode != imm); ! 1956: genamode_pre (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_MOVE); ! 1957: flags = 1 | (dualprefetch ? GF_NOREFILL : 0); ! 1958: genamode2 (curi->dmode, "dstreg", curi->size, "dst", 2, 0, flags | GF_MOVE, 0); ! 1959: genamode_post (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 1960: if (curi->mnemo == i_MOVEA && curi->size == sz_word) ! 1961: printf ("\tsrc = (uae_s32)(uae_s16)src;\n"); ! 1962: if (curi->dmode == Apdi) { ! 1963: fill_prefetch_next (); ! 1964: prefetch_done = 1; ! 1965: } ! 1966: if (curi->mnemo == i_MOVE) ! 1967: genflags (flag_logical, curi->size, "src", "", ""); ! 1968: genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 1969: sync_m68k_pc (); ! 1970: if (dualprefetch) { ! 1971: fill_prefetch_full (); ! 1972: prefetch_done = 1; ! 1973: } ! 1974: if (!prefetch_done) ! 1975: fill_prefetch_next (); ! 1976: } ! 1977: break; ! 1978: case i_MVSR2: // MOVE FROM SR ! 1979: genamode (curi->smode, "srcreg", sz_word, "src", 2, 0, 0); ! 1980: fill_prefetch_next (); ! 1981: if (isreg (curi->smode)) ! 1982: addcycles000 (2); ! 1983: printf ("\tMakeSR ();\n"); ! 1984: if (curi->size == sz_byte) ! 1985: genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src"); ! 1986: else ! 1987: genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src"); ! 1988: break; ! 1989: case i_MV2SR: // MOVE TO SR ! 1990: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); ! 1991: if (curi->size == sz_byte) { ! 1992: // MOVE TO CCR ! 1993: dummy_prefetch (); ! 1994: addcycles000 (4); ! 1995: printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n"); ! 1996: } else { ! 1997: // MOVE TO SR ! 1998: dummy_prefetch (); ! 1999: addcycles000 (4); ! 2000: printf ("\tregs.sr = src;\n"); ! 2001: } ! 2002: printf ("\tMakeFromSR ();\n"); ! 2003: fill_prefetch_next (); ! 2004: break; ! 2005: case i_SWAP: ! 2006: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0); ! 2007: fill_prefetch_next (); ! 2008: start_brace (); ! 2009: printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n"); ! 2010: genflags (flag_logical, sz_long, "dst", "", ""); ! 2011: genastore ("dst", curi->smode, "srcreg", sz_long, "src"); ! 2012: break; ! 2013: case i_EXG: ! 2014: // confirmed ! 2015: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 2016: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 2017: fill_prefetch_next (); ! 2018: addcycles000 (2); ! 2019: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 2020: genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 2021: break; ! 2022: case i_EXT: ! 2023: // confirmed ! 2024: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0); ! 2025: fill_prefetch_next (); ! 2026: start_brace (); ! 2027: switch (curi->size) { ! 2028: case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break; ! 2029: case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break; ! 2030: case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break; ! 2031: default: abort (); ! 2032: } ! 2033: genflags (flag_logical, ! 2034: curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); ! 2035: genastore ("dst", curi->smode, "srcreg", ! 2036: curi->size == sz_word ? sz_word : sz_long, "src"); ! 2037: break; ! 2038: case i_MVMEL: ! 2039: // confirmed ! 2040: if (using_ce) ! 2041: genmovemel_ce (opcode); ! 2042: else ! 2043: genmovemel (opcode); ! 2044: break; ! 2045: case i_MVMLE: ! 2046: // confirmed ! 2047: if (using_ce) ! 2048: genmovemle_ce (opcode); ! 2049: else ! 2050: genmovemle (opcode); ! 2051: break; ! 2052: case i_TRAP: ! 2053: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 2054: gen_set_fault_pc (); ! 2055: sync_m68k_pc (); ! 2056: printf ("\tException (src + 32, 0 ,M68000_EXC_SRC_CPU);\n"); ! 2057: did_prefetch = 1; ! 2058: m68k_pc_offset = 0; ! 2059: break; ! 2060: case i_MVR2USP: ! 2061: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 2062: fill_prefetch_next (); ! 2063: printf ("\tregs.usp = src;\n"); ! 2064: break; ! 2065: case i_MVUSP2R: ! 2066: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0, 0); ! 2067: fill_prefetch_next (); ! 2068: genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src"); ! 2069: break; ! 2070: case i_RESET: ! 2071: fill_prefetch_next (); ! 2072: printf ("\tcpureset ();\n"); ! 2073: addcycles000 (128); ! 2074: if (using_prefetch) ! 2075: printf ("\tregs.irc = get_iword (4);\n"); ! 2076: break; ! 2077: case i_NOP: ! 2078: fill_prefetch_next (); ! 2079: if (using_ce020) ! 2080: printf ("\tdo_cycles_ce (6 * CYCLE_UNIT);\n"); ! 2081: break; ! 2082: case i_STOP: ! 2083: if (using_prefetch) { ! 2084: printf ("\tregs.sr = regs.irc;\n"); ! 2085: m68k_pc_offset += 2; ! 2086: } else { ! 2087: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 2088: printf ("\tregs.sr = src;\n"); ! 2089: } ! 2090: printf ("\tMakeFromSR ();\n"); ! 2091: printf ("\tm68k_setstopped ();\n"); ! 2092: sync_m68k_pc (); ! 2093: // STOP does not prefetch anything ! 2094: did_prefetch = -1; ! 2095: break; ! 2096: case i_LPSTOP: /* 68060 */ ! 2097: printf ("\tuae_u16 sw = get_iword (2);\n"); ! 2098: printf ("\tuae_u16 sr;\n"); ! 2099: printf ("\tif (sw != (0x100|0x80|0x40)) { Exception (4, 0 ,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 2100: printf ("\tsr = get_iword (4);\n"); ! 2101: printf ("\tif (!(sr & 0x8000)) { Exception (8, 0 ,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 2102: printf ("\tregs.sr = sr;\n"); ! 2103: printf ("\tMakeFromSR ();\n"); ! 2104: printf ("\tm68k_setstopped();\n"); ! 2105: m68k_pc_offset += 4; ! 2106: sync_m68k_pc (); ! 2107: fill_prefetch_full (); ! 2108: break; ! 2109: case i_RTE: ! 2110: if (cpu_level == 0) { ! 2111: genamode (Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL); ! 2112: genamode (Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL); ! 2113: printf ("\tregs.sr = sr;\n"); ! 2114: setpc ("pc"); ! 2115: printf ("\tMakeFromSR ();\n"); ! 2116: } else { ! 2117: int old_brace_level = n_braces; ! 2118: if (next_cpu_level < 0) ! 2119: next_cpu_level = 0; ! 2120: printf ("\tuae_u16 newsr; uae_u32 newpc;\n"); ! 2121: printf ("\tfor (;;) {\n"); ! 2122: printf ("\t\tuaecptr a = m68k_areg (regs, 7);\n"); ! 2123: printf ("\t\tuae_s16 sr = %s (a);\n", srcw); ! 2124: printf ("\t\tuae_s32 pc = %s (a + 2);\n", srcl); ! 2125: printf ("\t\tuae_s16 format = %s (a + 2 + 4);\n", srcw); ! 2126: printf ("\t\tint frame = format >> 12;\n"); ! 2127: printf ("\t\tint offset = 8;\n"); ! 2128: printf ("\t\tnewsr = sr; newpc = pc;\n"); ! 2129: printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n"); ! 2130: printf ("\t\telse if (frame == 0x1) { m68k_areg (regs, 7) += offset; }\n"); ! 2131: printf ("\t\telse if (frame == 0x2) { m68k_areg (regs, 7) += offset + 4; break; }\n"); ! 2132: printf ("\t\telse if (frame == 0x4) { m68k_areg (regs, 7) += offset + 8; break; }\n"); ! 2133: if (using_mmu) ! 2134: printf ("\t\telse if (frame == 0x7) { m68k_do_rte_mmu (a); m68k_areg (regs, 7) += offset + 52; break; }\n"); ! 2135: printf ("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n"); ! 2136: printf ("\t\telse if (frame == 0x9) { m68k_areg (regs, 7) += offset + 12; break; }\n"); ! 2137: printf ("\t\telse if (frame == 0xa) { m68k_areg (regs, 7) += offset + 24; break; }\n"); ! 2138: printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n"); ! 2139: printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14, 0 ,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 2140: printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n"); ! 2141: pop_braces (old_brace_level); ! 2142: printf ("\tregs.sr = newsr; MakeFromSR ();\n"); ! 2143: printf ("\tif (newpc & 1) {\n"); ! 2144: printf ("\t\texception3i (0x%04X, m68k_getpc (), newpc);\n", opcode); ! 2145: printf ("\t\tgoto %s;\n", endlabelstr); ! 2146: printf ("\t}\n"); ! 2147: printf ("\t\tm68k_setpc (newpc);\n"); ! 2148: printf ("\tipl_fetch ();\n"); ! 2149: need_endlabel = 1; ! 2150: } ! 2151: /* PC is set and prefetch filled. */ ! 2152: m68k_pc_offset = 0; ! 2153: fill_prefetch_full (); ! 2154: break; ! 2155: case i_RTD: ! 2156: if (using_mmu) { ! 2157: genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); ! 2158: genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); ! 2159: printf ("\tm68k_areg(regs, 7) += offs;\n"); ! 2160: } else { ! 2161: genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); ! 2162: genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0); ! 2163: printf ("\tm68k_areg (regs, 7) += offs;\n"); ! 2164: printf ("\tif (pc & 1) {\n"); ! 2165: printf ("\t\texception3i (0x%04X, m68k_getpc (), pc);\n", opcode); ! 2166: printf ("\t\tgoto %s;\n", endlabelstr); ! 2167: printf ("\t}\n"); ! 2168: } ! 2169: printf ("\tif (pc & 1) {\n"); ! 2170: printf ("\t\texception3i (0x%04X, m68k_getpc(), pc);\n", opcode); ! 2171: printf ("\t\tgoto %s;\n", endlabelstr); ! 2172: printf ("\t}\n"); ! 2173: setpc ("pc"); ! 2174: /* PC is set and prefetch filled. */ ! 2175: m68k_pc_offset = 0; ! 2176: fill_prefetch_full (); ! 2177: need_endlabel = 1; ! 2178: break; ! 2179: case i_LINK: ! 2180: // ce confirmed ! 2181: if (using_mmu) { ! 2182: genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); ! 2183: genamode (Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0); ! 2184: genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0); ! 2185: genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src"); ! 2186: printf ("\tm68k_areg(regs, 7) += offs;\n"); ! 2187: genastore ("src", Apdi, "7", sz_long, "old"); ! 2188: } else { ! 2189: genamode (Apdi, "7", sz_long, "old", 2, 0, GF_AA); ! 2190: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA); ! 2191: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0); ! 2192: genastore ("src", Apdi, "7", sz_long, "old"); ! 2193: genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src"); ! 2194: printf ("\tm68k_areg (regs, 7) += offs;\n"); ! 2195: fill_prefetch_next (); ! 2196: } ! 2197: break; ! 2198: case i_UNLK: ! 2199: // ce confirmed ! 2200: if (using_mmu) { ! 2201: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 2202: printf ("\tuae_s32 old = get_long_mmu (src);\n"); ! 2203: printf ("\tm68k_areg (regs, 7) = src + 4;\n"); ! 2204: printf ("\tm68k_areg (regs, srcreg) = old;\n"); ! 2205: } else { ! 2206: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 2207: printf ("\tm68k_areg (regs, 7) = src;\n"); ! 2208: genamode (Aipi, "7", sz_long, "old", 1, 0, 0); ! 2209: fill_prefetch_next (); ! 2210: genastore ("old", curi->smode, "srcreg", curi->size, "src"); ! 2211: } ! 2212: break; ! 2213: case i_RTS: ! 2214: printf ("\tuaecptr pc = m68k_getpc ();\n"); ! 2215: if (using_ce020 == 1) ! 2216: printf ("\tm68k_do_rts_ce020 ();\n"); ! 2217: else if (using_ce020 == 2) ! 2218: printf ("\tm68k_do_rts_ce030 ();\n"); ! 2219: else if (using_ce) ! 2220: printf ("\tm68k_do_rts_ce ();\n"); ! 2221: else if (using_indirect) ! 2222: printf ("\tm68k_do_rtsi ();\n"); ! 2223: else if (using_mmu) ! 2224: printf ("\tm68k_do_rts_mmu ();\n"); ! 2225: else ! 2226: printf ("\tm68k_do_rts ();\n"); ! 2227: printf ("\tif (m68k_getpc () & 1) {\n"); ! 2228: printf ("\t\tuaecptr faultpc = m68k_getpc ();\n"); ! 2229: printf ("\t\tm68k_setpc (pc);\n"); ! 2230: printf ("\t\texception3i (0x%04X, pc, faultpc);\n", opcode); ! 2231: printf ("\t\tgoto %s;\n", endlabelstr); ! 2232: printf ("\t}\n"); ! 2233: count_read += 2; ! 2234: m68k_pc_offset = 0; ! 2235: fill_prefetch_full (); ! 2236: need_endlabel = 1; ! 2237: break; ! 2238: case i_TRAPV: ! 2239: sync_m68k_pc (); ! 2240: fill_prefetch_next (); ! 2241: printf ("\tif (GET_VFLG ()) {\n"); ! 2242: printf ("\t\tException (7, m68k_getpc () ,M68000_EXC_SRC_CPU);\n"); ! 2243: printf ("\t\tgoto %s;\n", endlabelstr); ! 2244: printf ("\t}\n"); ! 2245: need_endlabel = 1; ! 2246: break; ! 2247: case i_RTR: ! 2248: printf ("\tMakeSR ();\n"); ! 2249: genamode_pre (Aipi, "7", sz_word, "sr", 1, 0, 0); ! 2250: genamode (Aipi, "7", sz_long, "pc", 1, 0, 0); ! 2251: genamode_post (Aipi, "7", sz_word, "sr", 1, 0, 0); ! 2252: printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); ! 2253: printf ("\tregs.sr |= sr;\n"); ! 2254: setpc ("pc"); ! 2255: printf ("\tMakeFromSR ();\n"); ! 2256: m68k_pc_offset = 0; ! 2257: fill_prefetch_full (); ! 2258: break; ! 2259: case i_JSR: // TODO: check stack write order ! 2260: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL); ! 2261: start_brace (); ! 2262: printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset); ! 2263: if (using_exception_3) { ! 2264: printf ("\tif (srca & 1) {\n"); ! 2265: printf ("\t\texception3i (opcode, oldpc, srca);\n"); ! 2266: printf ("\t\tgoto %s;\n", endlabelstr); ! 2267: printf ("\t}\n"); ! 2268: need_endlabel = 1; ! 2269: } ! 2270: if (using_mmu) { ! 2271: printf ("\t%s (m68k_areg (regs, 7) - 4, oldpc);\n", dstl); ! 2272: printf ("\tm68k_areg (regs, 7) -= 4;\n"); ! 2273: setpc ("srca"); ! 2274: m68k_pc_offset = 0; ! 2275: } else { ! 2276: if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16) ! 2277: addcycles000 (2); ! 2278: setpc ("srca"); ! 2279: m68k_pc_offset = 0; ! 2280: fill_prefetch_1 (0); ! 2281: if (curi->smode == Ad8r || curi->smode == PC8r) ! 2282: addcycles000 (6); ! 2283: printf ("\tm68k_areg (regs, 7) -= 4;\n"); ! 2284: if (using_ce) { ! 2285: printf ("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n"); ! 2286: printf ("\tput_word_ce (m68k_areg (regs, 7) + 2, oldpc);\n"); ! 2287: } else { ! 2288: printf ("\t%s (m68k_areg (regs, 7), oldpc);\n", dstl); ! 2289: } ! 2290: } ! 2291: count_write += 2; ! 2292: fill_prefetch_next (); ! 2293: break; ! 2294: case i_JMP: ! 2295: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA | ((curi->smode == Ad8r || curi->smode == PC8r) ? 0 : GF_NOREFILL)); ! 2296: if (using_exception_3) { ! 2297: printf ("\tif (srca & 1) {\n"); ! 2298: printf ("\t\texception3i (opcode, m68k_getpc () + 6, srca);\n"); ! 2299: printf ("\t\tgoto %s;\n", endlabelstr); ! 2300: printf ("\t}\n"); ! 2301: need_endlabel = 1; ! 2302: } ! 2303: if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r) ! 2304: addcycles000 (2); ! 2305: setpc ("srca"); ! 2306: m68k_pc_offset = 0; ! 2307: fill_prefetch_full (); ! 2308: break; ! 2309: case i_BSR: ! 2310: // .b and .w confirmed ! 2311: printf ("\tuae_s32 s;\n"); ! 2312: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL); ! 2313: printf ("\ts = (uae_s32)src + 2;\n"); ! 2314: if (using_exception_3) { ! 2315: printf ("\tif (src & 1) {\n"); ! 2316: printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + s);\n"); ! 2317: printf ("\t\tgoto %s;\n", endlabelstr); ! 2318: printf ("\t}\n"); ! 2319: need_endlabel = 1; ! 2320: } ! 2321: addcycles000 (2); ! 2322: if (using_ce020 == 1) { ! 2323: printf ("\tm68k_do_bsr_ce020 (m68k_getpc () + %d, s);\n", m68k_pc_offset); ! 2324: } else if (using_ce020 == 2) { ! 2325: printf ("\tm68k_do_bsr_ce030 (m68k_getpc () + %d, s);\n", m68k_pc_offset); ! 2326: } else if (using_ce) { ! 2327: printf ("\tm68k_do_bsr_ce (m68k_getpc () + %d, s);\n", m68k_pc_offset); ! 2328: } else if (using_indirect) { ! 2329: printf ("\tm68k_do_bsri (m68k_getpc () + %d, s);\n", m68k_pc_offset); ! 2330: } else if (using_mmu) { ! 2331: printf ("\tm68k_do_bsr_mmu (m68k_getpc () + %d, s);\n", m68k_pc_offset); ! 2332: } else { ! 2333: printf ("\tm68k_do_bsr (m68k_getpc () + %d, s);\n", m68k_pc_offset); ! 2334: } ! 2335: count_write += 2; ! 2336: m68k_pc_offset = 0; ! 2337: fill_prefetch_full (); ! 2338: break; ! 2339: case i_Bcc: ! 2340: // bcc.b branch: idle cycle, prefetch, prefetch ! 2341: // bcc.b not branch: 2 idle cycles, prefetch ! 2342: if (curi->size == sz_long) { ! 2343: if (cpu_level < 2) { ! 2344: addcycles000 (2); ! 2345: printf ("\tif (cctrue (%d)) {\n", curi->cc); ! 2346: printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n"); ! 2347: printf ("\t\tgoto %s;\n", endlabelstr); ! 2348: printf ("\t}\n"); ! 2349: sync_m68k_pc (); ! 2350: irc2ir (); ! 2351: fill_prefetch_2 (); ! 2352: printf ("\tgoto %s;\n", endlabelstr); ! 2353: need_endlabel = 1; ! 2354: } else { ! 2355: if (next_cpu_level < 1) ! 2356: next_cpu_level = 1; ! 2357: } ! 2358: } ! 2359: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); ! 2360: addcycles000 (2); ! 2361: printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc); ! 2362: if (using_exception_3) { ! 2363: printf ("\tif (src & 1) {\n"); ! 2364: printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)src);\n"); ! 2365: printf ("\t\tgoto %s;\n", endlabelstr); ! 2366: printf ("\t}\n"); ! 2367: need_endlabel = 1; ! 2368: } ! 2369: if (using_prefetch) { ! 2370: incpc ("(uae_s32)src + 2"); ! 2371: fill_prefetch_full (); ! 2372: if (using_ce) ! 2373: printf ("\treturn;\n"); ! 2374: else ! 2375: printf ("\treturn 10 * CYCLE_UNIT / 2;\n"); ! 2376: } else { ! 2377: incpc ("(uae_s32)src + 2"); ! 2378: returncycles ("\t", 10); ! 2379: } ! 2380: printf ("didnt_jump:;\n"); ! 2381: need_endlabel = 1; ! 2382: sync_m68k_pc (); ! 2383: if (curi->size == sz_byte) { ! 2384: addcycles000 (2); ! 2385: irc2ir (); ! 2386: fill_prefetch_2 (); ! 2387: } else if (curi->size == sz_word) { ! 2388: addcycles000 (2); ! 2389: fill_prefetch_full (); ! 2390: } else { ! 2391: fill_prefetch_full (); ! 2392: } ! 2393: insn_n_cycles = curi->size == sz_byte ? 8 : 12; ! 2394: break; ! 2395: case i_LEA: ! 2396: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA); ! 2397: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA); ! 2398: if (curi->smode == Ad8r || curi->smode == PC8r) ! 2399: addcycles000 (2); ! 2400: fill_prefetch_next (); ! 2401: if (curi->smode == Ad8r || curi->smode == PC8r) ! 2402: addcycles000 (2); ! 2403: genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); ! 2404: break; ! 2405: case i_PEA: ! 2406: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA); ! 2407: genamode (Apdi, "7", sz_long, "dst", 2, 0, GF_AA); ! 2408: if (curi->smode == Ad8r || curi->smode == PC8r) ! 2409: addcycles000 (2); ! 2410: if (!(curi->smode == absw || curi->smode == absl)) ! 2411: fill_prefetch_next (); ! 2412: if (curi->smode == Ad8r || curi->smode == PC8r) ! 2413: addcycles000 (2); ! 2414: genastore ("srca", Apdi, "7", sz_long, "dst"); ! 2415: if ((curi->smode == absw || curi->smode == absl)) ! 2416: fill_prefetch_next (); ! 2417: break; ! 2418: case i_DBcc: ! 2419: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL); ! 2420: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL); ! 2421: printf ("\tuaecptr oldpc = m68k_getpc ();\n"); ! 2422: addcycles000 (2); ! 2423: printf ("\tif (!cctrue (%d)) {\n", curi->cc); ! 2424: incpc ("(uae_s32)offs + 2"); ! 2425: printf ("\t"); fill_prefetch_1 (0); ! 2426: printf ("\t"); genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src"); ! 2427: ! 2428: printf ("\t\tif (src) {\n"); ! 2429: addcycles_ce020 (4); ! 2430: if (using_exception_3) { ! 2431: printf ("\t\t\tif (offs & 1) {\n"); ! 2432: printf ("\t\t\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)offs + 2);\n"); ! 2433: printf ("\t\t\t\tgoto %s;\n", endlabelstr); ! 2434: printf ("\t\t\t}\n"); ! 2435: need_endlabel = 1; ! 2436: } ! 2437: irc2ir (); ! 2438: fill_prefetch_1 (2); ! 2439: returncycles ("\t\t\t", 12); ! 2440: if (using_ce) ! 2441: printf ("\t\t\treturn;\n"); ! 2442: printf ("\t\t}\n"); ! 2443: addcycles_ce020 (8); ! 2444: printf ("\t} else {\n"); ! 2445: addcycles000_2 ("\t\t", 2); ! 2446: addcycles_ce020 (4); ! 2447: printf ("\t}\n"); ! 2448: setpc ("oldpc + %d", m68k_pc_offset); ! 2449: m68k_pc_offset = 0; ! 2450: fill_prefetch_full (); ! 2451: insn_n_cycles = 12; ! 2452: need_endlabel = 1; ! 2453: break; ! 2454: case i_Scc: ! 2455: // confirmed ! 2456: genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0); ! 2457: start_brace (); ! 2458: fill_prefetch_next(); ! 2459: start_brace (); ! 2460: printf ("\tint val = cctrue (%d) ? 0xff : 0;\n", curi->cc); ! 2461: if (using_ce) { ! 2462: printf ("\tint cycles = 0;\n"); ! 2463: if (isreg (curi->smode)) ! 2464: printf ("\tif (val) cycles += 2;\n"); ! 2465: addcycles000_3 ("\t"); ! 2466: } ! 2467: genastore ("val", curi->smode, "srcreg", curi->size, "src"); ! 2468: break; ! 2469: case i_DIVU: ! 2470: printf ("\tuaecptr oldpc = m68k_getpc ();\n"); ! 2471: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); ! 2472: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); ! 2473: printf ("\tCLEAR_CZNV ();\n"); ! 2474: printf ("\tif (src == 0) {\n"); ! 2475: if (cpu_level > 0) { ! 2476: /* 68020 sets V when dividing by zero and N if dst is negative ! 2477: * 68000 clears both ! 2478: */ ! 2479: printf("\t\tSET_VFLG (1);\n"); ! 2480: printf("\t\tif (dst < 0) SET_NFLG (1);\n"); ! 2481: } ! 2482: incpc ("%d", m68k_pc_offset); ! 2483: printf ("\t\tException (5, oldpc ,M68000_EXC_SRC_CPU);\n"); ! 2484: printf ("\t\tgoto %s;\n", endlabelstr); ! 2485: printf ("\t} else {\n"); ! 2486: printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); ! 2487: printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n"); ! 2488: fill_prefetch_next (); ! 2489: if (using_ce) { ! 2490: start_brace (); ! 2491: printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src));\n"); ! 2492: addcycles000_3 ("\t\t"); ! 2493: } else if (using_ce020) { ! 2494: addcycles_ce020 (36); ! 2495: } ! 2496: /* The N flag appears to be set each time there is an overflow. ! 2497: * Weird. but 68020 only sets N when dst is negative.. */ ! 2498: printf ("\t\tif (newv > 0xffff) {\n"); ! 2499: printf ("\t\t\tSET_VFLG (1);\n"); ! 2500: #ifdef UNDEF68020 ! 2501: if (cpu_level >= 2) ! 2502: printf ("\t\t\tif (currprefs.cpu_level == 0 || dst < 0) SET_NFLG (®s, 1);\n"); ! 2503: else /* ??? some 68000 revisions may not set NFLG when overflow happens.. */ ! 2504: #endif ! 2505: printf ("\t\t\tSET_NFLG (1);\n"); ! 2506: printf ("\t\t} else {\n"); ! 2507: printf ("\t\t"); genflags (flag_logical, sz_word, "newv", "", ""); ! 2508: printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); ! 2509: printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 2510: printf ("\t\t}\n"); ! 2511: sync_m68k_pc (); ! 2512: printf ("\t}\n"); ! 2513: count_ncycles++; ! 2514: insn_n_cycles += 136 - (136 - 76) / 2; /* average */ ! 2515: need_endlabel = 1; ! 2516: break; ! 2517: case i_DIVS: ! 2518: printf ("\tuaecptr oldpc = m68k_getpc ();\n"); ! 2519: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); ! 2520: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0); ! 2521: printf ("\tCLEAR_CZNV ();\n"); ! 2522: printf ("\tif (src == 0) {\n"); ! 2523: if (cpu_level > 0) { ! 2524: /* 68020 sets V when dividing by zero. Z is also set. ! 2525: * 68000 clears both ! 2526: */ ! 2527: printf("\t\tSET_VFLG (1);\n"); ! 2528: printf("\t\tSET_ZFLG (1);\n"); ! 2529: } ! 2530: incpc ("%d", m68k_pc_offset); ! 2531: printf ("\t\tException (5, oldpc ,M68000_EXC_SRC_CPU);\n"); ! 2532: printf ("\t\tgoto %s;\n", endlabelstr); ! 2533: printf ("\t} else {\n"); ! 2534: printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n"); ! 2535: printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n"); ! 2536: fill_prefetch_next (); ! 2537: if (using_ce) { ! 2538: start_brace (); ! 2539: printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src));\n"); ! 2540: addcycles000_3 ("\t\t"); ! 2541: } else if (using_ce020) { ! 2542: addcycles_ce020 (46); ! 2543: } ! 2544: printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n"); ! 2545: printf ("\t\t\tSET_VFLG (1);\n"); ! 2546: #ifdef UNDEF68020 ! 2547: if (cpu_level > 0) ! 2548: printf ("\t\t\tif (currprefs.cpu_level == 0) SET_NFLG (®s, 1);\n"); ! 2549: else ! 2550: #endif ! 2551: printf ("\t\t\tSET_NFLG (1);\n"); ! 2552: printf ("\t\t} else {\n"); ! 2553: printf ("\t\t\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n"); ! 2554: genflags (flag_logical, sz_word, "newv", "", ""); ! 2555: printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); ! 2556: printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 2557: printf ("\t\t}\n"); ! 2558: sync_m68k_pc (); ! 2559: printf ("\t}\n"); ! 2560: count_ncycles++; ! 2561: insn_n_cycles += 156 - (156 - 120) / 2; /* average */ ! 2562: need_endlabel = 1; ! 2563: break; ! 2564: case i_MULU: ! 2565: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); ! 2566: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); ! 2567: fill_prefetch_next(); ! 2568: start_brace (); ! 2569: printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n"); ! 2570: if (using_ce) ! 2571: printf ("\tint cycles = 38 - 4, bits;\n"); ! 2572: genflags (flag_logical, sz_long, "newv", "", ""); ! 2573: if (using_ce) { ! 2574: printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n"); ! 2575: printf ("\t\tif (src & 1) cycles += 2;\n"); ! 2576: addcycles000_3 ("\t"); ! 2577: } else if (using_ce020) { ! 2578: addcycles_ce020 (20); ! 2579: } ! 2580: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 2581: sync_m68k_pc (); ! 2582: count_cycles += 38 - 4; ! 2583: count_ncycles++; ! 2584: insn_n_cycles += (70 - 38) / 2 + 38; /* average */ ! 2585: break; ! 2586: case i_MULS: ! 2587: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0); ! 2588: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0); ! 2589: fill_prefetch_next(); ! 2590: start_brace (); ! 2591: printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n"); ! 2592: if (using_ce) { ! 2593: printf ("\tint cycles = 38 - 4, bits;\n"); ! 2594: printf ("\tuae_u32 usrc;\n"); ! 2595: } ! 2596: genflags (flag_logical, sz_long, "newv", "", ""); ! 2597: if (using_ce) { ! 2598: printf ("\tusrc = ((uae_u32)src) << 1;\n"); ! 2599: printf ("\tfor(bits = 0; bits < 16 && usrc; bits++, usrc >>= 1)\n"); ! 2600: printf ("\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) cycles += 2;\n"); ! 2601: addcycles000_3 ("\t"); ! 2602: } else if (using_ce020) { ! 2603: addcycles_ce020 (20); ! 2604: } ! 2605: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 2606: count_cycles += 38 - 4; ! 2607: count_ncycles++; ! 2608: insn_n_cycles += (70 - 38) / 2 + 38; /* average */ ! 2609: break; ! 2610: case i_CHK: ! 2611: printf ("\tuaecptr oldpc = m68k_getpc ();\n"); ! 2612: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 2613: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 2614: sync_m68k_pc (); ! 2615: addcycles000 (4); ! 2616: printf ("\tif (dst > src) {\n"); ! 2617: printf ("\t\tSET_NFLG (0);\n"); ! 2618: printf ("\t\tException (6, oldpc ,M68000_EXC_SRC_CPU);\n"); ! 2619: printf ("\t\tgoto %s;\n", endlabelstr); ! 2620: printf ("\t}\n"); ! 2621: addcycles000 (2); ! 2622: printf ("\tif ((uae_s32)dst < 0) {\n"); ! 2623: printf ("\t\tSET_NFLG (1);\n"); ! 2624: printf ("\t\tException (6, oldpc ,M68000_EXC_SRC_CPU);\n"); ! 2625: printf ("\t\tgoto %s;\n", endlabelstr); ! 2626: printf ("\t}\n"); ! 2627: fill_prefetch_next (); ! 2628: need_endlabel = 1; ! 2629: break; ! 2630: case i_CHK2: ! 2631: printf ("\tuaecptr oldpc = m68k_getpc ();\n"); ! 2632: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 2633: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); ! 2634: fill_prefetch_0 (); ! 2635: printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); ! 2636: switch (curi->size) { ! 2637: case sz_byte: ! 2638: printf ("\tlower = (uae_s32)(uae_s8)%s (dsta); upper = (uae_s32)(uae_s8)%s (dsta + 1);\n", srcb, srcb); ! 2639: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n"); ! 2640: break; ! 2641: case sz_word: ! 2642: printf ("\tlower = (uae_s32)(uae_s16)%s (dsta); upper = (uae_s32)(uae_s16)%s (dsta + 2);\n", srcw, srcw); ! 2643: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n"); ! 2644: break; ! 2645: case sz_long: ! 2646: printf ("\tlower = %s (dsta); upper = %s (dsta + 4);\n", srcl, srcl); ! 2647: break; ! 2648: default: ! 2649: abort (); ! 2650: } ! 2651: printf ("\tSET_ZFLG (upper == reg || lower == reg);\n"); ! 2652: printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n"); ! 2653: printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6, oldpc ,M68000_EXC_SRC_CPU); goto %s; }\n}\n", endlabelstr); ! 2654: need_endlabel = 1; ! 2655: break; ! 2656: ! 2657: case i_ASR: ! 2658: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2659: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2660: fill_prefetch_next(); ! 2661: start_brace (); ! 2662: switch (curi->size) { ! 2663: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2664: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2665: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2666: default: abort (); ! 2667: } ! 2668: printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1); ! 2669: printf ("\tint ccnt = cnt & 63;\n"); ! 2670: printf ("\tcnt &= 63;\n"); ! 2671: printf ("\tCLEAR_CZNV ();\n"); ! 2672: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 2673: printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size)); ! 2674: printf ("\t\tSET_CFLG (sign);\n"); ! 2675: duplicate_carry (1); ! 2676: if (source_is_imm1_8 (curi)) ! 2677: printf ("\t} else {\n"); ! 2678: else ! 2679: printf ("\t} else if (cnt > 0) {\n"); ! 2680: printf ("\t\tval >>= cnt - 1;\n"); ! 2681: printf ("\t\tSET_CFLG (val & 1);\n"); ! 2682: duplicate_carry (1); ! 2683: printf ("\t\tval >>= 1;\n"); ! 2684: printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n", ! 2685: bit_mask (curi->size), ! 2686: bit_size (curi->size)); ! 2687: printf ("\t\tval &= %s;\n", bit_mask (curi->size)); ! 2688: printf ("\t}\n"); ! 2689: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2690: shift_ce (curi->dmode, curi->size); ! 2691: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2692: break; ! 2693: case i_ASL: ! 2694: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2695: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2696: fill_prefetch_next(); ! 2697: start_brace (); ! 2698: switch (curi->size) { ! 2699: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2700: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2701: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2702: default: abort (); ! 2703: } ! 2704: printf ("\tint ccnt = cnt & 63;\n"); ! 2705: printf ("\tcnt &= 63;\n"); ! 2706: printf ("\tCLEAR_CZNV ();\n"); ! 2707: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 2708: printf ("\t\tSET_VFLG (val != 0);\n"); ! 2709: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", ! 2710: bit_size (curi->size)); ! 2711: duplicate_carry (1); ! 2712: printf ("\t\tval = 0;\n"); ! 2713: if (source_is_imm1_8 (curi)) ! 2714: printf ("\t} else {\n"); ! 2715: else ! 2716: printf ("\t} else if (cnt > 0) {\n"); ! 2717: printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n", ! 2718: bit_mask (curi->size), ! 2719: bit_size (curi->size) - 1, ! 2720: bit_mask (curi->size)); ! 2721: printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n"); ! 2722: printf ("\t\tval <<= cnt - 1;\n"); ! 2723: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); ! 2724: duplicate_carry (1); ! 2725: printf ("\t\tval <<= 1;\n"); ! 2726: printf ("\t\tval &= %s;\n", bit_mask (curi->size)); ! 2727: printf ("\t}\n"); ! 2728: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2729: shift_ce (curi->dmode, curi->size); ! 2730: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2731: break; ! 2732: case i_LSR: ! 2733: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2734: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2735: fill_prefetch_next(); ! 2736: start_brace (); ! 2737: switch (curi->size) { ! 2738: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2739: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2740: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2741: default: abort (); ! 2742: } ! 2743: printf ("\tint ccnt = cnt & 63;\n"); ! 2744: printf ("\tcnt &= 63;\n"); ! 2745: printf ("\tCLEAR_CZNV ();\n"); ! 2746: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 2747: printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n", ! 2748: bit_size (curi->size), bit_size (curi->size) - 1); ! 2749: duplicate_carry (1); ! 2750: printf ("\t\tval = 0;\n"); ! 2751: if (source_is_imm1_8 (curi)) ! 2752: printf ("\t} else {\n"); ! 2753: else ! 2754: printf ("\t} else if (cnt > 0) {\n"); ! 2755: printf ("\t\tval >>= cnt - 1;\n"); ! 2756: printf ("\t\tSET_CFLG (val & 1);\n"); ! 2757: duplicate_carry (1); ! 2758: printf ("\t\tval >>= 1;\n"); ! 2759: printf ("\t}\n"); ! 2760: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2761: shift_ce (curi->dmode, curi->size); ! 2762: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2763: break; ! 2764: case i_LSL: ! 2765: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2766: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2767: fill_prefetch_next(); ! 2768: start_brace (); ! 2769: switch (curi->size) { ! 2770: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2771: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2772: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2773: default: abort (); ! 2774: } ! 2775: printf ("\tint ccnt = cnt & 63;\n"); ! 2776: printf ("\tcnt &= 63;\n"); ! 2777: printf ("\tCLEAR_CZNV ();\n"); ! 2778: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 2779: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", bit_size (curi->size)); ! 2780: duplicate_carry (1); ! 2781: printf ("\t\tval = 0;\n"); ! 2782: if (source_is_imm1_8 (curi)) ! 2783: printf ("\t} else {\n"); ! 2784: else ! 2785: printf ("\t} else if (cnt > 0) {\n"); ! 2786: printf ("\t\tval <<= (cnt - 1);\n"); ! 2787: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); ! 2788: duplicate_carry (1); ! 2789: printf ("\t\tval <<= 1;\n"); ! 2790: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 2791: printf ("\t}\n"); ! 2792: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2793: shift_ce (curi->dmode, curi->size); ! 2794: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2795: break; ! 2796: case i_ROL: ! 2797: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2798: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2799: fill_prefetch_next (); ! 2800: start_brace (); ! 2801: switch (curi->size) { ! 2802: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2803: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2804: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2805: default: abort (); ! 2806: } ! 2807: printf ("\tint ccnt = cnt & 63;\n"); ! 2808: printf ("\tcnt &= 63;\n"); ! 2809: printf ("\tCLEAR_CZNV ();\n"); ! 2810: if (source_is_imm1_8 (curi)) ! 2811: printf ("{"); ! 2812: else ! 2813: printf ("\tif (cnt > 0) {\n"); ! 2814: printf ("\tuae_u32 loval;\n"); ! 2815: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); ! 2816: printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size)); ! 2817: printf ("\tval <<= cnt;\n"); ! 2818: printf ("\tval |= loval;\n"); ! 2819: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 2820: printf ("\tSET_CFLG (val & 1);\n"); ! 2821: printf ("}\n"); ! 2822: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2823: shift_ce (curi->dmode, curi->size); ! 2824: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2825: break; ! 2826: case i_ROR: ! 2827: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2828: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2829: fill_prefetch_next (); ! 2830: start_brace (); ! 2831: switch (curi->size) { ! 2832: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2833: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2834: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2835: default: abort (); ! 2836: } ! 2837: printf ("\tint ccnt = cnt & 63;\n"); ! 2838: printf ("\tcnt &= 63;\n"); ! 2839: printf ("\tCLEAR_CZNV ();\n"); ! 2840: if (source_is_imm1_8 (curi)) ! 2841: printf ("{"); ! 2842: else ! 2843: printf ("\tif (cnt > 0) {"); ! 2844: printf ("\tuae_u32 hival;\n"); ! 2845: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); ! 2846: printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size)); ! 2847: printf ("\tval >>= cnt;\n"); ! 2848: printf ("\tval |= hival;\n"); ! 2849: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 2850: printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); ! 2851: printf ("\t}\n"); ! 2852: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2853: shift_ce (curi->dmode, curi->size); ! 2854: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2855: break; ! 2856: case i_ROXL: ! 2857: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2858: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2859: fill_prefetch_next (); ! 2860: start_brace (); ! 2861: switch (curi->size) { ! 2862: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2863: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2864: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2865: default: abort (); ! 2866: } ! 2867: printf ("\tint ccnt = cnt & 63;\n"); ! 2868: printf ("\tcnt &= 63;\n"); ! 2869: printf ("\tCLEAR_CZNV ();\n"); ! 2870: if (source_is_imm1_8 (curi)) ! 2871: printf ("{"); ! 2872: else { ! 2873: force_range_for_rox ("cnt", curi->size); ! 2874: printf ("\tif (cnt > 0) {\n"); ! 2875: } ! 2876: printf ("\tcnt--;\n"); ! 2877: printf ("\t{\n\tuae_u32 carry;\n"); ! 2878: printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1); ! 2879: printf ("\tcarry = loval & 1;\n"); ! 2880: printf ("\tval = (((val << 1) | GET_XFLG ()) << cnt) | (loval >> 1);\n"); ! 2881: printf ("\tSET_XFLG (carry);\n"); ! 2882: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 2883: printf ("\t} }\n"); ! 2884: printf ("\tSET_CFLG (GET_XFLG ());\n"); ! 2885: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2886: shift_ce (curi->dmode, curi->size); ! 2887: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2888: break; ! 2889: case i_ROXR: ! 2890: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0); ! 2891: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0); ! 2892: fill_prefetch_next (); ! 2893: start_brace (); ! 2894: switch (curi->size) { ! 2895: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2896: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2897: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2898: default: abort (); ! 2899: } ! 2900: printf ("\tint ccnt = cnt & 63;\n"); ! 2901: printf ("\tcnt &= 63;\n"); ! 2902: printf ("\tCLEAR_CZNV ();\n"); ! 2903: if (source_is_imm1_8 (curi)) ! 2904: printf ("{"); ! 2905: else { ! 2906: force_range_for_rox ("cnt", curi->size); ! 2907: printf ("\tif (cnt > 0) {\n"); ! 2908: } ! 2909: printf ("\tcnt--;\n"); ! 2910: printf ("\t{\n\tuae_u32 carry;\n"); ! 2911: printf ("\tuae_u32 hival = (val << 1) | GET_XFLG ();\n"); ! 2912: printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1); ! 2913: printf ("\tval >>= cnt;\n"); ! 2914: printf ("\tcarry = val & 1;\n"); ! 2915: printf ("\tval >>= 1;\n"); ! 2916: printf ("\tval |= hival;\n"); ! 2917: printf ("\tSET_XFLG (carry);\n"); ! 2918: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 2919: printf ("\t} }\n"); ! 2920: printf ("\tSET_CFLG (GET_XFLG ());\n"); ! 2921: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2922: shift_ce (curi->dmode, curi->size); ! 2923: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2924: break; ! 2925: case i_ASRW: ! 2926: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 2927: fill_prefetch_next (); ! 2928: start_brace (); ! 2929: switch (curi->size) { ! 2930: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2931: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2932: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2933: default: abort (); ! 2934: } ! 2935: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); ! 2936: printf ("\tuae_u32 cflg = val & 1;\n"); ! 2937: printf ("\tval = (val >> 1) | sign;\n"); ! 2938: genflags (flag_logical, curi->size, "val", "", ""); ! 2939: printf ("\tSET_CFLG (cflg);\n"); ! 2940: duplicate_carry (0); ! 2941: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2942: break; ! 2943: case i_ASLW: ! 2944: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 2945: fill_prefetch_next (); ! 2946: start_brace (); ! 2947: switch (curi->size) { ! 2948: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2949: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2950: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2951: default: abort (); ! 2952: } ! 2953: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); ! 2954: printf ("\tuae_u32 sign2;\n"); ! 2955: printf ("\tval <<= 1;\n"); ! 2956: genflags (flag_logical, curi->size, "val", "", ""); ! 2957: printf ("\tsign2 = %s & val;\n", cmask (curi->size)); ! 2958: printf ("\tSET_CFLG (sign != 0);\n"); ! 2959: duplicate_carry (0); ! 2960: ! 2961: printf ("\tSET_VFLG (GET_VFLG () | (sign2 != sign));\n"); ! 2962: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2963: break; ! 2964: case i_LSRW: ! 2965: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 2966: fill_prefetch_next (); ! 2967: start_brace (); ! 2968: switch (curi->size) { ! 2969: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2970: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2971: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2972: default: abort (); ! 2973: } ! 2974: printf ("\tuae_u32 carry = val & 1;\n"); ! 2975: printf ("\tval >>= 1;\n"); ! 2976: genflags (flag_logical, curi->size, "val", "", ""); ! 2977: printf ("\tSET_CFLG (carry);\n"); ! 2978: duplicate_carry (0); ! 2979: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2980: break; ! 2981: case i_LSLW: ! 2982: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 2983: fill_prefetch_next (); ! 2984: start_brace (); ! 2985: switch (curi->size) { ! 2986: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 2987: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 2988: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2989: default: abort (); ! 2990: } ! 2991: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); ! 2992: printf ("\tval <<= 1;\n"); ! 2993: genflags (flag_logical, curi->size, "val", "", ""); ! 2994: printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); ! 2995: duplicate_carry (0); ! 2996: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2997: break; ! 2998: case i_ROLW: ! 2999: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 3000: fill_prefetch_next (); ! 3001: start_brace (); ! 3002: switch (curi->size) { ! 3003: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 3004: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 3005: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 3006: default: abort (); ! 3007: } ! 3008: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); ! 3009: printf ("\tval <<= 1;\n"); ! 3010: printf ("\tif (carry) val |= 1;\n"); ! 3011: genflags (flag_logical, curi->size, "val", "", ""); ! 3012: printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); ! 3013: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 3014: break; ! 3015: case i_RORW: ! 3016: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 3017: fill_prefetch_next (); ! 3018: start_brace (); ! 3019: switch (curi->size) { ! 3020: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 3021: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 3022: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 3023: default: abort (); ! 3024: } ! 3025: printf ("\tuae_u32 carry = val & 1;\n"); ! 3026: printf ("\tval >>= 1;\n"); ! 3027: printf ("\tif (carry) val |= %s;\n", cmask (curi->size)); ! 3028: genflags (flag_logical, curi->size, "val", "", ""); ! 3029: printf ("\tSET_CFLG (carry);\n"); ! 3030: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 3031: break; ! 3032: case i_ROXLW: ! 3033: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 3034: fill_prefetch_next (); ! 3035: start_brace (); ! 3036: switch (curi->size) { ! 3037: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 3038: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 3039: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 3040: default: abort (); ! 3041: } ! 3042: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); ! 3043: printf ("\tval <<= 1;\n"); ! 3044: printf ("\tif (GET_XFLG ()) val |= 1;\n"); ! 3045: genflags (flag_logical, curi->size, "val", "", ""); ! 3046: printf ("\tSET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); ! 3047: duplicate_carry (0); ! 3048: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 3049: break; ! 3050: case i_ROXRW: ! 3051: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, 0); ! 3052: fill_prefetch_next (); ! 3053: start_brace (); ! 3054: switch (curi->size) { ! 3055: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 3056: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 3057: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 3058: default: abort (); ! 3059: } ! 3060: printf ("\tuae_u32 carry = val & 1;\n"); ! 3061: printf ("\tval >>= 1;\n"); ! 3062: printf ("\tif (GET_XFLG ()) val |= %s;\n", cmask (curi->size)); ! 3063: genflags (flag_logical, curi->size, "val", "", ""); ! 3064: printf ("\tSET_CFLG (carry);\n"); ! 3065: duplicate_carry (0); ! 3066: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 3067: break; ! 3068: case i_MOVEC2: ! 3069: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 3070: fill_prefetch_next (); ! 3071: start_brace (); ! 3072: printf ("\tint regno = (src >> 12) & 15;\n"); ! 3073: printf ("\tuae_u32 *regp = regs.regs + regno;\n"); ! 3074: printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr); ! 3075: break; ! 3076: case i_MOVE2C: ! 3077: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 3078: fill_prefetch_next (); ! 3079: start_brace (); ! 3080: printf ("\tint regno = (src >> 12) & 15;\n"); ! 3081: printf ("\tuae_u32 *regp = regs.regs + regno;\n"); ! 3082: printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr); ! 3083: break; ! 3084: case i_CAS: ! 3085: { ! 3086: int old_brace_level; ! 3087: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 3088: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 3089: fill_prefetch_0 (); ! 3090: start_brace (); ! 3091: printf ("\tint ru = (src >> 6) & 7;\n"); ! 3092: printf ("\tint rc = src & 7;\n"); ! 3093: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, rc)", "dst"); ! 3094: printf ("\tif (GET_ZFLG ())"); ! 3095: old_brace_level = n_braces; ! 3096: start_brace (); ! 3097: genastore ("(m68k_dreg (regs, ru))", curi->dmode, "dstreg", curi->size, "dst"); ! 3098: pop_braces (old_brace_level); ! 3099: printf ("else"); ! 3100: start_brace (); ! 3101: printf ("m68k_dreg (regs, rc) = dst;\n"); ! 3102: pop_braces (old_brace_level); ! 3103: } ! 3104: break; ! 3105: case i_CAS2: ! 3106: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3107: printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n"); ! 3108: printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n"); ! 3109: if (curi->size == sz_word) { ! 3110: int old_brace_level = n_braces; ! 3111: printf ("\tuae_u16 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcw, srcw); ! 3112: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1"); ! 3113: printf ("\tif (GET_ZFLG ()) {\n"); ! 3114: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2"); ! 3115: printf ("\tif (GET_ZFLG ()) {\n"); ! 3116: printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstw); ! 3117: printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n", dstw); ! 3118: printf ("\t}}\n"); ! 3119: pop_braces (old_brace_level); ! 3120: printf ("\tif (! GET_ZFLG ()) {\n"); ! 3121: printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = (m68k_dreg (regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n"); ! 3122: printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = (m68k_dreg (regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n"); ! 3123: printf ("\t}\n"); ! 3124: } else { ! 3125: int old_brace_level = n_braces; ! 3126: printf ("\tuae_u32 dst1 = %s (rn1), dst2 = %s (rn2);\n", srcl, srcl); ! 3127: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, (extra >> 16) & 7)", "dst1"); ! 3128: printf ("\tif (GET_ZFLG ()) {\n"); ! 3129: genflags (flag_cmp, curi->size, "newv", "m68k_dreg (regs, extra & 7)", "dst2"); ! 3130: printf ("\tif (GET_ZFLG ()) {\n"); ! 3131: printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 22) & 7));\n", dstl); ! 3132: printf ("\t%s (rn1, m68k_dreg (regs, (extra >> 6) & 7));\n", dstl); ! 3133: printf ("\t}}\n"); ! 3134: pop_braces (old_brace_level); ! 3135: printf ("\tif (! GET_ZFLG ()) {\n"); ! 3136: printf ("\tm68k_dreg (regs, (extra >> 22) & 7) = dst1;\n"); ! 3137: printf ("\tm68k_dreg (regs, (extra >> 6) & 7) = dst2;\n"); ! 3138: printf ("\t}\n"); ! 3139: } ! 3140: break; ! 3141: case i_MOVES: /* ignore DFC and SFC when using_mmu == false */ ! 3142: { ! 3143: int old_brace_level; ! 3144: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3145: printf ("\tif (extra & 0x800)\n"); ! 3146: { ! 3147: int old_m68k_pc_offset = m68k_pc_offset; ! 3148: old_brace_level = n_braces; ! 3149: start_brace (); ! 3150: printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n"); ! 3151: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0); ! 3152: genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 3153: pop_braces (old_brace_level); ! 3154: m68k_pc_offset = old_m68k_pc_offset; ! 3155: } ! 3156: printf ("else"); ! 3157: { ! 3158: start_brace (); ! 3159: genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0, GF_FC); ! 3160: printf ("\tif (extra & 0x8000) {\n"); ! 3161: switch (curi->size) { ! 3162: case sz_byte: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break; ! 3163: case sz_word: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break; ! 3164: case sz_long: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = src;\n"); break; ! 3165: default: abort (); ! 3166: } ! 3167: printf ("\t} else {\n"); ! 3168: genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, ""); ! 3169: printf ("\t}\n"); ! 3170: sync_m68k_pc (); ! 3171: pop_braces (old_brace_level); ! 3172: } ! 3173: } ! 3174: break; ! 3175: case i_BKPT: /* only needed for hardware emulators */ ! 3176: sync_m68k_pc (); ! 3177: printf ("\top_illg (opcode);\n"); ! 3178: break; ! 3179: case i_CALLM: /* not present in 68030 */ ! 3180: sync_m68k_pc (); ! 3181: printf ("\top_illg (opcode);\n"); ! 3182: break; ! 3183: case i_RTM: /* not present in 68030 */ ! 3184: sync_m68k_pc (); ! 3185: printf ("\top_illg (opcode);\n"); ! 3186: break; ! 3187: case i_TRAPcc: ! 3188: if (curi->smode != am_unknown && curi->smode != am_illg) ! 3189: genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); ! 3190: fill_prefetch_0 (); ! 3191: printf ("\tif (cctrue (%d)) { Exception (7, m68k_getpc () ,M68000_EXC_SRC_CPU); goto %s; }\n", curi->cc, endlabelstr); ! 3192: need_endlabel = 1; ! 3193: break; ! 3194: case i_DIVL: ! 3195: printf ("\tuaecptr oldpc = m68k_getpc ();\n"); ! 3196: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3197: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 3198: if (using_ce020) { ! 3199: addcycles_ce020 (70); ! 3200: } ! 3201: sync_m68k_pc (); ! 3202: printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n"); ! 3203: break; ! 3204: case i_MULL: ! 3205: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3206: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0); ! 3207: if (using_ce020) { ! 3208: addcycles_ce020 (40); ! 3209: } ! 3210: sync_m68k_pc (); ! 3211: printf ("\tm68k_mull(opcode, dst, extra);\n"); ! 3212: break; ! 3213: case i_BFTST: ! 3214: case i_BFEXTU: ! 3215: case i_BFCHG: ! 3216: case i_BFEXTS: ! 3217: case i_BFCLR: ! 3218: case i_BFFFO: ! 3219: case i_BFSET: ! 3220: case i_BFINS: ! 3221: { ! 3222: const char *getb, *putb; ! 3223: ! 3224: if (using_mmu || using_ce020) { ! 3225: getb = "x_get_bitfield"; ! 3226: putb = "x_put_bitfield"; ! 3227: } else { ! 3228: getb = "get_bitfield"; ! 3229: putb = "put_bitfield"; ! 3230: } ! 3231: ! 3232: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3233: genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0); ! 3234: start_brace (); ! 3235: printf ("\tuae_u32 bdata[2];\n"); ! 3236: printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n"); ! 3237: printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n"); ! 3238: if (curi->dmode == Dreg) { ! 3239: printf ("\tuae_u32 tmp = m68k_dreg(regs, dstreg);\n"); ! 3240: printf ("\toffset &= 0x1f;\n"); ! 3241: printf ("\ttmp = (tmp << offset) | (tmp >> (32 - offset));\n"); ! 3242: printf ("\tbdata[0] = tmp & ((1 << (32 - width)) - 1);\n"); ! 3243: } else { ! 3244: printf ("\tuae_u32 tmp;\n"); ! 3245: printf ("\tdsta += offset >> 3;\n"); ! 3246: printf ("\ttmp = %s (dsta, bdata, offset, width);\n", getb); ! 3247: } ! 3248: printf ("\tSET_NFLG_ALWAYS (((uae_s32)tmp) < 0 ? 1 : 0);\n"); ! 3249: if (curi->mnemo == i_BFEXTS) ! 3250: printf ("\ttmp = (uae_s32)tmp >> (32 - width);\n"); ! 3251: else ! 3252: printf ("\ttmp >>= (32 - width);\n"); ! 3253: printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n"); ! 3254: switch (curi->mnemo) { ! 3255: case i_BFTST: ! 3256: break; ! 3257: case i_BFEXTU: ! 3258: case i_BFEXTS: ! 3259: printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = tmp;\n"); ! 3260: break; ! 3261: case i_BFCHG: ! 3262: printf ("\ttmp = tmp ^ (0xffffffffu >> (32 - width));\n"); ! 3263: break; ! 3264: case i_BFCLR: ! 3265: printf ("\ttmp = 0;\n"); ! 3266: break; ! 3267: case i_BFFFO: ! 3268: printf ("\t{ uae_u32 mask = 1 << (width - 1);\n"); ! 3269: printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n"); ! 3270: printf ("\tm68k_dreg (regs, (extra >> 12) & 7) = offset;\n"); ! 3271: break; ! 3272: case i_BFSET: ! 3273: printf ("\ttmp = 0xffffffffu >> (32 - width);\n"); ! 3274: break; ! 3275: case i_BFINS: ! 3276: printf ("\ttmp = m68k_dreg (regs, (extra >> 12) & 7);\n"); ! 3277: printf ("\ttmp = tmp & (0xffffffffu >> (32 - width));\n"); ! 3278: printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n"); ! 3279: printf ("\tSET_ZFLG (tmp == 0);\n"); ! 3280: break; ! 3281: default: ! 3282: break; ! 3283: } ! 3284: if (curi->mnemo == i_BFCHG ! 3285: || curi->mnemo == i_BFCLR ! 3286: || curi->mnemo == i_BFSET ! 3287: || curi->mnemo == i_BFINS) { ! 3288: if (curi->dmode == Dreg) { ! 3289: printf ("\ttmp = bdata[0] | (tmp << (32 - width));\n"); ! 3290: printf ("\tm68k_dreg(regs, dstreg) = (tmp >> offset) | (tmp << (32 - offset));\n"); ! 3291: } else { ! 3292: printf ("\t%s(dsta, bdata, tmp, offset, width);\n", putb); ! 3293: } ! 3294: } ! 3295: } ! 3296: break; ! 3297: case i_PACK: ! 3298: if (curi->smode == Dreg) { ! 3299: printf ("\tuae_u16 val = m68k_dreg (regs, srcreg) + %s;\n", gen_nextiword (0)); ! 3300: printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n"); ! 3301: } else { ! 3302: printf ("\tuae_u16 val;\n"); ! 3303: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); ! 3304: printf ("\tval = (uae_u16)%s (m68k_areg (regs, srcreg));\n", srcb); ! 3305: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); ! 3306: printf ("\tval = (val | ((uae_u16)%s (m68k_areg (regs, srcreg)) << 8)) + %s;\n", srcb, gen_nextiword (0)); ! 3307: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); ! 3308: gen_set_fault_pc (); ! 3309: printf ("\t%s (m68k_areg (regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n", dstb); ! 3310: } ! 3311: break; ! 3312: case i_UNPK: ! 3313: if (curi->smode == Dreg) { ! 3314: printf ("\tuae_u16 val = m68k_dreg (regs, srcreg);\n"); ! 3315: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0)); ! 3316: printf ("\tm68k_dreg (regs, dstreg) = (m68k_dreg (regs, dstreg) & 0xffff0000) | (val & 0xffff);\n"); ! 3317: } else { ! 3318: printf ("\tuae_u16 val;\n"); ! 3319: printf ("\tm68k_areg (regs, srcreg) -= areg_byteinc[srcreg];\n"); ! 3320: printf ("\tval = (uae_u16)%s (m68k_areg (regs, srcreg));\n", srcb); ! 3321: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword (0)); ! 3322: if (cpu_level >= 2) { ! 3323: printf ("\tm68k_areg (regs, dstreg) -= 2 * areg_byteinc[dstreg];\n"); ! 3324: printf ("\t%s (m68k_areg (regs, dstreg) + areg_byteinc[dstreg], val);\n", dstb); ! 3325: printf ("\t%s (m68k_areg (regs, dstreg), val >> 8);\n", dstb); ! 3326: } else { ! 3327: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); ! 3328: printf ("\t%s (m68k_areg (regs, dstreg),val);\n", dstb); ! 3329: printf ("\tm68k_areg (regs, dstreg) -= areg_byteinc[dstreg];\n"); ! 3330: gen_set_fault_pc (); ! 3331: printf ("\t%s (m68k_areg (regs, dstreg),val >> 8);\n", dstb); ! 3332: } ! 3333: } ! 3334: break; ! 3335: case i_TAS: ! 3336: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0); ! 3337: genflags (flag_logical, curi->size, "src", "", ""); ! 3338: if (!isreg (curi->smode)) ! 3339: addcycles000 (2); ! 3340: fill_prefetch_next (); ! 3341: printf ("\tsrc |= 0x80;\n"); ! 3342: if (cpu_level >= 2 || curi->smode == Dreg || !using_ce) { ! 3343: if (next_cpu_level < 2) ! 3344: next_cpu_level = 2 - 1; ! 3345: genastore ("src", curi->smode, "srcreg", curi->size, "src"); ! 3346: } else { ! 3347: printf ("\tif (!is_cycle_ce ()) {\n"); ! 3348: genastore ("src", curi->smode, "srcreg", curi->size, "src"); ! 3349: printf ("\t} else {\n"); ! 3350: printf ("\t\tdo_cycles_ce000 (4);\n"); ! 3351: printf ("\t}\n"); ! 3352: } ! 3353: break; ! 3354: case i_FPP: ! 3355: fpulimit(); ! 3356: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3357: sync_m68k_pc (); ! 3358: printf ("\tfpuop_arithmetic(opcode, extra);\n"); ! 3359: break; ! 3360: case i_FDBcc: ! 3361: fpulimit(); ! 3362: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3363: sync_m68k_pc (); ! 3364: printf ("\tfpuop_dbcc (opcode, extra);\n"); ! 3365: break; ! 3366: case i_FScc: ! 3367: fpulimit(); ! 3368: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3369: sync_m68k_pc (); ! 3370: printf ("\tfpuop_scc (opcode, extra);\n"); ! 3371: break; ! 3372: case i_FTRAPcc: ! 3373: fpulimit(); ! 3374: printf ("\tuaecptr oldpc = m68k_getpc ();\n"); ! 3375: printf ("\tuae_u16 extra = %s;\n", gen_nextiword (0)); ! 3376: if (curi->smode != am_unknown && curi->smode != am_illg) ! 3377: genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0); ! 3378: sync_m68k_pc (); ! 3379: printf ("\tfpuop_trapcc (opcode, oldpc, extra);\n"); ! 3380: break; ! 3381: case i_FBcc: ! 3382: fpulimit(); ! 3383: sync_m68k_pc (); ! 3384: start_brace (); ! 3385: printf ("\tuaecptr pc = m68k_getpc ();\n"); ! 3386: genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0); ! 3387: sync_m68k_pc (); ! 3388: printf ("\tfpuop_bcc (opcode, pc,extra);\n"); ! 3389: break; ! 3390: case i_FSAVE: ! 3391: fpulimit(); ! 3392: sync_m68k_pc (); ! 3393: printf ("\tfpuop_save (opcode);\n"); ! 3394: break; ! 3395: case i_FRESTORE: ! 3396: fpulimit(); ! 3397: sync_m68k_pc (); ! 3398: printf ("\tfpuop_restore (opcode);\n"); ! 3399: break; ! 3400: ! 3401: case i_CINVL: ! 3402: case i_CINVP: ! 3403: case i_CINVA: ! 3404: case i_CPUSHL: ! 3405: case i_CPUSHP: ! 3406: case i_CPUSHA: ! 3407: if (using_mmu) ! 3408: printf ("\tflush_mmu(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n"); ! 3409: printf ("\tif (opcode & 0x80)\n"); ! 3410: printf ("\t\tflush_icache(m68k_areg (regs, opcode & 3), (opcode >> 6) & 3);\n"); ! 3411: break; ! 3412: ! 3413: case i_MOVE16: ! 3414: { ! 3415: if ((opcode & 0xfff8) == 0xf620) { ! 3416: /* MOVE16 (Ax)+,(Ay)+ */ ! 3417: printf ("\tuae_u32 v1, v2, v3, v4;\n"); ! 3418: printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n"); ! 3419: printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0)); ! 3420: printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n"); ! 3421: printf ("\tv1 = %s (mems);\n", srcl); ! 3422: printf ("\tv2 = %s (mems + 4);\n", srcl); ! 3423: printf ("\tv3 = %s (mems + 8);\n", srcl); ! 3424: printf ("\tv4 = %s (mems + 12);\n", srcl); ! 3425: printf ("\t%s (memd , v1);\n", dstl); ! 3426: printf ("\t%s (memd + 4, v2);\n", dstl); ! 3427: printf ("\t%s (memd + 8, v3);\n", dstl); ! 3428: printf ("\t%s (memd + 12, v4);\n", dstl); ! 3429: printf ("\tif (srcreg != dstreg)\n"); ! 3430: printf ("\t\tm68k_areg (regs, srcreg) += 16;\n"); ! 3431: printf ("\tm68k_areg (regs, dstreg) += 16;\n"); ! 3432: } else { ! 3433: /* Other variants */ ! 3434: printf ("\tuae_u32 v1, v2, v3, v4;\n"); ! 3435: genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0); ! 3436: genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0); ! 3437: printf ("\tmemsa &= ~15;\n"); ! 3438: printf ("\tmemda &= ~15;\n"); ! 3439: printf ("\tv1 = %s (memsa);\n", srcl); ! 3440: printf ("\tv2 = %s (memsa + 4);\n", srcl); ! 3441: printf ("\tv3 = %s (memsa + 8);\n", srcl); ! 3442: printf ("\tv4 = %s (memsa + 12);\n", srcl); ! 3443: printf ("\t%s (memda , v1);\n", dstl); ! 3444: printf ("\t%s (memda + 4, v2);\n", dstl); ! 3445: printf ("\t%s (memda + 8, v3);\n", dstl); ! 3446: printf ("\t%s (memda + 12, v4);\n", dstl); ! 3447: if ((opcode & 0xfff8) == 0xf600) ! 3448: printf ("\tm68k_areg (regs, srcreg) += 16;\n"); ! 3449: else if ((opcode & 0xfff8) == 0xf608) ! 3450: printf ("\tm68k_areg (regs, dstreg) += 16;\n"); ! 3451: } ! 3452: } ! 3453: break; ! 3454: ! 3455: case i_PFLUSHN: ! 3456: case i_PFLUSH: ! 3457: case i_PFLUSHAN: ! 3458: case i_PFLUSHA: ! 3459: case i_PLPAR: ! 3460: case i_PLPAW: ! 3461: case i_PTESTR: ! 3462: case i_PTESTW: ! 3463: sync_m68k_pc (); ! 3464: printf ("\tmmu_op (opcode, 0);\n"); ! 3465: break; ! 3466: case i_MMUOP030: ! 3467: printf ("\tuaecptr pc = m68k_getpc ();\n"); ! 3468: printf ("\tuae_u16 extra = x_get_word (pc + 2);\n"); ! 3469: m68k_pc_offset += 2; ! 3470: sync_m68k_pc (); ! 3471: if (curi->smode == Areg || curi->smode == Dreg) ! 3472: printf("\tuae_u16 extraa = 0;\n"); ! 3473: else ! 3474: genamode (curi->smode, "srcreg", curi->size, "extra", 0, 0, 0); ! 3475: sync_m68k_pc (); ! 3476: printf ("\tmmu_op30 (pc, opcode, extra, extraa);\n"); ! 3477: break; ! 3478: default: ! 3479: abort (); ! 3480: break; ! 3481: } ! 3482: finish_braces (); ! 3483: if (limit_braces) { ! 3484: printf ("\n#endif\n"); ! 3485: n_braces = limit_braces; ! 3486: limit_braces = 0; ! 3487: finish_braces (); ! 3488: } ! 3489: if (did_prefetch >= 0) ! 3490: fill_prefetch_finish (); ! 3491: if (!count_cycles) ! 3492: addcycles_ce020 (2); ! 3493: sync_m68k_pc (); ! 3494: did_prefetch = 0; ! 3495: } ! 3496: ! 3497: static void generate_includes (FILE * f) ! 3498: { ! 3499: fprintf (f, "#include \"sysconfig.h\"\n"); ! 3500: fprintf (f, "#include \"sysdeps.h\"\n"); ! 3501: fprintf (f, "#include \"options_cpu.h\"\n"); ! 3502: fprintf (f, "#include \"memory.h\"\n"); ! 3503: fprintf (f, "#include \"custom.h\"\n"); ! 3504: fprintf (f, "#include \"events.h\"\n"); ! 3505: fprintf (f, "#include \"newcpu.h\"\n"); ! 3506: fprintf (f, "#include \"cpu_prefetch.h\"\n"); ! 3507: fprintf (f, "#include \"cputbl.h\"\n"); ! 3508: fprintf (f, "#include \"main.h\"\n"); ! 3509: fprintf (f, "#include \"cpummu.h\"\n"); ! 3510: ! 3511: ! 3512: fprintf (f, "#define CPUFUNC(x) x##_ff\n" ! 3513: "#define SET_CFLG_ALWAYS(x) SET_CFLG(x)\n" ! 3514: "#define SET_NFLG_ALWAYS(x) SET_NFLG(x)\n" ! 3515: "#ifdef NOFLAGS\n" ! 3516: "#include \"noflags.h\"\n" ! 3517: "#endif\n"); ! 3518: } ! 3519: ! 3520: static int postfix; ! 3521: ! 3522: ! 3523: static char *decodeEA (amodes mode, wordsizes size) ! 3524: { ! 3525: static char buffer[80]; ! 3526: ! 3527: buffer[0] = 0; ! 3528: switch (mode){ ! 3529: case Dreg: ! 3530: strcpy (buffer,"Dn"); ! 3531: break; ! 3532: case Areg: ! 3533: strcpy (buffer,"An"); ! 3534: break; ! 3535: case Aind: ! 3536: strcpy (buffer,"(An)"); ! 3537: break; ! 3538: case Aipi: ! 3539: strcpy (buffer,"(An)+"); ! 3540: break; ! 3541: case Apdi: ! 3542: strcpy (buffer,"-(An)"); ! 3543: break; ! 3544: case Ad16: ! 3545: strcpy (buffer,"(d16,An)"); ! 3546: break; ! 3547: case Ad8r: ! 3548: strcpy (buffer,"(d8,An,Xn)"); ! 3549: break; ! 3550: case PC16: ! 3551: strcpy (buffer,"(d16,PC)"); ! 3552: break; ! 3553: case PC8r: ! 3554: strcpy (buffer,"(d8,PC,Xn)"); ! 3555: break; ! 3556: case absw: ! 3557: strcpy (buffer,"(xxx).W"); ! 3558: break; ! 3559: case absl: ! 3560: strcpy (buffer,"(xxx).L"); ! 3561: break; ! 3562: case imm: ! 3563: switch (size){ ! 3564: case sz_byte: ! 3565: strcpy (buffer,"#<data>.B"); ! 3566: break; ! 3567: case sz_word: ! 3568: strcpy (buffer,"#<data>.W"); ! 3569: break; ! 3570: case sz_long: ! 3571: strcpy (buffer,"#<data>.L"); ! 3572: break; ! 3573: default: ! 3574: break; ! 3575: } ! 3576: break; ! 3577: case imm0: ! 3578: strcpy (buffer,"#<data>.B"); ! 3579: break; ! 3580: case imm1: ! 3581: strcpy (buffer,"#<data>.W"); ! 3582: break; ! 3583: case imm2: ! 3584: strcpy (buffer,"#<data>.L"); ! 3585: break; ! 3586: case immi: ! 3587: strcpy (buffer,"#<data>"); ! 3588: break; ! 3589: ! 3590: default: ! 3591: break; ! 3592: } ! 3593: return buffer; ! 3594: } ! 3595: ! 3596: static char *outopcode (int opcode) ! 3597: { ! 3598: static char out[100]; ! 3599: struct instr *ins; ! 3600: int i; ! 3601: ! 3602: ins = &table68k[opcode]; ! 3603: for (i = 0; lookuptab[i].name[0]; i++) { ! 3604: if (ins->mnemo == lookuptab[i].mnemo) ! 3605: break; ! 3606: } ! 3607: { ! 3608: // char *s = ua (lookuptab[i].name); ! 3609: const char *s = lookuptab[i].name; ! 3610: strcpy (out, s); ! 3611: //xfree (s); ! 3612: } ! 3613: if (ins->smode == immi) ! 3614: strcat (out, "Q"); ! 3615: if (ins->size == sz_byte) ! 3616: strcat (out,".B"); ! 3617: if (ins->size == sz_word) ! 3618: strcat (out,".W"); ! 3619: if (ins->size == sz_long) ! 3620: strcat (out,".L"); ! 3621: strcat (out," "); ! 3622: if (ins->suse) ! 3623: strcat (out, decodeEA (ins->smode, ins->size)); ! 3624: if (ins->duse) { ! 3625: if (ins->suse) strcat (out,","); ! 3626: strcat (out, decodeEA (ins->dmode, ins->size)); ! 3627: } ! 3628: return out; ! 3629: } ! 3630: ! 3631: static void generate_one_opcode (int rp) ! 3632: { ! 3633: int idx; ! 3634: uae_u16 smsk, dmsk; ! 3635: long int opcode = opcode_map[rp]; ! 3636: int i68000 = table68k[opcode].clev > 0; ! 3637: ! 3638: if (table68k[opcode].mnemo == i_ILLG ! 3639: || table68k[opcode].clev > cpu_level) ! 3640: return; ! 3641: ! 3642: for (idx = 0; lookuptab[idx].name[0]; idx++) { ! 3643: if (table68k[opcode].mnemo == lookuptab[idx].mnemo) ! 3644: break; ! 3645: } ! 3646: ! 3647: if (table68k[opcode].handler != -1) ! 3648: return; ! 3649: ! 3650: if (opcode_next_clev[rp] != cpu_level) { ! 3651: //char *name = ua (lookuptab[idx].name); ! 3652: const char *name = lookuptab[idx].name; ! 3653: if (generate_stbl) ! 3654: fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n", ! 3655: (using_ce || using_ce020) ? "(cpuop_func*)" : "", ! 3656: opcode, opcode_last_postfix[rp], ! 3657: opcode, name); ! 3658: //xfree (name); ! 3659: return; ! 3660: } ! 3661: fprintf (headerfile, "extern %s op_%04lx_%d_nf;\n", ! 3662: (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix); ! 3663: fprintf (headerfile, "extern %s op_%04lx_%d_ff;\n", ! 3664: (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix); ! 3665: printf ("/* %s */\n", outopcode (opcode)); ! 3666: if (i68000) ! 3667: printf("#ifndef CPUEMU_68000_ONLY\n"); ! 3668: printf ("%s REGPARAM2 CPUFUNC(op_%04lx_%d)(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "unsigned long", opcode, postfix); ! 3669: ! 3670: switch (table68k[opcode].stype) { ! 3671: case 0: smsk = 7; break; ! 3672: case 1: smsk = 255; break; ! 3673: case 2: smsk = 15; break; ! 3674: case 3: smsk = 7; break; ! 3675: case 4: smsk = 7; break; ! 3676: case 5: smsk = 63; break; ! 3677: case 7: smsk = 3; break; ! 3678: default: abort (); ! 3679: } ! 3680: dmsk = 7; ! 3681: ! 3682: next_cpu_level = -1; ! 3683: if (table68k[opcode].suse ! 3684: && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 ! 3685: && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 ! 3686: && table68k[opcode].smode != absw && table68k[opcode].smode != absl ! 3687: && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) ! 3688: { ! 3689: if (table68k[opcode].spos == -1) { ! 3690: if (((int) table68k[opcode].sreg) >= 128) ! 3691: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); ! 3692: else ! 3693: printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg); ! 3694: } else { ! 3695: char source[100]; ! 3696: int pos = table68k[opcode].spos; ! 3697: ! 3698: if (pos) ! 3699: sprintf (source, "((opcode >> %d) & %d)", pos, smsk); ! 3700: else ! 3701: sprintf (source, "(opcode & %d)", smsk); ! 3702: ! 3703: if (table68k[opcode].stype == 3) ! 3704: printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); ! 3705: else if (table68k[opcode].stype == 1) ! 3706: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); ! 3707: else ! 3708: printf ("\tuae_u32 srcreg = %s;\n", source); ! 3709: } ! 3710: } ! 3711: if (table68k[opcode].duse ! 3712: /* Yes, the dmode can be imm, in case of LINK or DBcc */ ! 3713: && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 ! 3714: && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 ! 3715: && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) ! 3716: { ! 3717: if (table68k[opcode].dpos == -1) { ! 3718: if (((int) table68k[opcode].dreg) >= 128) ! 3719: printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); ! 3720: else ! 3721: printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg); ! 3722: } else { ! 3723: int pos = table68k[opcode].dpos; ! 3724: if (pos) ! 3725: printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", ! 3726: pos, dmsk); ! 3727: else ! 3728: printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); ! 3729: } ! 3730: } ! 3731: need_endlabel = 0; ! 3732: endlabelno++; ! 3733: sprintf (endlabelstr, "endlabel%d", endlabelno); ! 3734: count_read = count_write = count_ncycles = count_cycles = 0; ! 3735: count_read_ea = count_write_ea = count_cycles_ea = 0; ! 3736: gen_opcode (opcode); ! 3737: if (need_endlabel) ! 3738: printf ("%s: ;\n", endlabelstr); ! 3739: returncycles ("", insn_n_cycles); ! 3740: printf ("}"); ! 3741: if (using_ce || using_prefetch) { ! 3742: if (count_read + count_write + count_cycles == 0) ! 3743: count_cycles = 4; ! 3744: printf (" /* %d%s (%d/%d)", ! 3745: (count_read + count_write) * 4 + count_cycles, count_ncycles ? "+" : "", count_read, count_write); ! 3746: printf (" */\n"); ! 3747: } else { ! 3748: printf("\n"); ! 3749: } ! 3750: printf ("\n"); ! 3751: if (i68000) ! 3752: printf("#endif\n"); ! 3753: opcode_next_clev[rp] = next_cpu_level; ! 3754: opcode_last_postfix[rp] = postfix; ! 3755: ! 3756: if (generate_stbl) { ! 3757: // char *name = ua (lookuptab[idx].name); ! 3758: const char *name = lookuptab[idx].name; ! 3759: if (i68000) ! 3760: fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n"); ! 3761: fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n", ! 3762: (using_ce || using_ce020) ? "(cpuop_func*)" : "", ! 3763: opcode, postfix, opcode, name); ! 3764: if (i68000) ! 3765: fprintf (stblfile, "#endif\n"); ! 3766: //xfree (name); ! 3767: } ! 3768: } ! 3769: ! 3770: static void generate_func (void) ! 3771: { ! 3772: int j, rp; ! 3773: ! 3774: /* sam: this is for people with low memory (eg. me :)) */ ! 3775: printf ("\n" ! 3776: "#if !defined(PART_1) && !defined(PART_2) && " ! 3777: "!defined(PART_3) && !defined(PART_4) && " ! 3778: "!defined(PART_5) && !defined(PART_6) && " ! 3779: "!defined(PART_7) && !defined(PART_8)" ! 3780: "\n" ! 3781: "#define PART_1 1\n" ! 3782: "#define PART_2 1\n" ! 3783: "#define PART_3 1\n" ! 3784: "#define PART_4 1\n" ! 3785: "#define PART_5 1\n" ! 3786: "#define PART_6 1\n" ! 3787: "#define PART_7 1\n" ! 3788: "#define PART_8 1\n" ! 3789: "#endif\n\n"); ! 3790: ! 3791: rp = 0; ! 3792: for(j = 1; j <= 8; ++j) { ! 3793: int k = (j * nr_cpuop_funcs) / 8; ! 3794: printf ("#ifdef PART_%d\n",j); ! 3795: for (; rp < k; rp++) ! 3796: generate_one_opcode (rp); ! 3797: printf ("#endif\n\n"); ! 3798: } ! 3799: ! 3800: if (generate_stbl) ! 3801: fprintf (stblfile, "{ 0, 0 }};\n"); ! 3802: } ! 3803: ! 3804: int main (int argc, char **argv) ! 3805: { ! 3806: int i, rp, postfix2; ! 3807: char fname[100]; ! 3808: ! 3809: read_table68k (); ! 3810: do_merges (); ! 3811: ! 3812: opcode_map = xmalloc (int, nr_cpuop_funcs); ! 3813: opcode_last_postfix = xmalloc (int, nr_cpuop_funcs); ! 3814: opcode_next_clev = xmalloc (int, nr_cpuop_funcs); ! 3815: counts = xmalloc (unsigned long, 65536); ! 3816: read_counts (); ! 3817: ! 3818: /* It would be a lot nicer to put all in one file (we'd also get rid of ! 3819: * cputbl.h that way), but cpuopti can't cope. That could be fixed, but ! 3820: * I don't dare to touch the 68k version. */ ! 3821: ! 3822: headerfile = fopen ("cputbl.h", "wb"); ! 3823: ! 3824: stblfile = fopen ("cpustbl.c", "wb"); ! 3825: generate_includes (stblfile); ! 3826: ! 3827: using_prefetch = 0; ! 3828: using_indirect = 0; ! 3829: using_exception_3 = 1; ! 3830: using_ce = 0; ! 3831: ! 3832: postfix2 = -1; ! 3833: for (i = 0; i < 32; i++) { ! 3834: postfix = i; ! 3835: if ((i >= 6 && i < 11) || (i > 12 && i < 20) || (i > 23 && i < 31)) ! 3836: continue; ! 3837: generate_stbl = 1; ! 3838: if (i == 0 || i == 11 || i == 12 || i == 20 || i == 21 || i == 31) { ! 3839: if (generate_stbl) ! 3840: fprintf (stblfile, "#ifdef CPUEMU_%d\n", postfix); ! 3841: postfix2 = postfix; ! 3842: sprintf (fname, "cpuemu_%d.c", postfix); ! 3843: if (freopen (fname, "wb", stdout) == NULL) { ! 3844: perror(fname); ! 3845: return -1; ! 3846: } ! 3847: generate_includes (stdout); ! 3848: } ! 3849: using_mmu = 0; ! 3850: using_prefetch = 0; ! 3851: using_ce = 0; ! 3852: using_ce020 = 0; ! 3853: using_mmu = 0; ! 3854: cpu_level = 5 - i; ! 3855: if (i == 11 || i == 12) { ! 3856: cpu_level = 0; ! 3857: using_prefetch = 1; ! 3858: using_exception_3 = 1; ! 3859: if (i == 12) ! 3860: using_ce = 1; ! 3861: for (rp = 0; rp < nr_cpuop_funcs; rp++) ! 3862: opcode_next_clev[rp] = 0; ! 3863: } else if (i == 20) { ! 3864: cpu_level = 2; ! 3865: using_ce020 = 1; ! 3866: read_counts (); ! 3867: for (rp = 0; rp < nr_cpuop_funcs; rp++) ! 3868: opcode_next_clev[rp] = cpu_level; ! 3869: } else if (i == 21 || i == 22 || i == 23) { ! 3870: cpu_level = 3 + (23 - i); ! 3871: using_ce020 = 2; ! 3872: if (i == 21) { ! 3873: read_counts (); ! 3874: for (rp = 0; rp < nr_cpuop_funcs; rp++) ! 3875: opcode_next_clev[rp] = cpu_level; ! 3876: } ! 3877: } else if (i >= 31 && i < 40) { ! 3878: cpu_level = 4; ! 3879: using_mmu = 1; ! 3880: if (i == 31) ! 3881: read_counts (); ! 3882: for (rp = 0; rp < nr_cpuop_funcs; rp++) ! 3883: opcode_next_clev[rp] = cpu_level; ! 3884: } ! 3885: ! 3886: if (generate_stbl) { ! 3887: if ((i > 0 && i < 10) || (i >= 20)) ! 3888: fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n"); ! 3889: fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix); ! 3890: } ! 3891: ! 3892: generate_func (); ! 3893: if (generate_stbl) { ! 3894: if ((i > 0 && i < 10) || (i >= 20)) ! 3895: fprintf (stblfile, "#endif /* CPUEMU_68000_ONLY */\n"); ! 3896: if (postfix2 >= 0) ! 3897: fprintf (stblfile, "#endif /* CPUEMU_%d */\n", postfix2); ! 3898: } ! 3899: postfix2 = -1; ! 3900: } ! 3901: ! 3902: free (table68k); ! 3903: return 0; ! 3904: } ! 3905: ! 3906: void write_log (const TCHAR *format,...) ! 3907: { ! 3908: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.