Annotation of previous/src/uae-cpu/gencpu.c, revision 1.1

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

unix.superglobalmegacorp.com

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