Diff for /np2/i386c/ia32/cpu.c between versions 1.2 and 1.25

version 1.2, 2003/12/22 18:00:31 version 1.25, 2008/03/22 04:03:07
Line 12 Line 12
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    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   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 28 Line 26
  */   */
   
 #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];  #endif
 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));  sigjmp_buf exec_1step_jmpbuf;
         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  #if defined(IA32_INSTRUCTION_TRACE)
 show_profile_inst(void)  typedef struct {
 {          CPU_REGS                regs;
         int i;          disasm_context_t        disasm;
   
         printf("instruction (16bit)\n");          BYTE                    op[MAX_PREFIX + 2];
         for (i = 0; i < 256; i++) {          int                     opbytes;
                 if (inst_1byte_count[0][i] != 0) {  } ia32_context_t;
                         printf("0x%02x: %d\n", i, inst_1byte_count[0][i]);  
                 }  #define NCTX    1024
         }  
         for (i = 0; i < 256; i++) {  ia32_context_t ctx[NCTX];
                 if (inst_2byte_count[0][i] != 0) {  int ctx_index = 0;
                         printf("0x0f%02x: %d\n", i, inst_2byte_count[0][i]);  
                 }  int cpu_inst_trace = 0;
         }  #endif
   
         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  void
 show_profile_ea(void)  exec_1step(void)
 {  {
         char buf[80];          int prefix;
         char tmp[80];          UINT32 op;
         int i;  
         int t;          CPU_PREV_EIP = CPU_EIP;
           CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default;
         printf("EA16\n");  
         for (i = 0; i < NELEMENTS(ea16_count); i++) {  #if defined(ENABLE_TRAP)
                 if (ea16_count[i] != 0) {          steptrap(CPU_CS, CPU_EIP);
                         printf("%s: %d\n", ea16_str[i], ea16_count[i]);  #endif
                 }  
         }  #if defined(IA32_INSTRUCTION_TRACE)
         printf("EA32\n");          ctx[ctx_index].regs = CPU_STATSAVE.cpu_regs;
         for (i = 0; i < NELEMENTS(ea32_count); i++) {          if (cpu_inst_trace) {
                 if (ea32_count[i] != 0) {                  disasm_context_t *d = &ctx[ctx_index].disasm;
                         printf("%s: %d\n", ea32_str[i], ea32_count[i]);                  UINT32 eip = CPU_EIP;
                 }                  int rv;
         }  
         printf("SIB0\n");                  rv = disasm(&eip, d);
         for (i = 0; i < NELEMENTS(sib0_count); i++) {                  if (rv == 0) {
                 if (sib0_count[i] != 0) {                          char buf[256];
                         sprintf(tmp, "%s", sib0_base_str[i & 7]);                          char tmp[32];
                         strcpy(buf, tmp);                          int len = d->nopbytes > 8 ? 8 : d->nopbytes;
                         t = (i >> 3) & 7;                          int i;
                         if (t != 4) {  
                                 sprintf(tmp, " + %s", sib_index_str[t]);                          buf[0] = '\0';
                                 strcat(buf, tmp);                          for (i = 0; i < len; i++) {
                                   snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]);
                                   milstr_ncat(buf, tmp, sizeof(buf));
                         }                          }
                         t = (i >> 6) & 3;                          for (; i < 8; i++) {
                         if (t != 0) {                                  milstr_ncat(buf, "   ", sizeof(buf));
                                 sprintf(tmp, " * %s", sib_scale_str[t]);  
                                 strcat(buf, tmp);  
                         }                          }
                         printf("%s: %d\n", buf, sib0_count[i]);                          VERBOSE(("%04x:%08x: %s%s", CPU_CS, CPU_EIP, buf, d->str));
                 }  
         }                          buf[0] = '\0';
         printf("SIB1\n");                          for (; i < d->nopbytes; i++) {
         for (i = 0; i < NELEMENTS(sib1_count); i++) {                                  snprintf(tmp, sizeof(tmp), "%02x ", d->opcode[i]);
                 if (sib1_count[i] != 0) {                                  milstr_ncat(buf, tmp, sizeof(buf));
                         sprintf(tmp, "%s", sib1_base_str[i & 7]);                                  if ((i % 8) == 7) {
                         strcpy(buf, tmp);                                          VERBOSE(("             : %s", buf));
                         t = (i >> 3) & 7;                                          buf[0] = '\0';
                         if (t != 4) {                                  }
                                 sprintf(tmp, " + %s", sib_index_str[t]);  
                                 strcat(buf, tmp);  
                         }                          }
                         t = (i >> 6) & 3;                          if ((i % 8) != 0) {
                         if (t != 0) {                                  VERBOSE(("             : %s", buf));
                                 sprintf(tmp, " * %s", sib_scale_str[t]);  
                                 strcat(buf, tmp);  
                         }                          }
                         printf("%s + DISP8: %d\n", buf, sib1_count[i]);  
                 }                  }
         }          }
         printf("SIB2\n");          ctx[ctx_index].opbytes = 0;
         for (i = 0; i < NELEMENTS(sib2_count); i++) {  #endif
                 if (sib2_count[i] != 0) {  
                         sprintf(tmp, "%s", sib1_base_str[i & 7]);  #if defined(IA32_SUPPORT_DEBUG_REGISTER)
                         strcpy(buf, tmp);          if (CPU_STAT_BP && !(CPU_EFLAG & RF_FLAG)) {
                         t = (i >> 3) & 7;                  int i;
                         if (t != 4) {                  for (i = 0; i < CPU_DEBUG_REG_INDEX_NUM; i++) {
                                 sprintf(tmp, " + %s", sib_index_str[t]);                          if ((CPU_STAT_BP & (1 << i))
                                 strcat(buf, tmp);                           && (CPU_DR7_GET_RW(i) == CPU_DR7_RW_CODE)
                         }                           && (CPU_DR(i) == CPU_EIP)
                         t = (i >> 6) & 3;                           && (CPU_DR7_GET_LEN(i) == 0)) {
                         if (t != 0) {                                  CPU_DR6 |= CPU_DR6_B(i);
                                 sprintf(tmp, " * %s", sib_scale_str[t]);                                  EXCEPTION(DB_EXCEPTION, 0);
                                 strcat(buf, tmp);  
                         }                          }
                         printf("%s + DISP32: %d\n", buf, sib2_count[i]);  
                 }                  }
         }          }
 }  #endif  /* IA32_SUPPORT_DEBUG_REGISTER */
 #endif  
   
 #define MAX_PREFIX      8  
   
 jmp_buf exec_1step_jmpbuf;  
   
 void  
 exec_1step(void)  
 {  
         BYTE op;  
         BYTE prefix;  
   
         CPU_PREV_EIP = CPU_EIP;  
   
         CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default;  
   
         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)
                   ctx[ctx_index].op[prefix] = op;
                   ctx[ctx_index].opbytes++;
   #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 225  exec_1step(void) Line 143  exec_1step(void)
         if (prefix == MAX_PREFIX) {          if (prefix == MAX_PREFIX) {
                 EXCEPTION(UD_EXCEPTION, 0);                  EXCEPTION(UD_EXCEPTION, 0);
         }          }
         PROFILE_INC_INST_1BYTE(op);  
   #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 */          /* 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 239  exec_1step(void) Line 170  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, INTR_TYPE_EXCEPTION);
           }
           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.2  
changed lines
  Added in v.1.25


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