Annotation of uae/src/gencpu.c, revision 1.1.1.6

1.1.1.3   root        1: /*
1.1       root        2:  * UAE - The Un*x Amiga Emulator
                      3:  *
                      4:  * MC68000 emulation generator
                      5:  *
1.1.1.3   root        6:  * This is a fairly stupid program that generates a lot of case labels that
1.1       root        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().
1.1.1.3   root       13:  * The generated code is sometimes sub-optimal, an optimizing compiler should
1.1       root       14:  * take care of this.
1.1.1.3   root       15:  *
1.1       root       16:  * Copyright 1995, 1996 Bernd Schmidt
                     17:  */
                     18: 
                     19: #include "sysconfig.h"
                     20: #include "sysdeps.h"
                     21: #include <ctype.h>
                     22: 
                     23: #include "config.h"
                     24: #include "options.h"
                     25: #include "readcpu.h"
                     26: 
                     27: #define BOOL_TYPE "int"
                     28: 
1.1.1.3   root       29: static FILE *headerfile;
                     30: static FILE *stblfile;
                     31: 
                     32: static int using_prefetch;
                     33: static int using_exception_3;
                     34: static int cpu_level;
                     35: 
                     36: /* For the current opcode, the next lower level that will have different code.
                     37:  * Initialized to -1 for each opcode. If it remains unchanged, indicates we
                     38:  * are done with that opcode.  */
                     39: static int next_cpu_level;
1.1       root       40: 
1.1.1.5   root       41: void write_log (const char *s, ...)
1.1       root       42: {
1.1.1.3   root       43:     fprintf (stderr, "%s", s);
1.1       root       44: }
                     45: 
1.1.1.3   root       46: static int *opcode_map;
                     47: static int *opcode_next_clev;
                     48: static int *opcode_last_postfix;
                     49: static unsigned long *counts;
                     50: 
1.1.1.5   root       51: static void read_counts (void)
1.1       root       52: {
                     53:     FILE *file;
1.1.1.5   root       54:     unsigned long opcode, count, total;
1.1       root       55:     char name[20];
1.1.1.5   root       56:     int nr = 0;
1.1.1.3   root       57:     memset (counts, 0, 65536 * sizeof *counts);
1.1       root       58: 
1.1.1.3   root       59:     file = fopen ("frequent.68k", "r");
                     60:     if (file) {
                     61:        fscanf (file, "Total: %lu\n", &total);
1.1.1.5   root       62:        while (fscanf (file, "%lx: %lu %s\n", &opcode, &count, name) == 3) {
1.1.1.3   root       63:            opcode_next_clev[nr] = 3;
                     64:            opcode_last_postfix[nr] = -1;
                     65:            opcode_map[nr++] = opcode;
                     66:            counts[opcode] = count;
                     67:        }
                     68:        fclose (file);
                     69:     }
                     70:     if (nr == nr_cpuop_funcs)
                     71:        return;
                     72:     for (opcode = 0; opcode < 0x10000; opcode++) {
                     73:        if (table68k[opcode].handler == -1 && table68k[opcode].mnemo != i_ILLG
                     74:            && counts[opcode] == 0)
1.1       root       75:        {
1.1.1.3   root       76:            opcode_next_clev[nr] = 3;
                     77:            opcode_last_postfix[nr] = -1;
                     78:            opcode_map[nr++] = opcode;
                     79:            counts[opcode] = count;
1.1       root       80:        }
                     81:     }
1.1.1.3   root       82:     if (nr != nr_cpuop_funcs)
                     83:        abort ();
1.1       root       84: }
                     85: 
1.1.1.3   root       86: static char endlabelstr[80];
                     87: static int endlabelno = 0;
1.1.1.5   root       88: static int need_endlabel;
1.1       root       89: 
                     90: static int n_braces = 0;
1.1.1.3   root       91: static int m68k_pc_offset = 0;
1.1.1.5   root       92: static int insn_n_cycles;
1.1       root       93: 
1.1.1.5   root       94: static void start_brace (void)
1.1       root       95: {
                     96:     n_braces++;
1.1.1.3   root       97:     printf ("{");
1.1       root       98: }
                     99: 
1.1.1.5   root      100: static void close_brace (void)
1.1       root      101: {
                    102:     assert (n_braces > 0);
                    103:     n_braces--;
1.1.1.3   root      104:     printf ("}");
1.1       root      105: }
                    106: 
1.1.1.5   root      107: static void finish_braces (void)
1.1       root      108: {
                    109:     while (n_braces > 0)
1.1.1.5   root      110:        close_brace ();
1.1       root      111: }
                    112: 
1.1.1.5   root      113: static void pop_braces (int to)
1.1       root      114: {
                    115:     while (n_braces > to)
1.1.1.5   root      116:        close_brace ();
1.1       root      117: }
                    118: 
1.1.1.5   root      119: static int bit_size (int size)
1.1       root      120: {
1.1.1.5   root      121:     switch (size) {
                    122:      case sz_byte: return 8;
                    123:      case sz_word: return 16;
                    124:      case sz_long: return 32;
                    125:      default: abort ();
1.1       root      126:     }
                    127:     return 0;
                    128: }
                    129: 
1.1.1.5   root      130: static const char *bit_mask (int size)
1.1       root      131: {
1.1.1.5   root      132:     switch (size) {
1.1.1.3   root      133:      case sz_byte: return "0xff";
                    134:      case sz_word: return "0xffff";
                    135:      case sz_long: return "0xffffffff";
1.1.1.5   root      136:      default: abort ();
1.1       root      137:     }
                    138:     return 0;
                    139: }
                    140: 
1.1.1.3   root      141: static const char *gen_nextilong (void)
                    142: {
                    143:     static char buffer[80];
                    144:     int r = m68k_pc_offset;
                    145:     m68k_pc_offset += 4;
1.1.1.5   root      146: 
                    147:     insn_n_cycles += 4;
                    148: 
                    149:     if (using_prefetch)
                    150:        sprintf (buffer, "get_ilong_prefetch(%d)", r);
                    151:     else
                    152:        sprintf (buffer, "get_ilong(%d)", r);
1.1.1.3   root      153:     return buffer;
                    154: }
                    155: 
                    156: static const char *gen_nextiword (void)
                    157: {
                    158:     static char buffer[80];
                    159:     int r = m68k_pc_offset;
                    160:     m68k_pc_offset += 2;
1.1.1.5   root      161: 
                    162:     insn_n_cycles += 2;
                    163: 
                    164:     if (using_prefetch)
                    165:        sprintf (buffer, "get_iword_prefetch(%d)", r);
                    166:     else
                    167:        sprintf (buffer, "get_iword(%d)", r);
1.1.1.3   root      168:     return buffer;
                    169: }
                    170: 
                    171: static const char *gen_nextibyte (void)
                    172: {
                    173:     static char buffer[80];
                    174:     int r = m68k_pc_offset;
                    175:     m68k_pc_offset += 2;
1.1.1.5   root      176: 
                    177:     insn_n_cycles += 2;
                    178: 
                    179:     if (using_prefetch)
                    180:        sprintf (buffer, "get_ibyte_prefetch(%d)", r);
                    181:     else
                    182:        sprintf (buffer, "get_ibyte(%d)", r);
1.1.1.3   root      183:     return buffer;
                    184: }
                    185: 
                    186: static void fill_prefetch_0 (void)
                    187: {
                    188:     if (using_prefetch)
                    189:        printf ("fill_prefetch_0 ();\n");
                    190: }
                    191: 
                    192: static void fill_prefetch_2 (void)
                    193: {
                    194:     if (using_prefetch)
                    195:        printf ("fill_prefetch_2 ();\n");
                    196: }
                    197: 
1.1.1.6 ! root      198: static void swap_opcode (void)
1.1.1.5   root      199: {
1.1.1.6 ! root      200:   printf ("#ifdef HAVE_GET_WORD_UNSWAPPED\n");
        !           201:   printf ("\topcode = ((opcode << 8) & 0xFF00) | ((opcode >> 8) & 0xFF);\n");
        !           202:   printf ("#endif\n");
1.1.1.5   root      203: }
                    204: 
1.1.1.3   root      205: static void sync_m68k_pc (void)
                    206: {
                    207:     if (m68k_pc_offset == 0)
                    208:        return;
                    209:     printf ("m68k_incpc(%d);\n", m68k_pc_offset);
                    210:     switch (m68k_pc_offset) {
                    211:      case 0:
1.1.1.5   root      212:        /*fprintf (stderr, "refilling prefetch at 0\n"); */
1.1.1.3   root      213:        break;
                    214:      case 2:
1.1.1.5   root      215:        fill_prefetch_2 ();
1.1.1.3   root      216:        break;
                    217:      default:
1.1.1.5   root      218:        fill_prefetch_0 ();
1.1.1.3   root      219:        break;
                    220:     }
                    221:     m68k_pc_offset = 0;
                    222: }
                    223: 
                    224: /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
1.1.1.5   root      225:  * the calling routine handles Apdi and Aipi modes. */
1.1.1.3   root      226: static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem)
1.1       root      227: {
1.1.1.6 ! root      228:     start_brace ();
1.1.1.5   root      229:     switch (mode) {
1.1       root      230:      case Dreg:
                    231:        if (movem)
1.1.1.5   root      232:            abort ();
1.1.1.3   root      233:        if (getv == 1)
1.1.1.5   root      234:            switch (size) {
1.1       root      235:             case sz_byte:
1.1.1.2   root      236: #ifdef AMIGA
                    237:                /* sam: I don't know why gcc.2.7.2.1 produces a code worse */
                    238:                /* if it is not done like that: */
1.1.1.3   root      239:                printf ("\tuae_s8 %s = ((uae_u8*)&m68k_dreg(regs, %s))[3];\n", name, reg);
1.1.1.2   root      240: #else
1.1.1.3   root      241:                printf ("\tuae_s8 %s = m68k_dreg(regs, %s);\n", name, reg);
1.1.1.2   root      242: #endif
1.1       root      243:                break;
                    244:             case sz_word:
1.1.1.2   root      245: #ifdef AMIGA
1.1.1.3   root      246:                printf ("\tuae_s16 %s = ((uae_s16*)&m68k_dreg(regs, %s))[1];\n", name, reg);
1.1.1.2   root      247: #else
1.1.1.3   root      248:                printf ("\tuae_s16 %s = m68k_dreg(regs, %s);\n", name, reg);
1.1.1.2   root      249: #endif
1.1       root      250:                break;
                    251:             case sz_long:
1.1.1.3   root      252:                printf ("\tuae_s32 %s = m68k_dreg(regs, %s);\n", name, reg);
1.1       root      253:                break;
1.1.1.5   root      254:             default:
                    255:                abort ();
1.1       root      256:            }
1.1.1.3   root      257:        return;
1.1       root      258:      case Areg:
                    259:        if (movem)
1.1.1.5   root      260:            abort ();
1.1.1.3   root      261:        if (getv == 1)
1.1.1.5   root      262:            switch (size) {
1.1       root      263:             case sz_word:
1.1.1.3   root      264:                printf ("\tuae_s16 %s = m68k_areg(regs, %s);\n", name, reg);
1.1       root      265:                break;
                    266:             case sz_long:
1.1.1.3   root      267:                printf ("\tuae_s32 %s = m68k_areg(regs, %s);\n", name, reg);
1.1       root      268:                break;
1.1.1.5   root      269:             default:
                    270:                abort ();
1.1       root      271:            }
1.1.1.3   root      272:        return;
1.1       root      273:      case Aind:
1.1.1.3   root      274:        printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg);
1.1       root      275:        break;
                    276:      case Aipi:
1.1.1.3   root      277:        printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg);
1.1       root      278:        break;
                    279:      case Apdi:
1.1.1.5   root      280:        switch (size) {
1.1       root      281:         case sz_byte:
1.1.1.3   root      282:            if (movem)
                    283:                printf ("\tuaecptr %sa = m68k_areg(regs, %s);\n", name, reg);
                    284:            else
                    285:                printf ("\tuaecptr %sa = m68k_areg(regs, %s) - areg_byteinc[%s];\n", name, reg, reg);
1.1       root      286:            break;
                    287:         case sz_word:
1.1.1.3   root      288:            printf ("\tuaecptr %sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 2);
1.1       root      289:            break;
                    290:         case sz_long:
1.1.1.3   root      291:            printf ("\tuaecptr %sa = m68k_areg(regs, %s) - %d;\n", name, reg, movem ? 0 : 4);
1.1       root      292:            break;
1.1.1.5   root      293:         default:
                    294:            abort ();
1.1       root      295:        }
                    296:        break;
                    297:      case Ad16:
1.1.1.5   root      298:        printf ("\tuaecptr %sa = m68k_areg(regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword ());
1.1       root      299:        break;
                    300:      case Ad8r:
1.1.1.3   root      301:        if (cpu_level > 1) {
                    302:            if (next_cpu_level < 1)
                    303:                next_cpu_level = 1;
1.1.1.5   root      304:            sync_m68k_pc ();
                    305:            start_brace ();
1.1.1.3   root      306:            printf ("\tuaecptr %sa = get_disp_ea_020(m68k_areg(regs, %s), next_iword());\n", name, reg);
1.1.1.6 ! root      307:        } else
1.1.1.5   root      308:            printf ("\tuaecptr %sa = get_disp_ea_000(m68k_areg(regs, %s), %s);\n", name, reg, gen_nextiword ());
1.1.1.6 ! root      309: 
1.1       root      310:        break;
                    311:      case PC16:
1.1.1.6 ! root      312:        printf ("\tuaecptr %sa = m68k_getpc () + %d;\n", name, m68k_pc_offset);
        !           313:        printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword ());
1.1       root      314:        break;
                    315:      case PC8r:
1.1.1.3   root      316:        if (cpu_level > 1) {
                    317:            if (next_cpu_level < 1)
                    318:                next_cpu_level = 1;
1.1.1.5   root      319:            sync_m68k_pc ();
                    320:            start_brace ();
1.1.1.3   root      321:            printf ("\tuaecptr tmppc = m68k_getpc();\n");
                    322:            printf ("\tuaecptr %sa = get_disp_ea_020(tmppc, next_iword());\n", name);
                    323:        } else {
1.1.1.6 ! root      324:            printf ("\tuaecptr tmppc = m68k_getpc() + %d;\n", m68k_pc_offset);
        !           325:            printf ("\tuaecptr %sa = get_disp_ea_000(tmppc, %s);\n", name, gen_nextiword ());
1.1       root      326:        }
1.1.1.3   root      327: 
1.1       root      328:        break;
                    329:      case absw:
1.1.1.6 ! root      330:        printf ("\tuaecptr %sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword ());
1.1       root      331:        break;
                    332:      case absl:
1.1.1.6 ! root      333:        printf ("\tuaecptr %sa = %s;\n", name, gen_nextilong ());
1.1       root      334:        break;
                    335:      case imm:
1.1.1.3   root      336:        if (getv != 1)
                    337:            abort ();
1.1.1.5   root      338:        switch (size) {
1.1.1.3   root      339:         case sz_byte:
1.1.1.6 ! root      340:            printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ());
1.1.1.3   root      341:            break;
                    342:         case sz_word:
1.1.1.6 ! root      343:            printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ());
1.1.1.3   root      344:            break;
                    345:         case sz_long:
1.1.1.6 ! root      346:            printf ("\tuae_s32 %s = %s;\n", name, gen_nextilong ());
1.1.1.3   root      347:            break;
1.1.1.5   root      348:         default:
                    349:            abort ();
1.1.1.3   root      350:        }
                    351:        return;
                    352:      case imm0:
1.1.1.5   root      353:        if (getv != 1)
                    354:            abort ();
1.1.1.6 ! root      355:        printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte ());
1.1.1.3   root      356:        return;
                    357:      case imm1:
1.1.1.5   root      358:        if (getv != 1)
                    359:            abort ();
1.1.1.6 ! root      360:        printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword ());
1.1.1.3   root      361:        return;
                    362:      case imm2:
1.1.1.5   root      363:        if (getv != 1)
                    364:            abort ();
1.1.1.6 ! root      365:        printf ("\tuae_s32 %s = %s;\n", name, gen_nextilong ());
1.1.1.3   root      366:        return;
                    367:      case immi:
1.1.1.5   root      368:        if (getv != 1)
                    369:            abort ();
1.1.1.3   root      370:        printf ("\tuae_u32 %s = %s;\n", name, reg);
                    371:        return;
                    372:      default:
1.1.1.5   root      373:        abort ();
1.1.1.3   root      374:     }
                    375: 
                    376:     /* We get here for all non-reg non-immediate addressing modes to
                    377:      * actually fetch the value. */
                    378: 
