Annotation of generator/src/.extra/compile-arm.c, revision 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.