Annotation of uae/gencpu.c, revision 1.1.1.2

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: 
1.1.1.2 ! root       20: #include "sysconfig.h"
        !            21: #include "sysdeps.h"
1.1       root       22: #include <ctype.h>
                     23: 
                     24: #include "config.h"
1.1.1.2 ! root       25: #include "options.h"
        !            26: #include "readcpu.h"
1.1       root       27: 
1.1.1.2 ! root       28: #define BOOL_TYPE "int"
1.1       root       29: 
1.1.1.2 ! root       30: long int counts[65536];
1.1       root       31: 
1.1.1.2 ! root       32: static int isspecific(int opcode)
1.1       root       33: {
1.1.1.2 ! root       34:     return counts[opcode]>5;
1.1       root       35: }
                     36: 
1.1.1.2 ! root       37: static void read_counts(void)
1.1       root       38: {
1.1.1.2 ! root       39:     FILE *file;
        !            40:     unsigned long opcode,count, total;
        !            41:     int trapcount=0;
        !            42:     int trap=0;
        !            43:     memset(counts, 0, sizeof counts);
1.1       root       44: 
1.1.1.2 ! root       45:     file=fopen("insncount","r");
        !            46:     if(file)
        !            47:     {
        !            48:        fscanf(file,"Total: %d",&total);
        !            49:        while(fscanf(file,"%x: %d\n",&opcode,&count)==2)
        !            50:        {
        !            51:            counts[opcode]=10000.0*count/total;
        !            52:            if(isspecific(opcode))
1.1       root       53:            {
1.1.1.2 ! root       54:                trapcount+=count;
        !            55:                trap++;
1.1       root       56:            }
1.1.1.2 ! root       57:        }
1.1       root       58: #if 0
1.1.1.2 ! root       59:        fprintf(stderr,"trap %d function: %f%\n",trap,100.0*trapcount/total);
1.1       root       60: #endif
                     61:     }
                     62: }
                     63: 
1.1.1.2 ! root       64: 
1.1       root       65: static int n_braces = 0;
                     66: 
                     67: static void start_brace(void)
                     68: {
                     69:     n_braces++;
                     70:     printf("{");
                     71: }
                     72: 
                     73: static void close_brace(void)
                     74: {
                     75:     assert (n_braces > 0);
                     76:     n_braces--;
                     77:     printf("}");
                     78: }
                     79: 
                     80: static void finish_braces(void)
                     81: {
                     82:     while (n_braces > 0)
                     83:        close_brace();
                     84: }
                     85: 
                     86: static void pop_braces(int to)
                     87: {
                     88:     while (n_braces > to)
                     89:        close_brace();
                     90: }
                     91: 
1.1.1.2 ! root       92: static void genamode(amodes mode, char *reg, wordsizes size, char *name, int getv, int movem)
1.1       root       93: {
                     94:     start_brace ();
                     95:     switch(mode) {
                     96:      case Dreg:
                     97:        if (movem)
                     98:            abort();
                     99:        if (getv)
                    100:            switch(size) {        
                    101:             case sz_byte:
                    102:                printf("\tBYTE %s = regs.d[%s];\n", name, reg);
                    103:                break;
                    104:             case sz_word:
                    105:                printf("\tWORD %s = regs.d[%s];\n", name, reg);
                    106:                break;
                    107:             case sz_long:
                    108:                printf("\tLONG %s = regs.d[%s];\n", name, reg);
                    109:                break;
1.1.1.2 ! root      110:             default: abort();
1.1       root      111:            }
                    112:        break;
                    113:      case Areg:
                    114:        if (movem)
                    115:            abort();
                    116:        if (getv)
                    117:            switch(size) {        
                    118:             case sz_word:
                    119:                printf("\tWORD %s = regs.a[%s];\n", name, reg);
                    120:                break;
                    121:             case sz_long:
                    122:                printf("\tLONG %s = regs.a[%s];\n", name, reg);
                    123:                break;
1.1.1.2 ! root      124:             default: abort();
1.1       root      125:            }
                    126:        break;
                    127:      case Aind:
                    128:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    129:        if (getv)
                    130:            switch(size) {        
                    131:             case sz_byte:
                    132:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    133:                break;
                    134:             case sz_word:
                    135:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    136:                break;
                    137:             case sz_long:
                    138:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    139:                break;
1.1.1.2 ! root      140:             default: abort();
1.1       root      141:            }
                    142:        break;
                    143:      case Aipi:
                    144:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    145:        switch(size) {
                    146:         case sz_byte:      
                    147:            if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    148:            if (!movem) {
                    149:                start_brace();
1.1.1.2 ! root      150:                printf("\tregs.a[%s] += areg_byteinc[%s];\n", reg, reg);
1.1       root      151:            }
                    152:            break;
                    153:         case sz_word:
                    154:            if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
                    155:            if (!movem) {
                    156:                start_brace();
                    157:                printf("\tregs.a[%s] += 2;\n", reg);
                    158:            }
                    159:            break;
                    160:         case sz_long:
                    161:            if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
                    162:            if (!movem) {
                    163:                start_brace();
                    164:                printf("\tregs.a[%s] += 4;\n", reg);
                    165:            }
                    166:            break;
1.1.1.2 ! root      167:         default: abort();
1.1       root      168:        }
                    169:        break;
                    170:      case Apdi:
                    171:        switch(size) {    
                    172:         case sz_byte:
1.1.1.2 ! root      173:            if (!movem) printf("\tregs.a[%s] -= areg_byteinc[%s];\n", reg, reg);
1.1       root      174:            start_brace();
                    175:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    176:            if (getv) printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    177:            break;
                    178:         case sz_word:
                    179:            if (!movem) printf("\tregs.a[%s] -= 2;\n", reg);
                    180:            start_brace();
                    181:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    182:            if (getv) printf("\tWORD %s = get_word(%sa);\n", name, name);
                    183:            break;
                    184:         case sz_long:
                    185:            if (!movem) printf("\tregs.a[%s] -= 4;\n", reg);
                    186:            start_brace();
                    187:            printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
                    188:            if (getv) printf("\tLONG %s = get_long(%sa);\n", name, name);
                    189:            break;
1.1.1.2 ! root      190:         default: abort();
1.1       root      191:        }
                    192:        break;
                    193:      case Ad16:
                    194:        printf("\tCPTR %sa = regs.a[%s] + (LONG)(WORD)nextiword();\n", name, reg);
                    195:        if (getv) 
                    196:            switch(size) {        
                    197:             case sz_byte:
                    198:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    199:                break;
                    200:             case sz_word:
                    201:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    202:                break;
                    203:             case sz_long:
                    204:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    205:                break;
1.1.1.2 ! root      206:             default: abort();
1.1       root      207:            }
                    208:        break;
                    209:      case Ad8r:
                    210:        printf("\tCPTR %sa = regs.a[%s];\n", name, reg);
1.1.1.2 ! root      211: #if 0
1.1       root      212:        printf("\tUWORD %sdp = nextiword();\n", name);
                    213:        printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
                    214:        start_brace();
                    215:        printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
                    216:        printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
                    217:        printf("\t%sa += %sdpr;\n", name, name);
1.1.1.2 ! root      218: #endif
        !           219:        printf("\t%sa = get_disp_ea (%sa, nextiword());\n", name, name);
1.1       root      220:        if (getv) {
                    221:            start_brace();
                    222:            switch(size) {        
                    223:             case sz_byte:
                    224:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    225:                break;
                    226:             case sz_word:
                    227:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    228:                break;
                    229:             case sz_long:
                    230:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    231:                break;
1.1.1.2 ! root      232:             default: abort();
1.1       root      233:            }
                    234:        }
                    235:        break;
                    236:      case PC16:
                    237:        printf("\tCPTR %sa = m68k_getpc();\n", name);
                    238:        printf("\t%sa += (LONG)(WORD)nextiword();\n", name);
                    239:        if (getv) {
                    240:            start_brace();
                    241:            switch(size) {        
                    242:             case sz_byte:
                    243:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    244:                break;
                    245:             case sz_word:
                    246:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    247:                break;
                    248:             case sz_long:
                    249:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    250:                break;
1.1.1.2 ! root      251:             default: abort();
1.1       root      252:            }
                    253:        }
                    254:        break;
                    255:      case PC8r:
                    256:        printf("\tCPTR %sa = m68k_getpc();\n", name);
1.1.1.2 ! root      257: #if 0
1.1       root      258:        printf("\tUWORD %sdp = nextiword();\n", name);
                    259:        printf("\t%sa += (LONG)(BYTE)(%sdp & 0xFF);\n", name, name);
                    260:        start_brace();
                    261:        printf("\tULONG %sdpr = %sdp & 0x8000 ? regs.a[(%sdp & 0x7000) >> 12] : regs.d[(%sdp & 0x7000) >> 12];\n", name, name, name, name);
                    262:        printf("\tif (!(%sdp & 0x800)) %sdpr = (LONG)(WORD)%sdpr;\n", name, name, name);
                    263:        printf("\t%sa += %sdpr;\n", name, name);
1.1.1.2 ! root      264: #endif
        !           265:        printf("\t%sa = get_disp_ea (%sa, nextiword());\n", name, name);
1.1       root      266:        if (getv) {
                    267:            start_brace();
                    268:            switch(size) {        
                    269:             case sz_byte:
                    270:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    271:                break;
                    272:             case sz_word:
                    273:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    274:                break;
                    275:             case sz_long:
                    276:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    277:                break;
1.1.1.2 ! root      278:             default: abort();
1.1       root      279:            }
                    280:        }
                    281:        break;
                    282:      case absw:
                    283:        printf("\tCPTR %sa = (LONG)(WORD)nextiword();\n", name);
                    284:        if (getv) 
                    285:            switch(size) {        
                    286:             case sz_byte:
                    287:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    288:                break;
                    289:             case sz_word:
                    290:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    291:                break;
                    292:             case sz_long:
                    293:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    294:                break;
1.1.1.2 ! root      295:             default: abort();
1.1       root      296:            }
                    297:        break;
                    298:      case absl:
                    299:        printf("\tCPTR %sa = nextilong();\n", name);
                    300:        if (getv) 
                    301:            switch(size) {        
                    302:             case sz_byte:
                    303:                printf("\tBYTE %s = get_byte(%sa);\n", name, name);
                    304:                break;
                    305:             case sz_word:
                    306:                printf("\tWORD %s = get_word(%sa);\n", name, name);
                    307:                break;
                    308:             case sz_long:
                    309:                printf("\tLONG %s = get_long(%sa);\n", name, name);
                    310:                break;
1.1.1.2 ! root      311:             default: abort();
1.1       root      312:            }
                    313:        break;
                    314:      case imm:
                    315:        if (getv) 
                    316:            switch(size) {
                    317:             case sz_byte:
                    318:                printf("\tBYTE %s = nextiword();\n", name);
                    319:                break;
                    320:             case sz_word:
                    321:                printf("\tWORD %s = nextiword();\n", name);
                    322:                break;
                    323:             case sz_long:
                    324:                printf("\tLONG %s = nextilong();\n", name);
                    325:                break;
1.1.1.2 ! root      326:             default: abort();
1.1       root      327:            }
                    328:        break;
                    329:      case imm0:
1.1.1.2 ! root      330:        if (!getv) abort();
1.1       root      331:        printf("\tBYTE %s = nextiword();\n", name);
                    332:        break;
                    333:      case imm1:
1.1.1.2 ! root      334:        if (!getv) abort();
1.1       root      335:        printf("\tWORD %s = nextiword();\n", name);
                    336:        break;
                    337:      case imm2:
1.1.1.2 ! root      338:        if (!getv) abort();
1.1       root      339:         printf("\tLONG %s = nextilong();\n", name);
                    340:        break;
                    341:      case immi:
1.1.1.2 ! root      342:        if (!getv) abort();
1.1       root      343:        printf("\tULONG %s = %s;\n", name, reg);
                    344:        break;
                    345:      default: 
1.1.1.2 ! root      346:        abort();
1.1       root      347:     }
                    348: }
                    349: 
                    350: static void genastore(char *from, amodes mode, char *reg, wordsizes size, char *to)
                    351: {
                    352:     switch(mode) {
                    353:      case Dreg:
                    354:        switch(size) {    
                    355:         case sz_byte:
                    356:            printf("\tregs.d[%s] &= ~0xff; regs.d[%s] |= (%s) & 0xff;\n", reg, reg, from);
                    357:            break;
                    358:         case sz_word:
                    359:            printf("\tregs.d[%s] &= ~0xffff; regs.d[%s] |= (%s) & 0xffff;\n", reg, reg, from);
                    360:            break;
                    361:         case sz_long:
                    362:            printf("\tregs.d[%s] = (%s);\n", reg, from);
                    363:            break;
1.1.1.2 ! root      364:         default: abort();
1.1       root      365:        }
                    366:        break;
                    367:      case Areg:
                    368:        switch(size) {    
                    369:         case sz_word:
                    370:            printf("\tregs.a[%s] = (LONG)(WORD)(%s);\n", reg, from);
                    371:            break;
                    372:         case sz_long:
                    373:            printf("\tregs.a[%s] = (%s);\n", reg, from);
                    374:            break;
1.1.1.2 ! root      375:         default: abort();
1.1       root      376:        }
                    377:        break;
                    378:      case Aind:
                    379:      case Aipi:
                    380:      case Apdi:
                    381:      case Ad16:
                    382:      case Ad8r:
                    383:      case absw:
                    384:      case absl:
                    385:        switch(size) {
                    386:         case sz_byte:
                    387:            printf("\tput_byte(%sa,%s);\n", to, from);
                    388:            break;
                    389:         case sz_word:
                    390:            printf("\tput_word(%sa,%s);\n", to, from);
                    391:            break;
                    392:         case sz_long:
                    393:            printf("\tput_long(%sa,%s);\n", to, from);
                    394:            break;
1.1.1.2 ! root      395:         default: abort();
1.1       root      396:        }
                    397:        break;
                    398:      case PC16:
                    399:      case PC8r:
                    400:        switch(size) {
                    401:         case sz_byte:
                    402:            printf("\tput_byte(%sa,%s);\n", to, from);
                    403:            break;
1.1.1.2 ! root      404:         case sz_word:
        !           405:            if (CPU_LEVEL < 2)
        !           406:                abort();
        !           407:            printf("\tput_word(%sa,%s);\n", to, from);
        !           408:            break;
        !           409:         case sz_long:
        !           410:            if (CPU_LEVEL < 2)
        !           411:                abort();
        !           412:            printf("\tput_long(%sa,%s);\n", to, from);
        !           413:            break;
        !           414:         default: abort();
1.1       root      415:        }
                    416:        break;
                    417:      case imm:
                    418:      case imm0:
                    419:      case imm1:
                    420:      case imm2:
                    421:      case immi:
1.1.1.2 ! root      422:        abort();
1.1       root      423:        break;
                    424:      default: 
1.1.1.2 ! root      425:        abort();
1.1       root      426:     }
                    427: }
                    428: 
                    429: static void genmovemel(UWORD opcode)
                    430: {
                    431:     char getcode[100];
1.1.1.2 ! root      432:     int size = table68k[opcode].size == sz_long ? 4 : 2;
1.1       root      433:     
1.1.1.2 ! root      434:     if (table68k[opcode].size == sz_long) {    
1.1       root      435:        strcpy(getcode, "get_long(srca)");
                    436:     } else {       
                    437:        strcpy(getcode, "(LONG)(WORD)get_word(srca)");
                    438:     }
                    439:     
                    440:     printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
1.1.1.2 ! root      441:     genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 1);
1.1       root      442:     start_brace();
                    443:     printf("\tint i, bitcnt = 0;\n");
                    444:     printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
                    445:     
                    446:     printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.d[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
                    447:     printf("\tfor(i=0;i<8;i++) { if (mask & 1) { regs.a[i] = %s; srca += %d; } mask >>= 1; }\n", getcode, size);
                    448:     
1.1.1.2 ! root      449:     if (table68k[opcode].smode == Aipi)
1.1       root      450:        printf("\tregs.a[srcreg] = srca;\n");
                    451: }
                    452: 
                    453: static void genmovemle(UWORD opcode)
                    454: {
                    455:     char putcode[100], shiftcode[] = ">>";
1.1.1.2 ! root      456:     int size = table68k[opcode].size == sz_long ? 4 : 2;
1.1       root      457:     int mask = 1;
1.1.1.2 ! root      458:     if (table68k[opcode].size == sz_long) {
1.1       root      459:        strcpy(putcode, "put_long(srca,");
                    460:     } else {       
                    461:        strcpy(putcode, "put_word(srca,");
                    462:     }
                    463:     
                    464:     printf("\tUWORD mask = nextiword(), bitmask = mask;\n");
1.1.1.2 ! root      465:     genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 1);
1.1       root      466:     start_brace();
                    467:     printf("\tint i, bitcnt = 0;\n");
                    468:     printf("\tULONG rd[8], ra[8];\n");
                    469:     printf("\tfor(i=0;i<16;i++) { bitcnt += bitmask & 1; bitmask >>= 1; }\n");
                    470:     printf("\tfor(i=0;i<8;i++) { rd[i] = regs.d[i]; ra[i] = regs.a[i]; }\n");
