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

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

unix.superglobalmegacorp.com

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