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

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

unix.superglobalmegacorp.com

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