|
|
1.1 ! root 1: /*****************************************************************************/ ! 2: /* Generator - Sega Genesis emulation - (c) James Ponder 1997-1998 */ ! 3: /*****************************************************************************/ ! 4: /* */ ! 5: /* compile-arm.c */ ! 6: /* */ ! 7: /*****************************************************************************/ ! 8: ! 9: #include <stdio.h> ! 10: #include <stdlib.h> ! 11: ! 12: #include <sys/swis.h> ! 13: #include <sys/os.h> ! 14: ! 15: #include <generator.h> ! 16: #include <cpu68k.h> ! 17: #include <mem68k.h> ! 18: ! 19: #define MAXBLOCKSIZE 10240 ! 20: #define true 1 ! 21: #define false 0 ! 22: ! 23: /* static global variables */ ! 24: ! 25: static uint8 *curpos; ! 26: static sint32 regstate[6]; /* 0 = unused, 1 = used, 2 = updated */ ! 27: static sint32 regnum[6]; /* register number or -1 */ ! 28: static sint32 regtimer[6]; /* instructions since used */ ! 29: ! 30: /* forward references */ ! 31: ! 32: inline uint8 *compile_w(uint32 i) ! 33: { ! 34: *(uint32 *)curpos = i; ! 35: curpos+= 4; ! 36: return curpos; ! 37: } ! 38: ! 39: /*** compile_initregs - set all registers to unused ***/ ! 40: ! 41: void compile_initregs(void) ! 42: { ! 43: int i; ! 44: ! 45: for (i = 1; i < 6; i++) { ! 46: regstate[i] = 0; ! 47: regnum[i] = -1; ! 48: regtimer[i] = 0; ! 49: } ! 50: } ! 51: ! 52: /*** compile_getreg - given a 68000 register or -1 return an ARM register ***/ ! 53: ! 54: int compile_getreg(int reg) ! 55: { ! 56: int i; ! 57: int free = -1; ! 58: int reg_last = -1; ! 59: int reg_lasttime = -1; ! 60: ! 61: /* check for an ARM register already holding the 68000 register or a free ! 62: ARM register if we can't find it */ ! 63: ! 64: for (i = 1; i < 6; i++) { ! 65: if (reg != -1 && regstate[i] && regnum[i] == reg) { ! 66: regtimer[i] = 0; ! 67: return i; ! 68: } ! 69: if (!regstate[i]) { ! 70: free = i; ! 71: } ! 72: } ! 73: if (free == -1) { ! 74: /* no free registers, find a register not holding a specific 68000 ! 75: register if pos - if we can't find one then use the oldest 68000 ! 76: register cached even if it was used this instruction */ ! 77: ! 78: for (i = 1; i < 6; i++) { ! 79: if (regtimer[i] && regnum[i] == -1) { ! 80: free = i; ! 81: } else { ! 82: if (regtimer[i] >= reg_lasttime) { ! 83: /* we always prefer higher registers */ ! 84: reg_last = i; ! 85: reg_lasttime = regtimer[i]; ! 86: } ! 87: } ! 88: } ! 89: if (free == -1) { ! 90: free = reg_last; ! 91: if (free == -1) { ! 92: fprintf(stderr, "free: %d\n", free); ! 93: fprintf(stderr, "reg_last: %d\n", reg_last); ! 94: fprintf(stderr, "reg_lasttime: %d\n", reg_lasttime); ! 95: fprintf(stderr, "5 state: %d\n", regstate[5]); ! 96: fprintf(stderr, "5 num: %d\n", regnum[5]); ! 97: fprintf(stderr, "5 timer: %d\n", regtimer[5]); ! 98: compile_w(0); ! 99: compile_w((uint32)(-1)); ! 100: compile_finalregs(); ! 101: fprintf(stderr, "5 state: %d\n", regstate[5]); ! 102: fprintf(stderr, "5 num: %d\n", regnum[5]); ! 103: fprintf(stderr, "5 timer: %d\n", regtimer[5]); ! 104: fprintf(stderr, "Insufficient registers\n"); ! 105: exit(1); ! 106: } ! 107: if (regstate[reg_last] == 2) { ! 108: /* STR r(reg_last),[r8,#x] */ ! 109: compile_w(0xE5880000 | (regnum[reg_last]*4) | reg_last<<12); ! 110: } ! 111: } ! 112: } ! 113: regstate[free] = 1; ! 114: regnum[free] = reg; ! 115: regtimer[free] = 0; ! 116: if (reg != -1) { ! 117: compile_w(0xE5980000 | (reg*4) | free<<12); /* LDR rfree,[r8,#x] */ ! 118: } ! 119: return free; ! 120: } ! 121: ! 122: /*** compile_findreg - given a 68000 register return an ARM register ***/ ! 123: ! 124: int compile_findreg(int reg) ! 125: { ! 126: int i; ! 127: ! 128: for (i = 1; i < 6; i++) { ! 129: if (regstate[i] && regnum[i] == reg) { ! 130: return i; ! 131: } ! 132: } ! 133: return -1; ! 134: } ! 135: ! 136: /*** compile_updatereg - we have changed a register ***/ ! 137: ! 138: void compile_updatereg(int reg) ! 139: { ! 140: if (!regstate[reg]) { ! 141: fprintf(stderr, "Compiler error - updatereg %d\n", reg); ! 142: exit(1); ! 143: } ! 144: regstate[reg] = 2; ! 145: } ! 146: ! 147: /*** compile_inctimer - update timers on registers ***/ ! 148: ! 149: void compile_inctimer(void) { ! 150: int i; ! 151: ! 152: for (i = 1; i < 6; i++) { ! 153: if (regstate[i]) { ! 154: if (regnum[i] == -1) ! 155: regstate[i] = 0; ! 156: else ! 157: regtimer[i]++; ! 158: } ! 159: } ! 160: } ! 161: ! 162: /*** compile_finalregs - write back all changed registers ***/ ! 163: ! 164: void compile_finalregs(void) { ! 165: int i; ! 166: ! 167: for (i = 1; i < 6; i++) { ! 168: if (regstate[i] == 2 && regnum[i] != -1) { ! 169: compile_w(0xE5880000 | (regnum[i]*4) | i<<12); /* STR ri,[r8,#x] */ ! 170: } ! 171: regstate[i] = 0; ! 172: regnum[i] = -1; ! 173: regtimer[i] = 0; ! 174: } ! 175: } ! 176: ! 177: void compile_ea(t_iib *iib, t_ipc *ipc, t_type type, int update, int *reg) ! 178: { ! 179: t_datatype datatype = type ? iib->dtype : iib->stype; ! 180: int reg68; ! 181: int a, b, c, pos; ! 182: ! 183: /* compile EA to register(s) regea/regval */ ! 184: ! 185: switch(datatype) { ! 186: case dt_Dreg: ! 187: case dt_Areg: ! 188: *reg = -1; ! 189: break; ! 190: case dt_Aind: ! 191: reg68 = 8 + ((ipc->opcode >> (type ? iib->dbitpos : iib->sbitpos)) & 7); ! 192: a = compile_getreg(reg68); ! 193: b = compile_getreg(-1); /* effective address */ ! 194: compile_w(0xE1A00000 | b<<12 | a); /* MOV rb,ra */ ! 195: *reg = b; ! 196: break; ! 197: case dt_Ainc: ! 198: reg68 = 8 + ((ipc->opcode >> (type ? iib->dbitpos : iib->sbitpos)) & 7); ! 199: a = compile_getreg(reg68); /* 68000 register */ ! 200: if (update) { ! 201: b = compile_getreg(-1); /* effective address */ ! 202: regnum[a] = -1; ! 203: regnum[b] = reg68; /* swap */ ! 204: /* ADD rb,ra,#size */ ! 205: compile_w(0xE2800000 | 1<<(iib->size-1) | a<<16 | b<<12); ! 206: compile_updatereg(b); ! 207: } ! 208: *reg = a; ! 209: break; ! 210: case dt_Adec: ! 211: reg68 = 8 + ((ipc->opcode >> (type ? iib->dbitpos : iib->sbitpos)) & 7); ! 212: a = compile_getreg(reg68); /* 68000 register */ ! 213: if (update) { ! 214: /* SUB ra,ra,#size */ ! 215: compile_w(0xE2400000 | 1<<(iib->size-1) | a<<16 | a<<12); ! 216: compile_updatereg(a); ! 217: } ! 218: *reg = a; ! 219: break; ! 220: case dt_Adis: ! 221: reg68 = 8 + ((ipc->opcode >> (type ? iib->dbitpos : iib->sbitpos)) & 7); ! 222: a = compile_getreg(reg68); /* 68000 register */ ! 223: b = compile_getreg(-1); /* effective address */ ! 224: pos = (uint32)(type ? &ipc->dst : &ipc->src) - (uint32)ipc; ! 225: /* LDR rb,[r6,#pos] ADD rb,rb,ra */ ! 226: compile_w(0xE5960000 | pos | b<<12); ! 227: compile_w(0xE0800000 | b<<16 | b<<12 | a); ! 228: *reg = b; ! 229: break; ! 230: case dt_Aidx: ! 231: reg68 = 8 + ((ipc->opcode >> (type ? iib->dbitpos : iib->sbitpos)) & 7); ! 232: b = compile_getreg(-1); /* effective address */ ! 233: c = compile_getreg(((type ? ipc->dst : ipc->src)>>28) & 15); /* idx reg */ ! 234: pos = (uint32)(type ? &ipc->dst : &ipc->src) - (uint32)ipc; ! 235: /* LDR rb,[r6,#pos] MOV rb,rb,LSL#8 MOV rb,rb,ASR#8 */ ! 236: compile_w(0xE5960000 | pos | b<<12); ! 237: compile_w(0xE1A00400 | b<<12 | b); ! 238: compile_w(0xE1A00440 | b<<12 | b); ! 239: if ((ipc->src>>27) & 1) { ! 240: /* ADD rb,rb,rc */ ! 241: compile_w(0xE0800000 | b<<16 | b<<12 | c); ! 242: } else { ! 243: /* MOV r14,rc,LSL#16 MOV r14,r14,ASR#16 ADD rb,rb,r14 */ ! 244: compile_w(0xE1A0E800 | c); ! 245: compile_w(0xE1A0E84E); ! 246: compile_w(0xE080000E | b<<16 | b<<12); ! 247: } ! 248: a = compile_getreg(reg68); /* 68000 register */ ! 249: /* ADD rb,rb,ra */ ! 250: compile_w(0xE0800000 | b<<16 | b<<12 | a); ! 251: *reg = b; ! 252: break; ! 253: case dt_AbsW: ! 254: case dt_AbsL: ! 255: case dt_Pdis: ! 256: a = compile_getreg(-1); /* effective address */ ! 257: pos = (uint32)(type ? &ipc->dst : &ipc->src) - (uint32)ipc; ! 258: /* LDR ra,[r6,#pos] */ ! 259: compile_w(0xE5960000 | pos | a<<12); ! 260: *reg = a; ! 261: break; ! 262: case dt_Pidx: ! 263: b = compile_getreg(-1); /* effective address */ ! 264: c = compile_getreg(((type ? ipc->dst : ipc->src)>>28) & 15); /* idx reg */ ! 265: pos = (uint32)(type ? &ipc->dst : &ipc->src) - (uint32)ipc; ! 266: /* LDR rb,[r6,#pos] MOV rb,rb,LSL#8 MOV rb,rb,ASL#8 */ ! 267: compile_w(0xE5960000 | pos | b<<12); ! 268: compile_w(0xE1A00400 | b<<12 | b); ! 269: compile_w(0xE1A00440 | b<<12 | b); ! 270: if ((ipc->src>>27) & 1) { ! 271: /* ADD rb,rb,rc */ ! 272: compile_w(0xE0800000 | b<<16 | b<<12 | c); ! 273: } else { ! 274: /* MOV r14,rc,LSL#16 MOV r14,r14,ASR#16 ADD rb,rb,r14 */ ! 275: compile_w(0xE1A0E800 | c); ! 276: compile_w(0xE1A0E84E); ! 277: compile_w(0xE080000E | b<<16 | b<<12); ! 278: } ! 279: *reg = b; ! 280: break; ! 281: case dt_ImmB: ! 282: case dt_ImmW: ! 283: case dt_ImmL: ! 284: case dt_ImmS: ! 285: case dt_Imm3: ! 286: case dt_Imm4: ! 287: case dt_Imm8: ! 288: case dt_Imm8s: ! 289: *reg = -1; ! 290: break; ! 291: default: ! 292: fprintf(stderr, "Invalid datatype %d\n", datatype); ! 293: exit(1); ! 294: } ! 295: } ! 296: ! 297: void compile_eaval(t_iib *iib, t_ipc *ipc, t_type type, int update, ! 298: int eareg, int *eaval) ! 299: { ! 300: t_datatype datatype = type ? iib->dtype : iib->stype; ! 301: int reg68; ! 302: int a, b, pos; ! 303: ! 304: /* compile EA value */ ! 305: ! 306: switch(datatype) { ! 307: case dt_Dreg: ! 308: case dt_Areg: ! 309: reg68 = ((datatype == dt_Areg ? 8 : 0) + ! 310: ((ipc->opcode >> (type ? iib->dbitpos : iib->sbitpos)) & 7)); ! 311: a = compile_getreg(reg68); ! 312: b = compile_getreg(-1); ! 313: switch(iib->size) { ! 314: case sz_byte: ! 315: compile_w(0xE20000FF | b<<12 | a<<16); /* AND rb,ra,#&FF */ ! 316: break; ! 317: case sz_word: ! 318: compile_w(0xE1A00800 | b<<12 | a); /* MOV rb,ra,LSL#16 */ ! 319: compile_w(0xE1A00820 | b<<12 | b); /* MOV rb,rb,LSR#16 */ ! 320: break; ! 321: case sz_long: ! 322: compile_w(0xE1A00000 | b<<12 | a); /* MOV rb,ra */ ! 323: break; ! 324: default: ! 325: fprintf(stderr, "Invalid size %d\n", iib->size); ! 326: exit(1); ! 327: } ! 328: *eaval = b; ! 329: break; ! 330: case dt_Aind: ! 331: case dt_Ainc: ! 332: case dt_Adec: ! 333: case dt_Adis: ! 334: case dt_Aidx: ! 335: case dt_AbsW: ! 336: case dt_AbsL: ! 337: case dt_Pdis: ! 338: case dt_Pidx: ! 339: a = compile_getreg(-1); ! 340: compile_w(0xE92D100E); /* STMFD r13!,{r1-r3,r12} */ ! 341: compile_w(0xE3C004FF | eareg<<16); /* BIC r0,eareg,#&FF000000 */ ! 342: compile_w(0xE1A03620); /* MOV r3,r0,LSR#12 */ ! 343: compile_w(0xE59F2004); /* LDR r2,[PC,#4] */ ! 344: compile_w(0xE28FE004); /* ADD r14,PC,#4 */ ! 345: compile_w(0xE792F103); /* LDR PC,[r2,r3,LSL#2]; */ ! 346: /* EQUD <array address> */ ! 347: switch (iib->size) { ! 348: case sz_byte: ! 349: compile_w((uint32)mem68k_fetch_byte); ! 350: break; ! 351: case sz_word: ! 352: compile_w((uint32)mem68k_fetch_word); ! 353: break; ! 354: case sz_long: ! 355: compile_w((uint32)mem68k_fetch_long); ! 356: break; ! 357: default: ! 358: fprintf(stderr, "Invalid size %d\n", iib->size); ! 359: exit(1); ! 360: } ! 361: compile_w(0xE8BD100E); /* LDMFD r13!,{r1-r3,r12} */ ! 362: compile_w(0xE1A00000 | a<<12); /* MOV ra, r0 */ ! 363: *eaval = a; ! 364: break; ! 365: case dt_ImmB: ! 366: a = compile_getreg(-1); ! 367: /* MOV eaval,#data */ ! 368: compile_w(0xE3A00000 | (type ? ipc->dst : ipc->src) | a<<12); ! 369: *eaval = a; ! 370: break; ! 371: case dt_ImmW: ! 372: case dt_ImmL: ! 373: case dt_Imm3: /* I want optimising */ ! 374: case dt_Imm4: ! 375: case dt_Imm8: ! 376: case dt_Imm8s: ! 377: a = compile_getreg(-1); ! 378: pos = (uint32)(type ? &ipc->dst : &ipc->src) - (uint32)ipc; ! 379: /* LDR eaval,[r6,#pos] */ ! 380: compile_w(0xE5960000 | pos | a<<12); ! 381: *eaval = a; ! 382: break; ! 383: case dt_ImmS: ! 384: a = compile_getreg(-1); ! 385: /* MOV a,#val */ ! 386: compile_w(0xE3A00000 | iib->immvalue | a<<12); ! 387: *eaval = a; ! 388: break; ! 389: default: ! 390: fprintf(stderr, "Invalid datatype %d\n", datatype); ! 391: exit(1); ! 392: } ! 393: } ! 394: ! 395: void compile_eastore(t_iib *iib, t_ipc *ipc, t_type type, int eareg, ! 396: int eaval) ! 397: { ! 398: t_datatype datatype = type ? iib->dtype : iib->stype; ! 399: int reg68; ! 400: int a, b, pos; ! 401: ! 402: /* store EA value */ ! 403: ! 404: switch(datatype) { ! 405: case dt_Dreg: ! 406: case dt_Areg: ! 407: reg68 = ((datatype == dt_Areg ? 8 : 0) + ! 408: ((ipc->opcode >> (type ? iib->dbitpos : iib->sbitpos)) & 7)); ! 409: a = compile_findreg(reg68); ! 410: if (a == eaval) { ! 411: fprintf(stderr, "Compiler error - eastore\n"); ! 412: exit(1); ! 413: } ! 414: switch(iib->size) { ! 415: case sz_byte: ! 416: if (a == -1) ! 417: a = compile_getreg(reg68); ! 418: compile_w(0xE3C000FF | a<<16 | a<<12); /* BIC ra,ra,#&FF */ ! 419: compile_w(0xE1800000 | a<<16 | a<<12 | eaval); /* ORR ra,ra,eaval */ ! 420: compile_updatereg(a); ! 421: break; ! 422: case sz_word: ! 423: if (a == -1) ! 424: a = compile_getreg(reg68); ! 425: compile_w(0xE1A00820 | a<<12 | a); /* MOV ra,ra,LSR#16 */ ! 426: /* ORR ra,eaval,ra,LSL#16 */ ! 427: compile_w(0xE1800800 | eaval<<16 | a<<12 | a); ! 428: compile_updatereg(a); ! 429: break; ! 430: case sz_long: ! 431: if (a != -1) { ! 432: /* the 68000 reg is in an ARM register */ ! 433: regnum[a] = -1; ! 434: regnum[eaval] = reg68; ! 435: regstate[eaval] = 2; /* needs writing back */ ! 436: } else { ! 437: /* the 68000 reg is not in an ARM reg and we're writing all 32 ! 438: bits so we can just name the ARM reg as the 68000 reg */ ! 439: regnum[eaval] = reg68; ! 440: regstate[eaval] = 2; /* needs writing back */ ! 441: } ! 442: break; ! 443: default: ! 444: fprintf(stderr, "Invalid size %d\n", iib->size); ! 445: exit(1); ! 446: } ! 447: break; ! 448: case dt_Aind: ! 449: case dt_Ainc: ! 450: case dt_Adec: ! 451: case dt_Adis: ! 452: case dt_Aidx: ! 453: case dt_AbsW: ! 454: case dt_AbsL: ! 455: case dt_Pdis: ! 456: case dt_Pidx: ! 457: compile_w(0xE92D100E); /* STMFD r13!,{r1-r3,r12} */ ! 458: compile_w(0xE3C004FF | eareg<<16); /* BIC r0,eareg,#&FF000000 */ ! 459: compile_w(0xE1A01000 | eaval); /* MOV r1,eaval */ ! 460: compile_w(0xE1A03620); /* MOV r3,r0,LSR#12 */ ! 461: compile_w(0xE59F2004); /* LDR r2,[PC,#4] */ ! 462: compile_w(0xE28FE004); /* ADD r14,PC,#4 */ ! 463: compile_w(0xE792F103); /* LDR PC,[r2,r3,LSL#2]; */ ! 464: /* EQUD <array address> */ ! 465: switch (iib->size) { ! 466: case sz_byte: ! 467: compile_w((uint32)mem68k_store_byte); ! 468: break; ! 469: case sz_word: ! 470: compile_w((uint32)mem68k_store_word); ! 471: break; ! 472: case sz_long: ! 473: compile_w((uint32)mem68k_store_long); ! 474: break; ! 475: default: ! 476: fprintf(stderr, "Invalid size %d\n", iib->size); ! 477: exit(1); ! 478: } ! 479: compile_w(0xE8BD100E); /* LDMFD r13!,{r1-r3,r12} */ ! 480: break; ! 481: case dt_ImmB: ! 482: case dt_ImmW: ! 483: case dt_ImmL: ! 484: case dt_Imm3: /* I want optimising */ ! 485: case dt_Imm4: ! 486: case dt_Imm8: ! 487: case dt_Imm8s: ! 488: case dt_ImmS: ! 489: default: ! 490: fprintf(stderr, "Invalid datatype %d\n", datatype); ! 491: exit(1); ! 492: } ! 493: } ! 494: ! 495: void compile_clrflag_v(t_iib *iib) ! 496: { ! 497: compile_w(0xE3C99000 | SR_VFLAG); /* BIC r9,r9,#SR_VFLAG */ ! 498: } ! 499: ! 500: void compile_clrflag_c(t_iib *iib) ! 501: { ! 502: compile_w(0xE3C99000 | SR_CFLAG); /* BIC r9,r9,#SR_CFLAG */ ! 503: } ! 504: ! 505: void compile_stdflag_n(t_iib *iib, int reg) ! 506: { ! 507: switch(iib->size) { ! 508: case sz_byte: ! 509: compile_w(0xE3100080 | reg<<16); /* TST reg,#1<<7 */ ! 510: break; ! 511: case sz_word: ! 512: compile_w(0xE3100902 | reg<<16); /* TST reg,#1<<15 */ ! 513: break; ! 514: case sz_long: ! 515: compile_w(0xE3100102 | reg<<16); /* TST reg,#1<<31 */ ! 516: break; ! 517: default: ! 518: fprintf(stderr, "Invalid size %d\n", iib->size); ! 519: exit(1); ! 520: } ! 521: compile_w(0x13899000 | SR_NFLAG); /* ORRNE r9,r9,#SR_NFLAG */ ! 522: compile_w(0x03C99000 | SR_NFLAG); /* BICEQ r9,r9,#SR_NFLAG */ ! 523: } ! 524: ! 525: void compile_stdflag_z(t_iib *iib, int reg) ! 526: { ! 527: switch(iib->size) { ! 528: case sz_byte: ! 529: compile_w(0xE1B0EC00 | reg); /* MOVS r14,r1,LSL#24 */ ! 530: break; ! 531: case sz_word: ! 532: compile_w(0xE1B0E800 | reg); /* MOVS r14,r1,LSL#16 */ ! 533: break; ! 534: case sz_long: ! 535: compile_w(0xE1B00000 | reg<<12 | reg); /* MOVS r1,r1 */ ! 536: break; ! 537: default: ! 538: fprintf(stderr, "Invalid size %d\n", iib->size); ! 539: exit(1); ! 540: } ! 541: compile_w(0x03899000 | SR_ZFLAG); /* ORREQ r9,r9,#SR_ZFLAG */ ! 542: compile_w(0x13C99000 | SR_ZFLAG); /* BICNE r9,r9,#SR_ZFLAG */ ! 543: } ! 544: ! 545: /* ! 546: * R0-R5 = work registers ! 547: * R6 = IPC ! 548: * R7 = PC ! 549: * R8-> registers ! 550: * R9 = SR ! 551: */ ! 552: ! 553: char *compile_make(t_ipclist *list) ! 554: { ! 555: int instrs = 0; ! 556: uint8 *block = malloc(MAXBLOCKSIZE); ! 557: t_ipc *ipc = (t_ipc *)(list+1); ! 558: t_iib *iib; ! 559: int len; ! 560: uint8 *stmia, *p; ! 561: uint32 r[10]; ! 562: int srcreg, dstreg, srcval, dstval; ! 563: static int blockno = 1; ! 564: static char tmp[256]; ! 565: FILE *file; ! 566: int normal; ! 567: ! 568: *(uint32 *)0x7004 = (uint32)block; ! 569: *(uint32 *)0x7008 = (uint32)list->pc; ! 570: ! 571: if (!block) { ! 572: fprintf(stderr, "Out of memory!\n"); ! 573: exit(1); ! 574: } ! 575: curpos = block; ! 576: ! 577: compile_w(0xE92D4070); /* STMDB r13!,{r4-r6,r14} */ ! 578: compile_w(0xE1A06000); /* MOV r6,r0 */ ! 579: ! 580: compile_initregs(); ! 581: ! 582: while(*(int *)ipc) { ! 583: if ((curpos - block) > MAXBLOCKSIZE-1024) { ! 584: fprintf(stderr, "Block too short\n"); ! 585: exit(1); ! 586: } ! 587: instrs++; ! 588: iib = cpu68k_iibtable[ipc->opcode]; ! 589: ! 590: normal = 1; ! 591: ! 592: switch(iib->mnemonic) { ! 593: case i_MOVE: ! 594: if ((iib->stype == dt_Dreg || iib->stype == dt_Areg) && ! 595: (iib->dtype == dt_Dreg || iib->dtype == dt_Areg)) { ! 596: compile_ea(iib, ipc, tp_src, true, &srcreg); ! 597: compile_eaval(iib, ipc, tp_src, true, srcreg, &srcval); ! 598: if (srcreg != -1) ! 599: regtimer[srcreg]++; ! 600: compile_ea(iib, ipc, tp_dst, true, &dstreg); ! 601: compile_eastore(iib, ipc, tp_dst, dstreg, srcval); ! 602: if (ipc->set & IIB_FLAG_V) ! 603: compile_clrflag_v(iib); ! 604: if (ipc->set & IIB_FLAG_C) ! 605: compile_clrflag_c(iib); ! 606: if (ipc->set & IIB_FLAG_N) ! 607: compile_stdflag_n(iib, srcval); ! 608: if (ipc->set & IIB_FLAG_Z) ! 609: compile_stdflag_z(iib, srcval); ! 610: compile_w(0xE2877000 | 2*iib->wordlen); /* ADD r7,r7,#wordlen */ ! 611: normal = 0; ! 612: } ! 613: break; ! 614: default: ! 615: break; ! 616: } ! 617: if (normal) { ! 618: compile_finalregs(); ! 619: compile_w(0xE1A00006); /* MOV r0,r6 */ ! 620: /* BL ipc->function */ ! 621: compile_w(0xEB000000 + ( ((((uint32)ipc->function - ! 622: (uint32)curpos)>>2)-2) & 0xFFFFFF)); ! 623: } ! 624: ipc++; ! 625: if (*(int *)ipc) { ! 626: compile_w(0xE2866000 + sizeof(t_ipc)); /* ADD r6,r6,#sizeof(t_ipc) */ ! 627: compile_inctimer(); ! 628: } ! 629: } ! 630: compile_finalregs(); ! 631: compile_w(0xE8FD8070); /* LDMIA r13!,{r4-r6,PC}^ */ ! 632: compile_w(list->pc); ! 633: p = realloc(block, curpos - block); ! 634: if (p != block) { ! 635: fprintf(stderr, "realloc moved block!\n"); ! 636: exit(1); ! 637: } ! 638: *(uint32 *)0x7000 = (uint32)block; ! 639: ! 640: /* ! 641: sprintf(tmp, "b/%02x/blk%d", blockno/77, blockno++ % 77); ! 642: file = fopen(tmp, "w"); ! 643: fwrite(block, 1, curpos - block, file); ! 644: fclose(file); ! 645: */ ! 646: ! 647: r[0] = (uint32)1; ! 648: r[1] = (uint32)block; ! 649: r[2] = (uint32)(curpos-4); ! 650: os_swi(0x20000 | OS_SynchroniseCodeAreas, r); ! 651: ! 652: return block; ! 653: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.