--- np2/i386c/ia32/cpu.c 2004/01/23 14:33:26 1.7 +++ np2/i386c/ia32/cpu.c 2012/01/08 11:36:05 1.28 @@ -1,5 +1,3 @@ -/* $Id: cpu.c,v 1.7 2004/01/23 14:33:26 monaka Exp $ */ - /* * Copyright (c) 2002-2003 NONAKA Kimihiro * All rights reserved. @@ -12,8 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -28,473 +24,101 @@ */ #include "compiler.h" +#include "dosio.h" #include "cpu.h" #include "ia32.mcr" #include "inst_table.h" +#if defined(ENABLE_TRAP) +#include "steptrap.h" +#endif -#if defined(IA32_INSTRUCTION_TRACE) -static FILE *fp = NULL; -BOOL cpu_inst_trace = FALSE; - -static const char *opcode_1byte[2][256] = { -/* 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*/ "pushad","popad", "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", "iretd", -/*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] = { -/* 16bit */ -{ -/*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", "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] = { -/* 16bit */ -{ - { "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] = { -/* 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" } -}, -}; +sigjmp_buf exec_1step_jmpbuf; -static const char *opcode_0xf6[2][2][8] = { -/* 16bit */ -{ - { "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" } -}, -}; +#if defined(IA32_INSTRUCTION_TRACE) +typedef struct { + CPU_REGS regs; + disasm_context_t disasm; -static const char *opcode_0xfe[2][2][8] = { -/* 16bit */ -{ - { "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 } -} -}; + BYTE op[MAX_PREFIX + 2]; + int opbytes; +} ia32_context_t; -static const char *opcode2_g6[8] = { - "sldt", "str", "lldt", "ltr", "verr", "verw", NULL, NULL -}; +#define NCTX 1024 -static const char *opcode2_g7[8] = { - "sgdt", "sidt", "lgdt", "lidt", "smsw", NULL, "lmsw", "invlpg" -}; +ia32_context_t ctx[NCTX]; +int ctx_index = 0; -static const char *opcode2_g8[8] = { - NULL, NULL, NULL, NULL, "bt", "bts", "btr", "btc" -}; +int cpu_inst_trace = 0; +#endif -static const char *opcode2_g9[8] = { - NULL, "cmpxchg8b", NULL, NULL, NULL, NULL, NULL, NULL -}; +#if defined(DEBUG) +int cpu_debug_rep_cont = 0; +CPU_REGS cpu_debug_rep_regs; +#endif -static DWORD -ea(DWORD eip, DWORD op) +void +exec_1step(void) { - static const char *ea16[8] = { - "bx + si", "bx + di", "bp + si", "bp + di", - "si", "di", "bp", "bx" - }; - - char buf[256]; - DWORD mod = (op >> 6) & 3; - DWORD rm = op & 7; - DWORD val; - - __ASSERT(mod != 3); + int prefix; + UINT32 op; - buf[0] = '\0'; + CPU_PREV_EIP = CPU_EIP; + CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; - 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)); - - if (rm == 5) { - DWORD sib; - DWORD scale; - 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 defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_EIP); +#endif - if (rm == 6 && mod == 0) { - /* disp32 */ - val = cpu_codefetch_d(eip); - eip += 4; - count[8] += val; - } else { - if (mod == 1) { - /* disp8 */ - val = cpu_codefetch(eip); - eip++; - if (val & 0x80) { - val |= 0xffffff00; - } - count[8] += val; - } else if (mod == 2) { - /* disp32 */ - val = cpu_codefetch_d(eip); - eip += 4; - count[8] += val; +#if defined(IA32_INSTRUCTION_TRACE) + ctx[ctx_index].regs = CPU_STATSAVE.cpu_regs; + if (cpu_inst_trace) { + disasm_context_t *d = &ctx[ctx_index].disasm; + UINT32 eip = CPU_EIP; + int rv; + + rv = disasm(&eip, d); + if (rv == 0) { + char buf[256]; + char tmp[32]; + int len = d->nopbytes > 8 ? 8 : d->nopbytes; + int i; + + buf[0] = '\0'; + for (i = 0; i < len; i++) { + snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); + milstr_ncat(buf, tmp, sizeof(buf)); } - if (rm != 5) { - count[rm]++; + for (; i < 8; i++) { + milstr_ncat(buf, " ", sizeof(buf)); } - } + VERBOSE(("%04x:%08x: %s%s", CPU_CS, CPU_EIP, buf, d->str)); - n = 0; - for (i = 0; i < 8; i++) { - if (count[i] != 0) { - if (n > 0) { - milstr_ncat(buf, " + ", sizeof(buf)); - } - if (count[i] > 1) { - SPRINTF(tmp, "%s * %d", - reg32_str[i], count[i]); - } else { - milstr_ncpy(tmp, reg32_str[i], sizeof(tmp)); - } + buf[0] = '\0'; + for (; i < d->nopbytes; i++) { + snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); milstr_ncat(buf, tmp, sizeof(buf)); - n++; + if ((i % 8) == 7) { + VERBOSE((" : %s", buf)); + buf[0] = '\0'; + } } - } - if (count[8] != 0) { - if (n > 0) { - milstr_ncat(buf, " + ", sizeof(buf)); + if ((i % 8) != 0) { + VERBOSE((" : %s", buf)); } - SPRINTF(tmp, "0x%08x", count[8]); - milstr_ncat(buf, tmp, sizeof(buf)); } } - fprintf(fp, "[%s]", buf); - - return eip; -} - -void -close_instruction_trace(void) -{ - - if (fp) { - fclose(fp); - fp = NULL; - } -} -#endif /* IA32_INSTRUCTION_TRACE */ - - -jmp_buf exec_1step_jmpbuf; - -void -exec_1step(void) -{ - int prefix; - BYTE op; - - 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); - } + ctx[ctx_index].opbytes = 0; #endif for (prefix = 0; prefix < MAX_PREFIX; prefix++) { GET_PCBYTE(op); - -#ifdef IA32_INSTRUCTION_TRACE - eip++; - if (fp && t) { - opcode[num++] = op; - fprintf(fp, " %02x", op); - } +#if defined(IA32_INSTRUCTION_TRACE) + ctx[ctx_index].op[prefix] = op; + ctx[ctx_index].opbytes++; #endif /* prefix */ @@ -508,146 +132,129 @@ exec_1step(void) EXCEPTION(UD_EXCEPTION, 0); } -#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) { - case 0x80: case 0x81: case 0x82: case 0x83: - p = opcode_0x8x[CPU_INST_OP32][c&1][t]; - break; - - case 0xc0: case 0xc1: - 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); - } - } - } - - /* arg */ - switch (op) { - case 0xcd: - op2 = cpu_codefetch(eip); - eip++; - fprintf(fp, "%02xh", op2); - break; - } - fprintf(fp, "\n"); +#if defined(IA32_INSTRUCTION_TRACE) + if (op == 0x0f) { + BYTE op2; + op2 = cpu_codefetch(CPU_EIP); + ctx[ctx_index].op[prefix + 1] = op2; + ctx[ctx_index].opbytes++; } -} + ctx_index = (ctx_index + 1) % NELEMENTS(ctx); #endif /* normal / rep, but not use */ if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif (*insttable_1byte[CPU_INST_OP32][op])(); return; } /* rep */ CPU_WORKCLOCK(5); +#if defined(DEBUG) + if (!cpu_debug_rep_cont) { + cpu_debug_rep_cont = 1; + cpu_debug_rep_regs = CPU_STATSAVE.cpu_regs; + } +#endif if (!CPU_INST_AS32) { if (CPU_CX != 0) { if (!(insttable_info[op] & REP_CHECKZF)) { /* rep */ - do { + for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); - } while (--CPU_CX); + if (--CPU_CX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } } else if (CPU_INST_REPUSE != 0xf2) { /* repe */ - do { + for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); - } while (--CPU_CX && (CPU_FLAGL & Z_FLAG)); + if (--CPU_CX == 0 || CC_NZ) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } } else { /* repne */ - do { + for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); - } while (--CPU_CX && !(CPU_FLAGL & Z_FLAG)); + if (--CPU_CX == 0 || CC_Z) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } } } } else { if (CPU_ECX != 0) { if (!(insttable_info[op] & REP_CHECKZF)) { /* rep */ - do { + for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); - } while (--CPU_ECX); + if (--CPU_ECX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } } else if (CPU_INST_REPUSE != 0xf2) { /* repe */ - do { + for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); - } while (--CPU_ECX && (CPU_FLAGL & Z_FLAG)); + if (--CPU_ECX == 0 || CC_NZ) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } } else { /* repne */ - do { + for (;;) { (*insttable_1byte[CPU_INST_OP32][op])(); - } while (--CPU_ECX && !(CPU_FLAGL & Z_FLAG)); + if (--CPU_ECX == 0 || CC_Z) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } } } }