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