1.1.1.6 ! root      379:     if (using_exception_3 && getv != 0 && size != sz_byte) {       
1.1.1.3   root      380:        printf ("\tif ((%sa & 1) != 0) {\n", name);
                    381:        printf ("\t\tlast_fault_for_exception_3 = %sa;\n", name);
1.1.1.5   root      382:        printf ("\t\tlast_op_for_exception_3 = opcode;\n");
1.1.1.3   root      383:        printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + %d;\n", m68k_pc_offset);
                    384:        printf ("\t\tException(3, 0);\n");
                    385:        printf ("\t\tgoto %s;\n", endlabelstr);
                    386:        printf ("\t}\n");
1.1.1.5   root      387:        need_endlabel = 1;
1.1.1.3   root      388:        start_brace ();
                    389:     }
1.1.1.6 ! root      390: 
        !           391:     if (getv == 1) {
        !           392:        switch (size) {
        !           393:         case sz_byte: insn_n_cycles += 2; break;
        !           394:         case sz_word: insn_n_cycles += 2; break;
        !           395:         case sz_long: insn_n_cycles += 4; break;
        !           396:         default: abort ();
        !           397:        }
        !           398:        start_brace ();
        !           399:        switch (size) {
        !           400:         case sz_byte: printf ("\tuae_s8 %s = get_byte(%sa);\n", name, name); break;
        !           401:         case sz_word: printf ("\tuae_s16 %s = get_word(%sa);\n", name, name); break;
        !           402:         case sz_long: printf ("\tuae_s32 %s = get_long(%sa);\n", name, name); break;
        !           403:         default: abort ();
        !           404:        }
        !           405:     }
        !           406: 
1.1.1.3   root      407:     /* We now might have to fix up the register for pre-dec or post-inc
                    408:      * addressing modes. */
                    409:     if (!movem)
                    410:        switch (mode) {
                    411:         case Aipi:
1.1.1.5   root      412:            switch (size) {
1.1       root      413:             case sz_byte:
1.1.1.3   root      414:                printf ("\tm68k_areg(regs, %s) += areg_byteinc[%s];\n", reg, reg);
1.1       root      415:                break;
                    416:             case sz_word:
1.1.1.3   root      417:                printf ("\tm68k_areg(regs, %s) += 2;\n", reg);
1.1       root      418:                break;
                    419:             case sz_long:
1.1.1.3   root      420:                printf ("\tm68k_areg(regs, %s) += 4;\n", reg);
1.1       root      421:                break;
1.1.1.5   root      422:             default:
                    423:                abort ();
1.1       root      424:            }
1.1.1.3   root      425:            break;
                    426:         case Apdi:
                    427:            printf ("\tm68k_areg (regs, %s) = %sa;\n", reg, name);
                    428:            break;
                    429:         default:
                    430:            break;
                    431:        }
1.1       root      432: }
                    433: 
1.1.1.3   root      434: static void genastore (char *from, amodes mode, char *reg, wordsizes size, char *to)
1.1       root      435: {
1.1.1.5   root      436:     switch (mode) {
1.1       root      437:      case Dreg:
1.1.1.5   root      438:        switch (size) {
1.1       root      439:         case sz_byte:
1.1.1.3   root      440:            printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xff) | ((%s) & 0xff);\n", reg, reg, from);
1.1       root      441:            break;
                    442:         case sz_word:
1.1.1.3   root      443:            printf ("\tm68k_dreg(regs, %s) = (m68k_dreg(regs, %s) & ~0xffff) | ((%s) & 0xffff);\n", reg, reg, from);
1.1       root      444:            break;
                    445:         case sz_long:
1.1.1.3   root      446:            printf ("\tm68k_dreg(regs, %s) = (%s);\n", reg, from);
1.1       root      447:            break;
1.1.1.5   root      448:         default:
                    449:            abort ();
1.1       root      450:        }
                    451:        break;
                    452:      case Areg:
1.1.1.5   root      453:        switch (size) {
1.1       root      454:         case sz_word:
1.1.1.3   root      455:            fprintf (stderr, "Foo\n");
                    456:            printf ("\tm68k_areg(regs, %s) = (uae_s32)(uae_s16)(%s);\n", reg, from);
1.1       root      457:            break;
                    458:         case sz_long:
1.1.1.3   root      459:            printf ("\tm68k_areg(regs, %s) = (%s);\n", reg, from);
1.1       root      460:            break;
1.1.1.5   root      461:         default:
                    462:            abort ();
1.1       root      463:        }
                    464:        break;
                    465:      case Aind:
                    466:      case Aipi:
                    467:      case Apdi:
                    468:      case Ad16:
                    469:      case Ad8r:
                    470:      case absw:
                    471:      case absl:
                    472:      case PC16:
                    473:      case PC8r:
1.1.1.3   root      474:        if (using_prefetch)
1.1.1.5   root      475:            sync_m68k_pc ();
                    476:        switch (size) {
1.1       root      477:         case sz_byte:
1.1.1.5   root      478:            insn_n_cycles += 2;
1.1.1.3   root      479:            printf ("\tput_byte(%sa,%s);\n", to, from);
1.1       root      480:            break;
                    481:         case sz_word:
1.1.1.5   root      482:            insn_n_cycles += 2;
                    483:            if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                    484:                abort ();
1.1.1.3   root      485:            printf ("\tput_word(%sa,%s);\n", to, from);
1.1       root      486:            break;
                    487:         case sz_long:
1.1.1.5   root      488:            insn_n_cycles += 4;
                    489:            if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                    490:                abort ();
1.1.1.3   root      491:            printf ("\tput_long(%sa,%s);\n", to, from);
1.1       root      492:            break;
1.1.1.5   root      493:         default:
                    494:            abort ();
1.1       root      495:        }
                    496:        break;
                    497:      case imm:
                    498:      case imm0:
                    499:      case imm1:
                    500:      case imm2:
                    501:      case immi:
1.1.1.5   root      502:        abort ();
1.1       root      503:        break;
1.1.1.3   root      504:      default:
1.1.1.5   root      505:        abort ();
1.1       root      506:     }
                    507: }
                    508: 
1.1.1.5   root      509: static void genmovemel (uae_u16 opcode)
1.1       root      510: {
                    511:     char getcode[100];
                    512:     int size = table68k[opcode].size == sz_long ? 4 : 2;
1.1.1.3   root      513: 
                    514:     if (table68k[opcode].size == sz_long) {
1.1.1.5   root      515:        strcpy (getcode, "get_long(srca)");
1.1.1.3   root      516:     } else {
1.1.1.5   root      517:        strcpy (getcode, "(uae_s32)(uae_s16)get_word(srca)");
1.1       root      518:     }
1.1.1.3   root      519: 
1.1.1.5   root      520:     printf ("\tuae_u16 mask = %s;\n", gen_nextiword ());
1.1.1.3   root      521:     printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
                    522:     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
1.1.1.5   root      523:     start_brace ();
1.1.1.3   root      524:     printf ("\twhile (dmask) { m68k_dreg(regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask]; }\n",
1.1.1.5   root      525:            getcode, size);
1.1.1.3   root      526:     printf ("\twhile (amask) { m68k_areg(regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask]; }\n",
1.1.1.5   root      527:            getcode, size);
1.1       root      528: 
                    529:     if (table68k[opcode].dmode == Aipi)
1.1.1.3   root      530:        printf ("\tm68k_areg(regs, dstreg) = srca;\n");
1.1       root      531: }
                    532: 
1.1.1.5   root      533: static void genmovemle (uae_u16 opcode)
1.1       root      534: {
                    535:     char putcode[100];
                    536:     int size = table68k[opcode].size == sz_long ? 4 : 2;
                    537:     if (table68k[opcode].size == sz_long) {
1.1.1.5   root      538:        strcpy (putcode, "put_long(srca,");
1.1.1.3   root      539:     } else {
1.1.1.5   root      540:        strcpy (putcode, "put_word(srca,");
1.1       root      541:     }
1.1.1.3   root      542: 
1.1.1.5   root      543:     printf ("\tuae_u16 mask = %s;\n", gen_nextiword ());
1.1.1.3   root      544:     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1);
                    545:     if (using_prefetch)
1.1.1.5   root      546:        sync_m68k_pc ();
1.1.1.3   root      547: 
1.1.1.5   root      548:     start_brace ();
1.1       root      549:     if (table68k[opcode].dmode == Apdi) {
1.1.1.3   root      550:        printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
                    551:        printf ("\twhile (amask) { srca -= %d; %s m68k_areg(regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
1.1.1.5   root      552:                size, putcode);
1.1.1.3   root      553:        printf ("\twhile (dmask) { srca -= %d; %s m68k_dreg(regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
1.1.1.5   root      554:                size, putcode);
1.1.1.3   root      555:        printf ("\tm68k_areg(regs, dstreg) = srca;\n");
1.1.1.2   root      556:     } else {
1.1.1.3   root      557:        printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
                    558:        printf ("\twhile (dmask) { %s m68k_dreg(regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
1.1.1.5   root      559:                putcode, size);
1.1.1.3   root      560:        printf ("\twhile (amask) { %s m68k_areg(regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
1.1.1.5   root      561:                putcode, size);
1.1       root      562:     }
                    563: }
                    564: 
                    565: typedef enum {
                    566:     flag_logical, flag_add, flag_sub, flag_cmp, flag_addx, flag_subx, flag_zn,
                    567:     flag_av, flag_sv
                    568: } flagtypes;
                    569: 
1.1.1.5   root      570: static void genflags_normal (flagtypes type, wordsizes size, char *value, char *src, char *dst)
1.1       root      571: {
1.1.1.5   root      572:     char vstr[100], sstr[100], dstr[100];
                    573:     char usstr[100], udstr[100];
                    574:     char unsstr[100], undstr[100];
1.1       root      575: 
1.1.1.5   root      576:     switch (size) {
1.1       root      577:      case sz_byte:
1.1.1.5   root      578:        strcpy (vstr, "((uae_s8)(");
                    579:        strcpy (usstr, "((uae_u8)(");
1.1       root      580:        break;
                    581:      case sz_word:
1.1.1.5   root      582:        strcpy (vstr, "((uae_s16)(");
                    583:        strcpy (usstr, "((uae_u16)(");
1.1       root      584:        break;
                    585:      case sz_long:
1.1.1.5   root      586:        strcpy (vstr, "((uae_s32)(");
                    587:        strcpy (usstr, "((uae_u32)(");
1.1       root      588:        break;
                    589:      default:
1.1.1.5   root      590:        abort ();
1.1       root      591:     }
1.1.1.5   root      592:     strcpy (unsstr, usstr);
1.1       root      593: 
1.1.1.5   root      594:     strcpy (sstr, vstr);
                    595:     strcpy (dstr, vstr);
                    596:     strcat (vstr, value);
                    597:     strcat (vstr, "))");
                    598:     strcat (dstr, dst);
                    599:     strcat (dstr, "))");
                    600:     strcat (sstr, src);
                    601:     strcat (sstr, "))");
                    602: 
                    603:     strcpy (udstr, usstr);
                    604:     strcat (udstr, dst);
                    605:     strcat (udstr, "))");
                    606:     strcat (usstr, src);
                    607:     strcat (usstr, "))");
                    608: 
                    609:     strcpy (undstr, unsstr);
                    610:     strcat (unsstr, "-");
                    611:     strcat (undstr, "~");
                    612:     strcat (undstr, dst);
                    613:     strcat (undstr, "))");
                    614:     strcat (unsstr, src);
                    615:     strcat (unsstr, "))");
1.1       root      616: 
                    617:     switch (type) {
                    618:      case flag_logical:
                    619:      case flag_zn:
                    620:      case flag_av:
                    621:      case flag_sv:
                    622:      case flag_addx:
                    623:      case flag_subx:
                    624:        break;
1.1.1.3   root      625: 
1.1       root      626:      case flag_add:
1.1.1.5   root      627:        start_brace ();
1.1.1.3   root      628:        printf ("uae_u32 %s = %s + %s;\n", value, dstr, sstr);
1.1       root      629:        break;
                    630:      case flag_sub:
                    631:      case flag_cmp:
1.1.1.5   root      632:        start_brace ();
1.1.1.3   root      633:        printf ("uae_u32 %s = %s - %s;\n", value, dstr, sstr);
1.1       root      634:        break;
                    635:     }
                    636: 
                    637: 
                    638:     switch (type) {
                    639:      case flag_logical:
                    640:      case flag_zn:
                    641:        break;
1.1.1.3   root      642: 
1.1       root      643:      case flag_add:
                    644:      case flag_sub:
                    645:      case flag_addx:
                    646:      case flag_subx:
                    647:      case flag_cmp:
                    648:      case flag_av:
                    649:      case flag_sv:
1.1.1.5   root      650:        start_brace ();
                    651:        printf ("\t" BOOL_TYPE " flgs = %s < 0;\n", sstr);
                    652:        printf ("\t" BOOL_TYPE " flgo = %s < 0;\n", dstr);
                    653:        printf ("\t" BOOL_TYPE " flgn = %s < 0;\n", vstr);
1.1       root      654:        break;
                    655:     }
1.1.1.3   root      656: 
1.1.1.5   root      657:     switch (type) {
1.1       root      658:      case flag_logical:
1.1.1.3   root      659:        printf ("\tVFLG = CFLG = 0;\n");
                    660:        printf ("\tZFLG = %s == 0;\n", vstr);
                    661:        printf ("\tNFLG = %s < 0;\n", vstr);
1.1       root      662:        break;
                    663:      case flag_av:
1.1.1.5   root      664:        printf ("\tVFLG = (flgs ^ flgn) & (flgo ^ flgn);\n");
1.1       root      665:        break;
                    666:      case flag_sv:
1.1.1.5   root      667:        printf ("\tVFLG = (flgs ^ flgo) & (flgn ^ flgo);\n");
1.1       root      668:        break;
                    669:      case flag_zn:
1.1.1.3   root      670:        printf ("\tif (%s != 0) ZFLG = 0;\n", vstr);
                    671:        printf ("\tNFLG = %s < 0;\n", vstr);
1.1       root      672:        break;
                    673:      case flag_add:
1.1.1.3   root      674:        printf ("\tZFLG = %s == 0;\n", vstr);
1.1.1.5   root      675:        printf ("\tVFLG = (flgs ^ flgn) & (flgo ^ flgn);\n");
1.1.1.3   root      676:        printf ("\tCFLG = XFLG = %s < %s;\n", undstr, usstr);
                    677:        printf ("\tNFLG = flgn != 0;\n");
1.1       root      678:        break;
                    679:      case flag_sub:
1.1.1.3   root      680:        printf ("\tZFLG = %s == 0;\n", vstr);
1.1.1.5   root      681:        printf ("\tVFLG = (flgs ^ flgo) & (flgn ^ flgo);\n");
1.1.1.3   root      682:        printf ("\tCFLG = XFLG = %s > %s;\n", usstr, udstr);
                    683:        printf ("\tNFLG = flgn != 0;\n");
1.1       root      684:        break;
                    685:      case flag_addx:
1.1.1.5   root      686: #if 0
                    687:        printf ("\tVFLG = (flgs && flgo && !flgn) || (!flgs && !flgo && flgn);\n"); /* minterm SON: 0x42 */
                    688:        printf ("\tXFLG = CFLG = (flgs && flgo) || (!flgn && (flgo || flgs));\n"); /* minterm SON: 0xD4 */
                    689: #else
                    690:        printf ("\tVFLG = (flgs ^ flgn) & (flgo ^ flgn);\n"); /* minterm SON: 0x42 */
                    691:        printf ("\tXFLG = CFLG = flgs ^ ((flgs ^ flgo) & (flgo ^ flgn));\n"); /* minterm SON: 0xD4 */
                    692: #endif
1.1       root      693:        break;
                    694:      case flag_subx:
1.1.1.5   root      695: #if 0
                    696:        printf ("\tVFLG = (!flgs && flgo && !flgn) || (flgs && !flgo && flgn);\n"); /* minterm SON: 0x24 */
                    697:        printf ("\tXFLG = CFLG = (flgs && !flgo) || (flgn && (!flgo || flgs));\n"); /* minterm SON: 0xB2 */
                    698: #else
                    699:        printf ("\tVFLG = (flgs ^ flgo) & (flgo ^ flgn);\n"); /* minterm SON: 0x24 */
                    700:        printf ("\tXFLG = CFLG = flgs ^ ((flgs ^ flgn) & (flgo ^ flgn));\n"); /* minterm SON: 0xB2 */
                    701: #endif
1.1       root      702:        break;
                    703:      case flag_cmp:
1.1.1.3   root      704:        printf ("\tZFLG = %s == 0;\n", vstr);
                    705:        printf ("\tVFLG = (flgs != flgo) && (flgn != flgo);\n");
                    706:        printf ("\tCFLG = %s > %s;\n", usstr, udstr);
                    707:        printf ("\tNFLG = flgn != 0;\n");
1.1       root      708:        break;
                    709:     }
                    710: }
                    711: 
