--- np2/i386c/ia32/cpu.c 2003/12/08 00:55:31 1.1 +++ np2/i386c/ia32/cpu.c 2003/12/22 18:00:31 1.2 @@ -1,4 +1,4 @@ -/* $Id: cpu.c,v 1.1 2003/12/08 00:55:31 yui Exp $ */ +/* $Id: cpu.c,v 1.2 2003/12/22 18:00:31 monaka Exp $ */ /* * Copyright (c) 2002-2003 NONAKA Kimihiro @@ -33,27 +33,199 @@ #include "inst_table.h" +#if defined(IA32_PROFILE_INSTRUCTION) +UINT32 inst_1byte_count[2][256]; +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 + +#define MAX_PREFIX 8 + jmp_buf exec_1step_jmpbuf; void exec_1step(void) { BYTE op; + BYTE prefix; CPU_PREV_EIP = CPU_EIP; - cpu_inst = cpu_inst_default; + CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; - for (;;) { + for (prefix = 0; prefix < MAX_PREFIX; prefix++) { GET_PCBYTE(op); /* prefix */ if (insttable_info[op] & INST_PREFIX) { + PROFILE_INC_INST_1BYTE(op); (*insttable_1byte[0][op])(); continue; } break; } + if (prefix == MAX_PREFIX) { + EXCEPTION(UD_EXCEPTION, 0); + } + PROFILE_INC_INST_1BYTE(op); /* normal / rep, but not use */ if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) {