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