Diff for /np2/i386c/ia32/cpu.c between versions 1.6 and 1.23

version 1.6, 2004/01/16 15:17:51 version 1.23, 2005/03/03 06:59:41
Line 28 Line 28
  */   */
   
 #include "compiler.h"  #include "compiler.h"
   #include "dosio.h"
 #include "cpu.h"  #include "cpu.h"
 #include "ia32.mcr"  #include "ia32.mcr"
   
 #include "inst_table.h"  #include "inst_table.h"
   
 #if defined(IA32_PROFILE_INSTRUCTION)  #if defined(ENABLE_TRAP)
 UINT32  inst_1byte_count[2][256];  #include "steptrap.h"
 UINT32  inst_2byte_count[2][256];  
 UINT32  ea16_count[24];  
 UINT32  ea32_count[24];  
 UINT32  sib0_count[256];  
 UINT32  sib1_count[256];  
 UINT32  sib2_count[256];  
   
 static const char *ea16_str[24] = {  
         "BX + SI", "BX + SI + DISP8", "BX + SI + DISP16",  
         "BX + DI", "BX + DI + DISP8", "BX + DI + DISP16",  
         "BP + SI", "BP + SI + DISP8", "BP + SI + DISP16",  
         "BP + DI", "BP + DI + DISP8", "BP + DI + DISP16",  
         "SI",      "SI + DISP8",      "SI + DISP16",  
         "DI",      "DI + DISP8",      "DI + DISP16",  
         "DISP16",  "BP + DISP8",      "BP + DISP16",  
         "BX",      "BX + DISP8",      "BX + DISP16",  
 };  
   
 static const char *ea32_str[24] = {  
         "EAX", "ECX", "EDX", "EBX", "SIB", "DISP32", "ESI", "EDI",  
         "EAX + DISP8",  "ECX + DISP8",  "EDX + DISP8",  "EBX + DISP8",  
         "SIB + DISP8",  "EBP + DISP8",  "ESI + DISP8",  "EDI + DISP8",  
         "EAX + DISP32", "ECX + DISP32", "EDX + DISP32", "EBX + DISP32",  
         "SIB + DISP32", "EBP + DISP32", "ESI + DISP32", "EDI + DISP32",  
 };  
   
 static const char *sib0_base_str[8] = {  
         "EAX", "ECX", "EDX", "EBX", "ESP", "DISP32", "ESI", "EDI",  
 };  
   
 static const char *sib1_base_str[8] = {  
         "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI",  
 };  
   
 static const char *sib_index_str[8] = {  
         "EAX", "ECX", "EDX", "EBX", "", "EBP", "ESI", "EDI",  
 };  
   
 static const char *sib_scale_str[4] = {  
         "", "2", "4", "8",  
 };  
   
 void  
 clear_profile_inst(void)  
 {  
   
         memset(inst_1byte_count, 0, sizeof(inst_1byte_count));  
         memset(inst_2byte_count, 0, sizeof(inst_2byte_count));  
         memset(ea16_count, 0, sizeof(ea16_count));  
         memset(ea32_count, 0, sizeof(ea32_count));  
         memset(sib0_count, 0, sizeof(sib0_count));  
         memset(sib1_count, 0, sizeof(sib1_count));  
         memset(sib2_count, 0, sizeof(sib2_count));  
 }  
   
 void  
 show_profile_inst(void)  
 {  
         int i;  
   
         printf("instruction (16bit)\n");  
         for (i = 0; i < 256; i++) {  
                 if (inst_1byte_count[0][i] != 0) {  
                         printf("0x%02x: %d\n", i, inst_1byte_count[0][i]);  
                 }  
         }  
         for (i = 0; i < 256; i++) {  
                 if (inst_2byte_count[0][i] != 0) {  
                         printf("0x0f%02x: %d\n", i, inst_2byte_count[0][i]);  
                 }  
         }  
   
         printf("instruction (32bit)\n");  
         for (i = 0; i < 256; i++) {  
                 if (inst_1byte_count[1][i] != 0) {  
                         printf("0x%02x: %d\n", i, inst_1byte_count[1][i]);  
                 }  
         }  
         for (i = 0; i < 256; i++) {  
                 if (inst_2byte_count[1][i] != 0) {  
                         printf("0x0f%02x: %d\n", i, inst_2byte_count[1][i]);  
                 }  
         }  
 }  
   
 void  
 show_profile_ea(void)  
 {  
         char buf[80];  
         char tmp[80];  
         int i;  
         int t;  
   
         printf("EA16\n");  
         for (i = 0; i < NELEMENTS(ea16_count); i++) {  
                 if (ea16_count[i] != 0) {  
                         printf("%s: %d\n", ea16_str[i], ea16_count[i]);  
                 }  
         }  
         printf("EA32\n");  
         for (i = 0; i < NELEMENTS(ea32_count); i++) {  
                 if (ea32_count[i] != 0) {  
                         printf("%s: %d\n", ea32_str[i], ea32_count[i]);  
                 }  
         }  
         printf("SIB0\n");  
         for (i = 0; i < NELEMENTS(sib0_count); i++) {  
                 if (sib0_count[i] != 0) {  
                         sprintf(tmp, "%s", sib0_base_str[i & 7]);  
                         strcpy(buf, tmp);  
                         t = (i >> 3) & 7;  
                         if (t != 4) {  
                                 sprintf(tmp, " + %s", sib_index_str[t]);  
                                 strcat(buf, tmp);  
                         }  
                         t = (i >> 6) & 3;  
                         if (t != 0) {  
                                 sprintf(tmp, " * %s", sib_scale_str[t]);  
                                 strcat(buf, tmp);  
                         }  
                         printf("%s: %d\n", buf, sib0_count[i]);  
                 }  
         }  
         printf("SIB1\n");  
         for (i = 0; i < NELEMENTS(sib1_count); i++) {  
                 if (sib1_count[i] != 0) {  
                         sprintf(tmp, "%s", sib1_base_str[i & 7]);  
                         strcpy(buf, tmp);  
                         t = (i >> 3) & 7;  
                         if (t != 4) {  
                                 sprintf(tmp, " + %s", sib_index_str[t]);  
                                 strcat(buf, tmp);  
                         }  
                         t = (i >> 6) & 3;  
                         if (t != 0) {  
                                 sprintf(tmp, " * %s", sib_scale_str[t]);  
                                 strcat(buf, tmp);  
                         }  
                         printf("%s + DISP8: %d\n", buf, sib1_count[i]);  
                 }  
         }  
         printf("SIB2\n");  
         for (i = 0; i < NELEMENTS(sib2_count); i++) {  
                 if (sib2_count[i] != 0) {  
                         sprintf(tmp, "%s", sib1_base_str[i & 7]);  
                         strcpy(buf, tmp);  
                         t = (i >> 3) & 7;  
                         if (t != 4) {  
                                 sprintf(tmp, " + %s", sib_index_str[t]);  
                                 strcat(buf, tmp);  
                         }  
                         t = (i >> 6) & 3;  
                         if (t != 0) {  
                                 sprintf(tmp, " * %s", sib_scale_str[t]);  
                                 strcat(buf, tmp);  
                         }  
                         printf("%s + DISP32: %d\n", buf, sib2_count[i]);  
                 }  
         }  
 }  
 #endif  #endif
   
 #ifdef  IA32_INSTRUCTION_TRACE  
 static FILE *fp = NULL;  
 BOOL cpu_inst_trace = FALSE;  
   
 static const char *opcode_1byte[2][256] = {  sigjmp_buf exec_1step_jmpbuf;
 /* 16bit */  
 {  
 /*00*/  "addb",  "addw",  "addb",  "addw",  "addb",  "addw",  "push",  "pop",  
         "orb",   "orw",   "orb",   "orw",   "orb",   "orw",   "push",  NULL,  
 /*10*/  "adcb",  "adcw",  "adcb",  "adcw",  "adcb",  "adcw",  "push",  "pop",  
         "sbbb",  "sbbw",  "sbbb",  "sbbw",  "sbbb",  "sbbw",  "push",  "pop",  
 /*20*/  "andb",  "andw",  "andb",  "andw",  "andb",  "andw",  "es:",   "daa",  
         "subb",  "subw",  "subb",  "subw",  "subb",  "subw",  "cs:",   "das",  
 /*30*/  "xorb",  "xorw",  "xorb",  "xorw",  "xorb",  "xorw",  "ss:",   "aaa",  
         "cmpb",  "cmpw",  "cmpb",  "cmpw",  "cmpb",  "cmpw",  "ds:",   "aas",  
 /*40*/  "incw",  "incw",  "incw",  "incw",  "incw",  "incw",  "incw",  "incw",  
         "decw",  "decw",  "decw",  "decw",  "decw",  "decw",  "decw",  "decw",  
 /*50*/  "push",  "push",  "push",  "push",  "push",  "push",  "push",  "push",  
         "pop",   "pop",   "pop",   "pop",   "pop",   "pop",   "pop",   "pop",  
 /*60*/  "pusha", "popa",  "bound", "arpl",  "fs:",   "gs:",   NULL,    NULL,  
         "push",  "imul",  "push",  "imul",  "insb",  "insw",  "outsb", "outsw",  
 /*70*/  "jo",    "jno",   "jc",    "jnc",   "jz",    "jnz",   "jna",   "ja",  
         "js",    "jns",   "jp",    "jnp",   "jl",    "jnl",   "jle",   "jnle",  
 /*80*/  NULL,    NULL,    NULL,    NULL,    "testb", "testw", "xchgb", "xchgw",  
         "movb",  "movw",  "movb",  "movw",  "movw",  "lea",   "movw",  "pop",  
 /*90*/  "nop",   "xchgw", "xchgw", "xchgw", "xchgw", "xchgw", "xchgw", "xchgw",  
         "cbw",   "cwd",   "callf", "fwait", "pushf", "popf",  "sahf",  "lahf",  
 /*a0*/  "movb",  "movw",  "movb",  "movw",  "movsb", "movsw", "cmpsb", "cmpsw",  
         "testb", "testw", "stosb", "stosw", "lodsb", "lodsw", "scasb", "scasw",  
 /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",    
         "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",  "movw",    
 /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movw",  
         "enter", "leave", "retf",  "retf",  "int3",  "int",   "into",  "iret",  
 /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",  
         "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",  
 /*e0*/  "loopne","loope", "loop",  "jcxz",  "inb",   "inw",   "outb",  "outw",  
         "call",  "jmp",   "jmpf",  "jmp",   "inb",   "inw",   "outb",  "outw",  
 /*f0*/  "lock:", "int1",  "repne", "repe",  "hlt",   "cmc",   NULL,    NULL,  
         "clc",   "stc",   "cli",   "sti",   "cld",   "std",   NULL,    NULL,  
 },  
 /* 32bit */  
 {  
 /*00*/  "addb",  "addl",  "addb",  "addl",  "addb",  "addl",  "pushl", "popl",  
         "orb",   "orl",   "orb",   "orl",   "orb",   "orl",   "pushl", NULL,  
 /*10*/  "adcb",  "adcl",  "adcb",  "adcl",  "adcb",  "adcl",  "pushl", "popl",  
         "sbbb",  "sbbl",  "sbbb",  "sbbl",  "sbbb",  "sbbl",  "pushl", "popl",  
 /*20*/  "andb",  "andl",  "andb",  "andl",  "andb",  "andl",  "es:",   "daa",  
         "subb",  "subl",  "subb",  "subl",  "subb",  "subl",  "cs:",   "das",  
 /*30*/  "xorb",  "xorl",  "xorb",  "xorl",  "xorb",  "xorl",  "ss:",   "aaa",  
         "cmpb",  "cmpl",  "cmpb",  "cmpl",  "cmpb",  "cmpl",  "ds:",   "aas",  
 /*40*/  "incl",  "incl",  "incl",  "incl",  "incl",  "incl",  "incl",  "incl",  
         "decl",  "decl",  "decl",  "decl",  "decl",  "decl",  "decl",  "decl",  
 /*50*/  "pushl", "pushl", "pushl", "pushl", "pushl", "pushl", "pushl", "pushl",  
         "popl",  "popl",  "popl",  "popl",  "popl",  "popl",  "popl",  "pop",  
 /*60*/  "pushal","popal", "bound", "arpl",  "fs:",   "gs:",   NULL,    NULL,  
         "pushl", "imul",  "pushl", "imul",  "insb",  "insl",  "outsb", "outsl",  
 /*70*/  "jo",    "jno",   "jc",    "jnc",   "jz",    "jnz",   "jna",   "ja",  
         "js",    "jns",   "jp",    "jnp",   "jl",    "jnl",   "jle",   "jnle",  
 /*80*/  NULL,    NULL,    NULL,    NULL,    "testb", "testl", "xchgb", "xchgl",  
         "movb",  "movl",  "movb",  "movl",  "movl",  "lea",   "movl",  "popl",  
 /*90*/  "nop",   "xchgl", "xchgl", "xchgl", "xchgl", "xchgl", "xchgl", "xchgl",  
         "cwde",  "cdq",   "callfl","fwait", "pushfd","popfd", "sahf",  "lahf",  
 /*a0*/  "movb",  "movl",  "movb",  "movl",  "movsb", "movsd", "cmpsb", "cmpsd",  
         "testb", "testl", "stosb", "stosd", "lodsb", "lodsd", "scasb", "scasd",  
 /*b0*/  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",  "movb",    
         "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",  "movl",    
 /*c0*/  NULL,    NULL,    "ret",   "ret",   "les",   "lds",   "movb",  "movl",  
         "enter", "leave", "retfd", "retfd", "int3",  "int",   "into",  "iret",  
 /*d0*/  NULL,    NULL,    NULL,    NULL,    "aam",   "aad",   "salc",  "xlat",  
         "esc0",  "esc1",  "esc2",  "esc3",  "esc4",  "esc5",  "esc6",  "esc7",  
 /*e0*/  "loopne","loope", "loop",  "jecxz", "inb",   "inl",   "outb",  "outl",  
         "call",  "jmp",   "jmpf",  "jmp",   "inb",   "inl",   "outb",  "outl",  
 /*f0*/  "lock:", "int1",  "repne", "repe",  "hlt",   "cmc",   NULL,    NULL,  
         "clc",   "stc",   "cli",   "sti",   "cld",   "std",   NULL,    NULL,  
 }  
 };  
   
 static const char *opcode_2byte[2][256] = {  #if defined(IA32_INSTRUCTION_TRACE)
 /* 16bit */  typedef struct {
 {          CPU_REGS                regs;
 /*00*/  NULL,      NULL,      "lar",     "lsl",          disasm_context_t        disasm;
         NULL,      "loadall", "clts",    NULL,  
         "invd",    "wbinvd",  NULL,      "UD2",  
         NULL,      NULL,      NULL,      NULL,  
 /*10*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*20*/  "movl",    "movl",    "movl",    "movl",  
         "movl",    NULL,      "movl",    NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*30*/  "wrmsr",   "rdtsc",   "rdmsr",   NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*40*/  "cmovo",   "cmovno",  "cmovc",   "cmovnc",  
         "cmovz",   "cmovnz",  "cmovna",  "cmova",  
         "cmovs",   "cmovns",  "cmovp",   "cmovnp",  
         "cmovl",   "cmovnl",  "cmovle",  "cmovnle",  
 /*50*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*60*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*70*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*80*/  "jo",      "jno",     "jc",      "jnc",  
         "jz",      "jnz",     "jna",     "ja",  
         "js",      "jns",     "jp",      "jnp",  
         "jl",      "jnl",     "jle",     "jnle",  
 /*90*/  "seto",    "setno",   "setc",    "setnc",  
         "setz",    "setnz",   "setna",   "seta",  
         "sets",    "setns",   "setp",    "setnp",  
         "setl",    "setnl",   "setle",   "setnle",  
 /*a0*/  "push",    "pop",     "cpuid",   "bt",  
         "shldb",   "shldw",   "cmpxchgb","cmpxchgw",  
         "push",    "pop",     "rsm",     "bts",  
         "shrdb",   "shrdw",   NULL,      "imul",  
 /*b0*/  "cmpxchgb","cmpxchgw","lss",     "btr",  
         "lfs",     "lgs",     "movzb",   "movzw",  
         NULL,      "UD2",     NULL,      "btc",  
         "bsf",     "bsr",     "movsb",   "movsw",  
 /*c0*/  "xaddb",   "xaddw",   NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         "bswap",   "bswap",   "bswap",   "bswap",  
         "bswap",   "bswap",   "bswap",   "bswap",  
 /*d0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*e0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*f0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 },  
 /* 32bit */  
 {  
 /*00*/  NULL,      NULL,      "lar",     "lsl",  
         NULL,      "loadall", "clts",    NULL,  
         "invd",    "wbinvd",  NULL,      "UD2",  
         NULL,      NULL,      NULL,      NULL,  
 /*10*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*20*/  "movl",    "movl",    "movl",    "movl",  
         "movl",    NULL,      "movl",    NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*30*/  "wrmsr",   "rdtsc",   "rdmsr",   NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*40*/  "cmovo",   "cmovno",  "cmovc",   "cmovnc",  
         "cmovz",   "cmovnz",  "cmovna",  "cmova",  
         "cmovs",   "cmovns",  "cmovp",   "cmovnp",  
         "cmovl",   "cmovnl",  "cmovle",  "cmovnle",  
 /*50*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*60*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*70*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*80*/  "jo",      "jno",     "jc",      "jnc",  
         "jz",      "jnz",     "jna",     "ja",  
         "js",      "jns",     "jp",      "jnp",  
         "jl",      "jnl",     "jle",     "jnle",  
 /*90*/  "seto",    "setno",   "setc",    "setnc",  
         "setz",    "setnz",   "setna",   "seta",  
         "sets",    "setns",   "setp",    "setnp",  
         "setl",    "setnl",   "setle",   "setnle",  
 /*a0*/  "push",    "pop",     "cpuid",   "bt",  
         "shldb",   "shldl",   "cmpxchgb","cmpxchgl",  
         "push",    "pop",     "rsm",     "bts",  
         "shrdb",   "shrdl",   NULL,      "imul",  
 /*b0*/  "cmpxchgb","cmpxchgd","lss",     "btr",  
         "lfs",     "lgs",     "movzbl",  "movzwl",  
         NULL,      "UD2",     NULL,      "btc",  
         "bsf",     "bsr",     "movsbl",  "movswl",  
 /*c0*/  "xaddb",   "xaddl",   NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         "bswapl",  "bswapl",  "bswapl",  "bswapl",  
         "bswapl",  "bswapl",  "bswapl",  "bswapl",  
 /*d0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*e0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 /*f0*/  NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
         NULL,      NULL,      NULL,      NULL,  
 }  
 };  
   
 static const char *opcode_0x8x[2][2][8] = {          BYTE                    op[MAX_PREFIX + 2];
 /* 16bit */          int                     opbytes;
 {  } ia32_context_t;
         { "addb", "orb", "adcb", "sbbb", "andb", "subb", "xorb", "cmpb" },  
         { "addw", "orw", "adcw", "sbbw", "andw", "subw", "xorw", "cmpw" }  
 },  
 /* 32bit */  
 {  
         { "addb", "orb", "adcb", "sbbb", "andb", "subb", "xorb", "cmpb" },  
         { "addl", "orl", "adcl", "sbbl", "andl", "subl", "xorl", "cmpl" }  
 }  
 };  
   
 static const char *opcode_shift[2][2][8] = {  #define NCTX    1024
 /* 16bit */  
 {  
         { "rolb", "rorb", "rclb", "rcrb", "shlb", "shrb", "shlb", "sarb" },  
         { "rolw", "rorw", "rclw", "rcrw", "shlw", "shrw", "shlw", "sarw" }  
 },  
 /* 32bit */  
 {  
         { "rolb", "rorb", "rclb", "rcrb", "shlb", "shrb", "shlb", "sarb" },  
         { "roll", "rorl", "rcll", "rcrl", "shll", "shrl", "shll", "sarl" }  
 },  
 };  
   
 static const char *opcode_0xf6[2][2][8] = {  ia32_context_t ctx[NCTX];
 /* 16bit */  int ctx_index = 0;
 {  
         { "testb", "testb", "notb", "negb", "mul", "imul", "div", "idiv" },  
         { "testw", "testw", "notw", "negw", "mulw", "imulw", "divw", "idivw" }  
 },  
 /* 32bit */  
 {  
         { "testb", "testb", "notb", "negb", "mul", "imul", "div", "idiv" },  
         { "testl", "testl", "notl", "negl", "mull", "imull", "divl", "idivl" }  
 },  
 };  
   
 static const char *opcode_0xfe[2][2][8] = {  int cpu_inst_trace = 0;
 /* 16bit */  #endif
 {  
         { "incb", "decb", NULL, NULL, NULL, NULL, NULL, NULL },  
         { "incw", "decw", "call", "callf", "jmp", "jmpf", "push", NULL }  
 },  
 /* 32bit */  
 {  
         { "incb", "decb", NULL, NULL, NULL, NULL, NULL, NULL },  
         { "incl", "decl", "call", "callf", "jmp", "jmpf", "pushl", NULL }  
 }  
 };  
   
 static const char *opcode2_g6[8] = {  
         "sldt", "str", "lldt", "ltr", "verr", "verw", NULL, NULL  
 };  
   
 static const char *opcode2_g7[8] = {  
         "sgdt", "sidt", "lgdt", "lidt", "smsw", NULL, "lmsw", "invlpg"  
 };  
   
 static const char *opcode2_g8[8] = {  
         NULL, NULL, NULL, NULL, "bt", "bts", "btr", "btc"  
 };  
   
 static const char *opcode2_g9[8] = {  
         NULL, "cmpxchg8b", NULL, NULL, NULL, NULL, NULL, NULL  
 };  
   
 static const char *reg8[8] = {  
         "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"  
 };  
   
 static const char *reg16[8] = {   
         "ax", "cx", "dx", "bx", "sp", "bp", "si", "di"  
 };  
   
 static const char *reg32[8] = {   
         "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"  
 };  
   
 static DWORD  void
 ea(DWORD eip, DWORD op)  exec_1step(void)
 {  {
         static const char *ea16[8] = {          int prefix;
                 "bx + si", "bx + di", "bp + si", "bp + di",          UINT32 op;
                 "si", "di", "bp", "bx"  
         };  
   
         char buf[256];  
         DWORD mod = (op >> 6) & 3;  
         DWORD rm = op & 7;  
         DWORD val;  
   
         __ASSERT(mod != 3);  
   
         buf[0] = '\0';  
   
         if (!CPU_INST_AS32) {  
                 if (mod == 0) {  
                         if (rm == 6) {  
                                 /* disp16 */  
                                 val = cpu_codefetch_w(eip);  
                                 eip += 2;  
                                 SPRINTF(buf, "0x%04x", val);  
                         } else {  
                                 SPRINTF(buf, "%s", ea16[rm]);  
                         }  
                 } else {  
                         if (mod == 1) {  
                                 /* disp8 */  
                                 val = cpu_codefetch(eip);  
                                 if (val & 0x80) {  
                                         val |= 0xff00;  
                                 }  
                                 eip++;  
                         } else {  
                                 /* disp16 */  
                                 val = cpu_codefetch_w(eip);  
                                 eip += 2;  
                         }  
                         SPRINTF(buf, "%s + 0x%04x", ea16[rm], val);  
                 }  
         } else {  
                 char tmp[32];  
                 BYTE count[9];  
                 int n;  
                 int i;  
   
                 ZeroMemory(count, sizeof(count));          CPU_PREV_EIP = CPU_EIP;
           CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default;
   
                 if (rm == 5) {  #if defined(ENABLE_TRAP)
                         DWORD sib;          steptrap(CPU_CS, CPU_EIP);
                         DWORD scale;  #endif
                         DWORD idx;  
                         DWORD base;  
   
                         sib = cpu_codefetch(eip);  
                         eip++;  
   
                         scale = (sib >> 6) & 3;  
                         idx = (sib >> 3) & 7;  
                         base = sib & 7;  
   
                         if (base == 5 && mod == 0) {  
                                 val = cpu_codefetch_d(eip);  
                                 eip += 4;  
                                 count[8] += val;  
                         } else {  
                                 count[base]++;  
                         }  
                         if (idx != 4) {  
                                 count[idx] += 1 << scale;  
                         }  
                 }  
   
                 if (rm == 6 && mod == 0) {  #if defined(IA32_INSTRUCTION_TRACE)
                         /* disp32 */          ctx[ctx_index].regs = CPU_STATSAVE.cpu_regs;
                         val = cpu_codefetch_d(eip);          if (cpu_inst_trace) {
                         eip += 4;                  disasm_context_t *d = &ctx[ctx_index].disasm;
                         count[8] += val;                  UINT32 eip = CPU_EIP;
                 } else {                  int rv;
                         if (mod == 1) {  
                                 /* disp8 */                  rv = disasm(&eip, d);
                                 val = cpu_codefetch(eip);                  if (rv == 0) {
                                 eip++;                          char buf[256];
                                 if (val & 0x80) {                          char tmp[32];
                                         val |= 0xffffff00;                          int len = d->nopbytes > 8 ? 8 : d->nopbytes;
                                 }                          int i;
                                 count[8] += val;  
                         } else if (mod == 2) {                          buf[0] = '\0';
                                 /* disp32 */                          for (i = 0; i < len; i++) {
                                 val = cpu_codefetch_d(eip);                                  snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]);
                                 eip += 4;                                  milstr_ncat(buf, tmp, sizeof(buf));
                                 count[8] += val;  
                         }                          }
                         if (rm != 5) {                          for (; i < 8; i++) {
                                 count[rm]++;                                  milstr_ncat(buf, "   ", sizeof(buf));
                         }                          }
                 }                          VERBOSE(("%04x:%08x: %s%s", CPU_CS, CPU_EIP, buf, d->str));
   
                 n = 0;                          buf[0] = '\0';
                 for (i = 0; i < 8; i++) {                          for (; i < d->nopbytes; i++) {
                         if (count[i] != 0) {                                  snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]);
                                 if (n > 0) {  
                                         milstr_ncat(buf, " + ", sizeof(buf));  
                                 }  
                                 if (count[i] > 1) {  
                                         SPRINTF(tmp, "%s * %d",  
                                             reg32[i], count[i]);  
                                 } else {  
                                         milstr_ncpy(tmp, reg32[i], sizeof(tmp));  
                                 }  
                                 milstr_ncat(buf, tmp, sizeof(buf));                                  milstr_ncat(buf, tmp, sizeof(buf));
                                 n++;                                  if ((i % 8) == 7) {
                                           VERBOSE(("             : %s", buf));
                                           buf[0] = '\0';
                                   }
                         }                          }
                 }                          if ((i % 8) != 0) {
                 if (count[8] != 0) {                                  VERBOSE(("             : %s", buf));
                         if (n > 0) {  
                                 milstr_ncat(buf, " + ", sizeof(buf));  
                         }                          }
                         SPRINTF(tmp, "0x%08x", count[8]);  
                         milstr_ncat(buf, tmp, sizeof(buf));  
                 }                  }
         }          }
         fprintf(fp, "[%s]", buf);          ctx[ctx_index].opbytes = 0;
   
         return eip;  
 }  
   
 void  
 close_instruction_trace(void)  
 {  
   
         if (fp) {  
                 fclose(fp);  
                 fp = NULL;  
         }  
 }  
 #endif  #endif
   
 #define MAX_PREFIX      8  #if defined(IA32_SUPPORT_DEBUG_REGISTER)
           if (CPU_STAT_BP && !(CPU_EFLAG & RF_FLAG)) {
 jmp_buf exec_1step_jmpbuf;                  int i;
                   for (i = 0; i < CPU_DEBUG_REG_INDEX_NUM; i++) {
 void                          if ((CPU_STAT_BP & (1 << i))
 exec_1step(void)                           && (CPU_DR7_GET_RW(i) == CPU_DR7_RW_CODE)
 {                           && (CPU_DR(i) == CPU_EIP)
         int prefix;                           && (CPU_DR7_GET_LEN(i) == 0)) {
         BYTE op;                                  CPU_DR6 |= CPU_DR6_B(i);
                                   EXCEPTION(DB_EXCEPTION, 0);
         CPU_PREV_EIP = CPU_EIP;                          }
                   }
         CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default;  
   
 #ifdef  IA32_INSTRUCTION_TRACE  
 {  
         BYTE opcode[MAX_PREFIX + 1];  
         DWORD eip = CPU_EIP;  
         int num = 0;  
         int i;  
         BOOL t = cpu_inst_trace;  
   
         if ((fp == NULL) && t) {  
                 fp = fopen("ia32trace.txt", "a");  
         }  
         if (fp && t) {  
                 fprintf(fp, "%04x:%08x:", CPU_CS, eip);  
         }          }
 #endif  #endif  /* IA32_SUPPORT_DEBUG_REGISTER */
   
         for (prefix = 0; prefix < MAX_PREFIX; prefix++) {          for (prefix = 0; prefix < MAX_PREFIX; prefix++) {
                 GET_PCBYTE(op);                  GET_PCBYTE(op);
   #if defined(IA32_INSTRUCTION_TRACE)
 #ifdef  IA32_INSTRUCTION_TRACE                  ctx[ctx_index].op[prefix] = op;
                 eip++;                  ctx[ctx_index].opbytes++;
                 if (fp && t) {  
                         opcode[num++] = op;  
                         fprintf(fp, " %02x", op);  
                 }  
 #endif  #endif
   
                 /* prefix */                  /* prefix */
                 if (insttable_info[op] & INST_PREFIX) {                  if (insttable_info[op] & INST_PREFIX) {
                         PROFILE_INC_INST_1BYTE(op);  
                         (*insttable_1byte[0][op])();                          (*insttable_1byte[0][op])();
                         continue;                          continue;
                 }                  }
Line 683  exec_1step(void) Line 145  exec_1step(void)
         if (prefix == MAX_PREFIX) {          if (prefix == MAX_PREFIX) {
                 EXCEPTION(UD_EXCEPTION, 0);                  EXCEPTION(UD_EXCEPTION, 0);
         }          }
         PROFILE_INC_INST_1BYTE(op);  
   
 #ifdef  IA32_INSTRUCTION_TRACE  
         if (fp && t) {  
                 BYTE op2 = 0;  
                 if ((op == 0x0f)  
                  || (op >= 0x80 && op <= 0x83)  
                  || (op >= 0xc0 && op <= 0xc1)  
                  || (op >= 0xd0 && op <= 0xd3)  
                  || (op >= 0xf6 && op <= 0xf7)  
                  || (op >= 0xfe /* && op <= 0xff */)  
                 ) {  
                         op2 = cpu_codefetch(eip);  
                         eip++;  
                         fprintf(fp, " %02x", op2);  
                 }  
   
                 fprintf(fp, "\t\t");  
                 for (i = 0; i < num; i++) {  
                         BYTE c = opcode[i];  
                         const char *p = opcode_1byte[CPU_INST_OP32][c];  
                         if (p) {  
                                 fprintf(fp, "%s ", p);  
                         } else {  
                                 BYTE t = (op2 >> 3) & 7;  
   
                                 switch (c) {  #if defined(IA32_INSTRUCTION_TRACE)
                                 case 0x80: case 0x81: case 0x82: case 0x83:          if (op == 0x0f) {
                                         p = opcode_0x8x[CPU_INST_OP32][c&1][t];                  BYTE op2;
                                         break;                  op2 = cpu_codefetch(CPU_EIP);
                   ctx[ctx_index].op[prefix + 1] = op2;
                                 case 0xc0: case 0xc1:                  ctx[ctx_index].opbytes++;
                                 case 0xd0: case 0xd1: case 0xd2: case 0xd3:  
                                         p = opcode_shift[CPU_INST_OP32][c&1][t];  
                                         break;  
   
                                 case 0xf6:  
                                 case 0xf7:  
                                         p = opcode_0xf6[CPU_INST_OP32][c&1][t];  
                                         break;  
   
                                 case 0xfe:  
                                 case 0xff:  
                                         p = opcode_0xfe[CPU_INST_OP32][c&1][t];  
                                         break;  
                                 }  
                                 if (p) {  
                                         fprintf(fp, "%s ", p);  
                                 }  
                         }  
                 }  
                 if (op == 0x0f) {  
                         const char *p = opcode_2byte[CPU_INST_OP32][op2];  
                         if (p) {  
                                 fprintf(fp, "%s ", p);  
                         } else {  
                                 BYTE t;  
   
                                 t = cpu_codefetch(eip);  
                                 eip++;  
                                 t = (t >> 3) & 7;  
   
                                 switch (op2) {  
                                 case 0x00:  
                                         p = opcode2_g6[t];  
                                         break;  
   
                                 case 0x01:  
                                         p = opcode2_g7[t];  
                                         break;  
   
                                 case 0xba:  
                                         p = opcode2_g8[t];  
                                         break;  
   
                                 case 0xc7:  
                                         p = opcode2_g9[t];  
                                         break;  
                                 }  
                                 if (p) {  
                                         fprintf(fp, "%s ", p);  
                                 }  
                         }  
                 }  
                 fprintf(fp, "\n");  
         }  
 #if 0  
         if (fp) {  
                 fclose(fp);  
                 fp = NULL;  
         }          }
 #endif          ctx_index = (ctx_index + 1) % NELEMENTS(ctx);
 }  
 #endif  #endif
   
         /* normal / rep, but not use */          /* normal / rep, but not use */
         if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) {          if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) {
                 (*insttable_1byte[CPU_INST_OP32][op])();                  (*insttable_1byte[CPU_INST_OP32][op])();
   #if defined(IA32_SUPPORT_DEBUG_REGISTER)
                   goto check_break_point;
   #else
                 return;                  return;
   #endif
         }          }
   
         /* rep */          /* rep */
Line 790  exec_1step(void) Line 172  exec_1step(void)
                 if (CPU_CX != 0) {                  if (CPU_CX != 0) {
                         if (!(insttable_info[op] & REP_CHECKZF)) {                          if (!(insttable_info[op] & REP_CHECKZF)) {
                                 /* rep */                                  /* rep */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_CX);                                          if (--CPU_CX == 0)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else if (CPU_INST_REPUSE != 0xf2) {                          } else if (CPU_INST_REPUSE != 0xf2) {
                                 /* repe */                                  /* repe */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_CX && (CPU_FLAGL & Z_FLAG));                                          if (--CPU_CX == 0 || CC_NZ)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else {                          } else {
                                 /* repne */                                  /* repne */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_CX && !(CPU_FLAGL & Z_FLAG));                                          if (--CPU_CX == 0 || CC_Z)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         }                          }
                 }                  }
         } else {          } else {
                 if (CPU_ECX != 0) {                  if (CPU_ECX != 0) {
                         if (!(insttable_info[op] & REP_CHECKZF)) {                          if (!(insttable_info[op] & REP_CHECKZF)) {
                                 /* rep */                                  /* rep */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_ECX);                                          if (--CPU_ECX == 0)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else if (CPU_INST_REPUSE != 0xf2) {                          } else if (CPU_INST_REPUSE != 0xf2) {
                                 /* repe */                                  /* repe */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_ECX && (CPU_FLAGL & Z_FLAG));                                          if (--CPU_ECX == 0 || CC_NZ)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         } else {                          } else {
                                 /* repne */                                  /* repne */
                                 do {                                  for (;;) {
                                         (*insttable_1byte[CPU_INST_OP32][op])();                                          (*insttable_1byte[CPU_INST_OP32][op])();
                                 } while (--CPU_ECX && !(CPU_FLAGL & Z_FLAG));                                          if (--CPU_ECX == 0 || CC_Z)
                                                   break;
                                           if (CPU_REMCLOCK <= 0) {
                                                   CPU_EIP = CPU_PREV_EIP;
                                                   break;
                                           }
                                   }
                         }                          }
                 }                  }
         }          }
   
   #if defined(IA32_SUPPORT_DEBUG_REGISTER)
   check_break_point:
           if (CPU_TRAP || (CPU_STAT_BP_EVENT & ~CPU_STAT_BP_EVENT_RF)) {
                   UINT8 orig = CPU_STAT_BP_EVENT & ~CPU_STAT_BP_EVENT_RF;
   
                   CPU_STAT_BP_EVENT &= CPU_STAT_BP_EVENT_RF;
   
                   CPU_DR6 |= (orig & 0xf);
                   if (orig & CPU_STAT_BP_EVENT_TASK) {
                           CPU_DR6 |= CPU_DR6_BT;
                   }
                   if (CPU_TRAP) {
                           CPU_DR6 |= CPU_DR6_BS;
                   }
                   INTERRUPT(DB_EXCEPTION, TRUE, FALSE, 0);
           }
           if (CPU_EFLAG & RF_FLAG) {
                   if (CPU_STAT_BP_EVENT & CPU_STAT_BP_EVENT_RF) {
                           /* after IRETD or task switch */
                           CPU_STAT_BP_EVENT &= ~CPU_STAT_BP_EVENT_RF;
                   } else {
                           CPU_EFLAG &= ~RF_FLAG;
                   }
           }
   #endif  /* IA32_SUPPORT_DEBUG_REGISTER */
 }  }

Removed from v.1.6  
changed lines
  Added in v.1.23


RetroPC.NET-CVS <cvs@retropc.net>