|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * MC68000 compilation generator ! 5: * ! 6: * Based on work Copyright 1995, 1996 Bernd Schmidt. Changes Copyright 2000 ! 7: * Bernd Meyer ! 8: */ ! 9: ! 10: #include "sysconfig.h" ! 11: #include "sysdeps.h" ! 12: #include <ctype.h> ! 13: ! 14: #include "readcpu.h" ! 15: ! 16: #include <stdio.h> ! 17: #include <stdarg.h> ! 18: ! 19: #define BOOL_TYPE "int" ! 20: #define failure global_failure=1 ! 21: #define FAILURE global_failure=1 ! 22: #define isjump global_isjump=1 ! 23: #define is_const_jump global_iscjump=1; ! 24: #define isaddx global_isaddx=1 ! 25: #define uses_cmov global_cmov=1 ! 26: #define mayfail global_mayfail=1 ! 27: ! 28: int hack_opcode; ! 29: ! 30: static int global_failure; ! 31: static int global_isjump; ! 32: static int global_iscjump; ! 33: static int global_isaddx; ! 34: static int global_cmov; ! 35: static int long_opcode; ! 36: static int global_mayfail; ! 37: ! 38: static char endstr[1000]; ! 39: static char lines[100000]; ! 40: static int comp_index=0; ! 41: ! 42: static int cond_codes_x86[]={-1,-1,7,6,3,2,5,4,-1,-1,9,8,13,12,15,14}; ! 43: ! 44: static void comprintf(const char* format, ...) ! 45: { ! 46: va_list args; ! 47: ! 48: va_start(args,format); ! 49: comp_index+=vsprintf(lines+comp_index,format,args); ! 50: } ! 51: ! 52: static void com_discard(void) ! 53: { ! 54: comp_index=0; ! 55: } ! 56: ! 57: static void com_flush(void) ! 58: { ! 59: int i; ! 60: for (i=0;i<comp_index;i++) ! 61: putchar(lines[i]); ! 62: com_discard(); ! 63: } ! 64: ! 65: ! 66: static FILE *headerfile; ! 67: static FILE *stblfile; ! 68: ! 69: static int using_prefetch; ! 70: static int using_exception_3; ! 71: static int cpu_level; ! 72: static int noflags; ! 73: ! 74: /* For the current opcode, the next lower level that will have different code. ! 75: * Initialized to -1 for each opcode. If it remains unchanged, indicates we ! 76: * are done with that opcode. */ ! 77: static int next_cpu_level; ! 78: ! 79: static int *opcode_map; ! 80: static int *opcode_next_clev; ! 81: static int *opcode_last_postfix; ! 82: static unsigned long *counts; ! 83: ! 84: static void ! 85: read_counts (void) ! 86: { ! 87: FILE *file; ! 88: unsigned long opcode, count = 0, total; ! 89: char name[20]; ! 90: int nr = 0; ! 91: memset (counts, 0, 65536 * sizeof *counts); ! 92: ! 93: file = fopen ("frequent.68k", "r"); ! 94: if (file) ! 95: { ! 96: fscanf (file, "Total: %lu\n", &total); ! 97: while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) ! 98: { ! 99: opcode_next_clev[nr] = 5; ! 100: opcode_last_postfix[nr] = -1; ! 101: opcode_map[nr++] = opcode; ! 102: counts[opcode] = count; ! 103: } ! 104: fclose (file); ! 105: } ! 106: if (nr == nr_cpuop_funcs) ! 107: return; ! 108: for (opcode = 0; opcode < 0x10000; opcode++) ! 109: { ! 110: if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG ! 111: && counts[opcode] == 0) ! 112: { ! 113: opcode_next_clev[nr] = 5; ! 114: opcode_last_postfix[nr] = -1; ! 115: opcode_map[nr++] = opcode; ! 116: counts[opcode] = count; ! 117: } ! 118: } ! 119: if (nr != nr_cpuop_funcs) ! 120: abort (); ! 121: } ! 122: ! 123: static int n_braces = 0; ! 124: static int insn_n_cycles; ! 125: ! 126: static void ! 127: start_brace (void) ! 128: { ! 129: n_braces++; ! 130: comprintf ("{"); ! 131: } ! 132: ! 133: static void ! 134: close_brace (void) ! 135: { ! 136: assert (n_braces > 0); ! 137: n_braces--; ! 138: comprintf ("}"); ! 139: } ! 140: ! 141: static void ! 142: finish_braces (void) ! 143: { ! 144: while (n_braces > 0) ! 145: close_brace (); ! 146: } ! 147: ! 148: static void ! 149: pop_braces (int to) ! 150: { ! 151: while (n_braces > to) ! 152: close_brace (); ! 153: } ! 154: ! 155: static int ! 156: bit_size (int size) ! 157: { ! 158: switch (size) ! 159: { ! 160: case sz_byte: ! 161: return 8; ! 162: case sz_word: ! 163: return 16; ! 164: case sz_long: ! 165: return 32; ! 166: default: ! 167: abort (); ! 168: } ! 169: return 0; ! 170: } ! 171: ! 172: static const char * ! 173: bit_mask (int size) ! 174: { ! 175: switch (size) ! 176: { ! 177: case sz_byte: ! 178: return "0xff"; ! 179: case sz_word: ! 180: return "0xffff"; ! 181: case sz_long: ! 182: return "0xffffffff"; ! 183: default: ! 184: abort (); ! 185: } ! 186: return 0; ! 187: } ! 188: ! 189: static __inline__ void gen_update_next_handler(void) ! 190: { ! 191: return; /* Can anything clever be done here? */ ! 192: } ! 193: ! 194: static void gen_writebyte (char* address, char* source) ! 195: { ! 196: comprintf("\twritebyte(%s,%s,scratchie);\n",address,source); ! 197: } ! 198: ! 199: static void gen_writeword (char* address, char* source) ! 200: { ! 201: comprintf("\twriteword(%s,%s,scratchie);\n",address,source); ! 202: } ! 203: ! 204: static void gen_writelong (char* address, char* source) ! 205: { ! 206: comprintf("\twritelong(%s,%s,scratchie);\n",address,source); ! 207: } ! 208: ! 209: static void gen_readbyte (char* address, char* dest) ! 210: { ! 211: comprintf("\treadbyte(%s,%s,scratchie);\n",address,dest); ! 212: } ! 213: ! 214: static void gen_readword (char* address, char* dest) ! 215: { ! 216: comprintf("\treadword(%s,%s,scratchie);\n",address,dest); ! 217: } ! 218: ! 219: static void gen_readlong (char* address, char* dest) ! 220: { ! 221: comprintf("\treadlong(%s,%s,scratchie);\n",address,dest); ! 222: } ! 223: ! 224: ! 225: ! 226: static const char * ! 227: gen_nextilong (void) ! 228: { ! 229: static char buffer[80]; ! 230: ! 231: sprintf (buffer, "comp_get_ilong((m68k_pc_offset+=4)-4)"); ! 232: insn_n_cycles += 4; ! 233: ! 234: long_opcode=1; ! 235: return buffer; ! 236: } ! 237: ! 238: static const char * ! 239: gen_nextiword (void) ! 240: { ! 241: static char buffer[80]; ! 242: ! 243: sprintf (buffer, "comp_get_iword((m68k_pc_offset+=2)-2)"); ! 244: insn_n_cycles+=2; ! 245: ! 246: long_opcode=1; ! 247: return buffer; ! 248: } ! 249: ! 250: static const char * ! 251: gen_nextibyte (void) ! 252: { ! 253: static char buffer[80]; ! 254: ! 255: sprintf (buffer, "comp_get_ibyte((m68k_pc_offset+=2)-2)"); ! 256: insn_n_cycles += 2; ! 257: ! 258: long_opcode=1; ! 259: return buffer; ! 260: } ! 261: ! 262: static void ! 263: sync_m68k_pc (void) ! 264: { ! 265: comprintf("\t if (m68k_pc_offset>100) sync_m68k_pc();\n"); ! 266: } ! 267: ! 268: ! 269: /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0, ! 270: * the calling routine handles Apdi and Aipi modes. */ ! 271: static void ! 272: genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem) ! 273: { ! 274: start_brace (); ! 275: switch (mode) ! 276: { ! 277: case Dreg: /* Do we need to check dodgy here? */ ! 278: if (movem) ! 279: abort (); ! 280: if (getv == 1 || getv==2) { ! 281: /* We generate the variable even for getv==2, so we can use ! 282: it as a destination for MOVE */ ! 283: comprintf ("\tint %s=%s;\n",name,reg); ! 284: } ! 285: return; ! 286: ! 287: case Areg: ! 288: if (movem) ! 289: abort (); ! 290: if (getv == 1 || getv==2) { ! 291: /* see above */ ! 292: comprintf ("\tint %s=dodgy?scratchie++:%s+8;\n",name,reg); ! 293: if (getv==1) { ! 294: comprintf ("\tif (dodgy) \n"); ! 295: comprintf ("\t\tmov_l_rr(%s,%s+8);\n",name, reg); ! 296: } ! 297: } ! 298: return; ! 299: ! 300: case Aind: ! 301: comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); ! 302: comprintf ("\tif (dodgy) \n"); ! 303: comprintf ("\t\tmov_l_rr(%sa,%s+8);\n",name, reg); ! 304: break; ! 305: case Aipi: ! 306: comprintf ("\tint %sa=scratchie++;\n",name,reg); ! 307: comprintf ("\tmov_l_rr(%sa,%s+8);\n",name, reg); ! 308: break; ! 309: case Apdi: ! 310: switch (size) ! 311: { ! 312: case sz_byte: ! 313: if (movem) { ! 314: comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); ! 315: comprintf ("\tif (dodgy) \n"); ! 316: comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); ! 317: } ! 318: else { ! 319: start_brace(); ! 320: comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); ! 321: comprintf("\tlea_l_brr(%s+8,%s+8,(uae_s32)-areg_byteinc[%s]);\n",reg,reg,reg); ! 322: comprintf ("\tif (dodgy) \n"); ! 323: comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); ! 324: } ! 325: break; ! 326: case sz_word: ! 327: if (movem) { ! 328: comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); ! 329: comprintf ("\tif (dodgy) \n"); ! 330: comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); ! 331: } ! 332: else { ! 333: start_brace(); ! 334: comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); ! 335: comprintf("\tlea_l_brr(%s+8,%s+8,-2);\n",reg,reg); ! 336: comprintf ("\tif (dodgy) \n"); ! 337: comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); ! 338: } ! 339: break; ! 340: case sz_long: ! 341: if (movem) { ! 342: comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); ! 343: comprintf ("\tif (dodgy) \n"); ! 344: comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); ! 345: } ! 346: else { ! 347: start_brace(); ! 348: comprintf ("\tint %sa=dodgy?scratchie++:%s+8;\n",name,reg); ! 349: comprintf("\tlea_l_brr(%s+8,%s+8,-4);\n",reg,reg); ! 350: comprintf ("\tif (dodgy) \n"); ! 351: comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); ! 352: } ! 353: break; ! 354: default: ! 355: abort (); ! 356: } ! 357: break; ! 358: case Ad16: ! 359: comprintf("\tint %sa=scratchie++;\n",name); ! 360: comprintf("\tmov_l_rr(%sa,8+%s);\n",name,reg); ! 361: comprintf("\tlea_l_brr(%sa,%sa,(uae_s32)(uae_s16)%s);\n",name,name,gen_nextiword()); ! 362: break; ! 363: case Ad8r: ! 364: comprintf("\tint %sa=scratchie++;\n",name); ! 365: comprintf("\tcalc_disp_ea_020(%s+8,%s,%sa,scratchie);\n", ! 366: reg,gen_nextiword(),name); ! 367: break; ! 368: ! 369: case PC16: ! 370: comprintf("\tint %sa=scratchie++;\n",name); ! 371: comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); ! 372: comprintf ("\tuae_s32 PC16off = (uae_s32)(uae_s16)%s;\n", gen_nextiword ()); ! 373: comprintf("\tmov_l_ri(%sa,address+PC16off);\n",name); ! 374: break; ! 375: ! 376: case PC8r: ! 377: comprintf("\tint pctmp=scratchie++;\n"); ! 378: comprintf("\tint %sa=scratchie++;\n",name); ! 379: comprintf("\tuae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); ! 380: start_brace(); ! 381: comprintf("\tmov_l_ri(pctmp,address);\n"); ! 382: ! 383: comprintf("\tcalc_disp_ea_020(pctmp,%s,%sa,scratchie);\n", ! 384: gen_nextiword(),name); ! 385: break; ! 386: case absw: ! 387: comprintf ("\tint %sa = scratchie++;\n",name); ! 388: comprintf ("\tmov_l_ri(%sa,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); ! 389: break; ! 390: case absl: ! 391: comprintf ("\tint %sa = scratchie++;\n",name); ! 392: comprintf ("\tmov_l_ri(%sa,%s); /* absl */\n", name, gen_nextilong ()); ! 393: break; ! 394: case imm: ! 395: if (getv != 1) ! 396: abort (); ! 397: switch (size) ! 398: { ! 399: case sz_byte: ! 400: comprintf ("\tint %s = scratchie++;\n",name); ! 401: comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ()); ! 402: break; ! 403: case sz_word: ! 404: comprintf ("\tint %s = scratchie++;\n",name); ! 405: comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); ! 406: break; ! 407: case sz_long: ! 408: comprintf ("\tint %s = scratchie++;\n",name); ! 409: comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ()); ! 410: break; ! 411: default: ! 412: abort (); ! 413: } ! 414: return; ! 415: case imm0: ! 416: if (getv != 1) ! 417: abort (); ! 418: comprintf ("\tint %s = scratchie++;\n",name); ! 419: comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s8)%s);\n", name, gen_nextibyte ()); ! 420: return; ! 421: case imm1: ! 422: if (getv != 1) ! 423: abort (); ! 424: comprintf ("\tint %s = scratchie++;\n",name); ! 425: comprintf ("\tmov_l_ri(%s,(uae_s32)(uae_s16)%s);\n", name, gen_nextiword ()); ! 426: return; ! 427: case imm2: ! 428: if (getv != 1) ! 429: abort (); ! 430: comprintf ("\tint %s = scratchie++;\n",name); ! 431: comprintf ("\tmov_l_ri(%s,%s);\n", name, gen_nextilong ()); ! 432: return; ! 433: case immi: ! 434: if (getv != 1) ! 435: abort (); ! 436: comprintf ("\tint %s = scratchie++;\n",name); ! 437: comprintf ("\tmov_l_ri(%s,%s);\n", name, reg); ! 438: return; ! 439: default: ! 440: abort (); ! 441: } ! 442: ! 443: /* We get here for all non-reg non-immediate addressing modes to ! 444: * actually fetch the value. */ ! 445: if (getv == 1) ! 446: { ! 447: char astring[80]; ! 448: sprintf(astring,"%sa",name); ! 449: switch (size) ! 450: { ! 451: case sz_byte: ! 452: insn_n_cycles += 2; ! 453: break; ! 454: case sz_word: ! 455: insn_n_cycles += 2; ! 456: break; ! 457: case sz_long: ! 458: insn_n_cycles += 4; ! 459: break; ! 460: default: ! 461: abort (); ! 462: } ! 463: start_brace (); ! 464: comprintf("\tint %s=scratchie++;\n",name); ! 465: switch (size) ! 466: { ! 467: case sz_byte: ! 468: gen_readbyte(astring,name); ! 469: break; ! 470: case sz_word: ! 471: gen_readword(astring,name); ! 472: break; ! 473: case sz_long: ! 474: gen_readlong(astring,name); ! 475: break; ! 476: default: ! 477: abort (); ! 478: } ! 479: } ! 480: ! 481: /* We now might have to fix up the register for pre-dec or post-inc ! 482: * addressing modes. */ ! 483: if (!movem) { ! 484: switch (mode) ! 485: { ! 486: case Aipi: ! 487: switch (size) ! 488: { ! 489: case sz_byte: ! 490: comprintf("\tlea_l_brr(%s+8,%s+8,areg_byteinc[%s]);\n",reg,reg,reg); ! 491: break; ! 492: case sz_word: ! 493: comprintf("\tlea_l_brr(%s+8,%s+8,2);\n",reg,reg,reg); ! 494: break; ! 495: case sz_long: ! 496: comprintf("\tlea_l_brr(%s+8,%s+8,4);\n",reg,reg); ! 497: break; ! 498: default: ! 499: abort (); ! 500: } ! 501: break; ! 502: case Apdi: ! 503: break; ! 504: default: ! 505: break; ! 506: } ! 507: } ! 508: } ! 509: ! 510: static void ! 511: genastore (char *from, amodes mode, char *reg, wordsizes size, char *to) ! 512: { ! 513: switch (mode) ! 514: { ! 515: case Dreg: ! 516: switch (size) ! 517: { ! 518: case sz_byte: ! 519: comprintf("\tif(%s!=%s)\n",reg,from); ! 520: comprintf ("\t\tmov_b_rr(%s,%s);\n", reg, from); ! 521: break; ! 522: case sz_word: ! 523: comprintf("\tif(%s!=%s)\n",reg,from); ! 524: comprintf ("\t\tmov_w_rr(%s,%s);\n", reg, from); ! 525: break; ! 526: case sz_long: ! 527: comprintf("\tif(%s!=%s)\n",reg,from); ! 528: comprintf ("\t\tmov_l_rr(%s,%s);\n", reg, from); ! 529: break; ! 530: default: ! 531: abort (); ! 532: } ! 533: break; ! 534: case Areg: ! 535: switch (size) ! 536: { ! 537: case sz_word: ! 538: comprintf("\tif(%s+8!=%s)\n",reg,from); ! 539: comprintf ("\t\tmov_w_rr(%s+8,%s);\n", reg, from); ! 540: break; ! 541: case sz_long: ! 542: comprintf("\tif(%s+8!=%s)\n",reg,from); ! 543: comprintf ("\t\tmov_l_rr(%s+8,%s);\n", reg, from); ! 544: break; ! 545: default: ! 546: abort (); ! 547: } ! 548: break; ! 549: ! 550: case Apdi: ! 551: case absw: ! 552: case PC16: ! 553: case PC8r: ! 554: case Ad16: ! 555: case Ad8r: ! 556: case Aipi: ! 557: case Aind: ! 558: case absl: ! 559: { ! 560: char astring[80]; ! 561: sprintf(astring,"%sa",to); ! 562: ! 563: switch (size) ! 564: { ! 565: case sz_byte: ! 566: insn_n_cycles += 2; ! 567: gen_writebyte(astring,from); ! 568: break; ! 569: case sz_word: ! 570: insn_n_cycles += 2; ! 571: gen_writeword(astring,from); ! 572: break; ! 573: case sz_long: ! 574: insn_n_cycles += 4; ! 575: gen_writelong(astring,from); ! 576: break; ! 577: default: ! 578: abort (); ! 579: } ! 580: } ! 581: break; ! 582: case imm: ! 583: case imm0: ! 584: case imm1: ! 585: case imm2: ! 586: case immi: ! 587: abort (); ! 588: break; ! 589: default: ! 590: abort (); ! 591: } ! 592: } ! 593: static void genmov16(uae_u32 opcode, struct instr *curi) ! 594: { ! 595: comprintf("\tint src=scratchie++;\n"); ! 596: comprintf("\tint dst=scratchie++;\n"); ! 597: ! 598: if ((opcode & 0xfff8) == 0xf620) { ! 599: /* MOVE16 (Ax)+,(Ay)+ */ ! 600: comprintf("\tuae_u16 dstreg=((%s)>>12)&0x07;\n", gen_nextiword()); ! 601: comprintf("\tmov_l_rr(src,8+srcreg);\n"); ! 602: comprintf("\tmov_l_rr(dst,8+dstreg);\n"); ! 603: } else { ! 604: /* Other variants */ ! 605: genamode (curi->smode, "srcreg", curi->size, "src", 0, 2); ! 606: genamode (curi->dmode, "dstreg", curi->size, "dst", 0, 2); ! 607: comprintf("\tmov_l_rr(src,srca);\n"); ! 608: comprintf("\tmov_l_rr(dst,dsta);\n"); ! 609: } ! 610: ! 611: /* Align on 16-byte boundaries */ ! 612: comprintf("\tand_l_ri(src,~15);\n"); ! 613: comprintf("\tand_l_ri(dst,~15);\n"); ! 614: ! 615: ! 616: if ((opcode & 0xfff8) == 0xf620) { ! 617: comprintf("\tif (srcreg != dstreg)\n"); ! 618: comprintf("\tadd_l_ri(srcreg+8,16);\n"); ! 619: comprintf("\tadd_l_ri(dstreg+8,16);\n"); ! 620: } else if ((opcode & 0xfff8) == 0xf600) ! 621: comprintf("\tadd_l_ri(srcreg+8,16);\n"); ! 622: else if ((opcode & 0xfff8) == 0xf608) ! 623: comprintf("\tadd_l_ri(dstreg+8,16);\n"); ! 624: ! 625: comprintf("\tif (special_mem) {\n"); ! 626: comprintf("\t\tint tmp=scratchie;\n"); ! 627: comprintf("\tscratchie+=4;\n" ! 628: "\treadlong(src,tmp,scratchie);\n" ! 629: "\twritelong_clobber(dst,tmp,scratchie);\n" ! 630: "\tadd_l_ri(src,4);\n" ! 631: "\tadd_l_ri(dst,4);\n" ! 632: "\treadlong(src,tmp,scratchie);\n" ! 633: "\twritelong_clobber(dst,tmp,scratchie);\n" ! 634: "\tadd_l_ri(src,4);\n" ! 635: "\tadd_l_ri(dst,4);\n" ! 636: "\treadlong(src,tmp,scratchie);\n" ! 637: "\twritelong_clobber(dst,tmp,scratchie);\n" ! 638: "\tadd_l_ri(src,4);\n" ! 639: "\tadd_l_ri(dst,4);\n" ! 640: "\treadlong(src,tmp,scratchie);\n" ! 641: "\twritelong_clobber(dst,tmp,scratchie);\n"); ! 642: comprintf("\t} else {\n"); ! 643: comprintf("\t\tint tmp=scratchie;\n"); ! 644: comprintf("\tscratchie+=4;\n"); ! 645: comprintf("\tget_n_addr(src,src,scratchie);\n" ! 646: "\tget_n_addr(dst,dst,scratchie);\n" ! 647: "\tmov_l_rR(tmp+0,src,0);\n" ! 648: "\tmov_l_rR(tmp+1,src,4);\n" ! 649: "\tmov_l_rR(tmp+2,src,8);\n" ! 650: "\tmov_l_rR(tmp+3,src,12);\n" ! 651: "\tmov_l_Rr(dst,tmp+0,0);\n" ! 652: "\tforget_about(tmp+0);\n" ! 653: "\tmov_l_Rr(dst,tmp+1,4);\n" ! 654: "\tforget_about(tmp+1);\n" ! 655: "\tmov_l_Rr(dst,tmp+2,8);\n" ! 656: "\tforget_about(tmp+2);\n" ! 657: "\tmov_l_Rr(dst,tmp+3,12);\t}\n"); ! 658: ! 659: } ! 660: ! 661: #if 0 ! 662: static void genmov16(void) ! 663: { ! 664: comprintf("\tint src=scratchie++;\n" ! 665: "\tuae_u16 dstreg=((%s)>>12)&0x07;\n",gen_nextiword()); ! 666: comprintf("\tint dst=scratchie++;\n" ! 667: "\tint tmp=scratchie;\n" ! 668: "\tscratchie+=4;\n" ! 669: "\tmov_l_rr(src,8+srcreg);\n" ! 670: "\tand_l_ri(src,~15);\n" ! 671: "\tmov_l_rr(dst,8+dstreg);\n" ! 672: "\tand_l_ri(dst,~15);\n" ! 673: "\tadd_l_ri(srcreg+8,16);\n" ! 674: "\tadd_l_ri(dstreg+8,16);\n"); ! 675: ! 676: comprintf("\tif (special_mem) {\n" ! 677: "\treadlong(src,tmp,scratchie);\n" ! 678: "\twritelong_clobber(dst,tmp,scratchie);\n" ! 679: "\tadd_l_ri(src,4);\n" ! 680: "\tadd_l_ri(dst,4);\n" ! 681: "\treadlong(src,tmp,scratchie);\n" ! 682: "\twritelong_clobber(dst,tmp,scratchie);\n" ! 683: "\tadd_l_ri(src,4);\n" ! 684: "\tadd_l_ri(dst,4);\n" ! 685: "\treadlong(src,tmp,scratchie);\n" ! 686: "\twritelong_clobber(dst,tmp,scratchie);\n" ! 687: "\tadd_l_ri(src,4);\n" ! 688: "\tadd_l_ri(dst,4);\n" ! 689: "\treadlong(src,tmp,scratchie);\n" ! 690: "\twritelong_clobber(dst,tmp,scratchie);\n"); ! 691: comprintf("\t} else {\n"); ! 692: comprintf("\tget_n_addr(src,src,scratchie);\n" ! 693: "\tget_n_addr(dst,dst,scratchie);\n" ! 694: "\tmov_l_rR(tmp+0,src,0);\n" ! 695: "\tmov_l_rR(tmp+1,src,4);\n" ! 696: "\tmov_l_rR(tmp+2,src,8);\n" ! 697: "\tmov_l_rR(tmp+3,src,12);\n" ! 698: "\tmov_l_Rr(dst,tmp+0,0);\n" ! 699: "\tforget_about(tmp+0);\n" ! 700: "\tmov_l_Rr(dst,tmp+1,4);\n" ! 701: "\tforget_about(tmp+1);\n" ! 702: "\tmov_l_Rr(dst,tmp+2,8);\n" ! 703: "\tforget_about(tmp+2);\n" ! 704: "\tmov_l_Rr(dst,tmp+3,12);\n" ! 705: "\t}\n"); ! 706: } ! 707: #endif ! 708: ! 709: static void ! 710: genmovemel (uae_u16 opcode) ! 711: { ! 712: comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); ! 713: comprintf ("\tint native=scratchie++;\n"); ! 714: comprintf ("\tint i;\n"); ! 715: comprintf ("\tint offset=0;\n"); ! 716: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); ! 717: comprintf("\tif (1 && !special_mem) {\n"); ! 718: ! 719: /* Fast but unsafe... */ ! 720: comprintf("\tget_n_addr(srca,native,scratchie);\n"); ! 721: ! 722: ! 723: comprintf("\tfor (i=0;i<16;i++) {\n" ! 724: "\t\tif ((mask>>i)&1) {\n"); ! 725: switch(table68k[opcode].size) { ! 726: case sz_long: ! 727: comprintf("\t\t\tmov_l_rR(i,native,offset);\n" ! 728: "\t\t\tgen_bswap_32(i);\n" ! 729: "\t\t\toffset+=4;\n"); ! 730: break; ! 731: case sz_word: ! 732: comprintf("\t\t\tmov_w_rR(i,native,offset);\n" ! 733: "\t\t\tgen_bswap_16(i);\n" ! 734: "\t\t\tsign_extend_16_rr(i,i);\n" ! 735: "\t\t\toffset+=2;\n"); ! 736: break; ! 737: default: abort(); ! 738: } ! 739: comprintf("\t\t}\n" ! 740: "\t}"); ! 741: if (table68k[opcode].dmode == Aipi) { ! 742: comprintf("\t\t\tlea_l_brr(8+dstreg,srca,offset);\n"); ! 743: } ! 744: /* End fast but unsafe. */ ! 745: ! 746: comprintf("\t} else {\n"); ! 747: ! 748: comprintf ("\tint tmp=scratchie++;\n"); ! 749: ! 750: comprintf("\tmov_l_rr(tmp,srca);\n"); ! 751: comprintf("\tfor (i=0;i<16;i++) {\n" ! 752: "\t\tif ((mask>>i)&1) {\n"); ! 753: switch(table68k[opcode].size) { ! 754: case sz_long: ! 755: comprintf("\t\t\treadlong(tmp,i,scratchie);\n" ! 756: "\t\t\tadd_l_ri(tmp,4);\n"); ! 757: break; ! 758: case sz_word: ! 759: comprintf("\t\t\treadword(tmp,i,scratchie);\n" ! 760: "\t\t\tadd_l_ri(tmp,2);\n"); ! 761: break; ! 762: default: abort(); ! 763: } ! 764: ! 765: comprintf("\t\t}\n" ! 766: "\t}"); ! 767: if (table68k[opcode].dmode == Aipi) { ! 768: comprintf("\t\t\tmov_l_rr(8+dstreg,tmp);\n"); ! 769: } ! 770: comprintf("\t}\n"); ! 771: ! 772: } ! 773: ! 774: ! 775: static void ! 776: genmovemle (uae_u16 opcode) ! 777: { ! 778: comprintf ("\tuae_u16 mask = %s;\n", gen_nextiword ()); ! 779: comprintf ("\tint native=scratchie++;\n"); ! 780: comprintf ("\tint i;\n"); ! 781: comprintf ("\tint tmp=scratchie++;\n"); ! 782: comprintf ("\tsigned char offset=0;\n"); ! 783: genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1); ! 784: ! 785: /* *Sigh* Some clever geek realized that the fastest way to copy a ! 786: buffer from main memory to the gfx card is by using movmle. Good ! 787: on her, but unfortunately, gfx mem isn't "real" mem, and thus that ! 788: act of cleverness means that movmle must pay attention to special_mem, ! 789: or Genetic Species is a rather boring-looking game ;-) */ ! 790: comprintf("\tif (1 && !special_mem) {\n"); ! 791: comprintf("\tget_n_addr(srca,native,scratchie);\n"); ! 792: ! 793: if (table68k[opcode].dmode!=Apdi) { ! 794: comprintf("\tfor (i=0;i<16;i++) {\n" ! 795: "\t\tif ((mask>>i)&1) {\n"); ! 796: switch(table68k[opcode].size) { ! 797: case sz_long: ! 798: comprintf("\t\t\tmov_l_rr(tmp,i);\n" ! 799: "\t\t\tgen_bswap_32(tmp);\n" ! 800: "\t\t\tmov_l_Rr(native,tmp,offset);\n" ! 801: "\t\t\toffset+=4;\n"); ! 802: break; ! 803: case sz_word: ! 804: comprintf("\t\t\tmov_l_rr(tmp,i);\n" ! 805: "\t\t\tgen_bswap_16(tmp);\n" ! 806: "\t\t\tmov_w_Rr(native,tmp,offset);\n" ! 807: "\t\t\toffset+=2;\n"); ! 808: break; ! 809: default: abort(); ! 810: } ! 811: } else { /* Pre-decrement */ ! 812: comprintf("\tfor (i=0;i<16;i++) {\n" ! 813: "\t\tif ((mask>>i)&1) {\n"); ! 814: switch(table68k[opcode].size) { ! 815: case sz_long: ! 816: comprintf("\t\t\toffset-=4;\n" ! 817: "\t\t\tmov_l_rr(tmp,15-i);\n" ! 818: "\t\t\tgen_bswap_32(tmp);\n" ! 819: "\t\t\tmov_l_Rr(native,tmp,offset);\n" ! 820: ); ! 821: break; ! 822: case sz_word: ! 823: comprintf("\t\t\toffset-=2;\n" ! 824: "\t\t\tmov_l_rr(tmp,15-i);\n" ! 825: "\t\t\tgen_bswap_16(tmp);\n" ! 826: "\t\t\tmov_w_Rr(native,tmp,offset);\n" ! 827: ); ! 828: break; ! 829: default: abort(); ! 830: } ! 831: } ! 832: ! 833: comprintf("\t\t}\n" ! 834: "\t}"); ! 835: if (table68k[opcode].dmode == Apdi) { ! 836: comprintf("\t\t\tlea_l_brr(8+dstreg,srca,(uae_s32)offset);\n"); ! 837: } ! 838: comprintf("\t} else {\n"); ! 839: ! 840: if (table68k[opcode].dmode!=Apdi) { ! 841: comprintf("\tmov_l_rr(tmp,srca);\n"); ! 842: comprintf("\tfor (i=0;i<16;i++) {\n" ! 843: "\t\tif ((mask>>i)&1) {\n"); ! 844: switch(table68k[opcode].size) { ! 845: case sz_long: ! 846: comprintf("\t\t\twritelong(tmp,i,scratchie);\n" ! 847: "\t\t\tadd_l_ri(tmp,4);\n"); ! 848: break; ! 849: case sz_word: ! 850: comprintf("\t\t\twriteword(tmp,i,scratchie);\n" ! 851: "\t\t\tadd_l_ri(tmp,2);\n"); ! 852: break; ! 853: default: abort(); ! 854: } ! 855: } ! 856: else { /* Pre-decrement */ ! 857: comprintf("\tfor (i=0;i<16;i++) {\n" ! 858: "\t\tif ((mask>>i)&1) {\n"); ! 859: switch(table68k[opcode].size) { ! 860: case sz_long: ! 861: comprintf("\t\t\tsub_l_ri(srca,4);\n" ! 862: "\t\t\twritelong(srca,15-i,scratchie);\n"); ! 863: break; ! 864: case sz_word: ! 865: comprintf("\t\t\tsub_l_ri(srca,2);\n" ! 866: "\t\t\twriteword(srca,15-i,scratchie);\n"); ! 867: break; ! 868: default: abort(); ! 869: } ! 870: } ! 871: ! 872: ! 873: comprintf("\t\t}\n" ! 874: "\t}"); ! 875: if (table68k[opcode].dmode == Apdi) { ! 876: comprintf("\t\t\tmov_l_rr(8+dstreg,srca);\n"); ! 877: } ! 878: comprintf("\t}\n"); ! 879: } ! 880: ! 881: ! 882: static void ! 883: duplicate_carry (void) ! 884: { ! 885: comprintf ("\tif (needed_flags&FLAG_X) duplicate_carry();\n"); ! 886: } ! 887: ! 888: typedef enum ! 889: { ! 890: flag_logical_noclobber, flag_logical, flag_add, flag_sub, flag_cmp, ! 891: flag_addx, flag_subx, flag_zn, flag_av, flag_sv, flag_and, flag_or, ! 892: flag_eor, flag_mov ! 893: } ! 894: flagtypes; ! 895: ! 896: ! 897: static void ! 898: genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst) ! 899: { ! 900: if (noflags) { ! 901: switch(type) { ! 902: case flag_cmp: ! 903: comprintf("\tdont_care_flags();\n"); ! 904: comprintf("/* Weird --- CMP with noflags ;-) */\n"); ! 905: return; ! 906: case flag_add: ! 907: case flag_sub: ! 908: comprintf("\tdont_care_flags();\n"); ! 909: { ! 910: char* op; ! 911: switch(type) { ! 912: case flag_add: op="add"; break; ! 913: case flag_sub: op="sub"; break; ! 914: default: abort(); ! 915: } ! 916: switch (size) ! 917: { ! 918: case sz_byte: ! 919: comprintf("\t%s_b(%s,%s);\n",op,dst,src); ! 920: break; ! 921: case sz_word: ! 922: comprintf("\t%s_w(%s,%s);\n",op,dst,src); ! 923: break; ! 924: case sz_long: ! 925: comprintf("\t%s_l(%s,%s);\n",op,dst,src); ! 926: break; ! 927: } ! 928: return; ! 929: } ! 930: break; ! 931: ! 932: case flag_and: ! 933: comprintf("\tdont_care_flags();\n"); ! 934: switch (size) ! 935: { ! 936: case sz_byte: ! 937: comprintf("if (kill_rodent(dst)) {\n"); ! 938: comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); ! 939: comprintf("\tor_l_ri(scratchie,0xffffff00);\n"); ! 940: comprintf("\tand_l(%s,scratchie);\n",dst); ! 941: comprintf("\tforget_about(scratchie);\n"); ! 942: comprintf("\t} else \n" ! 943: "\tand_b(%s,%s);\n",dst,src); ! 944: break; ! 945: case sz_word: ! 946: comprintf("if (kill_rodent(dst)) {\n"); ! 947: comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); ! 948: comprintf("\tor_l_ri(scratchie,0xffff0000);\n"); ! 949: comprintf("\tand_l(%s,scratchie);\n",dst); ! 950: comprintf("\tforget_about(scratchie);\n"); ! 951: comprintf("\t} else \n" ! 952: "\tand_w(%s,%s);\n",dst,src); ! 953: break; ! 954: case sz_long: ! 955: comprintf("\tand_l(%s,%s);\n",dst,src); ! 956: break; ! 957: } ! 958: return; ! 959: ! 960: case flag_mov: ! 961: comprintf("\tdont_care_flags();\n"); ! 962: switch (size) ! 963: { ! 964: case sz_byte: ! 965: comprintf("if (kill_rodent(dst)) {\n"); ! 966: comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); ! 967: comprintf("\tand_l_ri(%s,0xffffff00);\n",dst); ! 968: comprintf("\tor_l(%s,scratchie);\n",dst); ! 969: comprintf("\tforget_about(scratchie);\n"); ! 970: comprintf("\t} else \n" ! 971: "\tmov_b_rr(%s,%s);\n",dst,src); ! 972: break; ! 973: case sz_word: ! 974: comprintf("if (kill_rodent(dst)) {\n"); ! 975: comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); ! 976: comprintf("\tand_l_ri(%s,0xffff0000);\n",dst); ! 977: comprintf("\tor_l(%s,scratchie);\n",dst); ! 978: comprintf("\tforget_about(scratchie);\n"); ! 979: comprintf("\t} else \n" ! 980: "\tmov_w_rr(%s,%s);\n",dst,src); ! 981: break; ! 982: case sz_long: ! 983: comprintf("\tmov_l_rr(%s,%s);\n",dst,src); ! 984: break; ! 985: } ! 986: return; ! 987: ! 988: case flag_or: ! 989: case flag_eor: ! 990: comprintf("\tdont_care_flags();\n"); ! 991: start_brace(); ! 992: { ! 993: char* op; ! 994: switch(type) { ! 995: case flag_or: op="or"; break; ! 996: case flag_eor: op="xor"; break; ! 997: default: abort(); ! 998: } ! 999: switch (size) ! 1000: { ! 1001: case sz_byte: ! 1002: comprintf("if (kill_rodent(dst)) {\n"); ! 1003: comprintf("\tzero_extend_8_rr(scratchie,%s);\n",src); ! 1004: comprintf("\t%s_l(%s,scratchie);\n",op,dst); ! 1005: comprintf("\tforget_about(scratchie);\n"); ! 1006: comprintf("\t} else \n" ! 1007: "\t%s_b(%s,%s);\n",op,dst,src); ! 1008: break; ! 1009: case sz_word: ! 1010: comprintf("if (kill_rodent(dst)) {\n"); ! 1011: comprintf("\tzero_extend_16_rr(scratchie,%s);\n",src); ! 1012: comprintf("\t%s_l(%s,scratchie);\n",op,dst); ! 1013: comprintf("\tforget_about(scratchie);\n"); ! 1014: comprintf("\t} else \n" ! 1015: "\t%s_w(%s,%s);\n",op,dst,src); ! 1016: break; ! 1017: case sz_long: ! 1018: comprintf("\t%s_l(%s,%s);\n",op,dst,src); ! 1019: break; ! 1020: } ! 1021: close_brace(); ! 1022: return; ! 1023: } ! 1024: ! 1025: ! 1026: case flag_addx: ! 1027: case flag_subx: ! 1028: ! 1029: comprintf("\tdont_care_flags();\n"); ! 1030: { ! 1031: char* op; ! 1032: switch(type) { ! 1033: case flag_addx: op="adc"; break; ! 1034: case flag_subx: op="sbb"; break; ! 1035: default: abort(); ! 1036: } ! 1037: comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ ! 1038: switch (size) ! 1039: { ! 1040: case sz_byte: ! 1041: comprintf("\t%s_b(%s,%s);\n",op,dst,src); ! 1042: break; ! 1043: case sz_word: ! 1044: comprintf("\t%s_w(%s,%s);\n",op,dst,src); ! 1045: break; ! 1046: case sz_long: ! 1047: comprintf("\t%s_l(%s,%s);\n",op,dst,src); ! 1048: break; ! 1049: } ! 1050: return; ! 1051: } ! 1052: break; ! 1053: default: return; ! 1054: } ! 1055: } ! 1056: ! 1057: /* Need the flags, but possibly not all of them */ ! 1058: switch (type) ! 1059: { ! 1060: case flag_logical_noclobber: ! 1061: failure; ! 1062: ! 1063: case flag_and: ! 1064: case flag_or: ! 1065: case flag_eor: ! 1066: comprintf("\tdont_care_flags();\n"); ! 1067: start_brace(); ! 1068: { ! 1069: char* op; ! 1070: switch(type) { ! 1071: case flag_and: op="and"; break; ! 1072: case flag_or: op="or"; break; ! 1073: case flag_eor: op="xor"; break; ! 1074: default: abort(); ! 1075: } ! 1076: switch (size) ! 1077: { ! 1078: case sz_byte: ! 1079: comprintf("\tstart_needflags();\n" ! 1080: "\t%s_b(%s,%s);\n",op,dst,src); ! 1081: break; ! 1082: case sz_word: ! 1083: comprintf("\tstart_needflags();\n" ! 1084: "\t%s_w(%s,%s);\n",op,dst,src); ! 1085: break; ! 1086: case sz_long: ! 1087: comprintf("\tstart_needflags();\n" ! 1088: "\t%s_l(%s,%s);\n",op,dst,src); ! 1089: break; ! 1090: } ! 1091: comprintf("\tlive_flags();\n"); ! 1092: comprintf("\tend_needflags();\n"); ! 1093: close_brace(); ! 1094: return; ! 1095: } ! 1096: ! 1097: case flag_mov: ! 1098: comprintf("\tdont_care_flags();\n"); ! 1099: start_brace(); ! 1100: { ! 1101: switch (size) ! 1102: { ! 1103: case sz_byte: ! 1104: comprintf("\tif (%s!=%s) {\n",src,dst); ! 1105: comprintf("\tmov_b_ri(%s,0);\n" ! 1106: "\tstart_needflags();\n",dst); ! 1107: comprintf("\tor_b(%s,%s);\n",dst,src); ! 1108: comprintf("\t} else {\n"); ! 1109: comprintf("\tmov_b_rr(%s,%s);\n",dst,src); ! 1110: comprintf("\ttest_b_rr(%s,%s);\n",dst,dst); ! 1111: comprintf("\t}\n"); ! 1112: break; ! 1113: case sz_word: ! 1114: comprintf("\tif (%s!=%s) {\n",src,dst); ! 1115: comprintf("\tmov_w_ri(%s,0);\n" ! 1116: "\tstart_needflags();\n",dst); ! 1117: comprintf("\tor_w(%s,%s);\n",dst,src); ! 1118: comprintf("\t} else {\n"); ! 1119: comprintf("\tmov_w_rr(%s,%s);\n",dst,src); ! 1120: comprintf("\ttest_w_rr(%s,%s);\n",dst,dst); ! 1121: comprintf("\t}\n"); ! 1122: break; ! 1123: case sz_long: ! 1124: comprintf("\tif (%s!=%s) {\n",src,dst); ! 1125: comprintf("\tmov_l_ri(%s,0);\n" ! 1126: "\tstart_needflags();\n",dst); ! 1127: comprintf("\tor_l(%s,%s);\n",dst,src); ! 1128: comprintf("\t} else {\n"); ! 1129: comprintf("\tmov_l_rr(%s,%s);\n",dst,src); ! 1130: comprintf("\ttest_l_rr(%s,%s);\n",dst,dst); ! 1131: comprintf("\t}\n"); ! 1132: break; ! 1133: } ! 1134: comprintf("\tlive_flags();\n"); ! 1135: comprintf("\tend_needflags();\n"); ! 1136: close_brace(); ! 1137: return; ! 1138: } ! 1139: ! 1140: case flag_logical: ! 1141: comprintf("\tdont_care_flags();\n"); ! 1142: start_brace(); ! 1143: switch (size) ! 1144: { ! 1145: case sz_byte: ! 1146: comprintf("\tstart_needflags();\n" ! 1147: "\ttest_b_rr(%s,%s);\n",value,value); ! 1148: break; ! 1149: case sz_word: ! 1150: comprintf("\tstart_needflags();\n" ! 1151: "\ttest_w_rr(%s,%s);\n",value,value); ! 1152: break; ! 1153: case sz_long: ! 1154: comprintf("\tstart_needflags();\n" ! 1155: "\ttest_l_rr(%s,%s);\n",value,value); ! 1156: break; ! 1157: } ! 1158: comprintf("\tlive_flags();\n"); ! 1159: comprintf("\tend_needflags();\n"); ! 1160: close_brace(); ! 1161: return; ! 1162: ! 1163: ! 1164: case flag_add: ! 1165: case flag_sub: ! 1166: case flag_cmp: ! 1167: comprintf("\tdont_care_flags();\n"); ! 1168: { ! 1169: char* op; ! 1170: switch(type) { ! 1171: case flag_add: op="add"; break; ! 1172: case flag_sub: op="sub"; break; ! 1173: case flag_cmp: op="cmp"; break; ! 1174: default: abort(); ! 1175: } ! 1176: switch (size) ! 1177: { ! 1178: case sz_byte: ! 1179: comprintf("\tstart_needflags();\n" ! 1180: "\t%s_b(%s,%s);\n",op,dst,src); ! 1181: break; ! 1182: case sz_word: ! 1183: comprintf("\tstart_needflags();\n" ! 1184: "\t%s_w(%s,%s);\n",op,dst,src); ! 1185: break; ! 1186: case sz_long: ! 1187: comprintf("\tstart_needflags();\n" ! 1188: "\t%s_l(%s,%s);\n",op,dst,src); ! 1189: break; ! 1190: } ! 1191: comprintf("\tlive_flags();\n"); ! 1192: comprintf("\tend_needflags();\n"); ! 1193: if (type!=flag_cmp) { ! 1194: duplicate_carry(); ! 1195: } ! 1196: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 1197: ! 1198: return; ! 1199: } ! 1200: ! 1201: case flag_addx: ! 1202: case flag_subx: ! 1203: uses_cmov; ! 1204: comprintf("\tdont_care_flags();\n"); ! 1205: { ! 1206: char* op; ! 1207: switch(type) { ! 1208: case flag_addx: op="adc"; break; ! 1209: case flag_subx: op="sbb"; break; ! 1210: default: abort(); ! 1211: } ! 1212: start_brace(); ! 1213: comprintf("\tint zero=scratchie++;\n" ! 1214: "\tint one=scratchie++;\n" ! 1215: "\tif (needed_flags&FLAG_Z) {\n" ! 1216: "\tmov_l_ri(zero,0);\n" ! 1217: "\tmov_l_ri(one,1);\n" ! 1218: "\tmake_flags_live();\n" ! 1219: "\tcmov_l_rr(zero,one,5);\n" ! 1220: "\t}\n"); ! 1221: comprintf("\trestore_carry();\n"); /* Reload the X flag into C */ ! 1222: switch (size) ! 1223: { ! 1224: case sz_byte: ! 1225: comprintf("\tstart_needflags();\n" ! 1226: "\t%s_b(%s,%s);\n",op,dst,src); ! 1227: break; ! 1228: case sz_word: ! 1229: comprintf("\tstart_needflags();\n" ! 1230: "\t%s_w(%s,%s);\n",op,dst,src); ! 1231: break; ! 1232: case sz_long: ! 1233: comprintf("\tstart_needflags();\n" ! 1234: "\t%s_l(%s,%s);\n",op,dst,src); ! 1235: break; ! 1236: } ! 1237: comprintf("\tlive_flags();\n"); ! 1238: comprintf("\tif (needed_flags&FLAG_Z) {\n" ! 1239: "\tcmov_l_rr(zero,one,5);\n" ! 1240: "\tsetzflg_l(zero);\n" ! 1241: "\tlive_flags();\n" ! 1242: "\t}\n"); ! 1243: comprintf("\tend_needflags();\n"); ! 1244: duplicate_carry(); ! 1245: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 1246: return; ! 1247: } ! 1248: default: ! 1249: failure; ! 1250: break; ! 1251: } ! 1252: } ! 1253: ! 1254: static void ! 1255: force_range_for_rox (const char *var, wordsizes size) ! 1256: { ! 1257: /* Could do a modulo operation here... which one is faster? */ ! 1258: switch (size) ! 1259: { ! 1260: case sz_long: ! 1261: comprintf ("\tif (%s >= 33) %s -= 33;\n", var, var); ! 1262: break; ! 1263: case sz_word: ! 1264: comprintf ("\tif (%s >= 34) %s -= 34;\n", var, var); ! 1265: comprintf ("\tif (%s >= 17) %s -= 17;\n", var, var); ! 1266: break; ! 1267: case sz_byte: ! 1268: comprintf ("\tif (%s >= 36) %s -= 36;\n", var, var); ! 1269: comprintf ("\tif (%s >= 18) %s -= 18;\n", var, var); ! 1270: comprintf ("\tif (%s >= 9) %s -= 9;\n", var, var); ! 1271: break; ! 1272: } ! 1273: } ! 1274: ! 1275: static const char * ! 1276: cmask (wordsizes size) ! 1277: { ! 1278: switch (size) ! 1279: { ! 1280: case sz_byte: ! 1281: return "0x80"; ! 1282: case sz_word: ! 1283: return "0x8000"; ! 1284: case sz_long: ! 1285: return "0x80000000"; ! 1286: default: ! 1287: abort (); ! 1288: } ! 1289: } ! 1290: ! 1291: static int ! 1292: source_is_imm1_8 (struct instr *i) ! 1293: { ! 1294: return i->stype == 3; ! 1295: } ! 1296: ! 1297: static int /* returns zero for success, non-zero for failure */ ! 1298: gen_opcode (unsigned long int opcode) ! 1299: { ! 1300: struct instr *curi = table68k + opcode; ! 1301: char* ssize=NULL; ! 1302: ! 1303: insn_n_cycles = 2; ! 1304: global_failure=0; ! 1305: long_opcode=0; ! 1306: global_isjump=0; ! 1307: global_iscjump=0; ! 1308: global_isaddx=0; ! 1309: global_cmov=0; ! 1310: global_mayfail=0; ! 1311: hack_opcode=opcode; ! 1312: endstr[0]=0; ! 1313: ! 1314: start_brace (); ! 1315: comprintf("\tuae_u8 scratchie=S1;\n"); ! 1316: switch (curi->plev) ! 1317: { ! 1318: case 0: /* not privileged */ ! 1319: break; ! 1320: case 1: /* unprivileged only on 68000 */ ! 1321: if (cpu_level == 0) ! 1322: break; ! 1323: if (next_cpu_level < 0) ! 1324: next_cpu_level = 0; ! 1325: ! 1326: /* fall through */ ! 1327: case 2: /* priviledged */ ! 1328: failure; /* Easy ones first */ ! 1329: break; ! 1330: case 3: /* privileged if size == word */ ! 1331: if (curi->size == sz_byte) ! 1332: break; ! 1333: failure; ! 1334: break; ! 1335: } ! 1336: switch (curi->size) { ! 1337: case sz_byte: ssize="b"; break; ! 1338: case sz_word: ssize="w"; break; ! 1339: case sz_long: ssize="l"; break; ! 1340: default: abort(); ! 1341: } ! 1342: ! 1343: switch (curi->mnemo) ! 1344: { ! 1345: case i_OR: ! 1346: case i_AND: ! 1347: case i_EOR: ! 1348: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1349: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1350: switch(curi->mnemo) { ! 1351: case i_OR: genflags (flag_or, curi->size, "", "src", "dst"); break; ! 1352: case i_AND: genflags (flag_and, curi->size, "", "src", "dst"); break; ! 1353: case i_EOR: genflags (flag_eor, curi->size, "", "src", "dst"); break; ! 1354: } ! 1355: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1356: break; ! 1357: ! 1358: case i_ORSR: ! 1359: case i_EORSR: ! 1360: failure; ! 1361: isjump; ! 1362: break; ! 1363: case i_ANDSR: ! 1364: failure; ! 1365: isjump; ! 1366: break; ! 1367: case i_SUB: ! 1368: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1369: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1370: genflags (flag_sub, curi->size, "", "src", "dst"); ! 1371: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1372: break; ! 1373: case i_SUBA: ! 1374: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1375: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1376: start_brace(); ! 1377: comprintf("\tint tmp=scratchie++;\n"); ! 1378: switch(curi->size) { ! 1379: case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; ! 1380: case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; ! 1381: case sz_long: comprintf("\ttmp=src;\n"); break; ! 1382: default: abort(); ! 1383: } ! 1384: comprintf("\tsub_l(dst,tmp);\n"); ! 1385: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); ! 1386: break; ! 1387: case i_SUBX: ! 1388: isaddx; ! 1389: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1390: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1391: genflags (flag_subx, curi->size, "", "src", "dst"); ! 1392: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1393: break; ! 1394: case i_SBCD: ! 1395: failure; ! 1396: /* I don't think so! */ ! 1397: break; ! 1398: case i_ADD: ! 1399: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1400: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1401: genflags (flag_add, curi->size, "", "src", "dst"); ! 1402: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1403: break; ! 1404: case i_ADDA: ! 1405: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1406: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1407: start_brace(); ! 1408: comprintf("\tint tmp=scratchie++;\n"); ! 1409: switch(curi->size) { ! 1410: case sz_byte: comprintf("\tsign_extend_8_rr(tmp,src);\n"); break; ! 1411: case sz_word: comprintf("\tsign_extend_16_rr(tmp,src);\n"); break; ! 1412: case sz_long: comprintf("\ttmp=src;\n"); break; ! 1413: default: abort(); ! 1414: } ! 1415: comprintf("\tadd_l(dst,tmp);\n"); ! 1416: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); ! 1417: break; ! 1418: case i_ADDX: ! 1419: isaddx; ! 1420: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1421: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1422: start_brace(); ! 1423: genflags (flag_addx, curi->size, "", "src", "dst"); ! 1424: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1425: break; ! 1426: case i_ABCD: ! 1427: failure; ! 1428: /* No BCD maths for me.... */ ! 1429: break; ! 1430: case i_NEG: ! 1431: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1432: start_brace (); ! 1433: comprintf("\tint dst=scratchie++;\n"); ! 1434: comprintf("\tmov_l_ri(dst,0);\n"); ! 1435: genflags (flag_sub, curi->size, "", "src", "dst"); ! 1436: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1437: break; ! 1438: case i_NEGX: ! 1439: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1440: start_brace (); ! 1441: comprintf("\tint dst=scratchie++;\n"); ! 1442: comprintf("\tmov_l_ri(dst,0);\n"); ! 1443: genflags (flag_subx, curi->size, "", "src", "dst"); ! 1444: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1445: break; ! 1446: ! 1447: case i_NBCD: ! 1448: failure; ! 1449: /* Nope! */ ! 1450: break; ! 1451: case i_CLR: ! 1452: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); ! 1453: start_brace(); ! 1454: comprintf("\tint dst=scratchie++;\n"); ! 1455: comprintf("\tmov_l_ri(dst,0);\n"); ! 1456: genflags (flag_logical, curi->size, "dst", "", ""); ! 1457: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1458: break; ! 1459: case i_NOT: ! 1460: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1461: start_brace (); ! 1462: comprintf("\tint dst=scratchie++;\n"); ! 1463: comprintf("\tmov_l_ri(dst,0xffffffff);\n"); ! 1464: genflags (flag_eor, curi->size, "", "src", "dst"); ! 1465: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1466: break; ! 1467: case i_TST: ! 1468: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1469: genflags (flag_logical, curi->size, "src", "", ""); ! 1470: break; ! 1471: case i_BCHG: ! 1472: case i_BCLR: ! 1473: case i_BSET: ! 1474: case i_BTST: ! 1475: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1476: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1477: start_brace(); ! 1478: comprintf("\tint s=scratchie++;\n" ! 1479: "\tmov_l_rr(s,src);\n"); ! 1480: if (curi->size == sz_byte) ! 1481: comprintf("\tand_l_ri(s,7);\n"); ! 1482: else ! 1483: comprintf("\tand_l_ri(s,31);\n"); ! 1484: ! 1485: { ! 1486: char* op; ! 1487: int need_write=1; ! 1488: ! 1489: switch(curi->mnemo) { ! 1490: case i_BCHG: op="btc"; break; ! 1491: case i_BCLR: op="btr"; break; ! 1492: case i_BSET: op="bts"; break; ! 1493: case i_BTST: op="bt"; need_write=0; break; ! 1494: } ! 1495: comprintf("\t%s_l_rr(dst,s);\n" /* Answer now in C */ ! 1496: "\tsbb_l(s,s);\n" /* s is 0 if bit was 0, -1 otherwise */ ! 1497: "\tmake_flags_live();\n" /* Get the flags back */ ! 1498: "\tdont_care_flags();\n",op); ! 1499: if (!noflags) { ! 1500: comprintf("\tstart_needflags();\n" ! 1501: "\tsetzflg_l(s);\n" ! 1502: "\tlive_flags();\n" ! 1503: "\tend_needflags();\n"); ! 1504: } ! 1505: if (need_write) ! 1506: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1507: } ! 1508: break; ! 1509: /*if (!noflags) { ! 1510: failure; ! 1511: break; ! 1512: } ! 1513: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1514: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1515: start_brace(); ! 1516: comprintf("\tint s=scratchie++;\n" ! 1517: "\tmov_l_rr(s,src);\n"); ! 1518: if (curi->size == sz_byte) ! 1519: comprintf("\tand_l_ri(s,7);\n"); ! 1520: else ! 1521: comprintf("\tand_l_ri(s,31);\n"); ! 1522: ! 1523: { ! 1524: char* op; ! 1525: int need_write=1; ! 1526: ! 1527: switch(curi->mnemo) { ! 1528: case i_BCHG: op="btc"; break; ! 1529: case i_BCLR: op="btr"; break; ! 1530: case i_BSET: op="bts"; break; ! 1531: case i_BTST: op="bt"; need_write=0; break; ! 1532: } ! 1533: comprintf("\t%s_l_rr(dst,s);\n" // Answer now in C ! 1534: "\tsbb_l(s,s);\n" // s is 0 if bit was 0, -1 otherwise ! 1535: "\tmake_flags_live();\n" // Get the flags back ! 1536: "\tdont_care_flags();\n" ! 1537: "\tstart_needflags();\n" ! 1538: "\tbsf_l_rr(s,s);\n" ! 1539: "\tlive_flags();\n" ! 1540: "\tend_needflags();\n",op); ! 1541: if (need_write) ! 1542: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1543: } ! 1544: break; ! 1545: */ ! 1546: case i_CMPM: ! 1547: case i_CMP: ! 1548: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1549: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1550: start_brace (); ! 1551: genflags (flag_cmp, curi->size, "", "src", "dst"); ! 1552: break; ! 1553: case i_CMPA: ! 1554: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1555: genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0); ! 1556: start_brace(); ! 1557: comprintf("\tint tmps=scratchie++;\n"); ! 1558: switch(curi->size) { ! 1559: case sz_byte: comprintf("\tsign_extend_8_rr(tmps,src);\n"); break; ! 1560: case sz_word: comprintf("\tsign_extend_16_rr(tmps,src);\n"); break; ! 1561: case sz_long: comprintf("tmps=src;\n"); break; ! 1562: default: abort(); ! 1563: } ! 1564: genflags (flag_cmp, sz_long, "", "tmps", "dst"); ! 1565: break; ! 1566: /* The next two are coded a little unconventional, but they are doing ! 1567: * weird things... */ ! 1568: case i_MVPRM: ! 1569: isjump; ! 1570: failure; ! 1571: break; ! 1572: case i_MVPMR: ! 1573: isjump; ! 1574: failure; ! 1575: break; ! 1576: case i_MOVE: ! 1577: switch(curi->dmode) { ! 1578: case Dreg: ! 1579: case Areg: ! 1580: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1581: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1582: genflags (flag_mov, curi->size, "", "src", "dst"); ! 1583: genastore ("dst", curi->dmode, "dstreg", curi->size, "dst"); ! 1584: break; ! 1585: default: /* It goes to memory, not a register */ ! 1586: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1587: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1588: genflags (flag_logical, curi->size, "src", "", ""); ! 1589: genastore ("src", curi->dmode, "dstreg", curi->size, "dst"); ! 1590: break; ! 1591: } ! 1592: break; ! 1593: case i_MOVEA: ! 1594: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1595: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1596: ! 1597: start_brace(); ! 1598: comprintf("\tint tmps=scratchie++;\n"); ! 1599: switch(curi->size) { ! 1600: case sz_word: comprintf("\tsign_extend_16_rr(dst,src);\n"); break; ! 1601: case sz_long: comprintf("\tmov_l_rr(dst,src);\n"); break; ! 1602: default: abort(); ! 1603: } ! 1604: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); ! 1605: break; ! 1606: ! 1607: case i_MVSR2: ! 1608: isjump; ! 1609: failure; ! 1610: break; ! 1611: case i_MV2SR: ! 1612: isjump; ! 1613: failure; ! 1614: break; ! 1615: case i_SWAP: ! 1616: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); ! 1617: comprintf("\tdont_care_flags();\n"); ! 1618: comprintf("\trol_l_ri(src,16);\n"); ! 1619: genflags (flag_logical, sz_long, "src", "", ""); ! 1620: genastore ("src", curi->smode, "srcreg", sz_long, "src"); ! 1621: break; ! 1622: case i_EXG: ! 1623: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1624: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 1625: start_brace(); ! 1626: comprintf("\tint tmp=scratchie++;\n" ! 1627: "\tmov_l_rr(tmp,src);\n"); ! 1628: genastore ("dst", curi->smode, "srcreg", curi->size, "src"); ! 1629: genastore ("tmp", curi->dmode, "dstreg", curi->size, "dst"); ! 1630: break; ! 1631: case i_EXT: ! 1632: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); ! 1633: comprintf("\tdont_care_flags();\n"); ! 1634: start_brace (); ! 1635: switch (curi->size) ! 1636: { ! 1637: case sz_byte: ! 1638: comprintf ("\tint dst = src;\n" ! 1639: "\tsign_extend_8_rr(src,src);\n"); ! 1640: break; ! 1641: case sz_word: ! 1642: comprintf ("\tint dst = scratchie++;\n" ! 1643: "\tsign_extend_8_rr(dst,src);\n"); ! 1644: break; ! 1645: case sz_long: ! 1646: comprintf ("\tint dst = src;\n" ! 1647: "\tsign_extend_16_rr(src,src);\n"); ! 1648: break; ! 1649: default: ! 1650: abort (); ! 1651: } ! 1652: genflags (flag_logical, ! 1653: curi->size == sz_word ? sz_word : sz_long, "dst", "", ""); ! 1654: genastore ("dst", curi->smode, "srcreg", ! 1655: curi->size == sz_word ? sz_word : sz_long, "src"); ! 1656: break; ! 1657: case i_MVMEL: ! 1658: genmovemel (opcode); ! 1659: break; ! 1660: case i_MVMLE: ! 1661: genmovemle (opcode); ! 1662: break; ! 1663: case i_TRAP: ! 1664: isjump; ! 1665: failure; ! 1666: break; ! 1667: case i_MVR2USP: ! 1668: isjump; ! 1669: failure; ! 1670: break; ! 1671: case i_MVUSP2R: ! 1672: isjump; ! 1673: failure; ! 1674: break; ! 1675: case i_RESET: ! 1676: isjump; ! 1677: failure; ! 1678: break; ! 1679: case i_NOP: ! 1680: break; ! 1681: case i_STOP: ! 1682: isjump; ! 1683: failure; ! 1684: break; ! 1685: case i_RTE: ! 1686: isjump; ! 1687: failure; ! 1688: break; ! 1689: case i_RTD: ! 1690: genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0); ! 1691: /* offs is constant */ ! 1692: comprintf("\tadd_l_ri(offs,4);\n"); ! 1693: start_brace(); ! 1694: comprintf("\tint newad=scratchie++;\n" ! 1695: "\treadlong(15,newad,scratchie);\n" ! 1696: "\tand_l_ri(newad,~1);\n" ! 1697: "\tmov_l_mr((uae_u32)®s.pc,newad);\n" ! 1698: "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" ! 1699: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n" ! 1700: "\tm68k_pc_offset=0;\n" ! 1701: "\tadd_l(15,offs);\n"); ! 1702: gen_update_next_handler(); ! 1703: isjump; ! 1704: break; ! 1705: case i_LINK: ! 1706: genamode (curi->smode, "srcreg", sz_long, "src", 1, 0); ! 1707: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); ! 1708: comprintf("\tsub_l_ri(15,4);\n" ! 1709: "\twritelong_clobber(15,src,scratchie);\n" ! 1710: "\tmov_l_rr(src,15);\n"); ! 1711: if (curi->size==sz_word) ! 1712: comprintf("\tsign_extend_16_rr(offs,offs);\n"); ! 1713: comprintf("\tadd_l(15,offs);\n"); ! 1714: genastore ("src", curi->smode, "srcreg", sz_long, "src"); ! 1715: break; ! 1716: case i_UNLK: ! 1717: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1718: comprintf("\tmov_l_rr(15,src);\n" ! 1719: "\treadlong(15,src,scratchie);\n" ! 1720: "\tadd_l_ri(15,4);\n"); ! 1721: genastore ("src", curi->smode, "srcreg", curi->size, "src"); ! 1722: break; ! 1723: case i_RTS: ! 1724: comprintf("\tint newad=scratchie++;\n" ! 1725: "\treadlong(15,newad,scratchie);\n" ! 1726: "\tand_l_ri(newad,~1);\n" ! 1727: "\tmov_l_mr((uae_u32)®s.pc,newad);\n" ! 1728: "\tget_n_addr_jmp(newad,PC_P,scratchie);\n" ! 1729: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n" ! 1730: "\tm68k_pc_offset=0;\n" ! 1731: "\tlea_l_brr(15,15,4);\n"); ! 1732: gen_update_next_handler(); ! 1733: isjump; ! 1734: break; ! 1735: case i_TRAPV: ! 1736: isjump; ! 1737: failure; ! 1738: break; ! 1739: case i_RTR: ! 1740: isjump; ! 1741: failure; ! 1742: break; ! 1743: case i_JSR: ! 1744: isjump; ! 1745: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1746: start_brace(); ! 1747: comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); ! 1748: comprintf("\tint ret=scratchie++;\n" ! 1749: "\tmov_l_ri(ret,retadd);\n" ! 1750: "\tsub_l_ri(15,4);\n" ! 1751: "\twritelong_clobber(15,ret,scratchie);\n"); ! 1752: comprintf("\tand_l_ri(srca,~1);\n" ! 1753: "\tmov_l_mr((uae_u32)®s.pc,srca);\n" ! 1754: "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" ! 1755: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n" ! 1756: "\tm68k_pc_offset=0;\n"); ! 1757: gen_update_next_handler(); ! 1758: break; ! 1759: case i_JMP: ! 1760: isjump; ! 1761: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1762: comprintf("\tand_l_ri(srca,~1);\n" ! 1763: "\tmov_l_mr((uae_u32)®s.pc,srca);\n" ! 1764: "\tget_n_addr_jmp(srca,PC_P,scratchie);\n" ! 1765: "\tmov_l_mr((uae_u32)®s.pc_oldp,PC_P);\n" ! 1766: "\tm68k_pc_offset=0;\n"); ! 1767: gen_update_next_handler(); ! 1768: break; ! 1769: case i_BSR: ! 1770: if (curi->size==sz_long) ! 1771: failure; ! 1772: is_const_jump; ! 1773: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1774: comprintf("\tand_l_ri(src,~1);\n"); ! 1775: start_brace(); ! 1776: comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n"); ! 1777: comprintf("\tint ret=scratchie++;\n" ! 1778: "\tmov_l_ri(ret,retadd);\n" ! 1779: "\tsub_l_ri(15,4);\n" ! 1780: "\twritelong_clobber(15,ret,scratchie);\n"); ! 1781: comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n"); ! 1782: comprintf("\tm68k_pc_offset=0;\n"); ! 1783: comprintf("\tadd_l(PC_P,src);\n"); ! 1784: ! 1785: comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n"); ! 1786: break; ! 1787: case i_Bcc: ! 1788: comprintf("\tuae_u32 v1,v2;\n"); ! 1789: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1790: /* That source is an immediate, so we can clobber it with abandon */ ! 1791: switch(curi->size) { ! 1792: case sz_byte: comprintf("\tsign_extend_8_rr(src,src);\n"); break; ! 1793: case sz_word: comprintf("\tsign_extend_16_rr(src,src);\n"); break; ! 1794: case sz_long: break; ! 1795: } ! 1796: comprintf("\tand_l_ri(src,~1);\n"); ! 1797: comprintf("\tsub_l_ri(src,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); ! 1798: /* Leave the following as "add" --- it will allow it to be optimized ! 1799: away due to src being a constant ;-) */ ! 1800: comprintf("\tadd_l_ri(src,(uae_u32)comp_pc_p);\n"); ! 1801: comprintf("\tmov_l_ri(PC_P,(uae_u32)comp_pc_p);\n"); ! 1802: /* Now they are both constant. Might as well fold in m68k_pc_offset */ ! 1803: comprintf("\tadd_l_ri(src,m68k_pc_offset);\n"); ! 1804: comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); ! 1805: comprintf("\tm68k_pc_offset=0;\n"); ! 1806: ! 1807: if (curi->cc>=2) { ! 1808: comprintf("\tv1=get_const(PC_P);\n" ! 1809: "\tv2=get_const(src);\n" ! 1810: "\tregister_branch(v1,v2,%d);\n", ! 1811: cond_codes_x86[curi->cc]); ! 1812: comprintf("\tmake_flags_live();\n"); /* Load the flags */ ! 1813: isjump; ! 1814: } ! 1815: else { ! 1816: is_const_jump; ! 1817: } ! 1818: ! 1819: switch(curi->cc) { ! 1820: case 0: /* Unconditional jump */ ! 1821: comprintf("\tmov_l_rr(PC_P,src);\n"); ! 1822: comprintf("\tcomp_pc_p=(uae_u8*)get_const(PC_P);\n"); ! 1823: break; ! 1824: case 1: break; /* This is silly! */ ! 1825: case 8: failure; break; /* Work out details! FIXME */ ! 1826: case 9: failure; break; /* Not critical, though! */ ! 1827: ! 1828: case 2: ! 1829: case 3: ! 1830: case 4: ! 1831: case 5: ! 1832: case 6: ! 1833: case 7: ! 1834: case 10: ! 1835: case 11: ! 1836: case 12: ! 1837: case 13: ! 1838: case 14: ! 1839: case 15: ! 1840: break; ! 1841: default: abort(); ! 1842: } ! 1843: break; ! 1844: case i_LEA: ! 1845: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1846: genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0); ! 1847: genastore ("srca", curi->dmode, "dstreg", curi->size, "dst"); ! 1848: break; ! 1849: case i_PEA: ! 1850: if (table68k[opcode].smode==Areg || ! 1851: table68k[opcode].smode==Aind || ! 1852: table68k[opcode].smode==Aipi || ! 1853: table68k[opcode].smode==Apdi || ! 1854: table68k[opcode].smode==Ad16 || ! 1855: table68k[opcode].smode==Ad8r) ! 1856: comprintf("if (srcreg==7) dodgy=1;\n"); ! 1857: ! 1858: genamode (curi->smode, "srcreg", curi->size, "src", 0, 0); ! 1859: genamode (Apdi, "7", sz_long, "dst", 2, 0); ! 1860: genastore ("srca", Apdi, "7", sz_long, "dst"); ! 1861: break; ! 1862: case i_DBcc: ! 1863: isjump; ! 1864: uses_cmov; ! 1865: genamode (curi->smode, "srcreg", curi->size, "src", 1, 0); ! 1866: genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0); ! 1867: ! 1868: /* That offs is an immediate, so we can clobber it with abandon */ ! 1869: switch(curi->size) { ! 1870: case sz_word: comprintf("\tsign_extend_16_rr(offs,offs);\n"); break; ! 1871: default: abort(); /* Seems this only comes in word flavour */ ! 1872: } ! 1873: comprintf("\tsub_l_ri(offs,m68k_pc_offset-m68k_pc_offset_thisinst-2);\n"); ! 1874: comprintf("\tadd_l_ri(offs,(uae_u32)comp_pc_p);\n"); /* New PC, ! 1875: once the ! 1876: offset_68k is ! 1877: * also added */ ! 1878: /* Let's fold in the m68k_pc_offset at this point */ ! 1879: comprintf("\tadd_l_ri(offs,m68k_pc_offset);\n"); ! 1880: comprintf("\tadd_l_ri(PC_P,m68k_pc_offset);\n"); ! 1881: comprintf("\tm68k_pc_offset=0;\n"); ! 1882: ! 1883: start_brace(); ! 1884: comprintf("\tint nsrc=scratchie++;\n"); ! 1885: ! 1886: if (curi->cc>=2) { ! 1887: comprintf("\tmake_flags_live();\n"); /* Load the flags */ ! 1888: } ! 1889: ! 1890: if (curi->size!=sz_word) ! 1891: abort(); ! 1892: ! 1893: ! 1894: switch(curi->cc) { ! 1895: case 0: /* This is an elaborate nop? */ ! 1896: break; ! 1897: case 1: ! 1898: comprintf("\tstart_needflags();\n"); ! 1899: comprintf("\tsub_w_ri(src,1);\n"); ! 1900: comprintf("\t end_needflags();\n"); ! 1901: start_brace(); ! 1902: comprintf("\tuae_u32 v2;\n" ! 1903: "\tuae_u32 v1=get_const(PC_P);\n"); ! 1904: comprintf("\tv2=get_const(offs);\n" ! 1905: "\tregister_branch(v1,v2,3);\n"); ! 1906: break; ! 1907: ! 1908: case 8: failure; break; /* Work out details! FIXME */ ! 1909: case 9: failure; break; /* Not critical, though! */ ! 1910: ! 1911: case 2: ! 1912: case 3: ! 1913: case 4: ! 1914: case 5: ! 1915: case 6: ! 1916: case 7: ! 1917: case 10: ! 1918: case 11: ! 1919: case 12: ! 1920: case 13: ! 1921: case 14: ! 1922: case 15: ! 1923: comprintf("\tmov_l_rr(nsrc,src);\n"); ! 1924: comprintf("\tlea_l_brr(scratchie,src,(uae_s32)-1);\n" ! 1925: "\tmov_w_rr(src,scratchie);\n"); ! 1926: comprintf("\tcmov_l_rr(offs,PC_P,%d);\n", ! 1927: cond_codes_x86[curi->cc]); ! 1928: comprintf("\tcmov_l_rr(src,nsrc,%d);\n", ! 1929: cond_codes_x86[curi->cc]); ! 1930: /* OK, now for cc=true, we have src==nsrc and offs==PC_P, ! 1931: so whether we move them around doesn't matter. However, ! 1932: if cc=false, we have offs==jump_pc, and src==nsrc-1 */ ! 1933: ! 1934: comprintf("\t start_needflags();\n"); ! 1935: comprintf("\ttest_w_rr(nsrc,nsrc);\n"); ! 1936: comprintf("\t end_needflags();\n"); ! 1937: comprintf("\tcmov_l_rr(PC_P,offs,5);\n"); ! 1938: break; ! 1939: default: abort(); ! 1940: } ! 1941: genastore ("src", curi->smode, "srcreg", curi->size, "src"); ! 1942: gen_update_next_handler(); ! 1943: break; ! 1944: ! 1945: case i_Scc: ! 1946: genamode (curi->smode, "srcreg", curi->size, "src", 2, 0); ! 1947: start_brace (); ! 1948: comprintf ("\tint val = scratchie++;\n"); ! 1949: ! 1950: /* We set val to 0 if we really should use 255, and to 1 for real 0 */ ! 1951: switch(curi->cc) { ! 1952: case 0: /* Unconditional set */ ! 1953: comprintf("\tmov_l_ri(val,0);\n"); ! 1954: break; ! 1955: case 1: ! 1956: /* Unconditional not-set */ ! 1957: comprintf("\tmov_l_ri(val,1);\n"); ! 1958: break; ! 1959: case 8: failure; break; /* Work out details! FIXME */ ! 1960: case 9: failure; break; /* Not critical, though! */ ! 1961: ! 1962: case 2: ! 1963: case 3: ! 1964: case 4: ! 1965: case 5: ! 1966: case 6: ! 1967: case 7: ! 1968: case 10: ! 1969: case 11: ! 1970: case 12: ! 1971: case 13: ! 1972: case 14: ! 1973: case 15: ! 1974: comprintf("\tmake_flags_live();\n"); /* Load the flags */ ! 1975: /* All condition codes can be inverted by changing the LSB */ ! 1976: comprintf("\tsetcc(val,%d);\n", ! 1977: cond_codes_x86[curi->cc]^1); break; ! 1978: default: abort(); ! 1979: } ! 1980: comprintf("\tsub_b_ri(val,1);\n"); ! 1981: genastore ("val", curi->smode, "srcreg", curi->size, "src"); ! 1982: break; ! 1983: case i_DIVU: ! 1984: isjump; ! 1985: failure; ! 1986: break; ! 1987: case i_DIVS: ! 1988: isjump; ! 1989: failure; ! 1990: break; ! 1991: case i_MULU: ! 1992: comprintf("\tdont_care_flags();\n"); ! 1993: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); ! 1994: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); ! 1995: /* To do 16x16 unsigned multiplication, we actually use ! 1996: 32x32 signed, and zero-extend the registers first. ! 1997: That solves the problem of MUL needing dedicated registers ! 1998: on the x86 */ ! 1999: comprintf("\tzero_extend_16_rr(scratchie,src);\n" ! 2000: "\tzero_extend_16_rr(dst,dst);\n" ! 2001: "\timul_32_32(dst,scratchie);\n"); ! 2002: genflags (flag_logical, sz_long, "dst", "", ""); ! 2003: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); ! 2004: break; ! 2005: case i_MULS: ! 2006: comprintf("\tdont_care_flags();\n"); ! 2007: genamode (curi->smode, "srcreg", sz_word, "src", 1, 0); ! 2008: genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0); ! 2009: comprintf("\tsign_extend_16_rr(scratchie,src);\n" ! 2010: "\tsign_extend_16_rr(dst,dst);\n" ! 2011: "\timul_32_32(dst,scratchie);\n"); ! 2012: genflags (flag_logical, sz_long, "dst", "", ""); ! 2013: genastore ("dst", curi->dmode, "dstreg", sz_long, "dst"); ! 2014: break; ! 2015: case i_CHK: ! 2016: isjump; ! 2017: failure; ! 2018: break; ! 2019: ! 2020: case i_CHK2: ! 2021: isjump; ! 2022: failure; ! 2023: break; ! 2024: ! 2025: case i_ASR: ! 2026: mayfail; ! 2027: if (curi->smode==Dreg) { ! 2028: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" ! 2029: " FAIL(1);\n" ! 2030: " return 0;\n" ! 2031: "} \n"); ! 2032: start_brace(); ! 2033: } ! 2034: comprintf("\tdont_care_flags();\n"); ! 2035: ! 2036: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 2037: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 2038: if (curi->smode!=immi) { ! 2039: if (!noflags) { ! 2040: uses_cmov; ! 2041: start_brace(); ! 2042: comprintf("\tint highmask;\n" ! 2043: "\tint width;\n" ! 2044: "\tint cdata=scratchie++;\n" ! 2045: "\tint tmpcnt=scratchie++;\n" ! 2046: "\tint highshift=scratchie++;\n"); ! 2047: comprintf("\tmov_l_rr(tmpcnt,cnt);\n" ! 2048: "\tand_l_ri(tmpcnt,63);\n" ! 2049: "\tmov_l_ri(cdata,0);\n" ! 2050: "\tcmov_l_rr(cdata,data,5);\n"); ! 2051: /* cdata is now either data (for shift count!=0) or ! 2052: 0 (for shift count==0) */ ! 2053: switch(curi->size) { ! 2054: case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n" ! 2055: "\thighmask=0x38;\n" ! 2056: "\twidth=8;\n"); ! 2057: break; ! 2058: case sz_word: comprintf("\tshra_w_rr(data,cnt);\n" ! 2059: "\thighmask=0x30;\n" ! 2060: "\twidth=16;\n"); ! 2061: break; ! 2062: case sz_long: comprintf("\tshra_l_rr(data,cnt);\n" ! 2063: "\thighmask=0x20;\n" ! 2064: "\twidth=32;\n"); ! 2065: break; ! 2066: default: abort(); ! 2067: } ! 2068: comprintf("test_l_ri(cnt,highmask);\n" ! 2069: "mov_l_ri(highshift,0);\n" ! 2070: "mov_l_ri(scratchie,width/2);\n" ! 2071: "cmov_l_rr(highshift,scratchie,5);\n"); ! 2072: /* The x86 masks out bits, so we now make sure that things ! 2073: really get shifted as much as planned */ ! 2074: switch(curi->size) { ! 2075: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; ! 2076: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; ! 2077: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; ! 2078: default: abort(); ! 2079: } ! 2080: /* And again */ ! 2081: switch(curi->size) { ! 2082: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; ! 2083: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; ! 2084: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; ! 2085: default: abort(); ! 2086: } ! 2087: ! 2088: /* Result of shift is now in data. Now we need to determine ! 2089: the carry by shifting cdata one less */ ! 2090: comprintf("\tsub_l_ri(tmpcnt,1);\n"); ! 2091: switch(curi->size) { ! 2092: case sz_byte: comprintf("\tshra_b_rr(cdata,tmpcnt);\n");break; ! 2093: case sz_word: comprintf("\tshra_w_rr(cdata,tmpcnt);\n");break; ! 2094: case sz_long: comprintf("\tshra_l_rr(cdata,tmpcnt);\n");break; ! 2095: default: abort(); ! 2096: } ! 2097: /* If the shift count was higher than the width, we need ! 2098: to pick up the sign from data */ ! 2099: comprintf("test_l_ri(tmpcnt,highmask);\n" ! 2100: "cmov_l_rr(cdata,data,5);\n"); ! 2101: /* And create the flags */ ! 2102: comprintf("\tstart_needflags();\n"); ! 2103: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2104: switch(curi->size) { ! 2105: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2106: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2107: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2108: } ! 2109: comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */ ! 2110: comprintf("\t live_flags();\n"); ! 2111: comprintf("\t end_needflags();\n"); ! 2112: comprintf("\t duplicate_carry();\n"); ! 2113: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2114: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2115: } ! 2116: else { ! 2117: uses_cmov; ! 2118: start_brace(); ! 2119: comprintf("\tint highmask;\n" ! 2120: "\tint width;\n" ! 2121: "\tint highshift=scratchie++;\n"); ! 2122: switch(curi->size) { ! 2123: case sz_byte: comprintf("\tshra_b_rr(data,cnt);\n" ! 2124: "\thighmask=0x38;\n" ! 2125: "\twidth=8;\n"); ! 2126: break; ! 2127: case sz_word: comprintf("\tshra_w_rr(data,cnt);\n" ! 2128: "\thighmask=0x30;\n" ! 2129: "\twidth=16;\n"); ! 2130: break; ! 2131: case sz_long: comprintf("\tshra_l_rr(data,cnt);\n" ! 2132: "\thighmask=0x20;\n" ! 2133: "\twidth=32;\n"); ! 2134: break; ! 2135: default: abort(); ! 2136: } ! 2137: comprintf("test_l_ri(cnt,highmask);\n" ! 2138: "mov_l_ri(highshift,0);\n" ! 2139: "mov_l_ri(scratchie,width/2);\n" ! 2140: "cmov_l_rr(highshift,scratchie,5);\n"); ! 2141: /* The x86 masks out bits, so we now make sure that things ! 2142: really get shifted as much as planned */ ! 2143: switch(curi->size) { ! 2144: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; ! 2145: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; ! 2146: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; ! 2147: default: abort(); ! 2148: } ! 2149: /* And again */ ! 2150: switch(curi->size) { ! 2151: case sz_byte: comprintf("\tshra_b_rr(data,highshift);\n");break; ! 2152: case sz_word: comprintf("\tshra_w_rr(data,highshift);\n");break; ! 2153: case sz_long: comprintf("\tshra_l_rr(data,highshift);\n");break; ! 2154: default: abort(); ! 2155: } ! 2156: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2157: } ! 2158: } ! 2159: else { ! 2160: start_brace(); ! 2161: comprintf("\tint tmp=scratchie++;\n" ! 2162: "\tint bp;\n" ! 2163: "\tmov_l_rr(tmp,data);\n"); ! 2164: switch(curi->size) { ! 2165: case sz_byte: comprintf("\tshra_b_ri(data,srcreg);\n" ! 2166: "\tbp=srcreg-1;\n"); break; ! 2167: case sz_word: comprintf("\tshra_w_ri(data,srcreg);\n" ! 2168: "\tbp=srcreg-1;\n"); break; ! 2169: case sz_long: comprintf("\tshra_l_ri(data,srcreg);\n" ! 2170: "\tbp=srcreg-1;\n"); break; ! 2171: default: abort(); ! 2172: } ! 2173: ! 2174: if (!noflags) { ! 2175: comprintf("\tstart_needflags();\n"); ! 2176: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2177: switch(curi->size) { ! 2178: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2179: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2180: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2181: } ! 2182: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ ! 2183: comprintf("\t live_flags();\n"); ! 2184: comprintf("\t end_needflags();\n"); ! 2185: comprintf("\t duplicate_carry();\n"); ! 2186: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2187: } ! 2188: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2189: } ! 2190: break; ! 2191: ! 2192: case i_ASL: ! 2193: mayfail; ! 2194: if (curi->smode==Dreg) { ! 2195: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" ! 2196: " FAIL(1);\n" ! 2197: " return 0;\n" ! 2198: "} \n"); ! 2199: start_brace(); ! 2200: } ! 2201: comprintf("\tdont_care_flags();\n"); ! 2202: /* Except for the handling of the V flag, this is identical to ! 2203: LSL. The handling of V is, uhm, unpleasant, so if it's needed, ! 2204: let the normal emulation handle it. Shoulders of giants kinda ! 2205: thing ;-) */ ! 2206: comprintf("if (needed_flags & FLAG_V) {\n" ! 2207: " FAIL(1);\n" ! 2208: " return 0;\n" ! 2209: "} \n"); ! 2210: ! 2211: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 2212: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 2213: if (curi->smode!=immi) { ! 2214: if (!noflags) { ! 2215: uses_cmov; ! 2216: start_brace(); ! 2217: comprintf("\tint highmask;\n" ! 2218: "\tint cdata=scratchie++;\n" ! 2219: "\tint tmpcnt=scratchie++;\n"); ! 2220: comprintf("\tmov_l_rr(tmpcnt,cnt);\n" ! 2221: "\tand_l_ri(tmpcnt,63);\n" ! 2222: "\tmov_l_ri(cdata,0);\n" ! 2223: "\tcmov_l_rr(cdata,data,5);\n"); ! 2224: /* cdata is now either data (for shift count!=0) or ! 2225: 0 (for shift count==0) */ ! 2226: switch(curi->size) { ! 2227: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" ! 2228: "\thighmask=0x38;\n"); ! 2229: break; ! 2230: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" ! 2231: "\thighmask=0x30;\n"); ! 2232: break; ! 2233: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" ! 2234: "\thighmask=0x20;\n"); ! 2235: break; ! 2236: default: abort(); ! 2237: } ! 2238: comprintf("test_l_ri(cnt,highmask);\n" ! 2239: "mov_l_ri(scratchie,0);\n" ! 2240: "cmov_l_rr(scratchie,data,4);\n"); ! 2241: switch(curi->size) { ! 2242: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; ! 2243: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; ! 2244: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; ! 2245: default: abort(); ! 2246: } ! 2247: /* Result of shift is now in data. Now we need to determine ! 2248: the carry by shifting cdata one less */ ! 2249: comprintf("\tsub_l_ri(tmpcnt,1);\n"); ! 2250: switch(curi->size) { ! 2251: case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break; ! 2252: case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break; ! 2253: case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break; ! 2254: default: abort(); ! 2255: } ! 2256: comprintf("test_l_ri(tmpcnt,highmask);\n" ! 2257: "mov_l_ri(scratchie,0);\n" ! 2258: "cmov_l_rr(cdata,scratchie,5);\n"); ! 2259: /* And create the flags */ ! 2260: comprintf("\tstart_needflags();\n"); ! 2261: ! 2262: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2263: switch(curi->size) { ! 2264: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); ! 2265: comprintf("\t bt_l_ri(cdata,7);\n"); break; ! 2266: case sz_word: comprintf("\t test_w_rr(data,data);\n"); ! 2267: comprintf("\t bt_l_ri(cdata,15);\n"); break; ! 2268: case sz_long: comprintf("\t test_l_rr(data,data);\n"); ! 2269: comprintf("\t bt_l_ri(cdata,31);\n"); break; ! 2270: } ! 2271: comprintf("\t live_flags();\n"); ! 2272: comprintf("\t end_needflags();\n"); ! 2273: comprintf("\t duplicate_carry();\n"); ! 2274: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2275: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2276: } ! 2277: else { ! 2278: uses_cmov; ! 2279: start_brace(); ! 2280: comprintf("\tint highmask;\n"); ! 2281: switch(curi->size) { ! 2282: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" ! 2283: "\thighmask=0x38;\n"); ! 2284: break; ! 2285: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" ! 2286: "\thighmask=0x30;\n"); ! 2287: break; ! 2288: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" ! 2289: "\thighmask=0x20;\n"); ! 2290: break; ! 2291: default: abort(); ! 2292: } ! 2293: comprintf("test_l_ri(cnt,highmask);\n" ! 2294: "mov_l_ri(scratchie,0);\n" ! 2295: "cmov_l_rr(scratchie,data,4);\n"); ! 2296: switch(curi->size) { ! 2297: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; ! 2298: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; ! 2299: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; ! 2300: default: abort(); ! 2301: } ! 2302: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2303: } ! 2304: } ! 2305: else { ! 2306: start_brace(); ! 2307: comprintf("\tint tmp=scratchie++;\n" ! 2308: "\tint bp;\n" ! 2309: "\tmov_l_rr(tmp,data);\n"); ! 2310: switch(curi->size) { ! 2311: case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n" ! 2312: "\tbp=8-srcreg;\n"); break; ! 2313: case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n" ! 2314: "\tbp=16-srcreg;\n"); break; ! 2315: case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n" ! 2316: "\tbp=32-srcreg;\n"); break; ! 2317: default: abort(); ! 2318: } ! 2319: ! 2320: if (!noflags) { ! 2321: comprintf("\tstart_needflags();\n"); ! 2322: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2323: switch(curi->size) { ! 2324: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2325: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2326: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2327: } ! 2328: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ ! 2329: comprintf("\t live_flags();\n"); ! 2330: comprintf("\t end_needflags();\n"); ! 2331: comprintf("\t duplicate_carry();\n"); ! 2332: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2333: } ! 2334: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2335: } ! 2336: break; ! 2337: ! 2338: case i_LSR: ! 2339: mayfail; ! 2340: if (curi->smode==Dreg) { ! 2341: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" ! 2342: " FAIL(1);\n" ! 2343: " return 0;\n" ! 2344: "} \n"); ! 2345: start_brace(); ! 2346: } ! 2347: comprintf("\tdont_care_flags();\n"); ! 2348: ! 2349: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 2350: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 2351: if (curi->smode!=immi) { ! 2352: if (!noflags) { ! 2353: uses_cmov; ! 2354: start_brace(); ! 2355: comprintf("\tint highmask;\n" ! 2356: "\tint cdata=scratchie++;\n" ! 2357: "\tint tmpcnt=scratchie++;\n"); ! 2358: comprintf("\tmov_l_rr(tmpcnt,cnt);\n" ! 2359: "\tand_l_ri(tmpcnt,63);\n" ! 2360: "\tmov_l_ri(cdata,0);\n" ! 2361: "\tcmov_l_rr(cdata,data,5);\n"); ! 2362: /* cdata is now either data (for shift count!=0) or ! 2363: 0 (for shift count==0) */ ! 2364: switch(curi->size) { ! 2365: case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n" ! 2366: "\thighmask=0x38;\n"); ! 2367: break; ! 2368: case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n" ! 2369: "\thighmask=0x30;\n"); ! 2370: break; ! 2371: case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n" ! 2372: "\thighmask=0x20;\n"); ! 2373: break; ! 2374: default: abort(); ! 2375: } ! 2376: comprintf("test_l_ri(cnt,highmask);\n" ! 2377: "mov_l_ri(scratchie,0);\n" ! 2378: "cmov_l_rr(scratchie,data,4);\n"); ! 2379: switch(curi->size) { ! 2380: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; ! 2381: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; ! 2382: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; ! 2383: default: abort(); ! 2384: } ! 2385: /* Result of shift is now in data. Now we need to determine ! 2386: the carry by shifting cdata one less */ ! 2387: comprintf("\tsub_l_ri(tmpcnt,1);\n"); ! 2388: switch(curi->size) { ! 2389: case sz_byte: comprintf("\tshrl_b_rr(cdata,tmpcnt);\n");break; ! 2390: case sz_word: comprintf("\tshrl_w_rr(cdata,tmpcnt);\n");break; ! 2391: case sz_long: comprintf("\tshrl_l_rr(cdata,tmpcnt);\n");break; ! 2392: default: abort(); ! 2393: } ! 2394: comprintf("test_l_ri(tmpcnt,highmask);\n" ! 2395: "mov_l_ri(scratchie,0);\n" ! 2396: "cmov_l_rr(cdata,scratchie,5);\n"); ! 2397: /* And create the flags */ ! 2398: comprintf("\tstart_needflags();\n"); ! 2399: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2400: switch(curi->size) { ! 2401: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2402: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2403: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2404: } ! 2405: comprintf("\t bt_l_ri(cdata,0);\n"); /* Set C */ ! 2406: comprintf("\t live_flags();\n"); ! 2407: comprintf("\t end_needflags();\n"); ! 2408: comprintf("\t duplicate_carry();\n"); ! 2409: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2410: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2411: } ! 2412: else { ! 2413: uses_cmov; ! 2414: start_brace(); ! 2415: comprintf("\tint highmask;\n"); ! 2416: switch(curi->size) { ! 2417: case sz_byte: comprintf("\tshrl_b_rr(data,cnt);\n" ! 2418: "\thighmask=0x38;\n"); ! 2419: break; ! 2420: case sz_word: comprintf("\tshrl_w_rr(data,cnt);\n" ! 2421: "\thighmask=0x30;\n"); ! 2422: break; ! 2423: case sz_long: comprintf("\tshrl_l_rr(data,cnt);\n" ! 2424: "\thighmask=0x20;\n"); ! 2425: break; ! 2426: default: abort(); ! 2427: } ! 2428: comprintf("test_l_ri(cnt,highmask);\n" ! 2429: "mov_l_ri(scratchie,0);\n" ! 2430: "cmov_l_rr(scratchie,data,4);\n"); ! 2431: switch(curi->size) { ! 2432: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; ! 2433: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; ! 2434: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; ! 2435: default: abort(); ! 2436: } ! 2437: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2438: } ! 2439: } ! 2440: else { ! 2441: start_brace(); ! 2442: comprintf("\tint tmp=scratchie++;\n" ! 2443: "\tint bp;\n" ! 2444: "\tmov_l_rr(tmp,data);\n"); ! 2445: switch(curi->size) { ! 2446: case sz_byte: comprintf("\tshrl_b_ri(data,srcreg);\n" ! 2447: "\tbp=srcreg-1;\n"); break; ! 2448: case sz_word: comprintf("\tshrl_w_ri(data,srcreg);\n" ! 2449: "\tbp=srcreg-1;\n"); break; ! 2450: case sz_long: comprintf("\tshrl_l_ri(data,srcreg);\n" ! 2451: "\tbp=srcreg-1;\n"); break; ! 2452: default: abort(); ! 2453: } ! 2454: ! 2455: if (!noflags) { ! 2456: comprintf("\tstart_needflags();\n"); ! 2457: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2458: switch(curi->size) { ! 2459: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2460: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2461: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2462: } ! 2463: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ ! 2464: comprintf("\t live_flags();\n"); ! 2465: comprintf("\t end_needflags();\n"); ! 2466: comprintf("\t duplicate_carry();\n"); ! 2467: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2468: } ! 2469: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2470: } ! 2471: break; ! 2472: ! 2473: case i_LSL: ! 2474: comprintf("\tdont_care_flags();\n"); ! 2475: ! 2476: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 2477: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 2478: if (curi->smode!=immi) { ! 2479: if (!noflags) { ! 2480: uses_cmov; ! 2481: start_brace(); ! 2482: comprintf("\tint highmask;\n" ! 2483: "\tint cdata=scratchie++;\n" ! 2484: "\tint tmpcnt=scratchie++;\n"); ! 2485: comprintf("\tmov_l_rr(tmpcnt,cnt);\n" ! 2486: "\tand_l_ri(tmpcnt,63);\n" ! 2487: "\tmov_l_ri(cdata,0);\n" ! 2488: "\tcmov_l_rr(cdata,data,5);\n"); ! 2489: /* cdata is now either data (for shift count!=0) or ! 2490: 0 (for shift count==0) */ ! 2491: switch(curi->size) { ! 2492: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" ! 2493: "\thighmask=0x38;\n"); ! 2494: break; ! 2495: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" ! 2496: "\thighmask=0x30;\n"); ! 2497: break; ! 2498: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" ! 2499: "\thighmask=0x20;\n"); ! 2500: break; ! 2501: default: abort(); ! 2502: } ! 2503: comprintf("test_l_ri(cnt,highmask);\n" ! 2504: "mov_l_ri(scratchie,0);\n" ! 2505: "cmov_l_rr(scratchie,data,4);\n"); ! 2506: switch(curi->size) { ! 2507: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; ! 2508: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; ! 2509: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; ! 2510: default: abort(); ! 2511: } ! 2512: /* Result of shift is now in data. Now we need to determine ! 2513: the carry by shifting cdata one less */ ! 2514: comprintf("\tsub_l_ri(tmpcnt,1);\n"); ! 2515: switch(curi->size) { ! 2516: case sz_byte: comprintf("\tshll_b_rr(cdata,tmpcnt);\n");break; ! 2517: case sz_word: comprintf("\tshll_w_rr(cdata,tmpcnt);\n");break; ! 2518: case sz_long: comprintf("\tshll_l_rr(cdata,tmpcnt);\n");break; ! 2519: default: abort(); ! 2520: } ! 2521: comprintf("test_l_ri(tmpcnt,highmask);\n" ! 2522: "mov_l_ri(scratchie,0);\n" ! 2523: "cmov_l_rr(cdata,scratchie,5);\n"); ! 2524: /* And create the flags */ ! 2525: comprintf("\tstart_needflags();\n"); ! 2526: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2527: switch(curi->size) { ! 2528: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); ! 2529: comprintf("\t bt_l_ri(cdata,7);\n"); break; ! 2530: case sz_word: comprintf("\t test_w_rr(data,data);\n"); ! 2531: comprintf("\t bt_l_ri(cdata,15);\n"); break; ! 2532: case sz_long: comprintf("\t test_l_rr(data,data);\n"); ! 2533: comprintf("\t bt_l_ri(cdata,31);\n"); break; ! 2534: } ! 2535: comprintf("\t live_flags();\n"); ! 2536: comprintf("\t end_needflags();\n"); ! 2537: comprintf("\t duplicate_carry();\n"); ! 2538: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2539: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2540: } ! 2541: else { ! 2542: uses_cmov; ! 2543: start_brace(); ! 2544: comprintf("\tint highmask;\n"); ! 2545: switch(curi->size) { ! 2546: case sz_byte: comprintf("\tshll_b_rr(data,cnt);\n" ! 2547: "\thighmask=0x38;\n"); ! 2548: break; ! 2549: case sz_word: comprintf("\tshll_w_rr(data,cnt);\n" ! 2550: "\thighmask=0x30;\n"); ! 2551: break; ! 2552: case sz_long: comprintf("\tshll_l_rr(data,cnt);\n" ! 2553: "\thighmask=0x20;\n"); ! 2554: break; ! 2555: default: abort(); ! 2556: } ! 2557: comprintf("test_l_ri(cnt,highmask);\n" ! 2558: "mov_l_ri(scratchie,0);\n" ! 2559: "cmov_l_rr(scratchie,data,4);\n"); ! 2560: switch(curi->size) { ! 2561: case sz_byte: comprintf("\tmov_b_rr(data,scratchie);\n");break; ! 2562: case sz_word: comprintf("\tmov_w_rr(data,scratchie);\n");break; ! 2563: case sz_long: comprintf("\tmov_l_rr(data,scratchie);\n");break; ! 2564: default: abort(); ! 2565: } ! 2566: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2567: } ! 2568: } ! 2569: else { ! 2570: start_brace(); ! 2571: comprintf("\tint tmp=scratchie++;\n" ! 2572: "\tint bp;\n" ! 2573: "\tmov_l_rr(tmp,data);\n"); ! 2574: switch(curi->size) { ! 2575: case sz_byte: comprintf("\tshll_b_ri(data,srcreg);\n" ! 2576: "\tbp=8-srcreg;\n"); break; ! 2577: case sz_word: comprintf("\tshll_w_ri(data,srcreg);\n" ! 2578: "\tbp=16-srcreg;\n"); break; ! 2579: case sz_long: comprintf("\tshll_l_ri(data,srcreg);\n" ! 2580: "\tbp=32-srcreg;\n"); break; ! 2581: default: abort(); ! 2582: } ! 2583: ! 2584: if (!noflags) { ! 2585: comprintf("\tstart_needflags();\n"); ! 2586: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2587: switch(curi->size) { ! 2588: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2589: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2590: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2591: } ! 2592: comprintf("\t bt_l_ri(tmp,bp);\n"); /* Set C */ ! 2593: comprintf("\t live_flags();\n"); ! 2594: comprintf("\t end_needflags();\n"); ! 2595: comprintf("\t duplicate_carry();\n"); ! 2596: comprintf("if (!(needed_flags & FLAG_CZNV)) dont_care_flags();\n"); ! 2597: } ! 2598: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2599: } ! 2600: break; ! 2601: ! 2602: case i_ROL: ! 2603: mayfail; ! 2604: if (curi->smode==Dreg) { ! 2605: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" ! 2606: " FAIL(1);\n" ! 2607: " return 0;\n" ! 2608: "} \n"); ! 2609: start_brace(); ! 2610: } ! 2611: comprintf("\tdont_care_flags();\n"); ! 2612: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 2613: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 2614: start_brace (); ! 2615: ! 2616: switch(curi->size) { ! 2617: case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break; ! 2618: case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break; ! 2619: case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break; ! 2620: } ! 2621: ! 2622: if (!noflags) { ! 2623: comprintf("\tstart_needflags();\n"); ! 2624: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2625: switch(curi->size) { ! 2626: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2627: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2628: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2629: } ! 2630: comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */ ! 2631: comprintf("\t live_flags();\n"); ! 2632: comprintf("\t end_needflags();\n"); ! 2633: } ! 2634: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2635: break; ! 2636: ! 2637: case i_ROR: ! 2638: mayfail; ! 2639: if (curi->smode==Dreg) { ! 2640: comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n" ! 2641: " FAIL(1);\n" ! 2642: " return 0;\n" ! 2643: "} \n"); ! 2644: start_brace(); ! 2645: } ! 2646: comprintf("\tdont_care_flags();\n"); ! 2647: genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0); ! 2648: genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0); ! 2649: start_brace (); ! 2650: ! 2651: switch(curi->size) { ! 2652: case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break; ! 2653: case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break; ! 2654: case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break; ! 2655: } ! 2656: ! 2657: if (!noflags) { ! 2658: comprintf("\tstart_needflags();\n"); ! 2659: comprintf("\tif (needed_flags & FLAG_ZNV)\n"); ! 2660: switch(curi->size) { ! 2661: case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break; ! 2662: case sz_word: comprintf("\t test_w_rr(data,data);\n"); break; ! 2663: case sz_long: comprintf("\t test_l_rr(data,data);\n"); break; ! 2664: } ! 2665: switch(curi->size) { ! 2666: case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break; ! 2667: case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break; ! 2668: case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break; ! 2669: } ! 2670: comprintf("\t live_flags();\n"); ! 2671: comprintf("\t end_needflags();\n"); ! 2672: } ! 2673: genastore ("data", curi->dmode, "dstreg", curi->size, "data"); ! 2674: break; ! 2675: ! 2676: case i_ROXL: ! 2677: failure; ! 2678: break; ! 2679: case i_ROXR: ! 2680: failure; ! 2681: break; ! 2682: case i_ASRW: ! 2683: failure; ! 2684: break; ! 2685: case i_ASLW: ! 2686: failure; ! 2687: break; ! 2688: case i_LSRW: ! 2689: failure; ! 2690: break; ! 2691: case i_LSLW: ! 2692: failure; ! 2693: break; ! 2694: case i_ROLW: ! 2695: failure; ! 2696: break; ! 2697: case i_RORW: ! 2698: failure; ! 2699: break; ! 2700: case i_ROXLW: ! 2701: failure; ! 2702: break; ! 2703: case i_ROXRW: ! 2704: failure; ! 2705: break; ! 2706: case i_MOVEC2: ! 2707: isjump; ! 2708: failure; ! 2709: break; ! 2710: case i_MOVE2C: ! 2711: isjump; ! 2712: failure; ! 2713: break; ! 2714: case i_CAS: ! 2715: failure; ! 2716: break; ! 2717: case i_CAS2: ! 2718: failure; ! 2719: break; ! 2720: case i_MOVES: /* ignore DFC and SFC because we have no MMU */ ! 2721: isjump; ! 2722: failure; ! 2723: break; ! 2724: case i_BKPT: /* only needed for hardware emulators */ ! 2725: isjump; ! 2726: failure; ! 2727: break; ! 2728: case i_CALLM: /* not present in 68030 */ ! 2729: isjump; ! 2730: failure; ! 2731: break; ! 2732: case i_RTM: /* not present in 68030 */ ! 2733: isjump; ! 2734: failure; ! 2735: break; ! 2736: case i_TRAPcc: ! 2737: isjump; ! 2738: failure; ! 2739: break; ! 2740: case i_DIVL: ! 2741: isjump; ! 2742: failure; ! 2743: break; ! 2744: case i_MULL: ! 2745: if (!noflags) { ! 2746: failure; ! 2747: break; ! 2748: } ! 2749: comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); ! 2750: comprintf("\tint r2=(extra>>12)&7;\n" ! 2751: "\tint tmp=scratchie++;\n"); ! 2752: ! 2753: genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0); ! 2754: /* The two operands are in dst and r2 */ ! 2755: comprintf("\tif (extra&0x0400) {\n" /* Need full 64 bit result */ ! 2756: "\tint r3=(extra&7);\n" ! 2757: "\tmov_l_rr(r3,dst);\n"); /* operands now in r3 and r2 */ ! 2758: comprintf("\tif (extra&0x0800) { \n" /* signed */ ! 2759: "\t\timul_64_32(r2,r3);\n" ! 2760: "\t} else { \n" ! 2761: "\t\tmul_64_32(r2,r3);\n" ! 2762: "\t} \n"); ! 2763: /* The result is in r2/tmp, with r2 holding the lower 32 bits */ ! 2764: comprintf("\t} else {\n"); /* Only want 32 bit result */ ! 2765: /* operands in dst and r2, result foes into r2 */ ! 2766: /* shouldn't matter whether it's signed or unsigned?!? */ ! 2767: comprintf("\timul_32_32(r2,dst);\n" ! 2768: "\t}\n"); ! 2769: break; ! 2770: ! 2771: case i_BFTST: ! 2772: case i_BFEXTU: ! 2773: case i_BFCHG: ! 2774: case i_BFEXTS: ! 2775: case i_BFCLR: ! 2776: case i_BFFFO: ! 2777: case i_BFSET: ! 2778: case i_BFINS: ! 2779: failure; ! 2780: break; ! 2781: case i_PACK: ! 2782: failure; ! 2783: break; ! 2784: case i_UNPK: ! 2785: failure; ! 2786: break; ! 2787: case i_TAS: ! 2788: failure; ! 2789: break; ! 2790: case i_FPP: ! 2791: mayfail; ! 2792: comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); ! 2793: comprintf("\tcomp_fpp_opp(opcode,extra);\n"); ! 2794: break; ! 2795: case i_FBcc: ! 2796: isjump; ! 2797: uses_cmov; ! 2798: mayfail; ! 2799: comprintf("\tcomp_fbcc_opp(opcode);\n"); ! 2800: break; ! 2801: case i_FDBcc: ! 2802: isjump; ! 2803: failure; ! 2804: break; ! 2805: case i_FScc: ! 2806: mayfail; ! 2807: uses_cmov; ! 2808: comprintf("\tuae_u16 extra=%s;\n",gen_nextiword()); ! 2809: comprintf("\tcomp_fscc_opp(opcode,extra);\n"); ! 2810: break; ! 2811: case i_FTRAPcc: ! 2812: isjump; ! 2813: failure; ! 2814: break; ! 2815: case i_FSAVE: ! 2816: failure; ! 2817: break; ! 2818: case i_FRESTORE: ! 2819: failure; ! 2820: break; ! 2821: ! 2822: case i_CINVL: ! 2823: case i_CINVP: ! 2824: case i_CINVA: ! 2825: isjump; /* Not really, but it's probably a good idea to stop ! 2826: translating at this point */ ! 2827: failure; ! 2828: comprintf ("\tflush_icache();\n"); /* Differentiate a bit more? */ ! 2829: break; ! 2830: case i_CPUSHL: ! 2831: case i_CPUSHP: ! 2832: case i_CPUSHA: ! 2833: isjump; /* Not really, but it's probably a good idea to stop ! 2834: translating at this point */ ! 2835: failure; ! 2836: break; ! 2837: case i_MOVE16: ! 2838: //if ((opcode & 0xfff8) == 0xf620) { ! 2839: genmov16(opcode,curi); ! 2840: //} else { ! 2841: // isjump; ! 2842: // failure; ! 2843: //} ! 2844: break; ! 2845: ! 2846: case i_MMUOP030: ! 2847: case i_PFLUSHN: ! 2848: case i_PFLUSH: ! 2849: case i_PFLUSHAN: ! 2850: case i_PFLUSHA: ! 2851: case i_PLPAR: ! 2852: case i_PLPAW: ! 2853: case i_PTESTR: ! 2854: case i_PTESTW: ! 2855: case i_LPSTOP: ! 2856: isjump; ! 2857: failure; ! 2858: break; ! 2859: default: ! 2860: abort (); ! 2861: break; ! 2862: } ! 2863: comprintf("%s",endstr); ! 2864: finish_braces (); ! 2865: sync_m68k_pc (); ! 2866: if (global_mayfail) ! 2867: comprintf("\tif (failure) m68k_pc_offset=m68k_pc_offset_thisinst;\n"); ! 2868: return global_failure; ! 2869: } ! 2870: ! 2871: static void ! 2872: generate_includes (FILE * f, int bigger) ! 2873: { ! 2874: fprintf (f, "#include \"sysconfig.h\"\n"); ! 2875: fprintf (f, "#if defined(JIT)\n"); ! 2876: fprintf (f, "#include \"sysdeps.h\"\n"); ! 2877: if (bigger) ! 2878: fprintf (f, "#include \"options.h\"\n"); ! 2879: fprintf (f, "#include \"memory.h\"\n"); ! 2880: fprintf (f, "#include \"newcpu.h\"\n"); ! 2881: fprintf (f, "#include \"comptbl.h\"\n"); ! 2882: } ! 2883: ! 2884: static int postfix; ! 2885: ! 2886: static void ! 2887: generate_one_opcode (int rp, int noflags) ! 2888: { ! 2889: int i; ! 2890: uae_u16 smsk, dmsk; ! 2891: long int opcode = opcode_map[rp]; ! 2892: int aborted=0; ! 2893: int have_srcreg=0; ! 2894: int have_dstreg=0; ! 2895: ! 2896: if (table68k[opcode].mnemo == i_ILLG ! 2897: || table68k[opcode].clev > cpu_level) ! 2898: return; ! 2899: ! 2900: for (i = 0; lookuptab[i].name[0]; i++) ! 2901: { ! 2902: if (table68k[opcode].mnemo == lookuptab[i].mnemo) ! 2903: break; ! 2904: } ! 2905: ! 2906: if (table68k[opcode].handler != -1) ! 2907: return; ! 2908: ! 2909: switch (table68k[opcode].stype) ! 2910: { ! 2911: case 0: smsk = 7; break; ! 2912: case 1: smsk = 255; break; ! 2913: case 2: smsk = 15; break; ! 2914: case 3: smsk = 7; break; ! 2915: case 4: smsk = 7; break; ! 2916: case 5: smsk = 63; break; ! 2917: case 7: smsk = 3; break; ! 2918: default: abort (); ! 2919: } ! 2920: dmsk = 7; ! 2921: ! 2922: next_cpu_level = -1; ! 2923: if (table68k[opcode].suse ! 2924: && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 ! 2925: && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 ! 2926: && table68k[opcode].smode != absw && table68k[opcode].smode != absl ! 2927: && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16) ! 2928: { ! 2929: have_srcreg=1; ! 2930: if (table68k[opcode].spos == -1) ! 2931: { ! 2932: if (((int) table68k[opcode].sreg) >= 128) ! 2933: comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg); ! 2934: else ! 2935: comprintf ("\tuae_s32 srcreg = %d;\n", (int) table68k[opcode].sreg); ! 2936: } ! 2937: else ! 2938: { ! 2939: char source[100]; ! 2940: int pos = table68k[opcode].spos; ! 2941: ! 2942: if (pos) ! 2943: sprintf (source, "((opcode >> %d) & %d)", pos, smsk); ! 2944: else ! 2945: sprintf (source, "(opcode & %d)", smsk); ! 2946: ! 2947: if (table68k[opcode].stype == 3) ! 2948: comprintf ("\tuae_s32 srcreg = imm8_table[%s];\n", source); ! 2949: else if (table68k[opcode].stype == 1) ! 2950: comprintf ("\tuae_s32 srcreg = (uae_s32)(uae_s8)%s;\n", source); ! 2951: else ! 2952: comprintf ("\tuae_s32 srcreg = %s;\n", source); ! 2953: } ! 2954: } ! 2955: if (table68k[opcode].duse ! 2956: /* Yes, the dmode can be imm, in case of LINK or DBcc */ ! 2957: && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0 ! 2958: && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2 ! 2959: && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) ! 2960: { ! 2961: have_dstreg=1; ! 2962: if (table68k[opcode].dpos == -1) ! 2963: { ! 2964: if (((int) table68k[opcode].dreg) >= 128) ! 2965: comprintf ("\tuae_s32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg); ! 2966: else ! 2967: comprintf ("\tuae_s32 dstreg = %d;\n", (int) table68k[opcode].dreg); ! 2968: } ! 2969: else ! 2970: { ! 2971: int pos = table68k[opcode].dpos; ! 2972: ! 2973: if (pos) ! 2974: comprintf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n", ! 2975: pos, dmsk); ! 2976: else ! 2977: comprintf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk); ! 2978: } ! 2979: } ! 2980: ! 2981: if (have_srcreg && have_dstreg && ! 2982: (table68k[opcode].dmode==Areg || ! 2983: table68k[opcode].dmode==Aind || ! 2984: table68k[opcode].dmode==Aipi || ! 2985: table68k[opcode].dmode==Apdi || ! 2986: table68k[opcode].dmode==Ad16 || ! 2987: table68k[opcode].dmode==Ad8r) && ! 2988: (table68k[opcode].smode==Areg || ! 2989: table68k[opcode].smode==Aind || ! 2990: table68k[opcode].smode==Aipi || ! 2991: table68k[opcode].smode==Apdi || ! 2992: table68k[opcode].smode==Ad16 || ! 2993: table68k[opcode].smode==Ad8r) ! 2994: ) { ! 2995: comprintf("\tuae_u32 dodgy=(srcreg==(uae_s32)dstreg);\n"); ! 2996: } ! 2997: else { ! 2998: comprintf("\tuae_u32 dodgy=0;\n"); ! 2999: } ! 3000: comprintf("\tuae_u32 m68k_pc_offset_thisinst=m68k_pc_offset;\n"); ! 3001: comprintf("\tm68k_pc_offset+=2;\n"); ! 3002: ! 3003: aborted=gen_opcode (opcode); ! 3004: { ! 3005: int flags=0; ! 3006: if (global_isjump) flags|=1; ! 3007: if (long_opcode) flags|=2; ! 3008: if (global_cmov) flags|=4; ! 3009: if (global_isaddx) flags|=8; ! 3010: if (global_iscjump) flags|=16; ! 3011: comprintf ("return 0;\n"); ! 3012: comprintf ("}\n"); ! 3013: ! 3014: char name[100] = { 0 }; ! 3015: for (int k = 0; lookuptab[i].name[k]; k++) ! 3016: name[k] = lookuptab[i].name[k]; ! 3017: ! 3018: if (aborted) { ! 3019: fprintf (stblfile, "{ NULL, %ld, 0x%08x }, /* %s */\n", opcode, flags, name); ! 3020: com_discard(); ! 3021: } else { ! 3022: if (noflags) { ! 3023: fprintf (stblfile, "{ op_%lx_%d_comp_nf, %ld, 0x%08x }, /* %s */\n", opcode, postfix, opcode, flags, name); ! 3024: fprintf (headerfile, "extern compop_func op_%lx_%d_comp_nf;\n", opcode, postfix); ! 3025: printf ("unsigned long REGPARAM2 op_%lx_%d_comp_nf(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, name); ! 3026: } else { ! 3027: fprintf (stblfile, "{ op_%lx_%d_comp_ff, %ld, 0x%08x }, /* %s */\n", opcode, postfix, opcode, flags, name); ! 3028: fprintf (headerfile, "extern compop_func op_%lx_%d_comp_ff;\n", opcode, postfix); ! 3029: printf ("unsigned long REGPARAM2 op_%lx_%d_comp_ff(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, name); ! 3030: } ! 3031: com_flush(); ! 3032: } ! 3033: } ! 3034: opcode_next_clev[rp] = next_cpu_level; ! 3035: opcode_last_postfix[rp] = postfix; ! 3036: } ! 3037: ! 3038: static void ! 3039: generate_func (int noflags) ! 3040: { ! 3041: int i, j, rp; ! 3042: ! 3043: using_prefetch = 0; ! 3044: using_exception_3 = 0; ! 3045: for (i = 0; i < 1; i++) /* We only do one level! */ ! 3046: { ! 3047: cpu_level = 5 - i; ! 3048: postfix = i; ! 3049: ! 3050: if (noflags) ! 3051: fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_nf[] = {\n", postfix); ! 3052: else ! 3053: fprintf (stblfile, "const struct comptbl op_smalltbl_%d_comp_ff[] = {\n", postfix); ! 3054: ! 3055: ! 3056: /* sam: this is for people with low memory (eg. me :)) */ ! 3057: printf ("\n" ! 3058: "#if !defined(PART_1) && !defined(PART_2) && " ! 3059: "!defined(PART_3) && !defined(PART_4) && " ! 3060: "!defined(PART_5) && !defined(PART_6) && " ! 3061: "!defined(PART_7) && !defined(PART_8)" ! 3062: "\n" ! 3063: "#define PART_1 1\n" ! 3064: "#define PART_2 1\n" ! 3065: "#define PART_3 1\n" ! 3066: "#define PART_4 1\n" ! 3067: "#define PART_5 1\n" ! 3068: "#define PART_6 1\n" ! 3069: "#define PART_7 1\n" ! 3070: "#define PART_8 1\n" ! 3071: "#endif\n\n" ! 3072: "void setzflg_l(uae_u32);\n" ! 3073: "void comp_fpp_opp(void);\n" ! 3074: "void comp_fscc_opp(void);\n" ! 3075: "void comp_fbcc_opp(void);\n\n"); ! 3076: ! 3077: rp = 0; ! 3078: for (j = 1; j <= 8; ++j) ! 3079: { ! 3080: int k = (j * nr_cpuop_funcs) / 8; ! 3081: printf ("#ifdef PART_%d\n", j); ! 3082: for (; rp < k; rp++) ! 3083: generate_one_opcode (rp,noflags); ! 3084: printf ("#endif\n\n"); ! 3085: } ! 3086: ! 3087: fprintf (stblfile, "{ 0, 65536, 0 }};\n"); ! 3088: } ! 3089: ! 3090: } ! 3091: ! 3092: int ! 3093: main (int argc, char **argv) ! 3094: { ! 3095: read_table68k (); ! 3096: do_merges (); ! 3097: ! 3098: opcode_map = xmalloc (int, nr_cpuop_funcs); ! 3099: opcode_last_postfix = xmalloc (int, nr_cpuop_funcs); ! 3100: opcode_next_clev = xmalloc (int, nr_cpuop_funcs); ! 3101: counts = xmalloc (unsigned long, 65536); ! 3102: read_counts (); ! 3103: ! 3104: /* It would be a lot nicer to put all in one file (we'd also get rid of ! 3105: * cputbl.h that way), but cpuopti can't cope. That could be fixed, but ! 3106: * I don't dare to touch the 68k version. */ ! 3107: ! 3108: headerfile = fopen ("jit/comptbl.h", "wb"); ! 3109: ! 3110: fprintf (headerfile, "" \ ! 3111: "#ifdef NOFLAGS_SUPPORT\n" \ ! 3112: "/* 68040 */\n" \ ! 3113: "extern const struct comptbl op_smalltbl_0_nf[];\n" \ ! 3114: "#endif\n" \ ! 3115: "extern const struct comptbl op_smalltbl_0_comp_nf[];\n" \ ! 3116: "extern const struct comptbl op_smalltbl_0_comp_ff[];\n" \ ! 3117: ""); ! 3118: ! 3119: stblfile = fopen ("jit/compstbl.cpp", "wb"); ! 3120: freopen ("jit/compemu.cpp", "wb", stdout); ! 3121: ! 3122: generate_includes (stdout, 1); ! 3123: generate_includes (stblfile, 1); ! 3124: ! 3125: printf("#include \"compemu.h\"\n"); ! 3126: ! 3127: noflags=0; ! 3128: generate_func (noflags); ! 3129: ! 3130: ! 3131: opcode_map = xmalloc (int, nr_cpuop_funcs); ! 3132: opcode_last_postfix = xmalloc (int, nr_cpuop_funcs); ! 3133: opcode_next_clev = xmalloc (int, nr_cpuop_funcs); ! 3134: counts = xmalloc (unsigned long, 65536); ! 3135: read_counts (); ! 3136: noflags=1; ! 3137: generate_func (noflags); ! 3138: ! 3139: printf ("#endif\n"); ! 3140: fprintf (stblfile, "#endif\n"); ! 3141: ! 3142: free (table68k); ! 3143: return 0; ! 3144: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.