1.1.1.2 ! root      471:     if (table68k[opcode].smode == Apdi) {
1.1       root      472:        printf("\tsrca -= %d*bitcnt;\n", size);
                    473:        printf("\tregs.a[srcreg] = srca;\n");
                    474:        strcpy(shiftcode, "<<");
                    475:        mask = 0x8000;
                    476:     }
                    477: 
                    478:     printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s rd[i]); srca += %d; } mask %s= 1; }\n", 
                    479:           mask, putcode, size, shiftcode);
                    480:     printf("\tfor(i=0;i<8;i++) { if (mask & %d) { %s ra[i]); srca += %d; } mask %s= 1; }\n",
                    481:           mask, putcode, size, shiftcode);    
                    482: }
                    483: 
                    484: typedef enum {
1.1.1.2 ! root      485:     flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn,
        !           486:     flag_av, flag_sv
1.1       root      487: } flagtypes;
                    488: 
1.1.1.2 ! root      489: static void genflags_normal(flagtypes type, wordsizes size, char *value, char *src, char *dst)
1.1       root      490: {
                    491:     char vstr[100],sstr[100],dstr[100];
                    492:     char usstr[100],udstr[100];
                    493:     char unsstr[100],undstr[100];
1.1.1.2 ! root      494: 
1.1       root      495:     switch(size) {         
                    496:      case sz_byte:
                    497:        strcpy(vstr, "((BYTE)(");
                    498:        strcpy(usstr, "((UBYTE)(");
                    499:        break;
                    500:      case sz_word:
                    501:        strcpy(vstr, "((WORD)(");
                    502:        strcpy(usstr, "((UWORD)(");
                    503:        break;
                    504:      case sz_long:
                    505:        strcpy(vstr, "((LONG)(");
                    506:        strcpy(usstr, "((ULONG)(");
                    507:        break;
                    508:      default:
1.1.1.2 ! root      509:        abort();
1.1       root      510:     }
                    511:     strcpy(unsstr, usstr); 
                    512: 
                    513:     strcpy(sstr, vstr);
                    514:     strcpy(dstr, vstr);
                    515:     strcat(vstr, value); strcat(vstr,"))");
                    516:     strcat(dstr, dst); strcat(dstr,"))");
                    517:     strcat(sstr, src); strcat(sstr,"))");
                    518:     
                    519:     strcpy(udstr, usstr);
                    520:     strcat(udstr, dst); strcat(udstr,"))");
                    521:     strcat(usstr, src); strcat(usstr,"))");
                    522:     
                    523:     strcpy(undstr, unsstr);
                    524:     strcat(unsstr, "-");
                    525:     strcat(undstr, "~");
                    526:     strcat(undstr, dst); strcat(undstr,"))");
                    527:     strcat(unsstr, src); strcat(unsstr,"))");
1.1.1.2 ! root      528: 
        !           529:     switch (type) {
1.1       root      530:      case flag_logical:
                    531:      case flag_zn:
1.1.1.2 ! root      532:      case flag_av:
        !           533:      case flag_sv:
        !           534:      case flag_addx:
        !           535:      case flag_subx:
1.1       root      536:        break;
1.1.1.2 ! root      537:     
1.1       root      538:      case flag_add:
                    539:        start_brace();
1.1.1.2 ! root      540:        printf("ULONG %s = %s + %s;\n", value, dstr, sstr);
1.1       root      541:        break;
                    542:      case flag_sub:
1.1.1.2 ! root      543:      case flag_cmp:
1.1       root      544:        start_brace();
1.1.1.2 ! root      545:        printf("ULONG %s = %s - %s;\n", value, dstr, sstr);
1.1       root      546:        break;
1.1.1.2 ! root      547:     }
        !           548: 
        !           549: 
        !           550:     switch (type) {
        !           551:      case flag_logical:
        !           552:      case flag_zn:
1.1       root      553:        break;
1.1.1.2 ! root      554:        
        !           555:      case flag_add:
        !           556:      case flag_sub:
        !           557:      case flag_addx:
1.1       root      558:      case flag_subx:
                    559:      case flag_cmp:
1.1.1.2 ! root      560:      case flag_av:
        !           561:      case flag_sv:
1.1       root      562:        start_brace();
1.1.1.2 ! root      563:        printf("\t"BOOL_TYPE" flgs = %s < 0;\n", sstr);
        !           564:        printf("\t"BOOL_TYPE" flgo = %s < 0;\n", dstr);
        !           565:        printf("\t"BOOL_TYPE" flgn = %s < 0;\n", vstr);
1.1       root      566:        break;
                    567:     }
1.1.1.2 ! root      568:     
1.1       root      569:     switch(type) {
                    570:      case flag_logical:
1.1.1.2 ! root      571:        printf("\tVFLG = CFLG = 0;\n");
        !           572:        printf("\tZFLG = %s == 0;\n", vstr);
        !           573:        printf("\tNFLG = %s < 0;\n", vstr);
        !           574:        break;
        !           575:      case flag_av:
        !           576:        printf("\tVFLG = (flgs == flgo) && (flgn != flgo);\n");
        !           577:        break;
        !           578:      case flag_sv:
        !           579:        printf("\tVFLG = (flgs != flgo) && (flgn != flgo);\n");
        !           580:        break;
        !           581:      case flag_zn:
        !           582:        printf("\tif (%s != 0) ZFLG = 0;\n", vstr);
        !           583:        printf("\tNFLG = %s < 0;\n", vstr);
1.1       root      584:        break;
                    585:      case flag_add:
1.1.1.2 ! root      586:        printf("\tZFLG = %s == 0;\n", vstr);
        !           587:        printf("\tVFLG = (flgs == flgo) && (flgn != flgo);\n");
        !           588:        printf("\tCFLG = regs.x = %s < %s;\n", undstr, usstr);
        !           589:        printf("\tNFLG = flgn != 0;\n");
1.1       root      590:        break;
                    591:      case flag_sub:
1.1.1.2 ! root      592:        printf("\tZFLG = %s == 0;\n", vstr);
        !           593:        printf("\tVFLG = (flgs != flgo) && (flgn != flgo);\n");
        !           594:        printf("\tCFLG = regs.x = %s > %s;\n", usstr, udstr);
        !           595:        printf("\tNFLG = flgn != 0;\n");
1.1       root      596:        break;
                    597:      case flag_addx:
1.1.1.2 ! root      598:        printf("\tVFLG = (flgs && flgo && !flgn) || (!flgs && !flgo && flgn);\n");
        !           599:        printf("\tregs.x = CFLG = (flgs && flgo) || (!flgn && (flgo || flgs));\n");
1.1       root      600:        break;
                    601:      case flag_subx:
1.1.1.2 ! root      602:        printf("\tVFLG = (!flgs && flgo && !flgn) || (flgs && !flgo && flgn);\n");
        !           603:        printf("\tregs.x = CFLG = (flgs && !flgo) || (flgn && (!flgo || flgs));\n");
1.1       root      604:        break;
                    605:      case flag_cmp:
1.1.1.2 ! root      606:        printf("\tZFLG = %s == 0;\n", vstr);
        !           607:        printf("\tVFLG = (flgs != flgo) && (flgn != flgo);\n");
        !           608:        printf("\tCFLG = %s > %s;\n", usstr, udstr);
        !           609:        printf("\tNFLG = flgn != 0;\n");
1.1       root      610:        break;
                    611:     }
                    612: }
                    613: 
