|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator - CPU core ! 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: * Adaptation to Hatari and better cpu timings by Thomas Huth ! 21: * ! 22: * This file is distributed under the GNU Public License, version 2 or at ! 23: * your option any later version. Read the file gpl.txt for details. ! 24: */ ! 25: ! 26: ! 27: /* 2007/03/xx [NP] Use add_cycles.pl to set 'CurrentInstrCycles' in each opcode. */ ! 28: /* 2007/04/09 [NP] Correct CLR : on 68000, CLR reads the memory before clearing it (but we should */ ! 29: /* not add cycles for reading). This means CLR can give 2 wait states (one for */ ! 30: /* read and one for right) (clr.b $fa1b.w in Decade's Demo Main Menu). */ ! 31: /* 2007/04/14 [NP] - Although dest -(an) normally takes 2 cycles, this is not the case for move : */ ! 32: /* move dest (an), (an)+ and -(an) all take the same time (curi->dmode == Apdi) */ ! 33: /* (Syntax Terror Demo Reset). */ ! 34: /* - Scc takes 6 cycles instead of 4 if the result is true (Ventura Demo Loader). */ ! 35: /* - Store the family of the current opcode into OpcodeFamily : used to check */ ! 36: /* instruction pairing on ST into m68000.c */ ! 37: /* 2007/04/17 [NP] Add support for cycle accurate MULU (No Cooper Greeting Screen). */ ! 38: /* 2007/04/24 [NP] BCLR #n,Dx takes 12 cycles instead of 14 if n<16 (ULM Demo Menu). */ ! 39: /* 2007/04/25 [NP] On ST, d8(An,Xn) and d8(PC,Xn) take 2 cycles more than the official 68000's */ ! 40: /* table (ULM Demo Menu). */ ! 41: /* 2007/11/12 [NP] Add refill_prefetch for i_ADD to fix Transbeauce 2 demo self modified code. */ ! 42: /* Ugly hack, we need better prefetch emulation (switch to winuae gencpu.c) */ ! 43: /* 2007/11/25 [NP] In i_DBcc, in case of address error, last_addr_for_exception_3 should be */ ! 44: /* pc+4, not pc+2 (Transbeauce 2 demo) (e.g. 'dbf d0,#$fff5'). */ ! 45: /* This means the value pushed on the frame stack should be the address of the */ ! 46: /* instruction following the one generating the address error. */ ! 47: /* FIXME : this should be the case for i_BSR and i_BCC too (need to check on */ ! 48: /* a real 68000). */ ! 49: /* 2007/11/28 [NP] Backport DIVS/DIVU cycles exact routines from WinUAE (original work by Jorge */ ! 50: /* Cwik, [email protected]). */ ! 51: /* 2007/12/08 [NP] In case of CHK/CHK2 exception, PC stored on the stack wasn't pointing to the */ ! 52: /* next instruction but to the current CHK/CHK2 instruction (Transbeauce 2 demo). */ ! 53: /* We need to call 'sync_m68k_pc' before calling 'Exception'. */ ! 54: /* 2007/12/09 [NP] CHK.L (e.g. $4700) doesn't exist on 68000 and should be considered as an illegal*/ ! 55: /* instruction (Transbeauce 2 demo) -> change in table68k. */ ! 56: /* 2008/01/24 [NP] BCLR Dy,Dx takes 8 cycles instead of 10 if Dy<16 (Fullshade in Anomaly Demos). */ ! 57: /* 2008/01/26 [NP] On ST, d8(An,Xn) takes 2 cycles more when used with ADDA/SUBA (ULM Demo Menu) */ ! 58: /* but not when used with MOVE (e.g. 'move.l 0(a5,d1),(a4)' takes 26 cycles and so */ ! 59: /* can pair with a lsr) (Anomaly Demo Intro). */ ! 60: /* 2008/04/26 [NP] Handle sz_byte for Areg in genamode, as 'move.b a1,(a0)' ($1089) is possible */ ! 61: /* on ST (fix Blood Money on Superior 65) */ ! 62: /* 2010/04/05 [NP] On ST, d8(An,Xn) takes 2 cycles more (which can generate pairing). */ ! 63: /* Use BusCyclePenalty to properly handle the 2/4 cycles added in that case when */ ! 64: /* addressing mode is Ad8r or PC8r (ULM Demo Menu, Anomaly Demo Intro, DHS */ ! 65: /* Sommarhack 2010) (see m68000.h) */ ! 66: ! 67: ! 68: const char GenCpu_fileid[] = "Hatari gencpu.c : " __DATE__ " " __TIME__; ! 69: ! 70: #include <ctype.h> ! 71: #include <string.h> ! 72: ! 73: #include "sysdeps.h" ! 74: #include "readcpu.h" ! 75: ! 76: #define BOOL_TYPE "int" ! 77: ! 78: static FILE *headerfile; ! 79: static FILE *stblfile; ! 80: ! 81: static int using_prefetch; ! 82: static int using_exception_3; ! 83: static int cpu_level; ! 84: ! 85: char exactCpuCycles[256]; /* Space to store return string for exact cpu cycles */ ! 86: ! 87: long nCurInstrCycPos; /* Stores where we have to patch in the current cycles value */ ! 88: ! 89: /* For the current opcode, the next lower level that will have different code. ! 90: * Initialized to -1 for each opcode. If it remains unchanged, indicates we ! 91: * are done with that opcode. */ ! 92: static int next_cpu_level; ! 93: static int *opcode_map; ! 94: static int *opcode_next_clev; ! 95: static int *opcode_last_postfix; ! 96: static unsigned long *counts; ! 97: ! 98: ! 99: static void read_counts (void) ! 100: { ! 101: FILE *file; ! 102: unsigned long opcode, count, total; ! 103: char name[20]; ! 104: int nr = 0; ! 105: memset (counts, 0, 65536 * sizeof *counts); ! 106: ! 107: file = fopen ("frequent.68k", "r"); ! 108: if (file) { ! 109: if (fscanf (file, "Total: %lu\n", &total) == EOF) { ! 110: perror("read_counts"); ! 111: } ! 112: while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) { ! 113: opcode_next_clev[nr] = 4; ! 114: opcode_last_postfix[nr] = -1; ! 115: opcode_map[nr++] = opcode; ! 116: counts[opcode] = count; ! 117: } ! 118: fclose (file); ! 119: } ! 120: if (nr == nr_cpuop_funcs) ! 121: return; ! 122: for (opcode = 0; opcode < 0x10000; opcode++) { ! 123: if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG ! 124: && counts[opcode] == 0) ! 125: { ! 126: opcode_next_clev[nr] = 4; ! 127: opcode_last_postfix[nr] = -1; ! 128: opcode_map[nr++] = opcode; ! 129: counts[opcode] = count; ! 130: } ! 131: } ! 132: if (nr != nr_cpuop_funcs) ! 133: abort (); ! 134: } ! 135: ! 136: static char endlabelstr[80]; ! 137: static int endlabelno = 0; ! 138: static int need_endlabel; ! 139: ! 140: static int n_braces = 0; ! 141: static int m68k_pc_offset = 0; ! 142: static int insn_n_cycles; ! 143: ! 144: static void start_brace (void) ! 145: { ! 146: n_braces++; ! 147: printf ("{"); ! 148: } ! 149: ! 150: static void close_brace (void) ! 151: { ! 152: assert (n_braces > 0); ! 153: n_braces--; ! 154: printf ("}"); ! 155: } ! 156: ! 157: static void finish_braces (void) ! 158: { ! 159: while (n_braces > 0) ! 160: close_brace (); ! 161: } ! 162: ! 163: static void pop_braces (int to) ! 164: { ! 165: while (n_braces > to) ! 166: close_brace (); ! 167: } ! 168: ! 169: static int bit_size (int size) ! 170: { ! 171: switch (size) { ! 172: case sz_byte: return 8; ! 173: case sz_word: return 16; ! 174: case sz_long: return 32; ! 175: default: abort (); ! 176: } ! 177: return 0; ! 178: } ! 179: ! 180: static const char *bit_mask (int size) ! 181: { ! 182: switch (size) { ! 183: case sz_byte: return "0xff"; ! 184: case sz_word: return "0xffff"; ! 185: case sz_long: return "0xffffffff"; ! 186: default: abort (); ! 187: } ! 188: return 0; ! 189: } ! 190: ! 191: static const char *gen_nextilong (void) ! 192: { ! 193: static char buffer[80]; ! 194: int r = m68k_pc_offset; ! 195: m68k_pc_offset += 4; ! 196: ! 197: insn_n_cycles += 8; ! 198: ! 199: if (using_prefetch) ! 200: sprintf (buffer, "get_ilong_prefetch(%d)", r); ! 201: else ! 202: sprintf (buffer, "get_ilong(%d)", r); ! 203: return buffer; ! 204: } ! 205: ! 206: static const char *gen_nextiword (void) ! 207: { ! 208: static char buffer[80]; ! 209: int r = m68k_pc_offset; ! 210: m68k_pc_offset += 2; ! 211: ! 212: insn_n_cycles += 4; ! 213: ! 214: if (using_prefetch) ! 215: sprintf (buffer, "get_iword_prefetch(%d)", r); ! 216: else ! 217: sprintf (buffer, "get_iword(%d)", r); ! 218: return buffer; ! 219: } ! 220: ! 221: static const char *gen_nextibyte (void) ! 222: { ! 223: static char buffer[80]; ! 224: int r = m68k_pc_offset; ! 225: m68k_pc_offset += 2; ! 226: ! 227: insn_n_cycles += 4; ! 228: ! 229: if (using_prefetch) ! 230: sprintf (buffer, "get_ibyte_prefetch(%d)", r); ! 231: else ! 232: sprintf (buffer, "get_ibyte(%d)", r); ! 233: return buffer; ! 234: } ! 235: ! 236: static void fill_prefetch_0 (void) ! 237: { ! 238: if (using_prefetch) ! 239: printf ("fill_prefetch_0 ();\n"); ! 240: } ! 241: ! 242: static void fill_prefetch_2 (void) ! 243: { ! 244: if (using_prefetch) ! 245: printf ("fill_prefetch_2 ();\n"); ! 246: } ! 247: ! 248: static void sync_m68k_pc (void) ! 249: { ! 250: if (m68k_pc_offset == 0) ! 251: return; ! 252: printf ("m68k_incpc(%d);\n", m68k_pc_offset); ! 253: switch (m68k_pc_offset) { ! 254: case 0: ! 255: /*fprintf (stderr, "refilling prefetch at 0\n"); */ ! 256: break; ! 257: case 2: ! 258: fill_prefetch_2 (); ! 259: break; ! 260: default: ! 261: fill_prefetch_0 (); ! 262: break; ! 263: } ! 264: m68k_pc_offset = 0; ! 265: } ! 266: ! 267: /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, ! 268: * the calling routine handles Apdi and Aipi modes. ! 269: * gb-- movem == 2 means the same thing but for a MOVE16 instruction */ ! 270: static void genamode (amodes mode, const char *reg, wordsizes size, ! 271: const char *name, int getv, int movem) ! 272: { ! 273: start_brace (); ! 274: switch (mode) { ! 275: case Dreg: ! 276: if (movem) ! 277: abort (); ! 278: if (getv == 1) ! 279: switch (size) { ! 280: case sz_byte: ! 281: printf ("\tuae_s8 %s = m68k_dreg(regs, %s);\n", name, reg); ! 282: break; ! 283: case sz_word: ! 284: printf ("\tuae_s16 %s = m68k_dreg(regs, %s);\n", name, reg); ! 285: break; ! 286: case sz_long: ! 287: printf ("\tuae_s32 %s = m68k_dreg(regs, %s);\n", name, reg); ! 288: break; ! 289: default: ! 290: abort (); ! 291: } ! 292: return; ! 293: case Areg: ! 294: if (movem) ! 295: abort (); ! 296: if (getv == 1) ! 297: switch (size) { ! 298: case sz_byte: // [NP] Areg with .b is possible in MOVE source */ ! 299: printf ("\tuae_s8 %s = m68k_areg(regs, %s);\n", name, reg); ! 300: break; ! 301: case sz_word: ! 302: printf ("\tuae_s16 %s = m68k_areg(regs, %s);\n", name, reg); ! 303: break; ! 304: case sz_long: ! 305: printf ("\tuae_s32 %s = m68k_areg(regs, %s);\n", name, reg); ! 306: break; ! 307: default: ! 308: abort (); ! 309: } ! 310: return; ! 311: case Aind: ! 312: printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); ! 313: break; ! 314: case Aipi: ! 315: printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); ! 316: break; ! 317: case Apdi: ! 318: insn_n_cycles += 2; ! 319: switch (size) { ! 320: case sz_byte: ! 321: if (movem) ! 322: printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg); ! 323: else ! 324: printf ("\tuaecptr %sa = m68k_areg(regs, %s) - areg_byteinc[%s];\n", name, reg, reg); ! 325: break; ! 326: case sz_word: ! 327: printf ("\tuaecptr %sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 2); ! 328: break; ! 329: case sz_long: ! 330: printf ("\tuaecptr %sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 4); ! 331: break; ! 332: default: ! 333: abort (); ! 334: } ! 335: break; ! 336: case Ad16: ! 337: printf ("\tuaecptr %sa = m68k_areg(regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword ()); ! 338: break; ! 339: case Ad8r: ! 340: insn_n_cycles += 2; ! 341: if (cpu_level > 1) { ! 342: if (next_cpu_level < 1) ! 343: next_cpu_level = 1; ! 344: sync_m68k_pc (); ! 345: start_brace (); ! 346: /* This would ordinarily be done in gen_nextiword, which we bypass. */ ! 347: insn_n_cycles += 4; ! 348: printf ("\tuaecptr %sa = get_disp_ea_020(m68k_areg(regs, %s), next_iword());\n", name, reg); ! 349: } else { ! 350: printf ("\tuaecptr %sa = get_disp_ea_000(m68k_areg(regs, %s), %s);\n", name, reg, gen_nextiword ()); ! 351: } ! 352: printf ("\tBusCyclePenalty += 2;\n"); ! 353: ! 354: break; ! 355: case PC16: ! 356: printf ("\tuaecptr %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset); ! 357: printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword ()); ! 358: break; ! 359: case PC8r: ! 360: insn_n_cycles += 2; ! 361: if (cpu_level > 1) { ! 362: if (next_cpu_level < 1) ! 363: next_cpu_level = 1; ! 364: sync_m68k_pc (); ! 365: start_brace (); ! 366: /* This would ordinarily be done in gen_nextiword, which we bypass. */ ! 367: insn_n_cycles += 4; ! 368: printf ("\tuaecptr tmppc = m68k_getpc();\n"); ! 369: printf ("\tuaecptr %sa = get_disp_ea_020(tmppc, next_iword());\n", name); ! 370: } else { ! 371: printf ("\tuaecptr tmppc = m68k_getpc() + %d;\n", m68k_pc_offset); ! 372: printf ("\tuaecptr %sa = get_disp_ea_000(tmppc, %s);\n", name, gen_nextiword ()); ! 373: } ! 374: printf ("\tBusCyclePenalty += 2;\n"); ! 375: ! 376: break; ! 377: case absw: ! 378: printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword ()); ! 379: break; ! 380: case absl: ! 381: printf ("\tuaecptr %sa = %s;\n", name, gen_nextilong ()); ! 382: break; ! 383: case imm: ! 384: if (getv != 1) ! 385: abort (); ! 386: switch (size) { ! 387: case sz_byte: ! 388: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ()); ! 389: break; ! 390: case sz_word: ! 391: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ()); ! 392: break; ! 393: case sz_long: ! 394: printf ("\tuae_s32 %s = %s;\n", name, gen_nextilong ()); ! 395: break; ! 396: default: ! 397: abort (); ! 398: } ! 399: return; ! 400: case imm0: ! 401: if (getv != 1) ! 402: abort (); ! 403: printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ()); ! 404: return; ! 405: case imm1: ! 406: if (getv != 1) ! 407: abort (); ! 408: printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ()); ! 409: return; ! 410: case imm2: ! 411: if (getv != 1) ! 412: abort (); ! 413: printf ("\tuae_s32 %s = %s;\n", name, gen_nextilong ()); ! 414: return; ! 415: case immi: ! 416: if (getv != 1) ! 417: abort (); ! 418: printf ("\tuae_u32 %s = %s;\n", name, reg); ! 419: return; ! 420: default: ! 421: abort (); ! 422: } ! 423: ! 424: /* We get here for all non-reg non-immediate addressing modes to ! 425: * actually fetch the value. */ ! 426: ! 427: if (using_exception_3 && getv != 0 && size != sz_byte) { ! 428: printf ("\tif ((%sa & 1) != 0) {\n", name); ! 429: printf ("\t\tlast_fault_for_exception_3 = %sa;\n", name); ! 430: printf ("\t\tlast_op_for_exception_3 = opcode;\n"); ! 431: printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + %d;\n", m68k_pc_offset); ! 432: printf ("\t\tException(3, 0, M68000_EXC_SRC_CPU);\n"); ! 433: printf ("\t\tgoto %s;\n", endlabelstr); ! 434: printf ("\t}\n"); ! 435: need_endlabel = 1; ! 436: start_brace (); ! 437: } ! 438: ! 439: if (getv == 1) { ! 440: switch (size) { ! 441: case sz_byte: insn_n_cycles += 4; break; ! 442: case sz_word: insn_n_cycles += 4; break; ! 443: case sz_long: insn_n_cycles += 8; break; ! 444: default: abort (); ! 445: } ! 446: start_brace (); ! 447: switch (size) { ! 448: case sz_byte: printf ("\tuae_s8 %s = get_byte(%sa);\n", name, name); break; ! 449: case sz_word: printf ("\tuae_s16 %s = get_word(%sa);\n", name, name); break; ! 450: case sz_long: printf ("\tuae_s32 %s = get_long(%sa);\n", name, name); break; ! 451: default: abort (); ! 452: } ! 453: } ! 454: ! 455: /* We now might have to fix up the register for pre-dec or post-inc ! 456: * addressing modes. */ ! 457: if (!movem) ! 458: switch (mode) { ! 459: case Aipi: ! 460: switch (size) { ! 461: case sz_byte: ! 462: printf ("\tm68k_areg(regs, %s) += areg_byteinc[%s];\n", reg, reg); ! 463: break; ! 464: case sz_word: ! 465: printf ("\tm68k_areg(regs, %s) += 2;\n", reg); ! 466: break; ! 467: case sz_long: ! 468: printf ("\tm68k_areg(regs, %s) += 4;\n", reg); ! 469: break; ! 470: default: ! 471: abort (); ! 472: } ! 473: break; ! 474: case Apdi: ! 475: printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name); ! 476: break; ! 477: default: ! 478: break; ! 479: } ! 480: } ! 481: ! 482: static void genastore (const char *from, amodes mode, const char *reg, ! 483: wordsizes size, const char *to) ! 484: { ! 485: switch (mode) { ! 486: case Dreg: ! 487: switch (size) { ! 488: case sz_byte: ! 489: printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from); ! 490: break; ! 491: case sz_word: ! 492: printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from); ! 493: break; ! 494: case sz_long: ! 495: printf ("\tm68k_dreg(regs, %s) = (%s);\n", reg, from); ! 496: break; ! 497: default: ! 498: abort (); ! 499: } ! 500: break; ! 501: case Areg: ! 502: switch (size) { ! 503: case sz_word: ! 504: fprintf (stderr, "Foo\n"); ! 505: printf ("\tm68k_areg(regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from); ! 506: break; ! 507: case sz_long: ! 508: printf ("\tm68k_areg(regs, %s) = (%s);\n", reg, from); ! 509: break; ! 510: default: ! 511: abort (); ! 512: } ! 513: break; ! 514: case Aind: ! 515: case Aipi: ! 516: case Apdi: ! 517: case Ad16: ! 518: case Ad8r: ! 519: case absw: ! 520: case absl: ! 521: case PC16: ! 522: case PC8r: ! 523: if (using_prefetch) ! 524: sync_m68k_pc (); ! 525: switch (size) { ! 526: case sz_byte: ! 527: insn_n_cycles += 4; ! 528: printf ("\tput_byte(%sa,%s);\n", to, from); ! 529: break; ! 530: case sz_word: ! 531: insn_n_cycles += 4; ! 532: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 533: abort (); ! 534: printf ("\tput_word(%sa,%s);\n", to, from); ! 535: break; ! 536: case sz_long: ! 537: insn_n_cycles += 8; ! 538: if (cpu_level < 2 && (mode == PC16 || mode == PC8r)) ! 539: abort (); ! 540: printf ("\tput_long(%sa,%s);\n", to, from); ! 541: break; ! 542: default: ! 543: abort (); ! 544: } ! 545: break; ! 546: case imm: ! 547: case imm0: ! 548: case imm1: ! 549: case imm2: ! 550: case immi: ! 551: abort (); ! 552: break; ! 553: default: ! 554: abort (); ! 555: } ! 556: } ! 557: ! 558: ! 559: static void genmovemel (uae_u16 opcode) ! 560: { ! 561: char getcode[100]; ! 562: int bMovemLong = (table68k[opcode].size == sz_long); ! 563: int size = bMovemLong ? 4 : 2; ! 564: ! 565: if (bMovemLong) { ! 566: strcpy (getcode, "get_long(srca)"); ! 567: } else { ! 568: strcpy (getcode, "(uae_s32)(uae_s16)get_word(srca)"); ! 569: } ! 570: ! 571: printf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); ! 572: printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); ! 573: printf ("\tretcycles = 0;\n"); ! 574: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); ! 575: start_brace (); ! 576: printf ("\twhile (dmask) { m68k_dreg(regs, movem_index1[dmask]) = %s;" ! 577: " srca += %d; dmask = movem_next[dmask]; retcycles+=%d; }\n", ! 578: getcode, size, (bMovemLong ? 8 : 4)); ! 579: printf ("\twhile (amask) { m68k_areg(regs, movem_index1[amask]) = %s;" ! 580: " srca += %d; amask = movem_next[amask]; retcycles+=%d; }\n", ! 581: getcode, size, (bMovemLong ? 8 : 4)); ! 582: ! 583: if (table68k[opcode].dmode == Aipi) ! 584: printf ("\tm68k_areg(regs, dstreg) = srca;\n"); ! 585: ! 586: /* Better cycles - experimental! (Thothy) */ ! 587: switch(table68k[opcode].dmode) ! 588: { ! 589: case Aind: insn_n_cycles=12; break; ! 590: case Aipi: insn_n_cycles=12; break; ! 591: case Ad16: insn_n_cycles=16; break; ! 592: case Ad8r: insn_n_cycles=18; break; ! 593: case absw: insn_n_cycles=16; break; ! 594: case absl: insn_n_cycles=20; break; ! 595: case PC16: insn_n_cycles=16; break; ! 596: case PC8r: insn_n_cycles=18; break; ! 597: } ! 598: sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles); ! 599: } ! 600: ! 601: static void genmovemle (uae_u16 opcode) ! 602: { ! 603: char putcode[100]; ! 604: int bMovemLong = (table68k[opcode].size == sz_long); ! 605: int size = bMovemLong ? 4 : 2; ! 606: ! 607: if (bMovemLong) { ! 608: strcpy (putcode, "put_long(srca,"); ! 609: } else { ! 610: strcpy (putcode, "put_word(srca,"); ! 611: } ! 612: ! 613: printf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); ! 614: printf ("\tretcycles = 0;\n"); ! 615: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); ! 616: if (using_prefetch) ! 617: sync_m68k_pc (); ! 618: ! 619: start_brace (); ! 620: if (table68k[opcode].dmode == Apdi) { ! 621: printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n"); ! 622: printf ("\twhile (amask) { srca -= %d; %s m68k_areg(regs, movem_index2[amask]));" ! 623: " amask = movem_next[amask]; retcycles+=%d; }\n", ! 624: size, putcode, (bMovemLong ? 8 : 4)); ! 625: printf ("\twhile (dmask) { srca -= %d; %s m68k_dreg(regs, movem_index2[dmask]));" ! 626: " dmask = movem_next[dmask]; retcycles+=%d; }\n", ! 627: size, putcode, (bMovemLong ? 8 : 4)); ! 628: printf ("\tm68k_areg(regs, dstreg) = srca;\n"); ! 629: } else { ! 630: printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n"); ! 631: printf ("\twhile (dmask) { %s m68k_dreg(regs, movem_index1[dmask])); srca += %d;" ! 632: " dmask = movem_next[dmask]; retcycles+=%d; }\n", ! 633: putcode, size, (bMovemLong ? 8 : 4)); ! 634: printf ("\twhile (amask) { %s m68k_areg(regs, movem_index1[amask])); srca += %d;" ! 635: " amask = movem_next[amask]; retcycles+=%d; }\n", ! 636: putcode, size, (bMovemLong ? 8 : 4)); ! 637: } ! 638: ! 639: /* Better cycles - experimental! (Thothy) */ ! 640: switch(table68k[opcode].dmode) ! 641: { ! 642: case Aind: insn_n_cycles=8; break; ! 643: case Apdi: insn_n_cycles=8; break; ! 644: case Ad16: insn_n_cycles=12; break; ! 645: case Ad8r: insn_n_cycles=14; break; ! 646: case absw: insn_n_cycles=12; break; ! 647: case absl: insn_n_cycles=16; break; ! 648: } ! 649: sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles); ! 650: } ! 651: ! 652: ! 653: static void duplicate_carry (void) ! 654: { ! 655: printf ("\tCOPY_CARRY;\n"); ! 656: } ! 657: ! 658: typedef enum ! 659: { ! 660: flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn, ! 661: flag_av, flag_sv ! 662: } ! 663: flagtypes; ! 664: ! 665: static void genflags_normal (flagtypes type, wordsizes size, const char *value, ! 666: const char *src, const char *dst) ! 667: { ! 668: char vstr[100], sstr[100], dstr[100]; ! 669: char usstr[100], udstr[100]; ! 670: char unsstr[100], undstr[100]; ! 671: ! 672: switch (size) { ! 673: case sz_byte: ! 674: strcpy (vstr, "((uae_s8)("); ! 675: strcpy (usstr, "((uae_u8)("); ! 676: break; ! 677: case sz_word: ! 678: strcpy (vstr, "((uae_s16)("); ! 679: strcpy (usstr, "((uae_u16)("); ! 680: break; ! 681: case sz_long: ! 682: strcpy (vstr, "((uae_s32)("); ! 683: strcpy (usstr, "((uae_u32)("); ! 684: break; ! 685: default: ! 686: abort (); ! 687: } ! 688: strcpy (unsstr, usstr); ! 689: ! 690: strcpy (sstr, vstr); ! 691: strcpy (dstr, vstr); ! 692: strcat (vstr, value); ! 693: strcat (vstr, "))"); ! 694: strcat (dstr, dst); ! 695: strcat (dstr, "))"); ! 696: strcat (sstr, src); ! 697: strcat (sstr, "))"); ! 698: ! 699: strcpy (udstr, usstr); ! 700: strcat (udstr, dst); ! 701: strcat (udstr, "))"); ! 702: strcat (usstr, src); ! 703: strcat (usstr, "))"); ! 704: ! 705: strcpy (undstr, unsstr); ! 706: strcat (unsstr, "-"); ! 707: strcat (undstr, "~"); ! 708: strcat (undstr, dst); ! 709: strcat (undstr, "))"); ! 710: strcat (unsstr, src); ! 711: strcat (unsstr, "))"); ! 712: ! 713: switch (type) { ! 714: case flag_logical_noclobber: ! 715: case flag_logical: ! 716: case flag_zn: ! 717: case flag_av: ! 718: case flag_sv: ! 719: case flag_addx: ! 720: case flag_subx: ! 721: break; ! 722: ! 723: case flag_add: ! 724: start_brace (); ! 725: printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr); ! 726: break; ! 727: case flag_sub: ! 728: case flag_cmp: ! 729: start_brace (); ! 730: printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr); ! 731: break; ! 732: } ! 733: ! 734: switch (type) { ! 735: case flag_logical_noclobber: ! 736: case flag_logical: ! 737: case flag_zn: ! 738: break; ! 739: ! 740: case flag_add: ! 741: case flag_sub: ! 742: case flag_addx: ! 743: case flag_subx: ! 744: case flag_cmp: ! 745: case flag_av: ! 746: case flag_sv: ! 747: start_brace (); ! 748: printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr); ! 749: printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr); ! 750: printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr); ! 751: break; ! 752: } ! 753: ! 754: switch (type) { ! 755: case flag_logical: ! 756: printf ("\tCLEAR_CZNV;\n"); ! 757: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 758: printf ("\tSET_NFLG (%s < 0);\n", vstr); ! 759: break; ! 760: case flag_logical_noclobber: ! 761: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 762: printf ("\tSET_NFLG (%s < 0);\n", vstr); ! 763: break; ! 764: case flag_av: ! 765: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); ! 766: break; ! 767: case flag_sv: ! 768: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); ! 769: break; ! 770: case flag_zn: ! 771: printf ("\tSET_ZFLG (GET_ZFLG & (%s == 0));\n", vstr); ! 772: printf ("\tSET_NFLG (%s < 0);\n", vstr); ! 773: break; ! 774: case flag_add: ! 775: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 776: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); ! 777: printf ("\tSET_CFLG (%s < %s);\n", undstr, usstr); ! 778: duplicate_carry (); ! 779: printf ("\tSET_NFLG (flgn != 0);\n"); ! 780: break; ! 781: case flag_sub: ! 782: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 783: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgn ^ flgo));\n"); ! 784: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); ! 785: duplicate_carry (); ! 786: printf ("\tSET_NFLG (flgn != 0);\n"); ! 787: break; ! 788: case flag_addx: ! 789: printf ("\tSET_VFLG ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0x42 */ ! 790: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgo) & (flgo ^ flgn)));\n"); /* minterm SON: 0xD4 */ ! 791: duplicate_carry (); ! 792: break; ! 793: case flag_subx: ! 794: printf ("\tSET_VFLG ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0x24 */ ! 795: printf ("\tSET_CFLG (flgs ^ ((flgs ^ flgn) & (flgo ^ flgn)));\n"); /* minterm SON: 0xB2 */ ! 796: duplicate_carry (); ! 797: break; ! 798: case flag_cmp: ! 799: printf ("\tSET_ZFLG (%s == 0);\n", vstr); ! 800: printf ("\tSET_VFLG ((flgs != flgo) && (flgn != flgo));\n"); ! 801: printf ("\tSET_CFLG (%s > %s);\n", usstr, udstr); ! 802: printf ("\tSET_NFLG (flgn != 0);\n"); ! 803: break; ! 804: } ! 805: } ! 806: ! 807: static void genflags (flagtypes type, wordsizes size, const char *value, ! 808: const char *src, const char *dst) ! 809: { ! 810: /* Temporarily deleted 68k/ARM flag optimizations. I'd prefer to have ! 811: them in the appropriate m68k.h files and use just one copy of this ! 812: code here. The API can be changed if necessary. */ ! 813: #ifdef OPTIMIZED_FLAGS ! 814: switch (type) { ! 815: case flag_add: ! 816: case flag_sub: ! 817: start_brace (); ! 818: printf ("\tuae_u32 %s;\n", value); ! 819: break; ! 820: ! 821: default: ! 822: break; ! 823: } ! 824: ! 825: /* At least some of those casts are fairly important! */ ! 826: switch (type) { ! 827: case flag_logical_noclobber: ! 828: printf ("\t{uae_u32 oldcznv = GET_CZNV & ~(FLAGVAL_Z | FLAGVAL_N);\n"); ! 829: if (strcmp (value, "0") == 0) { ! 830: printf ("\tSET_CZNV (olcznv | FLAGVAL_Z);\n"); ! 831: } else { ! 832: switch (size) { ! 833: case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break; ! 834: case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break; ! 835: case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break; ! 836: } ! 837: printf ("\tIOR_CZNV (oldcznv);\n"); ! 838: } ! 839: printf ("\t}\n"); ! 840: return; ! 841: case flag_logical: ! 842: if (strcmp (value, "0") == 0) { ! 843: printf ("\tSET_CZNV (FLAGVAL_Z);\n"); ! 844: } else { ! 845: switch (size) { ! 846: case sz_byte: printf ("\toptflag_testb ((uae_s8)(%s));\n", value); break; ! 847: case sz_word: printf ("\toptflag_testw ((uae_s16)(%s));\n", value); break; ! 848: case sz_long: printf ("\toptflag_testl ((uae_s32)(%s));\n", value); break; ! 849: } ! 850: } ! 851: return; ! 852: ! 853: case flag_add: ! 854: switch (size) { ! 855: case sz_byte: printf ("\toptflag_addb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; ! 856: case sz_word: printf ("\toptflag_addw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; ! 857: case sz_long: printf ("\toptflag_addl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; ! 858: } ! 859: return; ! 860: ! 861: case flag_sub: ! 862: switch (size) { ! 863: case sz_byte: printf ("\toptflag_subb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break; ! 864: case sz_word: printf ("\toptflag_subw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break; ! 865: case sz_long: printf ("\toptflag_subl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break; ! 866: } ! 867: return; ! 868: ! 869: case flag_cmp: ! 870: switch (size) { ! 871: case sz_byte: printf ("\toptflag_cmpb ((uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break; ! 872: case sz_word: printf ("\toptflag_cmpw ((uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break; ! 873: case sz_long: printf ("\toptflag_cmpl ((uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break; ! 874: } ! 875: return; ! 876: ! 877: default: ! 878: break; ! 879: } ! 880: #endif ! 881: ! 882: genflags_normal (type, size, value, src, dst); ! 883: } ! 884: ! 885: static void force_range_for_rox (const char *var, wordsizes size) ! 886: { ! 887: /* Could do a modulo operation here... which one is faster? */ ! 888: switch (size) { ! 889: case sz_long: ! 890: printf ("\tif (%s >= 33) %s -= 33;\n", var, var); ! 891: break; ! 892: case sz_word: ! 893: printf ("\tif (%s >= 34) %s -= 34;\n", var, var); ! 894: printf ("\tif (%s >= 17) %s -= 17;\n", var, var); ! 895: break; ! 896: case sz_byte: ! 897: printf ("\tif (%s >= 36) %s -= 36;\n", var, var); ! 898: printf ("\tif (%s >= 18) %s -= 18;\n", var, var); ! 899: printf ("\tif (%s >= 9) %s -= 9;\n", var, var); ! 900: break; ! 901: } ! 902: } ! 903: ! 904: static const char *cmask (wordsizes size) ! 905: { ! 906: switch (size) { ! 907: case sz_byte: return "0x80"; ! 908: case sz_word: return "0x8000"; ! 909: case sz_long: return "0x80000000"; ! 910: default: abort (); ! 911: } ! 912: } ! 913: ! 914: static int source_is_imm1_8 (struct instr *i) ! 915: { ! 916: return i->stype == 3; ! 917: } ! 918: ! 919: ! 920: ! 921: static void gen_opcode (unsigned long int opcode) ! 922: { ! 923: #if 0 ! 924: char *amodenames[] = { "Dreg", "Areg", "Aind", "Aipi", "Apdi", "Ad16", "Ad8r", ! 925: "absw", "absl", "PC16", "PC8r", "imm", "imm0", "imm1", "imm2", "immi", "am_unknown", "am_illg"}; ! 926: #endif ! 927: ! 928: struct instr *curi = table68k + opcode; ! 929: insn_n_cycles = 4; ! 930: ! 931: /* Store the family of the instruction (used to check for pairing on ST) ! 932: * and leave some space for patching in the current cycles later */ ! 933: printf ("\tOpcodeFamily = %d; CurrentInstrCycles = \n", curi->mnemo); ! 934: nCurInstrCycPos = ftell(stdout) - 5; ! 935: ! 936: start_brace (); ! 937: m68k_pc_offset = 2; ! 938: ! 939: switch (curi->plev) { ! 940: case 0: /* not privileged */ ! 941: break; ! 942: case 1: /* unprivileged only on 68000 */ ! 943: if (cpu_level == 0) ! 944: break; ! 945: if (next_cpu_level < 0) ! 946: next_cpu_level = 0; ! 947: ! 948: /* fall through */ ! 949: case 2: /* priviledged */ ! 950: printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 951: need_endlabel = 1; ! 952: start_brace (); ! 953: break; ! 954: case 3: /* privileged if size == word */ ! 955: if (curi->size == sz_byte) ! 956: break; ! 957: printf ("if (!regs.s) { Exception(8,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 958: need_endlabel = 1; ! 959: start_brace (); ! 960: break; ! 961: } ! 962: ! 963: /* Build the opcodes: */ ! 964: switch (curi->mnemo) { ! 965: case i_OR: ! 966: case i_AND: ! 967: case i_EOR: ! 968: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 969: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 970: printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^'); ! 971: genflags (flag_logical, curi->size, "src", "", ""); ! 972: genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 973: if(curi->size==sz_long && curi->dmode==Dreg) ! 974: { ! 975: insn_n_cycles += 2; ! 976: if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi)) ! 977: insn_n_cycles += 2; ! 978: } ! 979: #if 0 ! 980: /* Output the CPU cycles: */ ! 981: fprintf(stderr,"MOVE, size %i: ",curi->size); ! 982: fprintf(stderr," %s ->",amodenames[curi->smode]); ! 983: fprintf(stderr," %s ",amodenames[curi->dmode]); ! 984: fprintf(stderr," Cycles: %i\n",insn_n_cycles); ! 985: #endif ! 986: break; ! 987: case i_ORSR: ! 988: case i_EORSR: ! 989: printf ("\tMakeSR();\n"); ! 990: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 991: if (curi->size == sz_byte) { ! 992: printf ("\tsrc &= 0xFF;\n"); ! 993: } ! 994: printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|'); ! 995: printf ("\tMakeFromSR();\n"); ! 996: insn_n_cycles = 20; ! 997: break; ! 998: case i_ANDSR: ! 999: printf ("\tMakeSR();\n"); ! 1000: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1001: if (curi->size == sz_byte) { ! 1002: printf ("\tsrc |= 0xFF00;\n"); ! 1003: } ! 1004: printf ("\tregs.sr &= src;\n"); ! 1005: printf ("\tMakeFromSR();\n"); ! 1006: insn_n_cycles = 20; ! 1007: break; ! 1008: case i_SUB: ! 1009: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1010: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1011: start_brace (); ! 1012: genflags (flag_sub, curi->size, "newv", "src", "dst"); ! 1013: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1014: if(curi->size==sz_long && curi->dmode==Dreg) ! 1015: { ! 1016: insn_n_cycles += 2; ! 1017: if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi)) ! 1018: insn_n_cycles += 2; ! 1019: } ! 1020: break; ! 1021: case i_SUBA: ! 1022: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1023: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1024: start_brace (); ! 1025: printf ("\tuae_u32 newv = dst - src;\n"); ! 1026: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1027: if(curi->size==sz_long && curi->smode!=Dreg && curi->smode!=Areg && !(curi->smode>=imm && curi->smode<=immi)) ! 1028: insn_n_cycles += 2; ! 1029: else ! 1030: insn_n_cycles += 4; ! 1031: break; ! 1032: case i_SUBX: ! 1033: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1034: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1035: start_brace (); ! 1036: printf ("\tuae_u32 newv = dst - src - (GET_XFLG ? 1 : 0);\n"); ! 1037: genflags (flag_subx, curi->size, "newv", "src", "dst"); ! 1038: genflags (flag_zn, curi->size, "newv", "", ""); ! 1039: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1040: if(curi->smode==Dreg && curi->size==sz_long) ! 1041: insn_n_cycles=8; ! 1042: if(curi->smode==Apdi) ! 1043: { ! 1044: if(curi->size==sz_long) ! 1045: insn_n_cycles=30; ! 1046: else ! 1047: insn_n_cycles=18; ! 1048: } ! 1049: break; ! 1050: case i_SBCD: ! 1051: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1052: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1053: start_brace (); ! 1054: printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG ? 1 : 0);\n"); ! 1055: printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n"); ! 1056: printf ("\tuae_u16 newv, tmp_newv;\n"); ! 1057: printf ("\tint bcd = 0;\n"); ! 1058: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;\n"); ! 1059: printf ("\tif (newv_lo & 0xF0) { newv -= 6; bcd = 6; };\n"); ! 1060: printf ("\tif ((((dst & 0xFF) - (src & 0xFF) - (GET_XFLG ? 1 : 0)) & 0x100) > 0xFF) { newv -= 0x60; }\n"); ! 1061: printf ("\tSET_CFLG ((((dst & 0xFF) - (src & 0xFF) - bcd - (GET_XFLG ? 1 : 0)) & 0x300) > 0xFF);\n"); ! 1062: duplicate_carry (); ! 1063: genflags (flag_zn, curi->size, "newv", "", ""); ! 1064: printf ("\tSET_VFLG ((tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n"); ! 1065: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1066: if(curi->smode==Dreg) insn_n_cycles=6; ! 1067: if(curi->smode==Apdi) insn_n_cycles=18; ! 1068: break; ! 1069: case i_ADD: ! 1070: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1071: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1072: start_brace (); ! 1073: printf("\trefill_prefetch (m68k_getpc(), 2);\n"); // FIXME [NP] For Transbeauce 2 demo, need better prefetch emulation ! 1074: genflags (flag_add, curi->size, "newv", "src", "dst"); ! 1075: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1076: if(curi->size==sz_long && curi->dmode==Dreg) ! 1077: { ! 1078: insn_n_cycles += 2; ! 1079: if(curi->smode==Dreg || curi->smode==Areg || (curi->smode>=imm && curi->smode<=immi)) ! 1080: insn_n_cycles += 2; ! 1081: } ! 1082: break; ! 1083: case i_ADDA: ! 1084: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1085: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1086: start_brace (); ! 1087: printf ("\tuae_u32 newv = dst + src;\n"); ! 1088: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1089: if(curi->size==sz_long && curi->smode!=Dreg && curi->smode!=Areg && !(curi->smode>=imm && curi->smode<=immi)) ! 1090: insn_n_cycles += 2; ! 1091: else ! 1092: insn_n_cycles += 4; ! 1093: break; ! 1094: case i_ADDX: ! 1095: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1096: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1097: start_brace (); ! 1098: printf ("\tuae_u32 newv = dst + src + (GET_XFLG ? 1 : 0);\n"); ! 1099: genflags (flag_addx, curi->size, "newv", "src", "dst"); ! 1100: genflags (flag_zn, curi->size, "newv", "", ""); ! 1101: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1102: if(curi->smode==Dreg && curi->size==sz_long) ! 1103: insn_n_cycles=8; ! 1104: if(curi->smode==Apdi) ! 1105: { ! 1106: if(curi->size==sz_long) ! 1107: insn_n_cycles=30; ! 1108: else ! 1109: insn_n_cycles=18; ! 1110: } ! 1111: break; ! 1112: case i_ABCD: ! 1113: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1114: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1115: start_brace (); ! 1116: printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG ? 1 : 0);\n"); ! 1117: printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n"); ! 1118: printf ("\tuae_u16 newv, tmp_newv;\n"); ! 1119: printf ("\tint cflg;\n"); ! 1120: printf ("\tnewv = tmp_newv = newv_hi + newv_lo;"); ! 1121: printf ("\tif (newv_lo > 9) { newv += 6; }\n"); ! 1122: printf ("\tcflg = (newv & 0x3F0) > 0x90;\n"); ! 1123: printf ("\tif (cflg) newv += 0x60;\n"); ! 1124: printf ("\tSET_CFLG (cflg);\n"); ! 1125: duplicate_carry (); ! 1126: genflags (flag_zn, curi->size, "newv", "", ""); ! 1127: printf ("\tSET_VFLG ((tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n"); ! 1128: genastore ("newv", curi->dmode, "dstreg", curi->size, "dst"); ! 1129: if(curi->smode==Dreg) insn_n_cycles=6; ! 1130: if(curi->smode==Apdi) insn_n_cycles=18; ! 1131: break; ! 1132: case i_NEG: ! 1133: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1134: start_brace (); ! 1135: genflags (flag_sub, curi->size, "dst", "src", "0"); ! 1136: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1137: if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2; ! 1138: break; ! 1139: case i_NEGX: ! 1140: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1141: start_brace (); ! 1142: printf ("\tuae_u32 newv = 0 - src - (GET_XFLG ? 1 : 0);\n"); ! 1143: genflags (flag_subx, curi->size, "newv", "src", "0"); ! 1144: genflags (flag_zn, curi->size, "newv", "", ""); ! 1145: genastore ("newv", curi->smode, "srcreg", curi->size, "src"); ! 1146: if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2; ! 1147: break; ! 1148: case i_NBCD: ! 1149: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1150: start_brace (); ! 1151: printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG ? 1 : 0);\n"); ! 1152: printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n"); ! 1153: printf ("\tuae_u16 newv;\n"); ! 1154: printf ("\tint cflg;\n"); ! 1155: printf ("\tif (newv_lo > 9) { newv_lo -= 6; }\n"); ! 1156: printf ("\tnewv = newv_hi + newv_lo;"); ! 1157: printf ("\tcflg = (newv & 0x1F0) > 0x90;\n"); ! 1158: printf ("\tif (cflg) newv -= 0x60;\n"); ! 1159: printf ("\tSET_CFLG (cflg);\n"); ! 1160: duplicate_carry(); ! 1161: genflags (flag_zn, curi->size, "newv", "", ""); ! 1162: genastore ("newv", curi->smode, "srcreg", curi->size, "src"); ! 1163: if(curi->smode==Dreg) insn_n_cycles += 2; ! 1164: break; ! 1165: case i_CLR: ! 1166: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); ! 1167: ! 1168: /* [NP] CLR does a read before the write only on 68000 */ ! 1169: /* but there's no cycle penalty for doing the read */ ! 1170: if ( curi->smode != Dreg ) // only if destination is memory ! 1171: { ! 1172: if (curi->size==sz_byte) ! 1173: printf ("\tuae_s8 src = get_byte(srca);\n"); ! 1174: else if (curi->size==sz_word) ! 1175: printf ("\tuae_s16 src = get_word(srca);\n"); ! 1176: else if (curi->size==sz_long) ! 1177: printf ("\tuae_s32 src = get_long(srca);\n"); ! 1178: } ! 1179: ! 1180: genflags (flag_logical, curi->size, "0", "", ""); ! 1181: genastore ("0", curi->smode, "srcreg", curi->size, "src"); ! 1182: if(curi->size==sz_long) ! 1183: { ! 1184: if(curi->smode==Dreg) ! 1185: insn_n_cycles += 2; ! 1186: else ! 1187: insn_n_cycles += 4; ! 1188: } ! 1189: if(curi->smode!=Dreg) ! 1190: insn_n_cycles += 4; ! 1191: break; ! 1192: case i_NOT: ! 1193: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1194: start_brace (); ! 1195: printf ("\tuae_u32 dst = ~src;\n"); ! 1196: genflags (flag_logical, curi->size, "dst", "", ""); ! 1197: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1198: if(curi->size==sz_long && curi->smode==Dreg) insn_n_cycles += 2; ! 1199: break; ! 1200: case i_TST: ! 1201: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1202: genflags (flag_logical, curi->size, "src", "", ""); ! 1203: break; ! 1204: case i_BTST: ! 1205: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1206: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1207: if (curi->size == sz_byte) ! 1208: printf ("\tsrc &= 7;\n"); ! 1209: else ! 1210: printf ("\tsrc &= 31;\n"); ! 1211: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); ! 1212: if(curi->dmode==Dreg) insn_n_cycles += 2; ! 1213: break; ! 1214: case i_BCHG: ! 1215: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1216: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1217: if (curi->size == sz_byte) ! 1218: printf ("\tsrc &= 7;\n"); ! 1219: else ! 1220: printf ("\tsrc &= 31;\n"); ! 1221: printf ("\tdst ^= (1 << src);\n"); ! 1222: printf ("\tSET_ZFLG (((uae_u32)dst & (1 << src)) >> src);\n"); ! 1223: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1224: if(curi->dmode==Dreg) insn_n_cycles += 4; ! 1225: break; ! 1226: case i_BCLR: ! 1227: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1228: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1229: if (curi->size == sz_byte) ! 1230: printf ("\tsrc &= 7;\n"); ! 1231: else ! 1232: printf ("\tsrc &= 31;\n"); ! 1233: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); ! 1234: printf ("\tdst &= ~(1 << src);\n"); ! 1235: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1236: if(curi->dmode==Dreg) insn_n_cycles += 6; ! 1237: /* [NP] BCLR #n,Dx takes 12 cycles instead of 14 if n<16 */ ! 1238: if((curi->smode==imm1) && (curi->dmode==Dreg)) ! 1239: printf ("\tif ( src < 16 ) { m68k_incpc(4); return 12; }\n"); ! 1240: /* [NP] BCLR Dy,Dx takes 8 cycles instead of 10 if Dy<16 */ ! 1241: if((curi->smode==Dreg) && (curi->dmode==Dreg)) ! 1242: printf ("\tif ( src < 16 ) { m68k_incpc(2); return 8; }\n"); ! 1243: break; ! 1244: case i_BSET: ! 1245: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1246: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1247: if (curi->size == sz_byte) ! 1248: printf ("\tsrc &= 7;\n"); ! 1249: else ! 1250: printf ("\tsrc &= 31;\n"); ! 1251: printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n"); ! 1252: printf ("\tdst |= (1 << src);\n"); ! 1253: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1254: if(curi->dmode==Dreg) insn_n_cycles += 4; ! 1255: break; ! 1256: case i_CMPM: ! 1257: case i_CMP: ! 1258: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1259: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1260: start_brace (); ! 1261: genflags (flag_cmp, curi->size, "newv", "src", "dst"); ! 1262: if(curi->size==sz_long && curi->dmode==Dreg) ! 1263: insn_n_cycles += 2; ! 1264: break; ! 1265: case i_CMPA: ! 1266: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1267: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1268: start_brace (); ! 1269: genflags (flag_cmp, sz_long, "newv", "src", "dst"); ! 1270: insn_n_cycles += 2; ! 1271: break; ! 1272: /* The next two are coded a little unconventional, but they are doing ! 1273: * weird things... */ ! 1274: case i_MVPRM: ! 1275: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1276: ! 1277: printf ("\tuaecptr memp = m68k_areg(regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); ! 1278: if (curi->size == sz_word) { ! 1279: printf ("\tput_byte(memp, src >> 8); put_byte(memp + 2, src);\n"); ! 1280: } else { ! 1281: printf ("\tput_byte(memp, src >> 24); put_byte(memp + 2, src >> 16);\n"); ! 1282: printf ("\tput_byte(memp + 4, src >> 8); put_byte(memp + 6, src);\n"); ! 1283: } ! 1284: if(curi->size==sz_long) insn_n_cycles=24; else insn_n_cycles=16; ! 1285: break; ! 1286: case i_MVPMR: ! 1287: printf ("\tuaecptr memp = m68k_areg(regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); ! 1288: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1289: if (curi->size == sz_word) { ! 1290: printf ("\tuae_u16 val = (get_byte(memp) << 8) + get_byte(memp + 2);\n"); ! 1291: } else { ! 1292: printf ("\tuae_u32 val = (get_byte(memp) << 24) + (get_byte(memp + 2) << 16)\n"); ! 1293: printf (" + (get_byte(memp + 4) << 8) + get_byte(memp + 6);\n"); ! 1294: } ! 1295: genastore ("val", curi->dmode, "dstreg", curi->size, "dst"); ! 1296: if(curi->size==sz_long) insn_n_cycles=24; else insn_n_cycles=16; ! 1297: break; ! 1298: case i_MOVE: ! 1299: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1300: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1301: ! 1302: /* [NP] genamode counts 2 cycles if dest is -(An), this is wrong. */ ! 1303: /* For move dest (An), (An)+ and -(An) take the same time */ ! 1304: /* (for other instr, dest -(An) really takes 2 cycles more) */ ! 1305: if ( curi->dmode == Apdi ) ! 1306: insn_n_cycles -= 2; /* correct the wrong cycle count for -(An) */ ! 1307: ! 1308: genflags (flag_logical, curi->size, "src", "", ""); ! 1309: genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 1310: break; ! 1311: case i_MOVEA: ! 1312: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1313: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1314: if (curi->size == sz_word) { ! 1315: printf ("\tuae_u32 val = (uae_s32)(uae_s16)src;\n"); ! 1316: } else { ! 1317: printf ("\tuae_u32 val = src;\n"); ! 1318: } ! 1319: genastore ("val", curi->dmode, "dstreg", sz_long, "dst"); ! 1320: break; ! 1321: case i_MVSR2: /* Move from SR */ ! 1322: genamode (curi->smode, "srcreg", sz_word, "src", 2, 0); ! 1323: printf ("\tMakeSR();\n"); ! 1324: if (curi->size == sz_byte) ! 1325: genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src"); ! 1326: else ! 1327: genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src"); ! 1328: if (curi->smode==Dreg) insn_n_cycles += 2; else insn_n_cycles += 4; ! 1329: break; ! 1330: case i_MV2SR: /* Move to SR */ ! 1331: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); ! 1332: if (curi->size == sz_byte) ! 1333: printf ("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n"); ! 1334: else { ! 1335: printf ("\tregs.sr = src;\n"); ! 1336: } ! 1337: printf ("\tMakeFromSR();\n"); ! 1338: insn_n_cycles += 8; ! 1339: break; ! 1340: case i_SWAP: ! 1341: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); ! 1342: start_brace (); ! 1343: printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n"); ! 1344: genflags (flag_logical, sz_long, "dst", "", ""); ! 1345: genastore ("dst", curi->smode, "srcreg", sz_long, "src"); ! 1346: break; ! 1347: case i_EXG: ! 1348: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1349: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1350: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1351: genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 1352: insn_n_cycles = 6; ! 1353: break; ! 1354: case i_EXT: ! 1355: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); ! 1356: start_brace (); ! 1357: switch (curi->size) { ! 1358: case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break; ! 1359: case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break; ! 1360: case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break; ! 1361: default: abort (); ! 1362: } ! 1363: genflags (flag_logical, ! 1364: curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); ! 1365: genastore ("dst", curi->smode, "srcreg", ! 1366: curi->size == sz_word ? sz_word : sz_long, "src"); ! 1367: break; ! 1368: case i_MVMEL: ! 1369: genmovemel (opcode); ! 1370: break; ! 1371: case i_MVMLE: ! 1372: genmovemle (opcode); ! 1373: break; ! 1374: case i_TRAP: ! 1375: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1376: sync_m68k_pc (); ! 1377: printf ("\tException(src+32,0,M68000_EXC_SRC_CPU);\n"); ! 1378: m68k_pc_offset = 0; ! 1379: break; ! 1380: case i_MVR2USP: ! 1381: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1382: printf ("\tregs.usp = src;\n"); ! 1383: break; ! 1384: case i_MVUSP2R: ! 1385: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); ! 1386: genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src"); ! 1387: break; ! 1388: case i_RESET: ! 1389: printf ("\tcustomreset();\n"); ! 1390: insn_n_cycles = 132; /* I am not so sure about this!? - Thothy */ ! 1391: break; ! 1392: case i_NOP: ! 1393: break; ! 1394: case i_STOP: ! 1395: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1396: printf ("\tregs.sr = src;\n"); ! 1397: printf ("\tMakeFromSR();\n"); ! 1398: printf ("\tm68k_setstopped(1);\n"); ! 1399: insn_n_cycles = 4; ! 1400: break; ! 1401: case i_RTE: ! 1402: if (cpu_level == 0) { ! 1403: genamode (Aipi, "7", sz_word, "sr", 1, 0); ! 1404: genamode (Aipi, "7", sz_long, "pc", 1, 0); ! 1405: printf ("\tregs.sr = sr; m68k_setpc_rte(pc);\n"); ! 1406: fill_prefetch_0 (); ! 1407: printf ("\tMakeFromSR();\n"); ! 1408: } else { ! 1409: int old_brace_level = n_braces; ! 1410: if (next_cpu_level < 0) ! 1411: next_cpu_level = 0; ! 1412: printf ("\tuae_u16 newsr; uae_u32 newpc; for (;;) {\n"); ! 1413: genamode (Aipi, "7", sz_word, "sr", 1, 0); ! 1414: genamode (Aipi, "7", sz_long, "pc", 1, 0); ! 1415: genamode (Aipi, "7", sz_word, "format", 1, 0); ! 1416: printf ("\tnewsr = sr; newpc = pc;\n"); ! 1417: printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n"); ! 1418: printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n"); ! 1419: printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }\n"); ! 1420: printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }\n"); ! 1421: printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }\n"); ! 1422: printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }\n"); ! 1423: printf ("\telse if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; }\n"); ! 1424: printf ("\telse { Exception(14,0,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 1425: printf ("\tregs.sr = newsr; MakeFromSR();\n}\n"); ! 1426: pop_braces (old_brace_level); ! 1427: printf ("\tregs.sr = newsr; MakeFromSR();\n"); ! 1428: printf ("\tm68k_setpc_rte(newpc);\n"); ! 1429: fill_prefetch_0 (); ! 1430: need_endlabel = 1; ! 1431: } ! 1432: /* PC is set and prefetch filled. */ ! 1433: m68k_pc_offset = 0; ! 1434: insn_n_cycles = 20; ! 1435: break; ! 1436: case i_RTD: ! 1437: genamode (Aipi, "7", sz_long, "pc", 1, 0); ! 1438: genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0); ! 1439: printf ("\tm68k_areg(regs, 7) += offs;\n"); ! 1440: printf ("\tm68k_setpc_rte(pc);\n"); ! 1441: fill_prefetch_0 (); ! 1442: /* PC is set and prefetch filled. */ ! 1443: m68k_pc_offset = 0; ! 1444: break; ! 1445: case i_LINK: ! 1446: genamode (Apdi, "7", sz_long, "old", 2, 0); ! 1447: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); ! 1448: genastore ("src", Apdi, "7", sz_long, "old"); ! 1449: genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src"); ! 1450: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); ! 1451: printf ("\tm68k_areg(regs, 7) += offs;\n"); ! 1452: break; ! 1453: case i_UNLK: ! 1454: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1455: printf ("\tm68k_areg(regs, 7) = src;\n"); ! 1456: genamode (Aipi, "7", sz_long, "old", 1, 0); ! 1457: genastore ("old", curi->smode, "srcreg", curi->size, "src"); ! 1458: break; ! 1459: case i_RTS: ! 1460: printf ("\tm68k_do_rts();\n"); ! 1461: fill_prefetch_0 (); ! 1462: m68k_pc_offset = 0; ! 1463: insn_n_cycles = 16; ! 1464: break; ! 1465: case i_TRAPV: ! 1466: sync_m68k_pc (); ! 1467: printf ("\tif (GET_VFLG) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 1468: need_endlabel = 1; ! 1469: break; ! 1470: case i_RTR: ! 1471: printf ("\tMakeSR();\n"); ! 1472: genamode (Aipi, "7", sz_word, "sr", 1, 0); ! 1473: genamode (Aipi, "7", sz_long, "pc", 1, 0); ! 1474: printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n"); ! 1475: printf ("\tregs.sr |= sr; m68k_setpc(pc);\n"); ! 1476: fill_prefetch_0 (); ! 1477: printf ("\tMakeFromSR();\n"); ! 1478: m68k_pc_offset = 0; ! 1479: insn_n_cycles = 20; ! 1480: break; ! 1481: case i_JSR: ! 1482: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1483: printf ("\tm68k_do_jsr(m68k_getpc() + %d, srca);\n", m68k_pc_offset); ! 1484: fill_prefetch_0 (); ! 1485: m68k_pc_offset = 0; ! 1486: switch(curi->smode) ! 1487: { ! 1488: case Aind: insn_n_cycles=16; break; ! 1489: case Ad16: insn_n_cycles=18; break; ! 1490: case Ad8r: insn_n_cycles=22; break; ! 1491: case absw: insn_n_cycles=18; break; ! 1492: case absl: insn_n_cycles=20; break; ! 1493: case PC16: insn_n_cycles=18; break; ! 1494: case PC8r: insn_n_cycles=22; break; ! 1495: } ! 1496: break; ! 1497: case i_JMP: ! 1498: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1499: printf ("\tm68k_setpc(srca);\n"); ! 1500: fill_prefetch_0 (); ! 1501: m68k_pc_offset = 0; ! 1502: switch(curi->smode) ! 1503: { ! 1504: case Aind: insn_n_cycles=8; break; ! 1505: case Ad16: insn_n_cycles=10; break; ! 1506: case Ad8r: insn_n_cycles=14; break; ! 1507: case absw: insn_n_cycles=10; break; ! 1508: case absl: insn_n_cycles=12; break; ! 1509: case PC16: insn_n_cycles=10; break; ! 1510: case PC8r: insn_n_cycles=14; break; ! 1511: } ! 1512: break; ! 1513: case i_BSR: ! 1514: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1515: printf ("\tuae_s32 s = (uae_s32)src + 2;\n"); ! 1516: if (using_exception_3) { ! 1517: printf ("\tif (src & 1) {\n"); ! 1518: printf ("\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ? ! 1519: printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + s;\n"); ! 1520: printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); ! 1521: printf ("\t}\n"); ! 1522: need_endlabel = 1; ! 1523: } ! 1524: printf ("\tm68k_do_bsr(m68k_getpc() + %d, s);\n", m68k_pc_offset); ! 1525: fill_prefetch_0 (); ! 1526: m68k_pc_offset = 0; ! 1527: insn_n_cycles = 18; ! 1528: break; ! 1529: case i_Bcc: ! 1530: if (curi->size == sz_long) { ! 1531: if (cpu_level < 2) { ! 1532: printf ("\tm68k_incpc(2);\n"); ! 1533: printf ("\tif (!cctrue(%d)) goto %s;\n", curi->cc, endlabelstr); ! 1534: printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); ! 1535: printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 1;\n"); ! 1536: printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); ! 1537: need_endlabel = 1; ! 1538: } else { ! 1539: if (next_cpu_level < 1) ! 1540: next_cpu_level = 1; ! 1541: } ! 1542: } ! 1543: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1544: printf ("\tif (!cctrue(%d)) goto didnt_jump;\n", curi->cc); ! 1545: if (using_exception_3) { ! 1546: printf ("\tif (src & 1) {\n"); ! 1547: printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n"); // [NP] FIXME should be +4, not +2 (same as DBcc) ? ! 1548: printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)src;\n"); ! 1549: printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); ! 1550: printf ("\t}\n"); ! 1551: need_endlabel = 1; ! 1552: } ! 1553: printf ("\tm68k_incpc ((uae_s32)src + 2);\n"); ! 1554: fill_prefetch_0 (); ! 1555: printf ("\treturn 10;\n"); ! 1556: printf ("didnt_jump:;\n"); ! 1557: need_endlabel = 1; ! 1558: insn_n_cycles = (curi->size == sz_byte) ? 8 : 12; ! 1559: break; ! 1560: case i_LEA: ! 1561: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1562: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1563: genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); ! 1564: /* Set correct cycles: According to the M68K User Manual, LEA takes 12 ! 1565: * cycles in Ad8r and PC8r mode, but it takes 14 (or 16) cycles on a real ST: */ ! 1566: if (curi->smode == Ad8r || curi->smode == PC8r) ! 1567: insn_n_cycles = 14; ! 1568: break; ! 1569: case i_PEA: ! 1570: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1571: genamode (Apdi, "7", sz_long, "dst", 2, 0); ! 1572: genastore ("srca", Apdi, "7", sz_long, "dst"); ! 1573: /* Set correct cycles: */ ! 1574: switch(curi->smode) ! 1575: { ! 1576: case Aind: insn_n_cycles=12; break; ! 1577: case Ad16: insn_n_cycles=16; break; ! 1578: /* Note: according to the M68K User Manual, PEA takes 20 cycles for ! 1579: * the Ad8r mode, but on a real ST, it takes 22 (or 24) cycles! */ ! 1580: case Ad8r: insn_n_cycles=22; break; ! 1581: case absw: insn_n_cycles=16; break; ! 1582: case absl: insn_n_cycles=20; break; ! 1583: case PC16: insn_n_cycles=16; break; ! 1584: /* Note: PEA with PC8r takes 20 cycles according to the User Manual, ! 1585: * but it takes 22 (or 24) cycles on a real ST: */ ! 1586: case PC8r: insn_n_cycles=22; break; ! 1587: } ! 1588: break; ! 1589: case i_DBcc: ! 1590: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1591: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); ! 1592: ! 1593: printf ("\tif (!cctrue(%d)) {\n\t", curi->cc); ! 1594: genastore ("(src-1)", curi->smode, "srcreg", curi->size, "src"); ! 1595: ! 1596: printf ("\t\tif (src) {\n"); ! 1597: if (using_exception_3) { ! 1598: printf ("\t\t\tif (offs & 1) {\n"); ! 1599: printf ("\t\t\tlast_addr_for_exception_3 = m68k_getpc() + 2 + 2;\n"); // [NP] last_addr is pc+4, not pc+2 ! 1600: printf ("\t\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)offs + 2;\n"); ! 1601: printf ("\t\t\tlast_op_for_exception_3 = opcode; Exception(3,0,M68000_EXC_SRC_CPU); goto %s;\n", endlabelstr); ! 1602: printf ("\t\t}\n"); ! 1603: need_endlabel = 1; ! 1604: } ! 1605: printf ("\t\t\tm68k_incpc((uae_s32)offs + 2);\n"); ! 1606: fill_prefetch_0 (); ! 1607: printf ("\t\t\treturn 10;\n"); ! 1608: printf ("\t\t} else {\n\t\t\t"); ! 1609: { ! 1610: int tmp_offset = m68k_pc_offset; ! 1611: sync_m68k_pc(); /* not so nice to call it here... */ ! 1612: m68k_pc_offset = tmp_offset; ! 1613: } ! 1614: printf ("\t\t\treturn 14;\n"); ! 1615: printf ("\t\t}\n"); ! 1616: printf ("\t}\n"); ! 1617: insn_n_cycles = 12; ! 1618: need_endlabel = 1; ! 1619: break; ! 1620: case i_Scc: ! 1621: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); ! 1622: start_brace (); ! 1623: printf ("\tint val = cctrue(%d) ? 0xff : 0;\n", curi->cc); ! 1624: genastore ("val", curi->smode, "srcreg", curi->size, "src"); ! 1625: if (curi->smode!=Dreg) insn_n_cycles += 4; ! 1626: else ! 1627: { /* [NP] if result is TRUE, we return 6 instead of 4 */ ! 1628: printf ("\tif (val) { m68k_incpc(2) ; return 4+2; }\n"); ! 1629: } ! 1630: break; ! 1631: case i_DIVU: ! 1632: printf ("\tuaecptr oldpc = m68k_getpc();\n"); ! 1633: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); ! 1634: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1635: sync_m68k_pc (); ! 1636: /* Clear V flag when dividing by zero - Alcatraz Odyssey demo depends ! 1637: * on this (actually, it's doing a DIVS). */ ! 1638: printf ("\tif (src == 0) { SET_VFLG (0); Exception (5, oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr); ! 1639: printf ("\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n"); ! 1640: printf ("\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n"); ! 1641: /* The N flag appears to be set each time there is an overflow. ! 1642: * Weird. */ ! 1643: printf ("\tif (newv > 0xffff) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n"); ! 1644: genflags (flag_logical, sz_word, "newv", "", ""); ! 1645: printf ("\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); ! 1646: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1647: printf ("\t}\n"); ! 1648: printf ("\t}\n"); ! 1649: // insn_n_cycles += 136; ! 1650: printf ("\tretcycles = getDivu68kCycles((uae_u32)dst, (uae_u16)src);\n"); ! 1651: sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles); ! 1652: need_endlabel = 1; ! 1653: break; ! 1654: case i_DIVS: ! 1655: printf ("\tuaecptr oldpc = m68k_getpc();\n"); ! 1656: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); ! 1657: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1658: sync_m68k_pc (); ! 1659: printf ("\tif (src == 0) { SET_VFLG (0); Exception(5,oldpc,M68000_EXC_SRC_CPU); goto %s; } else {\n", endlabelstr); ! 1660: printf ("\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n"); ! 1661: printf ("\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n"); ! 1662: printf ("\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) { SET_VFLG (1); SET_NFLG (1); SET_CFLG (0); } else\n\t{\n"); ! 1663: printf ("\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n"); ! 1664: genflags (flag_logical, sz_word, "newv", "", ""); ! 1665: printf ("\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n"); ! 1666: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1667: printf ("\t}\n"); ! 1668: printf ("\t}\n"); ! 1669: // insn_n_cycles += 154; ! 1670: printf ("\tretcycles = getDivs68kCycles((uae_s32)dst, (uae_s16)src);\n"); ! 1671: sprintf(exactCpuCycles," return (%i+retcycles);", insn_n_cycles); ! 1672: need_endlabel = 1; ! 1673: break; ! 1674: case i_MULU: ! 1675: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); ! 1676: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); ! 1677: start_brace (); ! 1678: printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n"); ! 1679: genflags (flag_logical, sz_long, "newv", "", ""); ! 1680: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1681: /* [NP] number of cycles is 38 + 2n + ea time ; n is the number of 1 bits in src */ ! 1682: insn_n_cycles += 38-4; /* insn_n_cycles is already initialized to 4 instead of 0 */ ! 1683: printf ("\twhile (src) { if (src & 1) retcycles++; src = (uae_u16)src >> 1; }\n"); ! 1684: sprintf(exactCpuCycles," return (%i+retcycles*2);", insn_n_cycles); ! 1685: break; ! 1686: case i_MULS: ! 1687: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); ! 1688: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); ! 1689: start_brace (); ! 1690: printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n"); ! 1691: printf ("\tuae_u32 src2;\n"); ! 1692: genflags (flag_logical, sz_long, "newv", "", ""); ! 1693: genastore ("newv", curi->dmode, "dstreg", sz_long, "dst"); ! 1694: /* [NP] number of cycles is 38 + 2n + ea time ; n is the number of 01 or 10 patterns in src expanded to 17 bits */ ! 1695: insn_n_cycles += 38-4; /* insn_n_cycles is already initialized to 4 instead of 0 */ ! 1696: printf ("\tsrc2 = ((uae_u32)src) << 1;\n"); ! 1697: printf ("\twhile (src2) { if ( ( (src2 & 3) == 1 ) || ( (src2 & 3) == 2 ) ) retcycles++; src2 >>= 1; }\n"); ! 1698: sprintf(exactCpuCycles," return (%i+retcycles*2);", insn_n_cycles); ! 1699: break; ! 1700: case i_CHK: ! 1701: printf ("\tuaecptr oldpc = m68k_getpc();\n"); ! 1702: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1703: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1704: sync_m68k_pc (); ! 1705: printf ("\tif ((uae_s32)dst < 0) { SET_NFLG (1); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 1706: printf ("\telse if (dst > src) { SET_NFLG (0); Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n", endlabelstr); ! 1707: need_endlabel = 1; ! 1708: insn_n_cycles += 6; ! 1709: break; ! 1710: ! 1711: case i_CHK2: ! 1712: printf ("\tuaecptr oldpc = m68k_getpc();\n"); ! 1713: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 1714: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1715: printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n"); ! 1716: switch (curi->size) { ! 1717: case sz_byte: ! 1718: printf ("\tlower=(uae_s32)(uae_s8)get_byte(dsta); upper = (uae_s32)(uae_s8)get_byte(dsta+1);\n"); ! 1719: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n"); ! 1720: break; ! 1721: case sz_word: ! 1722: printf ("\tlower=(uae_s32)(uae_s16)get_word(dsta); upper = (uae_s32)(uae_s16)get_word(dsta+2);\n"); ! 1723: printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n"); ! 1724: break; ! 1725: case sz_long: ! 1726: printf ("\tlower=get_long(dsta); upper = get_long(dsta+4);\n"); ! 1727: break; ! 1728: default: ! 1729: abort (); ! 1730: } ! 1731: printf ("\tSET_ZFLG (upper == reg || lower == reg);\n"); ! 1732: printf ("\tSET_CFLG (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n"); ! 1733: sync_m68k_pc (); ! 1734: printf ("\tif ((extra & 0x800) && GET_CFLG) { Exception(6,oldpc,M68000_EXC_SRC_CPU); goto %s; }\n}\n", endlabelstr); ! 1735: need_endlabel = 1; ! 1736: break; ! 1737: ! 1738: case i_ASR: ! 1739: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1740: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1741: start_brace (); ! 1742: switch (curi->size) { ! 1743: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1744: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1745: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1746: default: abort (); ! 1747: } ! 1748: printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1); ! 1749: printf ("\tcnt &= 63;\n"); ! 1750: printf ("\tretcycles = cnt;\n"); ! 1751: printf ("\tCLEAR_CZNV;\n"); ! 1752: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 1753: printf ("\t\tval = %s & (uae_u32)-sign;\n", bit_mask (curi->size)); ! 1754: printf ("\t\tSET_CFLG (sign);\n"); ! 1755: duplicate_carry (); ! 1756: if (source_is_imm1_8 (curi)) ! 1757: printf ("\t} else {\n"); ! 1758: else ! 1759: printf ("\t} else if (cnt > 0) {\n"); ! 1760: printf ("\t\tval >>= cnt - 1;\n"); ! 1761: printf ("\t\tSET_CFLG (val & 1);\n"); ! 1762: duplicate_carry (); ! 1763: printf ("\t\tval >>= 1;\n"); ! 1764: printf ("\t\tval |= (%s << (%d - cnt)) & (uae_u32)-sign;\n", ! 1765: bit_mask (curi->size), ! 1766: bit_size (curi->size)); ! 1767: printf ("\t\tval &= %s;\n", bit_mask (curi->size)); ! 1768: printf ("\t}\n"); ! 1769: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 1770: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 1771: if(curi->size==sz_long) ! 1772: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 1773: else ! 1774: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 1775: break; ! 1776: case i_ASL: ! 1777: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1778: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1779: start_brace (); ! 1780: switch (curi->size) { ! 1781: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1782: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1783: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1784: default: abort (); ! 1785: } ! 1786: printf ("\tcnt &= 63;\n"); ! 1787: printf ("\tretcycles = cnt;\n"); ! 1788: printf ("\tCLEAR_CZNV;\n"); ! 1789: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 1790: printf ("\t\tSET_VFLG (val != 0);\n"); ! 1791: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", ! 1792: bit_size (curi->size)); ! 1793: duplicate_carry (); ! 1794: printf ("\t\tval = 0;\n"); ! 1795: if (source_is_imm1_8 (curi)) ! 1796: printf ("\t} else {\n"); ! 1797: else ! 1798: printf ("\t} else if (cnt > 0) {\n"); ! 1799: printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n", ! 1800: bit_mask (curi->size), ! 1801: bit_size (curi->size) - 1, ! 1802: bit_mask (curi->size)); ! 1803: printf ("\t\tSET_VFLG ((val & mask) != mask && (val & mask) != 0);\n"); ! 1804: printf ("\t\tval <<= cnt - 1;\n"); ! 1805: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); ! 1806: duplicate_carry (); ! 1807: printf ("\t\tval <<= 1;\n"); ! 1808: printf ("\t\tval &= %s;\n", bit_mask (curi->size)); ! 1809: printf ("\t}\n"); ! 1810: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 1811: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 1812: if(curi->size==sz_long) ! 1813: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 1814: else ! 1815: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 1816: break; ! 1817: case i_LSR: ! 1818: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1819: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1820: start_brace (); ! 1821: switch (curi->size) { ! 1822: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1823: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1824: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1825: default: abort (); ! 1826: } ! 1827: printf ("\tcnt &= 63;\n"); ! 1828: printf ("\tretcycles = cnt;\n"); ! 1829: printf ("\tCLEAR_CZNV;\n"); ! 1830: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 1831: printf ("\t\tSET_CFLG ((cnt == %d) & (val >> %d));\n", ! 1832: bit_size (curi->size), bit_size (curi->size) - 1); ! 1833: duplicate_carry (); ! 1834: printf ("\t\tval = 0;\n"); ! 1835: if (source_is_imm1_8 (curi)) ! 1836: printf ("\t} else {\n"); ! 1837: else ! 1838: printf ("\t} else if (cnt > 0) {\n"); ! 1839: printf ("\t\tval >>= cnt - 1;\n"); ! 1840: printf ("\t\tSET_CFLG (val & 1);\n"); ! 1841: duplicate_carry (); ! 1842: printf ("\t\tval >>= 1;\n"); ! 1843: printf ("\t}\n"); ! 1844: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 1845: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 1846: if(curi->size==sz_long) ! 1847: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 1848: else ! 1849: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 1850: break; ! 1851: case i_LSL: ! 1852: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1853: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1854: start_brace (); ! 1855: switch (curi->size) { ! 1856: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1857: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1858: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1859: default: abort (); ! 1860: } ! 1861: printf ("\tcnt &= 63;\n"); ! 1862: printf ("\tretcycles = cnt;\n"); ! 1863: printf ("\tCLEAR_CZNV;\n"); ! 1864: printf ("\tif (cnt >= %d) {\n", bit_size (curi->size)); ! 1865: printf ("\t\tSET_CFLG (cnt == %d ? val & 1 : 0);\n", ! 1866: bit_size (curi->size)); ! 1867: duplicate_carry (); ! 1868: printf ("\t\tval = 0;\n"); ! 1869: if (source_is_imm1_8 (curi)) ! 1870: printf ("\t} else {\n"); ! 1871: else ! 1872: printf ("\t} else if (cnt > 0) {\n"); ! 1873: printf ("\t\tval <<= (cnt - 1);\n"); ! 1874: printf ("\t\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); ! 1875: duplicate_carry (); ! 1876: printf ("\t\tval <<= 1;\n"); ! 1877: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 1878: printf ("\t}\n"); ! 1879: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 1880: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 1881: if(curi->size==sz_long) ! 1882: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 1883: else ! 1884: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 1885: break; ! 1886: case i_ROL: ! 1887: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1888: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1889: start_brace (); ! 1890: switch (curi->size) { ! 1891: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1892: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1893: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1894: default: abort (); ! 1895: } ! 1896: printf ("\tcnt &= 63;\n"); ! 1897: printf ("\tretcycles = cnt;\n"); ! 1898: printf ("\tCLEAR_CZNV;\n"); ! 1899: if (source_is_imm1_8 (curi)) ! 1900: printf ("{"); ! 1901: else ! 1902: printf ("\tif (cnt > 0) {\n"); ! 1903: printf ("\tuae_u32 loval;\n"); ! 1904: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); ! 1905: printf ("\tloval = val >> (%d - cnt);\n", bit_size (curi->size)); ! 1906: printf ("\tval <<= cnt;\n"); ! 1907: printf ("\tval |= loval;\n"); ! 1908: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 1909: printf ("\tSET_CFLG (val & 1);\n"); ! 1910: printf ("}\n"); ! 1911: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 1912: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 1913: if(curi->size==sz_long) ! 1914: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 1915: else ! 1916: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 1917: break; ! 1918: case i_ROR: ! 1919: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1920: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1921: start_brace (); ! 1922: switch (curi->size) { ! 1923: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1924: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1925: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1926: default: abort (); ! 1927: } ! 1928: printf ("\tcnt &= 63;\n"); ! 1929: printf ("\tretcycles = cnt;\n"); ! 1930: printf ("\tCLEAR_CZNV;\n"); ! 1931: if (source_is_imm1_8 (curi)) ! 1932: printf ("{"); ! 1933: else ! 1934: printf ("\tif (cnt > 0) {"); ! 1935: printf ("\tuae_u32 hival;\n"); ! 1936: printf ("\tcnt &= %d;\n", bit_size (curi->size) - 1); ! 1937: printf ("\thival = val << (%d - cnt);\n", bit_size (curi->size)); ! 1938: printf ("\tval >>= cnt;\n"); ! 1939: printf ("\tval |= hival;\n"); ! 1940: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 1941: printf ("\tSET_CFLG ((val & %s) >> %d);\n", cmask (curi->size), bit_size (curi->size) - 1); ! 1942: printf ("\t}\n"); ! 1943: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 1944: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 1945: if(curi->size==sz_long) ! 1946: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 1947: else ! 1948: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 1949: break; ! 1950: case i_ROXL: ! 1951: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1952: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1953: start_brace (); ! 1954: switch (curi->size) { ! 1955: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1956: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1957: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1958: default: abort (); ! 1959: } ! 1960: printf ("\tcnt &= 63;\n"); ! 1961: printf ("\tretcycles = cnt;\n"); ! 1962: printf ("\tCLEAR_CZNV;\n"); ! 1963: if (source_is_imm1_8 (curi)) ! 1964: printf ("{"); ! 1965: else { ! 1966: force_range_for_rox ("cnt", curi->size); ! 1967: printf ("\tif (cnt > 0) {\n"); ! 1968: } ! 1969: printf ("\tcnt--;\n"); ! 1970: printf ("\t{\n\tuae_u32 carry;\n"); ! 1971: printf ("\tuae_u32 loval = val >> (%d - cnt);\n", bit_size (curi->size) - 1); ! 1972: printf ("\tcarry = loval & 1;\n"); ! 1973: printf ("\tval = (((val << 1) | GET_XFLG) << cnt) | (loval >> 1);\n"); ! 1974: printf ("\tSET_XFLG (carry);\n"); ! 1975: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 1976: printf ("\t} }\n"); ! 1977: printf ("\tSET_CFLG (GET_XFLG);\n"); ! 1978: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 1979: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 1980: if(curi->size==sz_long) ! 1981: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 1982: else ! 1983: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 1984: break; ! 1985: case i_ROXR: ! 1986: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 1987: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 1988: start_brace (); ! 1989: switch (curi->size) { ! 1990: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 1991: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 1992: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 1993: default: abort (); ! 1994: } ! 1995: printf ("\tcnt &= 63;\n"); ! 1996: printf ("\tretcycles = cnt;\n"); ! 1997: printf ("\tCLEAR_CZNV;\n"); ! 1998: if (source_is_imm1_8 (curi)) ! 1999: printf ("{"); ! 2000: else { ! 2001: force_range_for_rox ("cnt", curi->size); ! 2002: printf ("\tif (cnt > 0) {\n"); ! 2003: } ! 2004: printf ("\tcnt--;\n"); ! 2005: printf ("\t{\n\tuae_u32 carry;\n"); ! 2006: printf ("\tuae_u32 hival = (val << 1) | GET_XFLG;\n"); ! 2007: printf ("\thival <<= (%d - cnt);\n", bit_size (curi->size) - 1); ! 2008: printf ("\tval >>= cnt;\n"); ! 2009: printf ("\tcarry = val & 1;\n"); ! 2010: printf ("\tval >>= 1;\n"); ! 2011: printf ("\tval |= hival;\n"); ! 2012: printf ("\tSET_XFLG (carry);\n"); ! 2013: printf ("\tval &= %s;\n", bit_mask (curi->size)); ! 2014: printf ("\t} }\n"); ! 2015: printf ("\tSET_CFLG (GET_XFLG);\n"); ! 2016: genflags (flag_logical_noclobber, curi->size, "val", "", ""); ! 2017: genastore ("val", curi->dmode, "dstreg", curi->size, "data"); ! 2018: if(curi->size==sz_long) ! 2019: strcpy(exactCpuCycles," return (8+retcycles*2);"); ! 2020: else ! 2021: strcpy(exactCpuCycles," return (6+retcycles*2);"); ! 2022: break; ! 2023: case i_ASRW: ! 2024: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2025: start_brace (); ! 2026: switch (curi->size) { ! 2027: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2028: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2029: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2030: default: abort (); ! 2031: } ! 2032: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); ! 2033: printf ("\tuae_u32 cflg = val & 1;\n"); ! 2034: printf ("\tval = (val >> 1) | sign;\n"); ! 2035: genflags (flag_logical, curi->size, "val", "", ""); ! 2036: printf ("\tSET_CFLG (cflg);\n"); ! 2037: duplicate_carry (); ! 2038: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2039: break; ! 2040: case i_ASLW: ! 2041: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2042: start_brace (); ! 2043: switch (curi->size) { ! 2044: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2045: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2046: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2047: default: abort (); ! 2048: } ! 2049: printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size)); ! 2050: printf ("\tuae_u32 sign2;\n"); ! 2051: printf ("\tval <<= 1;\n"); ! 2052: genflags (flag_logical, curi->size, "val", "", ""); ! 2053: printf ("\tsign2 = %s & val;\n", cmask (curi->size)); ! 2054: printf ("\tSET_CFLG (sign != 0);\n"); ! 2055: duplicate_carry (); ! 2056: ! 2057: printf ("\tSET_VFLG (GET_VFLG | (sign2 != sign));\n"); ! 2058: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2059: break; ! 2060: case i_LSRW: ! 2061: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2062: start_brace (); ! 2063: switch (curi->size) { ! 2064: case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break; ! 2065: case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break; ! 2066: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2067: default: abort (); ! 2068: } ! 2069: printf ("\tuae_u32 carry = val & 1;\n"); ! 2070: printf ("\tval >>= 1;\n"); ! 2071: genflags (flag_logical, curi->size, "val", "", ""); ! 2072: printf ("SET_CFLG (carry);\n"); ! 2073: duplicate_carry (); ! 2074: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2075: break; ! 2076: case i_LSLW: ! 2077: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2078: start_brace (); ! 2079: switch (curi->size) { ! 2080: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 2081: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 2082: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2083: default: abort (); ! 2084: } ! 2085: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); ! 2086: printf ("\tval <<= 1;\n"); ! 2087: genflags (flag_logical, curi->size, "val", "", ""); ! 2088: printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); ! 2089: duplicate_carry (); ! 2090: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2091: break; ! 2092: case i_ROLW: ! 2093: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2094: start_brace (); ! 2095: switch (curi->size) { ! 2096: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 2097: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 2098: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2099: default: abort (); ! 2100: } ! 2101: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); ! 2102: printf ("\tval <<= 1;\n"); ! 2103: printf ("\tif (carry) val |= 1;\n"); ! 2104: genflags (flag_logical, curi->size, "val", "", ""); ! 2105: printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); ! 2106: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2107: break; ! 2108: case i_RORW: ! 2109: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2110: start_brace (); ! 2111: switch (curi->size) { ! 2112: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 2113: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 2114: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2115: default: abort (); ! 2116: } ! 2117: printf ("\tuae_u32 carry = val & 1;\n"); ! 2118: printf ("\tval >>= 1;\n"); ! 2119: printf ("\tif (carry) val |= %s;\n", cmask (curi->size)); ! 2120: genflags (flag_logical, curi->size, "val", "", ""); ! 2121: printf ("SET_CFLG (carry);\n"); ! 2122: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2123: break; ! 2124: case i_ROXLW: ! 2125: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2126: start_brace (); ! 2127: switch (curi->size) { ! 2128: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 2129: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 2130: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2131: default: abort (); ! 2132: } ! 2133: printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size)); ! 2134: printf ("\tval <<= 1;\n"); ! 2135: printf ("\tif (GET_XFLG) val |= 1;\n"); ! 2136: genflags (flag_logical, curi->size, "val", "", ""); ! 2137: printf ("SET_CFLG (carry >> %d);\n", bit_size (curi->size) - 1); ! 2138: duplicate_carry (); ! 2139: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2140: break; ! 2141: case i_ROXRW: ! 2142: genamode (curi->smode, "srcreg", curi->size, "data", 1, 0); ! 2143: start_brace (); ! 2144: switch (curi->size) { ! 2145: case sz_byte: printf ("\tuae_u8 val = data;\n"); break; ! 2146: case sz_word: printf ("\tuae_u16 val = data;\n"); break; ! 2147: case sz_long: printf ("\tuae_u32 val = data;\n"); break; ! 2148: default: abort (); ! 2149: } ! 2150: printf ("\tuae_u32 carry = val & 1;\n"); ! 2151: printf ("\tval >>= 1;\n"); ! 2152: printf ("\tif (GET_XFLG) val |= %s;\n", cmask (curi->size)); ! 2153: genflags (flag_logical, curi->size, "val", "", ""); ! 2154: printf ("SET_CFLG (carry);\n"); ! 2155: duplicate_carry (); ! 2156: genastore ("val", curi->smode, "srcreg", curi->size, "data"); ! 2157: break; ! 2158: case i_MOVEC2: ! 2159: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 2160: start_brace (); ! 2161: printf ("\tint regno = (src >> 12) & 15;\n"); ! 2162: printf ("\tuae_u32 *regp = regs.regs + regno;\n"); ! 2163: printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr); ! 2164: break; ! 2165: case i_MOVE2C: ! 2166: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 2167: start_brace (); ! 2168: printf ("\tint regno = (src >> 12) & 15;\n"); ! 2169: printf ("\tuae_u32 *regp = regs.regs + regno;\n"); ! 2170: printf ("\tif (! m68k_move2c(src & 0xFFF, regp)) goto %s;\n", endlabelstr); ! 2171: break; ! 2172: case i_CAS: ! 2173: { ! 2174: int old_brace_level; ! 2175: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 2176: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 2177: start_brace (); ! 2178: printf ("\tint ru = (src >> 6) & 7;\n"); ! 2179: printf ("\tint rc = src & 7;\n"); ! 2180: genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, rc)", "dst"); ! 2181: printf ("\tif (GET_ZFLG)"); ! 2182: old_brace_level = n_braces; ! 2183: start_brace (); ! 2184: genastore ("(m68k_dreg(regs, ru))", curi->dmode, "dstreg", curi->size, "dst"); ! 2185: pop_braces (old_brace_level); ! 2186: printf ("else"); ! 2187: start_brace (); ! 2188: printf ("m68k_dreg(regs, rc) = dst;\n"); ! 2189: pop_braces (old_brace_level); ! 2190: } ! 2191: break; ! 2192: case i_CAS2: ! 2193: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2194: printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n"); ! 2195: printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n"); ! 2196: if (curi->size == sz_word) { ! 2197: int old_brace_level = n_braces; ! 2198: printf ("\tuae_u16 dst1 = get_word(rn1), dst2 = get_word(rn2);\n"); ! 2199: genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1"); ! 2200: printf ("\tif (GET_ZFLG) {\n"); ! 2201: genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, extra & 7)", "dst2"); ! 2202: printf ("\tif (GET_ZFLG) {\n"); ! 2203: printf ("\tput_word(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n"); ! 2204: printf ("\tput_word(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n"); ! 2205: printf ("\t}}\n"); ! 2206: pop_braces (old_brace_level); ! 2207: printf ("\tif (! GET_ZFLG) {\n"); ! 2208: printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = (m68k_dreg(regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n"); ! 2209: printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = (m68k_dreg(regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n"); ! 2210: printf ("\t}\n"); ! 2211: } else { ! 2212: int old_brace_level = n_braces; ! 2213: printf ("\tuae_u32 dst1 = get_long(rn1), dst2 = get_long(rn2);\n"); ! 2214: genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1"); ! 2215: printf ("\tif (GET_ZFLG) {\n"); ! 2216: genflags (flag_cmp, curi->size, "newv", "m68k_dreg(regs, extra & 7)", "dst2"); ! 2217: printf ("\tif (GET_ZFLG) {\n"); ! 2218: printf ("\tput_long(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n"); ! 2219: printf ("\tput_long(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n"); ! 2220: printf ("\t}}\n"); ! 2221: pop_braces (old_brace_level); ! 2222: printf ("\tif (! GET_ZFLG) {\n"); ! 2223: printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = dst1;\n"); ! 2224: printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = dst2;\n"); ! 2225: printf ("\t}\n"); ! 2226: } ! 2227: break; ! 2228: case i_MOVES: /* ignore DFC and SFC because we have no MMU */ ! 2229: { ! 2230: int old_brace_level; ! 2231: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2232: printf ("\tif (extra & 0x800)\n"); ! 2233: old_brace_level = n_braces; ! 2234: start_brace (); ! 2235: printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n"); ! 2236: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 2237: genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 2238: pop_braces (old_brace_level); ! 2239: printf ("else"); ! 2240: start_brace (); ! 2241: genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0); ! 2242: printf ("\tif (extra & 0x8000) {\n"); ! 2243: switch (curi->size) { ! 2244: case sz_byte: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break; ! 2245: case sz_word: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break; ! 2246: case sz_long: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = src;\n"); break; ! 2247: default: abort (); ! 2248: } ! 2249: printf ("\t} else {\n"); ! 2250: genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, ""); ! 2251: printf ("\t}\n"); ! 2252: pop_braces (old_brace_level); ! 2253: } ! 2254: break; ! 2255: case i_BKPT: /* only needed for hardware emulators */ ! 2256: sync_m68k_pc (); ! 2257: printf ("\top_illg(opcode);\n"); ! 2258: break; ! 2259: case i_CALLM: /* not present in 68030 */ ! 2260: sync_m68k_pc (); ! 2261: printf ("\top_illg(opcode);\n"); ! 2262: break; ! 2263: case i_RTM: /* not present in 68030 */ ! 2264: sync_m68k_pc (); ! 2265: printf ("\top_illg(opcode);\n"); ! 2266: break; ! 2267: case i_TRAPcc: ! 2268: if (curi->smode != am_unknown && curi->smode != am_illg) ! 2269: genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0); ! 2270: printf ("\tif (cctrue(%d)) { Exception(7,m68k_getpc(),M68000_EXC_SRC_CPU); goto %s; }\n", curi->cc, endlabelstr); ! 2271: need_endlabel = 1; ! 2272: break; ! 2273: case i_DIVL: ! 2274: sync_m68k_pc (); ! 2275: start_brace (); ! 2276: printf ("\tuaecptr oldpc = m68k_getpc();\n"); ! 2277: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2278: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 2279: sync_m68k_pc (); ! 2280: printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n"); ! 2281: break; ! 2282: case i_MULL: ! 2283: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2284: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 2285: sync_m68k_pc (); ! 2286: printf ("\tm68k_mull(opcode, dst, extra);\n"); ! 2287: break; ! 2288: case i_BFTST: ! 2289: case i_BFEXTU: ! 2290: case i_BFCHG: ! 2291: case i_BFEXTS: ! 2292: case i_BFCLR: ! 2293: case i_BFFFO: ! 2294: case i_BFSET: ! 2295: case i_BFINS: ! 2296: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2297: genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0); ! 2298: start_brace (); ! 2299: printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n"); ! 2300: printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n"); ! 2301: if (curi->dmode == Dreg) { ! 2302: printf ("\tuae_u32 tmp = m68k_dreg(regs, dstreg) << (offset & 0x1f);\n"); ! 2303: } else { ! 2304: printf ("\tuae_u32 tmp,bf0,bf1;\n"); ! 2305: printf ("\tdsta += (offset >> 3) | (offset & 0x80000000 ? ~0x1fffffff : 0);\n"); ! 2306: printf ("\tbf0 = get_long(dsta);bf1 = get_byte(dsta+4) & 0xff;\n"); ! 2307: printf ("\ttmp = (bf0 << (offset & 7)) | (bf1 >> (8 - (offset & 7)));\n"); ! 2308: } ! 2309: printf ("\ttmp >>= (32 - width);\n"); ! 2310: printf ("\tSET_NFLG (tmp & (1 << (width-1)) ? 1 : 0);\n"); ! 2311: printf ("\tSET_ZFLG (tmp == 0); SET_VFLG (0); SET_CFLG (0);\n"); ! 2312: switch (curi->mnemo) { ! 2313: case i_BFTST: ! 2314: break; ! 2315: case i_BFEXTU: ! 2316: printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n"); ! 2317: break; ! 2318: case i_BFCHG: ! 2319: printf ("\ttmp = ~tmp;\n"); ! 2320: break; ! 2321: case i_BFEXTS: ! 2322: printf ("\tif (GET_NFLG) tmp |= width == 32 ? 0 : (-1 << width);\n"); ! 2323: printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n"); ! 2324: break; ! 2325: case i_BFCLR: ! 2326: printf ("\ttmp = 0;\n"); ! 2327: break; ! 2328: case i_BFFFO: ! 2329: printf ("\t{ uae_u32 mask = 1 << (width-1);\n"); ! 2330: printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n"); ! 2331: printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = offset;\n"); ! 2332: break; ! 2333: case i_BFSET: ! 2334: printf ("\ttmp = 0xffffffff;\n"); ! 2335: break; ! 2336: case i_BFINS: ! 2337: printf ("\ttmp = m68k_dreg(regs, (extra >> 12) & 7);\n"); ! 2338: printf ("\tSET_NFLG (tmp & (1 << (width - 1)) ? 1 : 0);\n"); ! 2339: printf ("\tSET_ZFLG (tmp == 0);\n"); ! 2340: break; ! 2341: default: ! 2342: break; ! 2343: } ! 2344: if (curi->mnemo == i_BFCHG ! 2345: || curi->mnemo == i_BFCLR ! 2346: || curi->mnemo == i_BFSET ! 2347: || curi->mnemo == i_BFINS) ! 2348: { ! 2349: printf ("\ttmp <<= (32 - width);\n"); ! 2350: if (curi->dmode == Dreg) { ! 2351: printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & ((offset & 0x1f) == 0 ? 0 :\n"); ! 2352: printf ("\t\t(0xffffffff << (32 - (offset & 0x1f))))) |\n"); ! 2353: printf ("\t\t(tmp >> (offset & 0x1f)) |\n"); ! 2354: printf ("\t\t(((offset & 0x1f) + width) >= 32 ? 0 :\n"); ! 2355: printf (" (m68k_dreg(regs, dstreg) & ((uae_u32)0xffffffff >> ((offset & 0x1f) + width))));\n"); ! 2356: } else { ! 2357: printf ("\tbf0 = (bf0 & (0xff000000 << (8 - (offset & 7)))) |\n"); ! 2358: printf ("\t\t(tmp >> (offset & 7)) |\n"); ! 2359: printf ("\t\t(((offset & 7) + width) >= 32 ? 0 :\n"); ! 2360: printf ("\t\t (bf0 & ((uae_u32)0xffffffff >> ((offset & 7) + width))));\n"); ! 2361: printf ("\tput_long(dsta,bf0 );\n"); ! 2362: printf ("\tif (((offset & 7) + width) > 32) {\n"); ! 2363: printf ("\t\tbf1 = (bf1 & (0xff >> (width - 32 + (offset & 7)))) |\n"); ! 2364: printf ("\t\t\t(tmp << (8 - (offset & 7)));\n"); ! 2365: printf ("\t\tput_byte(dsta+4,bf1);\n"); ! 2366: printf ("\t}\n"); ! 2367: } ! 2368: } ! 2369: break; ! 2370: case i_PACK: ! 2371: if (curi->smode == Dreg) { ! 2372: printf ("\tuae_u16 val = m68k_dreg(regs, srcreg) + %s;\n", gen_nextiword ()); ! 2373: printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n"); ! 2374: } else { ! 2375: printf ("\tuae_u16 val;\n"); ! 2376: printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n"); ! 2377: printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg));\n"); ! 2378: printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n"); ! 2379: printf ("\tval = (val | ((uae_u16)get_byte(m68k_areg(regs, srcreg)) << 8)) + %s;\n", gen_nextiword ()); ! 2380: printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n"); ! 2381: printf ("\tput_byte(m68k_areg(regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n"); ! 2382: } ! 2383: break; ! 2384: case i_UNPK: ! 2385: if (curi->smode == Dreg) { ! 2386: printf ("\tuae_u16 val = m68k_dreg(regs, srcreg);\n"); ! 2387: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ()); ! 2388: printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffff0000) | (val & 0xffff);\n"); ! 2389: } else { ! 2390: printf ("\tuae_u16 val;\n"); ! 2391: printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n"); ! 2392: printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg));\n"); ! 2393: printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ()); ! 2394: printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n"); ! 2395: printf ("\tput_byte(m68k_areg(regs, dstreg),val);\n"); ! 2396: printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n"); ! 2397: printf ("\tput_byte(m68k_areg(regs, dstreg),val >> 8);\n"); ! 2398: } ! 2399: break; ! 2400: case i_TAS: ! 2401: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 2402: genflags (flag_logical, curi->size, "src", "", ""); ! 2403: printf ("\tsrc |= 0x80;\n"); ! 2404: genastore ("src", curi->smode, "srcreg", curi->size, "src"); ! 2405: if( curi->smode!=Dreg ) insn_n_cycles += 2; ! 2406: break; ! 2407: case i_FPP: ! 2408: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2409: sync_m68k_pc (); ! 2410: printf ("\tfpp_opp(opcode,extra);\n"); ! 2411: break; ! 2412: case i_FDBcc: ! 2413: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2414: sync_m68k_pc (); ! 2415: printf ("\tfdbcc_opp(opcode,extra);\n"); ! 2416: break; ! 2417: case i_FScc: ! 2418: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2419: sync_m68k_pc (); ! 2420: printf ("\tfscc_opp(opcode,extra);\n"); ! 2421: break; ! 2422: case i_FTRAPcc: ! 2423: sync_m68k_pc (); ! 2424: start_brace (); ! 2425: printf ("\tuaecptr oldpc = m68k_getpc();\n"); ! 2426: if (curi->smode != am_unknown && curi->smode != am_illg) ! 2427: genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0); ! 2428: sync_m68k_pc (); ! 2429: printf ("\tftrapcc_opp(opcode,oldpc);\n"); ! 2430: break; ! 2431: case i_FBcc: ! 2432: sync_m68k_pc (); ! 2433: start_brace (); ! 2434: printf ("\tuaecptr pc = m68k_getpc();\n"); ! 2435: genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0); ! 2436: sync_m68k_pc (); ! 2437: printf ("\tfbcc_opp(opcode,pc,extra);\n"); ! 2438: break; ! 2439: case i_FSAVE: ! 2440: sync_m68k_pc (); ! 2441: printf ("\tfsave_opp(opcode);\n"); ! 2442: break; ! 2443: case i_FRESTORE: ! 2444: sync_m68k_pc (); ! 2445: printf ("\tfrestore_opp(opcode);\n"); ! 2446: break; ! 2447: ! 2448: case i_CINVL: ! 2449: case i_CINVP: ! 2450: case i_CINVA: ! 2451: case i_CPUSHL: ! 2452: case i_CPUSHP: ! 2453: case i_CPUSHA: ! 2454: break; ! 2455: case i_MOVE16: ! 2456: if ((opcode & 0xfff8) == 0xf620) { ! 2457: /* MOVE16 (Ax)+,(Ay)+ */ ! 2458: printf ("\tuaecptr mems = m68k_areg(regs, srcreg) & ~15, memd;\n"); ! 2459: printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword()); ! 2460: printf ("\tmemd = m68k_areg(regs, dstreg) & ~15;\n"); ! 2461: printf ("\tput_long(memd, get_long(mems));\n"); ! 2462: printf ("\tput_long(memd+4, get_long(mems+4));\n"); ! 2463: printf ("\tput_long(memd+8, get_long(mems+8));\n"); ! 2464: printf ("\tput_long(memd+12, get_long(mems+12));\n"); ! 2465: printf ("\tif (srcreg != dstreg)\n"); ! 2466: printf ("\tm68k_areg(regs, srcreg) += 16;\n"); ! 2467: printf ("\tm68k_areg(regs, dstreg) += 16;\n"); ! 2468: } else { ! 2469: /* Other variants */ ! 2470: genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2); ! 2471: genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2); ! 2472: printf ("\tmemsa &= ~15;\n"); ! 2473: printf ("\tmemda &= ~15;\n"); ! 2474: printf ("\tput_long(memda, get_long(memsa));\n"); ! 2475: printf ("\tput_long(memda+4, get_long(memsa+4));\n"); ! 2476: printf ("\tput_long(memda+8, get_long(memsa+8));\n"); ! 2477: printf ("\tput_long(memda+12, get_long(memsa+12));\n"); ! 2478: if ((opcode & 0xfff8) == 0xf600) ! 2479: printf ("\tm68k_areg(regs, srcreg) += 16;\n"); ! 2480: else if ((opcode & 0xfff8) == 0xf608) ! 2481: printf ("\tm68k_areg(regs, dstreg) += 16;\n"); ! 2482: } ! 2483: break; ! 2484: ! 2485: case i_MMUOP: ! 2486: genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0); ! 2487: sync_m68k_pc (); ! 2488: printf ("\tmmu_op(opcode,extra);\n"); ! 2489: break; ! 2490: default: ! 2491: abort (); ! 2492: break; ! 2493: } ! 2494: finish_braces (); ! 2495: sync_m68k_pc (); ! 2496: } ! 2497: ! 2498: static void generate_includes (FILE * f) ! 2499: { ! 2500: fprintf (f, "#include \"sysdeps.h\"\n"); ! 2501: fprintf (f, "#include \"hatari-glue.h\"\n"); ! 2502: fprintf (f, "#include \"maccess.h\"\n"); ! 2503: fprintf (f, "#include \"memory.h\"\n"); ! 2504: fprintf (f, "#include \"newcpu.h\"\n"); ! 2505: fprintf (f, "#include \"cputbl.h\"\n"); ! 2506: fprintf (f, "#define CPUFUNC(x) x##_ff\n" ! 2507: "#ifdef NOFLAGS\n" ! 2508: "#include \"noflags.h\"\n" ! 2509: "#endif\n"); ! 2510: } ! 2511: ! 2512: static int postfix; ! 2513: ! 2514: static void generate_one_opcode (int rp) ! 2515: { ! 2516: int i; ! 2517: uae_u16 smsk, dmsk; ! 2518: long int opcode = opcode_map[rp]; ! 2519: ! 2520: exactCpuCycles[0] = 0; /* Default: not used */ ! 2521: ! 2522: if (table68k[opcode].mnemo == i_ILLG ! 2523: || table68k[opcode].clev > cpu_level) ! 2524: return; ! 2525: ! 2526: for (i = 0; lookuptab[i].name[0]; i++) { ! 2527: if (table68k[opcode].mnemo == lookuptab[i].mnemo) ! 2528: break; ! 2529: } ! 2530: ! 2531: if (table68k[opcode].handler != -1) ! 2532: return; ! 2533: ! 2534: if (opcode_next_clev[rp] != cpu_level) { ! 2535: fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp], ! 2536: opcode, lookuptab[i].name); ! 2537: return; ! 2538: } ! 2539: fprintf (stblfile, "{ CPUFUNC(op_%lx_%d), 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name); ! 2540: fprintf (headerfile, "extern cpuop_func op_%lx_%d_nf;\n", opcode, postfix); ! 2541: fprintf (headerfile, "extern cpuop_func op_%lx_%d_ff;\n", opcode, postfix); ! 2542: printf ("unsigned long REGPARAM2 CPUFUNC(op_%lx_%d)(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name); ! 2543: ! 2544: switch (table68k[opcode].stype) { ! 2545: case 0: smsk = 7; break; ! 2546: case 1: smsk = 255; break; ! 2547: case 2: smsk = 15; break; ! 2548: case 3: smsk = 7; break; ! 2549: case 4: smsk = 7; break; ! 2550: case 5: smsk = 63; break; ! 2551: case 7: smsk = 3; break; ! 2552: default: abort (); ! 2553: } ! 2554: dmsk = 7; ! 2555: ! 2556: next_cpu_level = -1; ! 2557: if (table68k[opcode].suse ! 2558: && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 ! 2559: && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 ! 2560: && table68k[opcode].smode != absw && table68k[opcode].smode != absl ! 2561: && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) ! 2562: { ! 2563: if (table68k[opcode].spos == -1) { ! 2564: if (((int) table68k[opcode].sreg) >= 128) ! 2565: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); ! 2566: else ! 2567: printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg); ! 2568: } else { ! 2569: char source[100]; ! 2570: int pos = table68k[opcode].spos; ! 2571: ! 2572: if (pos) ! 2573: sprintf (source, "((opcode >> %d) & %d)", pos, smsk); ! 2574: else ! 2575: sprintf (source, "(opcode & %d)", smsk); ! 2576: ! 2577: if (table68k[opcode].stype == 3) ! 2578: printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source); ! 2579: else if (table68k[opcode].stype == 1) ! 2580: printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source); ! 2581: else ! 2582: printf ("\tuae_u32 srcreg = %s;\n", source); ! 2583: } ! 2584: } ! 2585: if (table68k[opcode].duse ! 2586: /* Yes, the dmode can be imm, in case of LINK or DBcc */ ! 2587: && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 ! 2588: && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 ! 2589: && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) ! 2590: { ! 2591: if (table68k[opcode].dpos == -1) { ! 2592: if (((int) table68k[opcode].dreg) >= 128) ! 2593: printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); ! 2594: else ! 2595: printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg); ! 2596: } else { ! 2597: int pos = table68k[opcode].dpos; ! 2598: #if 0 ! 2599: /* Check that we can do the little endian optimization safely. */ ! 2600: if (pos < 8 && (dmsk >> (8 - pos)) != 0) ! 2601: abort (); ! 2602: #endif ! 2603: if (pos) ! 2604: printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", ! 2605: pos, dmsk); ! 2606: else ! 2607: printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); ! 2608: } ! 2609: } ! 2610: need_endlabel = 0; ! 2611: endlabelno++; ! 2612: sprintf (endlabelstr, "endlabel%d", endlabelno); ! 2613: if(table68k[opcode].mnemo==i_ASR || table68k[opcode].mnemo==i_ASL || table68k[opcode].mnemo==i_LSR || table68k[opcode].mnemo==i_LSL ! 2614: || table68k[opcode].mnemo==i_ROL || table68k[opcode].mnemo==i_ROR || table68k[opcode].mnemo==i_ROXL || table68k[opcode].mnemo==i_ROXR ! 2615: || table68k[opcode].mnemo==i_MVMEL || table68k[opcode].mnemo==i_MVMLE ! 2616: || table68k[opcode].mnemo==i_MULU || table68k[opcode].mnemo==i_MULS ! 2617: || table68k[opcode].mnemo==i_DIVU || table68k[opcode].mnemo==i_DIVS ) ! 2618: printf("\tunsigned int retcycles = 0;\n"); ! 2619: gen_opcode (opcode); ! 2620: if (need_endlabel) ! 2621: printf ("%s: ;\n", endlabelstr); ! 2622: ! 2623: if (strlen(exactCpuCycles) > 0) ! 2624: printf("%s\n",exactCpuCycles); ! 2625: else ! 2626: printf ("return %d;\n", insn_n_cycles); ! 2627: /* Now patch in the instruction cycles at the beginning of the function: */ ! 2628: fseek(stdout, nCurInstrCycPos, SEEK_SET); ! 2629: printf("%d;", insn_n_cycles); ! 2630: fseek(stdout, 0, SEEK_END); ! 2631: ! 2632: printf ("}\n"); ! 2633: opcode_next_clev[rp] = next_cpu_level; ! 2634: opcode_last_postfix[rp] = postfix; ! 2635: } ! 2636: ! 2637: static void generate_func (void) ! 2638: { ! 2639: int i, j, rp; ! 2640: ! 2641: using_prefetch = 0; ! 2642: using_exception_3 = 0; ! 2643: for (i = 0; i < 6; i++) { ! 2644: cpu_level = 4 - i; ! 2645: if (i == 5) { ! 2646: cpu_level = 0; ! 2647: using_prefetch = 1; ! 2648: using_exception_3 = 1; ! 2649: for (rp = 0; rp < nr_cpuop_funcs; rp++) ! 2650: opcode_next_clev[rp] = 0; ! 2651: } ! 2652: ! 2653: postfix = i; ! 2654: fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix); ! 2655: ! 2656: /* sam: this is for people with low memory (eg. me :)) */ ! 2657: printf ("\n" ! 2658: "#if !defined(PART_1) && !defined(PART_2) && " ! 2659: "!defined(PART_3) && !defined(PART_4) && " ! 2660: "!defined(PART_5) && !defined(PART_6) && " ! 2661: "!defined(PART_7) && !defined(PART_8)" ! 2662: "\n" ! 2663: "#define PART_1 1\n" ! 2664: "#define PART_2 1\n" ! 2665: "#define PART_3 1\n" ! 2666: "#define PART_4 1\n" ! 2667: "#define PART_5 1\n" ! 2668: "#define PART_6 1\n" ! 2669: "#define PART_7 1\n" ! 2670: "#define PART_8 1\n" ! 2671: "#endif\n\n"); ! 2672: ! 2673: rp = 0; ! 2674: for(j=1;j<=8;++j) { ! 2675: int k = (j*nr_cpuop_funcs)/8; ! 2676: printf ("#ifdef PART_%d\n",j); ! 2677: for (; rp < k; rp++) ! 2678: generate_one_opcode (rp); ! 2679: printf ("#endif\n\n"); ! 2680: } ! 2681: ! 2682: fprintf (stblfile, "{ 0, 0, 0 }};\n"); ! 2683: } ! 2684: ! 2685: } ! 2686: ! 2687: int main (int argc, char **argv) ! 2688: { ! 2689: read_table68k (); ! 2690: do_merges (); ! 2691: ! 2692: opcode_map = (int *) malloc (sizeof (int) * nr_cpuop_funcs); ! 2693: opcode_last_postfix = (int *) malloc (sizeof (int) * nr_cpuop_funcs); ! 2694: opcode_next_clev = (int *) malloc (sizeof (int) * nr_cpuop_funcs); ! 2695: counts = (unsigned long *) malloc (65536 * sizeof (unsigned long)); ! 2696: read_counts (); ! 2697: ! 2698: /* It would be a lot nicer to put all in one file (we'd also get rid of ! 2699: * cputbl.h that way), but cpuopti can't cope. That could be fixed, but ! 2700: * I don't dare to touch the 68k version. */ ! 2701: ! 2702: headerfile = fopen ("cputbl.h", "wb"); ! 2703: stblfile = fopen ("cpustbl.c", "wb"); ! 2704: if (freopen ("cpuemu.c", "wb", stdout) == NULL) { ! 2705: perror("cpuemu.c"); ! 2706: return -1; ! 2707: } ! 2708: ! 2709: generate_includes (stdout); ! 2710: generate_includes (stblfile); ! 2711: ! 2712: generate_func (); ! 2713: ! 2714: free (table68k); ! 2715: return 0; ! 2716: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.