1.1.1.5   root      712: static void genflags (flagtypes type, wordsizes size, char *value, char *src, char *dst)
1.1       root      713: {
1.1.1.3   root      714: #ifdef X86_ASSEMBLY
1.1.1.5   root      715:     start_brace ();
1.1.1.3   root      716:     printf ("\tuae_u32 scratch;\n");
1.1       root      717:     switch (type) {
1.1.1.5   root      718:      case flag_add:
                    719:      case flag_sub:
                    720:        start_brace ();
1.1.1.3   root      721:        printf ("\tuae_u32 %s;\n", value);
1.1       root      722:        break;
                    723: 
1.1.1.3   root      724:      default:
1.1       root      725:        break;
                    726:     }
                    727: 
1.1.1.3   root      728:     /* At least some of those casts are fairly important! */
1.1.1.5   root      729:     switch (type) {
1.1       root      730:      case flag_logical:
1.1.1.5   root      731:        if (strcmp (value, "0") == 0) {
1.1.1.3   root      732:            printf ("\t*(uae_u32 *)&regflags = 64;\n");
1.1       root      733:        } else {
1.1.1.5   root      734:            switch (size) {
1.1.1.3   root      735:             case sz_byte: printf ("\tx86_flag_testb ((uae_s8)(%s));\n", value); break;
                    736:             case sz_word: printf ("\tx86_flag_testw ((uae_s16)(%s));\n", value); break;
                    737:             case sz_long: printf ("\tx86_flag_testl ((uae_s32)(%s));\n", value); break;
1.1       root      738:            }
                    739:        }
                    740:        return;
                    741: 
                    742:      case flag_add:
1.1.1.5   root      743:        switch (size) {
1.1.1.3   root      744:         case sz_byte: printf ("\tx86_flag_addb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
                    745:         case sz_word: printf ("\tx86_flag_addw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
                    746:         case sz_long: printf ("\tx86_flag_addl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
1.1       root      747:        }
                    748:        return;
                    749: 
                    750:      case flag_sub:
1.1.1.5   root      751:        switch (size) {
1.1.1.3   root      752:         case sz_byte: printf ("\tx86_flag_subb (%s, (uae_s8)(%s), (uae_s8)(%s));\n", value, src, dst); break;
                    753:         case sz_word: printf ("\tx86_flag_subw (%s, (uae_s16)(%s), (uae_s16)(%s));\n", value, src, dst); break;
                    754:         case sz_long: printf ("\tx86_flag_subl (%s, (uae_s32)(%s), (uae_s32)(%s));\n", value, src, dst); break;
1.1       root      755:        }
                    756:        return;
                    757: 
                    758:      case flag_cmp:
1.1.1.5   root      759:        switch (size) {
1.1.1.3   root      760:         case sz_byte: printf ("\tx86_flag_cmpb ((uae_s8)(%s), (uae_s8)(%s));\n", src, dst); break;
                    761:         case sz_word: printf ("\tx86_flag_cmpw ((uae_s16)(%s), (uae_s16)(%s));\n", src, dst); break;
                    762:         case sz_long: printf ("\tx86_flag_cmpl ((uae_s32)(%s), (uae_s32)(%s));\n", src, dst); break;
1.1       root      763:        }
                    764:        return;
1.1.1.5   root      765:        
1.1.1.3   root      766:      default:
                    767:        break;
1.1       root      768:     }
1.1.1.2   root      769: #elif defined(M68K_FLAG_OPT)
1.1.1.3   root      770:     /* sam: here I'm cloning what X86_ASSEMBLY does */
                    771: #define EXT(size)  (size==sz_byte?"b":(size==sz_word?"w":"l"))
                    772: #define CAST(size) (size==sz_byte?"uae_s8":(size==sz_word?"uae_s16":"uae_s32"))
1.1.1.2   root      773:     switch (type) {
1.1.1.5   root      774:      case flag_add:
                    775:      case flag_sub:
                    776:        start_brace ();
1.1.1.3   root      777:        printf ("\tuae_u32 %s;\n", value);
1.1.1.2   root      778:        break;
                    779: 
1.1.1.3   root      780:      default:
1.1.1.2   root      781:        break;
                    782:     }
                    783: 
1.1.1.5   root      784:     switch (type) {
1.1.1.2   root      785:      case flag_logical:
1.1.1.5   root      786:        if (strcmp (value, "0") == 0) {
                    787:            printf ("\t*(uae_u16 *)&regflags = 4;\n");  /* Z = 1 */
1.1.1.2   root      788:        } else {
1.1.1.5   root      789:            printf ("\tm68k_flag_tst (%s, (%s)(%s));\n",
                    790:                    EXT (size), CAST (size), value);
1.1.1.2   root      791:        }
                    792:        return;
                    793: 
                    794:      case flag_add:
1.1.1.3   root      795:        printf ("\t{uae_u16 ccr;\n");
1.1.1.5   root      796:        printf ("\tm68k_flag_add (%s, (%s)%s, (%s)(%s), (%s)(%s));\n",
                    797:                EXT (size), CAST (size), value, CAST (size), src, CAST (size), dst);
1.1.1.3   root      798:        printf ("\t((uae_u16*)&regflags)[1]=((uae_u16*)&regflags)[0]=ccr;}\n");
1.1.1.2   root      799:        return;
                    800: 
                    801:      case flag_sub:
1.1.1.3   root      802:        printf ("\t{uae_u16 ccr;\n");
1.1.1.5   root      803:        printf ("\tm68k_flag_sub (%s, (%s)%s, (%s)(%s), (%s)(%s));\n",
                    804:                EXT (size), CAST (size), value, CAST (size), src, CAST (size), dst);
1.1.1.3   root      805:        printf ("\t((uae_u16*)&regflags)[1]=((uae_u16*)&regflags)[0]=ccr;}\n");
1.1.1.2   root      806:        return;
                    807: 
                    808:      case flag_cmp:
1.1.1.5   root      809:        printf ("\tm68k_flag_cmp (%s, (%s)(%s), (%s)(%s));\n",
                    810:                EXT (size), CAST (size), src, CAST (size), dst);
1.1.1.2   root      811:        return;
1.1.1.3   root      812: 
                    813:      default:
                    814:        break;
1.1.1.2   root      815:     }
1.1.1.3   root      816: #elif defined(ACORN_FLAG_OPT) && defined(__GNUC_MINOR__)
                    817: /*
                    818:  * This is new. Might be quite buggy.
                    819:  */
1.1.1.5   root      820:     switch (type) {
                    821:      case flag_av:
                    822:      case flag_sv:
                    823:      case flag_zn:
                    824:      case flag_addx:
                    825:      case flag_subx:
                    826:        break;
                    827: 
                    828:      case flag_logical:
                    829:        if (strcmp (value, "0") == 0) {
                    830:            /* v=c=n=0 z=1 */
                    831:            printf ("\t*(ULONG*)&regflags = 0x40000000;\n");
1.1.1.3   root      832:            return;
1.1.1.5   root      833:        } else {
                    834:            start_brace ();
                    835:            switch (size) {
                    836:             case sz_byte:
                    837:                printf ("\tUBYTE ccr;\n");
                    838:                printf ("\tULONG shift;\n");
                    839:                printf ("\t__asm__(\"mov %%2,%%1,lsl#24\n\ttst %%2,%%2\n\tmov %%0,r15,lsr#24\n\tbic %%0,%%0,#0x30\"\n"
                    840:                        "\t: \"=r\" (ccr) : \"r\" (%s), \"r\" (shift) : \"cc\" );\n", value);
                    841:                printf ("\t*((UBYTE*)&regflags+3) = ccr;\n");
                    842:                return;
                    843:             case sz_word:
                    844:                printf ("\tUBYTE ccr;\n");
                    845:                printf ("\tULONG shift;\n");
                    846:                printf ("\t__asm__(\"mov %%2,%%1,lsl#16\n\ttst %%2,%%2\n\tmov %%0,r15,lsr#24\n\tbic %%0,%%0,#0x30\"\n"
                    847:                        "\t: \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", value);
                    848:                printf ("\t*((UBYTE*)&regflags+3) = ccr;\n");
                    849:                return;
                    850:             case sz_long:
                    851:                printf ("\tUBYTE ccr;\n");
                    852:                printf ("\t__asm__(\"tst %%1,%%1\n\tmov %%0,r15,lsr#24\n\tbic %%0,%%0,#0x30\"\n"
                    853:                        "\t: \"=r\" (ccr) : \"r\" ((LONG)%s) : \"cc\" );\n", value);
                    854:                printf ("\t*((UBYTE*)&regflags+3) = ccr;\n");
                    855:                return;
                    856:            }
1.1.1.3   root      857:        }
1.1.1.5   root      858:        break;
                    859:      case flag_add:
                    860:        if (strcmp (dst, "0") == 0) {
                    861:            printf ("/* Error! Hier muss Peter noch was machen !!! (ADD-Flags) */");
                    862:        } else {
                    863:            start_brace ();
                    864:            switch (size) {
                    865:             case sz_byte:
                    866:                printf ("\tULONG ccr, shift, %s;\n", value);
                    867:                printf ("\t__asm__(\"mov %%4,%%3,lsl#24\n\tadds %%0,%%4,%%2,lsl#24\n\tmov %%0,%%0,asr#24\n\tmov %%1,r15\n\torr %%1,%%1,%%1,lsr#29\"\n"
                    868:                        "\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" (%s), \"r\" (%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
                    869:                printf ("\t*(ULONG*)&regflags = ccr;\n");
                    870:                return;
                    871:             case sz_word:
                    872:                printf ("\tULONG ccr, shift, %s;\n", value);
                    873:                printf ("\t__asm__(\"mov %%4,%%3,lsl#16\n\tadds %%0,%%4,%%2,lsl#16\n\tmov %%0,%%0,asr#16\n\tmov %%1,r15\n\torr %%1,%%1,%%1,lsr#29\"\n"
                    874:                        "\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
                    875:                printf ("\t*(ULONG*)&regflags = ccr;\n");
                    876:                return;
                    877:             case sz_long:
                    878:                printf ("\tULONG ccr, %s;\n", value);
                    879:                printf ("\t__asm__(\"adds %%0,%%3,%%2\n\tmov %%1,r15\n\torr %%1,%%1,%%1,lsr#29\"\n"
                    880:                        "\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((LONG)%s), \"r\" ((LONG)%s) : \"cc\" );\n", value, src, dst);
                    881:                printf ("\t*(ULONG*)&regflags = ccr;\n");
                    882:                return;
                    883:            }
1.1.1.3   root      884:        }
1.1.1.5   root      885:        break;
                    886:      case flag_sub:
                    887:        if (strcmp (dst, "0") == 0) {
                    888:            printf ("/* Error! Hier muss Peter noch was machen !!! (SUB-Flags) */");
                    889:        } else {
                    890:            start_brace ();
                    891:            switch (size) {
                    892:             case sz_byte:
                    893:                printf ("\tULONG ccr, shift, %s;\n", value);
                    894:                printf ("\t__asm__(\"mov %%4,%%3,lsl#24\n\tsubs %%0,%%4,%%2,lsl#24\n\tmov %%0,%%0,asr#24\n\tmov %%1,r15\n\teor %%1,%%1,#0x20000000\n\torr %%1,%%1,%%1,lsr#29\"\n"
                    895:                        "\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" (%s), \"r\" (%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
                    896:                printf ("\t*(ULONG*)&regflags = ccr;\n");
                    897:                return;
                    898:             case sz_word:
                    899:                printf ("\tULONG ccr, shift, %s;\n", value);
                    900:                printf ("\t__asm__(\"mov %%4,%%3,lsl#16\n\tsubs %%0,%%4,%%2,lsl#16\n\tmov %%0,%%0,asr#16\n\tmov %%1,r15\n\teor %%1,%%1,#0x20000000\n\torr %%1,%%1,%%1,lsr#29\"\n"
                    901:                        "\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", value, src, dst);
                    902:                printf ("\t*(ULONG*)&regflags = ccr;\n");
                    903:                return;
                    904:             case sz_long:
                    905:                printf ("\tULONG ccr, %s;\n", value);
                    906:                printf ("\t__asm__(\"subs %%0,%%3,%%2\n\tmov %%1,r15\n\teor %%1,%%1,#0x20000000\n\torr %%1,%%1,%%1,lsr#29\"\n"
                    907:                        "\t: \"=r\" (%s), \"=r\" (ccr) : \"r\" ((LONG)%s), \"r\" ((LONG)%s) : \"cc\" );\n", value, src, dst);
                    908:                printf ("\t*(ULONG*)&regflags = ccr;\n");
                    909:                return;
                    910:            }
1.1.1.3   root      911:        }
1.1.1.5   root      912:        break;
                    913:      case flag_cmp:
                    914:        if (strcmp (dst, "0") == 0) {
                    915:            printf ("/*Error! Hier muss Peter noch was machen !!! (CMP-Flags)*/");
                    916:        } else {
                    917:            start_brace ();
                    918:            switch (size) {
                    919:             case sz_byte:
                    920:                printf ("\tULONG shift, ccr;\n");
                    921:                printf ("\t__asm__(\"mov %%3,%%2,lsl#24\n\tcmp %%3,%%1,lsl#24\n\tmov %%0,r15,lsr#24\n\teor %%0,%%0,#0x20\"\n"
                    922:                        "\t: \"=r\" (ccr) : \"r\" (%s), \"r\" (%s), \"r\" (shift) : \"cc\" );\n", src, dst);
                    923:                printf ("\t*((UBYTE*)&regflags+3) = ccr;\n");
                    924:                return;
                    925:             case sz_word:
                    926:                printf ("\tULONG shift, ccr;\n");
                    927:                printf ("\t__asm__(\"mov %%3,%%2,lsl#16\n\tcmp %%3,%%1,lsl#16\n\tmov %%0,r15,lsr#24\n\teor %%0,%%0,#0x20\"\n"
                    928:                        "\t: \"=r\" (ccr) : \"r\" ((WORD)%s), \"r\" ((WORD)%s), \"r\" (shift) : \"cc\" );\n", src, dst);
                    929:                printf ("\t*((UBYTE*)&regflags+3) = ccr;\n");
                    930:                return;
                    931:             case sz_long:
                    932:                printf ("\tULONG ccr;\n");
                    933:                printf ("\t__asm__(\"cmp %%2,%%1\n\tmov %%0,r15,lsr#24\n\teor %%0,%%0,#0x20\"\n"
                    934:                        "\t: \"=r\" (ccr) : \"r\" ((LONG)%s), \"r\" ((LONG)%s) : \"cc\" );\n", src, dst);
                    935:                printf ("\t*((UBYTE*)&regflags+3) = ccr;\n");
                    936:                /*printf ("\tprintf (\"%%08x %%08x %%08x\\n\", %s, %s, *((ULONG*)&regflags));\n", src, dst); */
                    937:                return;
                    938:            }
                    939:        }
                    940:        break;
                    941:     }
1.1       root      942: #endif
1.1.1.5   root      943:     genflags_normal (type, size, value, src, dst);
1.1       root      944: }
1.1.1.3   root      945: 
1.1.1.5   root      946: static void gen_opcode (unsigned long int opcode)
1.1       root      947: {
1.1.1.5   root      948:     insn_n_cycles = 2;
                    949: 
1.1       root      950:     start_brace ();
1.1.1.3   root      951: #if 0
                    952:     printf ("uae_u8 *m68k_pc = regs.pc_p;\n");
                    953: #endif
                    954:     m68k_pc_offset = 2;
1.1       root      955:     switch (table68k[opcode].plev) {
1.1.1.3   root      956:      case 0: /* not privileged */
1.1       root      957:        break;
1.1.1.3   root      958:      case 1: /* unprivileged only on 68000 */
                    959:        if (cpu_level == 0)
1.1       root      960:            break;
1.1.1.3   root      961:        if (next_cpu_level < 0)
                    962:            next_cpu_level = 0;
                    963: 
1.1.1.5   root      964:        /* fall through */
1.1       root      965:      case 2: /* priviledged */
1.1.1.3   root      966:        printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr);
1.1.1.5   root      967:        need_endlabel = 1;
                    968:        start_brace ();
1.1       root      969:        break;
1.1.1.3   root      970:      case 3: /* privileged if size == word */
1.1       root      971:        if (table68k[opcode].size == sz_byte)
                    972:            break;
1.1.1.3   root      973:        printf ("if (!regs.s) { Exception(8,0); goto %s; }\n", endlabelstr);
1.1.1.5   root      974:        need_endlabel = 1;
                    975:        start_brace ();
1.1       root      976:        break;
                    977:     }
1.1.1.5   root      978:     switch (table68k[opcode].mnemo) {
1.1       root      979:      case i_OR:
1.1.1.3   root      980:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                    981:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
                    982:        printf ("\tsrc |= dst;\n");
1.1.1.5   root      983:        genflags (flag_logical, table68k[opcode].size, "src", "", "");
1.1.1.3   root      984:        genastore ("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      985:        break;
                    986:      case i_AND:
1.1.1.3   root      987:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                    988:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
                    989:        printf ("\tsrc &= dst;\n");
1.1.1.5   root      990:        genflags (flag_logical, table68k[opcode].size, "src", "", "");
1.1.1.3   root      991:        genastore ("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      992:        break;
                    993:      case i_EOR:
1.1.1.3   root      994:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                    995:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
                    996:        printf ("\tsrc ^= dst;\n");
1.1.1.5   root      997:        genflags (flag_logical, table68k[opcode].size, "src", "", "");
1.1.1.3   root      998:        genastore ("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root      999:        break;
                   1000:      case i_ORSR:
1.1.1.3   root     1001:        printf ("\tMakeSR();\n");
                   1002:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1003:        if (table68k[opcode].size == sz_byte) {
1.1.1.3   root     1004:            printf ("\tsrc &= 0xFF;\n");
1.1       root     1005:        }
1.1.1.3   root     1006:        printf ("\tregs.sr |= src;\n");
                   1007:        printf ("\tMakeFromSR();\n");
1.1       root     1008:        break;
1.1.1.3   root     1009:      case i_ANDSR:
                   1010:        printf ("\tMakeSR();\n");
                   1011:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1012:        if (table68k[opcode].size == sz_byte) {
1.1.1.3   root     1013:            printf ("\tsrc |= 0xFF00;\n");
1.1       root     1014:        }
1.1.1.3   root     1015:        printf ("\tregs.sr &= src;\n");
                   1016:        printf ("\tMakeFromSR();\n");
1.1       root     1017:        break;
                   1018:      case i_EORSR:
1.1.1.3   root     1019:        printf ("\tMakeSR();\n");
                   1020:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1021:        if (table68k[opcode].size == sz_byte) {
1.1.1.3   root     1022:            printf ("\tsrc &= 0xFF;\n");
1.1       root     1023:        }
1.1.1.3   root     1024:        printf ("\tregs.sr ^= src;\n");
                   1025:        printf ("\tMakeFromSR();\n");
1.1       root     1026:        break;
1.1.1.3   root     1027:      case i_SUB:
                   1028:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1029:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1030:        start_brace ();
1.1.1.5   root     1031:        genflags (flag_sub, table68k[opcode].size, "newv", "src", "dst");
1.1.1.3   root     1032:        genastore ("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1033:        break;
                   1034:      case i_SUBA:
1.1.1.3   root     1035:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1036:        genamode (table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root     1037:        start_brace ();
1.1.1.3   root     1038:        printf ("\tuae_u32 newv = dst - src;\n");
                   1039:        genastore ("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root     1040:        break;
                   1041:      case i_SUBX:
1.1.1.3   root     1042:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1043:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1044:        start_brace ();
1.1.1.3   root     1045:        printf ("\tuae_u32 newv = dst - src - (XFLG ? 1 : 0);\n");
1.1.1.5   root     1046:        genflags (flag_subx, table68k[opcode].size, "newv", "src", "dst");
                   1047:        genflags (flag_zn, table68k[opcode].size, "newv", "", "");
1.1.1.3   root     1048:        genastore ("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1049:        break;
                   1050:      case i_SBCD:
                   1051:        /* Let's hope this works... */
1.1.1.3   root     1052:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1053:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1054:        start_brace ();
1.1.1.3   root     1055:        printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (XFLG ? 1 : 0);\n");
                   1056:        printf ("\tuae_u16 newv_hi = (dst & 0xF0) - (src & 0xF0);\n");
                   1057:        printf ("\tuae_u16 newv;\n");
                   1058:        printf ("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n");
                   1059:        printf ("\tnewv = newv_hi + (newv_lo & 0xF);");
                   1060:        printf ("\tCFLG = XFLG = (newv_hi & 0x1F0) > 0x90;\n");
                   1061:        printf ("\tif (CFLG) newv -= 0x60;\n");
1.1.1.5   root     1062:        genflags (flag_zn, table68k[opcode].size, "newv", "", "");
                   1063:        genflags (flag_sv, table68k[opcode].size, "newv", "src", "dst");
1.1.1.3   root     1064:        genastore ("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1065:        break;
                   1066:      case i_ADD:
1.1.1.3   root     1067:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1068:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1069:        start_brace ();
1.1.1.5   root     1070:        genflags (flag_add, table68k[opcode].size, "newv", "src", "dst");
1.1.1.3   root     1071:        genastore ("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1072:        break;
1.1.1.3   root     1073:      case i_ADDA:
                   1074:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1075:        genamode (table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root     1076:        start_brace ();
1.1.1.3   root     1077:        printf ("\tuae_u32 newv = dst + src;\n");
                   1078:        genastore ("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root     1079:        break;
                   1080:      case i_ADDX:
1.1.1.3   root     1081:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1082:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1083:        start_brace ();
1.1.1.3   root     1084:        printf ("\tuae_u32 newv = dst + src + (XFLG ? 1 : 0);\n");
1.1.1.5   root     1085:        genflags (flag_addx, table68k[opcode].size, "newv", "src", "dst");
                   1086:        genflags (flag_zn, table68k[opcode].size, "newv", "", "");
1.1.1.3   root     1087:        genastore ("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1088:        break;
                   1089:      case i_ABCD:
1.1.1.3   root     1090:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1091:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1092:        start_brace ();
1.1.1.3   root     1093:        printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (XFLG ? 1 : 0);\n");
                   1094:        printf ("\tuae_u16 newv_hi = (src & 0xF0) + (dst & 0xF0);\n");
                   1095:        printf ("\tuae_u16 newv;\n");
                   1096:        printf ("\tif (newv_lo > 9) { newv_lo +=6; }\n");
                   1097:        printf ("\tnewv = newv_hi + newv_lo;");
                   1098:        printf ("\tCFLG = XFLG = (newv & 0x1F0) > 0x90;\n");
                   1099:        printf ("\tif (CFLG) newv += 0x60;\n");
1.1.1.5   root     1100:        genflags (flag_zn, table68k[opcode].size, "newv", "", "");
                   1101:        genflags (flag_sv, table68k[opcode].size, "newv", "src", "dst");
1.1.1.3   root     1102:        genastore ("newv", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1103:        break;
                   1104:      case i_NEG:
1.1.1.3   root     1105:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1106:        start_brace ();
1.1.1.5   root     1107:        genflags (flag_sub, table68k[opcode].size, "dst", "src", "0");
                   1108:        genastore ("dst", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1109:        break;
                   1110:      case i_NEGX:
1.1.1.3   root     1111:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1112:        start_brace ();
1.1.1.3   root     1113:        printf ("\tuae_u32 newv = 0 - src - (XFLG ? 1 : 0);\n");
1.1.1.5   root     1114:        genflags (flag_subx, table68k[opcode].size, "newv", "src", "0");
                   1115:        genflags (flag_zn, table68k[opcode].size, "newv", "", "");
1.1.1.3   root     1116:        genastore ("newv", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1117:        break;
1.1.1.3   root     1118:      case i_NBCD:
                   1119:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1120:        start_brace ();
1.1.1.3   root     1121:        printf ("\tuae_u16 newv_lo = - (src & 0xF) - (XFLG ? 1 : 0);\n");
                   1122:        printf ("\tuae_u16 newv_hi = - (src & 0xF0);\n");
                   1123:        printf ("\tuae_u16 newv;\n");
                   1124:        printf ("\tif (newv_lo > 9) { newv_lo-=6; newv_hi-=0x10; }\n");
                   1125:        printf ("\tnewv = newv_hi + (newv_lo & 0xF);");
                   1126:        printf ("\tCFLG = XFLG = (newv_hi & 0x1F0) > 0x90;\n");
                   1127:        printf ("\tif (CFLG) newv -= 0x60;\n");
1.1.1.5   root     1128:        genflags (flag_zn, table68k[opcode].size, "newv", "", "");
1.1.1.3   root     1129:        genastore ("newv", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1130:        break;
1.1.1.3   root     1131:      case i_CLR:
                   1132:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 2, 0);
1.1.1.5   root     1133:        genflags (flag_logical, table68k[opcode].size, "0", "", "");
                   1134:        genastore ("0", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1135:        break;
1.1.1.3   root     1136:      case i_NOT:
                   1137:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1       root     1138:        start_brace ();
1.1.1.3   root     1139:        printf ("\tuae_u32 dst = ~src;\n");
1.1.1.5   root     1140:        genflags (flag_logical, table68k[opcode].size, "dst", "", "");
                   1141:        genastore ("dst", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1142:        break;
                   1143:      case i_TST:
1.1.1.3   root     1144:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1.1.5   root     1145:        genflags (flag_logical, table68k[opcode].size, "src", "", "");
1.1       root     1146:        break;
                   1147:      case i_BTST:
1.1.1.3   root     1148:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1149:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1150:        if (table68k[opcode].size == sz_byte)
1.1.1.3   root     1151:            printf ("\tsrc &= 7;\n");
1.1       root     1152:        else
1.1.1.3   root     1153:            printf ("\tsrc &= 31;\n");
                   1154:        printf ("\tZFLG = !(dst & (1 << src));\n");
1.1       root     1155:        break;
                   1156:      case i_BCHG:
1.1.1.3   root     1157:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1158:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1159:        if (table68k[opcode].size == sz_byte)
1.1.1.3   root     1160:            printf ("\tsrc &= 7;\n");
1.1       root     1161:        else
1.1.1.3   root     1162:            printf ("\tsrc &= 31;\n");
                   1163:        printf ("\tZFLG = !(dst & (1 << src));\n");
                   1164:        printf ("\tdst ^= (1 << src);\n");
                   1165:        genastore ("dst", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1166:        break;
                   1167:      case i_BCLR:
1.1.1.3   root     1168:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1169:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1170:        if (table68k[opcode].size == sz_byte)
1.1.1.3   root     1171:            printf ("\tsrc &= 7;\n");
1.1       root     1172:        else
1.1.1.3   root     1173:            printf ("\tsrc &= 31;\n");
                   1174:        printf ("\tZFLG = !(dst & (1 << src));\n");
                   1175:        printf ("\tdst &= ~(1 << src);\n");
                   1176:        genastore ("dst", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1177:        break;
                   1178:      case i_BSET:
1.1.1.3   root     1179:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1180:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1181:        if (table68k[opcode].size == sz_byte)
1.1.1.3   root     1182:            printf ("\tsrc &= 7;\n");
1.1       root     1183:        else
1.1.1.3   root     1184:            printf ("\tsrc &= 31;\n");
                   1185:        printf ("\tZFLG = !(dst & (1 << src));\n");
                   1186:        printf ("\tdst |= (1 << src);\n");
                   1187:        genastore ("dst", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1188:        break;
                   1189:      case i_CMPM:
                   1190:      case i_CMP:
1.1.1.3   root     1191:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1192:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1       root     1193:        start_brace ();
1.1.1.5   root     1194:        genflags (flag_cmp, table68k[opcode].size, "newv", "src", "dst");
1.1       root     1195:        break;
1.1.1.3   root     1196:      case i_CMPA:
                   1197:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1198:        genamode (table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
1.1       root     1199:        start_brace ();
1.1.1.5   root     1200:        genflags (flag_cmp, sz_long, "newv", "src", "dst");
1.1       root     1201:        break;
                   1202:        /* The next two are coded a little unconventional, but they are doing
                   1203:         * weird things... */
                   1204:      case i_MVPRM:
1.1.1.3   root     1205:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1.1.5   root     1206: 
                   1207:        printf ("\tuaecptr memp = m68k_areg(regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword ());
1.1       root     1208:        if (table68k[opcode].size == sz_word) {
1.1.1.3   root     1209:            printf ("\tput_byte(memp, src >> 8); put_byte(memp + 2, src);\n");
1.1       root     1210:        } else {
1.1.1.3   root     1211:            printf ("\tput_byte(memp, src >> 24); put_byte(memp + 2, src >> 16);\n");
                   1212:            printf ("\tput_byte(memp + 4, src >> 8); put_byte(memp + 6, src);\n");
1.1       root     1213:        }
                   1214:        break;
1.1.1.3   root     1215:      case i_MVPMR:
1.1.1.5   root     1216:        printf ("\tuaecptr memp = m68k_areg(regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword ());
1.1.1.3   root     1217:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 2, 0);
1.1       root     1218:        if (table68k[opcode].size == sz_word) {
1.1.1.3   root     1219:            printf ("\tuae_u16 val = (get_byte(memp) << 8) + get_byte(memp + 2);\n");
1.1       root     1220:        } else {
1.1.1.3   root     1221:            printf ("\tuae_u32 val = (get_byte(memp) << 24) + (get_byte(memp + 2) << 16)\n");
                   1222:            printf ("              + (get_byte(memp + 4) << 8) + get_byte(memp + 6);\n");
1.1       root     1223:        }
1.1.1.3   root     1224:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1225:        break;
                   1226:      case i_MOVE:
1.1.1.3   root     1227:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1228:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 2, 0);
1.1.1.5   root     1229:        genflags (flag_logical, table68k[opcode].size, "src", "", "");
1.1.1.3   root     1230:        genastore ("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1231:        break;
                   1232:      case i_MOVEA:
1.1.1.3   root     1233:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1234:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 2, 0);
1.1       root     1235:        if (table68k[opcode].size == sz_word) {
1.1.1.3   root     1236:            printf ("\tuae_u32 val = (uae_s32)(uae_s16)src;\n");
1.1       root     1237:        } else {
1.1.1.3   root     1238:            printf ("\tuae_u32 val = src;\n");
1.1       root     1239:        }
1.1.1.3   root     1240:        genastore ("val", table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1       root     1241:        break;
1.1.1.3   root     1242:      case i_MVSR2:
                   1243:        genamode (table68k[opcode].smode, "srcreg", sz_word, "src", 2, 0);
                   1244:        printf ("\tMakeSR();\n");
1.1       root     1245:        if (table68k[opcode].size == sz_byte)
1.1.1.3   root     1246:            genastore ("regs.sr & 0xff", table68k[opcode].smode, "srcreg", sz_word, "src");
1.1       root     1247:        else
1.1.1.3   root     1248:            genastore ("regs.sr", table68k[opcode].smode, "srcreg", sz_word, "src");
1.1       root     1249:        break;
                   1250:      case i_MV2SR:
1.1.1.3   root     1251:        genamode (table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
1.1       root     1252:        if (table68k[opcode].size == sz_byte)
1.1.1.3   root     1253:            printf ("\tMakeSR();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
                   1254:        else {
                   1255:            printf ("\tregs.sr = src;\n");
1.1       root     1256:        }
1.1.1.3   root     1257:        printf ("\tMakeFromSR();\n");
1.1       root     1258:        break;
1.1.1.3   root     1259:      case i_SWAP:
                   1260:        genamode (table68k[opcode].smode, "srcreg", sz_long, "src", 1, 0);
1.1       root     1261:        start_brace ();
1.1.1.3   root     1262:        printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
1.1.1.5   root     1263:        genflags (flag_logical, sz_long, "dst", "", "");
                   1264:        genastore ("dst", table68k[opcode].smode, "srcreg", sz_long, "src");
1.1       root     1265:        break;
                   1266:      case i_EXG:
1.1.1.3   root     1267:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1268:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1.1.5   root     1269:        genastore ("dst", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
                   1270:        genastore ("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1271:        break;
                   1272:      case i_EXT:
1.1.1.3   root     1273:        genamode (table68k[opcode].smode, "srcreg", sz_long, "src", 1, 0);
1.1       root     1274:        start_brace ();
1.1.1.5   root     1275:        switch (table68k[opcode].size) {
1.1.1.3   root     1276:         case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break;
                   1277:         case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break;
                   1278:         case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break;
1.1.1.5   root     1279:         default: abort ();
1.1       root     1280:        }
1.1.1.5   root     1281:        genflags (flag_logical,
                   1282:                  table68k[opcode].size == sz_word ? sz_word : sz_long, "dst", "", "");
                   1283:        genastore ("dst", table68k[opcode].smode, "srcreg",
                   1284:            table68k[opcode].size == sz_word ? sz_word : sz_long, "src");
1.1       root     1285:        break;
                   1286:      case i_MVMEL:
1.1.1.5   root     1287:        genmovemel (opcode);
1.1       root     1288:        break;
                   1289:      case i_MVMLE:
1.1.1.5   root     1290:        genmovemle (opcode);
1.1       root     1291:        break;
                   1292:      case i_TRAP:
1.1.1.3   root     1293:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1.1.5   root     1294:        sync_m68k_pc ();
1.1.1.3   root     1295:        printf ("\tException(src+32,0);\n");
                   1296:        m68k_pc_offset = 0;
1.1       root     1297:        break;
                   1298:      case i_MVR2USP:
1.1.1.3   root     1299:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1300:        printf ("\tregs.usp = src;\n");
1.1       root     1301:        break;
1.1.1.3   root     1302:      case i_MVUSP2R:
                   1303:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 2, 0);
                   1304:        genastore ("regs.usp", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1305:        break;
                   1306:      case i_RESET:
1.1.1.3   root     1307:        printf ("\tcustomreset();\n");
1.1       root     1308:        break;
                   1309:      case i_NOP:
                   1310:        break;
                   1311:      case i_STOP:
1.1.1.3   root     1312:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1313:        printf ("\tregs.sr = src;\n");
                   1314:        printf ("\tMakeFromSR();\n");
                   1315:        printf ("\tm68k_setstopped(1);\n");
1.1       root     1316:        break;
                   1317:      case i_RTE:
1.1.1.3   root     1318:        if (cpu_level == 0) {
                   1319:            genamode (Aipi, "7", sz_word, "sr", 1, 0);
                   1320:            genamode (Aipi, "7", sz_long, "pc", 1, 0);
                   1321:            printf ("\tregs.sr = sr; m68k_setpc_rte(pc);\n");
                   1322:            fill_prefetch_0 ();
                   1323:            printf ("\tMakeFromSR();\n");
                   1324:        } else {
1.1       root     1325:            int old_brace_level = n_braces;
1.1.1.3   root     1326:            if (next_cpu_level < 0)
                   1327:                next_cpu_level = 0;
                   1328:            printf ("\tuae_u16 newsr; uae_u32 newpc; for (;;) {\n");
                   1329:            genamode (Aipi, "7", sz_word, "sr", 1, 0);
                   1330:            genamode (Aipi, "7", sz_long, "pc", 1, 0);
                   1331:            genamode (Aipi, "7", sz_word, "format", 1, 0);
                   1332:            printf ("\tnewsr = sr; newpc = pc;\n");
                   1333:            printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n");
                   1334:            printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n");
                   1335:            printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }\n");
                   1336:            printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }\n");
                   1337:            printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }\n");
                   1338:            printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }\n");
                   1339:            printf ("\telse if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; }\n");
                   1340:            printf ("\telse { Exception(14,0); goto %s; }\n", endlabelstr);
                   1341:            printf ("\tregs.sr = newsr; MakeFromSR();\n}\n");
1.1       root     1342:            pop_braces (old_brace_level);
1.1.1.3   root     1343:            printf ("\tregs.sr = newsr; MakeFromSR();\n");
                   1344:            printf ("\tm68k_setpc_rte(newpc);\n");
                   1345:            fill_prefetch_0 ();
1.1.1.5   root     1346:            need_endlabel = 1;
1.1       root     1347:        }
1.1.1.3   root     1348:        /* PC is set and prefetch filled. */
                   1349:        m68k_pc_offset = 0;
1.1       root     1350:        break;
                   1351:      case i_RTD:
1.1.1.3   root     1352:        printf ("\tcompiler_flush_jsr_stack();\n");
                   1353:        genamode (Aipi, "7", sz_long, "pc", 1, 0);
                   1354:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "offs", 1, 0);
                   1355:        printf ("\tm68k_areg(regs, 7) += offs;\n");
                   1356:        printf ("\tm68k_setpc_rte(pc);\n");
                   1357:        fill_prefetch_0 ();
                   1358:        /* PC is set and prefetch filled. */
                   1359:        m68k_pc_offset = 0;
1.1       root     1360:        break;
                   1361:      case i_LINK:
1.1.1.3   root     1362:        genamode (Apdi, "7", sz_long, "old", 2, 0);
                   1363:        genamode (table68k[opcode].smode, "srcreg", sz_long, "src", 1, 0);
                   1364:        genastore ("src", Apdi, "7", sz_long, "old");
                   1365:        genastore ("m68k_areg(regs, 7)", table68k[opcode].smode, "srcreg", sz_long, "src");
                   1366:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "offs", 1, 0);
                   1367:        printf ("\tm68k_areg(regs, 7) += offs;\n");
1.1       root     1368:        break;
                   1369:      case i_UNLK:
1.1.1.3   root     1370:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1371:        printf ("\tm68k_areg(regs, 7) = src;\n");
                   1372:        genamode (Aipi, "7", sz_long, "old", 1, 0);
                   1373:        genastore ("old", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1374:        break;
                   1375:      case i_RTS:
1.1.1.3   root     1376:        printf ("\tm68k_do_rts();\n");
                   1377:        fill_prefetch_0 ();
                   1378:        m68k_pc_offset = 0;
1.1       root     1379:        break;
                   1380:      case i_TRAPV:
1.1.1.3   root     1381:        sync_m68k_pc ();
                   1382:        printf ("\tif(VFLG) { Exception(7,m68k_getpc()); goto %s; }\n", endlabelstr);
1.1.1.5   root     1383:        need_endlabel = 1;
1.1       root     1384:        break;
1.1.1.2   root     1385:      case i_RTR:
1.1.1.3   root     1386:        printf ("\tcompiler_flush_jsr_stack();\n");
                   1387:        printf ("\tMakeSR();\n");
                   1388:        genamode (Aipi, "7", sz_word, "sr", 1, 0);
                   1389:        genamode (Aipi, "7", sz_long, "pc", 1, 0);
                   1390:        printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
                   1391:        printf ("\tregs.sr |= sr; m68k_setpc(pc);\n");
                   1392:        fill_prefetch_0 ();
                   1393:        printf ("\tMakeFromSR();\n");
                   1394:        m68k_pc_offset = 0;
1.1       root     1395:        break;
                   1396:      case i_JSR:
1.1.1.3   root     1397:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
                   1398:        printf ("\tm68k_do_jsr(m68k_getpc() + %d, srca);\n", m68k_pc_offset);
                   1399:        fill_prefetch_0 ();
                   1400:        m68k_pc_offset = 0;
                   1401:        break;
                   1402:      case i_JMP:
                   1403:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
                   1404:        printf ("\tm68k_setpc(srca);\n");
                   1405:        fill_prefetch_0 ();
                   1406:        m68k_pc_offset = 0;
1.1       root     1407:        break;
                   1408:      case i_BSR:
1.1.1.3   root     1409:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1410:        printf ("\tuae_s32 s = (uae_s32)src + 2;\n");
                   1411:        if (using_exception_3) {
                   1412:            printf ("\tif (src & 1) {\n");
                   1413:            printf ("\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n");
                   1414:            printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + s;\n");
                   1415:            printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr);
                   1416:            printf ("\t}\n");
1.1.1.5   root     1417:            need_endlabel = 1;
1.1.1.3   root     1418:        }
                   1419:        printf ("\tm68k_do_bsr(m68k_getpc() + %d, s);\n", m68k_pc_offset);
                   1420:        fill_prefetch_0 ();
                   1421:        m68k_pc_offset = 0;
1.1       root     1422:        break;
                   1423:      case i_Bcc:
1.1.1.3   root     1424:        if (table68k[opcode].size == sz_long) {
                   1425:            if (cpu_level < 2) {
                   1426:                printf ("\tm68k_incpc(2);\n");
                   1427:                printf ("\tif (!cctrue(%d)) goto %s;\n", table68k[opcode].cc, endlabelstr);
                   1428:                printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n");
                   1429:                printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 1;\n");
                   1430:                printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr);
1.1.1.5   root     1431:                need_endlabel = 1;
1.1.1.3   root     1432:            } else {
                   1433:                if (next_cpu_level < 1)
                   1434:                    next_cpu_level = 1;
                   1435:            }
                   1436:        }
                   1437:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1438:        printf ("\tif (!cctrue(%d)) goto didnt_jump;\n", table68k[opcode].cc);
                   1439:        if (using_exception_3) {
                   1440:            printf ("\tif (src & 1) {\n");
                   1441:            printf ("\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n");
                   1442:            printf ("\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)src;\n");
                   1443:            printf ("\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr);
                   1444:            printf ("\t}\n");
1.1.1.5   root     1445:            need_endlabel = 1;
1.1.1.3   root     1446:        }
1.1       root     1447: #ifdef USE_COMPILER
1.1.1.3   root     1448:        printf ("\tm68k_setpc_bcc(m68k_getpc() + 2 + (uae_s32)src);\n");
1.1       root     1449: #else
1.1.1.3   root     1450:        printf ("\tm68k_incpc ((uae_s32)src + 2);\n");
1.1       root     1451: #endif
1.1.1.3   root     1452:        fill_prefetch_0 ();
                   1453:        printf ("\tgoto %s;\n", endlabelstr);
                   1454:        printf ("didnt_jump:;\n");
1.1.1.5   root     1455:        need_endlabel = 1;
1.1       root     1456:        break;
                   1457:      case i_LEA:
1.1.1.3   root     1458:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
                   1459:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 2, 0);
                   1460:        genastore ("srca", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     1461:        break;
                   1462:      case i_PEA:
1.1.1.3   root     1463:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 0, 0);
                   1464:        genamode (Apdi, "7", sz_long, "dst", 2, 0);
                   1465:        genastore ("srca", Apdi, "7", sz_long, "dst");
1.1       root     1466:        break;
                   1467:      case i_DBcc:
1.1.1.3   root     1468:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1469:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "offs", 1, 0);
                   1470: 
                   1471:        printf ("\tif (!cctrue(%d)) {\n", table68k[opcode].cc);
                   1472:        genastore ("(src-1)", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
                   1473: 
                   1474:        printf ("\t\tif (src) {\n");
                   1475:        if (using_exception_3) {
                   1476:            printf ("\t\t\tif (offs & 1) {\n");
                   1477:            printf ("\t\t\tlast_addr_for_exception_3 = m68k_getpc() + 2;\n");
                   1478:            printf ("\t\t\tlast_fault_for_exception_3 = m68k_getpc() + 2 + (uae_s32)offs + 2;\n");
                   1479:            printf ("\t\t\tlast_op_for_exception_3 = opcode; Exception(3,0); goto %s;\n", endlabelstr);
                   1480:            printf ("\t\t}\n");
1.1.1.5   root     1481:            need_endlabel = 1;
1.1.1.3   root     1482:        }
1.1       root     1483: #ifdef USE_COMPILER
1.1.1.3   root     1484:        printf ("\t\t\tm68k_setpc_bcc(m68k_getpc() + (uae_s32)offs + 2);\n");
1.1       root     1485: #else
1.1.1.3   root     1486:        printf ("\t\t\tm68k_incpc((uae_s32)offs + 2);\n");
1.1       root     1487: #endif
1.1.1.3   root     1488:        fill_prefetch_0 ();
                   1489:        printf ("\t\tgoto %s;\n", endlabelstr);
                   1490:        printf ("\t\t}\n");
                   1491:        printf ("\t}\n");
1.1.1.5   root     1492:        need_endlabel = 1;
1.1       root     1493:        break;
1.1.1.3   root     1494:      case i_Scc:
                   1495:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 2, 0);
1.1       root     1496:        start_brace ();
1.1.1.3   root     1497:        printf ("\tint val = cctrue(%d) ? 0xff : 0;\n", table68k[opcode].cc);
1.1.1.5   root     1498:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     1499:        break;
                   1500:      case i_DIVU:
1.1.1.3   root     1501:        printf ("\tuaecptr oldpc = m68k_getpc();\n");
                   1502:        genamode (table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
                   1503:        genamode (table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
                   1504:        printf ("\tif(src == 0) { Exception(5,oldpc); goto %s; } else {\n", endlabelstr);
                   1505:        printf ("\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
                   1506:        printf ("\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n");
1.1       root     1507:        /* The N flag appears to be set each time there is an overflow.
                   1508:         * Weird. */
1.1.1.3   root     1509:        printf ("\tif (newv > 0xffff) { VFLG = NFLG = 1; CFLG = 0; } else\n\t{\n");
1.1.1.5   root     1510:        genflags (flag_logical, sz_word, "newv", "", "");
1.1.1.3   root     1511:        printf ("\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
1.1.1.5   root     1512:        genastore ("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1.1.3   root     1513:        printf ("\t}\n");
                   1514:        printf ("\t}\n");
1.1.1.5   root     1515:        insn_n_cycles += 68;
                   1516:        need_endlabel = 1;
1.1.1.3   root     1517:        break;
                   1518:      case i_DIVS:
                   1519:        printf ("\tuaecptr oldpc = m68k_getpc();\n");
                   1520:        genamode (table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
                   1521:        genamode (table68k[opcode].dmode, "dstreg", sz_long, "dst", 1, 0);
                   1522:        printf ("\tif(src == 0) { Exception(5,oldpc); goto %s; } else {\n", endlabelstr);
                   1523:        printf ("\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
                   1524:        printf ("\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
                   1525:        printf ("\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) { VFLG = NFLG = 1; CFLG = 0; } else\n\t{\n");
                   1526:        printf ("\tif (((uae_s16)rem < 0) != ((uae_s32)dst < 0)) rem = -rem;\n");
1.1.1.5   root     1527:        genflags (flag_logical, sz_word, "newv", "", "");
1.1.1.3   root     1528:        printf ("\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
1.1.1.5   root     1529:        genastore ("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
1.1.1.3   root     1530:        printf ("\t}\n");
                   1531:        printf ("\t}\n");
1.1.1.5   root     1532:        insn_n_cycles += 72;
                   1533:        need_endlabel = 1;
1.1.1.3   root     1534:        break;
                   1535:      case i_MULU:
                   1536:        genamode (table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
                   1537:        genamode (table68k[opcode].dmode, "dstreg", sz_word, "dst", 1, 0);
1.1       root     1538:        start_brace ();
1.1.1.3   root     1539:        printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
1.1.1.5   root     1540:        genflags (flag_logical, sz_long, "newv", "", "");
                   1541:        genastore ("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
                   1542:        insn_n_cycles += 32;
1.1       root     1543:        break;
                   1544:      case i_MULS:
1.1.1.3   root     1545:        genamode (table68k[opcode].smode, "srcreg", sz_word, "src", 1, 0);
                   1546:        genamode (table68k[opcode].dmode, "dstreg", sz_word, "dst", 1, 0);
1.1       root     1547:        start_brace ();
1.1.1.3   root     1548:        printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
1.1.1.5   root     1549:        genflags (flag_logical, sz_long, "newv", "", "");
                   1550:        genastore ("newv", table68k[opcode].dmode, "dstreg", sz_long, "dst");
                   1551:        insn_n_cycles += 32;
1.1       root     1552:        break;
                   1553:      case i_CHK:
1.1.1.3   root     1554:        printf ("\tuaecptr oldpc = m68k_getpc();\n");
                   1555:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   1556:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
                   1557:        printf ("\tif ((uae_s32)dst < 0) { NFLG=1; Exception(6,oldpc); goto %s; }\n", endlabelstr);
                   1558:        printf ("\telse if (dst > src) { NFLG=0; Exception(6,oldpc); goto %s; }\n", endlabelstr);
1.1.1.5   root     1559:        need_endlabel = 1;
1.1       root     1560:        break;
1.1.1.3   root     1561: 
1.1       root     1562:      case i_CHK2:
1.1.1.3   root     1563:        printf ("\tuaecptr oldpc = m68k_getpc();\n");
1.1       root     1564:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.3   root     1565:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 2, 0);
                   1566:        printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
1.1       root     1567:        switch (table68k[opcode].size) {
1.1.1.3   root     1568:         case sz_byte:
                   1569:            printf ("\tlower=(uae_s32)(uae_s8)get_byte(dsta); upper = (uae_s32)(uae_s8)get_byte(dsta+1);\n");
                   1570:            printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s8)reg;\n");
                   1571:            break;
                   1572:         case sz_word:
                   1573:            printf ("\tlower=(uae_s32)(uae_s16)get_word(dsta); upper = (uae_s32)(uae_s16)get_word(dsta+2);\n");
                   1574:            printf ("\tif ((extra & 0x8000) == 0) reg = (uae_s32)(uae_s16)reg;\n");
                   1575:            break;
                   1576:         case sz_long:
                   1577:            printf ("\tlower=get_long(dsta); upper = get_long(dsta+4);\n");
                   1578:            break;
                   1579:         default:
1.1.1.5   root     1580:            abort ();
1.1.1.3   root     1581:        }
                   1582:        printf ("\tZFLG=upper == reg || lower == reg;\n");
                   1583:        printf ("\tCFLG=lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower;\n");
                   1584:        printf ("\tif ((extra & 0x800) && CFLG) { Exception(6,oldpc); goto %s; }\n}\n", endlabelstr);
1.1.1.5   root     1585:        need_endlabel = 1;
1.1.1.3   root     1586:        break;
                   1587: 
                   1588:      case i_ASR:
                   1589:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1590:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
                   1591:        start_brace ();
1.1.1.5   root     1592:        switch (table68k[opcode].size) {
1.1.1.3   root     1593:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1594:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1595:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1596:         default: abort ();
1.1       root     1597:        }
1.1.1.5   root     1598:        switch (table68k[opcode].size) {
1.1.1.3   root     1599:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1600:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1601:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1602:         default: abort ();
1.1.1.3   root     1603:        }
                   1604:        printf ("\tuae_u32 sign = cmask & val;\n");
                   1605:        printf ("\tcnt &= 63;\n");
                   1606:        printf ("\tVFLG = 0;\n");
                   1607:        printf ("\tif (!cnt) { CFLG = 0; } else {\n");
1.1.1.5   root     1608:        printf ("\tif (cnt >= %d) {\n", bit_size (table68k[opcode].size));
                   1609:        printf ("\t\tval = sign ? %s : 0;\n", bit_mask (table68k[opcode].size));
1.1.1.3   root     1610:        printf ("\t\tCFLG=XFLG= sign ? 1 : 0;\n");
                   1611:        printf ("\t} else {\n");
                   1612:        printf ("\t\tCFLG=XFLG=(val >> (cnt-1)) & 1;\n");
                   1613:        printf ("\t\tval >>= cnt;\n");
                   1614:        printf ("\t\tif (sign) val |= %s << (%d - cnt);\n",
1.1.1.5   root     1615:                bit_mask (table68k[opcode].size),
                   1616:                bit_size (table68k[opcode].size));
1.1.1.3   root     1617:        printf ("\t}}\n");
                   1618:        printf ("\tNFLG = sign != 0;\n");
                   1619:        printf ("\tZFLG = val == 0;\n");
                   1620:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1621:        break;
                   1622:      case i_ASL:
1.1.1.3   root     1623:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1624:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1625:        start_brace ();
1.1.1.5   root     1626:        switch (table68k[opcode].size) {
1.1.1.3   root     1627:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1628:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1629:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1630:         default: abort ();
1.1       root     1631:        }
1.1.1.5   root     1632:        switch (table68k[opcode].size) {
1.1.1.3   root     1633:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1634:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1635:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1636:         default: abort ();
1.1       root     1637:        }
1.1.1.3   root     1638:        printf ("\tcnt &= 63;\n");
                   1639:        printf ("\tVFLG = 0;\n");
                   1640:        printf ("\tif (!cnt) { CFLG = 0; } else {\n");
1.1.1.5   root     1641:        printf ("\tif (cnt >= %d) {\n", bit_size (table68k[opcode].size));
1.1.1.3   root     1642:        printf ("\t\tVFLG = val != 0;\n");
                   1643:        printf ("\t\tCFLG=XFLG = cnt == %d ? val & 1 : 0;\n",
1.1.1.5   root     1644:                bit_size (table68k[opcode].size));
1.1.1.3   root     1645:        printf ("\t\tval = 0;\n");
                   1646:        printf ("\t} else {\n");
                   1647:        printf ("\t\tuae_u32 mask = (%s << (%d - cnt)) & %s;\n",
1.1.1.5   root     1648:                bit_mask (table68k[opcode].size),
                   1649:                bit_size (table68k[opcode].size) - 1,
                   1650:                bit_mask (table68k[opcode].size));
1.1.1.3   root     1651:        printf ("\t\tCFLG=XFLG=(val << (cnt-1)) & cmask ? 1 : 0;\n");
                   1652:        printf ("\t\tVFLG = (val & mask) != mask && (val & mask) != 0;\n");
                   1653:        printf ("\t\tval <<= cnt;\n");
                   1654:        printf ("\t}}\n");
                   1655:        printf ("\tNFLG = (val&cmask) != 0;\n");
                   1656:        printf ("\tZFLG = val == 0;\n");
                   1657:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1658:        break;
                   1659:      case i_LSR:
1.1.1.3   root     1660:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1661:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1662:        start_brace ();
1.1.1.5   root     1663:        switch (table68k[opcode].size) {
1.1.1.3   root     1664:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1665:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1666:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1667:         default: abort ();
1.1       root     1668:        }
1.1.1.5   root     1669:        switch (table68k[opcode].size) {
1.1.1.3   root     1670:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1671:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1672:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1673:         default: abort ();
1.1       root     1674:        }
1.1.1.3   root     1675:        printf ("\tcnt &= 63;\n");
                   1676:        printf ("\tif (!cnt) { CFLG = 0; } else {\n");
1.1.1.5   root     1677:        printf ("\tif (cnt >= %d) {\n", bit_size (table68k[opcode].size));
1.1.1.3   root     1678:        printf ("\t\tCFLG=XFLG = cnt == %d ? (val & cmask ? 1 : 0) : 0;\n",
1.1.1.5   root     1679:                bit_size (table68k[opcode].size));
1.1.1.3   root     1680:        printf ("\t\tval = 0;\n");
                   1681:        printf ("\t} else {\n");
                   1682:        printf ("\t\tCFLG=XFLG=(val >> (cnt-1)) & 1;\n");
                   1683:        printf ("\t\tval >>= cnt;\n");
                   1684:        printf ("\t}}\n");
                   1685:        printf ("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
                   1686:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1687:        break;
                   1688:      case i_LSL:
1.1.1.3   root     1689:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1690:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1691:        start_brace ();
1.1.1.5   root     1692:        switch (table68k[opcode].size) {
1.1.1.3   root     1693:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1694:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1695:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1696:         default: abort ();
1.1       root     1697:        }
1.1.1.5   root     1698:        switch (table68k[opcode].size) {
1.1.1.3   root     1699:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1700:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1701:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1702:         default: abort ();
1.1       root     1703:        }
1.1.1.3   root     1704:        printf ("\tcnt &= 63;\n");
                   1705:        printf ("\tif (!cnt) { CFLG = 0; } else {\n");
1.1.1.5   root     1706:        printf ("\tif (cnt >= %d) {\n", bit_size (table68k[opcode].size));
1.1.1.3   root     1707:        printf ("\t\tCFLG=XFLG = cnt == %d ? val & 1 : 0;\n",
1.1.1.5   root     1708:                bit_size (table68k[opcode].size));
1.1.1.3   root     1709:        printf ("\t\tval = 0;\n");
                   1710:        printf ("\t} else {\n");
                   1711:        printf ("\t\tCFLG=XFLG=(val << (cnt-1)) & cmask ? 1 : 0;\n");
                   1712:        printf ("\t\tval <<= cnt;\n");
                   1713:        printf ("\t}}\n");
                   1714:        printf ("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
                   1715:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1716:        break;
                   1717:      case i_ROL:
1.1.1.3   root     1718:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1719:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1720:        start_brace ();
1.1.1.5   root     1721:        switch (table68k[opcode].size) {
1.1.1.3   root     1722:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1723:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1724:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1725:         default: abort ();
1.1       root     1726:        }
1.1.1.5   root     1727:        switch (table68k[opcode].size) {
1.1.1.3   root     1728:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1729:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1730:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1731:         default: abort ();
1.1       root     1732:        }
1.1.1.3   root     1733:        printf ("\tcnt &= 63;\n");
                   1734:        printf ("\tif (!cnt) { CFLG = 0; } else {\n");
                   1735:        printf ("\tuae_u32 carry;\n");
                   1736:        printf ("\tfor(;cnt;--cnt){\n");
                   1737:        printf ("\tcarry=val&cmask; val <<= 1;\n");
                   1738:        printf ("\tif(carry) val |= 1;\n");
                   1739:        printf ("\t}\n");
                   1740:        printf ("\tCFLG = carry!=0;\n}\n");
                   1741:        printf ("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
                   1742:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1743:        break;
                   1744:      case i_ROR:
1.1.1.3   root     1745:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1746:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1747:        start_brace ();
1.1.1.5   root     1748:        switch (table68k[opcode].size) {
1.1.1.3   root     1749:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1750:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1751:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1752:         default: abort ();
1.1       root     1753:        }
1.1.1.5   root     1754:        switch (table68k[opcode].size) {
1.1.1.3   root     1755:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1756:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1757:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1758:         default: abort ();
1.1       root     1759:        }
1.1.1.3   root     1760:        printf ("\tcnt &= 63;\n");
                   1761:        printf ("\tif (!cnt) { CFLG = 0; } else {");
                   1762:        printf ("\tuae_u32 carry;\n");
                   1763:        printf ("\tfor(;cnt;--cnt){\n");
                   1764:        printf ("\tcarry=val&1; val = val >> 1;\n");
                   1765:        printf ("\tif(carry) val |= cmask;\n");
                   1766:        printf ("\t}\n");
                   1767:        printf ("\tCFLG = carry;\n}\n");
                   1768:        printf ("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
                   1769:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1770:        break;
1.1.1.3   root     1771:      case i_ROXL:
                   1772:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1773:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1774:        start_brace ();
1.1.1.5   root     1775:        switch (table68k[opcode].size) {
1.1.1.3   root     1776:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1777:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1778:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1779:         default: abort ();
1.1       root     1780:        }
1.1.1.5   root     1781:        switch (table68k[opcode].size) {
1.1.1.3   root     1782:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1783:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1784:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1785:         default: abort ();
1.1       root     1786:        }
1.1.1.3   root     1787:        printf ("\tuae_u32 carry;\n");
                   1788:        printf ("\tcnt &= 63;\n");
                   1789:        printf ("\tfor(;cnt;--cnt){\n");
                   1790:        printf ("\tcarry=val&cmask; val <<= 1;\n");
                   1791:        printf ("\tif(XFLG) val |= 1;\n");
                   1792:        printf ("\tXFLG = carry != 0;\n");
                   1793:        printf ("\t}\n");
                   1794:        printf ("\tCFLG = XFLG;\n");
                   1795:        printf ("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
                   1796:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1797:        break;
                   1798:      case i_ROXR:
1.1.1.3   root     1799:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "cnt", 1, 0);
                   1800:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1801:        start_brace ();
1.1.1.5   root     1802:        switch (table68k[opcode].size) {
1.1.1.3   root     1803:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1804:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1805:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1806:         default: abort ();
1.1       root     1807:        }
1.1.1.5   root     1808:        switch (table68k[opcode].size) {
1.1.1.3   root     1809:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1810:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1811:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1812:         default: abort ();
1.1       root     1813:        }
1.1.1.3   root     1814:        printf ("\tuae_u32 carry;\n");
                   1815:        printf ("\tcnt &= 63;\n");
                   1816:        printf ("\tfor(;cnt;--cnt){\n");
                   1817:        printf ("\tcarry=val&1; val >>= 1;\n");
                   1818:        printf ("\tif(XFLG) val |= cmask;\n");
                   1819:        printf ("\tXFLG = carry;\n");
                   1820:        printf ("\t}\n");
                   1821:        printf ("\tCFLG = XFLG;\n");
                   1822:        printf ("\tNFLG = (val & cmask) != 0; ZFLG = val == 0; VFLG = 0;\n");
                   1823:        genastore ("val", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "data");
1.1       root     1824:        break;
                   1825:      case i_ASRW:
1.1.1.3   root     1826:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
                   1827:        printf ("\tVFLG = 0;\n");
1.1       root     1828:        start_brace ();
1.1.1.5   root     1829:        switch (table68k[opcode].size) {
1.1.1.3   root     1830:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1831:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1832:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1833:         default: abort ();
1.1       root     1834:        }
1.1.1.5   root     1835:        switch (table68k[opcode].size) {
1.1.1.3   root     1836:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1837:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1838:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1839:         default: abort ();
1.1       root     1840:        }
1.1.1.3   root     1841:        printf ("\tuae_u32 sign = cmask & val;\n");
                   1842:        printf ("\tCFLG=XFLG=val&1; val = (val >> 1) | sign;\n");
                   1843:        printf ("\tNFLG = sign != 0;\n");
                   1844:        printf ("\tZFLG = val == 0;\n");
                   1845:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1846:        break;
                   1847:      case i_ASLW:
1.1.1.3   root     1848:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
                   1849:        printf ("\tVFLG = 0;\n");
1.1       root     1850:        start_brace ();
1.1.1.5   root     1851:        switch (table68k[opcode].size) {
1.1.1.3   root     1852:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1853:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1854:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1855:         default: abort ();
1.1       root     1856:        }
1.1.1.5   root     1857:        switch (table68k[opcode].size) {
1.1.1.3   root     1858:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1859:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1860:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1861:         default: abort ();
1.1       root     1862:        }
1.1.1.3   root     1863:        printf ("\tuae_u32 sign = cmask & val;\n");
                   1864:        printf ("\tCFLG=XFLG=(val&cmask)!=0; val <<= 1;\n");
                   1865:        printf ("\tif ((val&cmask)!=sign) VFLG=1;\n");
                   1866:        printf ("\tNFLG = (val&cmask) != 0;\n");
                   1867:        printf ("\tZFLG = val == 0;\n");
                   1868:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1869:        break;
                   1870:      case i_LSRW:
1.1.1.3   root     1871:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1872:        start_brace ();
1.1.1.5   root     1873:        switch (table68k[opcode].size) {
1.1.1.3   root     1874:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1875:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1876:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1877:         default: abort ();
1.1       root     1878:        }
1.1.1.3   root     1879:        printf ("\tuae_u32 carry = val&1;\n");
                   1880:        printf ("\tval >>= 1;\n");
1.1.1.5   root     1881:        genflags (flag_logical, table68k[opcode].size, "val", "", "");
1.1.1.3   root     1882:        printf ("CFLG = XFLG = carry!=0;\n");
                   1883:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1884:        break;
                   1885:      case i_LSLW:
1.1.1.3   root     1886:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1887:        start_brace ();
1.1.1.5   root     1888:        switch (table68k[opcode].size) {
1.1.1.3   root     1889:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1890:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1891:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1892:         default: abort ();
1.1       root     1893:        }
1.1.1.5   root     1894:        switch (table68k[opcode].size) {
1.1.1.3   root     1895:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1896:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1897:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1898:         default: abort ();
1.1       root     1899:        }
1.1.1.3   root     1900:        printf ("\tuae_u32 carry = val&cmask;\n");
                   1901:        printf ("\tval <<= 1;\n");
1.1.1.5   root     1902:        genflags (flag_logical, table68k[opcode].size, "val", "", "");
1.1.1.3   root     1903:        printf ("CFLG = XFLG = carry!=0;\n");
                   1904:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1905:        break;
                   1906:      case i_ROLW:
1.1.1.3   root     1907:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1908:        start_brace ();
1.1.1.5   root     1909:        switch (table68k[opcode].size) {
1.1.1.3   root     1910:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1911:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1912:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1913:         default: abort ();
1.1       root     1914:        }
1.1.1.5   root     1915:        switch (table68k[opcode].size) {
1.1.1.3   root     1916:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1917:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1918:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1919:         default: abort ();
1.1       root     1920:        }
1.1.1.3   root     1921:        printf ("\tuae_u32 carry = val&cmask;\n");
                   1922:        printf ("\tval <<= 1;\n");
                   1923:        printf ("\tif(carry)  val |= 1;\n");
1.1.1.5   root     1924:        genflags (flag_logical, table68k[opcode].size, "val", "", "");
1.1.1.3   root     1925:        printf ("CFLG = carry!=0;\n");
                   1926:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1927:        break;
                   1928:      case i_RORW:
1.1.1.3   root     1929:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1930:        start_brace ();
1.1.1.5   root     1931:        switch (table68k[opcode].size) {
1.1.1.3   root     1932:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1933:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1934:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1935:         default: abort ();
1.1       root     1936:        }
1.1.1.3   root     1937:        printf ("\tuae_u32 carry = val&1;\n");
1.1.1.5   root     1938:        switch (table68k[opcode].size) {
1.1.1.3   root     1939:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1940:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1941:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1942:         default: abort ();
1.1       root     1943:        }
1.1.1.3   root     1944:        printf ("\tval >>= 1;\n");
                   1945:        printf ("\tif(carry) val |= cmask;\n");
1.1.1.5   root     1946:        genflags (flag_logical, table68k[opcode].size, "val", "", "");
1.1.1.3   root     1947:        printf ("CFLG = carry!=0;\n");
                   1948:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1949:        break;
                   1950:      case i_ROXLW:
1.1.1.3   root     1951:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1952:        start_brace ();
1.1.1.5   root     1953:        switch (table68k[opcode].size) {
1.1.1.3   root     1954:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1955:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1956:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1957:         default: abort ();
1.1       root     1958:        }
1.1.1.5   root     1959:        switch (table68k[opcode].size) {
1.1.1.3   root     1960:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1961:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1962:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1963:         default: abort ();
1.1       root     1964:        }
1.1.1.3   root     1965:        printf ("\tuae_u32 carry = val&cmask;\n");
                   1966:        printf ("\tval <<= 1;\n");
                   1967:        printf ("\tif(XFLG) val |= 1;\n");
                   1968:        printf ("\tXFLG = carry != 0;\n");
1.1.1.5   root     1969:        genflags (flag_logical, table68k[opcode].size, "val", "", "");
1.1.1.3   root     1970:        printf ("XFLG = CFLG = carry!=0;\n");
                   1971:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1972:        break;
                   1973:      case i_ROXRW:
1.1.1.3   root     1974:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "data", 1, 0);
1.1       root     1975:        start_brace ();
1.1.1.5   root     1976:        switch (table68k[opcode].size) {
1.1.1.3   root     1977:         case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                   1978:         case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                   1979:         case sz_long: printf ("\tuae_u32 val = data;\n"); break;
1.1.1.5   root     1980:         default: abort ();
1.1       root     1981:        }
1.1.1.3   root     1982:        printf ("\tuae_u32 carry = val&1;\n");
1.1.1.5   root     1983:        switch (table68k[opcode].size) {
1.1.1.3   root     1984:         case sz_byte: printf ("\tuae_u32 cmask = 0x80;\n"); break;
                   1985:         case sz_word: printf ("\tuae_u32 cmask = 0x8000;\n"); break;
                   1986:         case sz_long: printf ("\tuae_u32 cmask = 0x80000000;\n"); break;
1.1.1.5   root     1987:         default: abort ();
1.1       root     1988:        }
1.1.1.3   root     1989:        printf ("\tval >>= 1;\n");
                   1990:        printf ("\tif(XFLG) val |= cmask;\n");
                   1991:        printf ("\tXFLG = carry != 0;\n");
1.1.1.5   root     1992:        genflags (flag_logical, table68k[opcode].size, "val", "", "");
1.1.1.3   root     1993:        printf ("XFLG = CFLG = carry!=0;\n");
                   1994:        genastore ("val", table68k[opcode].smode, "srcreg", table68k[opcode].size, "data");
1.1       root     1995:        break;
                   1996:      case i_MOVEC2:
                   1997:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1.1.5   root     1998:        start_brace ();
1.1.1.3   root     1999:        printf ("\tint regno = (src >> 12) & 15;\n");
                   2000:        printf ("\tuae_u32 *regp = regs.regs + regno;\n");
                   2001:        printf ("\tm68k_movec2(src & 0xFFF, regp);\n");
1.1       root     2002:        break;
                   2003:      case i_MOVE2C:
                   2004:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1.1.5   root     2005:        start_brace ();
1.1.1.3   root     2006:        printf ("\tint regno = (src >> 12) & 15;\n");
                   2007:        printf ("\tuae_u32 *regp = regs.regs + regno;\n");
                   2008:        printf ("\tm68k_move2c(src & 0xFFF, regp);\n");
1.1       root     2009:        break;
                   2010:      case i_CAS:
                   2011:        {
                   2012:            int old_brace_level;
                   2013:            genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
                   2014:            genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1.1.5   root     2015:            start_brace ();
1.1.1.3   root     2016:            printf ("\tint ru = (src >> 6) & 7;\n");
                   2017:            printf ("\tint rc = src & 7;\n");
1.1.1.5   root     2018:            genflags (flag_cmp, table68k[opcode].size, "newv", "m68k_dreg(regs, rc)", "dst");
1.1.1.3   root     2019:            printf ("\tif (ZFLG)");
1.1       root     2020:            old_brace_level = n_braces;
                   2021:            start_brace ();
1.1.1.5   root     2022:            genastore ("(m68k_dreg(regs, ru))", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     2023:            pop_braces (old_brace_level);
1.1.1.3   root     2024:            printf ("else");
1.1       root     2025:            start_brace ();
1.1.1.3   root     2026:            printf ("m68k_dreg(regs, rc) = dst;\n");
1.1       root     2027:            pop_braces (old_brace_level);
                   2028:        }
                   2029:        break;
                   2030:      case i_CAS2:
                   2031:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.3   root     2032:        printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 7];\n");
                   2033:        printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 7];\n");
1.1       root     2034:        if (table68k[opcode].size == sz_word) {
1.1.1.5   root     2035:            int old_brace_level = n_braces;
                   2036:            printf ("\tuae_u16 dst1 = get_word(rn1), dst2 = get_word(rn2);\n");
                   2037:            genflags (flag_cmp, table68k[opcode].size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1");
                   2038:            printf ("\tif (ZFLG) {\n");
                   2039:            genflags (flag_cmp, table68k[opcode].size, "newv", "m68k_dreg(regs, extra & 7)", "dst2");
                   2040:            printf ("\tif (ZFLG) {\n");
                   2041:            printf ("\tput_word(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n");
                   2042:            printf ("\tput_word(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n");
                   2043:            printf ("\t}}\n");
                   2044:            pop_braces (old_brace_level);
                   2045:            printf ("\tif (!ZFLG) {\n");
                   2046:            printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = (m68k_dreg(regs, (extra >> 22) & 7) & ~0xffff) | (dst1 & 0xffff);\n");
                   2047:            printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = (m68k_dreg(regs, (extra >> 6) & 7) & ~0xffff) | (dst2 & 0xffff);\n");
                   2048:            printf ("\t}\n");
1.1       root     2049:        } else {
1.1.1.5   root     2050:            int old_brace_level = n_braces;
                   2051:            printf ("\tuae_u32 dst1 = get_long(rn1), dst2 = get_long(rn2);\n");
                   2052:            genflags (flag_cmp, table68k[opcode].size, "newv", "m68k_dreg(regs, (extra >> 16) & 7)", "dst1");
                   2053:            printf ("\tif (ZFLG) {\n");
                   2054:            genflags (flag_cmp, table68k[opcode].size, "newv", "m68k_dreg(regs, extra & 7)", "dst2");
                   2055:            printf ("\tif (ZFLG) {\n");
                   2056:            printf ("\tput_long(rn1, m68k_dreg(regs, (extra >> 22) & 7));\n");
                   2057:            printf ("\tput_long(rn1, m68k_dreg(regs, (extra >> 6) & 7));\n");
                   2058:            printf ("\t}}\n");
                   2059:            pop_braces (old_brace_level);
                   2060:            printf ("\tif (!ZFLG) {\n");
                   2061:            printf ("\tm68k_dreg(regs, (extra >> 22) & 7) = dst1;\n");
                   2062:            printf ("\tm68k_dreg(regs, (extra >> 6) & 7) = dst2;\n");
                   2063:            printf ("\t}\n");
1.1       root     2064:        }
                   2065:        break;
1.1.1.5   root     2066:      case i_MOVES:             /* ignore DFC and SFC because we have no MMU */
1.1       root     2067:        {
                   2068:            int old_brace_level;
                   2069:            genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.3   root     2070:            printf ("\tif (extra & 0x800)\n");
1.1       root     2071:            old_brace_level = n_braces;
                   2072:            start_brace ();
1.1.1.3   root     2073:            printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
                   2074:            genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 2, 0);
                   2075:            genastore ("src", table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst");
1.1       root     2076:            pop_braces (old_brace_level);
1.1.1.3   root     2077:            printf ("else");
1.1       root     2078:            start_brace ();
1.1.1.3   root     2079:            genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 1, 0);
                   2080:            printf ("\tif (extra & 0x8000) {\n");
1.1.1.5   root     2081:            switch (table68k[opcode].size) {
1.1.1.3   root     2082:             case sz_byte: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break;
                   2083:             case sz_word: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break;
                   2084:             case sz_long: printf ("\tm68k_areg(regs, (extra >> 12) & 7) = src;\n"); break;
1.1.1.5   root     2085:             default: abort ();
1.1       root     2086:            }
1.1.1.3   root     2087:            printf ("\t} else {\n");
                   2088:            genastore ("src", Dreg, "(extra >> 12) & 7", table68k[opcode].size, "");
                   2089:            printf ("\t}\n");
1.1       root     2090:            pop_braces (old_brace_level);
                   2091:        }
                   2092:        break;
1.1.1.5   root     2093:      case i_BKPT:              /* only needed for hardware emulators */
                   2094:        sync_m68k_pc ();
1.1.1.3   root     2095:        printf ("\top_illg(opcode);\n");
1.1       root     2096:        break;
1.1.1.5   root     2097:      case i_CALLM:             /* not present in 68030 */
                   2098:        sync_m68k_pc ();
1.1.1.3   root     2099:        printf ("\top_illg(opcode);\n");
1.1       root     2100:        break;
1.1.1.5   root     2101:      case i_RTM:               /* not present in 68030 */
                   2102:        sync_m68k_pc ();
1.1.1.3   root     2103:        printf ("\top_illg(opcode);\n");
1.1       root     2104:        break;
                   2105:      case i_TRAPcc:
                   2106:        if (table68k[opcode].smode != am_unknown && table68k[opcode].smode != am_illg)
                   2107:            genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "dummy", 1, 0);
1.1.1.3   root     2108:        printf ("\tif (cctrue(%d)) { Exception(7,m68k_getpc()); goto %s; }\n", table68k[opcode].cc, endlabelstr);
1.1.1.5   root     2109:        need_endlabel = 1;
1.1       root     2110:        break;
                   2111:      case i_DIVL:
1.1.1.3   root     2112:        sync_m68k_pc ();
                   2113:        start_brace ();
                   2114:        printf ("\tuaecptr oldpc = m68k_getpc();\n");
1.1       root     2115:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
                   2116:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1.1.5   root     2117:        sync_m68k_pc ();
1.1.1.3   root     2118:        printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n");
1.1       root     2119:        break;
                   2120:      case i_MULL:
                   2121:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
                   2122:        genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "dst", 1, 0);
1.1.1.5   root     2123:        sync_m68k_pc ();
1.1.1.3   root     2124:        printf ("\tm68k_mull(opcode, dst, extra);\n");
1.1       root     2125:        break;
                   2126:      case i_BFTST:
                   2127:      case i_BFEXTU:
                   2128:      case i_BFCHG:
                   2129:      case i_BFEXTS:
                   2130:      case i_BFCLR:
                   2131:      case i_BFFFO:
                   2132:      case i_BFSET:
                   2133:      case i_BFINS:
                   2134:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.3   root     2135:        genamode (table68k[opcode].dmode, "dstreg", sz_long, "dst", 2, 0);
1.1.1.5   root     2136:        start_brace ();
1.1.1.3   root     2137:        printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n");
                   2138:        printf ("\tint width = (((extra & 0x20 ? m68k_dreg(regs, extra & 7) : extra) -1) & 0x1f) +1;\n");
1.1       root     2139:        if (table68k[opcode].dmode == Dreg) {
1.1.1.3   root     2140:            printf ("\tuae_u32 tmp = m68k_dreg(regs, dstreg) << (offset & 0x1f);\n");
                   2141:        } else {
                   2142:            printf ("\tuae_u32 tmp,bf0,bf1;\n");
                   2143:            printf ("\tdsta += (offset >> 3) | (offset & 0x80000000 ? ~0x1fffffff : 0);\n");
                   2144:            printf ("\tbf0 = get_long(dsta);bf1 = get_byte(dsta+4) & 0xff;\n");
                   2145:            printf ("\ttmp = (bf0 << (offset & 7)) | (bf1 >> (8 - (offset & 7)));\n");
                   2146:        }
                   2147:        printf ("\ttmp >>= (32 - width);\n");
                   2148:        printf ("\tNFLG = tmp & (1 << (width-1)) ? 1 : 0;ZFLG = tmp == 0;VFLG = 0;CFLG = 0;\n");
1.1.1.5   root     2149:        switch (table68k[opcode].mnemo) {
1.1.1.3   root     2150:         case i_BFTST:
                   2151:            break;
                   2152:         case i_BFEXTU:
                   2153:            printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n");
                   2154:            break;
                   2155:         case i_BFCHG:
                   2156:            printf ("\ttmp = ~tmp;\n");
                   2157:            break;
                   2158:         case i_BFEXTS:
                   2159:            printf ("\tif (NFLG) tmp |= width == 32 ? 0 : (-1 << width);\n");
                   2160:            printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = tmp;\n");
                   2161:            break;
                   2162:         case i_BFCLR:
                   2163:            printf ("\ttmp = 0;\n");
                   2164:            break;
                   2165:         case i_BFFFO:
                   2166:            printf ("\t{ uae_u32 mask = 1 << (width-1);\n");
                   2167:            printf ("\twhile (mask) { if (tmp & mask) break; mask >>= 1; offset++; }}\n");
                   2168:            printf ("\tm68k_dreg(regs, (extra >> 12) & 7) = offset;\n");
                   2169:            break;
                   2170:         case i_BFSET:
                   2171:            printf ("\ttmp = 0xffffffff;\n");
                   2172:            break;
                   2173:         case i_BFINS:
                   2174:            printf ("\ttmp = m68k_dreg(regs, (extra >> 12) & 7);\n");
                   2175:            break;
                   2176:         default:
                   2177:            break;
1.1       root     2178:        }
1.1.1.5   root     2179:        if (table68k[opcode].mnemo == i_BFCHG
                   2180:            || table68k[opcode].mnemo == i_BFCLR
                   2181:            || table68k[opcode].mnemo == i_BFSET
                   2182:            || table68k[opcode].mnemo == i_BFINS)
                   2183:        {
                   2184:            printf ("\ttmp <<= (32 - width);\n");
                   2185:            if (table68k[opcode].dmode == Dreg) {
                   2186:                printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & ((offset & 0x1f) == 0 ? 0 :\n");
                   2187:                printf ("\t\t(0xffffffff << (32 - (offset & 0x1f))))) |\n");
                   2188:                printf ("\t\t(tmp >> (offset & 0x1f)) |\n");
                   2189:                printf ("\t\t(((offset & 0x1f) + width) >= 32 ? 0 :\n");
                   2190:                printf (" (m68k_dreg(regs, dstreg) & ((uae_u32)0xffffffff >> ((offset & 0x1f) + width))));\n");
                   2191:            } else {
                   2192:                printf ("\tbf0 = (bf0 & (0xff000000 << (8 - (offset & 7)))) |\n");
                   2193:                printf ("\t\t(tmp >> (offset & 7)) |\n");
                   2194:                printf ("\t\t(((offset & 7) + width) >= 32 ? 0 :\n");
                   2195:                printf ("\t\t (bf0 & ((uae_u32)0xffffffff >> ((offset & 7) + width))));\n");
                   2196:                printf ("\tput_long(dsta,bf0 );\n");
                   2197:                printf ("\tif (((offset & 7) + width) > 32) {\n");
                   2198:                printf ("\t\tbf1 = (bf1 & (0xff >> (width - 32 + (offset & 7)))) |\n");
                   2199:                printf ("\t\t\t(tmp << (8 - (offset & 7)));\n");
                   2200:                printf ("\t\tput_byte(dsta+4,bf1);\n");
                   2201:                printf ("\t}\n");
                   2202:            }
1.1       root     2203:        }
                   2204:        break;
                   2205:      case i_PACK:
                   2206:        if (table68k[opcode].smode == Dreg) {
1.1.1.5   root     2207:            printf ("\tuae_u16 val = m68k_dreg(regs, srcreg) + %s;\n", gen_nextiword ());
1.1.1.3   root     2208:            printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffffff00) | ((val >> 4) & 0xf0) | (val & 0xf);\n");
                   2209:        } else {
                   2210:            printf ("\tuae_u16 val;\n");
                   2211:            printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
                   2212:            printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg));\n");
                   2213:            printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
1.1.1.5   root     2214:            printf ("\tval = (val | ((uae_u16)get_byte(m68k_areg(regs, srcreg)) << 8)) + %s;\n", gen_nextiword ());
1.1.1.3   root     2215:            printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
                   2216:            printf ("\tput_byte(m68k_areg(regs, dstreg),((val >> 4) & 0xf0) | (val & 0xf));\n");
1.1       root     2217:        }
                   2218:        break;
                   2219:      case i_UNPK:
                   2220:        if (table68k[opcode].smode == Dreg) {
1.1.1.3   root     2221:            printf ("\tuae_u16 val = m68k_dreg(regs, srcreg);\n");
1.1.1.5   root     2222:            printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ());
1.1.1.3   root     2223:            printf ("\tm68k_dreg(regs, dstreg) = (m68k_dreg(regs, dstreg) & 0xffff0000) | (val & 0xffff);\n");
                   2224:        } else {
                   2225:            printf ("\tuae_u16 val;\n");
                   2226:            printf ("\tm68k_areg(regs, srcreg) -= areg_byteinc[srcreg];\n");
                   2227:            printf ("\tval = (uae_u16)get_byte(m68k_areg(regs, srcreg));\n");
1.1.1.5   root     2228:            printf ("\tval = (((val << 4) & 0xf00) | (val & 0xf)) + %s;\n", gen_nextiword ());
1.1.1.3   root     2229:            printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
                   2230:            printf ("\tput_byte(m68k_areg(regs, dstreg),val);\n");
                   2231:            printf ("\tm68k_areg(regs, dstreg) -= areg_byteinc[dstreg];\n");
                   2232:            printf ("\tput_byte(m68k_areg(regs, dstreg),val >> 8);\n");
1.1       root     2233:        }
                   2234:        break;
                   2235:      case i_TAS:
1.1.1.3   root     2236:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "src", 1, 0);
1.1.1.5   root     2237:        genflags (flag_logical, table68k[opcode].size, "src", "", "");
1.1.1.3   root     2238:        printf ("\tsrc |= 0x80;\n");
                   2239:        genastore ("src", table68k[opcode].smode, "srcreg", table68k[opcode].size, "src");
1.1       root     2240:        break;
                   2241:      case i_FPP:
                   2242:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.5   root     2243:        sync_m68k_pc ();
1.1.1.6 ! root     2244:        swap_opcode ();
1.1.1.3   root     2245:        printf ("\tfpp_opp(opcode,extra);\n");
1.1       root     2246:        break;
                   2247:      case i_FDBcc:
                   2248:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.5   root     2249:        sync_m68k_pc ();
1.1.1.6 ! root     2250:        swap_opcode ();
1.1.1.3   root     2251:        printf ("\tfdbcc_opp(opcode,extra);\n");
1.1       root     2252:        break;
                   2253:      case i_FScc:
                   2254:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.5   root     2255:        sync_m68k_pc ();
1.1.1.6 ! root     2256:        swap_opcode ();
1.1.1.3   root     2257:        printf ("\tfscc_opp(opcode,extra);\n");
1.1       root     2258:        break;
                   2259:      case i_FTRAPcc:
1.1.1.5   root     2260:        sync_m68k_pc ();
                   2261:        start_brace ();
1.1.1.3   root     2262:        printf ("\tuaecptr oldpc = m68k_getpc();\n");
1.1       root     2263:        if (table68k[opcode].smode != am_unknown && table68k[opcode].smode != am_illg)
                   2264:            genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "dummy", 1, 0);
1.1.1.5   root     2265:        sync_m68k_pc ();
1.1.1.6 ! root     2266:        swap_opcode ();
1.1.1.3   root     2267:        printf ("\tftrapcc_opp(opcode,oldpc);\n");
1.1       root     2268:        break;
                   2269:      case i_FBcc:
1.1.1.5   root     2270:        sync_m68k_pc ();
                   2271:        start_brace ();
1.1.1.3   root     2272:        printf ("\tuaecptr pc = m68k_getpc();\n");
1.1       root     2273:        genamode (table68k[opcode].dmode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.5   root     2274:        sync_m68k_pc ();
1.1.1.6 ! root     2275:        swap_opcode ();
1.1.1.3   root     2276:        printf ("\tfbcc_opp(opcode,pc,extra);\n");
1.1       root     2277:        break;
                   2278:      case i_FSAVE:
1.1.1.5   root     2279:        sync_m68k_pc ();
1.1.1.6 ! root     2280:        swap_opcode ();
1.1.1.3   root     2281:        printf ("\tfsave_opp(opcode);\n");
1.1       root     2282:        break;
                   2283:      case i_FRESTORE:
1.1.1.5   root     2284:        sync_m68k_pc ();
1.1.1.6 ! root     2285:        swap_opcode ();
1.1.1.3   root     2286:        printf ("\tfrestore_opp(opcode);\n");
1.1       root     2287:        break;
                   2288:      case i_MMUOP:
                   2289:        genamode (table68k[opcode].smode, "srcreg", table68k[opcode].size, "extra", 1, 0);
1.1.1.5   root     2290:        sync_m68k_pc ();
1.1.1.6 ! root     2291:        swap_opcode ();
1.1.1.3   root     2292:        printf ("\tmmu_op(opcode,extra);\n");
1.1       root     2293:        break;
                   2294:      default:
1.1.1.5   root     2295:        abort ();
1.1       root     2296:        break;
1.1.1.5   root     2297:     }
1.1       root     2298:     finish_braces ();
1.1.1.3   root     2299:     sync_m68k_pc ();
1.1       root     2300: }
                   2301: 
1.1.1.5   root     2302: static void generate_includes (FILE * f)
1.1.1.3   root     2303: {
                   2304:     fprintf (f, "#include \"sysconfig.h\"\n");
                   2305:     fprintf (f, "#include \"sysdeps.h\"\n");
                   2306:     fprintf (f, "#include \"config.h\"\n");
                   2307:     fprintf (f, "#include \"options.h\"\n");
                   2308:     fprintf (f, "#include \"machdep/m68k.h\"\n");
                   2309:     fprintf (f, "#include \"memory.h\"\n");
                   2310:     fprintf (f, "#include \"custom.h\"\n");
                   2311:     fprintf (f, "#include \"readcpu.h\"\n");
                   2312:     fprintf (f, "#include \"newcpu.h\"\n");
                   2313:     fprintf (f, "#include \"compiler.h\"\n");
                   2314:     fprintf (f, "#include \"cputbl.h\"\n");
                   2315: }
                   2316: 
                   2317: static int postfix;
                   2318: 
                   2319: static void generate_one_opcode (int rp)
1.1       root     2320: {
                   2321:     int i;
1.1.1.3   root     2322:     uae_u16 smsk, dmsk;
                   2323:     long int opcode = opcode_map[rp];
1.1       root     2324: 
1.1.1.3   root     2325:     if (table68k[opcode].mnemo == i_ILLG
                   2326:        || table68k[opcode].clev > cpu_level)
                   2327:        return;
1.1       root     2328: 
1.1.1.5   root     2329:     for (i = 0; lookuptab[i].name[0]; i++) {
1.1.1.3   root     2330:        if (table68k[opcode].mnemo == lookuptab[i].mnemo)
                   2331:            break;
                   2332:     }
1.1       root     2333: 
1.1.1.3   root     2334:     if (table68k[opcode].handler != -1)
                   2335:        return;
1.1       root     2336: 
1.1.1.3   root     2337:     if (opcode_next_clev[rp] != cpu_level) {
                   2338:        fprintf (stblfile, "{ op_%lx_%d, 0, %ld }, /* %s */\n", opcode, opcode_last_postfix[rp],
                   2339:                 opcode, lookuptab[i].name);
                   2340:        return;
                   2341:     }
                   2342:     fprintf (stblfile, "{ op_%lx_%d, 0, %ld }, /* %s */\n", opcode, postfix, opcode, lookuptab[i].name);
                   2343:     fprintf (headerfile, "extern cpuop_func op_%lx_%d;\n", opcode, postfix);
1.1.1.5   root     2344:     printf ("unsigned long REGPARAM2 op_%lx_%d(uae_u32 opcode) /* %s */\n{\n", opcode, postfix, lookuptab[i].name);
1.1.1.3   root     2345: 
                   2346:     switch (table68k[opcode].stype) {
                   2347:      case 0: smsk = 7; break;
                   2348:      case 1: smsk = 255; break;
                   2349:      case 2: smsk = 15; break;
                   2350:      case 3: smsk = 7; break;
                   2351:      case 4: smsk = 7; break;
                   2352:      case 5: smsk = 63; break;
1.1.1.5   root     2353:      default: abort ();
1.1.1.3   root     2354:     }
                   2355:     dmsk = 7;
                   2356: 
                   2357:     next_cpu_level = -1;
                   2358:     if (table68k[opcode].suse
1.1.1.5   root     2359:        && table68k[opcode].smode != imm && table68k[opcode].smode != imm0
1.1.1.3   root     2360:        && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
                   2361:        && table68k[opcode].smode != absw && table68k[opcode].smode != absl
                   2362:        && table68k[opcode].smode != PC8r && table68k[opcode].smode != PC16)
                   2363:     {
                   2364:        if (table68k[opcode].spos == -1) {
1.1.1.5   root     2365:            if (((int) table68k[opcode].sreg) >= 128)
                   2366:                printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].sreg);
1.1.1.3   root     2367:            else
1.1.1.5   root     2368:                printf ("\tuae_u32 srcreg = %d;\n", (int) table68k[opcode].sreg);
1.1.1.3   root     2369:        } else {
                   2370:            char source[100];
1.1.1.6 ! root     2371:            int pos = table68k[opcode].spos;
1.1.1.5   root     2372: 
1.1.1.6 ! root     2373: #if 0
1.1.1.5   root     2374:            /* Check that we can do the little endian optimization safely.  */
1.1.1.6 ! root     2375:            if (pos < 8 && (smsk >> (8 - pos)) != 0)
1.1.1.5   root     2376:                abort ();
1.1.1.6 ! root     2377: #endif
1.1.1.5   root     2378:            printf ("#ifdef HAVE_GET_WORD_UNSWAPPED\n");
                   2379: 
1.1.1.6 ! root     2380:            if (pos < 8 && (smsk >> (8 - pos)) != 0)
        !          2381:                sprintf (source, "(((opcode >> %d) | (opcode << %d)) & %d)",
        !          2382:                        pos ^ 8, 8 - pos, dmsk);
        !          2383:            else if (pos != 8)
        !          2384:                sprintf (source, "((opcode >> %d) & %d)", pos ^ 8, smsk);
1.1.1.5   root     2385:            else
                   2386:                sprintf (source, "(opcode & %d)", smsk);
                   2387: 
                   2388:            if (table68k[opcode].stype == 3)
                   2389:                printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
                   2390:            else if (table68k[opcode].stype == 1)
                   2391:                printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
                   2392:            else
                   2393:                printf ("\tuae_u32 srcreg = %s;\n", source);
                   2394: 
                   2395:            printf ("#else\n");
                   2396: 
1.1.1.6 ! root     2397:            if (pos)
        !          2398:                sprintf (source, "((opcode >> %d) & %d)", pos, smsk);
1.1.1.3   root     2399:            else
1.1.1.5   root     2400:                sprintf (source, "(opcode & %d)", smsk);
                   2401: 
1.1.1.3   root     2402:            if (table68k[opcode].stype == 3)
                   2403:                printf ("\tuae_u32 srcreg = imm8_table[%s];\n", source);
                   2404:            else if (table68k[opcode].stype == 1)
                   2405:                printf ("\tuae_u32 srcreg = (uae_s32)(uae_s8)%s;\n", source);
                   2406:            else
                   2407:                printf ("\tuae_u32 srcreg = %s;\n", source);
1.1.1.5   root     2408: 
                   2409:            printf ("#endif\n");
1.1       root     2410:        }
1.1.1.3   root     2411:     }
                   2412:     if (table68k[opcode].duse
                   2413:        /* Yes, the dmode can be imm, in case of LINK or DBcc */
1.1.1.5   root     2414:        && table68k[opcode].dmode != imm && table68k[opcode].dmode != imm0
1.1.1.3   root     2415:        && table68k[opcode].dmode != imm1 && table68k[opcode].dmode != imm2
1.1.1.5   root     2416:        && table68k[opcode].dmode != absw && table68k[opcode].dmode != absl)
                   2417:     {
1.1.1.3   root     2418:        if (table68k[opcode].dpos == -1) {
1.1.1.5   root     2419:            if (((int) table68k[opcode].dreg) >= 128)
                   2420:                printf ("\tuae_u32 dstreg = (uae_s32)(uae_s8)%d;\n", (int) table68k[opcode].dreg);
1.1.1.3   root     2421:            else
1.1.1.5   root     2422:                printf ("\tuae_u32 dstreg = %d;\n", (int) table68k[opcode].dreg);
1.1.1.3   root     2423:        } else {
1.1.1.5   root     2424:            int pos = table68k[opcode].dpos;
1.1.1.6 ! root     2425: #if 0
1.1.1.5   root     2426:            /* Check that we can do the little endian optimization safely.  */
1.1.1.6 ! root     2427:            if (pos < 8 && (dmsk >> (8 - pos)) != 0)
1.1.1.5   root     2428:                abort ();
1.1.1.6 ! root     2429: #endif     
1.1.1.5   root     2430:            printf ("#ifdef HAVE_GET_WORD_UNSWAPPED\n");
                   2431: 
1.1.1.6 ! root     2432:            if (pos < 8 && (dmsk >> (8 - pos)) != 0)
        !          2433:                printf ("\tuae_u32 dstreg = ((opcode >> %d) | (opcode << %d)) & %d;\n",
        !          2434:                        pos ^ 8, 8 - pos, dmsk);
        !          2435:            else if (pos != 8)
1.1.1.5   root     2436:                printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
                   2437:                        pos ^ 8, dmsk);
                   2438:            else
                   2439:                printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
                   2440: 
                   2441:            printf ("#else\n");
                   2442: 
                   2443:            if (pos)
1.1.1.3   root     2444:                printf ("\tuae_u32 dstreg = (opcode >> %d) & %d;\n",
1.1.1.5   root     2445:                        pos, dmsk);
1.1.1.3   root     2446:            else
                   2447:                printf ("\tuae_u32 dstreg = opcode & %d;\n", dmsk);
1.1.1.5   root     2448: 
                   2449:            printf ("#endif\n");
1.1       root     2450:        }
                   2451:     }
1.1.1.5   root     2452:     need_endlabel = 0;
1.1.1.3   root     2453:     endlabelno++;
                   2454:     sprintf (endlabelstr, "endlabel%d", endlabelno);
                   2455:     gen_opcode (opcode);
1.1.1.5   root     2456:     if (need_endlabel)
1.1.1.6 ! root     2457:        printf ("%s: ;\n", endlabelstr);
1.1.1.5   root     2458:     printf ("return %d;\n", insn_n_cycles);
1.1.1.3   root     2459:     printf ("}\n");
                   2460:     opcode_next_clev[rp] = next_cpu_level;
                   2461:     opcode_last_postfix[rp] = postfix;
1.1       root     2462: }
                   2463: 
1.1.1.3   root     2464: static void generate_func (void)
1.1       root     2465: {
1.1.1.5   root     2466:     int i, j, rp;
1.1       root     2467: 
1.1.1.3   root     2468:     using_prefetch = 0;
                   2469:     using_exception_3 = 0;
                   2470:     for (i = 0; i < 5; i++) {
                   2471:        cpu_level = 3 - i;
                   2472:        if (i == 4) {
                   2473:            cpu_level = 0;
                   2474:            using_prefetch = 1;
                   2475:            using_exception_3 = 1;
                   2476:            for (rp = 0; rp < nr_cpuop_funcs; rp++)
                   2477:                opcode_next_clev[rp] = 0;
                   2478:        }
                   2479:        postfix = i;
                   2480:        fprintf (stblfile, "struct cputbl op_smalltbl_%d[] = {\n", postfix);
                   2481: 
1.1.1.5   root     2482:        /* sam: this is for people with low memory (eg. me :)) */
                   2483:        printf ("\n"
                   2484:                 "#if !defined(PART_1) && !defined(PART_2) && "
                   2485:                    "!defined(PART_3) && !defined(PART_4) && "
                   2486:                    "!defined(PART_5) && !defined(PART_6) && "
                   2487:                    "!defined(PART_7) && !defined(PART_8)"
                   2488:                "\n"
                   2489:                "#define PART_1 1\n"
                   2490:                "#define PART_2 1\n"
                   2491:                "#define PART_3 1\n"
                   2492:                "#define PART_4 1\n"
                   2493:                "#define PART_5 1\n"
                   2494:                "#define PART_6 1\n"
                   2495:                "#define PART_7 1\n"
                   2496:                "#define PART_8 1\n"
                   2497:                "#endif\n\n");
                   2498:        
                   2499:        rp = 0;
                   2500:        for(j=1;j<=8;++j) {
                   2501:                int k = (j*nr_cpuop_funcs)/8;
                   2502:                printf ("#ifdef PART_%d\n",j);
                   2503:                for (; rp < k; rp++)
                   2504:                   generate_one_opcode (rp);
                   2505:                printf ("#endif\n\n");
                   2506:        }
                   2507: 
1.1.1.3   root     2508:        fprintf (stblfile, "{ 0, 0, 0 }};\n");
1.1       root     2509:     }
                   2510: 
                   2511: }
                   2512: 
1.1.1.3   root     2513: int main (int argc, char **argv)
1.1.1.5   root     2514: {
1.1       root     2515:     read_table68k ();
                   2516:     do_merges ();
1.1.1.3   root     2517: 
1.1.1.5   root     2518:     opcode_map = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
                   2519:     opcode_last_postfix = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
                   2520:     opcode_next_clev = (int *) xmalloc (sizeof (int) * nr_cpuop_funcs);
                   2521:     counts = (unsigned long *) xmalloc (65536 * sizeof (unsigned long));
                   2522:     read_counts ();
1.1.1.3   root     2523: 
                   2524:     /* It would be a lot nicer to put all in one file (we'd also get rid of
                   2525:      * cputbl.h that way), but cpuopti can't cope.  That could be fixed, but
                   2526:      * I don't dare to touch the 68k version.  */
1.1.1.5   root     2527: 
1.1.1.3   root     2528:     headerfile = fopen ("cputbl.h", "wb");
                   2529:     stblfile = fopen ("cpustbl.c", "wb");
                   2530:     freopen ("cpuemu.c", "wb", stdout);
                   2531: 
                   2532:     generate_includes (stdout);
                   2533:     generate_includes (stblfile);
                   2534: 
                   2535:     generate_func ();
                   2536: 
                   2537:     free (table68k);
1.1       root     2538:     return 0;
                   2539: }

unix.superglobalmegacorp.com

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