1.1.1.2 ! root      614: static void genflags(flagtypes type, wordsizes size, char *value, char *src, char *dst)
        !           615: {
        !           616: #ifdef INTEL_FLAG_OPT
        !           617:     
        !           618:     switch (type) {
        !           619:      case flag_logical:
        !           620:      case flag_av:
        !           621:      case flag_sv:
        !           622:      case flag_zn:
        !           623:      case flag_addx:
        !           624:      case flag_subx:
        !           625:        break;
        !           626: 
        !           627:      case flag_add:
        !           628:      case flag_sub:
        !           629:      case flag_cmp:
        !           630:        start_brace();
        !           631:        printf("\tULONG %s;\n", value);
        !           632:        break;
        !           633:     }
        !           634: 
        !           635:     switch(type) {
        !           636:      case flag_av:
        !           637:      case flag_sv:
        !           638:      case flag_zn:
        !           639:      case flag_addx:
        !           640:      case flag_subx:
        !           641:        break;
        !           642: 
        !           643:      case flag_logical:
        !           644:        if (strcmp(value, "0") == 0) {
        !           645:            /* GCC doesn't want to load the constant into a register. 
        !           646:             * intel_flag_lookup[64] is just the zero flag set. */
        !           647:            printf("\tregflags = intel_flag_lookup[64];\n");
        !           648:        } else {
        !           649:            switch(size) {
        !           650:             case sz_byte:
        !           651:                printf("\t__asm__(\"testb %%0,%%0; lahf; movzbl %%%%ah,%%%%eax; movl intel_flag_lookup(,%%%%eax,4),%%%%eax; movl %%%%eax,regflags\""
        !           652:                       ": : \"r\" (%s) : \"%%eax\", \"cc\");", value);
        !           653:                break;
        !           654:             case sz_word:
        !           655:                printf("\t__asm__(\"testw %%0,%%0; lahf; movzbl %%%%ah,%%%%eax; movl intel_flag_lookup(,%%%%eax,4),%%%%eax; movl %%%%eax,regflags\""
        !           656:                       ": : \"r\" (%s) : \"%%eax\", \"cc\");", value);
        !           657:                break;
        !           658:             case sz_long:
        !           659:                printf("\t__asm__(\"testl %%0,%%0; lahf; movzbl %%%%ah,%%%%eax; movl intel_flag_lookup(,%%%%eax,4),%%%%eax; movl %%%%eax,regflags\""
        !           660:                       ": : \"r\" (%s) : \"%%eax\", \"cc\");", value);
        !           661:                
        !           662:                break;
        !           663:             case sz_unknown:
        !           664:                abort();
        !           665:            }
        !           666:        }
        !           667:        return;
        !           668: 
        !           669:      case flag_add:
        !           670:        /* Of course it would be better to let GCC find a proper register to 
        !           671:         * compute newv in, but it does not seem to like reloading the 8 bit
        !           672:         * regs. */
        !           673:        switch (size) {
        !           674:         case sz_byte:
        !           675:            printf("\t__asm__(\"addb %%b3,%%b0; lahf; movzbl %%%%ah,%%%%eax;"
        !           676:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al; movb %%%%ah,%%1; movl %%%%eax,regflags \""
        !           677:                   ": \"=&q\" (%s), \"=m\" (regs.x) "
        !           678:                   ": \"0\" ((BYTE)(%s)), \"qm\" ((BYTE)(%s)) : \"cc\", \"%%eax\");",
        !           679:                   value, src, dst);
        !           680:            break;
        !           681:         case sz_word:
        !           682:            printf("\t__asm__(\"addw %%w3,%%w0; lahf; movzbl %%%%ah,%%%%eax;"
        !           683:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al; movb %%%%ah,%%1; movl %%%%eax,regflags \""
        !           684:                   ": \"=&r\" (%s), \"=m\" (regs.x) "
        !           685:                   ": \"0\" ((WORD)(%s)), \"rmi\" ((WORD)(%s)) : \"cc\", \"%%eax\");",
        !           686:                   value, src, dst);
        !           687:            break;
        !           688:         case sz_long:
        !           689:            printf("\t__asm__(\"addl %%3,%%0; lahf; movzbl %%%%ah,%%%%eax;"
        !           690:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al; movb %%%%ah,%%1; movl %%%%eax,regflags \""
        !           691:                   ": \"=&r\" (%s), \"=m\" (regs.x) "
        !           692:                   ": \"0\" ((LONG)(%s)), \"rmi\" ((LONG)(%s)) : \"cc\", \"%%eax\");",
        !           693:                   value, src, dst);
        !           694:            break;
        !           695:         case sz_unknown:
        !           696:            abort();
        !           697:        }
        !           698:        return;
        !           699: 
        !           700:      case flag_sub:
        !           701:        switch (size) {
        !           702:         case sz_byte:
        !           703:            printf("\t__asm__(\"subb %%b2,%%b0; lahf; movzbl %%%%ah,%%%%eax;"
        !           704:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al; movb %%%%ah,%%1; movl %%%%eax,regflags \""
        !           705:                   ": \"=&q\" (%s), \"=m\" (regs.x) "
        !           706:                   ": \"qmi\" ((BYTE)(%s)), \"0\" ((BYTE)(%s)) : \"cc\", \"%%eax\");",
        !           707:                   value, src, dst);
        !           708:            break;
        !           709:         case sz_word:
        !           710:            printf("\t__asm__(\"subw %%w2,%%w0; lahf; movzbl %%%%ah,%%%%eax;"
        !           711:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al; movb %%%%ah,%%1; movl %%%%eax,regflags \""
        !           712:                   ": \"=&r\" (%s), \"=m\" (regs.x) "
        !           713:                   ": \"rmi\" ((WORD)(%s)), \"0\" ((WORD)(%s)) : \"cc\", \"%%eax\");",
        !           714:                   value, src, dst);
        !           715:            break;
        !           716:         case sz_long:
        !           717:            printf("\t__asm__(\"subl %%2,%%0; lahf; movzbl %%%%ah,%%%%eax;"
        !           718:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al; movb %%%%ah,%%1; movl %%%%eax,regflags \""
        !           719:                   ": \"=&r\" (%s), \"=m\" (regs.x) "
        !           720:                   ": \"rmi\" ((LONG)(%s)), \"0\" ((LONG)(%s)) : \"cc\", \"%%eax\");",
        !           721:                   value, src, dst);
        !           722:            break;
        !           723:         case sz_unknown:
        !           724:            abort();
        !           725:        }
        !           726:        return;
        !           727: 
        !           728:      case flag_cmp:
        !           729:        switch (size) {
        !           730:         case sz_byte:
        !           731:            printf("\t__asm__(\"movb %%3,%%%%cl; subb %%2,%%%%cl; lahf; movzbl %%%%ah,%%%%eax;"
        !           732:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al \""
        !           733:                   ": \"=a\" (regflags.longflags), \"=&c\" (%s) "
        !           734:                   ": \"rm\" ((BYTE)(%s)), \"rmi\" ((BYTE)(%s)) : \"cc\");",
        !           735:                   value, src, dst);
        !           736:            break;
        !           737:         case sz_word:
        !           738:            printf("\t__asm__(\"movw %%3,%%%%cx; subw %%2,%%%%cx; lahf; movzbl %%%%ah,%%%%eax;"
        !           739:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al \""
        !           740:                   ": \"=a\" (regflags.longflags), \"=&c\" (%s) "
        !           741:                   ": \"rm\" ((WORD)(%s)), \"rmi\" ((WORD)(%s)) : \"cc\");",
        !           742:                   value, src, dst);
        !           743:            break;
        !           744:         case sz_long:
        !           745:            printf("\t__asm__(\"movl %%3,%%%%ecx; subl %%2,%%%%ecx; lahf; movzbl %%%%ah,%%%%eax;"
        !           746:                   " movl intel_flag_lookup(,%%%%eax,4),%%%%eax; seto %%%%al \""
        !           747:                   ": \"=a\" (regflags.longflags), \"=&c\" (%s) "
        !           748:                   ": \"rm\" ((LONG)(%s)), \"rmi\" ((LONG)(%s)) : \"cc\");",
        !           749:                   value, src, dst);
        !           750:            break;
        !           751:         case sz_unknown:
        !           752:            abort();
        !           753:        }
        !           754:        return;
        !           755:     }
        !           756: #endif
        !           757:     genflags_normal(type, size, value, src, dst);
        !           758: }
