Annotation of frontvm/as68k/output_i386.c, revision 1.1

1.1     ! root        1: 
        !             2: #include <assert.h>
        !             3: #include <stdio.h>
        !             4: #include <stdlib.h>
        !             5: #include <string.h>
        !             6: #include <ctype.h>
        !             7: #include <stdarg.h>
        !             8: #include "dict.h"
        !             9: #include "as68k.h"
        !            10: #include "output.h"
        !            11: 
        !            12: static op_t pending;
        !            13: static enum M68K_OPS next_op_type;
        !            14: static char *pending_labels, *cur_labels;
        !            15: static int cur_bitpos;
        !            16: /* last instruction was a jsr/bsr, so must create an entry
        !            17:  * in the computed jump table for return point (this instr) */
        !            18: static int return_target;
        !            19: 
        !            20: #define LABBUF_LEN     32768
        !            21: 
        !            22: /* enable bounds checking and debug info in the generated turd */
        !            23: #define GEN_DEBUG
        !            24: //#define DUMP_LOADS_OF_CRAP
        !            25: 
        !            26: /* which flags an M68K_OP thingy may set */
        !            27: #define fZ     (1<<0)
        !            28: #define fNVC   (1<<1)
        !            29: #define fX     (1<<2)
        !            30: #define fNZVCX (fZ | fNVC | fX)
        !            31: #define fNZVC  (fZ | fNVC)
        !            32: #define fNVCX  (fX | fNVC)
        !            33: #define _fSafe 0
        !            34: /* _fSafe are ones i haven't got round to doing yet. */
        !            35: 
        !            36: /* does the flag need to be set? if the next instruction will
        !            37:  * set the flag then no. */
        !            38: #define ifZ    if(!(sets_flags[next_op_type] & fZ))
        !            39: #define ifNVC  if(!(sets_flags[next_op_type] & fNVC))
        !            40: #define ifZNVC if((!(sets_flags[next_op_type] & fZ)) || (!(sets_flags[next_op_type] & fNVC)))
        !            41: #define ifNVCX if((!(sets_flags[next_op_type] & fNVCX)))
        !            42: #define ifX    if(!(sets_flags[next_op_type] & fX))
        !            43: 
        !            44: /* XXX ONLY SET X FLAG FOR INSTRUCTIONS THAT OVERWRITE
        !            45:  * THE X FLAG __WITHOUT__ USING IT */
        !            46: 
        !            47: static int sets_flags[OP_MAX+1] = {
        !            48:        _fSafe, /* OP_NONE */
        !            49:        0, // OP_JMP
        !            50:        fZ, // OP_BCHG
        !            51:        fZ, // OP_BCLR
        !            52:        fZ, // OP_BSET
        !            53:        fZ, // OP_BTST
        !            54:        fNZVC, // OP_MULS
        !            55:        fNZVC, // OP_MULU,
        !            56:        fNZVC, // OP_AND
        !            57:        fNZVC, // OP_OR
        !            58:        fNZVC, // OP_XOR
        !            59:        fNZVC, // OP_NOT
        !            60:        fNZVC, // OP_NEGX
        !            61:        fNZVC, // OP_NEG
        !            62:        fNZVC, // OP_DIVU
        !            63:        fNZVC, // OP_DIVS
        !            64:        fNZVC, // OP_ASL,
        !            65:        fNZVCX, // OP_LSL
        !            66:        fNZVC, // OP_ROXR
        !            67:        fNZVC, // OP_ROXL
        !            68:        fNZVC, // OP_ROL
        !            69:        fNZVC, // OP_ROR
        !            70:        fNZVC, // OP_ASR
        !            71:        fNZVC, // OP_LSR,
        !            72:        0, // OP_MOVEM
        !            73:        fNZVC, // OP_SUBX
        !            74:        fNZVC, // OP_ADDX
        !            75:        fNZVCX, // OP_ADD
        !            76:        fNZVC, // OP_CMPA
        !            77:        fNZVC, // OP_CMP
        !            78:        fNZVCX, // OP_SUB,
        !            79:        _fSafe, // OP_ADDA
        !            80:        _fSafe, // OP_SUBA
        !            81:        fNZVC, // OP_SWAP
        !            82:        _fSafe, // OP_JSR
        !            83:        0, // OP_BCC
        !            84:        0, // OP_DBCC
        !            85:        fNZVC, // OP_CLR,
        !            86:        0, // OP_EXG
        !            87:        fNZVC, // OP_EXT
        !            88:        0, // OP_RTE
        !            89:        0, // OP_RTS
        !            90:        0, // OP_ILLEGAL
        !            91:        0, // OP_HCALL
        !            92:        0, // OP_LINK,
        !            93:        0, // OP_UNLK
        !            94:        fNZVC, // OP_MOVE
        !            95:        _fSafe, // OP_MOVEA
        !            96:        fNZVC, // OP_TST
        !            97:        0, // OP_PEA
        !            98:        0, // OP_LEA
        !            99:        0, // OP_SCC
        !           100:        _fSafe, // OP_MAX.....
        !           101: };
        !           102: 
        !           103: FILE *asm_out;
        !           104: 
        !           105: static void output_op (op_t *op, op_t *next);
        !           106: static void init_regalloc ();
        !           107: static void xflush_all ();
        !           108: 
        !           109: /* raw output */
        !           110: static void rout (const char *str)
        !           111: {
        !           112:        fputs (str, asm_out);
        !           113: }
        !           114: 
        !           115: /* formatted output */
        !           116: static void xout (const char *format, ...)
        !           117: {
        !           118:        va_list argptr;
        !           119: 
        !           120:        va_start (argptr, format);
        !           121:        vfprintf (asm_out, format, argptr);
        !           122:        va_end (argptr);
        !           123: }
        !           124: static void xln (const char *format, ...)
        !           125: {
        !           126:        va_list argptr;
        !           127: 
        !           128:        fputc ('\t', asm_out);
        !           129:        va_start (argptr, format);
        !           130:        vfprintf (asm_out, format, argptr);
        !           131:        va_end (argptr);
        !           132:        fputc ('\n', asm_out);
        !           133: }
        !           134: 
        !           135: static int regpos (int num)
        !           136: {
        !           137:        assert ((num >=0) && (num < 16));
        !           138:        return -64 + 4*num;
        !           139: }
        !           140: 
        !           141: #ifdef GEN_DEBUG
        !           142: static void set_line (int num)
        !           143: {
        !           144:        char buf[256];
        !           145: 
        !           146:        snprintf (buf, sizeof (buf), "  movl    $%d, line_no\n", num);
        !           147:        strcat (cur_labels, buf);
        !           148: }
        !           149: #endif
        !           150: 
        !           151: static int pending_flush, cur_flush;
        !           152: 
        !           153: void i386_label (const char *lab)
        !           154: {
        !           155:        char buf[256];
        !           156: 
        !           157:        /* lines that might be jumped to must have a consistent
        !           158:         * register state, so flush registers to memory before
        !           159:         * these lines. */
        !           160:        cur_flush = 1;
        !           161:        
        !           162:        snprintf (buf, sizeof (buf), "__N%s:\n", lab);
        !           163:        strcat (cur_labels, buf);
        !           164: 
        !           165:        add_fixup (0, C_ADDR, lab);
        !           166: }
        !           167: 
        !           168: void i386_addr_label (int labelled)
        !           169: {
        !           170:        char buf[256];
        !           171: 
        !           172:        if (labelled) {
        !           173:                cur_flush = 1;
        !           174:        }
        !           175:        
        !           176:        if (labelled || return_target) {
        !           177:                snprintf (buf, sizeof (buf), "__l%x", get_bitpos ());
        !           178:                add_fixup (get_bitpos (), C_ADDR, buf);
        !           179:        
        !           180:                snprintf (buf, sizeof (buf), "__l%x:\n", get_bitpos ());
        !           181:                strcat (cur_labels, buf);
        !           182:        } else {
        !           183: #ifdef GEN_DEBUG
        !           184:                snprintf (buf, sizeof (buf), "/* 0x%x */\n", get_bitpos ());
        !           185:                strcat (cur_labels, buf);
        !           186: #endif
        !           187:        }
        !           188:        
        !           189:        cur_bitpos = get_bitpos ();
        !           190:        
        !           191: #ifdef GEN_DEBUG
        !           192:        set_line (line_no);
        !           193: 
        !           194: #ifdef DUMP_LOADS_OF_CRAP
        !           195:        strcat (cur_labels, "   call DumpRegsChanged\n");
        !           196: #endif /* DUMP_LOADS_OF_CRAP */
        !           197: #endif /* GEN_DEBUG */
        !           198: }
        !           199: 
        !           200: #ifdef WIN32
        !           201: void winsym (const char *sym)
        !           202: {
        !           203:        xout ("#define %s _%s\n", sym, sym);
        !           204: }
        !           205: #endif /* WIN32 */
        !           206: 
        !           207: void i386_begin (const char *src_filename, const char *bin_filename)
        !           208: {
        !           209:        char buf[128];
        !           210:        snprintf (buf, sizeof (buf), ".%s.S", src_filename);
        !           211:        if ((asm_out = fopen (buf, "w"))==NULL) {
        !           212:                fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
        !           213:                exit (-1);
        !           214:        }
        !           215: 
        !           216:        init_regalloc ();
        !           217: 
        !           218:        pending_labels = NULL;
        !           219:        cur_labels = calloc (LABBUF_LEN, 1);
        !           220:        
        !           221:        xout ("#define MEM_SIZE 0x110000\n");
        !           222:        xout ("#define PROC_STATE 64\n");
        !           223:        xout ("#define MemBase  STData+PROC_STATE\n\n");
        !           224: 
        !           225:        xln (".data");
        !           226:        /* memory size + registers */
        !           227:        xln (".comm     STData,MEM_SIZE+PROC_STATE");
        !           228:        xln (".comm     X,4");
        !           229:        xln (".comm     N,4");
        !           230:        xln (".comm     Z,4");
        !           231:        xln (".comm     V,4");
        !           232:        xln (".comm     C,4");
        !           233:        /* register backing store for during exception handling */
        !           234:        xln (".comm     bX,4");
        !           235:        xln (".comm     bN,4");
        !           236:        xln (".comm     bZ,4");
        !           237:        xln (".comm     bV,4");
        !           238:        xln (".comm     bC,4");
        !           239:        /* exception return address */
        !           240:        xln (".comm     rdest,4");
        !           241:        xln (".comm     exceptions_pending_mask,4");
        !           242:        xln (".comm     exceptions_pending_nums,32");
        !           243:        xln (".comm     exception_handlers,4*32");
        !           244:        xln (".comm     line_no,4");
        !           245: #ifdef GEN_DEBUG
        !           246:        xout ("debugstr:        .string \"$%%x $%%x $%%x $%%x $%%x $%%x $%%x $%%x*$%%x $%%x $%%x $%%x $%%x $%%x $%%x $%%x:%%d\\n\"\n");
        !           247: #endif
        !           248:        xout (" .global STRam\n");
        !           249:        xout ("STRam:   .long   STData+PROC_STATE\n");
        !           250:        
        !           251:        xout (" .section        .rodata\n");
        !           252:        xout ("bin_filename:    .string \"%s\"\n", bin_filename);
        !           253:        xout ("open_mode:       .string \"r\"\n\n");
        !           254:        xout ("dreg_fmt:                .string \"D%%d = $%%08x\t\"\n");
        !           255:        xout ("areg_fmt:        .string \"A%%d = $%%08x\\n\"\n");
        !           256:        xout ("cr:              .string \"\\n\"\n");
        !           257:        xout ("cc_names:        .string \"XNZVC\"\n");
        !           258:        xout ("hex_fmt:         .string \"$%%02x \"\n");
        !           259:        xout ("illegal_fmt:     .string \"Illegal instruction at line %%d.\\n\"\n");
        !           260: 
        !           261:        xout (" .text\n");
        !           262:        
        !           263:        xout (".globl SetZFlag\n");
        !           264:        xout ("SetZFlag:\n");
        !           265:        rout (
        !           266: "      movl    4(%esp),%eax\n"
        !           267: "      movb    %al,Z\n"
        !           268: "      ret\n");
        !           269:        
        !           270:        xout (".globl GetXFlag\n");
        !           271:        xout ("GetXFlag:\n");
        !           272:        rout (
        !           273: "      movl    X,%eax\n"
        !           274: "      ret\n");
        !           275:        
        !           276:        xout (".globl GetZFlag\n");
        !           277:        xout ("GetZFlag:\n");
        !           278:        rout (
        !           279: "      movl    Z,%eax\n"
        !           280: "      ret\n");
        !           281:        
        !           282:        xout (".globl GetCFlag\n");
        !           283:        xout ("GetCFlag:\n");
        !           284:        rout (
        !           285: "      movl    C,%eax\n"
        !           286: "      ret\n");
        !           287:        
        !           288:        xout (".globl GetNFlag\n");
        !           289:        xout ("GetNFlag:\n");
        !           290:        rout (
        !           291: "      movl    N,%eax\n"
        !           292: "      ret\n");
        !           293:        
        !           294:        xout (".globl GetVFlag\n");
        !           295:        xout ("GetVFlag:\n");
        !           296:        rout (
        !           297: "      movl    V,%eax\n"
        !           298: "      ret\n");
        !           299: 
        !           300:        xout (".globl DumpRegs\n");
        !           301:        xout ("DumpRegs:\n");
        !           302:        rout (
        !           303: "      pushl   %ebp\n"
        !           304: "      pushl   %ebx\n"
        !           305: "      pushl   %ecx\n"
        !           306: "      pushl   %esi\n"
        !           307: "      movl    $STData,%ebx\n"
        !           308: "      xorl    %eax,%eax\n"
        !           309: "1:    pushl   %eax\n"
        !           310: "      pushl   (%ebx,%eax,4)\n"
        !           311: "      pushl   %eax\n"
        !           312: "      pushl   $dreg_fmt\n"
        !           313: "      call    printf\n"
        !           314: "      addl    $12,%esp\n"
        !           315: "      movl    (%esp),%eax\n"
        !           316: "      pushl   8*4(%ebx,%eax,4)\n"
        !           317: "      pushl   %eax\n"
        !           318: "      pushl   $areg_fmt\n"
        !           319: "      call    printf\n"
        !           320: "      addl    $12,%esp\n"
        !           321: "      popl    %eax\n"
        !           322: "      inc     %eax\n"
        !           323: "      cmpl    $8,%eax\n"
        !           324: "      jl      1b\n"
        !           325: /* print status flags */
        !           326: "      movb    X,%al\n"
        !           327: "      movl    $0,%ecx\n"
        !           328: "      call    print_scat\n"
        !           329: "      movb    N,%al\n"
        !           330: "      movl    $1,%ecx\n"
        !           331: "      call    print_scat\n"
        !           332: "      movb    Z,%al\n"
        !           333: "      movl    $2,%ecx\n"
        !           334: "      call    print_scat\n"
        !           335: "      movb    V,%al\n"
        !           336: "      movl    $3,%ecx\n"
        !           337: "      call    print_scat\n"
        !           338: "      movb    C,%al\n"
        !           339: "      movl    $4,%ecx\n"
        !           340: "      call    print_scat\n"
        !           341: "      pushl   $cr\n"
        !           342: "      call    printf\n"
        !           343: "      addl    $4,%esp\n"
        !           344: /* print memory contents */
        !           345: 
        !           346: "      movl    $STData+PROC_STATE,%esi\n"
        !           347: "      movl    $MEM_SIZE,%ebx\n"
        !           348: "1:    movzbl  (%esi),%eax\n"
        !           349: "      pushl   %eax\n"
        !           350: "      pushl   $hex_fmt\n"
        !           351: "      call    printf\n"
        !           352: "      addl    $8,%esp\n"
        !           353: "      inc     %esi\n"
        !           354: "      dec     %ebx\n"
        !           355: 
        !           356: "      testl   $15,%ebx\n"
        !           357: "      jz      3f\n"
        !           358: 
        !           359: "2:    testl   %ebx,%ebx\n"
        !           360: "      jnz     1b\n"
        !           361: 
        !           362: 
        !           363: "      popl    %esi\n"
        !           364: "      popl    %ecx\n"
        !           365: "      popl    %ebx\n"
        !           366: "      popl    %ebp\n"
        !           367: "      ret\n"
        !           368: 
        !           369: "3:    pushl   $cr\n"
        !           370: "      call    printf\n"
        !           371: "      addl    $4,%esp\n"
        !           372: "      jmp     2b\n"
        !           373: 
        !           374: "print_scat:\n"
        !           375: "      xorl    %ebx,%ebx\n"
        !           376: "      cmpb    %al,%bl\n"
        !           377: "      jz      1f\n"
        !           378: "      movb    cc_names(%ecx),%al\n"
        !           379: "      pushl   %eax\n"
        !           380: "      call    putchar\n"
        !           381: "      addl    $4,%esp\n"
        !           382: "1:    ret\n"
        !           383: );
        !           384:        
        !           385:        xout (".globl FlagException\n");
        !           386:        xout ("FlagException:\n");
        !           387:        rout (
        !           388: "      movl    4(%esp),%eax\n"
        !           389: "      btsl    %eax,exceptions_pending_mask\n"
        !           390: "      incb    exceptions_pending_nums(%eax)\n"
        !           391: "      ret\n");
        !           392:        
        !           393:        xout (".globl MemReadByte\n");
        !           394:        xout ("MemReadByte:\n");
        !           395:        rout (
        !           396: "      movl    4(%esp),%eax\n"
        !           397: "      movsbl  STData+PROC_STATE(%eax),%eax\n"
        !           398: "      ret\n");
        !           399: 
        !           400:        xout (".globl MemReadWord\n");
        !           401:        xout ("MemReadWord:\n");
        !           402:        rout (
        !           403: "      movl    4(%esp),%eax\n"
        !           404: "      movswl  STData+PROC_STATE(%eax),%eax\n"
        !           405: "      xchg    %al,%ah\n"
        !           406: "      ret\n");
        !           407: 
        !           408:        xout (".globl MemReadLong\n");
        !           409:        xout ("MemReadLong:\n");
        !           410:        rout (
        !           411: "      movl    4(%esp),%eax\n"
        !           412: "      movl    STData+PROC_STATE(%eax),%eax\n"
        !           413: "      bswap   %eax\n"
        !           414: "      ret\n");
        !           415: 
        !           416:        xout (".globl MemWriteByte\n");
        !           417:        xout ("MemWriteByte:\n");
        !           418:        rout (
        !           419: "      movl    4(%esp),%eax\n"
        !           420: "      movl    8(%esp),%edx\n"
        !           421: "      movb    %dl,STData+PROC_STATE(%eax)\n"
        !           422: "      ret\n");
        !           423: 
        !           424:        xout (".globl MemWriteWord\n");
        !           425:        xout ("MemWriteWord:\n");
        !           426:        rout (
        !           427: "      movl    8(%esp),%edx\n"
        !           428: "      movl    4(%esp),%eax\n"
        !           429: "      xchg    %dl,%dh\n"
        !           430: "      movw    %dx,STData+PROC_STATE(%eax)\n"
        !           431: "      ret\n");
        !           432: 
        !           433:        xout (".globl MemWriteLong\n");
        !           434:        xout ("MemWriteLong:\n");
        !           435:        rout (
        !           436: "      movl    8(%esp),%edx\n"
        !           437: "      movl    4(%esp),%eax\n"
        !           438: "      bswap   %edx\n"
        !           439: "      movl    %edx,STData+PROC_STATE(%eax)\n"
        !           440: "      ret\n");
        !           441: 
        !           442:        xout (".globl GetReg\n");
        !           443:        xout ("GetReg:\n");
        !           444:        rout (
        !           445: "      movl    4(%esp),%eax\n"
        !           446: "      movl    STData(,%eax,4),%eax\n"
        !           447: "      ret\n");
        !           448: 
        !           449:        xout (".globl SetReg\n");
        !           450:        xout ("SetReg:\n");
        !           451:        rout (
        !           452: "      movl    4(%esp),%eax\n"
        !           453: "      movl    8(%esp),%edx\n"
        !           454: "      movl    %edx,STData(,%eax,4)\n"
        !           455: "      ret\n");
        !           456: 
        !           457:        xout (".globl Init680x0\n");
        !           458:        xout ("Init680x0:\n");
        !           459:        rout (
        !           460: "      pushl   %esi\n"
        !           461: "      pushl   %ebx\n"
        !           462: "      pushl   $open_mode\n"
        !           463: "      pushl   $bin_filename\n"
        !           464: "      call    fopen\n"
        !           465: "      movl    %eax, %ebx\n"
        !           466: "      popl    %eax\n"
        !           467: "      xorl    %eax, %eax\n"
        !           468: "      testl   %ebx, %ebx\n"
        !           469: "      popl    %edx\n"
        !           470: "      je      1f\n"
        !           471: "      pushl   $2\n"
        !           472: "      pushl   $0\n"
        !           473: "      pushl   %ebx\n"
        !           474: "      call    fseek\n"
        !           475: "      pushl   %ebx\n"
        !           476: "      call    ftell\n"
        !           477: "      pushl   $0\n"
        !           478: "      movl    %eax, %esi\n"
        !           479: "      pushl   $0\n"
        !           480: "      pushl   %ebx\n"
        !           481: "      call    fseek\n"
        !           482: "      addl    $28, %esp\n"
        !           483: "      xorl    %eax, %eax\n"
        !           484: "      cmpl    $MEM_SIZE, %esi\n"
        !           485: "      jge     1f\n"
        !           486: "      pushl   %ebx\n"
        !           487: "      pushl   %esi\n"
        !           488: "      pushl   $1\n"
        !           489: "      pushl   $STData+PROC_STATE\n"
        !           490: "      call    fread\n"
        !           491: "      pushl   %ebx\n"
        !           492: "      call    fclose\n"
        !           493: "      movl    $1, %eax\n"
        !           494: "      addl    $20, %esp\n"
        !           495: "1:\n"
        !           496: "      popl    %ebx\n"
        !           497: "      popl    %esi\n"
        !           498: "      ret\n");
        !           499: 
        !           500:        xout (".globl Start680x0\n");
        !           501:        xout ("Start680x0:\n");
        !           502:        xout (" pushl   %%ebp\n");
        !           503:        xout (" pushl   %%esi\n");
        !           504:        xout (" pushl   %%edi\n");
        !           505:        xout (" pushl   %%edx\n");
        !           506:        xout (" pushl   %%ecx\n");
        !           507:        xout (" pushl   %%ebx\n");
        !           508:        xout (" movl    $STData+PROC_STATE,%%ebp\n\n");
        !           509:        //xout ("       movl    $0x110000,Regs+15*4");
        !           510: //     xout (" movl    $0x1c,%%edx");
        !           511: 
        !           512: //     xout (" jmp     jumptable");
        !           513: }
        !           514: 
        !           515: static void do_pending ();
        !           516: 
        !           517: void i386_end (const char *src_filename)
        !           518: {
        !           519:        /* some more crap needs to be added to the top */
        !           520:        int prev, i;
        !           521:        char c, buf[128];
        !           522:        FILE *f;
        !           523:        struct Fixup *fix;
        !           524:        struct Label *lab;
        !           525:        
        !           526:        /* output last instruction */
        !           527:        next_op_type = OP_NONE;
        !           528:        do_pending ();
        !           529:        
        !           530:        xout ("\n");
        !           531:        xflush_all ();
        !           532:        xln ("popl      %%ebx");
        !           533:        xln ("popl      %%ecx");
        !           534:        xln ("popl      %%edx");
        !           535:        xln ("popl      %%edi");
        !           536:        xln ("popl      %%esi");
        !           537:        xln ("popl      %%ebp");
        !           538:        xln ("ret");
        !           539: 
        !           540:        fclose (asm_out);
        !           541: 
        !           542:        snprintf (buf, sizeof (buf), "%s.S", src_filename);
        !           543:        if ((asm_out = fopen (buf, "w"))==NULL) {
        !           544:                fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
        !           545:                exit (-1);
        !           546:        }
        !           547: 
        !           548: #ifdef WIN32
        !           549:        winsym ("printf");
        !           550:        winsym ("hcalls");
        !           551:        winsym ("fopen");
        !           552:        winsym ("fseek");
        !           553:        winsym ("ftell");
        !           554:        winsym ("fclose");
        !           555:        winsym ("abort");
        !           556:        winsym ("putchar");
        !           557:        winsym ("fread");
        !           558:        winsym ("SetReg");
        !           559:        winsym ("GetReg");
        !           560:        winsym ("STRam");
        !           561:        winsym ("MemReadLong");
        !           562:        winsym ("MemReadWord");
        !           563:        winsym ("MemReadByte");
        !           564:        winsym ("MemWriteLong");
        !           565:        winsym ("MemWriteWord");
        !           566:        winsym ("MemWriteByte");
        !           567:        winsym ("GetZFlag");
        !           568:        winsym ("GetNFlag");
        !           569:        winsym ("GetVFlag");
        !           570:        winsym ("GetCFlag");
        !           571:        winsym ("GetXFlag");
        !           572:        winsym ("Init680x0");
        !           573:        winsym ("Start680x0");
        !           574:        winsym ("FlagException");
        !           575:        winsym ("line_no");
        !           576:        winsym ("exception_handlers");
        !           577: #endif /* WIN32 */
        !           578:        
        !           579:        /* address 'fixups' */
        !           580:        fix = fix_first;
        !           581:        for (; fix != NULL; fix = fix->next) {
        !           582:                if (fix->size != C_ADDR) continue;
        !           583: 
        !           584:                lab = get_label (fix->label);
        !           585:                if ((fix->adr != 0) || (!lab)) {
        !           586:                        continue;
        !           587:                }
        !           588:                xout ("#define __D%s 0x%x\n", lab->name, lab->val+BASE);
        !           589:        }
        !           590: 
        !           591:        /* computed jump table */
        !           592:        xln (".align 4");
        !           593:        xout ("jtab:\n");
        !           594:        
        !           595:        prev = -2;
        !           596:        fix = fix_first;
        !           597:        for (; fix != NULL; fix = fix->next) {
        !           598:                if (fix->size != C_ADDR) continue;
        !           599: 
        !           600:                lab = get_label (fix->label);
        !           601:                
        !           602:                if (!fix->adr) {
        !           603:                        /* ignore. let pass2 throw the error. */
        !           604:                        continue;
        !           605:                }
        !           606:                /* add ones since prev */
        !           607:                for (i=prev+2; i<fix->adr; i+=2) {
        !           608:                        xln (".long     bad_jmp");
        !           609:                }
        !           610:                xln (".long     %s", fix->label);
        !           611:                prev = fix->adr;
        !           612:        }
        !           613:        xout ("jumptable:\n");
        !           614:        xln ("jmp       *jtab(,%%eax,2)");
        !           615: #ifdef GEN_DEBUG
        !           616:        xout (" .section        .rodata\n");
        !           617:        xout ("bad_jmp_str:     .string \"Error. Bad jump target: $%%x at line %%d.\\n\"\n");
        !           618:        xln (".text");
        !           619:        xout ("bad_jmp:\n");
        !           620:        xln ("shll      $1,%%eax");
        !           621:        xln ("pushl     line_no");
        !           622:        xln ("pushl     %%eax");
        !           623:        xln ("pushl     $bad_jmp_str");
        !           624:        xln ("call      printf");
        !           625:        xln ("addl      $8,%%esp");
        !           626:        xln ("call      abort");
        !           627: #else
        !           628:        xout ("bad_jmp:\n");
        !           629:        xout ("bad_jmp2:\n");
        !           630:        xln ("call      abort");
        !           631: #endif
        !           632:        
        !           633:        /* the code we made */
        !           634:        snprintf (buf, sizeof (buf), ".%s.S", src_filename);
        !           635:        if ((f = fopen (buf, "r"))==NULL) {
        !           636:                fprintf (stderr, "Error: Cannot open %s for writing.\n", buf);
        !           637:                exit (-1);
        !           638:        }
        !           639:        while ((c = fgetc (f)) != EOF) fputc (c, asm_out);
        !           640:        fclose (f);
        !           641:        remove (buf);
        !           642: 
        !           643:        xout ("handle_exception:\n");
        !           644:        
        !           645:        /* no exceptions while in an exception handler */
        !           646:        xln ("movl      rdest,%%ebx");
        !           647:        xln ("testl     %%ebx,%%ebx");
        !           648:        xln ("jnz       jumptable");
        !           649: 
        !           650:        xln ("movl      %%eax,rdest");
        !           651:        
        !           652:        xln ("movl      exceptions_pending_mask,%%edx");
        !           653:        xln ("xorl      %%ecx,%%ecx");
        !           654:        xout ("1:\n");
        !           655:        xln ("btl       %%ecx,%%edx");
        !           656:        xln ("jnc       2f");
        !           657: 
        !           658:        /* yay. exception num %ecx pending */
        !           659:        xln ("movl      $exception_handlers,%%ebx");
        !           660:        xln ("movb      exceptions_pending_nums(%%ecx),%%al");
        !           661:        xln ("decb      %%al");
        !           662:        xln ("jnz       3f");
        !           663:        xln ("btrl      %%ecx,exceptions_pending_mask");
        !           664:        xln ("3: movb   %%al,exceptions_pending_nums(%%ecx)");
        !           665:        xln ("movl      (%%ebx,%%ecx,4),%%eax");
        !           666:        xln ("movb      X,%%bh");
        !           667:        xln ("movb      N,%%bl");
        !           668:        xln ("movb      Z,%%ch");
        !           669:        xln ("movb      V,%%cl");
        !           670:        xln ("movb      C,%%dh");
        !           671:        xln ("movb      %%bh,bX");
        !           672:        xln ("movb      %%bl,bN");
        !           673:        xln ("movb      %%ch,bZ");
        !           674:        xln ("movb      %%cl,bV");
        !           675:        xln ("movb      %%dh,bC");
        !           676:        xln ("jmp       jumptable");
        !           677: 
        !           678:        xout ("2:\n");
        !           679:        xln ("inc       %%ecx");
        !           680:        xln ("cmpl      $32,%%ecx");
        !           681:        xln ("jl        1b");
        !           682:        /* shouldn't get here... */
        !           683:        xln ("movl      rdest,%%eax");
        !           684:        xln ("movl      $0,rdest");
        !           685:        xln ("jmp       jumptable");
        !           686:        fclose (asm_out);
        !           687: }
        !           688: 
        !           689: static int is_reg (ea_t *ea)
        !           690: {
        !           691:        return ((ea->mode == 0) || (ea->mode == 1));
        !           692: }
        !           693: 
        !           694: static int is_immediate (ea_t *ea)
        !           695: {
        !           696:        return ((ea->mode == 7) && (ea->reg == 4));
        !           697: }
        !           698: 
        !           699: /* only x86 regs used in effective address shit. */
        !           700: enum X86REG {
        !           701:        EAX, EBX, ECX, EDX, ESI, EDI, X86REG_MAX
        !           702: };
        !           703: 
        !           704: /* m68k -> i386 reg allocation. age goes up with disuse */
        !           705: struct reg_alloc {
        !           706:        int m68k_reg;
        !           707:        int age;
        !           708:        int dirty;
        !           709:        int locked;
        !           710: };
        !           711: 
        !           712: #define xreg_unlock(reg) i386_regalloc[reg].locked--;
        !           713: #define xdirty_reg(reg)        {if (reg!=-1) i386_regalloc[reg].dirty = 1; }
        !           714: 
        !           715: /* set m68k_reg to REG_TEMP when allocating a reg as a temporary value,
        !           716:  * ie not holding a specific m68k reg's value */
        !           717: #define REG_TEMP       16
        !           718: 
        !           719: static struct reg_alloc i386_regalloc[X86REG_MAX];
        !           720: 
        !           721: /* x86 asm syntax is a pain in the arse for auto-generated stuff */
        !           722: static const char *reg_turd[3][X86REG_MAX] = {
        !           723:        { "%al", "%bl", "%cl", "%dl", "%invalid1", "%invalid2" },
        !           724:        { "%ax", "%bx", "%cx", "%dx", "%si", "%di" },
        !           725:        { "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" }
        !           726: };
        !           727: 
        !           728: static const char *szsconv[] = { "sbl", "swl", "l" };
        !           729: //static const char *szuconv[] = { "zbl", "zwl", "l" };
        !           730: static const char *szmov[] = { "b", "w", "l" };
        !           731: static const char *szfull[] = { "l", "l", "l" };
        !           732: 
        !           733: static const char *xreg (enum X86REG _reg, int size)
        !           734: {
        !           735:        return reg_turd[size][_reg];
        !           736: }
        !           737: 
        !           738: static void init_regalloc ()
        !           739: {
        !           740:        int i;
        !           741:        for (i=0; i<X86REG_MAX; i++) {
        !           742:                i386_regalloc[i].m68k_reg = -1;
        !           743:                i386_regalloc[i].locked = 0;
        !           744:        }
        !           745: }
        !           746: 
        !           747: static void xflush_reg (int x86_reg)
        !           748: {
        !           749:        int m68k_reg = i386_regalloc[x86_reg].m68k_reg;
        !           750: 
        !           751:        if (i386_regalloc[x86_reg].locked != 0) {
        !           752:                bug_error ("Internal compiler error. Attept to flush locked register.");
        !           753:        }
        !           754:        if (m68k_reg == -1) return;
        !           755:        assert (m68k_reg <= REG_TEMP);
        !           756: 
        !           757:        /* temps can simply be discarded. */
        !           758:        if (m68k_reg == REG_TEMP) {
        !           759:                i386_regalloc[x86_reg].m68k_reg = -1;
        !           760:                return;
        !           761:        }
        !           762:        /* while real m68k reg values must be flushed to memory */
        !           763:        if (i386_regalloc[x86_reg].dirty)
        !           764:                xln ("movl      %s,%d(%%ebp)", xreg (x86_reg, LONG), regpos (m68k_reg));
        !           765:        i386_regalloc[x86_reg].m68k_reg = -1;
        !           766:        i386_regalloc[x86_reg].dirty = 0;
        !           767: }
        !           768: 
        !           769: static void xflush_all ()
        !           770: {
        !           771:        int i;
        !           772:        for (i=0; i<X86REG_MAX; i++) {
        !           773:                if (i386_regalloc[i].m68k_reg != -1) 
        !           774:                        xflush_reg (i);
        !           775:        }
        !           776: }
        !           777: 
        !           778: /* return -1 if not cached */
        !           779: static int xfind_reg (int m68k_reg)
        !           780: {
        !           781:        int i;
        !           782:        for (i=0; i<X86REG_MAX; i++) {
        !           783:                if (i386_regalloc[i].m68k_reg == m68k_reg) {
        !           784:                        i386_regalloc[i].age = 0;
        !           785:                        return i;
        !           786:                }
        !           787:        }
        !           788:        return -1;
        !           789: }
        !           790: 
        !           791: static void xregalloc_age ()
        !           792: {
        !           793:        int i;
        !           794:        for (i=0; i<X86REG_MAX; i++) {
        !           795:                i386_regalloc[i].age++;
        !           796:        }
        !           797: }
        !           798: 
        !           799: /* set x86reg_preferred = whatever X86REG you MUST HAVE.
        !           800:  * need_bswap=1 means that */
        !           801: static enum X86REG xalloc_reg (int size, int x86reg_preferred)
        !           802: {
        !           803:        int i, top, oldest, age;
        !           804:        if (x86reg_preferred != -1) {
        !           805:                xflush_reg (x86reg_preferred);
        !           806:                i386_regalloc[x86reg_preferred].m68k_reg = REG_TEMP;
        !           807:                i386_regalloc[x86reg_preferred].dirty = 0;
        !           808:                return x86reg_preferred;
        !           809:        }
        !           810:        /* look for unused reg */
        !           811:        /* if we want BYTE size then regs esi,edi are no use */
        !           812:        oldest = -1;
        !           813:        age = -1;
        !           814:        top = ((size == BYTE) ? ESI : X86REG_MAX);
        !           815:        for (i=0; i<top; i++) {
        !           816:                if (i386_regalloc[i].locked) continue;
        !           817:                /* unallocated and unlocked temps can always be discarded */
        !           818:                if ((i386_regalloc[i].m68k_reg == -1) ||
        !           819:                    (i386_regalloc[i].m68k_reg == REG_TEMP)) {
        !           820:                        i386_regalloc[i].m68k_reg = REG_TEMP;
        !           821:                        i386_regalloc[i].dirty = 0;
        !           822:                        i386_regalloc[i].locked = 1;
        !           823:                        return i;
        !           824:                }
        !           825:                if (oldest == -1) {
        !           826:                        oldest = i;
        !           827:                        age = i386_regalloc[i].age;
        !           828:                } else if (i386_regalloc[i].age > age) {
        !           829:                        oldest = i;
        !           830:                        age = i386_regalloc[i].age;
        !           831:                }       
        !           832:        }
        !           833:        /* oh well.. we must evict a cached reg */
        !           834:        if (oldest == -1) {
        !           835:                error ("Internal compiler error: Run out of x86 registers (leaked temporaries?)");
        !           836:        }
        !           837:        xflush_reg (oldest);
        !           838:        i386_regalloc[oldest].m68k_reg = REG_TEMP;
        !           839:        i386_regalloc[oldest].dirty = 0;
        !           840:        i386_regalloc[oldest].locked = 1;
        !           841:        return oldest;
        !           842: }
        !           843: 
        !           844: #define XLOADREG_FOR_OVERWRITE (1<<0)
        !           845: 
        !           846: static enum X86REG xmove_reg (int size, enum X86REG src, enum X86REG dest)
        !           847: {
        !           848:        assert (!i386_regalloc[src].locked);
        !           849:        i386_regalloc[src].locked = 1;
        !           850:        dest = xalloc_reg (size, dest);
        !           851:        xln ("movl      %s,%s", xreg (src,LONG), xreg (dest,LONG));
        !           852:        i386_regalloc[dest] = i386_regalloc[src];
        !           853:        i386_regalloc[dest].age = 0;
        !           854:        i386_regalloc[src].locked = 0;
        !           855:        i386_regalloc[src].dirty = 0;
        !           856:        i386_regalloc[src].m68k_reg = -1;
        !           857:        return dest;
        !           858: }
        !           859: 
        !           860: static enum X86REG xload_reg2 (int m68k_reg, int size, int required_x86_reg, int flags, const char **conv)
        !           861: {
        !           862:        int i;
        !           863:        //static int crap;
        !           864:        /* is it already loaded? */
        !           865:        for (i=0; i<X86REG_MAX; i++) {
        !           866:                if (i386_regalloc[i].m68k_reg != m68k_reg) {
        !           867:                        continue;
        !           868:                } else {
        !           869:                        if ((required_x86_reg != -1) &&
        !           870:                            (i != required_x86_reg)) {
        !           871:                                /* reg loaded but not in desired place. do it */
        !           872:                                return xmove_reg (size, i, required_x86_reg);
        !           873:                        }
        !           874:                }
        !           875: 
        !           876:                if ((size == BYTE) && (i >= ESI)) {
        !           877:                        /* can't operate on byte values in the esi/edi regs */
        !           878:                        //printf ("stupid esi/edi shit (no worries mate (n %d, line %d)\n", crap++, line_no);
        !           879:                        
        !           880:                        xflush_reg (i);
        !           881:                        //return xmove_reg (size, i);
        !           882:                } else {
        !           883:                        i386_regalloc[i].age = 0;
        !           884:                        i386_regalloc[i].locked++;
        !           885:                        return i;
        !           886:                }
        !           887:        }
        !           888:        /* otherwise allocate.. */
        !           889:        i = xalloc_reg (size, required_x86_reg);
        !           890: 
        !           891:        /* registers loaded for overwrite size long do not need the original value */
        !           892:        if (! ((flags & XLOADREG_FOR_OVERWRITE) && (size == LONG)))
        !           893:                xln ("mov%s     %d(%%ebp),%s", conv[size], regpos (m68k_reg), xreg (i, LONG));
        !           894: 
        !           895:        i386_regalloc[i].m68k_reg = m68k_reg;
        !           896:        i386_regalloc[i].age = 0;
        !           897:        i386_regalloc[i].dirty = 0;
        !           898:        i386_regalloc[i].locked = 1;
        !           899:        return i;
        !           900: }
        !           901: static enum X86REG xload_reg (int m68k_reg, int size, int required_x86_reg)
        !           902: {
        !           903:        return xload_reg2 (m68k_reg, size, required_x86_reg, 0, szfull);
        !           904: }
        !           905: 
        !           906: enum RegConversion { XCONV_NONE, XCONV_SWL, XCONV_ZWL };
        !           907: /* returns a temporary reg alloc copy of an m68k register, that you can do
        !           908:  * what the fuck you like with */
        !           909: #define xcopy_reg(m68k_reg,size,required_x86_reg) \
        !           910:        xcopy_reg2 (m68k_reg, size, required_x86_reg, 0)
        !           911: static enum X86REG xcopy_reg2 (int m68k_reg, int size, int required_x86_reg, enum RegConversion conversion)
        !           912: {
        !           913:        int reg, copy_reg;
        !           914: 
        !           915:        /* i wonder if it is an optimisation to load directly to copy reg
        !           916:         * when the reg is not already cached.. */
        !           917:        reg = xload_reg (m68k_reg, size, -1);
        !           918:        copy_reg = xalloc_reg (size, required_x86_reg);
        !           919:        
        !           920:        switch (conversion) {
        !           921:                case XCONV_NONE:
        !           922:                        xln ("mov%s     %s,%s", szmov[size], xreg (reg, size), xreg (copy_reg, size));
        !           923:                        break;
        !           924:                case XCONV_SWL:
        !           925:                        assert (size == LONG);
        !           926:                        xln ("movswl    %s,%s", szmov[size], xreg (reg, WORD), xreg (copy_reg, LONG));
        !           927:                        break;
        !           928:                case XCONV_ZWL:
        !           929:                        assert (size == LONG);
        !           930:                        xln ("movzwl    %s,%s", szmov[size], xreg (reg, WORD), xreg (copy_reg, LONG));
        !           931:                        break;
        !           932:        }
        !           933:        xreg_unlock (reg);
        !           934:        return copy_reg;
        !           935: }
        !           936: 
        !           937: static int rset[2] = { EAX, EBX };
        !           938: static int rdirty[2] = { ECX, EDX };
        !           939: 
        !           940: #define sreg(reg)      xreg ((reg), size)
        !           941: 
        !           942: static void x_postea (ea_t *ea)
        !           943: {
        !           944:        int inc, reg;
        !           945:        
        !           946:        inc = 1<<ea->op_size;
        !           947:        if ((ea->reg == 15) && (inc == 1)) inc = 2;
        !           948:        /* deallocate temporary register allocations */
        !           949:        if (ea->x86_reg != -1) {
        !           950:                xreg_unlock (ea->x86_reg);
        !           951:        }
        !           952:        if (ea->x86_reg_writeback != -1) {
        !           953:                xreg_unlock (ea->x86_reg_writeback);
        !           954:        }
        !           955:        
        !           956:        switch (ea->mode) {
        !           957:                /* areg postinc */
        !           958:                case 3:
        !           959:                        reg = xload_reg (ea->reg, LONG, -1);
        !           960:                        xdirty_reg (reg);
        !           961:                        if (inc == 1)
        !           962:                                xln ("incl      %s", xreg (reg, LONG));
        !           963:                        else
        !           964:                                xln ("addl      $%d,%s", inc, xreg (reg, LONG));
        !           965:                        xreg_unlock (reg);
        !           966:                        break;
        !           967:                /* areg predec */
        !           968:                case 4:
        !           969:                        reg = xload_reg (ea->reg, LONG, -1);
        !           970:                        xdirty_reg (reg);
        !           971:                        if (inc == 1)
        !           972:                                xln ("decl      %s", xreg (reg, LONG));
        !           973:                        else
        !           974:                                xln ("subl      $%d,%s", inc, xreg (reg, LONG));
        !           975:                        xreg_unlock (reg);
        !           976:                        break;
        !           977:                default: break;
        !           978:        }
        !           979: }
        !           980: 
        !           981: #define        _S(x)   if (stage[arg] == (x))
        !           982: 
        !           983: /*
        !           984:  * Note on these multi-stage pipeline turds. The value must be actually
        !           985:  * set in val_reg on the final stage, final instruction, so that the
        !           986:  * condition codes are available.
        !           987:  *
        !           988:  * Actually used stages should be the final ones, if not all are needed.
        !           989:  */
        !           990: 
        !           991: /*
        !           992:  * Returns zero when done.
        !           993:  */
        !           994: static void xold_ea_get_address (ea_t *ea, int arg, int advance_stage)
        !           995: {
        !           996:        static int stage[2] = {1,1};
        !           997:        int rpos, inc;
        !           998: 
        !           999:        if (!advance_stage) {
        !          1000:                if (stage[arg] != 1)    error ("xold_ea_get_address stages missed. (as68k bug).");
        !          1001: 
        !          1002:                stage[arg] = 0;
        !          1003:        } else {
        !          1004:                stage[arg]++;
        !          1005:        }
        !          1006:        
        !          1007:        ea->x86_reg = -1;
        !          1008:        
        !          1009:        switch (ea->mode) {
        !          1010:                /* dreg, areg */
        !          1011:                case 0: case 1: assert (0);
        !          1012:                /* areg indirect, postinc */
        !          1013:                case 2: case 3:
        !          1014:                        _S(1) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rset[arg],LONG));
        !          1015:                        break;
        !          1016:                /* areg predec */
        !          1017:                case 4: 
        !          1018:                        inc = 1<<ea->op_size;
        !          1019:                        /* stack pointer always by 2 */
        !          1020:                        if ((ea->reg == 15) && (inc == 1)) inc = 2;
        !          1021:                        
        !          1022:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rset[arg],LONG));
        !          1023:                        //XXX
        !          1024:                        _S(1) {
        !          1025:                                if (inc == 1) xln ("dec %s", xreg (rset[arg],LONG));
        !          1026:                                else xln ("subl $%d,%s", inc, xreg (rset[arg],LONG));
        !          1027:                        }
        !          1028:                        break;
        !          1029:                /* areg offset */
        !          1030:                case 5:
        !          1031:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rset[arg],LONG));
        !          1032:                        //XXX
        !          1033:                        _S(1) xln ("addl        $%d,%s", ea->imm.val, xreg (rset[arg],LONG));
        !          1034:                        break;
        !          1035:                /* areg offset + reg */
        !          1036:                case 6:
        !          1037:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rset[arg],LONG));
        !          1038:                        if (ea->ext._.size) {
        !          1039:                                _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[arg], LONG));
        !          1040:                        } else {
        !          1041:                                _S(0) xln ("movswl      %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[arg], LONG));
        !          1042:                        }
        !          1043:                        _S(0) xln ("addl        $%d,%s", ea->ext._.displacement, xreg (rset[arg],LONG));
        !          1044:                        //XXX
        !          1045:                        _S(1) xln ("addl        %s,%s", xreg (rdirty[arg], LONG), xreg (rset[arg],LONG));
        !          1046:                        break;
        !          1047:                /* yes */
        !          1048:                case 7:
        !          1049:                        /* $xxx.w */
        !          1050:                        if (ea->reg == 0) {
        !          1051:                                _S(1) xln ("movl        $%d,%s", ea->imm.val, xreg (rset[arg],LONG));
        !          1052:                        }
        !          1053:                        /* $xxx.l */
        !          1054:                        else if (ea->reg == 1) {
        !          1055:                                if (ea->imm.has_label) {
        !          1056:                                        _S(1) xln ("movl        $__D%s,%s", ea->imm.label, xreg (rset[arg],LONG));
        !          1057:                                } else {
        !          1058:                                        _S(1) xln ("movl        $%d,%s", ea->imm.val, xreg (rset[arg],LONG));
        !          1059:                                }
        !          1060:                        }
        !          1061:                        /* immediate */
        !          1062:                        else if (ea->reg == 4) {
        !          1063:                                assert (0);
        !          1064:                        }
        !          1065:                        /* PC + offset */
        !          1066:                        else if (ea->reg == 2) {
        !          1067:                                if (ea->imm.has_label) {
        !          1068:                                        _S(1) xln ("movl        $__D%s,%s", ea->imm.label, xreg (rset[arg],LONG));
        !          1069:                                } else
        !          1070:                                        error ("Absolute value not allowed.");
        !          1071:                        }
        !          1072:                        /* PC + INDEX + OFFSET */
        !          1073:                        else if (ea->reg == 3) {
        !          1074:                                if (!ea->imm.has_label) error ("Absolute value not allowed.");
        !          1075:                                rpos = regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0));
        !          1076:                                if (ea->ext._.size) {
        !          1077:                                        _S(0) xln ("movl        %d(%%ebp),%s", rpos, xreg (rset[arg],LONG));
        !          1078:                                } else {
        !          1079:                                        _S(0) xln ("movswl      %d(%%ebp),%s", rpos, xreg (rset[arg],LONG));
        !          1080:                                }
        !          1081:                                // XXX
        !          1082:                                _S(1) xln ("addl        $__D%s,%s", ea->imm.label, xreg (rset[arg],LONG));
        !          1083:                        }
        !          1084:                        break;
        !          1085:                default:
        !          1086:                        assert (0);
        !          1087:        }
        !          1088: }
        !          1089: 
        !          1090: static void do_bswap (enum X86REG val, int size)
        !          1091: {
        !          1092:        switch (size) {
        !          1093:                case BYTE:      return;
        !          1094:                case WORD:      xln ("rorw      $8,%s", xreg (val, WORD));
        !          1095:                                return;
        !          1096:                case LONG:      xln ("bswap     %s", xreg (val, LONG));
        !          1097:                                return;
        !          1098:        }
        !          1099: }
        !          1100: 
        !          1101: /*
        !          1102:  * To avoid pipeline stalls the function outputs code until
        !          1103:  * a pipeline stall occurs, and then returns.
        !          1104:  * First call should be made with advance_stage == 0, subsequent
        !          1105:  * calls with advance_stage==1.
        !          1106:  * And then put shit inbetween.
        !          1107:  *
        !          1108:  * flag XQUICK_REGS means that for "reading" immediate values,
        !          1109:  * and XQUICK_REGS values in registers, nothing is done and instead ea->identifier
        !          1110:  * string is set to (for example) "$1234" or the i386 EA of the reg.
        !          1111:  *
        !          1112:  * XCAN_OVERWRITE means that you can modify the returned value because
        !          1113:  * it is a copy of the cached register (if it is a register, otherwise
        !          1114:  * this flag has no effect).
        !          1115:  */
        !          1116: #define XQUICK_REGS    (1<<0)
        !          1117: #define XQUICK_IMMS    (1<<1)
        !          1118: #define XQUICK_WRITEBACK       (1<<2)
        !          1119: #define XCAN_OVERWRITE (1<<3)
        !          1120: #define XSIGN_EXTEND_REGS      (1<<4)
        !          1121: 
        !          1122: #define xold_readea(ea,arg,adv)        xold_readea2(ea,arg,adv,0);
        !          1123: static void xold_readea2 (ea_t *ea, int arg, int advance_stage, int flags)
        !          1124: {
        !          1125:        static int stage[2] = {2,2};
        !          1126:        int inc, size;
        !          1127:        size = ea->op_size;
        !          1128: 
        !          1129:        if (!advance_stage) {
        !          1130:                if (stage[arg] != 2)    error ("xold_readea stages missed. (as68k bug).");
        !          1131: 
        !          1132:                stage[arg] = 0;
        !          1133:        } else {
        !          1134:                stage[arg]++;
        !          1135:        }
        !          1136: 
        !          1137:        ea->do_writeback = 1;
        !          1138:        ea->x86_reg_writeback = -1;
        !          1139:        ea->x86_reg = -1;
        !          1140:        
        !          1141:        switch (ea->mode) {
        !          1142:                /* dreg, areg */
        !          1143:                case 0:
        !          1144:                case 1:
        !          1145:                        if (flags & XQUICK_REGS) {
        !          1146:                                /* operate in-place (in memory) */
        !          1147:                                _S(0) snprintf (ea->identifier, sizeof (ea->identifier), "%d(%%ebp)", regpos (ea->reg));
        !          1148:                                ea->do_writeback = 0;
        !          1149:                                return;
        !          1150:                        }
        !          1151:                        _S(2) xln ("mov%s       %d(%%ebp),%s", szmov[size], regpos (ea->reg), xreg (rset[arg], size));
        !          1152:                        break;
        !          1153:                /* areg indirect */
        !          1154:                case 2:
        !          1155:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[arg], LONG));
        !          1156:                        _S(1) xln ("mov%s       (%%ebp,%s),%s", szmov[size], xreg (rdirty[arg], LONG), xreg (rset[arg], size));
        !          1157:                        _S(2) do_bswap (rset[arg], size);
        !          1158:                        break;
        !          1159:                /* areg postinc */
        !          1160:                case 3:
        !          1161:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[arg], LONG));
        !          1162:                        _S(1) xln ("mov%s       (%%ebp,%s),%s", szmov[size], xreg (rdirty[arg], LONG), xreg (rset[arg], size));
        !          1163:                        _S(2) do_bswap (rset[arg], size);
        !          1164:                        break;
        !          1165:                /* areg predec */
        !          1166:                case 4:
        !          1167:                        inc = 1<<size;
        !          1168:                        /* stack pointer always by 2 */
        !          1169:                        if ((ea->reg == 15) && (inc == 1)) inc = 2;
        !          1170:                        
        !          1171:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[arg], LONG));
        !          1172:                        _S(1) xln ("mov%s       -%d(%%ebp,%s),%s", szmov[size], inc, xreg (rdirty[arg], LONG), xreg (rset[arg], size));
        !          1173:                        _S(2) do_bswap (rset[arg], size);
        !          1174:                        break;
        !          1175:                /* areg offset */
        !          1176:                case 5:
        !          1177:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[arg], LONG));
        !          1178:                        _S(1) xln ("mov%s       %d(%%ebp,%s),%s", szmov[size], ea->imm.val, xreg (rdirty[arg], LONG), xreg (rset[arg], size));
        !          1179:                        _S(2) do_bswap (rset[arg], size);
        !          1180:                        break;
        !          1181:                /* areg offset + reg */
        !          1182:                case 6:
        !          1183:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[arg],LONG));
        !          1184:                        if (ea->ext._.size) {
        !          1185:                                _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rset[arg],LONG));
        !          1186:                        } else {
        !          1187:                                _S(0) xln ("movswl      %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rset[arg], LONG));
        !          1188:                        }
        !          1189:                        _S(0) xln ("addl        %%ebp,%s", xreg (rdirty[arg],LONG));
        !          1190:                        _S(1) xln ("mov%s       %d(%s,%s),%s", szmov[size], ea->ext._.displacement, xreg (rdirty[arg],LONG), xreg (rset[arg],LONG), xreg (rset[arg], size));
        !          1191:                        _S(2) do_bswap (rset[arg], size);
        !          1192:                        break;
        !          1193:                /* yes */
        !          1194:                case 7:
        !          1195:                        /* $xxx.w */
        !          1196:                        if (ea->reg == 0) {
        !          1197:                                _S(1) xln ("mov%s       %d(%%ebp),%s", szmov[size], ea->imm.val, xreg (rset[arg], size));
        !          1198:                                _S(1) do_bswap (rset[arg], size);
        !          1199:                        }
        !          1200:                        /* $xxx.l */
        !          1201:                        else if (ea->reg == 1) {
        !          1202:                                if (ea->imm.has_label) {
        !          1203:                                        _S(1) xln ("mov%s       __D%s(%%ebp),%s", szmov[size], ea->imm.label, xreg (rset[arg], size));
        !          1204:                                        _S(2) do_bswap (rset[arg], size);
        !          1205:                                } else {
        !          1206:                                        _S(1) xln ("mov%s       %d(%%ebp),%s", szmov[size], ea->imm.val, xreg (rset[arg], size));
        !          1207:                                        _S(2) do_bswap (rset[arg], size);
        !          1208:                                }
        !          1209:                        }
        !          1210:                        /* immediate */
        !          1211:                        else if (ea->reg == 4) {
        !          1212:                                if (flags & XQUICK_IMMS) {
        !          1213:                                        if (ea->imm.has_label) {
        !          1214:                                                _S(0) snprintf (ea->identifier, sizeof (ea->identifier),
        !          1215:                                                        "$__D%s", ea->imm.label);
        !          1216:                                        } else {
        !          1217:                                                _S(0) snprintf (ea->identifier, sizeof (ea->identifier),
        !          1218:                                                        "$%d", ea->imm.val);
        !          1219:                                        }
        !          1220:                                        return;
        !          1221:                                }
        !          1222:                                if (ea->imm.has_label) {
        !          1223:                                        _S(2) xln ("movl        $__D%s,%s", ea->imm.label, xreg (rset [arg], LONG));
        !          1224:                                } else {
        !          1225:                                        _S(2) xln ("movl        $%d,%s", ea->imm.val, xreg (rset [arg], LONG));
        !          1226:                                }
        !          1227:                        }
        !          1228:                        /* PC + offset */
        !          1229:                        else if (ea->reg == 2) {
        !          1230:                                assert (ea->imm.has_label);
        !          1231: 
        !          1232:                                _S(1) xln ("mov%s       __D%s(%%ebp),%s", szmov[size], ea->imm.label, xreg (rset[arg], size));
        !          1233:                                _S(2) do_bswap (rset[arg], size);
        !          1234:                        }
        !          1235:                        /* PC + INDEX + OFFSET */
        !          1236:                        else if (ea->reg == 3) {
        !          1237:                                assert (ea->imm.has_label);
        !          1238:                                if (ea->ext._.size) {
        !          1239:                                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[arg],LONG));
        !          1240:                                } else {
        !          1241:                                        _S(0) xln ("movswl      %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[arg], LONG));
        !          1242:                                }
        !          1243:                                _S(1) xln ("mov%s       __D%s(%%ebp,%s),%s", szmov[size], ea->imm.label, xreg (rdirty[arg],LONG), xreg (rset[arg], size));
        !          1244:                                _S(2) do_bswap (rset[arg], size);
        !          1245:                        }
        !          1246:                        break;
        !          1247:                default:
        !          1248:                        error ("nasty error in c_readea()");
        !          1249:        }
        !          1250:        _S(0) snprintf (ea->identifier, sizeof (ea->identifier),
        !          1251:                        "%s", reg_turd[size][arg]);
        !          1252: }
        !          1253: 
        !          1254: /*
        !          1255:  * Uses dirty regs of arg1 and arg2 (so they can't be pipelined together).
        !          1256:  */
        !          1257: static void xold_writeea (ea_t *ea, int size, enum X86REG val, int advance_stage)
        !          1258: {
        !          1259:        int inc;
        !          1260:        const int arg = 1; /* hack. _S macro ;-) */
        !          1261:        static int stage[2] = {2,2};
        !          1262: 
        !          1263:        assert ((val == EAX) || (val == EBX));
        !          1264:        
        !          1265:        if (!advance_stage) {
        !          1266:                if (stage[arg] != 2)    error ("xold_writeea stages missed. (as68k bug).");
        !          1267: 
        !          1268:                stage[arg] = 0;
        !          1269:        } else {
        !          1270:                stage[arg]++;
        !          1271:        }
        !          1272:        
        !          1273:        if (!ea->do_writeback) return;
        !          1274:        ea->x86_reg_writeback = -1;
        !          1275:        ea->x86_reg = -1;
        !          1276: 
        !          1277:        switch (ea->mode) {
        !          1278:                /* dreg, areg */
        !          1279:                case 0: case 1:
        !          1280:                        _S(2) xln ("mov%s       %s,%d(%%ebp)", szmov[size], xreg (val, size), regpos (ea->reg));
        !          1281:                        break;
        !          1282:                /* areg indirect */
        !          1283:                case 2:
        !          1284:                        _S(1) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[0], LONG));
        !          1285:                        _S(1) do_bswap (val, size);
        !          1286:                        _S(2) xln ("mov%s       %s,(%%ebp,%s)", szmov[size], xreg (val, size), xreg (rdirty[0], LONG));
        !          1287:                        break;
        !          1288:                /* areg postinc */
        !          1289:                case 3:
        !          1290:                        _S(1) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[0], LONG));
        !          1291:                        _S(1) do_bswap (val, size);
        !          1292:                        _S(2) xln ("mov%s       %s,(%%ebp,%s)", szmov[size], xreg (val, size), xreg (rdirty[0], LONG));
        !          1293:                        break;
        !          1294:                /* areg predec */
        !          1295:                case 4:
        !          1296:                        inc = 1<<size;
        !          1297:                        /* stack pointer always by 2 */
        !          1298:                        if ((ea->reg == 15) && (inc == 1)) inc = 2;
        !          1299:                        
        !          1300:                        _S(1) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[0], LONG));
        !          1301:                        _S(1) do_bswap (val, size);
        !          1302:                        _S(2) xln ("mov%s       %s,-%d(%%ebp,%s)", szmov[size], xreg (val, size), inc, xreg (rdirty[0], LONG));
        !          1303:                        break;
        !          1304:                /* areg offset */
        !          1305:                case 5:
        !          1306:                        _S(1) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[0], LONG));
        !          1307:                        _S(1) do_bswap (val, size);
        !          1308:                        _S(2) xln ("mov%s       %s,%d(%%ebp,%s)", szmov[size], xreg (val, size), ea->imm.val, xreg (rdirty[0], LONG));
        !          1309:                        break;
        !          1310:                /* areg offset + reg */
        !          1311:                case 6:
        !          1312:                        _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->reg), xreg (rdirty[1],LONG));
        !          1313:                        if (ea->ext._.size) {
        !          1314:                                _S(0) xln ("movl        %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[0],LONG));
        !          1315:                        } else {
        !          1316:                                _S(0) xln ("movswl      %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[0], LONG));
        !          1317:                        }
        !          1318:                        _S(0) xln ("addl        %%ebp,%s", xreg (rdirty[1],LONG));
        !          1319:                        _S(0) do_bswap (val, size);
        !          1320:                        _S(1) xln ("mov%s       %s,%d(%s,%s)", szmov[size], xreg (val, size), ea->ext._.displacement, xreg (rdirty[1],LONG), xreg (rdirty[0],LONG));
        !          1321:                        break;
        !          1322:                /* yes */
        !          1323:                case 7:
        !          1324:                        /* $xxx.w */
        !          1325:                        if (ea->reg == 0) {
        !          1326:                                _S(1) do_bswap (val, size);
        !          1327:                                _S(2) xln ("mov%s       %s,%d(%%ebp)", szmov[size], xreg (val, size), ea->imm.val);
        !          1328:                        }
        !          1329:                        /* $xxx.l */
        !          1330:                        else if (ea->reg == 1) {
        !          1331:                                if (ea->imm.has_label) {
        !          1332:                                        _S(1) do_bswap (val, size);
        !          1333:                                        _S(2) xln ("mov%s       %s,__D%s(%%ebp)", szmov[size], xreg (val, size), ea->imm.label);
        !          1334:                                } else {
        !          1335:                                        _S(1) do_bswap (val, size);
        !          1336:                                        _S(2) xln ("mov%s       %s,%d(%%ebp)", szmov[size], xreg (val, size), ea->imm.val);
        !          1337:                                }
        !          1338:                        }
        !          1339:                        /* immediate */
        !          1340:                        else if (ea->reg == 4) {
        !          1341:                                assert (0);
        !          1342:                        }
        !          1343:                        /* PC + offset */
        !          1344:                        else if (ea->reg == 2) {
        !          1345:                                assert (ea->imm.has_label);
        !          1346: 
        !          1347:                                _S(1) do_bswap (val, size);
        !          1348:                                _S(2) xln ("mov%s       %s,__D%s(%%ebp)", szmov[size], xreg (val, size), ea->imm.label);
        !          1349:                        }
        !          1350:                        /* PC + INDEX + OFFSET */
        !          1351:                        else if (ea->reg == 3) {
        !          1352:                                assert (ea->imm.has_label);
        !          1353:                                if (ea->ext._.size) {
        !          1354:                                        _S(1) xln ("movl        %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[0],LONG));
        !          1355:                                } else {
        !          1356:                                        _S(1) xln ("movswl      %d(%%ebp),%s", regpos (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0)), xreg (rdirty[0], LONG));
        !          1357:                                }
        !          1358:                                _S(1) do_bswap (val, size);
        !          1359:                                _S(2) xln ("mov%s       %s,__D%s(%%ebp,%s)", szmov[size], xreg (val,size), ea->imm.label, xreg (rdirty[0],LONG));
        !          1360:                        }
        !          1361:                        else {
        !          1362:                                error ("wtf in c_writeea ()");
        !          1363:                        }
        !          1364:                        break;
        !          1365:                default:
        !          1366:                        error ("nasty error in c_writeea()");
        !          1367:        }
        !          1368: }
        !          1369: 
        !          1370: /* loads effective address, not value pointed to */
        !          1371: static void x_loadea (ea_t *ea)
        !          1372: {
        !          1373:        int reg2, reg3, inc, out_reg;
        !          1374: 
        !          1375:        ea->do_writeback = 1;
        !          1376:        ea->x86_reg_writeback = -1;
        !          1377:        
        !          1378:        switch (ea->mode) {
        !          1379:                /* dreg, areg */
        !          1380:                case 0: case 1: assert (0);
        !          1381:                /* areg indirect, postinc */
        !          1382:                case 2: case 3:
        !          1383:                        out_reg = xcopy_reg (ea->reg, LONG, -1);
        !          1384:                        break;
        !          1385:                /* areg predec */
        !          1386:                case 4: 
        !          1387:                        inc = 1<<ea->op_size;
        !          1388:                        /* stack pointer always by 2 */
        !          1389:                        if ((ea->reg == 15) && (inc == 1)) inc = 2;
        !          1390:                        
        !          1391:                        out_reg = xcopy_reg (ea->reg, LONG, -1);
        !          1392:                        if (inc == 1) xln ("dec %s", xreg (out_reg,LONG));
        !          1393:                        else xln ("subl $%d,%s", inc, xreg (out_reg,LONG));
        !          1394:                        break;
        !          1395:                /* areg offset */
        !          1396:                case 5:
        !          1397:                        out_reg = xcopy_reg (ea->reg, LONG, -1);
        !          1398:                        xln ("addl      $%d,%s", ea->imm.val, xreg (out_reg,LONG));
        !          1399:                        break;
        !          1400:                /* areg offset + reg */
        !          1401:                case 6:
        !          1402:                        out_reg = xcopy_reg (ea->reg, LONG, -1);
        !          1403:                        if (ea->ext._.size) {
        !          1404:                                reg2 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1405:                        } else {
        !          1406:                                /* need fucking 16-bit chunk of variable sign extended to 32... */
        !          1407:                                reg3 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1408:                                reg2 = xalloc_reg (LONG, -1);
        !          1409:                                xln ("movswl    %s,%s", xreg (reg3, WORD), xreg (reg2, LONG));
        !          1410:                                xreg_unlock (reg3);
        !          1411: 
        !          1412:                        }
        !          1413:                        xln ("leal      %d(%s,%s),%s", ea->ext._.displacement, xreg (reg2, LONG), xreg(out_reg, LONG), xreg (out_reg, LONG));
        !          1414:                        xreg_unlock (reg2);
        !          1415:                        break;
        !          1416:                /* yes */
        !          1417:                case 7:
        !          1418:                        /* $xxx.w */
        !          1419:                        if (ea->reg == 0) {
        !          1420:                                out_reg = xalloc_reg (LONG, -1);
        !          1421:                                xln ("movl      $%d,%s", ea->imm.val, out_reg, LONG);
        !          1422:                        }
        !          1423:                        /* $xxx.l */
        !          1424:                        else if (ea->reg == 1) {
        !          1425:                                out_reg = xalloc_reg (LONG, -1);
        !          1426:                                if (ea->imm.has_label) {
        !          1427:                                        xln ("movl      $__D%s,%s", ea->imm.label, xreg (out_reg,LONG));
        !          1428:                                } else {
        !          1429:                                        xln ("movl      $%d,%s", ea->imm.val, xreg (out_reg,LONG));
        !          1430:                                }
        !          1431:                        }
        !          1432:                        /* immediate */
        !          1433:                        else if (ea->reg == 4) {
        !          1434:                                assert (0);
        !          1435:                        }
        !          1436:                        /* PC + offset */
        !          1437:                        else if (ea->reg == 2) {
        !          1438:                                if (ea->imm.has_label) {
        !          1439:                                        out_reg = xalloc_reg (LONG, -1);
        !          1440:                                        xln ("movl      $__D%s,%s", ea->imm.label, xreg (out_reg,LONG));
        !          1441:                                } else
        !          1442:                                        error ("Absolute value not allowed.");
        !          1443:                        }
        !          1444:                        /* PC + INDEX + OFFSET */
        !          1445:                        else if (ea->reg == 3) {
        !          1446:                                if (!ea->imm.has_label) error ("Absolute value not allowed.");
        !          1447:                                out_reg = xalloc_reg (LONG, -1);
        !          1448:                                if (ea->ext._.size) {
        !          1449:                                        reg2 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1450:                                } else {
        !          1451:                                        /* need fucking 16-bit chunk of variable sign extended to 32... */
        !          1452:                                        reg3 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1453:                                        reg2 = xalloc_reg (LONG, -1);
        !          1454:                                        xln ("movswl    %s,%s", xreg (reg3, WORD), xreg (reg2, LONG));
        !          1455:                                        xreg_unlock (reg3);
        !          1456:                                }
        !          1457:                                // XXX
        !          1458:                                xln ("leal      __D%s(%s),%s", ea->imm.label, xreg (reg2, LONG), xreg (out_reg, LONG));
        !          1459:                                xreg_unlock (reg2);
        !          1460:                        }
        !          1461:                        break;
        !          1462:                default:
        !          1463:                        assert (0);
        !          1464:        }
        !          1465:        ea->x86_reg = out_reg;
        !          1466:        snprintf (ea->identifier, sizeof (ea->identifier),
        !          1467:                        "%s", xreg (out_reg, LONG));
        !          1468: }
        !          1469: 
        !          1470: /* that is, preferred x86 reg.
        !          1471:  * XXX nothing preferred about it. it is a fucking demand. */
        !          1472: static void x_loadval (ea_t *ea, int preferred_reg, int flags)
        !          1473: {
        !          1474:        int inc, size, reg1, reg2, reg3, out_reg;
        !          1475:        size = ea->op_size;
        !          1476: 
        !          1477:        ea->do_writeback = 1;
        !          1478:        ea->x86_reg_writeback = -1;
        !          1479:        
        !          1480:        switch (ea->mode) {
        !          1481:                /* dreg, areg */
        !          1482:                case 0:
        !          1483:                case 1:
        !          1484:                        if (flags & XCAN_OVERWRITE) {
        !          1485:                                out_reg = xcopy_reg (ea->reg, LONG, preferred_reg);
        !          1486:                        } else
        !          1487:                        if ((flags & XQUICK_REGS) && (xfind_reg (ea->reg)==-1)) {
        !          1488:                                /* operate in-place (in memory) */
        !          1489:                                snprintf (ea->identifier, sizeof (ea->identifier), "%d(%%ebp)", regpos (ea->reg));
        !          1490:                                ea->do_writeback = 0;
        !          1491:                                return;
        !          1492:                        } else {
        !          1493:                                out_reg = xload_reg2 (ea->reg, size, preferred_reg,
        !          1494:                                                0, (flags & XSIGN_EXTEND_REGS ? szsconv : szfull));
        !          1495:                        }
        !          1496:                        break;
        !          1497:                /* areg indirect */
        !          1498:                case 2:
        !          1499:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1500:                        out_reg = xalloc_reg (size, preferred_reg);
        !          1501:                        
        !          1502:                        xln ("mov%s     (%%ebp,%s),%s", szmov[size], xreg (reg1, LONG), xreg (out_reg, size));
        !          1503:                        xreg_unlock (reg1);
        !          1504:                        do_bswap (out_reg, size);
        !          1505:                        break;
        !          1506:                /* areg postinc */
        !          1507:                case 3:
        !          1508:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1509:                        out_reg = xalloc_reg (size, preferred_reg);
        !          1510:                        
        !          1511:                        xln ("mov%s     (%%ebp,%s),%s", szmov[size], xreg (reg1, LONG), xreg (out_reg, size));
        !          1512:                        xreg_unlock (reg1);
        !          1513:                        do_bswap (out_reg, size);
        !          1514:                        break;
        !          1515:                /* areg predec */
        !          1516:                case 4:
        !          1517:                        inc = 1<<size;
        !          1518:                        /* stack pointer always by 2 */
        !          1519:                        if ((ea->reg == 15) && (inc == 1)) inc = 2;
        !          1520:                        
        !          1521:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1522:                        out_reg = xalloc_reg (size, preferred_reg);
        !          1523:                        xln ("mov%s     -%d(%%ebp,%s),%s", szmov[size], inc, xreg (reg1, LONG), xreg (out_reg, size));
        !          1524:                        xreg_unlock (reg1);
        !          1525:                        do_bswap (out_reg, size);
        !          1526:                        break;
        !          1527:                /* areg offset */
        !          1528:                case 5:
        !          1529:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1530:                        out_reg = xalloc_reg (size, preferred_reg);
        !          1531:                        
        !          1532:                        xln ("mov%s     %d(%%ebp,%s),%s", szmov[size], ea->imm.val, xreg (reg1, LONG), xreg (out_reg, size));
        !          1533:                        xreg_unlock (reg1);
        !          1534:                        do_bswap (out_reg, size);
        !          1535:                        break;
        !          1536:                /* areg offset + reg */
        !          1537:                case 6:
        !          1538:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1539:                        out_reg = xalloc_reg (size, preferred_reg);
        !          1540:                        if (ea->ext._.size) {
        !          1541:                                reg2 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1542:                        } else {
        !          1543:                                /* need fucking 16-bit chunk of variable sign extended to 32... */
        !          1544:                                reg3 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1545:                                reg2 = xalloc_reg (LONG, -1);
        !          1546:                                xln ("movswl    %s,%s", xreg (reg3, WORD), xreg (reg2, LONG));
        !          1547:                        }
        !          1548:                        if (flags & XQUICK_WRITEBACK) {
        !          1549:                                xln ("lea       (MemBase+%d)(%s,%s),%s", ea->ext._.displacement, xreg (reg1,LONG), xreg (reg2,LONG), xreg (reg2, LONG));
        !          1550:                                xln ("mov%s     (%s),%s", szmov[size], xreg (reg2,LONG), xreg (out_reg, size));
        !          1551:                                ea->x86_reg_writeback = reg2;
        !          1552:                                
        !          1553:                                xreg_unlock (reg1);
        !          1554:                                xreg_unlock (reg3);
        !          1555:                        } else {
        !          1556:                                xln ("mov%s     (MemBase+%d)(%s,%s),%s", szmov[size], ea->ext._.displacement, xreg (reg1,LONG), xreg (reg2,LONG), xreg (out_reg, size));
        !          1557:                                if (!ea->ext._.size) xreg_unlock (reg3);
        !          1558:                                xreg_unlock (reg1);
        !          1559:                                xreg_unlock (reg2);
        !          1560:                        }
        !          1561:                        do_bswap (out_reg, size);
        !          1562:                        break;
        !          1563:                /* yes */
        !          1564:                case 7:
        !          1565:                        /* $xxx.w */
        !          1566:                        if (ea->reg == 0) {
        !          1567:                                out_reg = xalloc_reg (size, preferred_reg);
        !          1568:                                xln ("mov%s     %d(%%ebp),%s", szmov[size], ea->imm.val, xreg (out_reg, size));
        !          1569:                                do_bswap (out_reg, size);
        !          1570:                        }
        !          1571:                        /* $xxx.l */
        !          1572:                        else if (ea->reg == 1) {
        !          1573:                                out_reg = xalloc_reg (size, preferred_reg);
        !          1574:                                if (ea->imm.has_label) {
        !          1575:                                        xln ("mov%s     __D%s(%%ebp),%s", szmov[size], ea->imm.label, xreg (out_reg, size));
        !          1576:                                } else {
        !          1577:                                        xln ("mov%s     %d(%%ebp),%s", szmov[size], ea->imm.val, xreg (out_reg, size));
        !          1578:                                }
        !          1579:                                do_bswap (out_reg, size);
        !          1580:                        }
        !          1581:                        /* immediate */
        !          1582:                        else if (ea->reg == 4) {
        !          1583:                                if (flags & XQUICK_IMMS) {
        !          1584:                                        if (ea->imm.has_label) {
        !          1585:                                                snprintf (ea->identifier, sizeof (ea->identifier),
        !          1586:                                                        "$__D%s", ea->imm.label);
        !          1587:                                        } else {
        !          1588:                                                snprintf (ea->identifier, sizeof (ea->identifier),
        !          1589:                                                        "$%d", ea->imm.val);
        !          1590:                                        }
        !          1591:                                        ea->x86_reg = -1;
        !          1592:                                        return;
        !          1593:                                }
        !          1594:                                out_reg = xalloc_reg (size, preferred_reg);
        !          1595:                                if (ea->imm.has_label) {
        !          1596:                                        xln ("movl      $__D%s,%s", ea->imm.label, xreg (out_reg, LONG));
        !          1597:                                } else {
        !          1598:                                        xln ("movl      $%d,%s", ea->imm.val, xreg (out_reg, LONG));
        !          1599:                                }
        !          1600:                        }
        !          1601:                        /* PC + offset */
        !          1602:                        else if (ea->reg == 2) {
        !          1603:                                assert (ea->imm.has_label);
        !          1604: 
        !          1605:                                out_reg = xalloc_reg (size, preferred_reg);
        !          1606:                                xln ("mov%s     __D%s(%%ebp),%s", szmov[size], ea->imm.label, xreg (out_reg, size));
        !          1607:                                do_bswap (out_reg, size);
        !          1608:                        }
        !          1609:                        /* PC + INDEX + OFFSET */
        !          1610:                        else if (ea->reg == 3) {
        !          1611:                                assert (ea->imm.has_label);
        !          1612:                                
        !          1613:                                out_reg = xalloc_reg (size, preferred_reg);
        !          1614:                                if (ea->ext._.size) {
        !          1615:                                        reg2 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1616:                                } else {
        !          1617:                                        /* need fucking 16-bit chunk of variable sign extended to 32... */
        !          1618:                                        reg3 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1619:                                        reg2 = xalloc_reg (LONG, -1);
        !          1620:                                        xln ("movswl    %s,%s", xreg (reg3, WORD), xreg (reg2, LONG));
        !          1621:                                        xreg_unlock (reg3);
        !          1622:                                }
        !          1623:                                xln ("mov%s     __D%s(%%ebp,%s),%s", szmov[size], ea->imm.label, xreg (reg2,LONG), xreg (out_reg, size));
        !          1624:                                do_bswap (out_reg, size);
        !          1625:                                xreg_unlock (reg2);
        !          1626:                        }
        !          1627:                        break;
        !          1628:                default:
        !          1629:                        error ("nasty error in c_readea()");
        !          1630:        }
        !          1631:                        
        !          1632:        ea->x86_reg = out_reg;
        !          1633:        snprintf (ea->identifier, sizeof (ea->identifier),
        !          1634:                        "%s", xreg (out_reg, size));
        !          1635: }
        !          1636: 
        !          1637: static void x_saveval (ea_t *ea, int size)
        !          1638: {
        !          1639:        int inc, reg1, reg2, reg3;
        !          1640: 
        !          1641:        if (!ea->do_writeback) return;
        !          1642: 
        !          1643:        if (ea->x86_reg_writeback != -1) {
        !          1644:                do_bswap (ea->x86_reg, size);
        !          1645:                xln ("mov%s     %s,(%s)", szmov[size], xreg (ea->x86_reg, size), xreg (ea->x86_reg_writeback, LONG));
        !          1646:                return;
        !          1647:        }
        !          1648:        
        !          1649:        switch (ea->mode) {
        !          1650:                /* dreg, areg */
        !          1651:                case 0: case 1:
        !          1652:                        /* don't need to act until xflush_reg... */
        !          1653:                        break;
        !          1654:                /* areg indirect */
        !          1655:                case 2:
        !          1656:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1657:                        do_bswap (ea->x86_reg, size);
        !          1658:                        xln ("mov%s     %s,(%%ebp,%s)", szmov[size], xreg (ea->x86_reg, size), xreg (reg1, LONG));
        !          1659:                        xreg_unlock (reg1);
        !          1660:                        break;
        !          1661:                /* areg postinc */
        !          1662:                case 3:
        !          1663:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1664:                        do_bswap (ea->x86_reg, size);
        !          1665:                        xln ("mov%s     %s,(%%ebp,%s)", szmov[size], xreg (ea->x86_reg, size), xreg (reg1, LONG));
        !          1666:                        xreg_unlock (reg1);
        !          1667:                        break;
        !          1668:                /* areg predec */
        !          1669:                case 4:
        !          1670:                        inc = 1<<size;
        !          1671:                        /* stack pointer always by 2 */
        !          1672:                        if ((ea->reg == 15) && (inc == 1)) inc = 2;
        !          1673:                        
        !          1674:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1675:                        do_bswap (ea->x86_reg, size);
        !          1676:                        xln ("mov%s     %s,-%d(%%ebp,%s)", szmov[size], xreg (ea->x86_reg, size), inc, xreg (reg1, LONG));
        !          1677:                        xreg_unlock (reg1);
        !          1678:                        break;
        !          1679:                /* areg offset */
        !          1680:                case 5:
        !          1681:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1682:                        do_bswap (ea->x86_reg, size);
        !          1683:                        xln ("mov%s     %s,%d(%%ebp,%s)", szmov[size], xreg (ea->x86_reg, size), ea->imm.val, xreg (reg1, LONG));
        !          1684:                        xreg_unlock (reg1);
        !          1685:                        break;
        !          1686:                /* areg offset + reg */
        !          1687:                case 6:
        !          1688:                        reg1 = xload_reg (ea->reg, LONG, -1);
        !          1689:                        if (ea->ext._.size) {
        !          1690:                                reg2 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1691:                        } else {
        !          1692:                                /* need fucking 16-bit chunk of variable sign extended to 32... */
        !          1693:                                reg3 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1694:                                reg2 = xalloc_reg (LONG, -1);
        !          1695:                                xln ("movswl    %s,%s", xreg (reg3, WORD), xreg (reg2, LONG));
        !          1696:                                xreg_unlock (reg3);
        !          1697:                        }
        !          1698:                        do_bswap (ea->x86_reg, size);
        !          1699:                        xln ("mov%s     %s,(MemBase+%d)(%s,%s)", szmov[size], xreg (ea->x86_reg, size), ea->ext._.displacement, xreg (reg1,LONG), xreg (reg2,LONG));
        !          1700:                        xreg_unlock (reg1);
        !          1701:                        xreg_unlock (reg2);
        !          1702:                        break;
        !          1703:                /* yes */
        !          1704:                case 7:
        !          1705:                        /* XXX TO DO */
        !          1706:                        /* $xxx.w */
        !          1707:                        if (ea->reg == 0) {
        !          1708:                                do_bswap (ea->x86_reg, size);
        !          1709:                                xln ("mov%s     %s,%d(%%ebp)", szmov[size], xreg (ea->x86_reg, size), ea->imm.val);
        !          1710:                        }
        !          1711:                        /* $xxx.l */
        !          1712:                        else if (ea->reg == 1) {
        !          1713:                                if (ea->imm.has_label) {
        !          1714:                                        do_bswap (ea->x86_reg, size);
        !          1715:                                        xln ("mov%s     %s,__D%s(%%ebp)", szmov[size], xreg (ea->x86_reg, size), ea->imm.label);
        !          1716:                                } else {
        !          1717:                                        do_bswap (ea->x86_reg, size);
        !          1718:                                        xln ("mov%s     %s,%d(%%ebp)", szmov[size], xreg (ea->x86_reg, size), ea->imm.val);
        !          1719:                                }
        !          1720:                        }
        !          1721:                        /* immediate */
        !          1722:                        else if (ea->reg == 4) {
        !          1723:                                assert (0);
        !          1724:                        }
        !          1725:                        /* PC + offset */
        !          1726:                        else if (ea->reg == 2) {
        !          1727:                                assert (ea->imm.has_label);
        !          1728: 
        !          1729:                                do_bswap (ea->x86_reg, size);
        !          1730:                                xln ("mov%s     %s,__D%s(%%ebp)", szmov[size], xreg (ea->x86_reg, size), ea->imm.label);
        !          1731:                        }
        !          1732:                        /* PC + INDEX + OFFSET */
        !          1733:                        else if (ea->reg == 3) {
        !          1734:                                assert (ea->imm.has_label);
        !          1735:                                if (ea->ext._.size) {
        !          1736:                                        reg2 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1737:                                } else {
        !          1738:                                        /* need fucking 16-bit chunk of variable sign extended to 32... */
        !          1739:                                        reg3 = xload_reg (ea->ext._.reg + (ea->ext._.d_or_a ? 8 : 0), LONG, -1);
        !          1740:                                        reg2 = xalloc_reg (LONG, -1);
        !          1741:                                        xln ("movswl    %s,%s", xreg (reg3, WORD), xreg (reg2, LONG));
        !          1742:                                        xreg_unlock (reg3);
        !          1743:                                }
        !          1744:                                do_bswap (ea->x86_reg, size);
        !          1745:                                xln ("mov%s     %s,__D%s(%%ebp,%s)", szmov[size], xreg (ea->x86_reg,size), ea->imm.label, xreg (reg2,LONG));
        !          1746:                                xreg_unlock (reg2);
        !          1747:                        }
        !          1748:                        else {
        !          1749:                                error ("wtf in c_writeea ()");
        !          1750:                        }
        !          1751:                        break;
        !          1752:                default:
        !          1753:                        error ("nasty error in c_writeea()");
        !          1754:        }
        !          1755: }
        !          1756: 
        !          1757: static void x_ea_set_val_2_reg (ea_t *ea, int size, int x86_reg)
        !          1758: {
        !          1759:        int i;
        !          1760:        assert (size == LONG);
        !          1761:        
        !          1762:        ea->do_writeback = 1;
        !          1763:        ea->x86_reg_writeback = -1;
        !          1764: 
        !          1765:        if ((ea->mode == 0) || (ea->mode == 1)) {
        !          1766:                i = xfind_reg (ea->reg);
        !          1767: 
        !          1768:                if (i != -1) {
        !          1769:                        /* reg already loaded, but we are wiping
        !          1770:                         * the bastard with a full LONG write so drop
        !          1771:                         * the existing regalloc */
        !          1772:                        assert (i386_regalloc[i].locked == 0);
        !          1773:                        i386_regalloc[i].m68k_reg = -1;
        !          1774:                        i386_regalloc[i].dirty = 0;
        !          1775:                }
        !          1776:                i386_regalloc[x86_reg].m68k_reg = ea->reg;
        !          1777:                i386_regalloc[x86_reg].dirty = 1;
        !          1778:                
        !          1779:                ea->x86_reg = x86_reg;
        !          1780:        } else {
        !          1781:                i386_regalloc[x86_reg].m68k_reg = REG_TEMP;
        !          1782:                ea->x86_reg = x86_reg;
        !          1783:        }
        !          1784:        i386_regalloc[x86_reg].locked++;
        !          1785:        i386_regalloc[x86_reg].age = 0;
        !          1786: }
        !          1787: 
        !          1788: static void x_cond_end ()
        !          1789: {
        !          1790:        xout ("2:\n");
        !          1791: }
        !          1792: 
        !          1793: static void x_cond_begin (int cond)
        !          1794: {
        !          1795:        switch (cond) {
        !          1796:                /* t */
        !          1797:                case 0: break;
        !          1798:                /* f */
        !          1799:                case 1: xln ("jmp       2f"); break;
        !          1800:                /* hi */
        !          1801:                case 2: 
        !          1802:                        xln ("movb      C,%%al");
        !          1803:                        xln ("orb       Z,%%al");
        !          1804:                        xln ("jnz       2f");
        !          1805:                        break;
        !          1806:                        //cout ("((!C) && !Z)"); break;
        !          1807:                /* ls */
        !          1808:                case 3:
        !          1809:                        xln ("movb      C,%%al");
        !          1810:                        xln ("orb       Z,%%al");
        !          1811:                        xln ("jz        2f");
        !          1812:                        break;
        !          1813:                        //cout ("(C || Z)"); break;
        !          1814:                /* cc */
        !          1815:                case 4: 
        !          1816:                        xln ("testb     $1,C");
        !          1817:                        xln ("jnz       2f");
        !          1818:                        break;
        !          1819:                        //cout ("(!C)"); break;
        !          1820:                /* cs */
        !          1821:                case 5: 
        !          1822:                        xln ("testb     $1,C");
        !          1823:                        xln ("jz        2f");
        !          1824:                        break;
        !          1825:                        //cout ("C"); break;
        !          1826:                /* ne */
        !          1827:                case 6: 
        !          1828:                        xln ("testb     $1,Z");
        !          1829:                        xln ("jnz       2f");
        !          1830:                        break;
        !          1831:                        //cout ("!Z"); break;
        !          1832:                /* eq */
        !          1833:                case 7: 
        !          1834:                        xln ("testb     $1,Z");
        !          1835:                        xln ("jz        2f");
        !          1836:                        break;
        !          1837:                        //cout ("(Z)"); break;
        !          1838:                /* vc */
        !          1839:                case 8: 
        !          1840:                        xln ("testb     $1,V");
        !          1841:                        xln ("jnz       2f");
        !          1842:                        break;
        !          1843:                        //cout ("(!V)"); break;
        !          1844:                /* vs */
        !          1845:                case 9: 
        !          1846:                        xln ("testb     $1,V");
        !          1847:                        xln ("jz        2f");
        !          1848:                        break;
        !          1849:                        //cout ("V"); break;
        !          1850:                /* pl */
        !          1851:                case 10: 
        !          1852:                        xln ("testb     $1,N");
        !          1853:                        xln ("jnz       2f");
        !          1854:                        break;
        !          1855:                        //cout ("(!N)"); break;
        !          1856:                /* mi */
        !          1857:                case 11: 
        !          1858:                        xln ("testb     $1,N");
        !          1859:                        xln ("jz        2f");
        !          1860:                        break;
        !          1861:                        //cout ("N"); break;
        !          1862:                /* ge */
        !          1863:                case 12:
        !          1864:                        xln ("movb      N,%%al");
        !          1865:                        xln ("xorb      V,%%al");
        !          1866:                        xln ("jnz       2f");
        !          1867:                        break;
        !          1868:                        //cout ("((N && V) || ((!N) && (!V)))"); break;
        !          1869:                /* lt */
        !          1870:                case 13:
        !          1871:                        xln ("movb      V,%%al");
        !          1872:                        xln ("xorb      $1,%%al");
        !          1873:                        xln ("xorb      N,%%al");
        !          1874:                        xln ("jnz       2f");
        !          1875:                        break;
        !          1876:                        //cout ("((N && (!V)) || ((!N) && V))"); break;
        !          1877:                /* gt */
        !          1878:                case 14:
        !          1879:                        xln ("movb      N,%%al");
        !          1880:                        xln ("xorb      V,%%al");
        !          1881:                        xln ("orb       Z,%%al");
        !          1882:                        xln ("jnz       2f");
        !          1883:                        break;
        !          1884:                        //cout ("((N && V && (!Z)) || ((!N) && (!V) && (!Z)))"); break;
        !          1885:                /* le */
        !          1886:                case 15:
        !          1887:                        xln ("movb      Z,%%ah");
        !          1888:                        xln ("movb      V,%%al");
        !          1889:                        xln ("xorb      $1,%%ah");
        !          1890:                        xln ("xorb      $1,%%al");
        !          1891:                        xln ("xorb      N,%%al");
        !          1892:                        xln ("andb      %%ah,%%al");
        !          1893:                        xln ("jnz       2f");
        !          1894:                        break;
        !          1895:                        //cout ("((Z) || (N && (!V)) || ((!N) && V))"); break;
        !          1896:        }
        !          1897: }
        !          1898: 
        !          1899: void i386_jump (ea_t *ea)
        !          1900: {
        !          1901:        xflush_all ();
        !          1902:        if (((ea->mode == 7) && (ea->reg == 1)) ||
        !          1903:            ((ea->mode == 7) && (ea->reg == 2))) {
        !          1904:                xln ("jmp       __N%s", ea->imm.label);
        !          1905:        } else {
        !          1906:                xold_ea_get_address (ea, 0, 0);
        !          1907:                xold_ea_get_address (ea, 0, 1);
        !          1908:                x_postea (ea);
        !          1909:                //xln ("jmp     jumptable");
        !          1910:                xln ("jmp       *jtab(,%%eax,2)");
        !          1911:        }
        !          1912: }
        !          1913: 
        !          1914: /* Check for pending exceptions also */
        !          1915: void i386_jump_e (ea_t *ea)
        !          1916: {
        !          1917:        xflush_all ();
        !          1918:        xln ("cmpl      $0,exceptions_pending_mask");
        !          1919: 
        !          1920:        /* yay! exception */
        !          1921:        if (((ea->mode == 7) && (ea->reg == 1)) ||
        !          1922:            ((ea->mode == 7) && (ea->reg == 2))) {
        !          1923:                xln ("movl      $__D%s,%%eax", ea->imm.label);
        !          1924:        } else {
        !          1925:                xold_ea_get_address (ea, 0, 0);
        !          1926:                xold_ea_get_address (ea, 0, 1);
        !          1927:                x_postea (ea);
        !          1928:        }
        !          1929:        xln ("jnz       handle_exception");
        !          1930:        i386_jump (ea);
        !          1931: }
        !          1932: 
        !          1933: static void i386_func_bitop (ea_t *src, ea_t *dest, int size, const char *op)
        !          1934: {
        !          1935:        int len = size2len [size];
        !          1936:        
        !          1937:        xflush_all ();
        !          1938:        
        !          1939:        if (is_immediate (src)) {
        !          1940:                xold_readea (dest, 1, 0);
        !          1941:                xold_readea (dest, 1, 1);
        !          1942:                xold_readea (dest, 1, 1);
        !          1943:                
        !          1944:                xln ("%sl       $%d,%%ebx", op, src->imm.val & (len-1));
        !          1945:                ifZ xln ("setnc Z");
        !          1946: 
        !          1947:                xold_writeea (dest, size, EBX, 0);
        !          1948:                xold_writeea (dest, size, EBX, 1);
        !          1949:                xold_writeea (dest, size, EBX, 1);
        !          1950: 
        !          1951:                x_postea (dest);
        !          1952:                return;
        !          1953:        }
        !          1954:        
        !          1955:        xold_readea (src, 0, 0);
        !          1956:        xold_readea (dest, 1, 0);
        !          1957:        xold_readea (src, 0, 1);
        !          1958:        xold_readea (dest, 1, 1);
        !          1959:        xold_readea (src, 0, 1);
        !          1960:        xold_readea (dest, 1, 1);
        !          1961: 
        !          1962:        if (size == BYTE) xln ("andl    $7,%%eax");
        !          1963:        xln ("%sl       %%eax,%%ebx", op, src->imm.val);
        !          1964:        ifZ xln ("setnc Z");
        !          1965:        
        !          1966:        xold_writeea (dest, size, EBX, 0);
        !          1967:        xold_writeea (dest, size, EBX, 1);
        !          1968:        xold_writeea (dest, size, EBX, 1);
        !          1969: 
        !          1970:        x_postea (src);
        !          1971:        x_postea (dest);
        !          1972: }
        !          1973: 
        !          1974: void i386_func_bchg (ea_t *src, ea_t *dest, int size)
        !          1975: {
        !          1976:        i386_func_bitop (src, dest, size, "btc");
        !          1977: }
        !          1978: 
        !          1979: void i386_func_bclr (ea_t *src, ea_t *dest, int size)
        !          1980: {
        !          1981:        i386_func_bitop (src, dest, size, "btr");
        !          1982: }
        !          1983: 
        !          1984: void i386_func_bset (ea_t *src, ea_t *dest, int size)
        !          1985: {
        !          1986:        i386_func_bitop (src, dest, size, "bts");
        !          1987: }
        !          1988: 
        !          1989: void i386_func_btst (ea_t *src, ea_t *dest, int size)
        !          1990: {
        !          1991:        int len = size2len [size];
        !          1992:        
        !          1993:        xflush_all ();
        !          1994:        
        !          1995:        if (is_immediate (src)) {
        !          1996:                xold_readea (dest, 1, 0);
        !          1997:                xold_readea (dest, 1, 1);
        !          1998:                xold_readea (dest, 1, 1);
        !          1999:                
        !          2000:                xln ("btl       $%d,%%ebx", src->imm.val & (len-1));
        !          2001:                xln ("setnc     Z");
        !          2002: 
        !          2003:                x_postea (dest);
        !          2004:                return;
        !          2005:        }
        !          2006:        
        !          2007:        xold_readea (src, 0, 0);
        !          2008:        xold_readea (dest, 1, 0);
        !          2009:        xold_readea (src, 0, 1);
        !          2010:        xold_readea (dest, 1, 1);
        !          2011:        xold_readea (src, 0, 1);
        !          2012:        xold_readea (dest, 1, 1);
        !          2013: 
        !          2014:        if (size == BYTE) xln ("andl    $7,%%eax");
        !          2015:        xln ("btl       %%eax,%%ebx", src->imm.val);
        !          2016:        xln ("setnc     Z");
        !          2017: 
        !          2018:        x_postea (src);
        !          2019:        x_postea (dest);
        !          2020: }
        !          2021: 
        !          2022: void i386_func_muls (ea_t *src, ea_t *dest)
        !          2023: {
        !          2024:        assert (dest->mode == 0);
        !          2025:        src->op_size = WORD;
        !          2026:        x_loadval (src, -1, XCAN_OVERWRITE);
        !          2027:        dest->op_size = WORD;
        !          2028:        x_loadval (dest, -1, 0);//XSIGN_EXTEND_REGS);
        !          2029: 
        !          2030:        xln ("movswl    %s,%s", src->identifier, xreg (src->x86_reg, LONG));
        !          2031:        xln ("movswl    %s,%s", dest->identifier, xreg (dest->x86_reg, LONG));
        !          2032:                
        !          2033:                xln ("imull     %s,%s", xreg (src->x86_reg, LONG), xreg (dest->x86_reg, LONG));
        !          2034:        ifNVC   xln ("movb      $0,C");
        !          2035:        ifNVC   xln ("movb      $0,V");
        !          2036:        ifZNVC  xln ("testl     %s,%s", xreg (dest->x86_reg, LONG), xreg (dest->x86_reg, LONG));
        !          2037:        ifNVC   xln ("sets      N");
        !          2038:        ifZ     xln ("setz      Z");
        !          2039: 
        !          2040:        xdirty_reg (dest->x86_reg);
        !          2041:        x_saveval (dest, WORD);
        !          2042:        x_postea (src);
        !          2043:        x_postea (dest);
        !          2044: }
        !          2045: void i386_func_mulu (ea_t *src, ea_t *dest)
        !          2046: {
        !          2047:        xflush_all ();
        !          2048:        xold_readea2 (src, 1, 0, XQUICK_REGS);
        !          2049:        xold_readea2 (dest, 0, 0, XQUICK_REGS);
        !          2050:        xold_readea2 (src, 1, 1, XQUICK_REGS);
        !          2051:        xold_readea2 (dest, 0, 1, XQUICK_REGS);
        !          2052:        xold_readea2 (src, 1, 1, XQUICK_REGS);
        !          2053:        xold_readea2 (dest, 0, 1, XQUICK_REGS);
        !          2054:        
        !          2055:        xln ("movzwl    %s,%%ebx", src->identifier);
        !          2056:        xln ("movzwl    %s,%%eax", dest->identifier);
        !          2057: 
        !          2058:                xln ("mull      %%ebx");
        !          2059:        ifNVC   xln ("movb      $0,C");
        !          2060:        ifNVC   xln ("movb      $0,V");
        !          2061:        ifZNVC  xln ("testl     %%eax,%%eax");
        !          2062:        ifNVC   xln ("sets      N");
        !          2063:        ifZ     xln ("setz      Z");
        !          2064: 
        !          2065:        /* hack - force writeback, because we didn't operate in-place */
        !          2066:        dest->do_writeback = 1;
        !          2067:        
        !          2068:        xold_writeea (dest, LONG, EAX, 0);
        !          2069:        xold_writeea (dest, LONG, EAX, 1);
        !          2070:        xold_writeea (dest, LONG, EAX, 1);
        !          2071:        x_postea (src);
        !          2072:        x_postea (dest);
        !          2073: }
        !          2074: 
        !          2075: void i386_func_logop (ea_t *src, ea_t *dest, int size, char op)
        !          2076: {
        !          2077:        x_loadval (src, -1, XQUICK_REGS | XQUICK_IMMS);
        !          2078:        x_loadval (dest, -1, XQUICK_WRITEBACK);
        !          2079: 
        !          2080:        switch (op) {
        !          2081:                case '&': xln ("and%s   %s,%s", szmov [size], src->identifier, dest->identifier); break;
        !          2082:                case '|': xln ("or%s    %s,%s", szmov [size], src->identifier, dest->identifier); break;
        !          2083:                case '^': xln ("xor%s   %s,%s", szmov [size], src->identifier, dest->identifier); break;
        !          2084:                default: assert (0);
        !          2085:        }
        !          2086: 
        !          2087:        ifNVC   xln ("sets      N");
        !          2088:        ifZ     xln ("setz      Z");
        !          2089:        ifNVC   xln ("movb      $0,V");
        !          2090:        ifNVC   xln ("movb      $0,C");
        !          2091: 
        !          2092:        xdirty_reg (dest->x86_reg);
        !          2093:        x_saveval (dest, size);
        !          2094:        x_postea (src);
        !          2095:        x_postea (dest);
        !          2096: }
        !          2097: 
        !          2098: void i386_func_not (ea_t *ea, int size)
        !          2099: {
        !          2100:        int flags = XQUICK_WRITEBACK;
        !          2101:        /* mem to mem operations are crap */
        !          2102:        //ifZNVC {} else flags |= XQUICK_REGS;
        !          2103:        
        !          2104:        x_loadval (ea, -1, flags);
        !          2105: 
        !          2106:        xln ("not%s     %s", szmov [size], ea->identifier);
        !          2107: 
        !          2108:        ifZNVC  xln ("test%s    %s,%s", szmov [size], ea->identifier, ea->identifier);
        !          2109:        ifNVC   xln ("sets      N");
        !          2110:        ifZ     xln ("setz      Z");
        !          2111:        ifNVC   xln ("movb      $0,V");
        !          2112:        ifNVC   xln ("movb      $0,C");
        !          2113:        
        !          2114:        xdirty_reg (ea->x86_reg);
        !          2115:        x_saveval (ea, size);
        !          2116:        x_postea (ea);
        !          2117: }
        !          2118: 
        !          2119: void i386_func_negx (ea_t *ea, int size)
        !          2120: {
        !          2121:        xflush_all ();
        !          2122:        xold_readea (ea, 0, 0);
        !          2123:        xold_readea (ea, 0, 1);
        !          2124:        xold_readea (ea, 0, 1);
        !          2125: 
        !          2126:        // XXX this is crap. do without jumps (negx)
        !          2127:        // then again, negx and subx caused so many problems
        !          2128:        // and took so long to get right that who cares..
        !          2129:        xln ("xorl      %%ebx,%%ebx");
        !          2130:        xln ("movb      X,%%cl");
        !          2131:        xln ("testb     %%cl,%%cl");
        !          2132:        xln ("jz        1f");
        !          2133:        xln ("stc");
        !          2134:        xln ("jmp       2f");
        !          2135:        
        !          2136:        xout ("1:\n");
        !          2137:        xln ("clc");
        !          2138:        
        !          2139:        xout ("2:\n");
        !          2140:        xln ("sbb%s     %s,%s", szmov [size], sreg (EAX), sreg (EBX));
        !          2141:        ifNVC {
        !          2142:                xln ("sets      N");
        !          2143:                xln ("seto      V");
        !          2144:                xln ("setc      C");
        !          2145:        }
        !          2146:                xln ("setc      X");
        !          2147:        ifZ {
        !          2148:                xln ("test%s    %s,%s", szmov[size], sreg (EBX), sreg (EBX));
        !          2149:                xln ("jz        1f");
        !          2150:                xln ("movb      $0,Z");
        !          2151:                xout ("1:\n");
        !          2152:        }
        !          2153:        
        !          2154:        xold_writeea (ea, size, EBX, 0);
        !          2155:        xold_writeea (ea, size, EBX, 1);
        !          2156:        xold_writeea (ea, size, EBX, 1);
        !          2157:        x_postea (ea);
        !          2158: }
        !          2159: void i386_func_neg (ea_t *ea, int size)
        !          2160: {
        !          2161:        x_loadval (ea, -1, XQUICK_WRITEBACK);
        !          2162: 
        !          2163:        xln ("neg%s     %s", szmov [size], ea->identifier);
        !          2164:        ifNVC {
        !          2165:                xln ("sets      N");
        !          2166:                xln ("seto      V");
        !          2167:                xln ("setc      C");
        !          2168:        }
        !          2169:        ifZ     xln ("setz      Z");
        !          2170:                xln ("setc      X");
        !          2171:        
        !          2172:        xdirty_reg (ea->x86_reg);
        !          2173:        x_saveval (ea, size);
        !          2174:        x_postea (ea);
        !          2175: }
        !          2176: 
        !          2177: void i386_func_divu (ea_t *ea, int reg)
        !          2178: {
        !          2179:        xflush_all ();
        !          2180:        ea->op_size = WORD;
        !          2181:        xold_readea (ea, 1, 0);
        !          2182:        xold_readea (ea, 1, 1);
        !          2183:        xold_readea (ea, 1, 1);
        !          2184: 
        !          2185:        xln ("movl      %d(%%ebp),%%eax", regpos (reg));
        !          2186:        xln ("movzwl    %%bx,%%ebx");
        !          2187:        xln ("xorl      %%edx,%%edx");
        !          2188:        xln ("divl      %%ebx");
        !          2189: 
        !          2190:        xln ("testl     $0xffff0000,%%eax");
        !          2191:        /* overflow */
        !          2192:        xln ("jnz       1f");
        !          2193: 
        !          2194:        ifZNVC  xln ("testl     %%eax,%%eax");
        !          2195:        ifNVC   xln ("sets      N");
        !          2196:        ifZ     xln ("setz      Z");
        !          2197:        ifNVC   xln ("movb      $0,V");
        !          2198:        ifNVC   xln ("movb      $0,C");
        !          2199: 
        !          2200:        xln ("shll      $16,%%edx");
        !          2201:        xln ("movw      %%ax,%%dx");
        !          2202: 
        !          2203:        xln ("movl      %%edx,%d(%%ebp)", regpos (reg));
        !          2204:        xln ("jmp       2f");
        !          2205:        xout ("1:\n");
        !          2206:        ifZNVC {
        !          2207:                xln ("movb      $0,C");
        !          2208:                xln ("movb      $1,N");
        !          2209:                xln ("movb      $0,Z");
        !          2210:                xln ("movb      $1,V");
        !          2211:        }
        !          2212:        xout ("2:\n");
        !          2213:        x_postea (ea);
        !          2214: }
        !          2215: 
        !          2216: void i386_func_divs (ea_t *ea, int reg)
        !          2217: {
        !          2218:        xflush_all ();
        !          2219:        ea->op_size = WORD;
        !          2220:        xold_readea (ea, 1, 0);
        !          2221:        xold_readea (ea, 1, 1);
        !          2222:        xold_readea (ea, 1, 1);
        !          2223: 
        !          2224:        xln ("movl      %d(%%ebp),%%eax", regpos (reg));
        !          2225:        xln ("movswl    %%bx,%%ebx");
        !          2226:        /* sign-extend eax into edx */
        !          2227:        xln ("cltd");
        !          2228:        xln ("idivl     %%ebx");
        !          2229:        xln ("jmp       3f");
        !          2230:        /* success */
        !          2231:        xout ("1:\n");
        !          2232:        
        !          2233:        ifZNVC  xln ("testl     %%eax,%%eax");
        !          2234:        ifNVC   xln ("sets      N");
        !          2235:        ifZ     xln ("setz      Z");
        !          2236: 
        !          2237:                xln ("shll      $16,%%edx");
        !          2238:        ifNVC   xln ("movb      $0,V");
        !          2239:                xln ("movw      %%ax,%%dx");
        !          2240:        ifNVC   xln ("movb      $0,C");
        !          2241:                xln ("movl      %%edx,%d(%%ebp)", regpos (reg));
        !          2242:                xln ("jmp       2f");
        !          2243:        /* overflow */
        !          2244:        xout ("3:\n");
        !          2245:        xln ("movl      %%eax,%%ecx");
        !          2246:        xln ("andl      $0xffff8000,%%ecx");
        !          2247:        xln ("jz        1b");
        !          2248:        xln ("cmpl      $0xffff8000,%%ecx");
        !          2249:        xln ("jz        1b");
        !          2250:        ifNVC {
        !          2251:                xln ("movb      $0,C");
        !          2252:                xln ("movb      $1,N");
        !          2253:                xln ("movb      $1,V");
        !          2254:        } ifZ   xln ("movb      $0,Z");
        !          2255:        xout ("2:\n");
        !          2256:        x_postea (ea);
        !          2257: }
        !          2258: 
        !          2259: /* src is the shift */
        !          2260: /* these are such cunts */
        !          2261: void i386_func_asl (ea_t *src, ea_t *dest, int size)
        !          2262: {
        !          2263:        /* special case we can optimise happily. no flags except X || Z needed, and
        !          2264:         * immediate src, reg dest. */
        !          2265:        ifNVC { } else if (is_immediate (src) && is_reg (dest)) {
        !          2266:                x_loadval (src, -1, XQUICK_IMMS);
        !          2267:                x_loadval (dest, -1, XQUICK_WRITEBACK);
        !          2268: 
        !          2269:                xln ("shl%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2270:                xln ("setc      X");
        !          2271:                ifZ     xln ("setz      Z");
        !          2272:                
        !          2273:                xdirty_reg (dest->x86_reg);
        !          2274:                x_saveval (dest, size);
        !          2275:                x_postea (src);
        !          2276:                x_postea (dest);
        !          2277:                return;
        !          2278:        }
        !          2279:        xflush_all ();
        !          2280:        xold_readea (src, 0, 0);
        !          2281:        xold_readea (dest, 1, 0);
        !          2282:        xold_readea (src, 0, 1);
        !          2283:        xold_readea (dest, 1, 1);
        !          2284:        xold_readea (src, 0, 1);
        !          2285:        xold_readea (dest, 1, 1);
        !          2286: 
        !          2287:        /* sets flags wrong. can use with flag optimisations one day */
        !          2288:        
        !          2289:        /* V flag not set by sal on x86 :( */
        !          2290:        
        !          2291:                xln ("and%s     $63,%s", szmov[size], sreg (EAX));
        !          2292:                xln ("cmp%s     $%d,%s", szmov[size], size2len[size], sreg (EAX));
        !          2293:                xln ("jl        2f");
        !          2294: 
        !          2295:                xln ("test%s    %s,%s", szmov[size], sreg (EBX), sreg (EBX));
        !          2296:                xln ("setnz     V");
        !          2297:                xln ("movb      $1,Z");
        !          2298:                xln ("movb      $0,N");
        !          2299:        /* XXX what should be done about C and X... */
        !          2300:                xln ("xor%s     %s,%s", szmov[size], sreg (EBX), sreg (EBX));
        !          2301:                xln ("jmp       4f");
        !          2302:                
        !          2303:                /* mask in edx */
        !          2304:                xout ("2:\n");
        !          2305:        ifNVC {
        !          2306:                xln ("movb      $%d,%%cl", size2len[size]-1);
        !          2307:                xln ("mov%s     $0x%s,%s", szmov[size],
        !          2308:                                (size == BYTE ? "ff" :
        !          2309:                                 (size == WORD ? "ffff" : "ffffffff")), sreg (EDX));
        !          2310:                xln ("subb      %%al,%%cl");
        !          2311:                xln ("movb      $0,V");
        !          2312:                xln ("shl%s     %%cl,%s", szmov[size], sreg (EDX));
        !          2313:                xln ("mov%s     %s,%s", szmov[size], sreg (EDX), sreg (ECX));
        !          2314: 
        !          2315:                /* V = ((val & mask) != mask &&) 
        !          2316:                 * ((val & mask != 0) */
        !          2317:                xln ("test%s    %s,%s", szmov[size], sreg (EBX), sreg (EDX));
        !          2318:                xln ("jz        3f");
        !          2319:                xln ("and%s     %s,%s", szmov[size], sreg (EBX), sreg (EDX));
        !          2320:                xln ("cmp%s     %s,%s", szmov[size], sreg (ECX), sreg (EDX));
        !          2321:                xln ("setnz     V");
        !          2322:                /* ^^ huge amount of code for one fucking flag... */
        !          2323:        
        !          2324:                xout ("3:\n");
        !          2325:        }
        !          2326:        xln ("movb      %%al,%%cl");
        !          2327:        xln ("shl%s     %%cl,%s", szmov [size], sreg (EBX));
        !          2328: 
        !          2329:        ifNVC {
        !          2330:                xln ("sets      N");
        !          2331:                xln ("setc      C");
        !          2332:        }
        !          2333:        xln ("setc      X");
        !          2334:        
        !          2335:        if (!is_immediate (src)) {
        !          2336:                /* shifts of zero bits set the Z flag on x86, apparently */
        !          2337:                /* (immediate shifts can't be zero) */
        !          2338:                ifZ     xln ("test%s    %s,%s", szmov[size], sreg (EBX), sreg (EBX));
        !          2339:        }
        !          2340:        ifZ     xln ("setz      Z");
        !          2341: 
        !          2342:        xout ("4:\n");
        !          2343: 
        !          2344:        xold_writeea (dest, size, EBX, 0);
        !          2345:        xold_writeea (dest, size, EBX, 1);
        !          2346:        xold_writeea (dest, size, EBX, 1);
        !          2347:        x_postea (src);
        !          2348:        x_postea (dest);
        !          2349: }
        !          2350: 
        !          2351: void i386_func_lsl (ea_t *src, ea_t *dest, int size)
        !          2352: {
        !          2353:        x_loadval (src, ECX, XQUICK_IMMS);
        !          2354:        x_loadval (dest, -1, XQUICK_WRITEBACK);
        !          2355:        
        !          2356:        if (is_immediate (src)) {
        !          2357:                xln ("shl%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2358:        } else {
        !          2359:                xln ("shl%s     %%cl,%s", szmov [size], dest->identifier);
        !          2360:        }
        !          2361: 
        !          2362:        ifZ     xln ("setz      Z");
        !          2363:        ifNVC {
        !          2364:                xln ("sets      N");
        !          2365:                xln ("setc      C");
        !          2366:                xln ("movb      $0,V");
        !          2367:        }
        !          2368:        ifX     xln ("setc      X");
        !          2369: 
        !          2370:        xdirty_reg (dest->x86_reg);
        !          2371:        x_saveval (dest, size);
        !          2372:        x_postea (src);
        !          2373:        x_postea (dest);
        !          2374: #if 0
        !          2375:        xflush_all ();
        !          2376:        xold_readea2 (src, 0, 0, XQUICK_REGS | XQUICK_IMMS);
        !          2377:        xold_readea2 (dest, 1, 0, XQUICK_REGS);
        !          2378:        xold_readea2 (src, 0, 1, XQUICK_REGS | XQUICK_IMMS);
        !          2379:        xold_readea2 (dest, 1, 1, XQUICK_REGS);
        !          2380:        xold_readea2 (src, 0, 1, XQUICK_REGS | XQUICK_IMMS);
        !          2381:        xold_readea2 (dest, 1, 1, XQUICK_REGS);
        !          2382: 
        !          2383:        if (is_immediate (src)) {
        !          2384:                xln ("shl%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2385:        } else {
        !          2386:                xln ("movl      %s,%%ecx", src->identifier);
        !          2387:                xln ("shl%s     %%cl,%s", szmov [size], dest->identifier);
        !          2388:        }
        !          2389: 
        !          2390:        ifZ     xln ("setz      Z");
        !          2391:        ifNVC {
        !          2392:                xln ("sets      N");
        !          2393:                xln ("setc      C");
        !          2394:                xln ("movb      $0,V");
        !          2395:        }
        !          2396:        xln ("setc      X");
        !          2397: 
        !          2398:        xold_writeea (dest, size, EBX, 0);
        !          2399:        xold_writeea (dest, size, EBX, 1);
        !          2400:        xold_writeea (dest, size, EBX, 1);
        !          2401:        x_postea (src);
        !          2402:        x_postea (dest);
        !          2403: #endif
        !          2404: }
        !          2405: 
        !          2406: void i386_func_roxr (ea_t *src, ea_t *dest, int size)
        !          2407: {
        !          2408:        xflush_all ();
        !          2409:        if ((src->mode != F_IMM) && (src->imm.val != 1)) {
        !          2410:                error ("X86 output of roxr unfinished. Only supports 1 bit immediate shifts.");
        !          2411:        }
        !          2412:        
        !          2413:        xold_readea (dest, 1, 0);
        !          2414:        xold_readea (dest, 1, 1);
        !          2415:        xold_readea (dest, 1, 1);
        !          2416: 
        !          2417:                xln ("movb      X,%%al");
        !          2418:                xln ("shr%s     $1,%s", szmov [size], sreg (EBX));
        !          2419:        ifNVC   xln ("setc      C");
        !          2420:                xln ("setc      X");
        !          2421:                xln ("shl%s     $%d,%s", szmov[size], size2len [size]-1, sreg (EAX));
        !          2422:        ifNVC   xln ("movb      $0,V");
        !          2423:                xln ("or%s      %s,%s", szmov [size], sreg (EAX), sreg (EBX));
        !          2424:        ifZNVC  xln ("test%s    %s,%s", szmov [size], sreg (EBX), sreg (EBX));
        !          2425:        ifNVC   xln ("sets      N");
        !          2426:        ifZ     xln ("setz      Z");
        !          2427: 
        !          2428:        xold_writeea (dest, size, EBX, 0);
        !          2429:        xold_writeea (dest, size, EBX, 1);
        !          2430:        xold_writeea (dest, size, EBX, 1);
        !          2431:        x_postea (dest);
        !          2432: }
        !          2433: void i386_func_roxl (ea_t *src, ea_t *dest, int size)
        !          2434: {
        !          2435:        xflush_all ();
        !          2436:        if ((src->mode != F_IMM) && (src->imm.val != 1)) {
        !          2437:                error ("X86 output of roxr unfinished. Only supports 1 bit immediate shifts.");
        !          2438:        }
        !          2439:        
        !          2440:        xold_readea (dest, 1, 0);
        !          2441:        xold_readea (dest, 1, 1);
        !          2442:        xold_readea (dest, 1, 1);
        !          2443: 
        !          2444:                xln ("movzbl    X,%%eax");
        !          2445:                xln ("shl%s     $1,%s", szmov [size], sreg (EBX));
        !          2446:        ifNVC   xln ("setc      C");
        !          2447:                xln ("setc      X");
        !          2448:                xln ("or%s      %s,%s", szmov [size], sreg (EAX), sreg (EBX));
        !          2449:        ifNVC   xln ("movb      $0,V");
        !          2450:        ifZNVC  xln ("test%s    %s,%s", szmov [size], sreg (EBX), sreg (EBX));
        !          2451:        ifNVC   xln ("sets      N");
        !          2452:        ifZ     xln ("setz      Z");
        !          2453: 
        !          2454:        xold_writeea (dest, size, EBX, 0);
        !          2455:        xold_writeea (dest, size, EBX, 1);
        !          2456:        xold_writeea (dest, size, EBX, 1);
        !          2457:        x_postea (dest);
        !          2458: }
        !          2459: void i386_func_rol (ea_t *src, ea_t *dest, int size)
        !          2460: {
        !          2461:        int len;
        !          2462:        len = size2len[size];
        !          2463:        /* fast case */
        !          2464:        ifZNVC {} else if (is_immediate (src)) {
        !          2465:                x_loadval (src, -1, XQUICK_IMMS);
        !          2466:                x_loadval (dest, -1, XQUICK_REGS);
        !          2467:        
        !          2468:                xln ("rol%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2469:                
        !          2470:                xdirty_reg (dest->x86_reg);
        !          2471:                x_saveval (dest, size);
        !          2472:                x_postea (src);
        !          2473:                x_postea (dest);
        !          2474:                return;
        !          2475:        }
        !          2476:        xflush_all ();
        !          2477:        src->op_size = BYTE;
        !          2478:        xold_readea (src, 0, 0);
        !          2479:        xold_readea (dest, 1, 0);
        !          2480:        xold_readea (src, 0, 1);
        !          2481:        xold_readea (dest, 1, 1);
        !          2482:        xold_readea (src, 0, 1);
        !          2483:        xold_readea (dest, 1, 1);
        !          2484: 
        !          2485:        xln ("movb      %%al,%%cl");
        !          2486:        xln ("decb      %%cl");
        !          2487:                xln ("rol%s     %%cl,%s", szmov [size], sreg (EBX));
        !          2488:                xln ("btl       $%d,%%ebx", len-1);
        !          2489:        ifNVC   xln ("setc      C");
        !          2490:                xln ("rol%s     $1,%s", szmov [size], sreg (EBX));
        !          2491:        ifNVC   xln ("movb      $0,V");
        !          2492:        ifZNVC  xln ("test%s    %s,%s", szmov [size], sreg (EBX), sreg (EBX));
        !          2493:        ifNVC   xln ("sets      N");
        !          2494:        ifZ     xln ("setz      Z");
        !          2495: 
        !          2496:        xold_writeea (dest, size, EBX, 0);
        !          2497:        xold_writeea (dest, size, EBX, 1);
        !          2498:        xold_writeea (dest, size, EBX, 1);
        !          2499:        x_postea (src);
        !          2500:        x_postea (dest);
        !          2501: }
        !          2502: 
        !          2503: void i386_func_ror (ea_t *src, ea_t *dest, int size)
        !          2504: {
        !          2505:        /* fast case */
        !          2506:        ifZNVC {} else if (is_immediate (src)) {
        !          2507:                x_loadval (src, -1, XQUICK_IMMS);
        !          2508:                x_loadval (dest, -1, 0);
        !          2509:        
        !          2510:                xln ("ror%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2511:                
        !          2512:                xdirty_reg (dest->x86_reg);
        !          2513:                x_saveval (dest, size);
        !          2514:                x_postea (src);
        !          2515:                x_postea (dest);
        !          2516:                return;
        !          2517:        }
        !          2518:        xflush_all ();
        !          2519:        xold_readea (src, 0, 0);
        !          2520:        xold_readea (dest, 1, 0);
        !          2521:        xold_readea (src, 0, 1);
        !          2522:        xold_readea (dest, 1, 1);
        !          2523:        xold_readea (src, 0, 1);
        !          2524:        xold_readea (dest, 1, 1);
        !          2525: 
        !          2526:        /* x86 ror doesn't set flags... */
        !          2527:                xln ("movb      %%al,%%cl");
        !          2528:                xln ("decb      %%cl");
        !          2529:                xln ("ror%s     %%cl,%s", szmov [size], sreg (EBX));
        !          2530:                xln ("btl       $0,%%ebx");
        !          2531:        ifNVC   xln ("setc      C");
        !          2532:                xln ("ror%s     $1,%s", szmov [size], sreg (EBX));
        !          2533:        ifNVC   xln ("movb      $0,V");
        !          2534:        ifZNVC  xln ("test%s    %s,%s", szmov [size], sreg (EBX), sreg (EBX));
        !          2535:        ifNVC   xln ("sets      N");
        !          2536:        ifZ     xln ("setz      Z");
        !          2537: 
        !          2538:        xold_writeea (dest, size, EBX, 0);
        !          2539:        xold_writeea (dest, size, EBX, 1);
        !          2540:        xold_writeea (dest, size, EBX, 1);
        !          2541:        x_postea (src);
        !          2542:        x_postea (dest);
        !          2543: }
        !          2544: 
        !          2545: void i386_func_asr (ea_t *src, ea_t *dest, int size)
        !          2546: {
        !          2547:        /* special case we can optimise happily. immediate src. */
        !          2548:        if (is_immediate (src) && is_reg (dest)) {
        !          2549:                x_loadval (src, -1, XQUICK_IMMS);
        !          2550:                x_loadval (dest, -1, XQUICK_WRITEBACK);
        !          2551:        
        !          2552:                xln ("sar%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2553:                ifNVC {
        !          2554:                        xln ("seto      V");
        !          2555:                        xln ("setc      C");
        !          2556:                }
        !          2557:                ifX     xln ("setc      X");
        !          2558:                ifZ     xln ("setz      Z");
        !          2559:                ifNVC   xln ("sets      N");
        !          2560: 
        !          2561:                xdirty_reg (dest->x86_reg);
        !          2562:                x_saveval (dest, size);
        !          2563:                x_postea (src);
        !          2564:                x_postea (dest);
        !          2565:                return;
        !          2566:        }
        !          2567:        xflush_all ();
        !          2568:        xold_readea (src, 0, 0);
        !          2569:        xold_readea (dest, 1, 0);
        !          2570:        xold_readea (src, 0, 1);
        !          2571:        xold_readea (dest, 1, 1);
        !          2572:        xold_readea (src, 0, 1);
        !          2573:        xold_readea (dest, 1, 1);
        !          2574: 
        !          2575: /* XXX warning if correct shift count zero behaviour matters then uncomment these */
        !          2576: //     xln ("movb      X,%%ch");
        !          2577:        xln ("movb      %%al,%%cl");
        !          2578:        xln ("cmpb      $%d,%%al", size2len[size]);
        !          2579:        xln ("jns       2f");
        !          2580:        xln ("sar%s     %%cl,%s", szmov [size], sreg (EBX));
        !          2581: 
        !          2582:        ifNVC {
        !          2583:                xln ("seto      V");
        !          2584:                xln ("setc      C");
        !          2585:        }
        !          2586:        ifX     xln ("setc      X");
        !          2587:        ifZ     xln ("setz      Z");
        !          2588:        ifNVC   xln ("sets      N");
        !          2589: 
        !          2590:        /* shift count zero do not set X... */
        !          2591: //             xln ("testb     %%al,%%al");
        !          2592: //             xln ("jnz       1f");
        !          2593:        
        !          2594: //             xln ("movb      %%ch,X");
        !          2595:        
        !          2596:                xout ("1:\n");
        !          2597:        /* shift count > thingy. smeg */
        !          2598:        //      xln ("cmpb      $%d,%%al", size2len[size]);
        !          2599:        //      xln ("jns       2f");
        !          2600:                
        !          2601:        //ifZNVC        xln ("test%s    %s,%s", szmov[size], sreg (EBX), sreg (EBX));
        !          2602:        //ifZ   xln ("setz      Z");
        !          2603: 
        !          2604:        /* Sign flag is crap with val=0 */
        !          2605:        //ifNVC xln ("sets      N");
        !          2606: 
        !          2607:                xln ("jmp       3f");
        !          2608:                xout ("2:\n");
        !          2609:                xln ("mov%s     $0,%s", szmov[size], sreg (EBX));
        !          2610:                xln ("movb      $0,Z");
        !          2611:                xout ("3:\n");
        !          2612: 
        !          2613:        xold_writeea (dest, size, EBX, 0);
        !          2614:        xold_writeea (dest, size, EBX, 1);
        !          2615:        xold_writeea (dest, size, EBX, 1);
        !          2616:        x_postea (src);
        !          2617:        x_postea (dest);
        !          2618: }
        !          2619: void i386_func_lsr (ea_t *src, ea_t *dest, int size)
        !          2620: {
        !          2621:        /* special case we can optimise happily. no flags except X || Z needed, and
        !          2622:         * immediate src, reg dest. */
        !          2623:        if (is_immediate (src) && is_reg (dest)) {
        !          2624:                x_loadval (src, -1, XQUICK_IMMS);
        !          2625:                x_loadval (dest, -1, XQUICK_WRITEBACK);
        !          2626: 
        !          2627:                xln ("shr%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2628:                ifZ     xln ("setz      Z");
        !          2629:                ifX     xln ("setc      X");
        !          2630:                ifNVC { 
        !          2631:                        xln ("sets      N");
        !          2632:                        xln ("setc      C");
        !          2633:                        xln ("movb      $0,V");
        !          2634:                }
        !          2635:        
        !          2636:                xdirty_reg (dest->x86_reg);
        !          2637:                x_saveval (dest, size);
        !          2638:                x_postea (src);
        !          2639:                x_postea (dest);
        !          2640:                return;
        !          2641:        }
        !          2642:        xflush_all ();
        !          2643:        xold_readea2 (src, 0, 0, XQUICK_REGS);
        !          2644:        xold_readea2 (dest, 1, 0, XQUICK_REGS);
        !          2645:        xold_readea2 (src, 0, 1, XQUICK_REGS);
        !          2646:        xold_readea2 (dest, 1, 1, XQUICK_REGS);
        !          2647:        xold_readea2 (src, 0, 1, XQUICK_REGS);
        !          2648:        xold_readea2 (dest, 1, 1, XQUICK_REGS);
        !          2649: 
        !          2650:        xln ("movl      %s,%%ecx", src->identifier);
        !          2651:        xln ("movb      X,%%ah");
        !          2652:        xln ("shr%s     %%cl,%s", szmov [size], dest->identifier);
        !          2653: 
        !          2654:        ifZ     xln ("setz      Z");
        !          2655:                xln ("setc      X");
        !          2656:        ifNVC { 
        !          2657:                xln ("sets      N");
        !          2658:                xln ("setc      C");
        !          2659:                xln ("movb      $0,V");
        !          2660:        }
        !          2661:        
        !          2662:        /* shift count of zero is special.. (and never in immediate case) */
        !          2663:        if (!is_immediate (src)) {
        !          2664:                xln ("testb     %%al,%%al");
        !          2665:                xln ("jnz       1f");
        !          2666:                xln ("movb      $0,C");
        !          2667:                xln ("movb      %%ah,X");
        !          2668:        }
        !          2669:        
        !          2670:        xout ("1:\n");
        !          2671:        xold_writeea (dest, size, EBX, 0);
        !          2672:        xold_writeea (dest, size, EBX, 1);
        !          2673:        xold_writeea (dest, size, EBX, 1);
        !          2674:        x_postea (src);
        !          2675:        x_postea (dest);
        !          2676: }
        !          2677: 
        !          2678: void i386_func_movem (ea_t *ea, int sz, int dr, int reg_mask)
        !          2679: {
        !          2680:        int i, offset, reg;
        !          2681:        sz++;
        !          2682:        ea_t dummy;
        !          2683: 
        !          2684:        x_loadea (ea);
        !          2685: 
        !          2686:        if (dr == 0) {
        !          2687:                /* reg to memory */
        !          2688:                if (ea->mode == 4) {
        !          2689:                        /* pre-decrement mode */
        !          2690:                        offset = 0;
        !          2691:                        for (i=0; i<16; i++) {
        !          2692:                                if (reg_mask & (1<<i)) {
        !          2693:                                        reg = xcopy_reg (15-i, sz, -1);
        !          2694:                                        do_bswap (reg, sz);
        !          2695:                                        xln ("mov%s     %s,-%d(%%ebp,%s)", szmov[sz], xreg (reg, sz), offset, ea->identifier);
        !          2696:                                        xreg_unlock (reg);
        !          2697:                                        offset += 1<<sz;
        !          2698:                                }
        !          2699:                        }
        !          2700:                        reg = xload_reg (ea->reg, LONG, -1);
        !          2701:                        xln ("subl      $%d,%s", offset, xreg (reg, LONG));
        !          2702:                        xdirty_reg (reg);
        !          2703:                        xreg_unlock (reg);
        !          2704:                } else {
        !          2705:                        offset = 0;
        !          2706:                        for (i=0; i<16; i++) {
        !          2707:                                if (reg_mask & (1<<i)) {
        !          2708:                                        reg = xcopy_reg (i, sz, -1);
        !          2709:                                        do_bswap (reg, sz);
        !          2710:                                        xln ("mov%s     %s,%d(%%ebp,%s)", szmov[sz], xreg (reg, sz), offset, ea->identifier);
        !          2711:                                        xreg_unlock (reg);
        !          2712:                                        offset += 1<<sz;
        !          2713:                                }
        !          2714:                        }
        !          2715:                }
        !          2716:        } else {
        !          2717: 
        !          2718:                /* mem to reg */
        !          2719:                offset = 0;
        !          2720:                for (i=0; i<16; i++) {
        !          2721:                        if (reg_mask & (1<<i)) {
        !          2722:                                dummy.mode = 0;
        !          2723:                                dummy.op_size = LONG;
        !          2724:                                dummy.x86_reg = -1;
        !          2725:                                dummy.x86_reg_writeback = -1;
        !          2726:                                dummy.reg = i;
        !          2727:                                reg = xalloc_reg (sz, -1);
        !          2728:                                x_ea_set_val_2_reg (&dummy, LONG, reg);
        !          2729:                                
        !          2730:                                xln ("mov%s     %d(%%ebp,%s),%s", szmov[sz], offset, ea->identifier, xreg (reg, sz));
        !          2731:                                do_bswap (reg, sz);
        !          2732:                                if (sz == WORD) xln ("movswl    %s,%s", xreg (reg, WORD), xreg (reg, LONG));
        !          2733:                                offset += 1<<sz;
        !          2734: 
        !          2735:                                /* once for xalloc_reg and once for x_ea_set_val_2_reg */
        !          2736:                                xreg_unlock (reg);
        !          2737:                                xreg_unlock (reg);
        !          2738:                        }
        !          2739:                }
        !          2740:                /* post-inc mode */
        !          2741:                if (ea->mode == 3) {
        !          2742:                        reg = xload_reg (ea->reg, LONG, -1);
        !          2743:                        xln ("addl      $%d,%s", offset, xreg (reg, LONG));
        !          2744:                        xdirty_reg (reg);
        !          2745:                        xreg_unlock (reg);
        !          2746:                }
        !          2747:        }
        !          2748:        /* deallocate temporary register allocations */
        !          2749:        if (ea->x86_reg != -1) {
        !          2750:                xreg_unlock (ea->x86_reg);
        !          2751:        }
        !          2752: }
        !          2753: 
        !          2754: void i386_func_subx (ea_t *src, ea_t *dest, int size)
        !          2755: {
        !          2756:        xflush_all ();
        !          2757:        xold_readea (src, 0, 0);
        !          2758:        xold_readea (dest, 1, 0);
        !          2759:        xold_readea (src, 0, 1);
        !          2760:        xold_readea (dest, 1, 1);
        !          2761:        xold_readea (src, 0, 1);
        !          2762:        xold_readea (dest, 1, 1);
        !          2763: 
        !          2764:        /* fucking X flag */
        !          2765:        ifNVCX {
        !          2766:                xln ("mov%s     %s,%s", szmov[size], sreg (EAX), sreg (ECX));
        !          2767:                xln ("mov%s     %s,%s", szmov[size], sreg (EBX), sreg (EDX));
        !          2768:                xln ("shr%s     $%d,%s", szmov[size], size2len[size]-1, sreg (ECX));
        !          2769:                xln ("shr%s     $%d,%s", szmov[size], size2len[size]-1, sreg (EDX));
        !          2770:        }
        !          2771:        xln ("add%s     X,%s", szmov [size], sreg (EAX));
        !          2772:        xln ("sub%s     %s,%s", szmov [size], sreg (EAX), sreg (EBX));
        !          2773: 
        !          2774:        ifNVC {
        !          2775:                xln ("sets      N");
        !          2776:                xln ("seto      V");
        !          2777:        }
        !          2778:        
        !          2779:        ifZ {
        !          2780:                xln ("jz        1f");
        !          2781:                xln ("movb      $0,Z");
        !          2782:                xout ("1:\n");
        !          2783:        }
        !          2784: 
        !          2785:        ifNVCX {
        !          2786:                /* fucking X flag */
        !          2787:                xln ("mov%s     %s,%s", szmov[size], sreg (EBX), sreg (EAX));
        !          2788:                xln ("shr%s     $%d,%s", szmov[size], size2len[size]-1, sreg (EAX));
        !          2789:                /* ecx=flgs, edx=flgo, eax=flgn */
        !          2790:                xln ("xor%s     %s,%s", szmov[size], sreg (EAX), sreg (EDX));
        !          2791:                xln ("xor%s     %s,%s", szmov[size], sreg (ECX), sreg (EAX));
        !          2792:                xln ("and%s     %s,%s", szmov[size], sreg (EDX), sreg (EAX));
        !          2793:                xln ("xor%s     %s,%s", szmov[size], sreg (EAX), sreg (ECX));
        !          2794:                ifX     xln ("movb      %%cl,X");
        !          2795:                ifNVC   xln ("movb      %%cl,C");
        !          2796:        }
        !          2797:        
        !          2798:        xold_writeea (dest, size, EBX, 0);
        !          2799:        xold_writeea (dest, size, EBX, 1);
        !          2800:        xold_writeea (dest, size, EBX, 1);
        !          2801:        x_postea (src);
        !          2802:        x_postea (dest);
        !          2803: }
        !          2804: 
        !          2805: void i386_func_addx (ea_t *src, ea_t *dest, int size)
        !          2806: {
        !          2807:        xflush_all ();
        !          2808:        xold_readea (src, 0, 0);
        !          2809:        xold_readea (dest, 1, 0);
        !          2810:        xold_readea (src, 0, 1);
        !          2811:        xold_readea (dest, 1, 1);
        !          2812:        xold_readea (src, 0, 1);
        !          2813:        xold_readea (dest, 1, 1);
        !          2814: 
        !          2815:        /* fucking X flag */
        !          2816:        ifNVCX {
        !          2817:                xln ("mov%s     %s,%s", szmov[size], sreg (EAX), sreg (ECX));
        !          2818:                xln ("mov%s     %s,%s", szmov[size], sreg (EBX), sreg (EDX));
        !          2819:                xln ("shr%s     $%d,%s", szmov[size], size2len[size]-1, sreg (ECX));
        !          2820:                xln ("shr%s     $%d,%s", szmov[size], size2len[size]-1, sreg (EDX));
        !          2821:        }
        !          2822:        xln ("add%s     X,%s", szmov [size], sreg (EAX));
        !          2823:        xln ("add%s     %s,%s", szmov [size], sreg (EAX), sreg (EBX));
        !          2824: 
        !          2825:        ifNVC {
        !          2826:                xln ("sets      N");
        !          2827:                xln ("seto      V");
        !          2828:        }
        !          2829:        
        !          2830:        ifZ {
        !          2831:                xln ("jz        1f");
        !          2832:                xln ("movb      $0,Z");
        !          2833:                xout ("1:\n");
        !          2834:        }
        !          2835: 
        !          2836:        ifNVCX {
        !          2837:                /* fucking X flag */
        !          2838:                xln ("mov%s     %s,%s", szmov[size], sreg (EBX), sreg (EAX));
        !          2839:                xln ("shr%s     $%d,%s", szmov[size], size2len[size]-1, sreg (EAX));
        !          2840:                /* ecx=flgs, edx=flgo, eax=flgn */
        !          2841:                xln ("xor%s     %s,%s", szmov[size], sreg (EDX), sreg (EAX));
        !          2842:                xln ("xor%s     %s,%s", szmov[size], sreg (ECX), sreg (EDX));
        !          2843:                xln ("and%s     %s,%s", szmov[size], sreg (EDX), sreg (EAX));
        !          2844:                xln ("xor%s     %s,%s", szmov[size], sreg (EAX), sreg (ECX));
        !          2845:                ifX     xln ("movb      %%cl,X");
        !          2846:                ifNVC   xln ("movb      %%cl,C");
        !          2847:        }
        !          2848:        xold_writeea (dest, size, EBX, 0);
        !          2849:        xold_writeea (dest, size, EBX, 1);
        !          2850:        xold_writeea (dest, size, EBX, 1);
        !          2851:        x_postea (src);
        !          2852:        x_postea (dest);
        !          2853: }
        !          2854: 
        !          2855: void i386_func_add (ea_t *src, ea_t *dest, int size)
        !          2856: {
        !          2857:        x_loadval (src, -1, XQUICK_REGS | XQUICK_IMMS);
        !          2858:        x_loadval (dest, -1, XQUICK_WRITEBACK);
        !          2859:        
        !          2860:        xln ("add%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2861:                
        !          2862:        ifNVC {
        !          2863:                xln ("sets      N");
        !          2864:                xln ("seto      V");
        !          2865:                xln ("setc      C");
        !          2866:        }
        !          2867:        ifZ     xln ("setz      Z");
        !          2868:        ifX     xln ("setc      X");
        !          2869: 
        !          2870:        xdirty_reg (dest->x86_reg);
        !          2871:        x_saveval (dest, size);
        !          2872:        x_postea (src);
        !          2873:        x_postea (dest);
        !          2874: }
        !          2875: 
        !          2876: void i386_func_cmpa (ea_t *src, ea_t *dest, int size)
        !          2877: {
        !          2878:        src->op_size = size;
        !          2879:        dest->op_size = LONG;
        !          2880:        x_loadval (src, -1, (size != WORD ? 0 : XCAN_OVERWRITE));
        !          2881:        x_loadval (dest, -1, 0);
        !          2882: 
        !          2883:        if (size == WORD) xln ("movswl  %s,%s", xreg (src->x86_reg, WORD), xreg (src->x86_reg, LONG));
        !          2884: 
        !          2885:        xln ("cmpl      %s,%s", xreg (src->x86_reg, LONG), dest->identifier);
        !          2886: 
        !          2887:        ifNVC {
        !          2888:                xln ("sets      N");
        !          2889:                xln ("seto      V");
        !          2890:                xln ("setc      C");
        !          2891:        }
        !          2892:        ifZ     xln ("setz      Z");
        !          2893: 
        !          2894:        x_postea (src);
        !          2895:        x_postea (dest);
        !          2896: }
        !          2897: 
        !          2898: void i386_func_cmp (ea_t *src, ea_t *dest, int size)
        !          2899: {
        !          2900:        x_loadval (src, -1, XQUICK_IMMS);
        !          2901:        x_loadval (dest, -1, 0);
        !          2902:        
        !          2903:        xln ("cmp%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2904: 
        !          2905:        ifNVC {
        !          2906:                xln ("sets      N");
        !          2907:                xln ("seto      V");
        !          2908:                xln ("setc      C");
        !          2909:        }
        !          2910:        ifZ     xln ("setz      Z");
        !          2911: 
        !          2912:        x_postea (src);
        !          2913:        x_postea (dest);
        !          2914: }
        !          2915: 
        !          2916: void i386_func_sub (ea_t *src, ea_t *dest, int size)
        !          2917: {
        !          2918:        x_loadval (src, -1, XQUICK_REGS | XQUICK_IMMS);
        !          2919:        x_loadval (dest, -1, XQUICK_WRITEBACK);
        !          2920:        
        !          2921:        xln ("sub%s     %s,%s", szmov [size], src->identifier, dest->identifier);
        !          2922: 
        !          2923:        ifNVC {
        !          2924:                xln ("sets      N");
        !          2925:                xln ("seto      V");
        !          2926:                xln ("setc      C");
        !          2927:        }
        !          2928:        ifZ     xln ("setz      Z");
        !          2929:        ifX     xln ("setc      X");
        !          2930: 
        !          2931:        xdirty_reg (dest->x86_reg);
        !          2932:        x_saveval (dest, size);
        !          2933:        x_postea (src);
        !          2934:        x_postea (dest);
        !          2935: }
        !          2936: 
        !          2937: void i386_func_adda (ea_t *src, ea_t *dest, int size)
        !          2938: {
        !          2939:        src->op_size = size;
        !          2940:        dest->op_size = LONG;
        !          2941:        x_loadval (src, -1, (size != WORD ? 0 : XCAN_OVERWRITE));
        !          2942:        x_loadval (dest, -1, 0);
        !          2943:        
        !          2944:        if (size == WORD) xln ("movswl  %s,%s", xreg (src->x86_reg, WORD), xreg (src->x86_reg, LONG));
        !          2945:        
        !          2946:        xln ("addl      %s,%s", xreg (src->x86_reg, LONG), dest->identifier);
        !          2947:                
        !          2948:        xdirty_reg (dest->x86_reg);
        !          2949:        x_saveval (dest, LONG);
        !          2950:        x_postea (src);
        !          2951:        x_postea (dest);
        !          2952: }
        !          2953: 
        !          2954: void i386_func_suba (ea_t *src, ea_t *dest, int size)
        !          2955: {
        !          2956:        src->op_size = size;
        !          2957:        dest->op_size = LONG;
        !          2958:        x_loadval (src, -1, (size != WORD ? 0 : XCAN_OVERWRITE));
        !          2959:        x_loadval (dest, -1, 0);
        !          2960:        
        !          2961:        if (size == WORD) xln ("movswl  %s,%s", xreg (src->x86_reg, WORD), xreg (src->x86_reg, LONG));
        !          2962:        
        !          2963:        xln ("subl      %s,%s", xreg (src->x86_reg, LONG), dest->identifier);
        !          2964:                
        !          2965:        xdirty_reg (dest->x86_reg);
        !          2966:        x_saveval (dest, LONG);
        !          2967:        x_postea (src);
        !          2968:        x_postea (dest);
        !          2969: }
        !          2970: 
        !          2971: void i386_func_swap (int reg)
        !          2972: {
        !          2973:        struct ea_t ea;
        !          2974: 
        !          2975:        ea.mode = 0;
        !          2976:        ea.reg = reg;
        !          2977:        ea.op_size = LONG;
        !          2978:        ea.x86_reg = -1;
        !          2979:        ea.x86_reg_writeback = -1;
        !          2980: 
        !          2981:        ifZNVC {
        !          2982:                x_loadval (&ea, -1, 0);
        !          2983:                ifNVC   xln ("movb      $0,V");
        !          2984:                        xln ("rorl      $16,%s", ea.identifier);
        !          2985:                ifNVC   xln ("movb      $0,C");
        !          2986:                ifZNVC  xln ("testl     %s,%s", ea.identifier, ea.identifier);
        !          2987:                ifNVC   xln ("sets      N");
        !          2988:                ifZ     xln ("setz      Z");
        !          2989:        } else {
        !          2990:                x_loadval (&ea, -1, 0);
        !          2991:                xln ("rorl      $16,%s", ea.identifier);
        !          2992:        }
        !          2993:        xdirty_reg (ea.x86_reg);
        !          2994:        x_saveval (&ea, LONG);
        !          2995:        x_postea (&ea);
        !          2996: }
        !          2997: 
        !          2998: void i386_func_jsr (ea_t *dest)
        !          2999: {
        !          3000:        char buf[256];
        !          3001:        xflush_all ();
        !          3002:        snprintf (buf, sizeof (buf), "%x", cur_bitpos);
        !          3003:        add_label (buf, C_ADDR, cur_bitpos - BASE);
        !          3004:        add_fixup (0, C_ADDR, buf);
        !          3005: 
        !          3006:        /* XXX this is a bit inefficient, since the label is a
        !          3007:         * constant and could be bswapped at compile-time
        !          3008:         * -- but the scheduling makes this irrelevant */
        !          3009:        xln ("movl      %d(%%ebp),%%ebx", regpos (15));
        !          3010:        xln ("movl      $__D%x,%%eax", cur_bitpos);
        !          3011:        xln ("subl      $4,%%ebx");
        !          3012:        xln ("bswap     %%eax");
        !          3013:        xln ("movl      %%ebx,%d(%%ebp)", regpos (15));
        !          3014:        xln ("movl      %%eax,(%%ebp,%%ebx)");
        !          3015:        
        !          3016:        i386_jump (dest);
        !          3017: }
        !          3018: 
        !          3019: void i386_func_bcc (ea_t *dest, int cond)
        !          3020: {
        !          3021:        xflush_all ();
        !          3022:        if (cond == 0) {
        !          3023:                i386_jump (dest);
        !          3024:        } else {
        !          3025:                x_cond_begin (cond);
        !          3026:                i386_jump_e (dest);
        !          3027:                x_cond_end (cond);
        !          3028:        }
        !          3029: }
        !          3030: 
        !          3031: /* XXX note: this does not call i386_jump and therefore does not
        !          3032:  * check for pending exceptions. an infinite DBcc loop will not
        !          3033:  * allow exceptions to occur.
        !          3034:  * does it matter? */
        !          3035: void i386_func_dbcc (const char *label, int cond, int reg)
        !          3036: {
        !          3037:        xflush_all ();
        !          3038:        if (cond == 1) {
        !          3039:                xln ("decw      %d(%%ebp)", regpos (reg));
        !          3040:                xln ("cmpw      $-1,%d(%%ebp)", regpos (reg));
        !          3041:                xln ("jne       __N%s", label);
        !          3042:        } else {
        !          3043:                /* relies on naming of x_cond_begin labels */
        !          3044:                x_cond_begin (cond);
        !          3045:                xln ("jmp       10f");
        !          3046:                x_cond_end ();
        !          3047:                xln ("decw      %d(%%ebp)", regpos (reg));
        !          3048:                xln ("cmpw      $-1,%d(%%ebp)", regpos (reg));
        !          3049:                xln ("jne       __N%s", label);
        !          3050:                xout ("10:\n");
        !          3051:        }
        !          3052: }
        !          3053: 
        !          3054: void i386_func_clr (ea_t *dest)
        !          3055: {
        !          3056:        xflush_all ();
        !          3057:                xln ("xorl      %%eax,%%eax");
        !          3058:        ifZ     xln ("movb      $1,Z");
        !          3059:        ifNVC   xln ("movb      %%al,N");
        !          3060:        ifNVC   xln ("movb      %%al,V");
        !          3061:        ifNVC   xln ("movb      %%al,C");
        !          3062:        
        !          3063:        xold_writeea (dest, dest->op_size, EAX, 0);
        !          3064:        xold_writeea (dest, dest->op_size, EAX, 1);
        !          3065:        xold_writeea (dest, dest->op_size, EAX, 1);
        !          3066:        x_postea (dest);
        !          3067: }
        !          3068: 
        !          3069: void i386_func_exg (int reg1, int reg2)
        !          3070: {
        !          3071:        xflush_all ();
        !          3072:        xln ("movl      %d(%%ebp),%%eax", regpos (reg1));
        !          3073:        xln ("movl      %d(%%ebp),%%ebx", regpos (reg2));
        !          3074:        xln ("movl      %%eax,%d(%%ebp)", regpos (reg2));
        !          3075:        xln ("movl      %%ebx,%d(%%ebp)", regpos (reg1));
        !          3076: }
        !          3077: 
        !          3078: void i386_func_ext (int reg, int size)
        !          3079: {
        !          3080:        int x86reg = xload_reg (reg, size-1, -1);
        !          3081: 
        !          3082:        if (size == WORD) {
        !          3083:                xln ("movsbw    %s,%s", xreg (x86reg, BYTE), xreg (x86reg, WORD));
        !          3084:        } else {
        !          3085:                xln ("movswl    %s,%s", xreg (x86reg, WORD), xreg (x86reg, LONG));
        !          3086:        }
        !          3087: 
        !          3088:        ifNVC   xln ("movb      $0,V");
        !          3089:        ifNVC   xln ("movb      $0,C");
        !          3090:        ifZNVC  xln ("test%s    %s,%s", szmov[size], xreg (x86reg,size), xreg (x86reg,size));
        !          3091:        ifZ     xln ("setz      Z");
        !          3092:        ifNVC   xln ("sets      N");
        !          3093:        xdirty_reg (x86reg);
        !          3094:        xreg_unlock (x86reg);
        !          3095: }
        !          3096: 
        !          3097: void i386_func_rte ()
        !          3098: {
        !          3099:        xflush_all ();
        !          3100:        xln ("movb      bX,%%bh");
        !          3101:        xln ("movb      bN,%%bl");
        !          3102:        xln ("movb      bZ,%%ch");
        !          3103:        xln ("movb      bV,%%cl");
        !          3104:        xln ("movb      bC,%%dh");
        !          3105:        xln ("movb      %%bh,X");
        !          3106:        xln ("movb      %%bl,N");
        !          3107:        xln ("movb      %%ch,Z");
        !          3108:        xln ("movb      %%cl,V");
        !          3109:        xln ("movb      %%dh,C");
        !          3110:        xln ("movl      rdest,%%eax");
        !          3111:        xln ("movl      $0,rdest");
        !          3112:        //xln ("jmp     jumptable");
        !          3113:        xln ("jmp       *jtab(,%%eax,2)");
        !          3114: }
        !          3115: 
        !          3116: void i386_func_rts ()
        !          3117: {
        !          3118:        xflush_all ();
        !          3119:        xln ("movl      %d(%%ebp),%%ebx", regpos (15));
        !          3120:        xln ("movl      (%%ebx,%%ebp),%%eax");
        !          3121:        xln ("addl      $4,%%ebx");
        !          3122:        xln ("bswap     %%eax");
        !          3123:        xln ("movl      %%ebx,%d(%%ebp)", regpos (15));
        !          3124:        //xln ("jmp     jumptable");
        !          3125:        xln ("jmp       *jtab(,%%eax,2)");
        !          3126: }
        !          3127: 
        !          3128: void i386_func_illegal ()
        !          3129: {
        !          3130:        xflush_all ();
        !          3131:        xln ("pushl     line_no");
        !          3132:        xln ("pushl     $illegal_fmt");
        !          3133:        xln ("call      printf");
        !          3134:        xln ("addl      $8,%%esp");
        !          3135:        xln ("call      abort");
        !          3136: }
        !          3137: 
        !          3138: void i386_func_hcall (int val)
        !          3139: {
        !          3140:        xflush_all ();
        !          3141:        xln ("call      *hcalls+%d", val*4);
        !          3142: }
        !          3143: 
        !          3144: void i386_func_link (int reg, int val)
        !          3145: {
        !          3146:        xflush_all ();
        !          3147:        xln ("movl      %d(%%ebp),%%ebx", regpos (15));
        !          3148:        xln ("subl      $4,%%ebx");
        !          3149:        
        !          3150:        xln ("movl      %d(%%ebp),%%eax", regpos (reg));
        !          3151:        xln ("bswap     %%eax");
        !          3152:        
        !          3153:        xln ("movl      %%eax,(%%ebp,%%ebx)");
        !          3154:        xln ("addl      $%d,%d(%%ebp)", val-4, regpos (15));
        !          3155:        xln ("movl      %%ebx,%d(%%ebp)", regpos (reg));
        !          3156: }
        !          3157: 
        !          3158: void i386_func_unlk (int reg)
        !          3159: {
        !          3160:        xflush_all ();
        !          3161:        xln ("movl      %d(%%ebp),%%eax", regpos (reg));
        !          3162:        xln ("movl      (%%ebp,%%eax),%%ebx");
        !          3163:        xln ("addl      $4,%%eax");
        !          3164:        xln ("bswap     %%ebx");
        !          3165:        xln ("movl      %%ebx,%d(%%ebp)", regpos (reg));
        !          3166:        xln ("movl      %%eax,%d(%%ebp)", regpos (15));
        !          3167: }
        !          3168: 
        !          3169: void i386_func_move (ea_t *src, ea_t *dest, int size)
        !          3170: {
        !          3171:        x_loadval (src, -1, XQUICK_IMMS);
        !          3172: 
        !          3173:        ifNVC xln ("movb        $0,V");
        !          3174:        ifNVC xln ("movb        $0,C");
        !          3175: 
        !          3176:        if (is_immediate (src)) {
        !          3177:                ifZ     xln ("movb      $%d,Z", src->imm.val == 0);
        !          3178:                ifNVC   xln ("movb      $%d,N", src->imm.val < 0);
        !          3179:        } else {
        !          3180:                ifZNVC xln ("test%s     %s,%s", szmov [size], src->identifier, src->identifier);
        !          3181:                ifZ xln ("setz  Z");
        !          3182:                ifNVC xln ("sets        N");
        !          3183:        }
        !          3184:        
        !          3185:        if (is_reg (dest)) {
        !          3186:                dest->x86_reg = xload_reg2 (dest->reg, size, -1, XLOADREG_FOR_OVERWRITE, szfull);
        !          3187:        } else {
        !          3188:                dest->x86_reg = xalloc_reg (size, -1);
        !          3189:        }
        !          3190:        xln ("mov%s     %s,%s", szmov[size], src->identifier,
        !          3191:                        xreg (dest->x86_reg, size));
        !          3192:        xdirty_reg (dest->x86_reg);
        !          3193:        
        !          3194:        x_saveval (dest, size);
        !          3195:        x_postea (src);
        !          3196:        x_postea (dest);
        !          3197: }
        !          3198: 
        !          3199: void i386_func_movea (ea_t *src, int reg_dest)
        !          3200: {
        !          3201: #if 0
        !          3202:        xflush_all ();
        !          3203:        xold_readea (src, 0, 0);
        !          3204:        xold_readea (src, 0, 1);
        !          3205:        xold_readea (src, 0, 1);
        !          3206:        if (src->op_size == WORD) xln ("movswl  %%ax,%%eax");
        !          3207:        xln ("movl      %%eax,%d(%%ebp)", regpos (reg_dest));
        !          3208:        x_postea (src);
        !          3209: #endif
        !          3210:        int reg;
        !          3211:        struct ea_t dest;
        !          3212: 
        !          3213:        dest.mode = 1;
        !          3214:        dest.reg = reg_dest;
        !          3215:        dest.op_size = LONG;
        !          3216:        dest.x86_reg = -1;
        !          3217:        dest.x86_reg_writeback = -1;
        !          3218:        
        !          3219:        x_loadval (src, -1, 0);
        !          3220:        
        !          3221:        reg = xalloc_reg (LONG, -1);
        !          3222: 
        !          3223:        if (src->op_size == WORD)
        !          3224:                xln ("movswl    %s,%s", xreg (src->x86_reg, WORD), xreg (reg, LONG));
        !          3225:        else
        !          3226:                xln ("movl      %s,%s", xreg (src->x86_reg, LONG), xreg (reg, LONG));
        !          3227:        
        !          3228:        x_ea_set_val_2_reg (&dest, LONG, reg);
        !          3229: 
        !          3230:        xreg_unlock (reg);
        !          3231:        xdirty_reg (reg);
        !          3232:        
        !          3233:        x_saveval (&dest, LONG);
        !          3234:        x_postea (src);
        !          3235:        x_postea (&dest);
        !          3236: }
        !          3237: 
        !          3238: void i386_func_tst (ea_t *ea)
        !          3239: {
        !          3240:        x_loadval (ea, -1, 0);
        !          3241:        ifNVC   xln ("movb      $0,C");
        !          3242:        ifNVC   xln ("movb      $0,V");
        !          3243:        xln ("test%s    %s,%s", szmov[ea->op_size], ea->identifier, ea->identifier);
        !          3244:        ifZ     xln ("setz      Z");
        !          3245:        ifNVC   xln ("sets      N");
        !          3246:        x_postea (ea);
        !          3247: }
        !          3248: 
        !          3249: void i386_func_pea (ea_t *ea)
        !          3250: {
        !          3251:        int a7;
        !          3252:        
        !          3253:        x_loadea (ea);
        !          3254:        a7 = xload_reg (15, LONG, -1);
        !          3255: 
        !          3256:        xln ("subl      $4,%s", xreg (a7, LONG));
        !          3257:        xln ("bswap     %s", ea->identifier);
        !          3258:        xln ("movl      %s,(%%ebp,%s)", ea->identifier, xreg (a7, LONG));
        !          3259:        
        !          3260:        xdirty_reg (a7);
        !          3261:        xreg_unlock (a7);
        !          3262:        x_postea (ea);
        !          3263: }
        !          3264: 
        !          3265: void i386_func_lea (ea_t *ea, int reg)
        !          3266: {
        !          3267:        struct ea_t dest;
        !          3268: 
        !          3269:        dest.mode = 1;
        !          3270:        dest.reg = reg;
        !          3271:        dest.op_size = LONG;
        !          3272:        dest.x86_reg = -1;
        !          3273:        dest.x86_reg_writeback = -1;
        !          3274: 
        !          3275:        x_loadea (ea);
        !          3276: 
        !          3277:        x_ea_set_val_2_reg (&dest, LONG, ea->x86_reg);
        !          3278:        x_saveval (&dest, LONG);
        !          3279:        x_postea (ea);
        !          3280:        x_postea (&dest);
        !          3281: }
        !          3282: 
        !          3283: void i386_func_scc (ea_t *dest, int cond)
        !          3284: {
        !          3285:        xflush_all ();
        !          3286:        x_cond_begin (cond);
        !          3287:        
        !          3288:        xln ("movb      $0xff,%%al");
        !          3289:        xold_writeea (dest, BYTE, EAX, 0);
        !          3290:        xold_writeea (dest, BYTE, EAX, 1);
        !          3291:        xold_writeea (dest, BYTE, EAX, 1);
        !          3292:        x_postea (dest);
        !          3293:        xln ("jmp       10f");
        !          3294:        
        !          3295:        x_cond_end ();
        !          3296: 
        !          3297:        xln ("xorb      %%al,%%al");
        !          3298:        xold_writeea (dest, BYTE, EAX, 0);
        !          3299:        xold_writeea (dest, BYTE, EAX, 1);
        !          3300:        xold_writeea (dest, BYTE, EAX, 1);
        !          3301:        x_postea (dest);
        !          3302:        
        !          3303:        xout ("10:\n");
        !          3304: }
        !          3305: 
        !          3306: static void output_op (op_t *op, op_t *next)
        !          3307: {
        !          3308:        xregalloc_age ();
        !          3309: 
        !          3310:        op->src.x86_reg = -1;
        !          3311:        op->src.x86_reg_writeback = -1;
        !          3312:        op->dest.x86_reg = -1;
        !          3313:        op->dest.x86_reg_writeback = -1;
        !          3314:        
        !          3315:        switch (op->optype) {
        !          3316:                case OP_MULS: i386_func_muls (&op->src, &op->dest); break;
        !          3317:                case OP_MULU: i386_func_mulu (&op->src, &op->dest); break;
        !          3318:                case OP_ADDA: i386_func_adda (&op->src, &op->dest, op->size); break;
        !          3319:                case OP_SUBA: i386_func_suba (&op->src, &op->dest, op->size); break;
        !          3320:                case OP_ADD: i386_func_add (&op->src, &op->dest, op->size); break;
        !          3321:                case OP_SUB: i386_func_sub (&op->src, &op->dest, op->size); break;
        !          3322:                case OP_NOT: i386_func_not (&op->src, op->size); break;
        !          3323:                case OP_NEGX: i386_func_negx (&op->src, op->size); break;
        !          3324:                case OP_NEG: i386_func_neg (&op->src, op->size); break;
        !          3325:                case OP_DIVS: i386_func_divs (&op->src, op->dest.reg); break;
        !          3326:                case OP_DIVU: i386_func_divu (&op->src, op->dest.reg); break;
        !          3327:                case OP_ADDX: i386_func_addx (&op->src, &op->dest, op->size); break;
        !          3328:                case OP_SUBX: i386_func_subx (&op->src, &op->dest, op->size); break;
        !          3329:                case OP_BCHG: i386_func_bchg (&op->src, &op->dest, op->size); break;
        !          3330:                case OP_BCLR: i386_func_bclr (&op->src, &op->dest, op->size); break;
        !          3331:                case OP_BSET: i386_func_bset (&op->src, &op->dest, op->size); break;
        !          3332:                case OP_BTST: i386_func_btst (&op->src, &op->dest, op->size); break;
        !          3333:                case OP_ASL: i386_func_asl (&op->src, &op->dest, op->size); break;
        !          3334:                case OP_ASR: i386_func_asr (&op->src, &op->dest, op->size); break;
        !          3335:                case OP_LSL: i386_func_lsl (&op->src, &op->dest, op->size); break;
        !          3336:                case OP_LSR: i386_func_lsr (&op->src, &op->dest, op->size); break;
        !          3337:                case OP_ROL: i386_func_rol (&op->src, &op->dest, op->size); break;
        !          3338:                case OP_ROR: i386_func_ror (&op->src, &op->dest, op->size); break;
        !          3339:                case OP_ROXL: i386_func_roxl (&op->src, &op->dest, op->size); break;
        !          3340:                case OP_ROXR: i386_func_roxr (&op->src, &op->dest, op->size); break;
        !          3341:                case OP_OR: i386_func_logop (&op->src, &op->dest, op->size, '|'); break;
        !          3342:                case OP_AND: i386_func_logop (&op->src, &op->dest, op->size, '&'); break;
        !          3343:                case OP_XOR: i386_func_logop (&op->src, &op->dest, op->size, '^'); break;
        !          3344:                case OP_SWAP: i386_func_swap (op->src.reg); break;
        !          3345:                case OP_JSR: i386_func_jsr (&op->src); break;
        !          3346:                case OP_BCC: i386_func_bcc (&op->src, op->opcode.Bcc.cond); break;
        !          3347:                case OP_DBCC: i386_func_dbcc (op->dest.imm.label, op->opcode.Bcc.cond, op->src.reg); break;
        !          3348:                case OP_CLR: i386_func_clr (&op->src); break;
        !          3349:                case OP_CMP: i386_func_cmp (&op->src, &op->dest, op->size); break;
        !          3350:                case OP_CMPA: i386_func_cmpa (&op->src, &op->dest, op->size); break;
        !          3351:                case OP_EXG: i386_func_exg (op->src.reg, op->dest.reg); break;
        !          3352:                case OP_EXT: i386_func_ext (op->src.reg, op->size); break;
        !          3353:                case OP_MOVEM: i386_func_movem (&op->src, op->opcode.movem.sz, op->opcode.movem.dr, op->dest.reg); break;
        !          3354:                case OP_RTE: i386_func_rte (); break;
        !          3355:                case OP_RTS: i386_func_rts (); break;
        !          3356:                case OP_ILLEGAL: i386_func_illegal (); break;
        !          3357:                case OP_HCALL: i386_func_hcall (op->src.imm.val); break;
        !          3358:                case OP_LINK: i386_func_link (op->src.reg, op->dest.imm.val); break;
        !          3359:                case OP_UNLK: i386_func_unlk (op->src.reg); break;
        !          3360:                case OP_MOVE: i386_func_move (&op->src, &op->dest, op->size); break;
        !          3361:                case OP_MOVEA: i386_func_movea (&op->src, op->dest.reg); break;
        !          3362:                case OP_TST: i386_func_tst (&op->src); break;
        !          3363:                case OP_PEA: i386_func_pea (&op->src); break;
        !          3364:                case OP_LEA: i386_func_lea (&op->src, op->dest.reg); break;
        !          3365:                case OP_JMP: i386_jump (&op->src); break;
        !          3366:                case OP_SCC: i386_func_scc (&op->src, op->opcode.DBcc.cond); break;
        !          3367: 
        !          3368:                default: 
        !          3369:                             printf ("type %d\n", op->optype);
        !          3370:                             assert (0);
        !          3371:        }
        !          3372: 
        !          3373: /*     int i;
        !          3374:        int fucked = 0;
        !          3375:        for (i=0; i<X86REG_MAX; i++) {
        !          3376:                printf ("l%d X86-reg %d: contained 68k reg %d, age %d, dirty %d, locked %d\n",
        !          3377:                                line_no,
        !          3378:                                i, i386_regalloc[i].m68k_reg,
        !          3379:                                i386_regalloc[i].age,
        !          3380:                                i386_regalloc[i].dirty,
        !          3381:                                i386_regalloc[i].locked);
        !          3382:                if (i386_regalloc[i].locked) fucked = 1;
        !          3383:        }
        !          3384:        printf ("\n");
        !          3385:        assert (fucked == 0);*/
        !          3386: }
        !          3387: 
        !          3388: static void do_pending ()
        !          3389: {
        !          3390:        if (pending_flush) {
        !          3391:                xflush_all ();
        !          3392:        }
        !          3393:        pending_flush = cur_flush;
        !          3394:        cur_flush = 0;
        !          3395: 
        !          3396: #ifdef DUMP_LOADS_OF_CRAP
        !          3397:        /* state must be consistent to print reg contents */
        !          3398:        xflush_all ();
        !          3399: #endif /* DUMP_LOADS_OF_CRAP */
        !          3400:        
        !          3401:        if (pending_labels) {
        !          3402:                rout (pending_labels);
        !          3403:                free (pending_labels);
        !          3404:        }
        !          3405:        pending_labels = cur_labels;
        !          3406:        cur_labels = calloc (LABBUF_LEN, 1);
        !          3407:        strcat (cur_labels, "\n");
        !          3408:        
        !          3409:        if (pending.optype) output_op (&pending, NULL);
        !          3410: }
        !          3411: 
        !          3412: void i386_push_op (enum M68K_OPS type, ea_t *src, ea_t *dest, int size)
        !          3413: {
        !          3414:        i386_push_op2 (type, src, dest, size, 0);
        !          3415: }
        !          3416: void i386_push_op2 (enum M68K_OPS type, ea_t *src, ea_t *dest, int size, int opcode)
        !          3417: {
        !          3418:        op_t op;
        !          3419: 
        !          3420:        op.size = size;
        !          3421:        op.opcode.code = opcode;
        !          3422:        op.optype = type;
        !          3423:        if (type == OP_JSR)
        !          3424:                return_target = 1;
        !          3425:        else
        !          3426:                return_target = 0;
        !          3427:        if (src) {
        !          3428:                op.src = *src;
        !          3429:        }
        !          3430:        if (dest) {
        !          3431:                op.dest = *dest;
        !          3432:        }
        !          3433:        next_op_type = op.optype;
        !          3434: 
        !          3435:        do_pending ();
        !          3436:        pending = op;
        !          3437: }
        !          3438: void i386_push_op_basic (enum M68K_OPS type)
        !          3439: {
        !          3440:        i386_push_op2 (type, NULL, NULL, 0, 0);
        !          3441: }
        !          3442: 

unix.superglobalmegacorp.com

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