Annotation of uae/gencpu.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * UAE - The Un*x Amiga Emulator
                      3:  *
                      4:  * MC68000 emulation generator
                      5:  *
                      6:  * This is a fairly stupid program that generates a lot of case labels that 
                      7:  * can be #included in a switch statement.
                      8:  * As an alternative, it can generate functions that handle specific
                      9:  * MC68000 instructions, plus a prototype header file and a function pointer
                     10:  * array to look up the function for an opcode.
                     11:  * Error checking is bad, an illegal table68k file will cause the program to
                     12:  * call abort().
                     13:  * The generated code is sometimes sub-optimal, an optimizing compiler should 
                     14:  * take care of this.
                     15:  * 
                     16:  * (c) 1995 Bernd Schmidt
                     17:  * 
                     18:  */
                     19: 
                     20: #include <assert.h>
                     21: #include <string.h>
                     22: #include <stdio.h>
                     23: #include <stdlib.h>
                     24: #include <ctype.h>
                     25: 
                     26: #include "config.h"
                     27: #include "amiga.h"
                     28: 
                     29: typedef enum {
                     30:   Dreg, Areg, Aind, Aipi, Apdi, Ad16, Ad8r, 
                     31:   absw, absl, PC16, PC8r, imm, imm0, imm1, imm2, immi, am_unknown, am_illg
                     32: } amodes;
                     33: 
                     34: FILE *tablef;
                     35: int nextch = 0;
                     36: 
                     37: typedef enum {
                     38:     i_ILLG,
                     39:     
                     40:     i_OR, i_AND, i_EOR, i_ORSR, i_ANDSR, i_EORSR, 
                     41:     i_SUB, i_SUBA, i_SUBX, i_SBCD, 
                     42:     i_ADD, i_ADDA, i_ADDX, i_ABCD,
                     43:     i_NEG, i_NEGX, i_NBCD, i_CLR, i_NOT, i_TST, 
                     44:     i_BTST, i_BCHG, i_BCLR, i_BSET,
                     45:     i_CMP, i_CMPM, i_CMPA, 
                     46:     i_MOVEP, i_MOVE, i_MOVEA, i_MVSR2, i_MV2SR, 
                     47:     i_SWAP, i_EXG, i_EXT, i_MVMEL, i_MVMLE, 
                     48:     i_TRAP, i_MVR2USP, i_MVUSP2R, i_RESET, i_NOP, i_STOP, i_RTE, i_RTD, 
                     49:     i_LINK, i_UNLK, 
                     50:     i_RTS, i_TRAPV, i_RTR, 
                     51:     i_JSR, i_JMP, i_BSR, i_Bcc,
                     52:     i_LEA, i_PEA, i_DBcc, i_Scc, 
                     53:     i_DIVU, i_DIVS, i_MULU, i_MULS, 
                     54:     i_ASR, i_ASL, i_LSR, i_LSL, i_ROL, i_ROR, i_ROXL, i_ROXR,
                     55:     i_ASRW, i_ASLW, i_LSRW, i_LSLW, i_ROLW, i_RORW, i_ROXLW, i_ROXRW
                     56: } instrmnem;
                     57: 
                     58: struct mnemolookup {
                     59:     instrmnem mnemo;
                     60:     char name[10];
                     61: } lookuptab[] = {
                     62:     { i_OR, "OR" },
                     63:     { i_AND, "AND" }, 
                     64:     { i_EOR, "EOR" },
                     65:     { i_ORSR, "ORSR" }, 
                     66:     { i_ANDSR, "ANDSR" }, 
                     67:     { i_EORSR, "EORSR" }, 
                     68:     { i_SUB, "SUB" }, 
                     69:     { i_SUBA, "SUBA" }, 
                     70:     { i_SUBX, "SUBX" }, 
                     71:     { i_SBCD, "SBCD" }, 
                     72:     { i_ADD, "ADD" }, 
                     73:     { i_ADDA, "ADDA" }, 
                     74:     { i_ADDX, "ADDX" }, 
                     75:     { i_ABCD, "ABCD" },
                     76:     { i_NEG, "NEG" }, 
                     77:     { i_NEGX, "NEGX" }, 
                     78:     { i_NBCD, "NBCD" }, 
                     79:     { i_CLR, "CLR" }, 
                     80:     { i_NOT, "NOT" }, 
                     81:     { i_TST, "TST" }, 
                     82:     { i_BTST, "BTST" }, 
                     83:     { i_BCHG, "BCHG" }, 
                     84:     { i_BCLR, "BCLR" }, 
                     85:     { i_BSET, "BSET" },
                     86:     { i_CMP, "CMP" }, 
                     87:     { i_CMPM, "CMPM" }, 
                     88:     { i_CMPA, "CMPA" }, 
                     89:     { i_MOVEP, "MOVEP" },
                     90:     { i_MOVE, "MOVE" }, 
                     91:     { i_MOVEA, "MOVEA" },
                     92:     { i_MVSR2, "MVSR2" },
                     93:     { i_MV2SR, "MV2SR" }, 
                     94:     { i_SWAP, "SWAP" },
                     95:     { i_EXG, "EXG" },
                     96:     { i_EXT, "EXT" },
                     97:     { i_MVMEL, "MVMEL" }, 
                     98:     { i_MVMLE, "MVMLE" }, 
                     99:     { i_TRAP, "TRAP" },
                    100:     { i_MVR2USP, "MVR2USP" }, 
                    101:     { i_MVUSP2R, "MVUSP2R" }, 
                    102:     { i_RESET, "RESET" },
                    103:     { i_NOP, "NOP" },
                    104:     { i_STOP, "STOP" },
                    105:     { i_RTE, "RTE" },
                    106:     { i_RTD, "RTD" }, 
                    107:     { i_LINK, "LINK" },
                    108:     { i_UNLK, "UNLK" }, 
                    109:     { i_RTS, "RTS" }, 
                    110:     { i_TRAPV, "TRAPV" }, 
                    111:     { i_RTR, "RTR" }, 
                    112:     { i_JSR, "JSR" },
                    113:     { i_JMP, "JMP" },
                    114:     { i_BSR, "BSR" },
                    115:     { i_Bcc, "Bcc" },
                    116:     { i_LEA, "LEA" },
                    117:     { i_PEA, "PEA" },
                    118:     { i_DBcc, "DBcc" }, 
                    119:     { i_Scc, "Scc" }, 
                    120:     { i_DIVU, "DIVU" }, 
                    121:     { i_DIVS, "DIVS" },
                    122:     { i_MULU, "MULU" },
                    123:     { i_MULS, "MULS" }, 
                    124:     { i_ASR, "ASR" },
                    125:     { i_ASL, "ASL" },
                    126:     { i_LSR, "LSR" },
                    127:     { i_LSL, "LSL" },
                    128:     { i_ROL, "ROL" },
                    129:     { i_ROR, "ROR" },
                    130:     { i_ROXL, "ROXL" },
                    131:     { i_ROXR, "ROXR" },
                    132:     { i_ASRW, "ASRW" },
                    133:     { i_ASLW, "ASLW" },
                    134:     { i_LSRW, "LSRW" },
                    135:     { i_LSLW, "LSLW" },
                    136:     { i_ROLW, "ROLW" },
                    137:     { i_RORW, "RORW" },
                    138:     { i_ROXLW, "ROXLW" },
                    139:     { i_ROXRW, "ROXRW" }
                    140: };
                    141: 
                    142: char patbits[16];
                    143: char opcstr[256];
                    144: 
                    145: UWORD bitmask,bitpattern;
                    146: 
                    147: typedef enum {
                    148:     bit0, bit1, bitc, bitC, bitf, biti, bitI, bitj, bitJ, bits, bitS, bitd, bitD, bitr, bitR, bitz, lastbit
                    149: } bitvals;
                    150: 
                    151: typedef enum {
                    152:     sz_unknown, sz_byte, sz_word, sz_long
                    153: } wordsizes;
                    154: 
                    155: struct instr {
                    156:     instrmnem mnemo;
                    157:     wordsizes size;
                    158:     amodes dmode, smode;
                    159:     unsigned char dreg;
                    160:     unsigned char sreg;
                    161:     unsigned int suse:1;
                    162:     unsigned int duse:1;
                    163:     unsigned int sbtarg:1;
                    164:     unsigned int generated:1;
                    165:     unsigned int cc:4;
                    166:     signed char dpos;
                    167:     signed char spos;
                    168:     UWORD handler;
                    169: } *table;
                    170: 
                    171: #ifdef DEBUG
                    172: static void myabort(void)
                    173: {
                    174:     abort();
                    175: }
                    176: #else 
                    177: #define myabort abort
                    178: #endif
                    179: static void getnextch(void)
                    180: {
                    181:     do {
                    182:        nextch = fgetc(tablef);
                    183:        if (nextch == '%') {
                    184:            do {
                    185:                nextch = fgetc(tablef);
                    186:            } while (nextch != EOF && nextch != '\n');  
                    187:        }
                    188:     } while (nextch != EOF && isspace(nextch));        
                    189: }
                    190: 
                    191: static void get_bits(void)
                    192: {
                    193:     int i;
                    194:     
                    195:     bitmask = bitpattern = 0;
                    196:     for(i=0; i<16; i++) {
                    197:        bitmask <<= 1;
                    198:        bitpattern <<= 1;
                    199:        if (nextch == '0' || nextch == '1') bitmask |= 1;
                    200:        if (nextch == '1') bitpattern |= 1;
                    201:        patbits[i] = nextch;
                    202:        getnextch();
                    203:     }
                    204: }
                    205: 
                    206: static amodes mode_from_str(char *str)
                    207: {
                    208:     if (strncmp(str,"Dreg",4) == 0) return Dreg;
                    209:     if (strncmp(str,"Areg",4) == 0) return Areg;
                    210:     if (strncmp(str,"Aind",4) == 0) return Aind;
                    211:     if (strncmp(str,"Apdi",4) == 0) return Apdi;
                    212:     if (strncmp(str,"Aipi",4) == 0) return Aipi;
                    213:     if (strncmp(str,"Ad16",4) == 0) return Ad16;
                    214:     if (strncmp(str,"Ad8r",4) == 0) return Ad8r;
                    215:     if (strncmp(str,"absw",4) == 0) return absw;
                    216:     if (strncmp(str,"absl",4) == 0) return absl;
                    217:     if (strncmp(str,"PC16",4) == 0) return PC16;
                    218:     if (strncmp(str,"PC8r",4) == 0) return PC8r;
                    219:     if (strncmp(str,"Immd",4) == 0) return imm;
                    220:     myabort();
                    221: }
                    222: 
                    223: static amodes mode_from_mr(int mode, int reg) 
                    224: {
                    225:     switch(mode) {
                    226:      case 0: return Dreg; 
                    227:      case 1: return Areg;
                    228:      case 2: return Aind;
                    229:      case 3: return Aipi;
                    230:      case 4: return Apdi;
                    231:      case 5: return Ad16;
                    232:      case 6: return Ad8r;
                    233:      case 7: 
                    234:        switch(reg) {
                    235:         case 0: return absw;
                    236:         case 1: return absl;
                    237:         case 2: return PC16;
                    238:         case 3: return PC8r;
                    239:         case 4: return imm;
                    240:         case 5:
                    241:         case 6:
                    242:         case 7: return am_illg;
                    243:        }
                    244:     }
                    245:     myabort();
                    246: }
                    247: 
                    248: static void get_strs(void)
                    249: {
                    250:     fgets(opcstr, 250, tablef);
                    251:     getnextch();
                    252: }
                    253: 
                    254: static void parse_bits(void)
                    255: {
                    256:     int find;
                    257:     long int opc;
                    258:     
                    259:     for(opc = 0; opc < 65536; opc ++) {
                    260:        if ((opc & bitmask) == bitpattern) {
                    261:            int bitcnt[lastbit];
                    262:            int bitval[lastbit];
                    263:            int bitpos[lastbit];
                    264:            int i,j;
                    265:            
                    266:            UWORD msk = 0x8000;
                    267: 
                    268:            int pos = 0;
                    269: 
                    270:            int mnp = 0;
                    271:            char mnemonic[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                    272:            wordsizes sz = sz_unknown;
                    273:            bool srcgather = false, dstgather = false;
                    274:            bool usesrc = false, usedst = false;
                    275:            bool srcbtarg = false;
                    276:            int srcpos, dstpos;
                    277:            
                    278:            amodes srcmode = am_unknown, destmode = am_unknown;
                    279:            int srcreg, destreg;
                    280:            
                    281:            for(i=0; i < lastbit; i++) bitcnt[i] = bitval[i] = 0;
                    282: 
                    283:            for(j=0; j < 16; j++, msk >>= 1) {
                    284:                bitvals currbit;
                    285:                switch(patbits[j]) {
                    286:                 case '0': currbit = bit0; break;
                    287:                 case '1': currbit = bit1; break;
                    288:                 case 'c': currbit = bitc; break;
                    289:                 case 'C': currbit = bitC; break;
                    290:                 case 'f': currbit = bitf; break;
                    291:                 case 'i': currbit = biti; break;
                    292:                 case 'I': currbit = bitI; break;
                    293:                 case 'j': currbit = bitj; break;
                    294:                 case 'J': currbit = bitJ; break;
                    295:                 case 's': currbit = bits; break;
                    296:                 case 'S': currbit = bitS; break;
                    297:                 case 'd': currbit = bitd; break;
                    298:                 case 'D': currbit = bitD; break;
                    299:                 case 'r': currbit = bitr; break;
                    300:                 case 'R': currbit = bitR; break;
                    301:                 case 'z': currbit = bitz; break;
                    302:                 default: myabort();
                    303:                }
                    304:                bitpos[currbit] = 15 - j;
                    305:                bitcnt[currbit]++;
                    306:                bitval[currbit] = (bitval[currbit] << 1) | ((opc & msk) ? 1 : 0);
                    307:            }
                    308:            if (bitval[bitj] == 0) bitval[bitj] = 8;
                    309:            /* first check whether this one does not match after all */
                    310:            if (bitval[bitz] == 3) continue; 
                    311:            if (bitval[bitC] == 1) continue;
                    312:            if (bitcnt[bitI] && bitval[bitI] == 0) continue;
                    313: 
                    314:            /* bitI and bitC get copied to biti and bitc */
                    315:            if (bitcnt[bitI]) { bitval[biti] = bitval[bitI]; bitpos[biti] = bitpos[bitI]; }
                    316:            if (bitcnt[bitC]) bitval[bitc] = bitval[bitC];
                    317:            
                    318:            while (isspace(opcstr[pos]) || opcstr[pos] == ':') pos++;
                    319:            while (!isspace(opcstr[pos])) {
                    320:                if (opcstr[pos] == '.') {
                    321:                    pos++;
                    322:                    switch(opcstr[pos]) {
                    323:                        
                    324:                     case 'B': sz = sz_byte; break;
                    325:                     case 'W': sz = sz_word; break;
                    326:                     case 'L': sz = sz_long; break;
                    327:                     case 'z': 
                    328:                        switch(bitval[bitz]) {
                    329:                         case 0: sz = sz_byte; break;
                    330:                         case 1: sz = sz_word; break;
                    331:                         case 2: sz = sz_long; break;
                    332:                         default: myabort();
                    333:                        }
                    334:                        break;
                    335:                     default: myabort();
                    336:                    }
                    337:                } else {                    
                    338:                    mnemonic[mnp] = opcstr[pos];
                    339:                    if(mnemonic[mnp] == 'f') {
                    340:                        switch(bitval[bitf]) {
                    341:                         case 0: mnemonic[mnp] = 'R'; break;
                    342:                         case 1: mnemonic[mnp] = 'L'; break;
                    343:                         default: myabort();
                    344:                        }
                    345:                    }
                    346:                    mnp++;
                    347:                }
                    348:                pos++;          
                    349:            }
                    350:            
                    351:            /* now, we have read the mnemonic and the size */
                    352:            while (isspace(opcstr[pos])) pos++;
                    353:            
                    354:            /* A goto a day keeps the D******a away. */
                    355:            if (opcstr[pos] == 0 || opcstr[pos] == ':') goto endofline;
                    356:            
                    357:            /* parse the source address */
                    358:            usesrc = true;
                    359:            switch(opcstr[pos++]) {
                    360:             case 'D': 
                    361:                srcmode = Dreg;
                    362:                switch (opcstr[pos++]) {
                    363:                 case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break;
                    364:                 case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break;
                    365:                 default: myabort();
                    366:                }
                    367:                
                    368:                break;
                    369:             case 'A': 
                    370:                srcmode = Areg;
                    371:                switch (opcstr[pos++]) {
                    372:                 case 'r': srcreg = bitval[bitr]; srcgather = true; srcpos = bitpos[bitr]; break;
                    373:                 case 'R': srcreg = bitval[bitR]; srcgather = true; srcpos = bitpos[bitR]; break;
                    374:                 default: myabort();
                    375:                }
                    376:                switch (opcstr[pos]) {
                    377:                 case 'p': srcmode = Apdi; pos++; break;
                    378:                 case 'P': srcmode = Aipi; pos++; break;
                    379:                }
                    380:                break;
                    381:             case '#':
                    382:                switch(opcstr[pos++]) {
                    383:                 case 'z': srcmode = imm; break;
                    384:                 case '0': srcmode = imm0; break;
                    385:                 case '1': srcmode = imm1; break;
                    386:                 case '2': srcmode = imm2; break;
                    387:                 case 'i': srcmode = immi; srcreg = (LONG)(BYTE)bitval[biti]; srcbtarg = true; srcgather = true; srcpos = bitpos[biti]; break;
                    388:                 case 'j': srcmode = immi; srcreg = bitval[bitj]; break;
                    389:                 case 'J': srcmode = immi; srcreg = bitval[bitJ]; break;
                    390:                 default: myabort();
                    391:                }
                    392:                break;
                    393:             case 'd':
                    394:                srcreg = bitval[bitD];
                    395:                srcmode = mode_from_mr(bitval[bitd],bitval[bitD]);
                    396:                if (srcmode == am_illg) continue;
                    397:                if (srcmode == Areg || srcmode == Dreg || srcmode == Aind 
                    398:                    || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
                    399:                    || srcmode == Apdi)
                    400:                {
                    401:                    srcgather = true; srcpos = bitpos[bitD];
                    402:                }
                    403:                if (opcstr[pos] == '[') {
                    404:                    pos++;
                    405:                    if (opcstr[pos] == '!') {
                    406:                        /* exclusion */
                    407:                        do {                        
                    408:                            pos++;
                    409:                            if (mode_from_str(opcstr+pos) == srcmode) goto nomatch;
                    410:                            pos += 4;                       
                    411:                        } while (opcstr[pos] == ',');
                    412:                        pos++;
                    413:                    } else {
                    414:                        if (opcstr[pos+4] == '-') {
                    415:                            /* replacement */
                    416:                            if (mode_from_str(opcstr+pos) == srcmode) 
                    417:                                srcmode = mode_from_str(opcstr+pos+5);
                    418:                            else
                    419:                                goto nomatch;
                    420:                            pos += 10;
                    421:                        } else {
                    422:                            /* normal */
                    423:                            while(mode_from_str(opcstr+pos) != srcmode) {
                    424:                                pos += 4;
                    425:                                if (opcstr[pos] == ']') goto nomatch;
                    426:                                pos++;
                    427:                            }
                    428:                            while(opcstr[pos] != ']') pos++;
                    429:                            pos++;
                    430:                            break;
                    431:                        }
                    432:                    }
                    433:                }
                    434:                /* Some addressing modes are invalid as destination */
                    435:                if (srcmode == imm || srcmode == PC16 || srcmode == PC8r)
                    436:                    goto nomatch; 
                    437:                break;
                    438:             case 's':
                    439:                srcreg = bitval[bitS];
                    440:                srcmode = mode_from_mr(bitval[bits],bitval[bitS]);
                    441:                
                    442:                if(srcmode == am_illg) continue;                    
                    443:                if (srcmode == Areg || srcmode == Dreg || srcmode == Aind 
                    444:                    || srcmode == Ad16 || srcmode == Ad8r || srcmode == Aipi
                    445:                    || srcmode == Apdi)
                    446:                {
                    447:                    srcgather = true; srcpos = bitpos[bitS];
                    448:                }
                    449:                if (opcstr[pos] == '[') {
                    450:                    pos++;
                    451:                    if (opcstr[pos] == '!') {
                    452:                        /* exclusion */
                    453:                        do {                        
                    454:                            pos++;
                    455:                            if (mode_from_str(opcstr+pos) == srcmode) goto nomatch;
                    456:                            pos += 4;                       
                    457:                        } while (opcstr[pos] == ',');
                    458:                        pos++;
                    459:                    } else {
                    460:                        if (opcstr[pos+4] == '-') {
                    461:                            /* replacement */
                    462:                            if (mode_from_str(opcstr+pos) == srcmode) 
                    463:                                srcmode = mode_from_str(opcstr+pos+5);
                    464:                            else
                    465:                                goto nomatch;
                    466:                            pos += 10;
                    467:                        } else {
                    468:                            /* normal */
                    469:                            while(mode_from_str(opcstr+pos) != srcmode) {
                    470:                                pos += 4;
                    471:                                if (opcstr[pos] == ']') goto nomatch;
                    472:                                pos++;
                    473:                            }
                    474:                            while(opcstr[pos] != ']') pos++;
                    475:                            pos++;
                    476:                        }
                    477:                    }
                    478:                }
                    479:                break;
                    480:             default: myabort();
                    481:            }
                    482:            /* safety check - might have changed */
                    483:            if (srcmode != Areg && srcmode != Dreg && srcmode != Aind 
                    484:                && srcmode != Ad16 && srcmode != Ad8r && srcmode != Aipi
                    485:                && srcmode != Apdi && srcmode != immi)
                    486:            {
                    487:                srcgather = false;
                    488:            }
                    489:            if (srcmode == Areg && sz == sz_byte)
                    490:                goto nomatch;
                    491:            
                    492:            if (opcstr[pos] != ',') goto endofline;
                    493:            pos++;
                    494:            
                    495:            /* parse the destination address */
                    496:            usedst = true;              
                    497:            switch(opcstr[pos++]) {
                    498:             case 'D': 
                    499:                destmode = Dreg;
                    500:                switch (opcstr[pos++]) {
                    501:                 case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break;
                    502:                 case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break;
                    503:                 default: myabort();
                    504:                }
                    505:                break;
                    506:             case 'A': 
                    507:                destmode = Areg;
                    508:                switch (opcstr[pos++]) {
                    509:                 case 'r': destreg = bitval[bitr]; dstgather = true; dstpos = bitpos[bitr]; break;
                    510:                 case 'R': destreg = bitval[bitR]; dstgather = true; dstpos = bitpos[bitR]; break;
                    511:                 default: myabort();
                    512:                }
                    513:                switch (opcstr[pos]) {
                    514:                 case 'p': destmode = Apdi; pos++; break;
                    515:                 case 'P': destmode = Aipi; pos++; break;
                    516:                }
                    517:                break;
                    518:             case '#':
                    519:                switch(opcstr[pos++]) {
                    520:                 case 'z': destmode = imm; break;
                    521:                 case '0': destmode = imm0; break;
                    522:                 case '1': destmode = imm1; break;
                    523:                 case '2': destmode = imm2; break;
                    524:                 case 'i': destmode = immi; destreg = (LONG)(BYTE)bitval[biti]; break;
                    525:                 case 'j': destmode = immi; destreg = bitval[bitj]; break;
                    526:                 case 'J': destmode = immi; destreg = bitval[bitJ]; break;
                    527:                 default: myabort();
                    528:                }
                    529:                break;
                    530:             case 'd':
                    531:                destreg = bitval[bitD];
                    532:                destmode = mode_from_mr(bitval[bitd],bitval[bitD]);
                    533:                if(destmode == am_illg) continue;
                    534:                if (destmode == Areg || destmode == Dreg || destmode == Aind 
                    535:                    || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
                    536:                    || destmode == Apdi)
                    537:                {
                    538:                    dstgather = true; dstpos = bitpos[bitD];
                    539:                }
                    540:                
                    541:                if (opcstr[pos] == '[') {
                    542:                    pos++;
                    543:                    if (opcstr[pos] == '!') {
                    544:                        /* exclusion */
                    545:                        do {                        
                    546:                            pos++;
                    547:                            if (mode_from_str(opcstr+pos) == destmode) goto nomatch;
                    548:                            pos += 4;                       
                    549:                        } while (opcstr[pos] == ',');
                    550:                        pos++;
                    551:                    } else {
                    552:                        if (opcstr[pos+4] == '-') {
                    553:                            /* replacement */
                    554:                            if (mode_from_str(opcstr+pos) == destmode) 
                    555:                                destmode = mode_from_str(opcstr+pos+5);
                    556:                            else
                    557:                                goto nomatch;
                    558:                            pos += 10;
                    559:                        } else {
                    560:                            /* normal */
                    561:                            while(mode_from_str(opcstr+pos) != destmode) {
                    562:                                pos += 4;
                    563:                                if (opcstr[pos] == ']') goto nomatch;
                    564:                                pos++;
                    565:                            }
                    566:                            while(opcstr[pos] != ']') pos++;
                    567:                            pos++;
                    568:                            break;
                    569:                        }
                    570:                    }
                    571:                }
                    572:                /* Some addressing modes are invalid as destination */
                    573:                if (destmode == imm || destmode == PC16 || destmode == PC8r)
                    574:                    goto nomatch;
                    575:                break;
                    576:             case 's':
                    577:                destreg = bitval[bitS];
                    578:                destmode = mode_from_mr(bitval[bits],bitval[bitS]);
                    579:                
                    580:                if(destmode == am_illg) continue;                   
                    581:                if (destmode == Areg || destmode == Dreg || destmode == Aind 
                    582:                    || destmode == Ad16 || destmode == Ad8r || destmode == Aipi
                    583:                    || destmode == Apdi)
                    584:                {
                    585:                    dstgather = true; dstpos = bitpos[bitS];
                    586:                }
                    587:                
                    588:                if (opcstr[pos] == '[') {
                    589:                    pos++;
                    590:                    if (opcstr[pos] == '!') {
                    591:                        /* exclusion */
                    592:                        do {                        
                    593:                            pos++;
                    594:                            if (mode_from_str(opcstr+pos) == destmode) goto nomatch;
                    595:                            pos += 4;                       
                    596:                        } while (opcstr[pos] == ',');
                    597:                        pos++;
                    598:                    } else {
                    599:                        if (opcstr[pos+4] == '-') {
                    600:                            /* replacement */
                    601:                            if (mode_from_str(opcstr+pos) == destmode) 
                    602:                                destmode = mode_from_str(opcstr+pos+5);
                    603:                            else
                    604:                                goto nomatch;
                    605:                            pos += 10;
                    606:                        } else {
                    607:                            /* normal */
                    608:                            while(mode_from_str(opcstr+pos) != destmode) {
                    609:                                pos += 4;
                    610:                                if (opcstr[pos] == ']') goto nomatch;
                    611:                                pos++;
                    612:                            }
                    613:                            while(opcstr[pos] != ']') pos++;
                    614:                            pos++;
                    615:                        }
                    616:                    }
                    617:                }
                    618:                break;
                    619:             default: myabort();
                    620:            }
                    621:            /* safety check - might have changed */
                    622:            if (destmode != Areg && destmode != Dreg && destmode != Aind 
                    623:                && destmode != Ad16 && destmode != Ad8r && destmode != Aipi
                    624:                && destmode != Apdi)
                    625:            {
                    626:                dstgather = false;
                    627:            }
                    628:            
                    629:            if (destmode == Areg && sz == sz_byte)
                    630:                goto nomatch;
                    631: #if 0
                    632:            if (sz == sz_byte && (destmode == Aipi || destmode == Apdi)) {
                    633:                dstgather = false;
                    634:            }
                    635: #endif
                    636: endofline:
                    637:            /* now, we have a match */
                    638:            if (table[opc].mnemo != i_ILLG)
                    639:                fprintf(stderr, "Double match: %x: %s\n", opc, opcstr);
                    640:            for(find = 0;; find++) {
                    641:                if (strcmp(mnemonic, lookuptab[find].name) == 0) {
                    642:                    table[opc].mnemo = lookuptab[find].mnemo;
                    643:                    break;
                    644:                }
                    645:                if (strlen(lookuptab[find].name) == 0) myabort();
                    646:            }
                    647:            table[opc].cc = bitval[bitc];
                    648:            if (table[opc].mnemo == i_BTST
                    649:                || table[opc].mnemo == i_BSET
                    650:                || table[opc].mnemo == i_BCLR
                    651:                || table[opc].mnemo == i_BCHG) 
                    652:            {
                    653:                sz = destmode == Dreg ? sz_long : sz_byte;
                    654:            }
                    655:            table[opc].generated = false;
                    656:            table[opc].size = sz;
                    657:            table[opc].sreg = srcreg;
                    658:            table[opc].dreg = destreg;
                    659:            table[opc].smode = srcmode;
                    660:            table[opc].dmode = destmode;
                    661:            table[opc].spos = srcgather ? srcpos : -1;
                    662:            table[opc].dpos = dstgather ? dstpos : -1;
                    663:            table[opc].suse = usesrc;
                    664:            table[opc].duse = usedst;
                    665:            table[opc].sbtarg = srcbtarg;
                    666: nomatch:
                    667:            /* FOO! */;
                    668:        }
                    669:     }
                    670: }
                    671: 
                    672: static int n_braces = 0;
                    673: 
                    674: static void start_brace(void)
                    675: {
                    676:     n_braces++;
                    677:     printf("{");
                    678: }
                    679: 
                    680: static void close_brace(void)
                    681: {
                    682:     assert (n_braces > 0);
                    683:     n_braces--;
                    684:     printf("}");
                    685: }
                    686: 
                    687: static void finish_braces(void)
                    688: {
                    689:     while (n_braces > 0)
                    690:        close_brace();
                    691: }
                    692: 
                    693: static void pop_braces(int to)
                    694: {
                    695:     while (n_braces > to)
                    696:        close_brace();
                    697: }
                    698: 
                    699: static void genamode(amodes mode, char *reg, wordsizes size, char *name, bool getv, bool movem)
                    700: {
                    701:     start_brace ();
                    702:     switch(mode) {
                    703:      case Dreg:
                    704:        if (movem)
                    705:            abort();
                    706:        if (getv)
                    707:            switch(size) {        
                    708:             case sz_byte:
                    709:                printf("\tBYTE %s = regs.d[%s];\n", name, reg);
                    710:                break;
                    711:             case sz_word:
                    712:                printf("\tWORD %s = regs.d[%s];\n", name, reg);
                    713:                break;
                    714:             case sz_long:
                    715:                printf("\tLONG %s = regs.d[%s];\n", name, reg);
                    716:                break;
                    717:             default: myabort();
                    718:            }
                    719:        break;
                    720:      case Areg:
                    721:        if (movem)
                    722:            abort();
                    723:        if (getv)
                    724:            switch(size) {        
                    725:             case sz_word:
                    726:                printf("\tWORD %s = regs.a[%s];\n", name, reg);
                    727:                break;
                    728:             case sz_long:
                    729:                printf("\tLONG %s = regs.a[%s];\n", name, reg);
                    730:                break;
                    731:             default: myabort();
                    732:            }
                    733:        break;
                    734:      case Aind:
                    735:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    736:        if (getv)
                    737:            switch(size) {        
                    738:             case sz_byte:
                    739:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    740:                break;
                    741:             case sz_word:
                    742:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    743:                break;
                    744:             case sz_long:
                    745:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    746:                break;
                    747:             default: myabort();
                    748:            }
                    749:        break;
                    750:      case Aipi:
                    751:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    752:        switch(size) {
                    753:         case sz_byte:      
                    754:            if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    755:            if (!movem) {
                    756:                start_brace();
                    757:                printf("\tregs.a[%s] += (%s == 7) ? 2 : 1;\n", reg, reg);
                    758:            }
                    759:            break;
                    760:         case sz_word:
                    761:            if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
                    762:            if (!movem) {
                    763:                start_brace();
                    764:                printf("\tregs.a[%s] += 2;\n", reg);
                    765:            }
                    766:            break;
                    767:         case sz_long:
                    768:            if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
                    769:            if (!movem) {
                    770:                start_brace();
                    771:                printf("\tregs.a[%s] += 4;\n", reg);
                    772:            }
                    773:            break;
                    774:         default: myabort();
                    775:        }
                    776:        break;
                    777:      case Apdi:
                    778:        switch(size) {    
                    779:         case sz_byte:
                    780:            if (!movem) printf("\tregs.a[%s] -= (%s == 7) ? 2 : 1;\n", reg, reg);
                    781:            start_brace();
                    782:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    783:            if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    784:            break;
                    785:         case sz_word:
                    786:            if (!movem) printf("\tregs.a[%s] -= 2;\n", reg);
                    787:            start_brace();
                    788:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    789:            if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
                    790:            break;
                    791:         case sz_long:
                    792:            if (!movem) printf("\tregs.a[%s] -= 4;\n", reg);
                    793:            start_brace();
                    794:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    795:            if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
                    796:            break;
                    797:         default: myabort();
                    798:        }
                    799:        break;
                    800:      case Ad16:
                    801:        printf("\tCPTR %sa = regs.a[%s] + (LONG)(WORD)nextiword();\n", name, reg);
                    802:        if (getv) 
                    803:            switch(size) {        
                    804:             case sz_byte:
                    805:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    806:                break;
                    807:             case sz_word:
                    808:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    809:                break;
                    810:             case sz_long:
                    811:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    812:                break;
                    813:             default: myabort();
                    814:            }
                    815:        break;
                    816:      case Ad8r:
                    817:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    818:        printf("\tUWORD %sdp = nextiword();\n", name);
                    819:        printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
                    820:        start_brace();
                    821:        printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
                    822:        printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
                    823:        printf("\t%sa += %sdpr;\n", name, name);
                    824:        if (getv) {
                    825:            start_brace();
                    826:            switch(size) {        
                    827:             case sz_byte:
                    828:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    829:                break;
                    830:             case sz_word:
                    831:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    832:                break;
                    833:             case sz_long:
                    834:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    835:                break;
                    836:             default: myabort();
                    837:            }
                    838:        }
                    839:        break;
                    840:      case PC16:
                    841:        printf("\tCPTR %sa = m68k_getpc();\n", name);
                    842:        printf("\t%sa += (LONG)(WORD)nextiword();\n", name);
                    843:        if (getv) {
                    844:            start_brace();
                    845:            switch(size) {        
                    846:             case sz_byte:
                    847:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    848:                break;
                    849:             case sz_word:
                    850:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    851:                break;
                    852:             case sz_long:
                    853:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    854:                break;
                    855:             default: myabort();
                    856:            }
                    857:        }
                    858:        break;
                    859:      case PC8r:
                    860:        printf("\tCPTR %sa = m68k_getpc();\n", name);
                    861:        printf("\tUWORD %sdp = nextiword();\n", name);
                    862:        printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
                    863:        start_brace();
                    864:        printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
                    865:        printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
                    866:        printf("\t%sa += %sdpr;\n", name, name);
                    867:        if (getv) {
                    868:            start_brace();
                    869:            switch(size) {        
                    870:             case sz_byte:
                    871:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    872:                break;
                    873:             case sz_word:
                    874:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    875:                break;
                    876:             case sz_long:
                    877:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    878:                break;
                    879:             default: myabort();
                    880:            }
                    881:        }
                    882:        break;
                    883:      case absw:
                    884:        printf("\tCPTR %sa = (LONG)(WORD)nextiword();\n", name);
                    885:        if (getv) 
                    886:            switch(size) {        
                    887:             case sz_byte:
                    888:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    889:                break;
                    890:             case sz_word:
                    891:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    892:                break;
                    893:             case sz_long:
                    894:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    895:                break;
                    896:             default: myabort();
                    897:            }
                    898:        break;
                    899:      case absl:
                    900:        printf("\tCPTR %sa = nextilong();\n", name);
                    901:        if (getv) 
                    902:            switch(size) {        
                    903:             case sz_byte:
                    904:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    905:                break;
                    906:             case sz_word:
                    907:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    908:                break;
                    909:             case sz_long:
                    910:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    911:                break;
                    912:             default: myabort();
                    913:            }
                    914:        break;
                    915:      case imm:
                    916:        if (getv) 
                    917:            switch(size) {
                    918:             case sz_byte:
                    919:                printf("\tBYTE %s = nextiword();\n", name);
                    920:                break;
                    921:             case sz_word:
                    922:                printf("\tWORD %s = nextiword();\n", name);
                    923:                break;
                    924:             case sz_long:
                    925:                printf("\tLONG %s = nextilong();\n", name);
                    926:                break;
                    927:             default: myabort();
                    928:            }
                    929:        break;
                    930:      case imm0:
                    931:        if (!getv) myabort();
                    932:        printf("\tBYTE %s = nextiword();\n", name);
                    933:        break;
                    934:      case imm1:
                    935:        if (!getv) myabort();
                    936:        printf("\tWORD %s = nextiword();\n", name);
                    937:        break;
                    938:      case imm2:
                    939:        if (!getv) myabort();
                    940:         printf("\tLONG %s = nextilong();\n", name);
                    941:        break;
                    942:      case immi:
                    943:        if (!getv) myabort();
                    944:        printf("\tULONG %s = %s;\n", name, reg);
                    945:        break;
                    946:      default: 
                    947:        myabort();
                    948:     }
                    949: }
                    950: 
                    951: static void genastore(char *from, amodes mode, char *reg, wordsizes size, char *to)
                    952: {
                    953:     switch(mode) {
                    954:      case Dreg:
                    955:        switch(size) {    
                    956:         case sz_byte:
                    957:            printf("\tregs.d[%s] &= ~0xff; regs.d[%s] |= (%s) & 0xff;\n", reg, reg, from);
                    958:            break;
                    959:         case sz_word:
                    960:            printf("\tregs.d[%s] &= ~0xffff; regs.d[%s] |= (%s) & 0xffff;\n", reg, reg, from);
                    961:            break;
                    962:         case sz_long:
                    963:            printf("\tregs.d[%s] = (%s);\n", reg, from);
                    964:            break;
                    965:         default: myabort();
                    966:        }
                    967:        break;
                    968:      case Areg:
                    969:        switch(size) {    
                    970:         case sz_word:
                    971:            printf("\tregs.a[%s] = (LONG)(WORD)(%s);\n", reg, from);
                    972:            break;
                    973:         case sz_long:
                    974:            printf("\tregs.a[%s] = (%s);\n", reg, from);
                    975:            break;
                    976:         default: myabort();
                    977:        }
                    978:        break;
                    979:      case Aind:
                    980:      case Aipi:
                    981:      case Apdi:
                    982:      case Ad16:
                    983:      case Ad8r:
                    984:      case absw:
                    985:      case absl:
                    986:        switch(size) {
                    987:         case sz_byte:
                    988:            printf("\tput_byte(%sa,%s);\n", to, from);
                    989:            break;
                    990:         case sz_word:
                    991:            printf("\tput_word(%sa,%s);\n", to, from);
                    992:            break;
                    993:         case sz_long:
                    994:            printf("\tput_long(%sa,%s);\n", to, from);
                    995:            break;
                    996:         default: myabort();
                    997:        }
                    998:        break;
                    999:      case PC16:
                   1000:      case PC8r:
                   1001:        switch(size) {
                   1002:         case sz_byte:
                   1003:            printf("\tput_byte(%sa,%s);\n", to, from);
                   1004:            break;
                   1005:            /* These are only used for byte-sized bit ops */
                   1006:         default: myabort();
                   1007:        }
                   1008:        break;
                   1009:      case imm:
                   1010:      case imm0:
                   1011:      case imm1:
                   1012:      case imm2:
                   1013:      case immi:
                   1014:        myabort();
                   1015:        break;
                   1016:      default: 
                   1017:        myabort();
                   1018:     }
                   1019: }
                   1020: 
                   1021: static void genmovemel(UWORD opcode)
                   1022: {
                   1023:     char getcode[100];
                   1024:     int size = table[opcode].size == sz_long ? 4 : 2;
                   1025:     
                   1026:     if (table[opcode].size == sz_long) {       
                   1027:        strcpy(getcode, "get_long(srca)");
                   1028:     } else {       
                   1029:        strcpy(getcode, "(LONG)(WORD)get_word(srca)");
                   1030:     }
                   1031:     
                   1032:     printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
                   1033:     genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true);
                   1034:     start_brace();
                   1035:     printf("\tint i, bitcnt = 0;\n");
                   1036:     printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
                   1037:     
                   1038:     printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.d[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
                   1039:     printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.a[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
                   1040:     
                   1041:     if (table[opcode].smode == Aipi)
                   1042:        printf("\tregs.a[srcreg] = srca;\n");
                   1043: }
                   1044: 
                   1045: static void genmovemle(UWORD opcode)
                   1046: {
                   1047:     char putcode[100], shiftcode[] = ">>";
                   1048:     int size = table[opcode].size == sz_long ? 4 : 2;
                   1049:     int mask = 1;
                   1050:     if (table[opcode].size == sz_long) {
                   1051:        strcpy(putcode, "put_long(srca,");
                   1052:     } else {       
                   1053:        strcpy(putcode, "put_word(srca,");
                   1054:     }
                   1055:     
                   1056:     printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
                   1057:     genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, true);
                   1058:     start_brace();
                   1059:     printf("\tint i, bitcnt = 0;\n");
                   1060:     printf("\tULONG rd[8], ra[8];\n");
                   1061:     printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
                   1062:     printf("\tfor(i=0;i<8;i++) { rd[i] = regs.d[i]; ra[i] = regs.a[i]; }\n");
                   1063:     if (table[opcode].smode == Apdi) {
                   1064:        printf("\tsrca -= %d*bitcnt;\n", size);
                   1065:        printf("\tregs.a[srcreg] = srca;\n");
                   1066:        strcpy(shiftcode, "<<");
                   1067:        mask = 0x8000;
                   1068:     }
                   1069: 
                   1070:     printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s rd[i]); srca += %d; } mask %s= 1; }\n", 
                   1071:           mask, putcode, size, shiftcode);
                   1072:     printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s ra[i]); srca += %d; } mask %s= 1; }\n",
                   1073:           mask, putcode, size, shiftcode);    
                   1074: }
                   1075: 
                   1076: typedef enum {
                   1077:     flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn
                   1078: } flagtypes;
                   1079: 
                   1080: static void genflags(flagtypes type, wordsizes size, char *value, char *src, char *dst)
                   1081: {
                   1082:     char vstr[100],sstr[100],dstr[100];
                   1083:     char usstr[100],udstr[100];
                   1084:     char unsstr[100],undstr[100];
                   1085:     ULONG mask;
                   1086:     switch(size) {
                   1087:      case sz_byte: mask = 0xFF; break;
                   1088:      case sz_word: mask = 0xFFFF; break;
                   1089:      case sz_long: mask = 0xFFFFFFFF; break;
                   1090:      default: myabort();
                   1091:     }
                   1092: #ifndef NO_INLINE_FLAGS
                   1093:     switch(size) {         
                   1094:      case sz_byte:
                   1095:        strcpy(vstr, "((BYTE)(");
                   1096:        strcpy(usstr, "((UBYTE)(");
                   1097:        break;
                   1098:      case sz_word:
                   1099:        strcpy(vstr, "((WORD)(");
                   1100:        strcpy(usstr, "((UWORD)(");
                   1101:        break;
                   1102:      case sz_long:
                   1103:        strcpy(vstr, "((LONG)(");
                   1104:        strcpy(usstr, "((ULONG)(");
                   1105:        break;
                   1106:      default:
                   1107:        myabort();
                   1108:     }
                   1109:     strcpy(unsstr, usstr); 
                   1110: 
                   1111:     strcpy(sstr, vstr);
                   1112:     strcpy(dstr, vstr);
                   1113:     strcat(vstr, value); strcat(vstr,"))");
                   1114:     strcat(dstr, dst); strcat(dstr,"))");
                   1115:     strcat(sstr, src); strcat(sstr,"))");
                   1116:     
                   1117:     strcpy(udstr, usstr);
                   1118:     strcat(udstr, dst); strcat(udstr,"))");
                   1119:     strcat(usstr, src); strcat(usstr,"))");
                   1120:     
                   1121:     strcpy(undstr, unsstr);
                   1122:     strcat(unsstr, "-");
                   1123:     strcat(undstr, "~");
                   1124:     strcat(undstr, dst); strcat(undstr,"))");
                   1125:     strcat(unsstr, src); strcat(unsstr,"))");
                   1126:     
                   1127:     switch(type) {
                   1128:      case flag_logical:
                   1129:        printf("\tregs.v = regs.c = 0;\n");
                   1130:        /* fall through */
                   1131:      case flag_zn:
                   1132:        switch(size) {
                   1133:         case sz_byte:
                   1134:            printf("\tregs.z = %s == 0;\n", vstr);
                   1135:            printf("\tregs.n = %s < 0;\n", vstr);
                   1136:            break;
                   1137:         case sz_word:
                   1138:            printf("\tregs.z = %s == 0;\n", vstr);
                   1139:            printf("\tregs.n = %s < 0;\n", vstr);
                   1140:            break;
                   1141:         case sz_long:
                   1142:            printf("\tregs.z = %s == 0;\n", vstr);
                   1143:            printf("\tregs.n = %s < 0;\n", vstr);
                   1144:            break;
                   1145:         default:
                   1146:            myabort();
                   1147:        }
                   1148:        break;
                   1149:      case flag_add:
                   1150:        start_brace();
                   1151:        printf("\tbool flgs = %s < 0;\n", sstr);
                   1152:        printf("\tbool flgo = %s < 0;\n", dstr);
                   1153:        printf("\tbool flgn = %s < 0;\n", vstr);
                   1154:        printf("\tregs.z = %s == 0;\n", vstr);
                   1155:        printf("\tregs.v = (flgs == flgo) && (flgn != flgo);\n");
                   1156:        printf("\tregs.c = regs.x = %s < %s;\n", undstr, usstr);
                   1157:        printf("\tregs.n = flgn != 0;\n");
                   1158:        break;
                   1159:      case flag_sub:
                   1160:        start_brace();
                   1161:        printf("\tbool flgs = %s < 0;\n", sstr);
                   1162:        printf("\tbool flgo = %s < 0;\n", dstr);
                   1163:        printf("\tbool flgn = %s < 0;\n", vstr);
                   1164:        printf("\tregs.z = %s == 0;\n", vstr);
                   1165:        printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n");
                   1166:        printf("\tregs.c = regs.x = %s > %s;\n", usstr, udstr);
                   1167:        printf("\tregs.n = flgn != 0;\n");
                   1168:        break;
                   1169:      case flag_addx:
                   1170:        start_brace();
                   1171:        printf("\tbool flgs = %s < 0;\n", sstr);
                   1172:        printf("\tbool flgo = %s < 0;\n", dstr);
                   1173:        printf("\tbool flgn = %s < 0;\n", vstr);
                   1174:        printf("\tif ((flgs && flgo && !flgn) || (!flgs && !flgo && flgn)) regs.v = 1;\n");
                   1175:        printf("\tif ((flgs && flgo) || (!flgn && (flgo || flgs))) regs.c = regs.x = 1;\n");
                   1176:        break;
                   1177:      case flag_subx:
                   1178:        start_brace();
                   1179:        printf("\tbool flgs = %s < 0;\n", sstr);
                   1180:        printf("\tbool flgo = %s < 0;\n", dstr);
                   1181:        printf("\tbool flgn = %s < 0;\n", vstr);
                   1182:        printf("\tif ((!flgs && flgo && !flgn) || (flgs && !flgo && flgn)) regs.v = 1;\n");
                   1183:        printf("\tif ((flgs && !flgo) || (flgn && (!flgo || flgs))) regs.c = regs.x = 1;\n");
                   1184:        break;
                   1185:      case flag_cmp:
                   1186:        start_brace();
                   1187:        printf("\tbool flgs = %s < 0;\n", sstr);
                   1188:        printf("\tbool flgo = %s < 0;\n", dstr);
                   1189:        printf("\tbool flgn = %s < 0;\n", vstr);
                   1190:        printf("\tregs.z = %s == 0;\n", vstr);
                   1191:        printf("\tregs.v = (flgs != flgo) && (flgn != flgo);\n");
                   1192:        printf("\tregs.c = %s > %s;\n", usstr, udstr);
                   1193:        printf("\tregs.n = flgn != 0;\n");
                   1194:        break;
                   1195:     }
                   1196: #else
                   1197:     switch(type) {
                   1198:      case flag_logical:
                   1199:        printf("\tsetflags_logical(%s,%s);\n", value, mask);
                   1200:        break;
                   1201:      case flag_add:
                   1202:        printf("\tsetflags_add(%s,%s,%s);\n", src, dest, value);
                   1203:        break;
                   1204:      case flag_sub:
                   1205:        printf("\tsetflags_sub(%s,%s,%s);\n", src, dest, value);
                   1206:        break;
                   1207:      case flag_addx:
                   1208:        printf("\tsetflags_addx(%s,%s,%s);\n", src, dest, value);
                   1209:        break;
                   1210:      case flag_subx:
                   1211:        printf("\tsetflags_subx(%s,%s,%s);\n", src, dest, value);
                   1212:        break;
                   1213:      case flag_cmp:
                   1214:        printf("\tsetflags_cmp(%s,%s,%s);\n", src, dest, value);
                   1215:        break;
                   1216:     }
                   1217: #endif    
                   1218: }
                   1219: 
                   1220: static void gen_opcode(unsigned long int opcode) 
                   1221: {
                   1222:     start_brace ();
                   1223:     switch(table[opcode].mnemo) {
                   1224:      case i_OR:
                   1225:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1226:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1227:        printf("\tsrc |= dst;\n");
                   1228:        genflags(flag_logical, table[opcode].size, "src", "", "");
                   1229:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1230:        break;
                   1231:      case i_AND:
                   1232:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1233:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1234:        printf("\tsrc &= dst;\n");
                   1235:        genflags(flag_logical, table[opcode].size, "src", "", "");
                   1236:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1237:        break;
                   1238:      case i_EOR:
                   1239:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1240:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1241:        printf("\tsrc ^= dst;\n");
                   1242:        genflags(flag_logical, table[opcode].size, "src", "", "");
                   1243:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1244:        break;
                   1245:      case i_ORSR:
                   1246:        if (table[opcode].size != sz_byte) {
                   1247:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
                   1248:        }
                   1249:        start_brace ();
                   1250:        printf("\tMakeSR();\n");
                   1251:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1252:        if (table[opcode].size == sz_byte) {
                   1253:            printf("\tsrc &= 0xFF;\n");
                   1254:        }
                   1255:        printf("\tregs.sr |= src;\n");
                   1256:        printf("\tMakeFromSR();\n");
                   1257:        break;
                   1258:      case i_ANDSR: 
                   1259:        if (table[opcode].size != sz_byte) {
                   1260:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
                   1261:        }
                   1262:        start_brace();
                   1263:        
                   1264:        printf("\tMakeSR();\n");
                   1265:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1266:        if (table[opcode].size == sz_byte) {
                   1267:            printf("\tsrc |= 0xFF00;\n");
                   1268:        }
                   1269:        printf("\tregs.sr &= src;\n");
                   1270:        printf("\tMakeFromSR();\n");
                   1271:        break;
                   1272:      case i_EORSR:
                   1273:        if (table[opcode].size != sz_byte) {
                   1274:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
                   1275:        }
                   1276:        start_brace ();
                   1277:        printf("\tMakeSR();\n");
                   1278:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1279:        if (table[opcode].size == sz_byte) {
                   1280:            printf("\tsrc &= 0xFF;\n");
                   1281:        }
                   1282:        printf("\tregs.sr ^= src;\n");
                   1283:        printf("\tMakeFromSR();\n");
                   1284:        break;
                   1285:      case i_SUB: 
                   1286:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1287:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1288:        start_brace ();
                   1289:        printf("\tULONG newv = dst - src;\n");
                   1290:        genflags(flag_sub, table[opcode].size, "newv", "src", "dst");
                   1291:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1292:        break;
                   1293:      case i_SUBA:
                   1294:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1295:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
                   1296:        start_brace ();
                   1297:        printf("\tULONG newv = dst - src;\n");
                   1298:        genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst");
                   1299:        break;
                   1300:      case i_SUBX:
                   1301:        {
                   1302:            int old_brace_level;
                   1303:            genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1304:            genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1305:            start_brace ();
                   1306:            printf("\tbool xflg = regs.x;\n");
                   1307:            printf("\tregs.v = regs.c = regs.x = 0;\n");
                   1308:            start_brace ();
                   1309:            printf("\tULONG newv = dst - src;\n");
                   1310:            genflags(flag_subx, table[opcode].size, "newv", "src", "dst");
                   1311:            /* FIXME: I'm not entirely sure how to handle this */
                   1312:            printf("\tif (xflg)\n"); 
                   1313:            old_brace_level = n_braces;
                   1314:            start_brace ();
                   1315:            genflags(flag_subx, table[opcode].size, "(newv-1)", "1", "newv");
                   1316:            printf("\tnewv--;\n");
                   1317:            pop_braces(old_brace_level);
                   1318:            
                   1319:            genflags(flag_zn, table[opcode].size, "newv", "", "");
                   1320:            genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1321:        }
                   1322:        break;
                   1323:      case i_SBCD:
                   1324:        /* Let's hope this works... */
                   1325:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1326:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1327:        start_brace ();
                   1328:        printf("\tUWORD newv = dst - src - regs.x;\n");
                   1329:        printf("\tif ((newv & 0xF) > 9) newv-=6;\n");
                   1330:        printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
                   1331:        printf("\tif (regs.c) newv -= 0x60;\n");
                   1332:        printf("\tif (newv != 0) regs.z = 0;\n");
                   1333:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1334:        break;
                   1335:      case i_ADD:
                   1336:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1337:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1338:        start_brace ();
                   1339:        printf("\tULONG newv = dst + src;\n");
                   1340:        genflags(flag_add, table[opcode].size, "newv", "src", "dst");
                   1341:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1342:        break;
                   1343:      case i_ADDA: 
                   1344:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1345:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
                   1346:        start_brace ();
                   1347:        printf("\tULONG newv = dst + src;\n");
                   1348:        genastore("newv", table[opcode].dmode, "dstreg", sz_long, "dst");
                   1349:        break;
                   1350:      case i_ADDX:
                   1351:        {
                   1352:            int old_brace_level;
                   1353:            genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1354:            genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1355:            start_brace ();
                   1356:            printf("\tbool xflg = regs.x;\n");
                   1357:            printf("\tregs.v = regs.c = regs.x = 0;\n");
                   1358:            start_brace ();
                   1359:            printf("\tULONG newv = dst + src;\n");
                   1360:            genflags(flag_addx, table[opcode].size, "newv", "src", "dst");
                   1361:            printf("\tif (xflg)\n");
                   1362:            old_brace_level = n_braces;
                   1363:            start_brace ();
                   1364:            genflags(flag_addx, table[opcode].size, "(newv+1)", "newv", "1");
                   1365:            printf("\tnewv++;\n");
                   1366:            pop_braces(old_brace_level);
                   1367:            genflags(flag_zn, table[opcode].size, "newv", "", "");
                   1368:            genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1369:        }
                   1370:        break;
                   1371:      case i_ABCD:
                   1372:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1373:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1374:        start_brace ();
                   1375:        printf("\tUWORD newv = src + dst + regs.x;\n");
                   1376:        printf("\tif ((newv & 0xF) > 9) newv+=6;\n");
                   1377:        printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
                   1378:        printf("\tif (regs.c) newv += 0x60;\n");
                   1379:        printf("\tif (newv != 0) regs.z = 0;\n");
                   1380:        genastore("newv", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1381:        break;
                   1382:      case i_NEG:
                   1383:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1384:        start_brace ();
                   1385:        printf("\tULONG dst = -src;\n");
                   1386:        genflags(flag_sub, table[opcode].size, "dst", "src", "0");
                   1387:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1388:        break;
                   1389:      case i_NEGX:
                   1390:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1391:        start_brace ();
                   1392:        printf("\tULONG dst = -src-regs.x;\n");
                   1393:        genflags(flag_sub, table[opcode].size, "dst", "src", "0");
                   1394:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1395:        break;
                   1396:      case i_NBCD: 
                   1397:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1398:        start_brace ();
                   1399:        printf("\tUWORD newv = - src - regs.x;\n");
                   1400:        printf("\tif ((newv & 0xF) > 9) newv-=6;\n");
                   1401:        printf("\tregs.c = regs.x = (newv & 0x1F0) > 0x90;\n");
                   1402:        printf("\tif (regs.c) newv -= 0x60;\n");
                   1403:        printf("\tif (newv != 0) regs.z = 0;\n");
                   1404:        genastore("newv", table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1405:        break;
                   1406:      case i_CLR: 
                   1407:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1408:        genflags(flag_logical, table[opcode].size, "0", "", "");
                   1409:        genastore("0",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1410:        break;
                   1411:      case i_NOT: 
                   1412:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1413:        start_brace ();
                   1414:        printf("\tULONG dst = ~src;\n");
                   1415:        genflags(flag_logical, table[opcode].size, "dst", "", "");
                   1416:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1417:        break;
                   1418:      case i_TST:
                   1419:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1420:        genflags(flag_logical, table[opcode].size, "src", "", "");
                   1421:        break;
                   1422:      case i_BTST:
                   1423:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1424:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1425:        if (table[opcode].size == sz_byte)
                   1426:            printf("\tsrc &= 7;\n");
                   1427:        else
                   1428:            printf("\tsrc &= 31;\n");
                   1429:        printf("\tregs.z = !(dst & (1 << src));\n");
                   1430:        break;
                   1431:      case i_BCHG:
                   1432:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1433:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1434:        if (table[opcode].size == sz_byte)
                   1435:            printf("\tsrc &= 7;\n");
                   1436:        else
                   1437:            printf("\tsrc &= 31;\n");
                   1438:        printf("\tregs.z = !(dst & (1 << src));\n");
                   1439:        printf("\tdst ^= (1 << src);\n");
                   1440:        genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1441:        break;
                   1442:      case i_BCLR:
                   1443:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1444:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1445:        if (table[opcode].size == sz_byte)
                   1446:            printf("\tsrc &= 7;\n");
                   1447:        else
                   1448:            printf("\tsrc &= 31;\n");
                   1449:        printf("\tregs.z = !(dst & (1 << src));\n");
                   1450:        printf("\tdst &= ~(1 << src);\n");
                   1451:        genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1452:        break;
                   1453:      case i_BSET:
                   1454:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1455:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1456:        if (table[opcode].size == sz_byte)
                   1457:            printf("\tsrc &= 7;\n");
                   1458:        else
                   1459:            printf("\tsrc &= 31;\n");
                   1460:        printf("\tregs.z = !(dst & (1 << src));\n");
                   1461:        printf("\tdst |= (1 << src);\n");
                   1462:        genastore("dst", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1463:        break;
                   1464:      case i_CMPM:
                   1465:      case i_CMP:
                   1466:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1467:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1468:        start_brace ();
                   1469:        printf("\tULONG newv = dst - src;\n");
                   1470:        genflags(flag_cmp, table[opcode].size, "newv", "src", "dst");
                   1471:        break;
                   1472:      case i_CMPA: 
                   1473:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1474:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
                   1475:        start_brace ();
                   1476:        printf("\tULONG newv = dst - src;\n");
                   1477:        genflags(flag_cmp, sz_long, "newv", "src", "dst");
                   1478:        break;
                   1479:      case i_MOVEP: 
                   1480:        printf("\tfprintf(stderr, \"MOVEP\\n\");\n");
                   1481:        break;
                   1482:      case i_MOVE:
                   1483:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1484:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
                   1485:        genflags(flag_logical, table[opcode].size, "src", "", "");
                   1486:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1487:        break;
                   1488:      case i_MOVEA:
                   1489:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1490:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
                   1491:        genastore("src", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1492:        break;
                   1493:      case i_MVSR2: 
                   1494:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1495:        printf("\tMakeSR();\n");
                   1496:        genastore("regs.sr", table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1497:        break;
                   1498:      case i_MV2SR:
                   1499:        if (table[opcode].size != sz_byte) {
                   1500:            printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else\n");
                   1501:        }
                   1502:        start_brace ();
                   1503:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1504:        if (table[opcode].size == sz_byte)
                   1505:            printf("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
                   1506:        else {              
                   1507:            printf("\tregs.sr = src;\n");
                   1508:        }
                   1509:        printf("\tMakeFromSR();\n");
                   1510:        break;
                   1511:      case i_SWAP: 
                   1512:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1513:        start_brace ();
                   1514:        printf("\tULONG dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
                   1515:        genflags(flag_logical, table[opcode].size, "dst", "", "");
                   1516:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1517:        break;
                   1518:      case i_EXG:
                   1519:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1520:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", true, false);
                   1521:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1522:        genastore("src",table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1523:        break;
                   1524:      case i_EXT:
                   1525:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1526:        start_brace ();
                   1527:        switch(table[opcode].size) {
                   1528:         case sz_word: printf("\tULONG dst = (LONG)(BYTE)src;\n"); break;
                   1529:         case sz_long: printf("\tULONG dst = (LONG)(WORD)src;\n"); break;
                   1530:         default: myabort();
                   1531:        }
                   1532:        genflags(flag_logical, table[opcode].size, "dst", "", "");
                   1533:        genastore("dst",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1534:        break;
                   1535:      case i_MVMEL:
                   1536:        genmovemel(opcode);
                   1537:        break;
                   1538:      case i_MVMLE:
                   1539:        genmovemle(opcode);
                   1540:        break;
                   1541:      case i_TRAP:
                   1542:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1543:        printf("\tException(src+32);\n");
                   1544:        break;
                   1545:      case i_MVR2USP:
                   1546:        printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
                   1547:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1548:        printf("\tregs.usp = src;\n");
                   1549:        printf("\t}\n");
                   1550:        break;
                   1551:      case i_MVUSP2R: 
                   1552:        printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
                   1553:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1554:        genastore("regs.usp", table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1555:        printf("\t}\n");
                   1556:        break;
                   1557:      case i_RESET:
                   1558:        printf("\tcustomreset();\n");
                   1559:        break;
                   1560:      case i_NOP:
                   1561:        break;
                   1562:      case i_STOP:
                   1563:        printf("\tif (!regs.s) { regs.pc_p--; Exception(8); } else {\n");
                   1564:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1565:        printf("\tregs.sr = src;\n");
                   1566:        printf("\tMakeFromSR();\n");
                   1567:        printf("\tm68k_setstopped(1);\n");
                   1568:        printf("\t}\n");
                   1569:        break;
                   1570:      case i_RTE:
                   1571:        genamode(Aipi, "7", sz_word, "sr", true, false);
                   1572:        genamode(Aipi, "7", sz_long, "pc", true, false);
                   1573:        printf("\tregs.sr = sr; m68k_setpc(pc);\n");
                   1574:        printf("\tMakeFromSR();\n");
                   1575:        break;
                   1576:      case i_RTD:
                   1577:        break;
                   1578:      case i_LINK:
                   1579:        genamode(Apdi, "7", sz_long, "old", false, false);
                   1580:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1581:        genastore("src", Apdi, "7", sz_long, "old");
                   1582:        genastore("regs.a[7]", table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1583:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false);
                   1584:        printf("\tregs.a[7] += offs;\n");
                   1585:        break;
                   1586:      case i_UNLK:
                   1587:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1588:        printf("\tregs.a[7] = src;\n");
                   1589:        genamode(Aipi, "7", sz_long, "old", true, false);
                   1590:        genastore("old", table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1591:        break;
                   1592:      case i_RTS:
                   1593:        genamode(Aipi, "7", sz_long, "pc", true, false);
                   1594:        printf("\tm68k_setpc(pc);\n");
                   1595:        break;
                   1596:      case i_TRAPV:
                   1597:        printf("\tif(regs.v) Exception(7);\n");
                   1598:        break;
                   1599:      case i_RTR: 
                   1600:        printf("\tMakeSR();\n");
                   1601:        genamode(Aipi, "7", sz_word, "sr", true, false);
                   1602:        genamode(Aipi, "7", sz_long, "pc", true, false);
                   1603:        printf("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
                   1604:        printf("\tregs.sr |= sr; m68k_setpc(pc);\n");
                   1605:        printf("\tMakeFromSR();\n");
                   1606:        break;
                   1607:      case i_JSR:
                   1608:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1609:        genamode(Apdi, "7", sz_long, "sp", false, false);
                   1610:        genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
                   1611:        printf("\tm68k_setpc(srca);\n");
                   1612:        break;
                   1613:      case i_JMP: 
                   1614:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1615:        printf("\tm68k_setpc(srca);\n");
                   1616:        break;
                   1617:      case i_BSR:
                   1618:        printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
                   1619:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1620:        genamode(Apdi, "7", sz_long, "sp", false, false);
                   1621:        genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
                   1622:        printf("\tregs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n");
                   1623:        break;
                   1624:      case i_Bcc:
                   1625:        printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
                   1626:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1627:        printf("\tif (cctrue(%d)) regs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n", table[opcode].cc);
                   1628:        break;
                   1629:      case i_LEA:
                   1630:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1631:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "dst", false, false);
                   1632:        genastore("srca", table[opcode].dmode, "dstreg", table[opcode].size, "dst");
                   1633:        break;
                   1634:      case i_PEA:
                   1635:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1636:        genamode(Apdi, "7", sz_long, "dst", false, false);
                   1637:        genastore("srca", Apdi, "7", sz_long, "dst");
                   1638:        break;
                   1639:      case i_DBcc:
                   1640:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", true, false);
                   1641:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "offs", true, false);
                   1642:        printf("\tif (!cctrue(%d)) {\n", table[opcode].cc);
                   1643:        printf("\tif (src--) regs.pc_p = (UWORD *)((char *)regs.pc_p + (LONG)offs - 2);\n");
                   1644:        genastore("src", table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1645:        printf("\t}\n");
                   1646:        break;
                   1647:      case i_Scc: 
                   1648:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "src", false, false);
                   1649:        start_brace ();
                   1650:        printf("\tint val = cctrue(%d) ? 0xff : 0;\n", table[opcode].cc);
                   1651:        genastore("val",table[opcode].smode, "srcreg", table[opcode].size, "src");
                   1652:        break;
                   1653:      case i_DIVU:
                   1654:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
                   1655:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
                   1656:        printf("\tif(src != 0){\n");
                   1657:        printf("\tULONG newv = (ULONG)dst / (UWORD)src;\n");
                   1658:        printf("\tULONG rem = (ULONG)dst %% (UWORD)src;\n");
                   1659:        /* The N flag appears to be set each time there is an overflow.
                   1660:         * Weird. */
                   1661:        printf("\tif (newv > 0xffff) { regs.v = regs.n = 1; } else\n\t{\n");
                   1662:        genflags(flag_logical, sz_word, "newv", "", "");
                   1663:        printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
                   1664:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
                   1665:        printf("\t}\n");
                   1666:        printf("\t}\n");
                   1667:        break;
                   1668:      case i_DIVS: 
                   1669:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
                   1670:        genamode(table[opcode].dmode, "dstreg", sz_long, "dst", true, false);
                   1671:        printf("\tif(src != 0){\n");
                   1672:        printf("\tLONG newv = (LONG)dst / (WORD)src;\n");
                   1673:        printf("\tUWORD rem = (LONG)dst %% (WORD)src;\n");
                   1674:        printf("\tif ((newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000) { regs.v = regs.n = 1; } else\n\t{\n");
                   1675:        printf("\tif (((WORD)rem < 0) != ((LONG)dst < 0)) rem = -rem;\n");
                   1676:        genflags(flag_logical, sz_word, "newv", "", "");
                   1677:        printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
                   1678:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
                   1679:        printf("\t}\n");
                   1680:        printf("\t}\n");
                   1681:        break;
                   1682:      case i_MULU: 
                   1683:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
                   1684:        genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false);
                   1685:        start_brace ();
                   1686:        printf("\tULONG newv = (ULONG)(UWORD)dst * (ULONG)(UWORD)src;\n");
                   1687:        genflags(flag_logical, sz_long, "newv", "", "");
                   1688:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
                   1689: #ifdef WANT_SLOW_MULTIPLY
                   1690:        printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
                   1691: #endif
                   1692:        break;
                   1693:      case i_MULS:
                   1694:        genamode(table[opcode].smode, "srcreg", sz_word, "src", true, false);
                   1695:        genamode(table[opcode].dmode, "dstreg", sz_word, "dst", true, false);
                   1696:        start_brace ();
                   1697:        printf("\tULONG newv = (LONG)(WORD)dst * (LONG)(WORD)src;\n");
                   1698:        genflags(flag_logical, sz_long, "newv", "", "");
                   1699:        genastore("newv",table[opcode].dmode, "dstreg", sz_long, "dst");
                   1700: #ifdef WANT_SLOW_MULTIPLY
                   1701:        printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
                   1702: #endif
                   1703:        break;
                   1704:      case i_ASR: 
                   1705:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1706:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1707:        start_brace ();
                   1708:        switch(table[opcode].size) {
                   1709:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1710:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1711:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1712:         default: myabort();
                   1713:        }
                   1714:        printf("\tcnt &= 63;\n");
                   1715:        printf("\tregs.v = 0;\n");
                   1716:        start_brace ();
                   1717:        switch(table[opcode].size) {
                   1718:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1719:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1720:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1721:         default: myabort();
                   1722:        }
                   1723:        printf("\tULONG sign = cmask & val;\n");
                   1724:        printf("\tfor(;cnt;--cnt){\n");
                   1725:        printf("\tregs.c=regs.x=val&1; val = ((ULONG)val >> 1) | sign;\n");
                   1726:        printf("\t}\n\tregs.n = sign != 0;\n");
                   1727:        printf("\tregs.z = val == 0;\n");
                   1728:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1729:        break;
                   1730:      case i_ASL:
                   1731:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1732:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1733:        start_brace ();
                   1734:        switch(table[opcode].size) {
                   1735:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1736:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1737:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1738:         default: myabort();
                   1739:        }
                   1740:        printf("\tcnt &= 63;\n");
                   1741:        printf("\tregs.v = 0;\n");
                   1742:        start_brace ();
                   1743:        switch(table[opcode].size) {
                   1744:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1745:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1746:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1747:         default: myabort();
                   1748:        }
                   1749:        printf("\tULONG sign = cmask & val;\n");
                   1750:        printf("\tfor(;cnt;--cnt){\n");
                   1751:        printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n");
                   1752:        printf("\tif ((val&cmask)!=sign)regs.v=1;\n");
                   1753:        printf("\t}\n\tregs.n = (val&cmask) != 0;\n");
                   1754:        printf("\tregs.z = val == 0;\n");
                   1755:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1756:        break;
                   1757:      case i_LSR:
                   1758:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1759:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1760:        start_brace ();
                   1761:        switch(table[opcode].size) {
                   1762:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1763:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1764:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1765:         default: myabort();
                   1766:        }
                   1767:        printf("\tcnt &= 63;\n");
                   1768:        start_brace ();
                   1769:        printf("\tint carry = 0;\n");
                   1770:        printf("\tfor(;cnt;--cnt){\n");
                   1771:        printf("\tcarry=val&1; val >>= 1;\n");
                   1772:        printf("\t}\n");
                   1773:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1774:        printf("regs.c = regs.x = carry!=0;\n");
                   1775:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1776:        break;
                   1777:      case i_LSL:
                   1778:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1779:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1780:        start_brace ();
                   1781:        switch(table[opcode].size) {
                   1782:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1783:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1784:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1785:         default: myabort();
                   1786:        }
                   1787:        printf("\tcnt &= 63;\n");
                   1788:        start_brace ();
                   1789:        printf("\tint carry = 0;\n");
                   1790:        switch(table[opcode].size) {
                   1791:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1792:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1793:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1794:         default: myabort();
                   1795:        }
                   1796:        printf("\tfor(;cnt;--cnt){\n");
                   1797:        printf("\tcarry=val&cmask; val <<= 1;\n");
                   1798:        printf("\t}\n");
                   1799:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1800:        printf("regs.c = regs.x = carry!=0;\n");
                   1801:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1802:        break;
                   1803:      case i_ROL:
                   1804:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1805:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1806:        start_brace ();
                   1807:        switch(table[opcode].size) {
                   1808:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1809:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1810:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1811:         default: myabort();
                   1812:        }
                   1813:        printf("\tcnt &= 63;\n");
                   1814:        start_brace ();
                   1815:        printf("\tint carry = 0;\n");
                   1816:        switch(table[opcode].size) {
                   1817:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1818:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1819:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1820:         default: myabort();
                   1821:        }
                   1822:        printf("\tfor(;cnt;--cnt){\n");
                   1823:        printf("\tcarry=val&cmask; val <<= 1;\n");
                   1824:        printf("\tif(carry)  val |= 1;\n");
                   1825:        printf("\t}\n");
                   1826:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1827:        printf("regs.c = carry!=0;\n");
                   1828:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1829:        break;
                   1830:      case i_ROR:
                   1831:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1832:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1833:        start_brace ();
                   1834:        switch(table[opcode].size) {
                   1835:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1836:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1837:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1838:         default: myabort();
                   1839:        }
                   1840:        
                   1841:        printf("\tcnt &= 63;\n");
                   1842:        start_brace ();
                   1843:        printf("\tint carry = 0;\n");
                   1844:        switch(table[opcode].size) {
                   1845:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1846:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1847:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1848:         default: myabort();
                   1849:        }
                   1850:        printf("\tfor(;cnt;--cnt){\n");
                   1851:        printf("\tcarry=val&1; val = (ULONG)val >> 1;\n");
                   1852:        printf("\tif(carry) val |= cmask;\n");
                   1853:        printf("\t}\n");
                   1854:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1855:        printf("\tregs.c = carry!=0;\n");
                   1856:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1857:        break;
                   1858:      case i_ROXL: 
                   1859:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1860:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1861:        start_brace ();
                   1862:        switch(table[opcode].size) {
                   1863:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1864:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1865:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1866:         default: myabort();
                   1867:        }
                   1868:        printf("\tcnt &= 63;\n");
                   1869:        start_brace ();
                   1870:        printf("\tint carry = 0;\n");
                   1871:        switch(table[opcode].size) {
                   1872:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1873:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1874:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1875:         default: myabort();
                   1876:        }
                   1877:        printf("\tfor(;cnt;--cnt){\n");
                   1878:        printf("\tcarry=val&cmask; val <<= 1;\n");
                   1879:        printf("\tif(regs.x) val |= 1;\n");    
                   1880:        printf("\tregs.x = carry != 0;\n");
                   1881:        printf("\t}\n");
                   1882:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1883:        printf("\tregs.x = regs.c = carry!=0;\n");
                   1884:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1885:        break;
                   1886:      case i_ROXR:
                   1887:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "cnt", true, false);
                   1888:        genamode(table[opcode].dmode, "dstreg", table[opcode].size, "data", true, false);
                   1889:        start_brace ();
                   1890:        switch(table[opcode].size) {
                   1891:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1892:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1893:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1894:         default: myabort();
                   1895:        }
                   1896:        printf("\tcnt &= 63;\n");
                   1897:        start_brace ();
                   1898:        printf("\tint carry = 0;\n");
                   1899:        switch(table[opcode].size) {
                   1900:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1901:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1902:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1903:         default: myabort();
                   1904:        }
                   1905:        printf("\tfor(;cnt;--cnt){\n");
                   1906:        printf("\tcarry=val&1; val >>= 1;\n");
                   1907:        printf("\tif(regs.x) val |= cmask;\n");
                   1908:        printf("\tregs.x = carry != 0;\n");
                   1909:        printf("\t}\n");
                   1910:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1911:        printf("\tregs.x = regs.c = carry!=0;\n");
                   1912:        genastore("val", table[opcode].dmode, "dstreg", table[opcode].size, "data");
                   1913:        break;
                   1914:      case i_ASRW:
                   1915:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   1916:        printf("\tregs.v = 0;\n");
                   1917:        start_brace ();
                   1918:        switch(table[opcode].size) {
                   1919:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1920:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1921:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1922:         default: myabort();
                   1923:        }
                   1924:        switch(table[opcode].size) {
                   1925:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1926:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1927:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1928:         default: myabort();
                   1929:        }
                   1930:        printf("\tULONG sign = cmask & val;\n");
                   1931:        printf("\tregs.c=regs.x=val&1; val = (val >> 1) | sign;\n");
                   1932:        printf("\tregs.n = sign != 0;\n");
                   1933:        printf("\tregs.z = val == 0;\n");
                   1934:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   1935:        break;
                   1936:      case i_ASLW:
                   1937:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   1938:        printf("\tregs.v = 0;\n");
                   1939:        start_brace ();
                   1940:        switch(table[opcode].size) {
                   1941:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1942:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1943:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1944:         default: myabort();
                   1945:        }
                   1946:        switch(table[opcode].size) {
                   1947:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1948:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1949:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1950:         default: myabort();
                   1951:        }
                   1952:        printf("\tULONG sign = cmask & val;\n");
                   1953:        printf("\tregs.c=regs.x=(val&cmask)!=0; val <<= 1;\n");
                   1954:        printf("\tif ((val&cmask)!=sign)regs.v=1;\n");
                   1955:        printf("\tregs.n = (val&cmask) != 0;\n");
                   1956:        printf("\tregs.z = val == 0;\n");
                   1957:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   1958:        break;
                   1959:      case i_LSRW:
                   1960:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   1961:        start_brace ();
                   1962:        switch(table[opcode].size) {
                   1963:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1964:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1965:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1966:         default: myabort();
                   1967:        }
                   1968:        printf("\tint carry = val&1;\n");
                   1969:        printf("\tcarry=val&1; val >>= 1;\n");
                   1970:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1971:        printf("regs.c = regs.x = carry!=0;\n");
                   1972:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   1973:        break;
                   1974:      case i_LSLW:
                   1975:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   1976:        start_brace ();
                   1977:        switch(table[opcode].size) {
                   1978:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1979:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1980:         case sz_long: printf("\tULONG val = data;\n"); break;
                   1981:         default: myabort();
                   1982:        }
                   1983:        switch(table[opcode].size) {
                   1984:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1985:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1986:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   1987:         default: myabort();
                   1988:        }
                   1989:        printf("\tint carry = val&cmask;\n");
                   1990:        printf("\tval <<= 1;\n");
                   1991:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   1992:        printf("regs.c = regs.x = carry!=0;\n");
                   1993:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   1994:        break;
                   1995:      case i_ROLW:
                   1996:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   1997:        start_brace ();
                   1998:        switch(table[opcode].size) {
                   1999:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   2000:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   2001:         case sz_long: printf("\tULONG val = data;\n"); break;
                   2002:         default: myabort();
                   2003:        }
                   2004:        switch(table[opcode].size) {
                   2005:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   2006:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   2007:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   2008:         default: myabort();
                   2009:        }
                   2010:        printf("\tint carry = val&cmask;\n");
                   2011:        printf("\tval <<= 1;\n");
                   2012:        printf("\tif(carry)  val |= 1;\n");
                   2013:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   2014:        printf("regs.c = carry!=0;\n");
                   2015:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   2016:        break;
                   2017:      case i_RORW:
                   2018:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   2019:        start_brace ();
                   2020:        switch(table[opcode].size) {
                   2021:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   2022:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   2023:         case sz_long: printf("\tULONG val = data;\n"); break;
                   2024:         default: myabort();
                   2025:        }
                   2026:        printf("\tint carry = val&1;\n");
                   2027:        switch(table[opcode].size) {
                   2028:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   2029:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   2030:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   2031:         default: myabort();
                   2032:        }
                   2033:        printf("\tval >>= 1;\n");
                   2034:        printf("\tif(carry) val |= cmask;\n");
                   2035:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   2036:        printf("regs.c = carry!=0;\n");
                   2037:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   2038:        break;
                   2039:      case i_ROXLW:
                   2040:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   2041:        start_brace ();
                   2042:        switch(table[opcode].size) {
                   2043:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   2044:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   2045:         case sz_long: printf("\tULONG val = data;\n"); break;
                   2046:         default: myabort();
                   2047:        }
                   2048:        switch(table[opcode].size) {
                   2049:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   2050:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   2051:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   2052:         default: myabort();
                   2053:        }
                   2054:        printf("\tint carry = val&cmask;\n");
                   2055:        printf("\tval <<= 1;\n");
                   2056:        printf("\tif(regs.x) val |= 1;\n");
                   2057:        printf("\tregs.x = carry != 0;\n");
                   2058:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   2059:        printf("regs.x = regs.c = carry!=0;\n");
                   2060:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   2061:        break;
                   2062:      case i_ROXRW:
                   2063:        genamode(table[opcode].smode, "srcreg", table[opcode].size, "data", true, false);
                   2064:        start_brace ();
                   2065:        switch(table[opcode].size) {
                   2066:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   2067:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   2068:         case sz_long: printf("\tULONG val = data;\n"); break;
                   2069:         default: myabort();
                   2070:        }
                   2071:        printf("\tint carry = val&1;\n");
                   2072:        switch(table[opcode].size) {
                   2073:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   2074:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   2075:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
                   2076:         default: myabort();
                   2077:        }
                   2078:        printf("\tval >>= 1;\n");
                   2079:        printf("\tif(regs.x) val |= cmask;\n");
                   2080:        printf("\tregs.x = carry != 0;\n");
                   2081:        genflags(flag_logical, table[opcode].size, "val", "", "");
                   2082:        printf("regs.x = regs.c = carry!=0;\n");
                   2083:        genastore("val", table[opcode].smode, "srcreg", table[opcode].size, "data");
                   2084:        break;
                   2085:      default:
                   2086:        myabort();
                   2087:        break;
                   2088:     };
                   2089:     finish_braces ();
                   2090: }
                   2091: 
                   2092: static int mismatch;
                   2093: 
                   2094: static void handle_merges(long int opcode)
                   2095: {
                   2096:     UWORD smsk; 
                   2097:     UWORD dmsk;
                   2098:     int sbitsrc, sbitdst;
                   2099:     int srcreg, dstreg;
                   2100:     
                   2101:     smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos;
                   2102:     dmsk = 7 << table[opcode].dpos;
                   2103:     sbitsrc = table[opcode].spos == -1 ? 0 : 0;
                   2104:     sbitdst = table[opcode].spos == -1 ? 1 : (table[opcode].sbtarg ? 256 : 8);
                   2105:     for (srcreg=sbitsrc; srcreg < sbitdst; srcreg++) {
                   2106:        for (dstreg=0; dstreg < (table[opcode].dpos == -1 ? 1 : 8); dstreg++) {
                   2107:            UWORD code = opcode;                
                   2108: 
                   2109:            if (table[opcode].spos != -1) code &= ~(smsk << table[opcode].spos);
                   2110:            if (table[opcode].dpos != -1) code &= ~(dmsk << table[opcode].dpos);
                   2111:            
                   2112:            if (table[opcode].spos != -1) code |= srcreg << table[opcode].spos;
                   2113:            if (table[opcode].dpos != -1) code |= dstreg << table[opcode].dpos;
                   2114:            
                   2115:            /* Check whether this is in fact the same instruction.
                   2116:             * The instructions should never differ, except for the
                   2117:             * Bcc.(BW) case. */
                   2118:            if (table[code].mnemo != table[opcode].mnemo
                   2119:                || table[code].size != table[opcode].size
                   2120:                || table[code].suse != table[opcode].suse
                   2121:                || table[code].duse != table[opcode].duse) 
                   2122:            {
                   2123:                mismatch++; continue;
                   2124:            }
                   2125:            if (table[opcode].suse 
                   2126:                && (table[opcode].spos != table[code].spos
                   2127:                    || table[opcode].smode != table[code].smode
                   2128:                    || table[opcode].sbtarg != table[code].sbtarg)) 
                   2129:            {
                   2130:                mismatch++; continue;
                   2131:            }
                   2132:            if (table[opcode].duse 
                   2133:                && (table[opcode].dpos != table[code].dpos
                   2134:                    || table[opcode].dmode != table[code].dmode))
                   2135:            {
                   2136:                mismatch++; continue;
                   2137:            }
                   2138:            
                   2139:            table[code].generated = true;
                   2140:            table[code].handler = opcode;
                   2141:        }
                   2142:     }
                   2143: }
                   2144:               
                   2145: static void generate_func(long int from, long int to)
                   2146: {
                   2147:     int illg = 0;
                   2148:     long int opcode;
                   2149:     UWORD smsk; 
                   2150:     UWORD dmsk;    
                   2151:     mismatch = 0;
                   2152: 
                   2153:     printf("#include <stdlib.h>\n");
                   2154:     printf("#include \"config.h\"\n");
                   2155:     printf("#include \"amiga.h\"\n");
                   2156:     printf("#include \"options.h\"\n");
                   2157:     printf("#include \"memory.h\"\n");
                   2158:     printf("#include \"custom.h\"\n");    
                   2159:     printf("#include \"newcpu.h\"\n");
                   2160:     printf("#include \"cputbl.h\"\n");
                   2161:     for(opcode=from; opcode < to; opcode++) {
                   2162:        if (table[opcode].mnemo == i_ILLG) {
                   2163:            illg++;
                   2164:            continue;
                   2165:        }
                   2166:        if (table[opcode].generated) {
                   2167:            continue;
                   2168:        }
                   2169: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
                   2170:     
                   2171:        handle_merges (opcode);
                   2172:        
                   2173:        smsk = (table[opcode].sbtarg ? 255 : 7) << table[opcode].spos;
                   2174:        dmsk = 7 << table[opcode].dpos;
                   2175: 
                   2176:        printf("void op_%lx(UWORD opcode)\n{\n", opcode);
                   2177:        if (table[opcode].suse
                   2178:            && table[opcode].smode != imm  && table[opcode].smode != imm0
                   2179:            && table[opcode].smode != imm1 && table[opcode].smode != imm2
                   2180:            && table[opcode].smode != absw && table[opcode].smode != absl
                   2181:            && table[opcode].smode != PC8r && table[opcode].smode != PC16)
                   2182:        {
                   2183:            if (table[opcode].spos == -1) {
                   2184:                printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg);
                   2185:            } else {
                   2186:                printf("\tULONG srcreg = (LONG)(BYTE)((opcode & %d) >> %d);\n", smsk, (int)table[opcode].spos);
                   2187:            }
                   2188:        }
                   2189:        if (table[opcode].duse
                   2190:            /* Yes, the dmode can be imm, in case of LINK or DBcc */
                   2191:            && table[opcode].dmode != imm  && table[opcode].dmode != imm0
                   2192:            && table[opcode].dmode != imm1 && table[opcode].dmode != imm2
                   2193:            && table[opcode].dmode != absw && table[opcode].dmode != absl) {
                   2194:            if (table[opcode].dpos == -1) {             
                   2195:                printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg);
                   2196:            } else {
                   2197:                printf("\tULONG dstreg = (opcode & %d) >> %d;\n", dmsk, (int)table[opcode].dpos);
                   2198:            }
                   2199:        }
                   2200: #else
                   2201:        printf("void op_%lx(UWORD opcode)\n{\n", opcode);
                   2202:        if (table[opcode].suse)
                   2203:            printf("\tULONG srcreg = %d;\n", (int)table[opcode].sreg);
                   2204:        if (table[opcode].duse)
                   2205:            printf("\tULONG dstreg = %d;\n", (int)table[opcode].dreg);
                   2206: #endif
                   2207:        gen_opcode(opcode);
                   2208:         printf("}\n");
                   2209:     }
                   2210: 
                   2211:     fprintf (stderr, "%d illegals generated.\n", illg);
                   2212:     if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
                   2213: }
                   2214: 
                   2215: static void generate_table(void)
                   2216: {
                   2217:     int illg = 0;
                   2218:     long int opcode;
                   2219:     
                   2220:     mismatch = 0;
                   2221:     
                   2222:     printf("#include <stdlib.h>\n");
                   2223:     printf("#include \"config.h\"\n");
                   2224:     printf("#include \"amiga.h\"\n");
                   2225:     printf("#include \"options.h\"\n");
                   2226:     printf("#include \"memory.h\"\n");
                   2227:     printf("#include \"custom.h\"\n");
                   2228:     printf("#include \"newcpu.h\"\n");
                   2229:     printf("#include \"cputbl.h\"\n");
                   2230:     
                   2231:     printf("cpuop_func *cpufunctbl[65536] = {\n");
                   2232:     for(opcode=0; opcode < 65536; opcode++) {
                   2233:        if (table[opcode].mnemo == i_ILLG) {
                   2234:            printf("op_illg");
                   2235:            illg++;
                   2236:            goto loop_end;
                   2237:        }
                   2238:        if (table[opcode].generated) {
                   2239:            printf("op_%x", table[opcode].handler);
                   2240:            goto loop_end;
                   2241:        }
                   2242: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
                   2243:        handle_merges (opcode);
                   2244: #endif
                   2245:        printf("op_%lx", opcode);
                   2246:        
                   2247:        loop_end:
                   2248:        if (opcode < 65535) printf(",");
                   2249:        if ((opcode & 7) == 7) printf("\n");
                   2250:     }
                   2251:     printf("\n};\n");
                   2252:     fprintf (stderr, "%d illegals generated.\n", illg);
                   2253:     if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
                   2254: }
                   2255: 
                   2256: static void generate_header(void)
                   2257: {
                   2258:     int illg = 0;
                   2259:     long int opcode;
                   2260:     
                   2261:     mismatch = 0;
                   2262:     
                   2263:     printf("extern void op_illg(UWORD) REGPARAM;\n");
                   2264:     
                   2265:     for(opcode=0; opcode < 65536; opcode++) {
                   2266:        if (table[opcode].mnemo == i_ILLG) {
                   2267:            illg++;
                   2268:            continue;
                   2269:        }
                   2270:        if (table[opcode].generated) 
                   2271:            continue;
                   2272:            
                   2273: #ifndef HAVE_ONE_GIG_OF_MEMORY_TO_COMPILE_THIS
                   2274:        handle_merges (opcode);
                   2275: #endif
                   2276:        printf("extern cpuop_func op_%lx;\n", opcode);
                   2277:     }
                   2278:     
                   2279:     fprintf (stderr, "%d illegals generated.\n", illg);
                   2280:     if (mismatch) fprintf(stderr, "%d mismatches.\n", mismatch);
                   2281: }
                   2282: 
                   2283: int main(int argc, char **argv)
                   2284: {
                   2285:     long int range = -1;
                   2286:     char mode = 'n';
                   2287:     int i;
                   2288:     
                   2289:     if (argc == 2)
                   2290:        mode = *argv[1];
                   2291: 
                   2292:     if (argc == 3) {
                   2293:        range = atoi(argv[2]);
                   2294:        mode = *argv[1];
                   2295:     }
                   2296:     tablef = fopen("table68k","r");
                   2297:     if (tablef == NULL) {
                   2298:        fprintf(stderr, "table68k not found\n");
                   2299:        exit(1);
                   2300:     }
                   2301:     table = (struct instr *) malloc (sizeof(struct instr) * 65536);
                   2302:     for(i = 0; i < 65536; i++) {
                   2303:        table[i].mnemo = i_ILLG;
                   2304:     }
                   2305:     getnextch();
                   2306:     while (nextch != EOF) {
                   2307:        get_bits();
                   2308:        get_strs();
                   2309:        parse_bits();
                   2310:     }
                   2311:     switch(mode) {
                   2312:      case 'f':
                   2313:        generate_func(range * 0x1000, (range + 1) * 0x1000);
                   2314:        break;
                   2315:      case 'h':
                   2316:        generate_header();
                   2317:        break;
                   2318:      case 't':
                   2319:        generate_table();
                   2320:        break;
                   2321:      default:
                   2322:        myabort();
                   2323:     }
                   2324:     fclose(tablef);
                   2325:     free(table);
                   2326:     return 0;
                   2327: }

unix.superglobalmegacorp.com

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