--- np2/i386c/ia32/cpu.c 2004/03/07 02:10:24 1.15 +++ np2/i386c/ia32/cpu.c 2005/03/03 06:59:41 1.23 @@ -1,4 +1,4 @@ -/* $Id: cpu.c,v 1.15 2004/03/07 02:10:24 yui Exp $ */ +/* $Id: cpu.c,v 1.23 2005/03/03 06:59:41 yui Exp $ */ /* * Copyright (c) 2002-2003 NONAKA Kimihiro @@ -34,6 +34,10 @@ #include "inst_table.h" +#if defined(ENABLE_TRAP) +#include "steptrap.h" +#endif + sigjmp_buf exec_1step_jmpbuf; @@ -55,41 +59,6 @@ int cpu_inst_trace = 0; #endif -// #define IPTRACE (1 << 14) - -#if defined(TRACE) && IPTRACE -static UINT trpos = 0; -static UINT32 trcs[IPTRACE]; -static UINT32 treip[IPTRACE]; - -void iptrace_out(void) { - - FILEH fh; - UINT s; - UINT32 cs; - UINT32 eip; - char buf[32]; - - s = trpos; - if (s > IPTRACE) { - s -= IPTRACE; - } - else { - s = 0; - } - fh = file_create_c("his.txt"); - while(s < trpos) { - cs = trcs[s & (IPTRACE - 1)]; - eip = treip[s & (IPTRACE - 1)]; - s++; - SPRINTF(buf, "%.4x:%.8x\r\n", cs, eip); - file_write(fh, buf, strlen(buf)); - } - file_close(fh); -} -#endif - - void exec_1step(void) { @@ -99,10 +68,8 @@ exec_1step(void) CPU_PREV_EIP = CPU_EIP; CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; -#if defined(TRACE) && IPTRACE - trcs[trpos & (IPTRACE - 1)] = CPU_CS; - treip[trpos & (IPTRACE - 1)] = CPU_EIP; - trpos++; +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_EIP); #endif #if defined(IA32_INSTRUCTION_TRACE) @@ -145,6 +112,22 @@ exec_1step(void) } ctx[ctx_index].opbytes = 0; #endif + +#if defined(IA32_SUPPORT_DEBUG_REGISTER) + if (CPU_STAT_BP && !(CPU_EFLAG & RF_FLAG)) { + int i; + for (i = 0; i < CPU_DEBUG_REG_INDEX_NUM; i++) { + if ((CPU_STAT_BP & (1 << i)) + && (CPU_DR7_GET_RW(i) == CPU_DR7_RW_CODE) + && (CPU_DR(i) == CPU_EIP) + && (CPU_DR7_GET_LEN(i) == 0)) { + CPU_DR6 |= CPU_DR6_B(i); + EXCEPTION(DB_EXCEPTION, 0); + } + } + } +#endif /* IA32_SUPPORT_DEBUG_REGISTER */ + for (prefix = 0; prefix < MAX_PREFIX; prefix++) { GET_PCBYTE(op); #if defined(IA32_INSTRUCTION_TRACE) @@ -176,7 +159,11 @@ exec_1step(void) /* normal / rep, but not use */ if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { (*insttable_1byte[CPU_INST_OP32][op])(); +#if defined(IA32_SUPPORT_DEBUG_REGISTER) + goto check_break_point; +#else return; +#endif } /* rep */ @@ -185,39 +172,101 @@ exec_1step(void) 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) + 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) + 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) + 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) + 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) + 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) + 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 */ }