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