x86dis.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       x86dis.c (37184B)
       ---
            1 // X86 assembly library, adapted for use in VX32
            2 
            3 #include "x86dis.h"
            4 #include <string.h>
            5 #include <stdio.h>
            6 
            7 #define offsetof(S, x) (int)(&((S*)0)->x)
            8 #define nelem(x) (sizeof(x)/sizeof((x)[0]))
            9 
           10 typedef unsigned int uint;
           11 
           12 enum
           13 {
           14         O_AAA = 1,
           15         O_AAD,
           16         O_AAM,
           17         O_AAS,
           18         O_ADC,
           19         O_ADD,
           20         O_ADDRSIZE,
           21         O_AND,
           22         O_ARPL,
           23         O_BOUND,
           24         O_BSF,
           25         O_BSR,
           26         O_BT,
           27         O_BTC,
           28         O_BTR,
           29         O_BTS,
           30         O_CBW,
           31         O_CLC,
           32         O_CLD,
           33         O_CLI,
           34         O_CLTS,
           35         O_CMC,
           36         O_CMP,
           37         O_CMPS,
           38         O_CMPXCHG,
           39         O_CPUID,
           40         O_CWD,
           41         O_DAA,
           42         O_DAS,
           43         O_DATASIZE,
           44         O_DEC,
           45         O_DIV,
           46         O_ENTER,
           47         O_HALT,
           48         O_IDIV,
           49         O_IMUL,
           50         O_IMUL2,
           51         O_IMUL3,
           52         O_IN,
           53         O_INC,
           54         O_INS,
           55         O_INT,
           56         O_IRET,
           57         O_JA,
           58         O_JC,
           59         O_JCXZ,
           60         O_JG,
           61         O_JGE,
           62         O_JL,
           63         O_JLE,
           64         O_JMP,
           65         O_JMPF,
           66         O_JNA,
           67         O_JNC,
           68         O_JNO,
           69         O_JNP,
           70         O_JNS,
           71         O_JNZ,
           72         O_JO,
           73         O_JP,
           74         O_JS,
           75         O_JZ,
           76         O_LAHF,
           77         O_LAR,
           78         O_LDS,
           79         O_LEA,
           80         O_LEAVE,
           81         O_LES,
           82         O_LFS,
           83         O_LGDT,
           84         O_LGS,
           85         O_LIDT,
           86         O_LLDT,
           87         O_LMSW,
           88         O_LOCK,
           89         O_LODS,
           90         O_LOOP,
           91         O_LOOPNZ,
           92         O_LOOPZ,
           93         O_LSL,
           94         O_LSS,
           95         O_LTR,
           96         O_MODRM,
           97         O_MOV,
           98         O_MOVS,
           99         O_MOVSXB,
          100         O_MOVSXW,
          101         O_MOVZB,
          102         O_MOVZW,
          103         O_MUL,
          104         O_NEG,
          105         O_NEXTB,
          106         O_NOP,
          107         O_NOT,
          108         O_OR,
          109         O_OUT,
          110         O_OUTS,
          111         O_POP,
          112         O_POPA,
          113         O_POPF,
          114         O_PUSH,
          115         O_PUSHA,
          116         O_PUSHF,
          117         O_RCL,
          118         O_RCR,
          119         O_REP,
          120         O_REPNE,
          121         O_RET,
          122         O_RETF,
          123         O_ROL,
          124         O_ROR,
          125         O_SAHF,
          126         O_SAR,
          127         O_SBB,
          128         O_SCAS,
          129         O_SEGMENT,
          130         O_SETA,
          131         O_SETC,
          132         O_SETG,
          133         O_SETGE,
          134         O_SETL,
          135         O_SETLE,
          136         O_SETNA,
          137         O_SETNC,
          138         O_SETNO,
          139         O_SETNP,
          140         O_SETNS,
          141         O_SETNZ,
          142         O_SETO,
          143         O_SETP,
          144         O_SETS,
          145         O_SETZ,
          146         O_SGDT,
          147         O_SHL,
          148         O_SHLD,
          149         O_SHR,
          150         O_SHRD,
          151         O_SIDT,
          152         O_SLDT,
          153         O_SMSW,
          154         O_STC,
          155         O_STD,
          156         O_STI,
          157         O_STOS,
          158         O_STR,
          159         O_SUB,
          160         O_TEST,
          161         O_VERR,
          162         O_VERW,
          163         O_WAIT,
          164         O_XCHG,
          165         O_XOR,
          166         O_CALL,
          167         O_CALLF,
          168         O_XLAT,
          169         
          170         MAXO
          171 };
          172 
          173 enum
          174 {
          175         F_8 = 1,
          176         F_16,
          177         F_32,
          178         F_1632,
          179         F_0A,
          180         F_X,
          181 };
          182 
          183 enum
          184 {
          185         A_0 = 5,
          186         A_1 = 1,
          187         A_3 = 3,
          188         A_4 = 4,
          189 
          190         A_AL = 8,
          191         A_CL,
          192         A_DL,
          193         A_BL,
          194         A_AH,
          195         A_CH,
          196         A_DH,
          197         A_BH,
          198         
          199         A_AX,
          200         A_CX,
          201         A_DX,
          202         A_BX,
          203         A_SP,
          204         A_BP,
          205         A_SI,
          206         A_DI,
          207         
          208         A_EAX,
          209         A_ECX,
          210         A_EDX,
          211         A_EBX,
          212         A_ESP,
          213         A_EBP,
          214         A_ESI,
          215         A_EDI,
          216         
          217         A_ES,
          218         A_CS,
          219         A_SS,
          220         A_DS,
          221         A_FS,
          222         A_GS,
          223 
          224         A_IMM8,
          225         A_IMM16,
          226         A_IMM32,
          227         
          228         A_CR,
          229         A_DR,
          230         A_TR,
          231         A_SR,
          232 
          233         A_M,
          234 
          235         A_MOFF8,
          236         A_MOFF16,
          237         A_MOFF32,
          238         
          239         A_R8,
          240         A_R16,
          241         A_R32,
          242         
          243         A_RM8,
          244         A_RM16,
          245         A_RM32,
          246         A_RM32R,
          247         
          248         A_REL8,
          249         A_REL16,
          250         A_REL32,
          251         A_IMM1616,
          252         A_IMM1632,
          253         
          254         MAXA
          255 };
          256 
          257 enum
          258 {
          259         D_LOCK = 1<<0,
          260         D_REP = 1<<1,
          261         D_REPN = 1<<2,
          262         D_ES = 1<<3,
          263         D_CS = 1<<4,
          264         D_SS = 1<<5,
          265         D_DS = 1<<6,
          266         D_FS = 1<<7,
          267         D_GS = 1<<8,
          268         D_ADDR32 = 1<<9,
          269         D_DATA8 = 1<<10,
          270         D_DATA16 = 1<<11,
          271         D_DATA32 = 1<<12,
          272         D_STACK32 = 1<<13,
          273 };
          274 
          275 enum
          276 {
          277         DA_NONE,
          278         DA_REG8,
          279         DA_REG16,
          280         DA_REG32,
          281         DA_IMM,
          282         DA_MEM,
          283         DA_SEGMEM,
          284         DA_IND16,
          285         DA_IND32,
          286         DA_SIB,
          287         DA_SIBX,
          288         DA_SEG16,
          289         DA_REL,
          290 };
          291 
          292 // String tables
          293 
          294 static char *opnames[MAXO][3] = 
          295 {
          296         { "xxx" },
          297 [O_AAA]        { "aaa" },
          298 [O_AAD]        { "aad" },
          299 [O_AAM]        { "aam" },
          300 [O_AAS]        { "aas" },
          301 [O_ADC]        { "adcb", "adcw", "adcl" },
          302 [O_ADD]        { "addb", "addw", "addl" },
          303 [O_ADDRSIZE]        { "addrsize" },
          304 [O_AND]        { "andb", "andw", "andl" },
          305 [O_ARPL]        { "arpl" },
          306 [O_BOUND]        { 0, "boundw", "boundl" },
          307 [O_BSF]        { 0, "bsfw", "bsfl" },
          308 [O_BSR]        { 0, "bsrw", "bsrl" },
          309 [O_BT]        { 0, "btw", "btl" },
          310 [O_BTC]        { 0, "btcw", "btcl" },
          311 [O_BTR]        { 0, "btrw", "btrl" },
          312 [O_BTS]        { 0, "btsw", "btsl" },
          313 [O_CALL]        { 0, "call", "call" },
          314 [O_CBW]        { 0, "cbw", "cwde" },
          315 [O_CLC]        { "clc" },
          316 [O_CLD]        { "cld" },
          317 [O_CLI]        { "cli" },
          318 [O_CLTS]        { "clts" },
          319 [O_CMC]        { "cmc" },
          320 [O_CMP]        { "cmpb", "cmpw", "cmpl" },
          321 [O_CMPS]        { "cmpsb", "cmpsw", "cmpsl" },
          322 [O_CMPXCHG] { "cmpxchgb", "cmpxchgw", "cmpxchgl" },
          323 [O_CPUID] { "cpuid" },
          324 [O_CWD]        { 0, "cwd", "cdq" },
          325 [O_DAA]        { "daa" },
          326 [O_DAS]        { "das" },
          327 [O_DATASIZE]        { "datasize" },
          328 [O_DEC]        { "decb", "decw", "decl" },
          329 [O_DIV]        { "divb", "divw", "divl" },
          330 [O_ENTER]        { "enter" },
          331 [O_HALT]        { "halt" },
          332 [O_IDIV]        { "idivb", "idivw", "idivl" },
          333 [O_IMUL]        { "imulb", "imulw", "imull" },
          334 [O_IMUL2]        { "imulb", "imulw", "imull" },
          335 [O_IMUL3]        { "imulb", "imulw", "imull" },
          336 [O_IN]        { "inb", "inw", "inl" },
          337 [O_INC]        { "incb", "incw", "incl" },
          338 [O_INS]        { "insb", "insw", "insl" },
          339 [O_INT]        { "int" },
          340 [O_IRET]        { 0, "iret", "iretd" },
          341 [O_JA]        { "ja", "ja", "ja" },
          342 [O_JC]        { "jc", "jc", "jc" },
          343 [O_JCXZ]        { "jcxz", "jcxz", "jcxz" },
          344 [O_JG]        { "jg", "jg", "jg" },
          345 [O_JGE]        { "jge", "jge", "jge" },
          346 [O_JL]        { "jl", "jl", "jl" },
          347 [O_JLE]        { "jle", "jle", "jle" },
          348 [O_JMP]        { "jmp", "jmp", "jmp" },
          349 [O_JMPF]        { "ljmp", "ljmp", "ljmp" },
          350 [O_JNA]        { "jna", "jna", "jna" },
          351 [O_JNC]        { "jnc", "jnc", "jnc" },
          352 [O_JNO]        { "jno", "jno", "jno" },
          353 [O_JNP]        { "jnp", "jnp", "jnp" },
          354 [O_JNS]        { "jns", "jns", "jns" },
          355 [O_JNZ]        { "jnz", "jnz", "jnz" },
          356 [O_JO]        { "jo", "jo", "jo" },
          357 [O_JP]        { "jp", "jp", "jp" },
          358 [O_JS]        { "js", "js", "js" },
          359 [O_JZ]        { "jz", "jz", "jz" },
          360 [O_LAHF]        { "lahf" },
          361 [O_LAR]        { 0, "larw", "larl" },
          362 [O_LEA]        { 0, "leaw", "leal" },
          363 [O_LEAVE]        { 0, "leavew", "leavel" },
          364 [O_LGDT]        { "lgdt", },
          365 [O_LDS]        { 0, "ldsw", "ldsl" },
          366 [O_LES]        { 0, "lesw", "lesl" },
          367 [O_LFS]        { 0, "lfsw", "lfsl" },
          368 [O_LGS]        { 0, "lgsw", "lgsl" },
          369 [O_LSS]        { 0, "lssw", "lssl" },
          370 [O_LIDT]        { "lidt" },
          371 [O_LLDT]        { "lldt" },
          372 [O_LMSW]        { 0, "lmsw" },
          373 [O_LOCK]        { "*LOCK*" },
          374 [O_LODS]        { "lodsb", "lodsw", "lodsl" },
          375 [O_LOOP]        { "loop" },
          376 [O_LOOPNZ]        { "loopnz" },
          377 [O_LOOPZ]        { "loopz" },
          378 [O_LSL]        { 0, "lslw", "lsll" },
          379 [O_LTR]        { 0, "ltr", 0 },
          380 [O_MODRM]        { "*MODRM*" },
          381 [O_MOV]        { "movb", "movw", "movl" },
          382 [O_MOVS]        { "movsb", "movsw", "movsl" },
          383 [O_MOVSXB]        { 0, "movsxb", "movsxb" },
          384 [O_MOVSXW]        { 0, 0, "movsxw" },
          385 [O_MOVZB]        { 0, "movzb", "movzb" },
          386 [O_MOVZW]        { 0, 0, "movzw" },
          387 [O_MUL]        { "mulb", "mulw", "mull" },
          388 [O_NEG]        { "negb", "negw", "negl" },
          389 [O_NEXTB]        { "*NEXTB*" },
          390 [O_NOP]        { "nop" },
          391 [O_NOT]        { "notb", "notw", "notl" },
          392 [O_OR]        { "orb", "orw", "orl" },
          393 [O_OUT]        { "outb", "outw", "outl" },
          394 [O_OUTS]        { "outsb", "outsw", "outsl" },
          395 [O_POP]        { 0, "popw", "popl" },
          396 [O_POPA]        { 0, "popaw", "popal" },
          397 [O_POPF]        { 0, "popfw", "popfl" },
          398 [O_PUSH]        { 0, "pushw", "pushl" },
          399 [O_PUSHA]        { 0, "pushaw", "pushal" },
          400 [O_PUSHF]        { 0, "pushfw", "pushfl" },
          401 [O_RCL]        { "rclb", "rclw", "rcll" },
          402 [O_RCR]        { "rcrb", "rcrw", "rcrl" },
          403 [O_REP]        { "rep" },
          404 [O_REPNE]        { "repne" },
          405 [O_RET]        { "ret", "ret", "ret" },
          406 [O_RETF]        { "retf", "retf", "retf" },
          407 [O_ROL]        { "rolb", "rolw", "roll" },
          408 [O_ROR]        { "rorb", "rorw", "rorl" },
          409 [O_SAHF]        { "sahf" },
          410 [O_SAR]        { "sarb", "sarw", "sarl" },
          411 [O_SBB]        { "sbbb", "sbbw", "sbbl" },
          412 [O_SCAS]        { "scasb", "scasw", "scasl" },
          413 [O_SEGMENT]        { "*SEGMENT*" },
          414 [O_SETA]        { "seta" },
          415 [O_SETC]        { "setc" },
          416 [O_SETG]        { "setg" },
          417 [O_SETGE]        { "setge" },
          418 [O_SETL]        { "setl" },
          419 [O_SETLE]        { "setle" },
          420 [O_SETNA]        { "setna" },
          421 [O_SETNC]        { "setnc" },
          422 [O_SETNO]        { "setno" },
          423 [O_SETNP]        { "setnp" },
          424 [O_SETNS]        { "setns" },
          425 [O_SETNZ]        { "setnz" },
          426 [O_SETO]        { "seto" },
          427 [O_SETP]        { "setp" },
          428 [O_SETS]        { "sets" },
          429 [O_SETZ]        { "setz" },
          430 [O_SGDT]        { "sgdt" },
          431 [O_SHL]        { "shlb", "shlw", "shll" },
          432 [O_SHLD]        { 0, "shldw", "shldl" },
          433 [O_SHR]        { "shrb", "shrw", "shrl" },
          434 [O_SHRD]        { 0, "shrdw", "shrdl" },
          435 [O_SIDT]        { "sidt" },
          436 [O_SLDT]        { "sldt" },
          437 [O_SMSW]        { 0, "smsw" },
          438 [O_STC]        { "stc" },
          439 [O_STD]        { "std" },
          440 [O_STI]        { "sti" },
          441 [O_STOS]        { "stosb", "stosw", "stosl" },
          442 [O_STR]        { 0, "str" },
          443 [O_SUB]        { "subb", "subw", "subl" },
          444 [O_TEST]        { "testb", "testw", "testl" },
          445 [O_VERR]        { 0, "verr" },
          446 [O_VERW]        { 0, "verw" },
          447 [O_WAIT]        { "wait" },
          448 [O_XCHG]        { "xchgb", "xchgw", "xchgl" },
          449 [O_XOR]        { "xorb", "xorw", "xorl" },
          450 [O_XLAT] { "xlat" },
          451 };
          452 
          453 static struct {
          454         int f;
          455         char *s;
          456 } prefixes[] = {
          457         D_LOCK, "lock",
          458         D_REP, "rep",
          459         D_REPN, "repn",
          460         D_CS, "cs:",
          461         D_DS, "ds:",
          462         D_ES, "es:",
          463         D_FS, "fs:",
          464         D_GS, "gs:",
          465         D_SS, "ss:",
          466 };
          467 
          468 static char *reg8[] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
          469 static char *reg16[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
          470 static char *reg32[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
          471                          "eip", "eflags",
          472                          "cr0", "cr2", "cr3",
          473                          "dr0", "dr1", "dr2", "dr3", "dr6", "dr7",
          474                          "tr6", "tr7" };
          475 static char *seg[] = { "cs", "ds", "es", "fs", "gs", "ss" };
          476 
          477 // Register Ids
          478 
          479 #define EAX 0
          480 #define ECX 4
          481 #define EDX 8
          482 #define EBX 12
          483 #define ESP 16
          484 #define EBP 20
          485 #define ESI 24
          486 #define EDI 28
          487 #define EIP 32
          488 #define EFLAGS 36
          489 #define CR0 40
          490 #define CR2 44
          491 #define CR3 48
          492 #define DR0 52
          493 #define DR1 56
          494 #define DR2 60
          495 #define DR3 64
          496 #define DR6 68
          497 #define DR7 72
          498 #define TR6 76
          499 #define TR7 80
          500 
          501 #define CS 100
          502 #define DS 101
          503 #define ES 102
          504 #define FS 103
          505 #define GS 104
          506 #define SS 105
          507 // Instruction decoding tables.
          508 
          509 static xinst inst0F00[] =
          510 {
          511 /*/0*/        { O_SLDT,        F_16,        A_RM16,                },
          512         { O_STR,        F_16,        A_RM16,                },
          513         { O_LLDT,        F_16,        A_RM16,                },
          514         { O_LTR,        F_16,        A_RM16,                },
          515         { O_VERR,        F_16,        A_RM16,                },
          516         { O_VERW,        F_16,        A_RM16,                },
          517         { -1 },
          518         { -1 },
          519 };
          520 
          521 static xinst inst0F01[] = 
          522 {
          523         { O_SGDT,        F_X,        A_M,                },
          524         { O_SIDT,        F_X,        A_M,                },
          525         { O_LGDT,        F_X,        A_M,                },
          526         { O_LIDT,        F_X,        A_M,                },
          527         { O_SMSW,        F_16,        A_RM16,                },
          528         { -1 },
          529         { O_LMSW,        F_16,        A_RM16,                },
          530         { -1 },
          531 };
          532 
          533 static xinst inst0FBA[] =
          534 {
          535         { -1 },
          536         { -1 },
          537         { -1 },
          538         { -1 },
          539         { O_BT,                F_1632,        A_RM16,        A_IMM8 },
          540         { O_BTS,        F_1632,        A_RM16,        A_IMM8 },
          541         { O_BTR,        F_1632,        A_RM16,        A_IMM8 },
          542         { O_BTC,        F_1632,        A_RM16,        A_IMM8 },
          543 };
          544 
          545 static xinst inst0F[] =
          546 {
          547 /*00*/        { O_MODRM,        0,        0,        0,        0,        inst0F00 },
          548         { O_MODRM,        0,        0,        0,        0,        inst0F01 },
          549         { O_LAR,        F_1632,        A_R16,        A_RM16,        },
          550         { O_LSL,        F_1632, A_R16,        A_RM16,        },
          551         { -1 },
          552         { -1 },
          553         { O_CLTS,        F_X,        0,        0,        },
          554         { -1 },
          555 /*08*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          556 /*10*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          557 /*18*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          558 /*20*/        { O_MOV,        F_32,        A_RM32R,        A_CR        },
          559         { O_MOV,        F_32,        A_RM32R,        A_DR        },
          560         { O_MOV,        F_32,        A_CR,        A_RM32R        },
          561         { O_MOV,        F_32,        A_DR,        A_RM32R        },
          562         { O_MOV,        F_32,        A_RM32R,        A_TR        },
          563         { -1 },
          564         { O_MOV,        F_32,        A_TR,        A_RM32R        },
          565         { -1 },
          566 /*28*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          567 /*30*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          568 /*38*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          569 /*40*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          570 /*48*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          571 /*50*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          572 /*58*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          573 /*60*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          574 /*68*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          575 /*70*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          576 /*78*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          577 /*80*/        { O_JO,                F_1632,        A_REL16,        },
          578         { O_JNO,        F_1632,        A_REL16,        },
          579         { O_JC,                F_1632,        A_REL16,        },
          580         { O_JNC,        F_1632,        A_REL16,        },
          581         { O_JZ,                F_1632,        A_REL16,        },
          582         { O_JNZ,        F_1632,        A_REL16,        },
          583         { O_JNA,        F_1632,        A_REL16,        },
          584         { O_JA,                F_1632,        A_REL16,        },
          585 /*88*/        { O_JS,                F_1632,        A_REL16,        },
          586         { O_JNS,        F_1632,        A_REL16,        },
          587         { O_JP,                F_1632,        A_REL16,        },
          588         { O_JNP,        F_1632,        A_REL16,        },
          589         { O_JL,                F_1632,        A_REL16,        },
          590         { O_JGE,        F_1632,        A_REL16,        },
          591         { O_JLE,        F_1632,        A_REL16,        },
          592         { O_JG,                F_1632,        A_REL16,        },
          593 /*90*/        { O_SETO,        F_8,        A_RM8,        },
          594         { O_SETNO,        F_8,        A_RM8,        },
          595         { O_SETC,        F_8,        A_RM8,        },
          596         { O_SETNC,        F_8,        A_RM8,        },
          597         { O_SETZ,        F_8,        A_RM8,        },
          598         { O_SETNZ,        F_8,        A_RM8,        },
          599         { O_SETNA,        F_8,        A_RM8,        },
          600         { O_SETA,        F_8,        A_RM8,        },
          601 /*98*/        { O_SETS,        F_8,        A_RM8,        },
          602         { O_SETNS,        F_8,        A_RM8,        },
          603         { O_SETP,        F_8,        A_RM8,        },
          604         { O_SETNP,        F_8,        A_RM8,        },
          605         { O_SETL,        F_8,        A_RM8,        },
          606         { O_SETGE,        F_8,        A_RM8,        },
          607         { O_SETLE,        F_8,        A_RM8,        },
          608         { O_SETG,        F_8,        A_RM8,        },
          609 /*A0*/        { O_PUSH,        0,        A_FS,        },
          610         { O_POP,        0,        A_FS,        },
          611         { O_CPUID, F_X, 0, 0 },
          612         { O_BT,                F_1632,        A_RM16,        A_R16 },
          613         { O_SHLD,        F_1632,        A_RM16,        A_R16,        A_IMM8 },
          614         { O_SHLD,        F_1632,        A_RM16,        A_R16,        A_CL },
          615         { -1 },
          616         { -1 },
          617 /*A8*/        { O_PUSH,        0,        A_GS,        },
          618         { O_POP,        0,        A_GS,        },
          619         { -1 },
          620         { O_BTS,        F_1632,        A_RM16,        A_R16 },
          621         { O_SHRD,        F_1632,        A_RM16,        A_R16,        A_IMM8 },
          622         { O_SHRD,        F_1632,        A_RM16,        A_R16,        A_CL },
          623         { -1 },
          624         { O_IMUL2,        F_1632,        A_R16,        A_RM16 },
          625 /*B0*/        { O_CMPXCHG, F_8, A_AL, A_RM8, A_R8 },
          626         { O_CMPXCHG, F_1632, A_AX, A_RM16, A_R16 },
          627         { O_LSS,        F_1632,        A_R16,        A_M },
          628         { O_BTR,        F_1632,        A_RM16,        A_R16 },
          629         { O_LFS,        F_1632,        A_R16,        A_M },
          630         { O_LGS,        F_1632,        A_R16,        A_M },
          631         { O_MOVZB,        F_1632,        A_R16,        A_RM8 },
          632         { O_MOVZW,        F_32,        A_R32,        A_RM16 },
          633 /*B8*/        { -1 },
          634         { -1 },
          635         { O_MODRM,        0,        0,        0,        0,        inst0FBA },
          636         { O_BTC,        F_1632,        A_RM16,        A_R16 },
          637         { O_BSF,        F_1632,        A_R16,        A_RM16 },
          638         { O_BSR,        F_1632,        A_R16,        A_RM16 },
          639         { O_MOVSXB,        F_1632,        A_R16,        A_RM8 },
          640         { O_MOVSXW,        F_32,        A_R32,        A_RM16 },
          641 /*C0*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          642 /*C8*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          643 /*D0*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          644 /*D8*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          645 /*E0*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          646 /*E8*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          647 /*F0*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          648 /*F8*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
          649 };
          650 
          651 static xinst inst80[] =
          652 {
          653         { O_ADD,        F_8,        A_RM8,        A_IMM8 },
          654         { O_OR,                F_8,        A_RM8,        A_IMM8 },
          655         { O_ADC,        F_8,        A_RM8,        A_IMM8 },
          656         { O_SBB,        F_8,        A_RM8,        A_IMM8 },
          657         { O_AND,        F_8,        A_RM8,        A_IMM8 },
          658         { O_SUB,        F_8,        A_RM8,        A_IMM8 },
          659         { O_XOR,        F_8,        A_RM8,        A_IMM8 },
          660         { O_CMP,        F_8,        A_RM8,        A_IMM8 },
          661 };
          662 
          663 static xinst inst81[] =
          664 {
          665         { O_ADD,        F_1632,        A_RM16,        A_IMM16 },
          666         { O_OR,                F_1632,        A_RM16,        A_IMM16 },
          667         { O_ADC,        F_1632,        A_RM16,        A_IMM16 },
          668         { O_SBB,        F_1632,        A_RM16,        A_IMM16 },
          669         { O_AND,        F_1632,        A_RM16,        A_IMM16 },
          670         { O_SUB,        F_1632,        A_RM16,        A_IMM16 },
          671         { O_XOR,        F_1632,        A_RM16,        A_IMM16 },
          672         { O_CMP,        F_1632,        A_RM16,        A_IMM16 },
          673 };
          674 
          675 static xinst inst83[] =
          676 {
          677         { O_ADD,        F_1632,        A_RM16,        A_IMM8 },
          678         { O_OR,                F_1632,        A_RM16,        A_IMM8 },
          679         { O_ADC,        F_1632,        A_RM16,        A_IMM8 },
          680         { O_SBB,        F_1632,        A_RM16,        A_IMM8 },
          681         { O_AND,        F_1632,        A_RM16,        A_IMM8 },
          682         { O_SUB,        F_1632,        A_RM16,        A_IMM8 },
          683         { O_XOR,        F_1632,        A_RM16,        A_IMM8 },
          684         { O_CMP,        F_1632,        A_RM16,        A_IMM8 },
          685 };
          686 
          687 static xinst inst8F[] = 
          688 {
          689         { O_POP,        F_1632,        A_M,        0,        },
          690         { -1 },
          691         { -1 },
          692         { -1 },
          693         { -1 },
          694         { -1 },
          695         { -1 },
          696         { -1 },
          697 };
          698 
          699 static xinst instC0[] =
          700 {
          701         { O_ROL,        F_8,        A_RM8,        A_IMM8,        },
          702         { O_ROR,        F_8,        A_RM8,        A_IMM8,        },
          703         { O_RCL,        F_8,        A_RM8,        A_IMM8,        },
          704         { O_RCR,        F_8,        A_RM8,        A_IMM8,        },
          705         { O_SHL,        F_8,        A_RM8,        A_IMM8,        },
          706         { O_SHR,        F_8,        A_RM8,        A_IMM8,        },
          707         { -1, },
          708         { O_SAR,        F_8,        A_RM8,        A_IMM8,        },
          709 };
          710 
          711 static xinst instC1[] =
          712 {
          713         { O_ROL,        F_1632,        A_RM16,        A_IMM8,        },
          714         { O_ROR,        F_1632,        A_RM16,        A_IMM8,        },
          715         { O_RCL,        F_1632,        A_RM16,        A_IMM8,        },
          716         { O_RCR,        F_1632,        A_RM16,        A_IMM8,        },
          717         { O_SHL,        F_1632,        A_RM16,        A_IMM8,        },
          718         { O_SHR,        F_1632,        A_RM16,        A_IMM8,        },
          719         { -1, },
          720         { O_SAR,        F_1632,        A_RM16,        A_IMM8,        },
          721 };
          722 
          723 static xinst instD0[] =
          724 {
          725         { O_ROL,        F_8,        A_RM8,        A_1,        },
          726         { O_ROR,        F_8,        A_RM8,        A_1,        },
          727         { O_RCL,        F_8,        A_RM8,        A_1,        },
          728         { O_RCR,        F_8,        A_RM8,        A_1,        },
          729         { O_SHL,        F_8,        A_RM8,        A_1,        },
          730         { O_SHR,        F_8,        A_RM8,        A_1,        },
          731         { -1, },
          732         { O_SAR,        F_8,        A_RM8,        A_1,        },
          733 };
          734 
          735 static xinst instD1[] =
          736 {
          737         { O_ROL,        F_1632,        A_RM16,        A_1,        },
          738         { O_ROR,        F_1632,        A_RM16,        A_1,        },
          739         { O_RCL,        F_1632,        A_RM16,        A_1,        },
          740         { O_RCR,        F_1632,        A_RM16,        A_1,        },
          741         { O_SHL,        F_1632,        A_RM16,        A_1,        },
          742         { O_SHR,        F_1632,        A_RM16,        A_1,        },
          743         { -1, },
          744         { O_SAR,        F_1632,        A_RM16,        A_1,        },
          745 };
          746 
          747 static xinst instD2[] =
          748 {
          749         { O_ROL,        F_8,        A_RM8,        A_CL,        },
          750         { O_ROR,        F_8,        A_RM8,        A_CL,        },
          751         { O_RCL,        F_8,        A_RM8,        A_CL,        },
          752         { O_RCR,        F_8,        A_RM8,        A_CL,        },
          753         { O_SHL,        F_8,        A_RM8,        A_CL,        },
          754         { O_SHR,        F_8,        A_RM8,        A_CL,        },
          755         { -1, },
          756         { O_SAR,        F_8,        A_RM8,        A_CL,        },
          757 };
          758 
          759 static xinst instD3[] =
          760 {
          761         { O_ROL,        F_1632,        A_RM16,        A_CL,        },
          762         { O_ROR,        F_1632,        A_RM16,        A_CL,        },
          763         { O_RCL,        F_1632,        A_RM16,        A_CL,        },
          764         { O_RCR,        F_1632,        A_RM16,        A_CL,        },
          765         { O_SHL,        F_1632,        A_RM16,        A_CL,        },
          766         { O_SHR,        F_1632,        A_RM16,        A_CL,        },
          767         { -1, },
          768         { O_SAR,        F_1632,        A_RM16,        A_CL,        },
          769 };
          770 
          771 static xinst instF6[] =
          772 {
          773         { O_TEST,        F_8,        A_RM8,        A_IMM8,        },
          774         { -1 },
          775         { O_NOT,        F_8,        A_RM8,        0,        },
          776         { O_NEG,        F_8,        A_RM8,        0,        },
          777         { O_MUL,        F_8,        A_AL,        A_RM8,        },
          778         { O_IMUL,        F_8,        A_RM8,        },
          779         { O_DIV,        F_8,        A_AX,        A_RM8,        },
          780         { O_IDIV,        F_8,        A_AX,        A_RM8,        },
          781 };
          782 static xinst instF7[] =
          783 {
          784         { O_TEST,        F_1632,        A_RM16,        A_IMM16,        },
          785         { -1 },
          786         { O_NOT,        F_1632,        A_RM16,        0,        },
          787         { O_NEG,        F_1632,        A_RM16,        0,        },
          788         { O_MUL,        F_1632,        A_AX,        A_RM16,        },
          789         { O_IMUL,        F_1632,        A_RM16,        },
          790         { O_DIV,        F_1632,        A_RM16,        },
          791         { O_IDIV,        F_1632,        A_RM16,        },
          792 };
          793 
          794 static xinst instFE[] =
          795 {
          796         { O_INC,        F_8,        A_RM8,        0,        },
          797         { O_DEC,        F_8,        A_RM8,        0,        },
          798         { -1 },
          799         { -1 },
          800         { -1 },
          801         { -1 },
          802         { -1 },
          803         { -1 },
          804         { -1 },
          805         { -1 },
          806 };
          807 
          808 static xinst instFF[] =
          809 {
          810         { O_INC,        F_1632,        A_RM16,        0,        },
          811         { O_DEC,        F_1632,        A_RM16,        0,        },
          812         { O_CALL,        F_1632,        A_RM16,        0,        },
          813         { O_CALLF,        F_1632,        A_M,        0,        },        // INDIRECT
          814         { O_JMP,        F_1632,        A_RM16,        0,        },
          815         { O_JMPF,        F_1632,        A_M,        0,        }, // INDIRECT
          816         { O_PUSH,        F_1632,        A_M,        0,        },
          817         { -1 },
          818 };
          819 
          820 xinst inst[] = 
          821 {
          822 /*00*/        { O_ADD,        F_8,        A_RM8,        A_R8        },
          823         { O_ADD,        F_1632,        A_RM16,        A_R16        },
          824         { O_ADD,        F_8,        A_R8,        A_RM8        },
          825         { O_ADD,        F_1632,        A_R16,        A_RM16        },
          826         { O_ADD,        F_8,        A_AL,        A_IMM8        },
          827         { O_ADD,        F_1632,        A_AX,        A_IMM16 },
          828         { O_PUSH,        0,        A_ES,                },
          829         { O_POP,        0,        A_ES,                },
          830 /*08*/        { O_OR,                F_8,        A_RM8,        A_R8        },
          831         { O_OR,                F_1632,        A_RM16,        A_R16        },
          832         { O_OR,                F_8,        A_R8,        A_RM8        },
          833         { O_OR,                F_1632,        A_R16,        A_RM16        },
          834         { O_OR,                F_8,        A_AL,        A_IMM8        },
          835         { O_OR,                F_1632,        A_AX,        A_IMM16 },
          836         { O_PUSH,        0,        A_CS,                },
          837         { O_NEXTB,        0,        0,        0,        0,        inst0F },
          838 /*10*/        { O_ADC,        F_8,        A_RM8,        A_R8        },
          839         { O_ADC,        F_1632,        A_RM16,        A_R16        },
          840         { O_ADC,        F_8,        A_R8,        A_RM8        },
          841         { O_ADC,        F_1632,        A_R16,        A_RM16        },
          842         { O_ADC,        F_8,        A_AL,        A_IMM8        },
          843         { O_ADC,        F_1632,        A_AX,        A_IMM16 },
          844         { O_PUSH,        0,        A_SS,                },
          845         { O_POP,        0,        A_SS,                },
          846 /*18*/        { O_SBB,        F_8,        A_RM8,        A_R8        },
          847         { O_SBB,        F_1632,        A_RM16,        A_R16        },
          848         { O_SBB,        F_8,        A_R8,        A_RM8        },
          849         { O_SBB,        F_1632,        A_R16,        A_RM16        },
          850         { O_SBB,        F_8,        A_AL,        A_IMM8        },
          851         { O_SBB,        F_1632,        A_AX,        A_IMM16 },
          852         { O_PUSH,        F_1632,        A_DS,        0,        },
          853         { O_POP,        F_1632,        A_DS,        0,        },
          854 /*20*/        { O_AND,        F_8,        A_RM8,        A_R8        },
          855         { O_AND,        F_1632,        A_RM16,        A_R16        },
          856         { O_AND,        F_8,        A_R8,        A_RM8        },
          857         { O_AND,        F_1632,        A_R16,        A_RM16        },
          858         { O_AND,        F_8,        A_AL,        A_IMM8        },
          859         { O_AND,        F_1632,        A_AX,        A_IMM16 },
          860         { O_SEGMENT,        0,        A_ES,        0,        },
          861         { O_DAA,        F_X,        0,        0,        },
          862 /*28*/        { O_SUB,        F_8,        A_RM8,        A_R8        },
          863         { O_SUB,        F_1632,        A_RM16,        A_R16        },
          864         { O_SUB,        F_8,        A_R8,        A_RM8        },
          865         { O_SUB,        F_1632,        A_R16,        A_RM16        },
          866         { O_SUB,        F_8,        A_AL,        A_IMM8        },
          867         { O_SUB,        F_1632,        A_AX,        A_IMM16 },
          868         { O_SEGMENT,        0,        A_CS,        0,        },
          869         { O_DAS,        F_X,        0,        0,        },
          870 /*30*/        { O_XOR,        F_8,        A_RM8,        A_R8        },
          871         { O_XOR,        F_1632,        A_RM16,        A_R16        },
          872         { O_XOR,        F_8,        A_R8,        A_RM8        },
          873         { O_XOR,        F_1632,        A_R16,        A_RM16        },
          874         { O_XOR,        F_8,        A_AL,        A_IMM8        },
          875         { O_XOR,        F_1632,        A_AX,        A_IMM16 },
          876         { O_SEGMENT,        0,        A_SS,        0,        },
          877         { O_AAA,        F_X,        0,        0,        },
          878 /*38*/        { O_CMP,        F_8,        A_RM8,        A_R8        },
          879         { O_CMP,        F_1632,        A_RM16,        A_R16        },
          880         { O_CMP,        F_8,        A_R8,        A_RM8        },
          881         { O_CMP,        F_1632,        A_R16,        A_RM16        },
          882         { O_CMP,        F_8,        A_AL,        A_IMM8        },
          883         { O_CMP,        F_1632,        A_AX,        A_IMM16 },
          884         { O_SEGMENT,        0,        A_DS,        0,        },
          885         { O_AAS,        F_X,        0,        0,        },
          886 /*40*/        { O_INC,        F_1632,        A_AX,        0,        },        // +r
          887         { O_INC,        F_1632,        A_CX,        0,        },
          888         { O_INC,        F_1632,        A_DX,        0,        },
          889         { O_INC,        F_1632,        A_BX,        0,        },
          890         { O_INC,        F_1632,        A_SP,        0,        },
          891         { O_INC,        F_1632,        A_BP,        0,        },
          892         { O_INC,        F_1632,        A_SI,        0,        },
          893         { O_INC,        F_1632,        A_DI,        0,        },
          894 /*48*/        { O_DEC,        F_1632,        A_AX,        0,        },        // +r
          895         { O_DEC,        F_1632,        A_CX,        0,        },
          896         { O_DEC,        F_1632,        A_DX,        0,        },
          897         { O_DEC,        F_1632,        A_BX,        0,        },
          898         { O_DEC,        F_1632,        A_SP,        0,        },
          899         { O_DEC,        F_1632,        A_BP,        0,        },
          900         { O_DEC,        F_1632,        A_SI,        0,        },
          901         { O_DEC,        F_1632,        A_DI,        0,        },
          902 /*50*/        { O_PUSH,        F_1632,        A_AX,        0,        },        // +r
          903         { O_PUSH,        F_1632,        A_CX,        0,        },
          904         { O_PUSH,        F_1632,        A_DX,        0,        },
          905         { O_PUSH,        F_1632,        A_BX,        0,        },
          906         { O_PUSH,        F_1632,        A_SP,        0,        },
          907         { O_PUSH,        F_1632,        A_BP,        0,        },
          908         { O_PUSH,        F_1632,        A_SI,        0,        },
          909         { O_PUSH,        F_1632,        A_DI,        0,        },
          910 /*58*/        { O_POP,        F_1632,        A_AX,        0,        },        // +r
          911         { O_POP,        F_1632,        A_CX,        0,        },
          912         { O_POP,        F_1632,        A_DX,        0,        },
          913         { O_POP,        F_1632,        A_BX,        0,        },
          914         { O_POP,        F_1632,        A_SP,        0,        },
          915         { O_POP,        F_1632,        A_BP,        0,        },
          916         { O_POP,        F_1632,        A_SI,        0,        },
          917         { O_POP,        F_1632,        A_DI,        0,        },
          918 /*60*/        { O_PUSHA,        F_1632,        0,        0,        },
          919         { O_POPA,        F_1632,        0,        0,        },
          920         { O_BOUND,        F_1632,        A_R16,        A_M,        },
          921         { O_ARPL,        F_X,        A_RM16,        A_R16,        },
          922         { O_SEGMENT,        0,        A_FS,        0,        },
          923         { O_SEGMENT,        0,        A_GS,        0,        },
          924         { O_DATASIZE,        0,        0,        0,        },
          925         { O_ADDRSIZE,        0,        0,        0,        },
          926 /*68*/        { O_PUSH,        F_1632,        A_IMM16,        0,        },
          927         { O_IMUL3,        F_1632,        A_R16,        A_RM16, A_IMM16        },
          928         { O_PUSH,        F_1632,        A_IMM8,        0,        },
          929         { O_IMUL3,        F_1632,        A_R16,        A_RM16, A_IMM8        },
          930         { O_INS,        F_8,        0,        0        },
          931         { O_INS,        F_1632,        0,        0,        },
          932         { O_OUTS,        F_8,        0,        0,        },
          933         { O_OUTS,        F_1632,        0,        0,        },
          934 /*70*/        { O_JO,                F_8,        A_REL8,        },
          935         { O_JNO,        F_8,        A_REL8,        },
          936         { O_JC,                F_8,        A_REL8,        },
          937         { O_JNC,        F_8,        A_REL8,        },
          938         { O_JZ,                F_8,        A_REL8,        },
          939         { O_JNZ,        F_8,        A_REL8,        },
          940         { O_JNA,        F_8,        A_REL8,        },
          941         { O_JA,                F_8,        A_REL8,        },
          942 /*78*/        { O_JS,                F_8,        A_REL8,        },
          943         { O_JNS,        F_8,        A_REL8,        },
          944         { O_JP,                F_8,        A_REL8,        },
          945         { O_JNP,        F_8,        A_REL8,        },
          946         { O_JL,                F_8,        A_REL8,        },
          947         { O_JGE,        F_8,        A_REL8,        },
          948         { O_JLE,        F_8,        A_REL8,        },
          949         { O_JG,                F_8,        A_REL8,        },
          950 /*80*/        { O_MODRM,        0,        0,        0,        0,        inst80 },
          951         { O_MODRM,        0,        0,        0,        0,        inst81 },
          952         { -1 },
          953         { O_MODRM,        0,        0,        0,        0,        inst83 },
          954         { O_TEST,        F_8,        A_RM8,        A_R8,        },
          955         { O_TEST,        F_1632,        A_RM16,        A_R16,        },
          956         { O_XCHG,        F_8,        A_R8,        A_RM8,        },
          957         { O_XCHG,        F_1632,        A_R16,        A_RM16,        },
          958 /*88*/        { O_MOV,        F_8,        A_RM8,        A_R8,        },
          959         { O_MOV,        F_1632,        A_RM16,        A_R16,        },
          960         { O_MOV,        F_8,        A_R8,        A_RM8,        },
          961         { O_MOV,        F_1632,        A_R16,        A_RM16,        },
          962         { O_MOV,        F_16,        A_RM16,        A_SR        },
          963         { O_LEA,        F_1632,        A_R16,        A_M        },
          964         { O_MOV,        F_16,        A_SR,        A_RM16        },
          965         { O_MODRM,        0,        0,        0,        0,        inst8F },
          966 /*90*/        { O_NOP,        F_X,        0,        0,        },        // really XCHG +r
          967         { O_XCHG,        F_1632,        A_CX,        A_R16        },
          968         { O_XCHG,        F_1632,        A_DX,        A_R16        },
          969         { O_XCHG,        F_1632,        A_BX,        A_R16        },
          970         { O_XCHG,        F_1632,        A_SP,        A_R16        },
          971         { O_XCHG,        F_1632,        A_BP,        A_R16        },
          972         { O_XCHG,        F_1632,        A_SI,        A_R16        },
          973         { O_XCHG,        F_1632,        A_DI,        A_R16        },
          974 /*98*/        { O_CBW,        F_1632,        0,        0        },        // or CWDE
          975         { O_CWD,        F_1632,        0,        0,        },        // or CDQ
          976         { O_CALLF,        F_1632,        A_IMM1616,        0,        },
          977         { O_WAIT,        F_X,        0,        0,        },
          978         { O_PUSHF,        F_1632,        0,        0,        },
          979         { O_POPF,        F_1632,        0,        0,        },
          980         { O_SAHF,        F_X,        0,        0,        },
          981         { O_LAHF,        F_X,        0,        0,        },
          982 /*A0*/        { O_MOV,        F_8,        A_AL,        A_MOFF8        },
          983         { O_MOV,        F_1632,        A_AX,        A_MOFF16},
          984         { O_MOV,        F_8,        A_MOFF8,A_AL        },
          985         { O_MOV,        F_1632,        A_MOFF16,        A_AX},
          986         { O_MOVS,        F_8,        0,        0        },
          987         { O_MOVS,        F_1632,        0,        0,        },
          988         { O_CMPS,        F_8,        0,        0        },
          989         { O_CMPS,        F_1632,        0,        0,        },
          990 /*A8*/        { O_TEST,        F_8,        A_AL,        A_IMM8        },
          991         { O_TEST,        F_1632,        A_AX,        A_IMM16        },
          992         { O_STOS,        F_8,        0,        0        },
          993         { O_STOS,        F_1632,        0,        0,        },
          994         { O_LODS,        F_8,        0,        0        },
          995         { O_LODS,        F_1632,        0,        0,        },
          996         { O_SCAS,        F_8,        0,        0        },
          997         { O_SCAS,        F_1632,        0,        0,        },
          998 /*B0*/        { O_MOV,        F_8,        A_AL,        A_IMM8,        },        // +r
          999         { O_MOV,        F_8,        A_CL,        A_IMM8,        },
         1000         { O_MOV,        F_8,        A_DL,        A_IMM8,        },
         1001         { O_MOV,        F_8,        A_BL,        A_IMM8,        },
         1002         { O_MOV,        F_8,        A_AH,        A_IMM8,        },
         1003         { O_MOV,        F_8,        A_CH,        A_IMM8,        },
         1004         { O_MOV,        F_8,        A_DH,        A_IMM8,        },
         1005         { O_MOV,        F_8,        A_BH,        A_IMM8,        },
         1006 /*B8*/        { O_MOV,        F_1632,        A_AX,        A_IMM16,        },        // +r
         1007         { O_MOV,        F_1632,        A_CX,        A_IMM16,        },
         1008         { O_MOV,        F_1632,        A_DX,        A_IMM16,        },
         1009         { O_MOV,        F_1632,        A_BX,        A_IMM16,        },
         1010         { O_MOV,        F_1632,        A_SP,        A_IMM16,        },
         1011         { O_MOV,        F_1632,        A_BP,        A_IMM16,        },
         1012         { O_MOV,        F_1632,        A_SI,        A_IMM16,        },
         1013         { O_MOV,        F_1632,        A_DI,        A_IMM16,        },
         1014 /*C0*/        { O_MODRM,        0,        0,        0,        0,        instC0 },
         1015         { O_MODRM,        0,        0,        0,        0,        instC1 },
         1016         { O_RET,        0,        A_IMM16,        0,        },
         1017         { O_RET,        0,        0,        0,        },
         1018         { O_LES,        F_1632,        A_R16,        A_M },
         1019         { O_LDS,        F_1632,        A_R16,        A_M },
         1020         { O_MOV,        F_8,        A_RM8,        A_IMM8        },
         1021         { O_MOV,        F_1632,        A_RM16,        A_IMM16        },
         1022 /*C8*/        { O_ENTER,        0,        A_IMM16,        A_IMM8 },
         1023         { O_LEAVE,        F_1632,        0,        0,        },
         1024         { O_RETF,        0,        A_IMM16,        0,        },
         1025         { O_RETF,        0,        0,        0,        },
         1026         { O_INT,        F_X,        A_3,        0,        },
         1027         { O_INT,        F_X,        A_IMM8,        0,        },
         1028         { O_INT,        F_X,        A_4,        0,        },
         1029         { O_IRET,        F_1632,        0,        0,        },
         1030 /*D0*/        { O_MODRM,        0,        0,        0,        0,        instD0 },
         1031         { O_MODRM,        0,        0,        0,        0,        instD1 },
         1032         { O_MODRM,        0,        0,        0,        0,        instD2 },
         1033         { O_MODRM,        0,        0,        0,        0,        instD3 },
         1034         { O_AAM,        F_0A,        0,        0,        },
         1035         { O_AAD,        F_0A,        0,        0,        },
         1036         { -1 },
         1037         { O_XLAT,       F_8 },
         1038 /*D8*/        { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 }, { -1 },
         1039 /*E0*/        { O_LOOPNZ,        F_8,        A_REL8,        0,        },
         1040         { O_LOOPZ,        F_8,        A_REL8,        0,        },
         1041         { O_LOOP,        F_8,        A_REL8,        0,        },
         1042         { O_JCXZ,        F_8,        A_REL8,        0,        },
         1043         { O_IN,                F_8,        A_AL,        A_IMM8,        },
         1044         { O_IN,                F_1632,        A_AX,        A_IMM8,        },
         1045         { O_OUT,        F_8,        A_IMM8,        A_AL,        },
         1046         { O_OUT,        F_1632,        A_IMM8,        A_AX,        },
         1047 /*E8*/        { O_CALL,        F_1632,        A_REL16,        0,        },
         1048         { O_JMP,        F_1632,        A_REL16,        0,        },
         1049         { O_JMPF,        F_1632,        A_IMM1616,        0,        },
         1050         { O_JMP,        F_8,        A_REL8,        0,        },
         1051         { O_IN,                F_8,        A_AL,        A_DX,        },
         1052         { O_IN,                F_1632,        A_AX,        A_DX,        },        // DX not part of 16 -> 32
         1053         { O_OUT,        F_8,        A_DX,        A_AL,        },
         1054         { O_OUT,        F_1632,        A_DX,        A_AX,        },
         1055 /*F0*/        { O_LOCK,        0,        0,        0,        },
         1056         { -1 },
         1057         { O_REPNE,        0,        0,        0,        },
         1058         { O_REP,        0,        0,        0,        },        // or O_REPE depending on next inst
         1059         { O_HALT,        F_X,        0,        0,        },
         1060         { O_CMC,        F_X,        0,        0,        },
         1061         { O_MODRM,        0,        0,        0,        0,        instF6 },
         1062         { O_MODRM,        0,        0,        0,        0,        instF7 },
         1063 /*F8*/        { O_CLC,        F_X,        0,        0,        },
         1064         { O_STC,        F_X,        0,        0,        },
         1065         { O_CLI,        F_X,        0,        0,        },
         1066         { O_STI,        F_X,        0,        0,        },
         1067         { O_CLD,        F_X,        0,        0,        },
         1068         { O_STD,        F_X,        0,        0,        },
         1069         { O_MODRM,        0,        0,        0,        0,        instFE },
         1070         { O_MODRM,        0,        0,        0,        0,        instFF },
         1071 };
         1072 
         1073 // Argument decoding tables.
         1074 
         1075 static int needsmodrm[MAXA] =
         1076 {
         1077 [A_CR]                1,
         1078 [A_DR]                1,
         1079 [A_TR]                1,
         1080 [A_SR]                1,
         1081 
         1082 [A_R8]                1,
         1083 [A_R16]                1,
         1084 [A_R32]                1,
         1085 
         1086 [A_M]        1,
         1087 
         1088 [A_RM8]                1,
         1089 [A_RM16]        1,
         1090 [A_RM32]        1,
         1091 };
         1092 
         1093 static int cvt32[MAXA] =
         1094 {
         1095 [A_AX]                A_EAX,
         1096 [A_CX]                A_ECX,
         1097 [A_DX]                A_EDX,
         1098 [A_BX]                A_EBX,
         1099 [A_SP]                A_ESP,
         1100 [A_BP]                A_EBP,
         1101 [A_SI]                A_ESI,
         1102 [A_DI]                A_EDI,        
         1103 [A_IMM16]        A_IMM32,
         1104 [A_R16]                A_R32,        
         1105 [A_RM16]        A_RM32,        
         1106 [A_REL16]        A_REL32,
         1107 [A_IMM1616]        A_IMM1632,
         1108 };
         1109 
         1110 static int acvt32[MAXA] =
         1111 {
         1112 [A_MOFF16]        A_MOFF32,        
         1113 };
         1114 
         1115 
         1116 // Addressing mode tables.
         1117 
         1118 static xdarg daimm = { DA_IMM };
         1119 static xdarg darel = { DA_REL };
         1120 
         1121 static xdarg daseg[] = {
         1122         { DA_SEG16, ES },
         1123         { DA_SEG16, CS },
         1124         { DA_SEG16, SS },
         1125         { DA_SEG16, DS },
         1126         { DA_SEG16, FS },
         1127         { DA_SEG16, GS },
         1128 };
         1129 
         1130 #define L 0        // offset of al in eax
         1131 #define H 1        // offset of ah in eax
         1132 #define X 0        // offset of ax in eax
         1133 
         1134 static xdarg dareg[] = {
         1135         { DA_REG8, EAX+L },
         1136         { DA_REG8, ECX+L },
         1137         { DA_REG8, EDX+L },
         1138         { DA_REG8, EBX+L },
         1139         { DA_REG8, EAX+H },
         1140         { DA_REG8, ECX+H },
         1141         { DA_REG8, EDX+H },
         1142         { DA_REG8, EBX+H },
         1143         
         1144         { DA_REG16, EAX+X },
         1145         { DA_REG16, ECX+X },
         1146         { DA_REG16, EDX+X },
         1147         { DA_REG16, EBX+X },
         1148         { DA_REG16, ESP+X },
         1149         { DA_REG16, EBP+X },
         1150         { DA_REG16, ESI+X },
         1151         { DA_REG16, EDI+X },
         1152         
         1153         { DA_REG32, EAX },
         1154         { DA_REG32, ECX },
         1155         { DA_REG32, EDX },
         1156         { DA_REG32, EBX },
         1157         { DA_REG32, ESP },
         1158         { DA_REG32, EBP },
         1159         { DA_REG32, ESI },
         1160         { DA_REG32, EDI },
         1161 };
         1162 
         1163 static xdarg dacr[] = {
         1164         { DA_REG32, CR0 },
         1165         { DA_NONE },
         1166         { DA_REG32, CR2 },
         1167         { DA_REG32, CR3 },
         1168         { DA_NONE },
         1169         { DA_NONE },
         1170         { DA_NONE },
         1171         { DA_NONE },
         1172 };
         1173 
         1174 static xdarg dadr[] = {
         1175         { DA_REG32, DR0 },
         1176         { DA_REG32, DR1 },
         1177         { DA_REG32, DR2 },
         1178         { DA_REG32, DR3 },
         1179         { DA_NONE },
         1180         { DA_NONE },
         1181         { DA_REG32, DR6 },
         1182         { DA_REG32, DR7 },
         1183 };
         1184 
         1185 static xdarg datr[] = {
         1186         { DA_NONE },
         1187         { DA_NONE },
         1188         { DA_NONE },
         1189         { DA_NONE },
         1190         { DA_NONE },
         1191         { DA_NONE },
         1192         { DA_REG32, TR6 },
         1193         { DA_REG32, TR7 },
         1194 };
         1195 
         1196 static xdarg daind16[] = {
         1197         { DA_IND16, EBX+X, ESI+X, 1, -DS },
         1198         { DA_IND16, EBX+X, EDI+X, 1, -DS },
         1199         { DA_IND16, EBP+X, ESI+X, 1, -SS },
         1200         { DA_IND16, EBP+X, EDI+X, 1, -SS },
         1201         { DA_IND16, ESI+X, 0, 0, -DS },
         1202         { DA_IND16, EDI+X, 0, 0, -DS },
         1203         { DA_IND16, EBP+X, 0, 0, -SS },
         1204         { DA_IND16, EBX+X, 0, 0, -DS },
         1205 
         1206         { DA_IND16, EBX+X, ESI+X, 1, -DS },
         1207         { DA_IND16, EBX+X, EDI+X, 1, -DS },
         1208         { DA_IND16, EBP+X, ESI+X, 1, -SS },
         1209         { DA_IND16, EBP+X, EDI+X, 1, -DS },
         1210         { DA_IND16, ESI+X, 0, 0, -DS },
         1211         { DA_IND16, EDI+X, 0, 0, -DS },
         1212         { DA_IND16, EBP+X, 0, 0, -SS },
         1213         { DA_IND16, EBX+X, 0, 0, -DS },
         1214 
         1215         { DA_IND16, EBX+X, ESI+X, 1, -DS },
         1216         { DA_IND16, EBX+X, EDI+X, 1, -DS },
         1217         { DA_IND16, EBP+X, ESI+X, 1, -SS },
         1218         { DA_IND16, EBP+X, EDI+X, 1, -DS },
         1219         { DA_IND16, ESI+X, 0, 0, -DS },
         1220         { DA_IND16, EDI+X, 0, 0, -DS },
         1221         { DA_IND16, EBP+X, 0, 0, -SS },
         1222         { DA_IND16, EBX+X, 0, 0, -DS },
         1223 };
         1224 
         1225 static xdarg daind32[] = {
         1226         { DA_IND32, EAX, 0, 0, -DS },
         1227         { DA_IND32, ECX, 0, 0, -DS },
         1228         { DA_IND32, EDX, 0, 0, -DS },
         1229         { DA_IND32, EBX, 0, 0, -DS },
         1230         { DA_NONE },
         1231         { DA_IND32, EBP, 0, 0, -SS },
         1232         { DA_IND32, ESI, 0, 0, -DS },
         1233         { DA_IND32, EDI, 0, 0, -DS },
         1234 
         1235         { DA_IND32, EAX, 0, 0, -DS },
         1236         { DA_IND32, ECX, 0, 0, -DS },
         1237         { DA_IND32, EDX, 0, 0, -DS },
         1238         { DA_IND32, EBX, 0, 0, -DS },
         1239         { DA_NONE },
         1240         { DA_IND32, EBP, 0, 0, -SS },
         1241         { DA_IND32, ESI, 0, 0, -DS },
         1242         { DA_IND32, EDI, 0, 0, -DS },
         1243 
         1244         { DA_IND32, EAX, 0, 0, -DS },
         1245         { DA_IND32, ECX, 0, 0, -DS },
         1246         { DA_IND32, EDX, 0, 0, -DS },
         1247         { DA_IND32, EBX, 0, 0, -DS },
         1248         { DA_NONE },
         1249         { DA_IND32, EBP, 0, 0, -SS },
         1250         { DA_IND32, ESI, 0, 0, -DS },
         1251         { DA_IND32, EDI, 0, 0, -DS },
         1252 };
         1253 
         1254 static xdarg dasib[] = {
         1255         { DA_SIB, 0, 0, 0, -DS },
         1256         { DA_SIB, 0, 0, 0, -DS },
         1257         { DA_SIB, 0, 0, 0, -DS },
         1258 };
         1259 
         1260 static xdarg dasibx[] = {
         1261         { DA_SIBX, 0, 0, 0, -DS },
         1262         { DA_SIBX, 0, 0, 0, -DS },
         1263         { DA_SIBX, 0, 0, 0, -DS },
         1264 };
         1265 
         1266 static xdarg damem[] = {
         1267         { DA_MEM, 0, 0, 0, -DS },
         1268         { DA_MEM, 0, 0, 0, -DS },
         1269         { DA_MEM, 0, 0, 0, -DS },
         1270 };
         1271 
         1272 static xdarg dasegmem[] = {
         1273         { DA_SEGMEM },
         1274         { DA_SEGMEM },
         1275         { DA_SEGMEM },
         1276 };
         1277 
         1278 // Instruction decode.
         1279 
         1280 static uint
         1281 getimm8(uint8_t **pa)
         1282 {
         1283         return *(int8_t*)(*pa)++;
         1284 }
         1285 
         1286 static uint
         1287 getimm16(uint8_t **pa)
         1288 {
         1289         uint8_t *a;
         1290         
         1291         a = *pa;
         1292         *pa += 2;
         1293         return *(int16_t*)a;
         1294 }
         1295 
         1296 static uint
         1297 getimm32(uint8_t **pa)
         1298 {
         1299         uint8_t *a;
         1300         
         1301         a = *pa;
         1302         *pa += 4;
         1303         return *(int32_t*)a;
         1304 }
         1305 
         1306 static uint8_t*
         1307 decodemodrm(uint8_t *a, uint flags, int sz, uint *reg, xdarg *ea)
         1308 {
         1309         int modrm, sib, s, i, b;
         1310         
         1311         memset(ea, 0, sizeof *ea);
         1312 
         1313         modrm = *a++;
         1314         *reg = (modrm >> 3) & 7;
         1315         if((modrm>>6) == 3){
         1316                 *ea = dareg[8*sz + (modrm&7)];
         1317                 return a;
         1318         }
         1319         if(!(flags&D_ADDR32)){
         1320                 if((modrm>>6) == 0 && (modrm&7) == 6){
         1321                         *ea = damem[sz];
         1322                         ea->disp = (uint16_t)getimm16(&a);
         1323                         return a;
         1324                 }
         1325                 *ea = daind16[sz*8 + (modrm&7)];
         1326                 switch(modrm>>6){
         1327                 case 1:
         1328                         ea->disp = getimm8(&a);
         1329                         break;
         1330                 case 2:
         1331                         ea->disp = (uint16_t)getimm16(&a);
         1332                         break;
         1333                 }
         1334         }else{
         1335                 if((modrm>>6) == 0 && (modrm&7) == 5){
         1336                         *ea = damem[sz];
         1337                         ea->disp = getimm32(&a);
         1338                         return a;
         1339                 }
         1340                 switch(modrm&7){
         1341                 default:        
         1342                         *ea = daind32[sz*8 + (modrm&7)];
         1343                         break;
         1344                 case 4:
         1345                         sib = *a++;
         1346                         s = (sib>>6);
         1347                         i = (sib>>3)&7;
         1348                         b = sib&7;
         1349                         *ea = dasib[sz];
         1350                         if((modrm>>6) == 0 && b == 5){
         1351                                 *ea = dasibx[sz];
         1352                                 ea->disp = getimm32(&a);
         1353                         }else{
         1354                                 *ea = dasib[sz];
         1355                                 ea->reg = 4*b;
         1356                         }
         1357                         if(ea->reg == 4*4 || ea->reg == 4*5)
         1358                                 ea->seg = -SS;
         1359                         if(i != 4){
         1360                                 ea->scale = 1<<s;
         1361                                 ea->index = 4*i;
         1362                         }
         1363                         break;
         1364                 }
         1365                 switch(modrm>>6){
         1366                 case 1:
         1367                         ea->disp = getimm8(&a);
         1368                         break;
         1369                 case 2:
         1370                         ea->disp = getimm32(&a);
         1371                         break;
         1372                 }
         1373         }
         1374         return a;
         1375 }        
         1376 
         1377 uint8_t*
         1378 x86decode(uint8_t *addr0, uint8_t *a, xdinst *dec)
         1379 {
         1380         int i, arg, sz, didmodrm;
         1381         uint reg;
         1382         xdarg ea;
         1383         xinst *ip;
         1384         xdarg *da;
         1385         uint8_t *astart;
         1386         int flags;
         1387         
         1388         flags = D_DATA32|D_ADDR32;
         1389         reg = 0;
         1390         
         1391         astart = a;
         1392         dec->addr = a - addr0;
         1393 
         1394         ip = &inst[*a++];
         1395         
         1396         // xinstruction prefix.
         1397         switch(ip->op){
         1398         case O_LOCK:
         1399                 flags |= D_LOCK;
         1400                 goto next;
         1401         case O_REPNE:
         1402                 flags |= D_REPN;
         1403                 goto next;
         1404         case O_REP:
         1405                 flags |= D_REP;
         1406         next:
         1407                 ip = &inst[*a++];
         1408                 break;
         1409         }
         1410         
         1411         // Address size prefix.
         1412         switch(ip->op){
         1413         case O_ADDRSIZE:
         1414                 flags ^= D_ADDR32;
         1415                 ip = &inst[*a++];
         1416                 break;
         1417         }
         1418         
         1419         // Operand size prefix.
         1420         switch(ip->op){
         1421         case O_DATASIZE:
         1422                 flags ^= D_DATA16|D_DATA32;
         1423                 ip = &inst[*a++];
         1424                 break;
         1425         }
         1426         
         1427         // Segment override.
         1428         switch(ip->op){
         1429         case O_SEGMENT:
         1430                 flags |= D_ES << (ip->arg1 - A_ES);
         1431                 ip = &inst[*a++];
         1432                 break;
         1433         }
         1434 
         1435         if(ip->op == O_NEXTB)
         1436                 ip = &ip->sub[*a++];
         1437 
         1438         didmodrm = 0;
         1439         if(ip->op == O_MODRM){
         1440                 ip = &ip->sub[(*a>>3)&7];
         1441                 didmodrm = 1;
         1442         }
         1443 
         1444         switch(ip->op){
         1445         case O_ADDRSIZE:
         1446         case O_DATASIZE:
         1447         case O_SEGMENT:
         1448         case O_LOCK:
         1449         case O_REPNE:
         1450         case O_REP:
         1451         case -1:
         1452                 return NULL;
         1453         }
         1454         
         1455         switch(ip->flags){
         1456         case F_X:        // Don't care about operand size; pretend 8-bit for tables.
         1457         case F_8:        // Force 8-bit operands
         1458                 flags &= ~(D_DATA16|D_DATA32);
         1459                 flags |= D_DATA8;
         1460                 break;
         1461         case F_16:        // Force 16-bit operands
         1462                 flags &= ~D_DATA32;
         1463                 flags |= D_DATA16;
         1464                 break;
         1465         case F_32:        // Force 32-bit operands
         1466                 flags &= ~D_DATA16;
         1467                 flags |= D_DATA32;
         1468         case F_1632:        // Convert 16-bit operands to 32-bit if needed
         1469                 break;
         1470         case F_0A:        // Eat 0x0A byte.
         1471                 if(*a++ != 0x0A)
         1472                         return NULL;
         1473                 break;
         1474         }
         1475         if(flags&D_DATA8)
         1476                 sz = 0;
         1477         else if(flags&D_DATA16)
         1478                 sz = 1;
         1479         else
         1480                 sz = 2;
         1481 
         1482         if(ip->op < 0 || ip->op >= MAXO)
         1483                 return NULL;
         1484 
         1485         dec->name = opnames[ip->op][sz];
         1486 
         1487         // Mod R/M byte if needed.
         1488         if(didmodrm || needsmodrm[ip->arg1] || needsmodrm[ip->arg2])
         1489                 a = decodemodrm(a, flags, sz, &reg, &ea);
         1490 
         1491         // TO DO: Use override prefixes.
         1492 
         1493         for(i=0; i<3; i++){
         1494                 arg = (&ip->arg1)[i];
         1495                 da = &dec->arg[i];
         1496                 if(arg == 0){
         1497                         da->op = DA_NONE;
         1498                         continue;
         1499                 }
         1500                 if((flags&D_DATA32) && ip->flags == F_1632 && cvt32[arg])
         1501                         arg = cvt32[arg];
         1502                 if((flags&D_ADDR32) && acvt32[arg])
         1503                         arg = acvt32[arg];
         1504 
         1505                 switch(arg){
         1506                 case A_0:
         1507                         *da = daimm;
         1508                         da->disp = 0;
         1509                         break;
         1510                 case A_1:
         1511                 case A_3:
         1512                 case A_4:
         1513                         *da = daimm;
         1514                         da->disp = arg;
         1515                         break;
         1516                 case A_AL:
         1517                 case A_CL:
         1518                 case A_DL:
         1519                 case A_BL:
         1520                 case A_AH:
         1521                 case A_CH:
         1522                 case A_DH:
         1523                 case A_BH:
         1524                         *da = dareg[arg - A_AL];
         1525                         break;
         1526                 case A_AX:
         1527                 case A_CX:
         1528                 case A_DX:
         1529                 case A_BX:
         1530                 case A_SP:
         1531                 case A_BP:
         1532                 case A_SI:
         1533                 case A_DI:
         1534                         *da = dareg[8 + arg - A_AX];
         1535                         break;
         1536                 case A_EAX:
         1537                 case A_ECX:
         1538                 case A_EDX:
         1539                 case A_EBX:
         1540                 case A_ESP:
         1541                 case A_EBP:
         1542                 case A_ESI:
         1543                 case A_EDI:
         1544                         *da = dareg[16 + arg - A_EAX];
         1545                         break;
         1546                 case A_ES:
         1547                 case A_CS:
         1548                 case A_SS:
         1549                 case A_DS:
         1550                 case A_FS:
         1551                 case A_GS:
         1552                         *da = daseg[arg - A_ES];
         1553                         break;
         1554 
         1555                 case A_IMM8:
         1556                         *da = daimm;
         1557                         da->disp = getimm8(&a);
         1558                         break;
         1559                 case A_IMM16:
         1560                         *da = daimm;
         1561                         da->disp = getimm16(&a);
         1562                         break;
         1563                 case A_IMM32:
         1564                         *da = daimm;
         1565                         da->disp = getimm32(&a);
         1566                         break;
         1567 
         1568                 case A_REL8:
         1569                         *da = darel;
         1570                         da->disp = getimm8(&a);
         1571                         break;
         1572                 case A_REL16:
         1573                         *da = darel;
         1574                         da->disp = getimm16(&a);
         1575                         break;
         1576                 case A_REL32:
         1577                         *da = darel;
         1578                         da->disp = getimm32(&a);
         1579                         break;
         1580 
         1581                 case A_R8:
         1582                 case A_R16:
         1583                 case A_R32:
         1584                         *da = dareg[sz*8 + reg];
         1585                         break;
         1586 
         1587                 case A_RM8:
         1588                 case A_RM16:
         1589                 case A_RM32:
         1590                         *da = ea;
         1591                         break;
         1592                 
         1593                 case A_RM32R:        // A_RM32 but needs to be register
         1594                         *da = ea;
         1595                         if(da->op > DA_REG32)
         1596                                 return NULL;
         1597                         break;
         1598                 
         1599                 case A_M:        // A_RM but needs to be memory
         1600                         *da = ea;
         1601                         if(da->op <= DA_REG32)
         1602                                 return NULL;
         1603                         break;
         1604 
         1605                 case A_MOFF8:
         1606                         *da = damem[sz];
         1607                         da->disp = getimm8(&a);
         1608                         break;
         1609                 case A_MOFF16:
         1610                         *da = damem[sz];
         1611                         da->disp = getimm16(&a);
         1612                         break;
         1613                 case A_MOFF32:
         1614                         *da = damem[sz];
         1615                         da->disp = getimm32(&a);
         1616                         break;
         1617 
         1618                 case A_SR:
         1619                         if(reg > 5)
         1620                                 return NULL;
         1621                         *da = daseg[reg];
         1622                         break;
         1623 
         1624                 case A_CR:
         1625                         *da = dacr[reg];
         1626                         if(da->op == DA_NONE)
         1627                                 return NULL;
         1628                         break;
         1629                 case A_DR:
         1630                         *da = dadr[reg];
         1631                         if(da->op == DA_NONE)
         1632                                 return NULL;
         1633                         break;
         1634                 case A_TR:
         1635                         *da = dadr[reg];
         1636                         if(da->op == DA_NONE)
         1637                                 return NULL;
         1638                         break;
         1639 
         1640                 case A_IMM1616:
         1641                 case A_IMM1632:
         1642                         *da = dasegmem[sz];
         1643                         if(arg == A_IMM1616)
         1644                                 da->disp = getimm16(&a);
         1645                         else
         1646                                 da->disp = getimm32(&a);
         1647                         da->seg = getimm16(&a);
         1648                         break;
         1649 
         1650                 }
         1651         }
         1652         dec->opsz = 8<<sz;
         1653         dec->flags = flags;
         1654         dec->len = a - astart;
         1655         if(dec->name == NULL)
         1656                 dec->name = "???";
         1657         return a;
         1658 }
         1659 
         1660 
         1661 // Instruction printing
         1662 
         1663 static char*
         1664 fmtseg(char *p, char *ep, xdarg *da)
         1665 {
         1666         if(da->seg < 0)
         1667                 p += snprintf(p, ep-p, "%s:", seg[-da->seg-CS]);
         1668         else
         1669                 p += snprintf(p, ep-p, "%#x:", da->seg);
         1670         return p;
         1671 }
         1672 
         1673 extern void vxrun_gentrap(void);
         1674 extern void vxrun_lookup_backpatch(void);
         1675 extern void vxrun_lookup_indirect(void);
         1676 
         1677 static char*
         1678 fmtarg(char *p, char *ep, xdarg *da, uint32_t npc)
         1679 {
         1680         uint32_t addr;
         1681 
         1682         switch(da->op){
         1683         default:
         1684                 p += snprintf(p, ep-p, "a%d", da->op);
         1685                 break;
         1686         case DA_REG8:
         1687                 p += snprintf(p, ep-p, "%s", reg8[da->reg/4 + 4*(da->reg%2)]);
         1688                 break;
         1689         case DA_REG16:
         1690                 p += snprintf(p, ep-p, "%s", reg16[da->reg/4]);
         1691                 break;
         1692         case DA_REG32:
         1693                 p += snprintf(p, ep-p, "%s", reg32[da->reg/4]);
         1694                 break;
         1695         case DA_SEG16:
         1696                 p += snprintf(p, ep-p, "%s", seg[da->reg-CS]);
         1697                 break;
         1698         case DA_IMM:
         1699                 p += snprintf(p, ep-p, "$%#x", da->disp);
         1700                 break;
         1701         case DA_REL:
         1702                 addr = da->disp + npc;
         1703                 if (addr == (uint32_t)(uintptr_t)vxrun_gentrap)
         1704                         p += snprintf(p, ep-p, "vxrun_gentrap");
         1705                 else if (addr == (uint32_t)(uintptr_t)vxrun_lookup_backpatch)
         1706                         p += snprintf(p, ep-p, "vxrun_lookup_backpatch");
         1707                 else if (addr == (uint32_t)(uintptr_t)vxrun_lookup_indirect)
         1708                         p += snprintf(p, ep-p, "vxrun_lookup_indirect");
         1709                 else
         1710                         p += snprintf(p, ep-p, "%#x", da->disp + npc);
         1711                 break;
         1712         case DA_MEM:
         1713                 p = fmtseg(p, ep, da);
         1714                 p += snprintf(p, ep-p, "%#x", da->disp);
         1715                 break;
         1716         case DA_SEGMEM:
         1717                 p += snprintf(p, ep-p, "%#x:%#x", da->seg, da->disp);
         1718                 break;
         1719         case DA_IND16:
         1720                 p = fmtseg(p, ep, da);
         1721                 if(da->disp)
         1722                         p += snprintf(p, ep-p, "%#x", da->disp);
         1723                 p += snprintf(p, ep-p, "(");
         1724                 p += snprintf(p, ep-p, "%s", reg16[da->reg/4]);
         1725                 if(da->scale)
         1726                         p += snprintf(p, ep-p, "+%s", reg16[da->reg/4]);
         1727                 p += snprintf(p, ep-p, ")");
         1728                 break;
         1729         case DA_IND32:
         1730                 p = fmtseg(p, ep, da);
         1731                 if(da->disp)
         1732                         p += snprintf(p, ep-p, "%#x", da->disp);
         1733                 p += snprintf(p, ep-p, "(%s)", reg32[da->reg/4]);
         1734                 break;
         1735         case DA_SIB:
         1736         case DA_SIBX:
         1737                 p = fmtseg(p, ep, da);
         1738                 if(da->disp)
         1739                         p += snprintf(p, ep-p, "%#x", da->disp);
         1740                 p += snprintf(p, ep-p, "(");
         1741                 if(da->op != DA_SIBX)
         1742                         p += snprintf(p, ep-p, "%s+", reg32[da->reg/4]);
         1743                 if(da->scale > 1)
         1744                         p += snprintf(p, ep-p, "%d*", da->scale);
         1745                 p += snprintf(p, ep-p, "%s", reg32[da->index/4]);
         1746                 p += snprintf(p, ep-p, ")");
         1747                 break;
         1748         }
         1749         return p;
         1750 }
         1751 
         1752 int
         1753 x86print(char *buf, int nbuf, xdinst *dec)
         1754 {
         1755         int i;
         1756         char *p, *ep;
         1757         
         1758         p = buf;
         1759         ep = buf + nbuf;
         1760         for(i=0; i<nelem(prefixes); i++)
         1761                 if(dec->flags & prefixes[i].f)
         1762                         p += snprintf(p, ep-p, "%s ", prefixes[i].s);
         1763         p += snprintf(p, ep-p, "%-6s", dec->name);
         1764         for(i=0; i<nelem(dec->arg) && dec->arg[i].op != DA_NONE; i++){
         1765                 if(i > 0)
         1766                         p += snprintf(p, ep-p, ",");
         1767                 p += snprintf(p, ep-p, " ");
         1768                 p = fmtarg(p, ep, &dec->arg[i], dec->addr + dec->len);
         1769         }
         1770         return p - buf;
         1771 }