Annotation of generator/extra/compile-arm.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.