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