1.1       root      759: static void gen_opcode(unsigned long int opcode) 
                    760: {
                    761:     start_brace ();
1.1.1.2 ! root      762:     switch (table68k[opcode].plev) {
        !           763:      case 0: /* not priviledged */
        !           764:        break;
        !           765:      case 1: /* unpriviledged only on 68000 */
        !           766:        if (CPU_LEVEL == 0)
        !           767:            break;
        !           768:      case 2: /* priviledged */
        !           769:        printf("if (!regs.s) { regs.pc_p--; Exception(8); } else\n");
        !           770:        start_brace();
        !           771:        break;
        !           772:      case 3: /* priviledged if size == word */
        !           773:        if (table68k[opcode].size == sz_byte)
        !           774:            break;
        !           775:        printf("if (!regs.s) { regs.pc_p--; Exception(8); } else\n");
        !           776:        start_brace();
        !           777:        break;
        !           778:     }
        !           779:     switch(table68k[opcode].mnemo) {
1.1       root      780:      case i_OR:
1.1.1.2 ! root      781:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           782:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      783:        printf("\tsrc |= dst;\n");
1.1.1.2 ! root      784:        genflags(flag_logical, table68k[opcode].size, "src", "", "");
        !           785:        genastore("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      786:        break;
                    787:      case i_AND:
1.1.1.2 ! root      788:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           789:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      790:        printf("\tsrc &= dst;\n");
1.1.1.2 ! root      791:        genflags(flag_logical, table68k[opcode].size, "src", "", "");
        !           792:        genastore("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      793:        break;
                    794:      case i_EOR:
1.1.1.2 ! root      795:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           796:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      797:        printf("\tsrc ^= dst;\n");
1.1.1.2 ! root      798:        genflags(flag_logical, table68k[opcode].size, "src", "", "");
        !           799:        genastore("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      800:        break;
                    801:      case i_ORSR:
                    802:        printf("\tMakeSR();\n");
1.1.1.2 ! root      803:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           804:        if (table68k[opcode].size == sz_byte) {
1.1       root      805:            printf("\tsrc &= 0xFF;\n");
                    806:        }
                    807:        printf("\tregs.sr |= src;\n");
                    808:        printf("\tMakeFromSR();\n");
                    809:        break;
1.1.1.2 ! root      810:      case i_ANDSR:     
1.1       root      811:        printf("\tMakeSR();\n");
1.1.1.2 ! root      812:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           813:        if (table68k[opcode].size == sz_byte) {
1.1       root      814:            printf("\tsrc |= 0xFF00;\n");
                    815:        }
                    816:        printf("\tregs.sr &= src;\n");
                    817:        printf("\tMakeFromSR();\n");
                    818:        break;
                    819:      case i_EORSR:
                    820:        printf("\tMakeSR();\n");
1.1.1.2 ! root      821:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           822:        if (table68k[opcode].size == sz_byte) {
1.1       root      823:            printf("\tsrc &= 0xFF;\n");
                    824:        }
                    825:        printf("\tregs.sr ^= src;\n");
                    826:        printf("\tMakeFromSR();\n");
                    827:        break;
                    828:      case i_SUB: 
1.1.1.2 ! root      829:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           830:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      831:        start_brace ();
1.1.1.2 ! root      832:        genflags(flag_sub, table68k[opcode].size, "newv", "src", "dst");
        !           833:        genastore("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      834:        break;
                    835:      case i_SUBA:
1.1.1.2 ! root      836:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           837:        genamode(table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root      838:        start_brace ();
                    839:        printf("\tULONG newv = dst - src;\n");
1.1.1.2 ! root      840:        genastore("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root      841:        break;
                    842:      case i_SUBX:
1.1.1.2 ! root      843:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           844:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !           845:        start_brace ();
        !           846:        printf("\tULONG newv = dst - src - (regs.x ? 1 : 0);\n");
        !           847:        genflags(flag_subx, table68k[opcode].size, "newv", "src", "dst");
        !           848:        genflags(flag_zn, table68k[opcode].size, "newv", "", "");
        !           849:        genastore("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      850:        break;
                    851:      case i_SBCD:
                    852:        /* Let's hope this works... */
1.1.1.2 ! root      853:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           854:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      855:        start_brace ();
1.1.1.2 ! root      856:        printf("\tUWORD newv_lo = (dst & 0xF) - (src & 0xF) - regs.x;\n");
        !           857:        printf("\tUWORD newv_hi = (dst & 0xF0) - (src & 0xF0);\n");
        !           858:        printf("\tUWORD newv;\n");
        !           859:        printf("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n");
        !           860:        printf("\tnewv = newv_hi + (newv_lo & 0xF);");
        !           861:        printf("\tCFLG = regs.x = (newv_hi & 0x1F0) > 0x90;\n");
        !           862:        printf("\tif (CFLG) newv -= 0x60;\n");
        !           863:        genflags(flag_zn, table68k[opcode].size, "newv", "", "");       
        !           864:        genflags(flag_sv, table68k[opcode].size, "newv", "src", "dst");         
        !           865:        genastore("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      866:        break;
                    867:      case i_ADD:
1.1.1.2 ! root      868:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           869:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      870:        start_brace ();
1.1.1.2 ! root      871:        genflags(flag_add, table68k[opcode].size, "newv", "src", "dst");
        !           872:        genastore("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      873:        break;
                    874:      case i_ADDA: 
1.1.1.2 ! root      875:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           876:        genamode(table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root      877:        start_brace ();
                    878:        printf("\tULONG newv = dst + src;\n");
1.1.1.2 ! root      879:        genastore("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root      880:        break;
                    881:      case i_ADDX:
1.1.1.2 ! root      882:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           883:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !           884:        start_brace ();
        !           885:        printf("\tULONG newv = dst + src + (regs.x ? 1 : 0);\n");
        !           886:        genflags(flag_addx, table68k[opcode].size, "newv", "src", "dst");
        !           887:        genflags(flag_zn, table68k[opcode].size, "newv", "", "");
        !           888:        genastore("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      889:        break;
                    890:      case i_ABCD:
1.1.1.2 ! root      891:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           892:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      893:        start_brace ();
1.1.1.2 ! root      894:        printf("\tUWORD newv_lo = (src & 0xF) + (dst & 0xF) + regs.x;\n");
        !           895:        printf("\tUWORD newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
        !           896:        printf("\tUWORD newv;\n");
        !           897:        printf("\tif (newv_lo > 9) { newv_lo +=6; }\n");
        !           898:        printf("\tnewv = newv_hi + newv_lo;");
        !           899:        printf("\tCFLG = regs.x = (newv & 0x1F0) > 0x90;\n");
        !           900:        printf("\tif (CFLG) newv += 0x60;\n");
        !           901:        genflags(flag_zn, table68k[opcode].size, "newv", "", "");
        !           902:        genflags(flag_sv, table68k[opcode].size, "newv", "src", "dst"); 
        !           903:        genastore("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      904:        break;
                    905:      case i_NEG:
1.1.1.2 ! root      906:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root      907:        start_brace ();
1.1.1.2 ! root      908:        genflags(flag_sub, table68k[opcode].size, "dst", "src", "0");
        !           909:        genastore("dst",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root      910:        break;
                    911:      case i_NEGX:
1.1.1.2 ! root      912:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root      913:        start_brace ();
1.1.1.2 ! root      914:        printf("\tsrc += regs.x;\n");
        !           915:        genflags(flag_sub, table68k[opcode].size, "dst", "src", "0");
        !           916:        genastore("dst",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root      917:        break;
                    918:      case i_NBCD: 
1.1.1.2 ! root      919:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root      920:        start_brace ();
1.1.1.2 ! root      921:        printf("\tUWORD newv_lo = - (src & 0xF) - regs.x;\n");
        !           922:        printf("\tUWORD newv_hi = - (src & 0xF0);\n");
        !           923:        printf("\tUWORD newv;\n");
        !           924:        printf("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n");
        !           925:        printf("\tnewv = newv_hi + (newv_lo & 0xF);");
        !           926:        printf("\tCFLG = regs.x = (newv_hi & 0x1F0) > 0x90;\n");
        !           927:        printf("\tif (CFLG) newv -= 0x60;\n");
        !           928:        printf("\tif (newv != 0) ZFLG = 0;\n");
        !           929:        genastore("newv", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root      930:        break;
                    931:      case i_CLR: 
1.1.1.2 ! root      932:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
        !           933:        genflags(flag_logical, table68k[opcode].size, "0", "", "");
        !           934:        genastore("0",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root      935:        break;
                    936:      case i_NOT: 
1.1.1.2 ! root      937:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root      938:        start_brace ();
                    939:        printf("\tULONG dst = ~src;\n");
1.1.1.2 ! root      940:        genflags(flag_logical, table68k[opcode].size, "dst", "", "");
        !           941:        genastore("dst",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root      942:        break;
                    943:      case i_TST:
1.1.1.2 ! root      944:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           945:        genflags(flag_logical, table68k[opcode].size, "src", "", "");
1.1       root      946:        break;
                    947:      case i_BTST:
1.1.1.2 ! root      948:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           949:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !           950:        if (table68k[opcode].size == sz_byte)
1.1       root      951:            printf("\tsrc &= 7;\n");
                    952:        else
                    953:            printf("\tsrc &= 31;\n");
1.1.1.2 ! root      954:        printf("\tZFLG = !(dst & (1 << src));\n");
1.1       root      955:        break;
                    956:      case i_BCHG:
1.1.1.2 ! root      957:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           958:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !           959:        if (table68k[opcode].size == sz_byte)
1.1       root      960:            printf("\tsrc &= 7;\n");
                    961:        else
                    962:            printf("\tsrc &= 31;\n");
1.1.1.2 ! root      963:        printf("\tZFLG = !(dst & (1 << src));\n");
1.1       root      964:        printf("\tdst ^= (1 << src);\n");
1.1.1.2 ! root      965:        genastore("dst", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      966:        break;
                    967:      case i_BCLR:
1.1.1.2 ! root      968:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           969:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !           970:        if (table68k[opcode].size == sz_byte)
1.1       root      971:            printf("\tsrc &= 7;\n");
                    972:        else
                    973:            printf("\tsrc &= 31;\n");
1.1.1.2 ! root      974:        printf("\tZFLG = !(dst & (1 << src));\n");
1.1       root      975:        printf("\tdst &= ~(1 << src);\n");
1.1.1.2 ! root      976:        genastore("dst", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      977:        break;
                    978:      case i_BSET:
1.1.1.2 ! root      979:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           980:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !           981:        if (table68k[opcode].size == sz_byte)
1.1       root      982:            printf("\tsrc &= 7;\n");
                    983:        else
                    984:            printf("\tsrc &= 31;\n");
1.1.1.2 ! root      985:        printf("\tZFLG = !(dst & (1 << src));\n");
1.1       root      986:        printf("\tdst |= (1 << src);\n");
1.1.1.2 ! root      987:        genastore("dst", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      988:        break;
                    989:      case i_CMPM:
                    990:      case i_CMP:
1.1.1.2 ! root      991:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           992:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root      993:        start_brace ();
1.1.1.2 ! root      994:        genflags(flag_cmp, table68k[opcode].size, "newv", "src", "dst");
1.1       root      995:        break;
                    996:      case i_CMPA: 
1.1.1.2 ! root      997:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !           998:        genamode(table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root      999:        start_brace ();
                   1000:        genflags(flag_cmp, sz_long, "newv", "src", "dst");
                   1001:        break;
1.1.1.2 ! root     1002:        /* The next two are coded a little unconventional, but they are doing
        !          1003:         * weird things... */
        !          1004:      case i_MVPRM:
        !          1005:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1006:        printf("\tCPTR memp = regs.a[dstreg] + nextiword();\n");
        !          1007:        if (table68k[opcode].size == sz_word) {
        !          1008:            printf("\tput_byte(memp, src >> 8); put_byte(memp + 2, src);\n");
        !          1009:        } else {
        !          1010:            printf("\tput_byte(memp, src >> 24); put_byte(memp + 2, src >> 16);\n");
        !          1011:            printf("\tput_byte(memp + 4, src >> 8); put_byte(memp + 6, src);\n");
        !          1012:        }
        !          1013:        break;
        !          1014:      case i_MVPMR: 
        !          1015:        printf("\tCPTR memp = regs.a[srcreg] + nextiword();\n");
        !          1016:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 0, 0);
        !          1017:        if (table68k[opcode].size == sz_word) {
        !          1018:            printf("\tUWORD val = (get_byte(memp) << 8) + get_byte(memp + 2);\n");
        !          1019:        } else {
        !          1020:            printf("\tULONG val = (get_byte(memp) << 24) + (get_byte(memp + 2) << 16)\n");
        !          1021:            printf("              + (get_byte(memp + 4) << 8) + get_byte(memp + 6);\n");
        !          1022:        }
        !          1023:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1024:        break;
                   1025:      case i_MOVE:
1.1.1.2 ! root     1026:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1027:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 0, 0);
        !          1028:        genflags(flag_logical, table68k[opcode].size, "src", "", "");
        !          1029:        genastore("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1030:        break;
                   1031:      case i_MOVEA:
1.1.1.2 ! root     1032:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1033:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 0, 0);
        !          1034:        genastore("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1035:        break;
                   1036:      case i_MVSR2: 
1.1.1.2 ! root     1037:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
1.1       root     1038:        printf("\tMakeSR();\n");
1.1.1.2 ! root     1039:        genastore("regs.sr", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1040:        break;
                   1041:      case i_MV2SR:
1.1.1.2 ! root     1042:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1043:        if (table68k[opcode].size == sz_byte)
1.1       root     1044:            printf("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
                   1045:        else {              
                   1046:            printf("\tregs.sr = src;\n");
                   1047:        }
                   1048:        printf("\tMakeFromSR();\n");
                   1049:        break;
                   1050:      case i_SWAP: 
1.1.1.2 ! root     1051:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1052:        start_brace ();
                   1053:        printf("\tULONG dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
1.1.1.2 ! root     1054:        genflags(flag_logical, table68k[opcode].size, "dst", "", "");
        !          1055:        genastore("dst",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1056:        break;
                   1057:      case i_EXG:
1.1.1.2 ! root     1058:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1059:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !          1060:        genastore("dst",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
        !          1061:        genastore("src",table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1062:        break;
                   1063:      case i_EXT:
1.1.1.2 ! root     1064:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1065:        start_brace ();
1.1.1.2 ! root     1066:        switch(table68k[opcode].size) {
1.1       root     1067:         case sz_word: printf("\tULONG dst = (LONG)(BYTE)src;\n"); break;
                   1068:         case sz_long: printf("\tULONG dst = (LONG)(WORD)src;\n"); break;
1.1.1.2 ! root     1069:         default: abort();
1.1       root     1070:        }
1.1.1.2 ! root     1071:        genflags(flag_logical, table68k[opcode].size, "dst", "", "");
        !          1072:        genastore("dst",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1073:        break;
                   1074:      case i_MVMEL:
                   1075:        genmovemel(opcode);
                   1076:        break;
                   1077:      case i_MVMLE:
                   1078:        genmovemle(opcode);
                   1079:        break;
                   1080:      case i_TRAP:
1.1.1.2 ! root     1081:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1082:        printf("\tException(src+32);\n");
                   1083:        break;
                   1084:      case i_MVR2USP:
1.1.1.2 ! root     1085:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1086:        printf("\tregs.usp = src;\n");
                   1087:        break;
                   1088:      case i_MVUSP2R: 
1.1.1.2 ! root     1089:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
        !          1090:        genastore("regs.usp", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1091:        break;
                   1092:      case i_RESET:
                   1093:        printf("\tcustomreset();\n");
                   1094:        break;
                   1095:      case i_NOP:
                   1096:        break;
                   1097:      case i_STOP:
1.1.1.2 ! root     1098:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1099:        printf("\tregs.sr = src;\n");
                   1100:        printf("\tMakeFromSR();\n");
                   1101:        printf("\tm68k_setstopped(1);\n");
                   1102:        break;
                   1103:      case i_RTE:
1.1.1.2 ! root     1104:        genamode(Aipi, "7", sz_word, "sr", 1, 0);
        !          1105:        genamode(Aipi, "7", sz_long, "pc", 1, 0);
        !          1106:        if (CPU_LEVEL > 0) {
        !          1107:            genamode(Aipi, "7", sz_word, "format", 1, 0);
        !          1108:        }
1.1       root     1109:        printf("\tregs.sr = sr; m68k_setpc(pc);\n");
1.1.1.2 ! root     1110:        if (CPU_LEVEL > 0) {
        !          1111:            printf("\tif ((format & 0xF000) == 0x8000) regs.a[7] += 50;\n");
        !          1112:        }
1.1       root     1113:        printf("\tMakeFromSR();\n");
                   1114:        break;
                   1115:      case i_RTD:
                   1116:        break;
                   1117:      case i_LINK:
1.1.1.2 ! root     1118:        genamode(Apdi, "7", sz_long, "old", 0, 0);
        !          1119:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1120:        genastore("src", Apdi, "7", sz_long, "old");
1.1.1.2 ! root     1121:        genastore("regs.a[7]", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
        !          1122:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "offs", 1, 0);
1.1       root     1123:        printf("\tregs.a[7] += offs;\n");
                   1124:        break;
                   1125:      case i_UNLK:
1.1.1.2 ! root     1126:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1127:        printf("\tregs.a[7] = src;\n");
1.1.1.2 ! root     1128:        genamode(Aipi, "7", sz_long, "old", 1, 0);
        !          1129:        genastore("old", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1130:        break;
                   1131:      case i_RTS:
1.1.1.2 ! root     1132:        genamode(Aipi, "7", sz_long, "pc", 1, 0);
1.1       root     1133:        printf("\tm68k_setpc(pc);\n");
                   1134:        break;
                   1135:      case i_TRAPV:
1.1.1.2 ! root     1136:        printf("\tif(VFLG) Exception(7);\n");
1.1       root     1137:        break;
                   1138:      case i_RTR: 
                   1139:        printf("\tMakeSR();\n");
1.1.1.2 ! root     1140:        genamode(Aipi, "7", sz_word, "sr", 1, 0);
        !          1141:        genamode(Aipi, "7", sz_long, "pc", 1, 0);
1.1       root     1142:        printf("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
                   1143:        printf("\tregs.sr |= sr; m68k_setpc(pc);\n");
                   1144:        printf("\tMakeFromSR();\n");
                   1145:        break;
                   1146:      case i_JSR:
1.1.1.2 ! root     1147:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
        !          1148:        genamode(Apdi, "7", sz_long, "sp", 0, 0);
1.1       root     1149:        genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
                   1150:        printf("\tm68k_setpc(srca);\n");
                   1151:        break;
                   1152:      case i_JMP: 
1.1.1.2 ! root     1153:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
1.1       root     1154:        printf("\tm68k_setpc(srca);\n");
                   1155:        break;
                   1156:      case i_BSR:
                   1157:        printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
1.1.1.2 ! root     1158:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1159:        genamode(Apdi, "7", sz_long, "sp", 0, 0);
1.1       root     1160:        genastore("m68k_getpc()", Apdi, "7", sz_long, "sp");
                   1161:        printf("\tregs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n");
                   1162:        break;
                   1163:      case i_Bcc:
                   1164:        printf("\tchar *oldpcp = (char *)regs.pc_p;\n");
1.1.1.2 ! root     1165:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1166:        printf("\tif (cctrue(%d)) regs.pc_p = (UWORD *)(oldpcp + (LONG)src);\n", table68k[opcode].cc);
1.1       root     1167:        break;
                   1168:      case i_LEA:
1.1.1.2 ! root     1169:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
        !          1170:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 0, 0);
        !          1171:        genastore("srca", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1172:        break;
                   1173:      case i_PEA:
1.1.1.2 ! root     1174:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
        !          1175:        genamode(Apdi, "7", sz_long, "dst", 0, 0);
1.1       root     1176:        genastore("srca", Apdi, "7", sz_long, "dst");
                   1177:        break;
                   1178:      case i_DBcc:
1.1.1.2 ! root     1179:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1180:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "offs", 1, 0);
        !          1181:        printf("\tif (!cctrue(%d)) {\n", table68k[opcode].cc);
1.1       root     1182:        printf("\tif (src--) regs.pc_p = (UWORD *)((char *)regs.pc_p + (LONG)offs - 2);\n");
1.1.1.2 ! root     1183:        genastore("src", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1184:        printf("\t}\n");
                   1185:        break;
                   1186:      case i_Scc: 
1.1.1.2 ! root     1187:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
1.1       root     1188:        start_brace ();
1.1.1.2 ! root     1189:        printf("\tint val = cctrue(%d) ? 0xff : 0;\n", table68k[opcode].cc);
        !          1190:        genastore("val",table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1191:        break;
                   1192:      case i_DIVU:
1.1.1.2 ! root     1193:        genamode(table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
        !          1194:        genamode(table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root     1195:        printf("\tif(src != 0){\n");
                   1196:        printf("\tULONG newv = (ULONG)dst / (UWORD)src;\n");
                   1197:        printf("\tULONG rem = (ULONG)dst %% (UWORD)src;\n");
                   1198:        /* The N flag appears to be set each time there is an overflow.
                   1199:         * Weird. */
1.1.1.2 ! root     1200:        printf("\tif (newv > 0xffff) { VFLG = NFLG = 1; } else\n\t{\n");
1.1       root     1201:        genflags(flag_logical, sz_word, "newv", "", "");
                   1202:        printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
1.1.1.2 ! root     1203:        genastore("newv",table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root     1204:        printf("\t}\n");
                   1205:        printf("\t}\n");
                   1206:        break;
                   1207:      case i_DIVS: 
1.1.1.2 ! root     1208:        genamode(table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
        !          1209:        genamode(table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root     1210:        printf("\tif(src != 0){\n");
                   1211:        printf("\tLONG newv = (LONG)dst / (WORD)src;\n");
                   1212:        printf("\tUWORD rem = (LONG)dst %% (WORD)src;\n");
1.1.1.2 ! root     1213:        printf("\tif ((newv & 0xffff0000) && (newv & 0xffff0000) != 0xffff0000) { VFLG = NFLG = 1; } else\n\t{\n");
1.1       root     1214:        printf("\tif (((WORD)rem < 0) != ((LONG)dst < 0)) rem = -rem;\n");
                   1215:        genflags(flag_logical, sz_word, "newv", "", "");
                   1216:        printf("\tnewv = (newv & 0xffff) | ((ULONG)rem << 16);\n");
1.1.1.2 ! root     1217:        genastore("newv",table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root     1218:        printf("\t}\n");
                   1219:        printf("\t}\n");
                   1220:        break;
                   1221:      case i_MULU: 
1.1.1.2 ! root     1222:        genamode(table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
        !          1223:        genamode(table68k[opcode].dmode, "dstreg", sz_word, "dst", 1, 0);
1.1       root     1224:        start_brace ();
                   1225:        printf("\tULONG newv = (ULONG)(UWORD)dst * (ULONG)(UWORD)src;\n");
                   1226:        genflags(flag_logical, sz_long, "newv", "", "");
1.1.1.2 ! root     1227:        genastore("newv",table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root     1228: #ifdef WANT_SLOW_MULTIPLY
                   1229:        printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
                   1230: #endif
                   1231:        break;
                   1232:      case i_MULS:
1.1.1.2 ! root     1233:        genamode(table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
        !          1234:        genamode(table68k[opcode].dmode, "dstreg", sz_word, "dst", 1, 0);
1.1       root     1235:        start_brace ();
                   1236:        printf("\tULONG newv = (LONG)(WORD)dst * (LONG)(WORD)src;\n");
                   1237:        genflags(flag_logical, sz_long, "newv", "", "");
1.1.1.2 ! root     1238:        genastore("newv",table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root     1239: #ifdef WANT_SLOW_MULTIPLY
                   1240:        printf("\tspecialflags |= SPCFLAG_EXTRA_CYCLES;\n");
                   1241: #endif
                   1242:        break;
1.1.1.2 ! root     1243:      case i_CHK:
        !          1244:        genamode(table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
        !          1245:        genamode(table68k[opcode].dmode, "dstreg", sz_word, "dst", 1, 0);
        !          1246:        printf("\tif ((WORD)dst < 0) { NFLG=1; Exception(6); }\n");
        !          1247:        printf("\telse if ((WORD)dst > (WORD)src) { NFLG=0; Exception(6); }\n");
        !          1248:        break;
        !          1249:        
1.1       root     1250:      case i_ASR: 
1.1.1.2 ! root     1251:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1252:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1253:        start_brace ();
1.1.1.2 ! root     1254:        switch(table68k[opcode].size) {
1.1       root     1255:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1256:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1257:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1258:         default: abort();
1.1       root     1259:        }
1.1.1.2 ! root     1260:        switch(table68k[opcode].size) {
1.1       root     1261:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1262:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1263:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1264:         default: abort();
1.1       root     1265:        }
                   1266:        printf("\tULONG sign = cmask & val;\n");
1.1.1.2 ! root     1267:        printf("\tcnt &= 63;\n");
        !          1268:        printf("\tVFLG = 0;\n");
        !          1269:        printf("\tif (!cnt) { CFLG = 0; } else {");
1.1       root     1270:        printf("\tfor(;cnt;--cnt){\n");
1.1.1.2 ! root     1271:        printf("\tCFLG=regs.x=val&1; val = ((ULONG)val >> 1) | sign;\n");
        !          1272:        printf("\t}}\n\tNFLG = sign != 0;\n");
        !          1273:        printf("\tZFLG = val == 0;\n");
        !          1274:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1275:        break;
                   1276:      case i_ASL:
1.1.1.2 ! root     1277:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1278:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1279:        start_brace ();
1.1.1.2 ! root     1280:        switch(table68k[opcode].size) {
1.1       root     1281:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1282:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1283:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1284:         default: abort();
1.1       root     1285:        }
1.1.1.2 ! root     1286:        switch(table68k[opcode].size) {
1.1       root     1287:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1288:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1289:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1290:         default: abort();
1.1       root     1291:        }
                   1292:        printf("\tULONG sign = cmask & val;\n");
1.1.1.2 ! root     1293:        printf("\tcnt &= 63;\n");
        !          1294:        printf("\tVFLG = 0;\n");
        !          1295:        printf("\tif (!cnt) { CFLG = 0; } else { ");
1.1       root     1296:        printf("\tfor(;cnt;--cnt){\n");
1.1.1.2 ! root     1297:        printf("\tCFLG=regs.x=(val&cmask)!=0; val <<= 1;\n");
        !          1298:        printf("\tif ((val&cmask)!=sign)VFLG=1;\n");
        !          1299:        printf("\t}}\n\tNFLG = (val&cmask) != 0;\n");
        !          1300:        printf("\tZFLG = val == 0;\n");
        !          1301:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1302:        break;
                   1303:      case i_LSR:
1.1.1.2 ! root     1304:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1305:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1306:        start_brace ();
1.1.1.2 ! root     1307:        switch(table68k[opcode].size) {
1.1       root     1308:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1309:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1310:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1311:         default: abort();
        !          1312:        }
        !          1313:        switch(table68k[opcode].size) {
        !          1314:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
        !          1315:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
        !          1316:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
        !          1317:         default: abort();
1.1       root     1318:        }
                   1319:        printf("\tcnt &= 63;\n");
1.1.1.2 ! root     1320:        printf("\tif (!cnt) { CFLG = 0; } else {");
1.1       root     1321:        printf("\tint carry = 0;\n");
                   1322:        printf("\tfor(;cnt;--cnt){\n");
                   1323:        printf("\tcarry=val&1; val >>= 1;\n");
                   1324:        printf("\t}\n");
1.1.1.2 ! root     1325:        printf("\tCFLG = regs.x = carry!=0;\n}\n");
        !          1326:        printf("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
        !          1327:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");    
1.1       root     1328:        break;
                   1329:      case i_LSL:
1.1.1.2 ! root     1330:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1331:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1332:        start_brace ();
1.1.1.2 ! root     1333:        switch(table68k[opcode].size) {
1.1       root     1334:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1335:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1336:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1337:         default: abort();
1.1       root     1338:        }
1.1.1.2 ! root     1339:        switch(table68k[opcode].size) {
1.1       root     1340:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1341:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1342:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1343:         default: abort();
1.1       root     1344:        }
1.1.1.2 ! root     1345:        printf("\tint carry = 0;\n");
        !          1346:        printf("\tcnt &= 63;\n");
        !          1347:        printf("\tif (!cnt) { CFLG = 0; } else {");
1.1       root     1348:        printf("\tfor(;cnt;--cnt){\n");
                   1349:        printf("\tcarry=val&cmask; val <<= 1;\n");
                   1350:        printf("\t}\n");
1.1.1.2 ! root     1351:        printf("\tCFLG = regs.x = carry!=0;\n}\n");
        !          1352:        printf("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
        !          1353:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1354:        break;
                   1355:      case i_ROL:
1.1.1.2 ! root     1356:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1357:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1358:        start_brace ();
1.1.1.2 ! root     1359:        switch(table68k[opcode].size) {
1.1       root     1360:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1361:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1362:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1363:         default: abort();
1.1       root     1364:        }
1.1.1.2 ! root     1365:        switch(table68k[opcode].size) {
1.1       root     1366:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1367:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1368:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1369:         default: abort();
1.1       root     1370:        }
1.1.1.2 ! root     1371:        printf("\tint carry = 0;\n");
        !          1372:        printf("\tcnt &= 63;\n");       
        !          1373:        printf("\tif (!cnt) { CFLG = 0; } else {");
1.1       root     1374:        printf("\tfor(;cnt;--cnt){\n");
                   1375:        printf("\tcarry=val&cmask; val <<= 1;\n");
                   1376:        printf("\tif(carry)  val |= 1;\n");
                   1377:        printf("\t}\n");
1.1.1.2 ! root     1378:        printf("\tCFLG = carry!=0;\n}\n");
        !          1379:        printf("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
        !          1380:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1381:        break;
                   1382:      case i_ROR:
1.1.1.2 ! root     1383:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1384:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1385:        start_brace ();
1.1.1.2 ! root     1386:        switch(table68k[opcode].size) {
1.1       root     1387:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1388:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1389:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1390:         default: abort();
1.1       root     1391:        }
1.1.1.2 ! root     1392:        switch(table68k[opcode].size) {
1.1       root     1393:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1394:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1395:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1396:         default: abort();
1.1       root     1397:        }
1.1.1.2 ! root     1398:        printf("\tint carry = 0;\n");   
        !          1399:        printf("\tcnt &= 63;\n");
        !          1400:        printf("\tif (!cnt) { CFLG = 0; } else {");
1.1       root     1401:        printf("\tfor(;cnt;--cnt){\n");
                   1402:        printf("\tcarry=val&1; val = (ULONG)val >> 1;\n");
                   1403:        printf("\tif(carry) val |= cmask;\n");
                   1404:        printf("\t}\n");
1.1.1.2 ! root     1405:        printf("\tCFLG = carry!=0;\n}\n");
        !          1406:        printf("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
        !          1407:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1408:        break;
                   1409:      case i_ROXL: 
1.1.1.2 ! root     1410:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1411:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1412:        start_brace ();
1.1.1.2 ! root     1413:        switch(table68k[opcode].size) {
1.1       root     1414:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1415:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1416:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1417:         default: abort();
1.1       root     1418:        }
1.1.1.2 ! root     1419:        switch(table68k[opcode].size) {
1.1       root     1420:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1421:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1422:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1423:         default: abort();
1.1       root     1424:        }
1.1.1.2 ! root     1425:        printf("\tint carry = 0;\n");
        !          1426:        printf("\tcnt &= 63;\n");
1.1       root     1427:        printf("\tfor(;cnt;--cnt){\n");
                   1428:        printf("\tcarry=val&cmask; val <<= 1;\n");
                   1429:        printf("\tif(regs.x) val |= 1;\n");    
                   1430:        printf("\tregs.x = carry != 0;\n");
                   1431:        printf("\t}\n");
1.1.1.2 ! root     1432:        printf("\tCFLG = regs.x;\n");
        !          1433:        printf("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
        !          1434:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1435:        break;
                   1436:      case i_ROXR:
1.1.1.2 ! root     1437:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
        !          1438:        genamode(table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1439:        start_brace ();
1.1.1.2 ! root     1440:        switch(table68k[opcode].size) {
1.1       root     1441:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1442:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1443:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1444:         default: abort();
1.1       root     1445:        }
1.1.1.2 ! root     1446:        switch(table68k[opcode].size) {
1.1       root     1447:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1448:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1449:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1450:         default: abort();
1.1       root     1451:        }
1.1.1.2 ! root     1452:        printf("\tint carry = 0;\n");
        !          1453:        printf("\tcnt &= 63;\n");
1.1       root     1454:        printf("\tfor(;cnt;--cnt){\n");
                   1455:        printf("\tcarry=val&1; val >>= 1;\n");
                   1456:        printf("\tif(regs.x) val |= cmask;\n");
                   1457:        printf("\tregs.x = carry != 0;\n");
                   1458:        printf("\t}\n");
1.1.1.2 ! root     1459:        printf("\tCFLG = regs.x;\n");
        !          1460:        printf("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
        !          1461:        genastore("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1462:        break;
                   1463:      case i_ASRW:
1.1.1.2 ! root     1464:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
        !          1465:        printf("\tVFLG = 0;\n");
1.1       root     1466:        start_brace ();
1.1.1.2 ! root     1467:        switch(table68k[opcode].size) {
1.1       root     1468:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1469:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1470:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1471:         default: abort();
1.1       root     1472:        }
1.1.1.2 ! root     1473:        switch(table68k[opcode].size) {
1.1       root     1474:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1475:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1476:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1477:         default: abort();
1.1       root     1478:        }
                   1479:        printf("\tULONG sign = cmask & val;\n");
1.1.1.2 ! root     1480:        printf("\tCFLG=regs.x=val&1; val = (val >> 1) | sign;\n");
        !          1481:        printf("\tNFLG = sign != 0;\n");
        !          1482:        printf("\tZFLG = val == 0;\n");
        !          1483:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1484:        break;
                   1485:      case i_ASLW:
1.1.1.2 ! root     1486:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
        !          1487:        printf("\tVFLG = 0;\n");
1.1       root     1488:        start_brace ();
1.1.1.2 ! root     1489:        switch(table68k[opcode].size) {
1.1       root     1490:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1491:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1492:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1493:         default: abort();
1.1       root     1494:        }
1.1.1.2 ! root     1495:        switch(table68k[opcode].size) {
1.1       root     1496:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1497:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1498:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1499:         default: abort();
1.1       root     1500:        }
                   1501:        printf("\tULONG sign = cmask & val;\n");
1.1.1.2 ! root     1502:        printf("\tCFLG=regs.x=(val&cmask)!=0; val <<= 1;\n");
        !          1503:        printf("\tif ((val&cmask)!=sign) VFLG=1;\n");
        !          1504:        printf("\tNFLG = (val&cmask) != 0;\n");
        !          1505:        printf("\tZFLG = val == 0;\n");
        !          1506:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1507:        break;
                   1508:      case i_LSRW:
1.1.1.2 ! root     1509:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1510:        start_brace ();
1.1.1.2 ! root     1511:        switch(table68k[opcode].size) {
1.1       root     1512:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1513:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1514:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1515:         default: abort();
1.1       root     1516:        }
                   1517:        printf("\tint carry = val&1;\n");
                   1518:        printf("\tcarry=val&1; val >>= 1;\n");
1.1.1.2 ! root     1519:        genflags(flag_logical, table68k[opcode].size, "val", "", "");
        !          1520:        printf("CFLG = regs.x = carry!=0;\n");
        !          1521:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1522:        break;
                   1523:      case i_LSLW:
1.1.1.2 ! root     1524:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1525:        start_brace ();
1.1.1.2 ! root     1526:        switch(table68k[opcode].size) {
1.1       root     1527:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1528:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1529:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1530:         default: abort();
1.1       root     1531:        }
1.1.1.2 ! root     1532:        switch(table68k[opcode].size) {
1.1       root     1533:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1534:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1535:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1536:         default: abort();
1.1       root     1537:        }
                   1538:        printf("\tint carry = val&cmask;\n");
                   1539:        printf("\tval <<= 1;\n");
1.1.1.2 ! root     1540:        genflags(flag_logical, table68k[opcode].size, "val", "", "");
        !          1541:        printf("CFLG = regs.x = carry!=0;\n");
        !          1542:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1543:        break;
                   1544:      case i_ROLW:
1.1.1.2 ! root     1545:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1546:        start_brace ();
1.1.1.2 ! root     1547:        switch(table68k[opcode].size) {
1.1       root     1548:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1549:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1550:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1551:         default: abort();
1.1       root     1552:        }
1.1.1.2 ! root     1553:        switch(table68k[opcode].size) {
1.1       root     1554:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1555:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1556:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1557:         default: abort();
1.1       root     1558:        }
                   1559:        printf("\tint carry = val&cmask;\n");
                   1560:        printf("\tval <<= 1;\n");
                   1561:        printf("\tif(carry)  val |= 1;\n");
1.1.1.2 ! root     1562:        genflags(flag_logical, table68k[opcode].size, "val", "", "");
        !          1563:        printf("CFLG = carry!=0;\n");
        !          1564:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1565:        break;
                   1566:      case i_RORW:
1.1.1.2 ! root     1567:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1568:        start_brace ();
1.1.1.2 ! root     1569:        switch(table68k[opcode].size) {
1.1       root     1570:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1571:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1572:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1573:         default: abort();
1.1       root     1574:        }
                   1575:        printf("\tint carry = val&1;\n");
1.1.1.2 ! root     1576:        switch(table68k[opcode].size) {
1.1       root     1577:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1578:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1579:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1580:         default: abort();
1.1       root     1581:        }
                   1582:        printf("\tval >>= 1;\n");
                   1583:        printf("\tif(carry) val |= cmask;\n");
1.1.1.2 ! root     1584:        genflags(flag_logical, table68k[opcode].size, "val", "", "");
        !          1585:        printf("CFLG = carry!=0;\n");
        !          1586:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1587:        break;
                   1588:      case i_ROXLW:
1.1.1.2 ! root     1589:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1590:        start_brace ();
1.1.1.2 ! root     1591:        switch(table68k[opcode].size) {
1.1       root     1592:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1593:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1594:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1595:         default: abort();
1.1       root     1596:        }
1.1.1.2 ! root     1597:        switch(table68k[opcode].size) {
1.1       root     1598:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1599:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1600:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1601:         default: abort();
1.1       root     1602:        }
                   1603:        printf("\tint carry = val&cmask;\n");
                   1604:        printf("\tval <<= 1;\n");
                   1605:        printf("\tif(regs.x) val |= 1;\n");
                   1606:        printf("\tregs.x = carry != 0;\n");
1.1.1.2 ! root     1607:        genflags(flag_logical, table68k[opcode].size, "val", "", "");
        !          1608:        printf("regs.x = CFLG = carry!=0;\n");
        !          1609:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1610:        break;
                   1611:      case i_ROXRW:
1.1.1.2 ! root     1612:        genamode(table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1613:        start_brace ();
1.1.1.2 ! root     1614:        switch(table68k[opcode].size) {
1.1       root     1615:         case sz_byte: printf("\tUBYTE val = data;\n"); break;
                   1616:         case sz_word: printf("\tUWORD val = data;\n"); break;
                   1617:         case sz_long: printf("\tULONG val = data;\n"); break;
1.1.1.2 ! root     1618:         default: abort();
1.1       root     1619:        }
                   1620:        printf("\tint carry = val&1;\n");
1.1.1.2 ! root     1621:        switch(table68k[opcode].size) {
1.1       root     1622:         case sz_byte: printf("\tULONG cmask = 0x80;\n"); break;
                   1623:         case sz_word: printf("\tULONG cmask = 0x8000;\n"); break;
                   1624:         case sz_long: printf("\tULONG cmask = 0x80000000;\n"); break;
1.1.1.2 ! root     1625:         default: abort();
1.1       root     1626:        }
                   1627:        printf("\tval >>= 1;\n");
                   1628:        printf("\tif(regs.x) val |= cmask;\n");
                   1629:        printf("\tregs.x = carry != 0;\n");
1.1.1.2 ! root     1630:        genflags(flag_logical, table68k[opcode].size, "val", "", "");
        !          1631:        printf("regs.x = CFLG = carry!=0;\n");
        !          1632:        genastore("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
        !          1633:        break;
        !          1634:      case i_MOVEC2:
        !          1635:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1636:        start_brace();
        !          1637:        printf("\tint regno = (src >> 12) & 7;\n");
        !          1638:        printf("\tULONG *regp = src & 0x8000 ? regs.a + regno : regs.d + regno;\n");
        !          1639:        printf("\tm68k_movec2(src & 0xFFF, regp);\n");
        !          1640:        break;
        !          1641:      case i_MOVE2C:
        !          1642:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1643:        start_brace();
        !          1644:        printf("\tint regno = (src >> 12) & 7;\n");
        !          1645:        printf("\tULONG *regp = src & 0x8000 ? regs.a + regno : regs.d + regno;\n");
        !          1646:        printf("\tm68k_move2c(src & 0xFFF, regp);\n");
        !          1647:        break;
        !          1648:      case i_CAS:
        !          1649:        {
        !          1650:            int old_brace_level;
        !          1651:            genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
        !          1652:            genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !          1653:            start_brace();
        !          1654:            printf("\tint ru = (src >> 6) & 7;\n");
        !          1655:            printf("\tint rc = src & 7;\n");
        !          1656:            printf("\tif ((LONG)regs.d[rc] == (LONG)dst)");
        !          1657:            old_brace_level = n_braces;
        !          1658:            start_brace ();
        !          1659:            genastore("(regs.d[ru])",table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
        !          1660:            pop_braces (old_brace_level);
        !          1661:            printf("else");
        !          1662:            start_brace ();
        !          1663:            printf("regs.d[rc] = dst;\n");
        !          1664:            pop_braces (old_brace_level);
        !          1665:        }
        !          1666:        break;
        !          1667:      case i_DIVL:
        !          1668:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
        !          1669:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !          1670:        printf("\tm68k_divl(opcode, dst, extra);\n");
        !          1671:        break;
        !          1672:      case i_MULL:
        !          1673:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
        !          1674:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
        !          1675:        printf("\tm68k_mull(opcode, dst, extra);\n");
1.1       root     1676:        break;
                   1677:      default:
1.1.1.2 ! root     1678:        abort();
1.1       root     1679:        break;
                   1680:     };
                   1681:     finish_braces ();
                   1682: }
                   1683: 
                   1684: static void generate_func(long int from, long int to)
                   1685: {
                   1686:     int illg = 0;
                   1687:     long int opcode;
                   1688:     UWORD smsk; 
                   1689:     UWORD dmsk;    
                   1690: 
1.1.1.2 ! root     1691:     printf("#include \"sysconfig.h\"\n");
        !          1692:     printf("#include \"sysdeps.h\"\n");
1.1       root     1693:     printf("#include \"config.h\"\n");
                   1694:     printf("#include \"options.h\"\n");
                   1695:     printf("#include \"memory.h\"\n");
                   1696:     printf("#include \"custom.h\"\n");    
                   1697:     printf("#include \"newcpu.h\"\n");
                   1698:     printf("#include \"cputbl.h\"\n");
                   1699:     for(opcode=from; opcode < to; opcode++) {
1.1.1.2 ! root     1700:        if (table68k[opcode].mnemo == i_ILLG) {
1.1       root     1701:            illg++;
                   1702:            continue;
                   1703:        }
1.1.1.2 ! root     1704: 
        !          1705:        if (isspecific(opcode)) {
        !          1706:            printf("void op_%lx_s(ULONG opcode)\n{\n", opcode);
        !          1707:            if (table68k[opcode].suse
        !          1708:                && table68k[opcode].smode != imm  && table68k[opcode].smode != imm0
        !          1709:                && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
        !          1710:                && table68k[opcode].smode != absw && table68k[opcode].smode != absl
        !          1711:                && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
        !          1712:            {
        !          1713:                printf("\tULONG srcreg = (LONG)(BYTE)%d;\n", (int)table68k[opcode].sreg);
        !          1714:            }
        !          1715:            if (table68k[opcode].duse
        !          1716:                /* Yes, the dmode can be imm, in case of LINK or DBcc */
        !          1717:                && table68k[opcode].dmode != imm  && table68k[opcode].dmode != imm0
        !          1718:                && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
        !          1719:                && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) {
        !          1720:                printf("\tULONG dstreg = (LONG)(BYTE)%d;\n", (int)table68k[opcode].dreg);
        !          1721:            }
        !          1722:            gen_opcode(opcode);
        !          1723:            printf("}\n");
        !          1724:        }
        !          1725:            
        !          1726:        if (table68k[opcode].handler != -1)
1.1       root     1727:            continue;
1.1.1.2 ! root     1728: 
        !          1729: 
        !          1730:        switch (table68k[opcode].stype) {
        !          1731:         case 0:
        !          1732:            smsk = 7; break;
        !          1733:         case 1:
        !          1734:            smsk = 255; break;
        !          1735:         case 2:
        !          1736:            smsk = 15; break;
        !          1737:         case 3:
        !          1738:            smsk = 7; break;
        !          1739:         default:
        !          1740:            abort();
1.1       root     1741:        }
1.1.1.2 ! root     1742:        smsk <<= table68k[opcode].spos;
        !          1743:        dmsk = 7 << table68k[opcode].dpos;
1.1       root     1744:        
1.1.1.2 ! root     1745:        printf("void op_%lx(ULONG opcode)\n{\n", opcode);
        !          1746:        if (table68k[opcode].suse
        !          1747:            && table68k[opcode].smode != imm  && table68k[opcode].smode != imm0
        !          1748:            && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
        !          1749:            && table68k[opcode].smode != absw && table68k[opcode].smode != absl
        !          1750:            && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
1.1       root     1751:        {
1.1.1.2 ! root     1752:            if (table68k[opcode].spos == -1) {
        !          1753:                printf("\tULONG srcreg = (LONG)(BYTE)%d;\n", (int)table68k[opcode].sreg);
1.1       root     1754:            } else {
1.1.1.2 ! root     1755:                if (table68k[opcode].stype == 3)
        !          1756:                    printf("\tULONG srcreg = imm8_table[(opcode & %d) >> %d];\n",
        !          1757:                           smsk, (int)table68k[opcode].spos);
        !          1758:                else
        !          1759:                    printf("\tULONG srcreg = (LONG)(BYTE)((opcode & %d) >> %d);\n", 
        !          1760:                           smsk, (int)table68k[opcode].spos);
1.1       root     1761:            }
                   1762:        }
1.1.1.2 ! root     1763:        if (table68k[opcode].duse
1.1       root     1764:            /* Yes, the dmode can be imm, in case of LINK or DBcc */
1.1.1.2 ! root     1765:            && table68k[opcode].dmode != imm  && table68k[opcode].dmode != imm0
        !          1766:            && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
        !          1767:            && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl) {
        !          1768:            if (table68k[opcode].dpos == -1) {          
        !          1769:                printf("\tULONG dstreg = (LONG)(BYTE)%d;\n", (int)table68k[opcode].dreg);
1.1       root     1770:            } else {
1.1.1.2 ! root     1771:                printf("\tULONG dstreg = (opcode & %d) >> %d;\n", dmsk, (int)table68k[opcode].dpos);
1.1       root     1772:            }
                   1773:        }
                   1774:        gen_opcode(opcode);
                   1775:         printf("}\n");
                   1776:     }
                   1777: 
                   1778:     fprintf (stderr, "%d illegals generated.\n", illg);
                   1779: }
                   1780: 
                   1781: static void generate_table(void)
                   1782: {
                   1783:     int illg = 0;
                   1784:     long int opcode;
                   1785:     
1.1.1.2 ! root     1786:     printf("#include \"sysconfig.h\"\n");
        !          1787:     printf("#include \"sysdeps.h\"\n");
1.1       root     1788:     printf("#include \"config.h\"\n");
                   1789:     printf("#include \"options.h\"\n");
                   1790:     printf("#include \"memory.h\"\n");
                   1791:     printf("#include \"custom.h\"\n");
                   1792:     printf("#include \"newcpu.h\"\n");
                   1793:     printf("#include \"cputbl.h\"\n");
                   1794:     
                   1795:     printf("cpuop_func *cpufunctbl[65536] = {\n");
                   1796:     for(opcode=0; opcode < 65536; opcode++) {
1.1.1.2 ! root     1797:        if (table68k[opcode].mnemo == i_ILLG) {
1.1       root     1798:            printf("op_illg");
                   1799:            illg++;
1.1.1.2 ! root     1800:        } else if (isspecific(opcode))
        !          1801:            printf("op_%lx_s", opcode);
        !          1802:        else if (table68k[opcode].handler != -1)
        !          1803:            printf("op_%lx", table68k[opcode].handler);
        !          1804:        else
        !          1805:            printf("op_%lx", opcode);
1.1       root     1806:        
                   1807:        if (opcode < 65535) printf(",");
                   1808:        if ((opcode & 7) == 7) printf("\n");
                   1809:     }
                   1810:     printf("\n};\n");
                   1811:     fprintf (stderr, "%d illegals generated.\n", illg);
1.1.1.2 ! root     1812:     if (get_no_mismatches())
        !          1813:        fprintf(stderr, "%d mismatches.\n", get_no_mismatches());
1.1       root     1814: }
                   1815: 
1.1.1.2 ! root     1816: static void generate_smalltable(void)
1.1       root     1817: {
                   1818:     long int opcode;
                   1819:     
1.1.1.2 ! root     1820:     printf("#include \"sysconfig.h\"\n");
        !          1821:     printf("#include \"sysdeps.h\"\n");
        !          1822:     printf("#include \"config.h\"\n");
        !          1823:     printf("#include \"options.h\"\n");
        !          1824:     printf("#include \"memory.h\"\n");
        !          1825:     printf("#include \"custom.h\"\n");
        !          1826:     printf("#include \"newcpu.h\"\n");
        !          1827:     printf("#include \"cputbl.h\"\n");
1.1       root     1828:     
1.1.1.2 ! root     1829:     printf("struct cputbl smallcputbl[] = {\n");
        !          1830:     for(opcode=0; opcode < 65536; opcode++) {
        !          1831:        if ((isspecific(opcode) || table68k[opcode].handler == -1)
        !          1832:            && table68k[opcode].mnemo != i_ILLG) 
        !          1833:        {
        !          1834:            if (isspecific(opcode))
        !          1835:                printf("{ op_%x_s, 1, %d },\n", opcode, opcode);
        !          1836:            if (table68k[opcode].handler == -1)
        !          1837:                printf("{ op_%x, 0, %d },\n", opcode, opcode);
        !          1838:        }
        !          1839:     }
        !          1840:     printf("{ 0, 0, 0 }};\n");
        !          1841: }
        !          1842: 
        !          1843: static void generate_header(void)
        !          1844: {
        !          1845:     int illg = 0;
        !          1846:     long int opcode;
1.1       root     1847:     
                   1848:     for(opcode=0; opcode < 65536; opcode++) {
1.1.1.2 ! root     1849:        if (table68k[opcode].mnemo == i_ILLG) {
1.1       root     1850:            illg++;
                   1851:            continue;
                   1852:        }
1.1.1.2 ! root     1853:        if (isspecific(opcode))
        !          1854:            printf("extern cpuop_func op_%lx_s;\n", opcode);
        !          1855:        if (table68k[opcode].handler != -1)
1.1       root     1856:            continue;
1.1.1.2 ! root     1857:        
1.1       root     1858:        printf("extern cpuop_func op_%lx;\n", opcode);
                   1859:     }
                   1860:     
                   1861:     fprintf (stderr, "%d illegals generated.\n", illg);
1.1.1.2 ! root     1862:     if (get_no_mismatches())
        !          1863:        fprintf(stderr, "%d mismatches.\n", get_no_mismatches());
1.1       root     1864: }
                   1865: 
                   1866: int main(int argc, char **argv)
                   1867: {
                   1868:     long int range = -1;
                   1869:     char mode = 'n';
                   1870:     int i;
                   1871:     
                   1872:     if (argc == 2)
                   1873:        mode = *argv[1];
                   1874: 
                   1875:     if (argc == 3) {
                   1876:        range = atoi(argv[2]);
                   1877:        mode = *argv[1];
                   1878:     }
1.1.1.2 ! root     1879:     
        !          1880:     read_table68k ();
        !          1881:     read_counts();
        !          1882:     do_merges ();
        !          1883:     
1.1       root     1884:     switch(mode) {
                   1885:      case 'f':
                   1886:        generate_func(range * 0x1000, (range + 1) * 0x1000);
                   1887:        break;
                   1888:      case 'h':
                   1889:        generate_header();
                   1890:        break;
                   1891:      case 't':
                   1892:        generate_table();
                   1893:        break;
1.1.1.2 ! root     1894:      case 's':
        !          1895:        generate_smalltable();
        !          1896:        break;
1.1       root     1897:      default:
1.1.1.2 ! root     1898:        abort();
1.1       root     1899:     }
1.1.1.2 ! root     1900:     free(table68k);
1.1       root     1901:     return 0;
                   1902: }

unix.superglobalmegacorp.com

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