Added MMX emulation (probably some bugs). Implemented RDMSR/WRMSR for Winchip.
This commit is contained in:
parent
cfb4ab27b4
commit
119fe36820
17 changed files with 2362 additions and 65 deletions
|
|
@ -1210,8 +1210,6 @@ void cpu_386_flags_rebuild()
|
|||
|
||||
int oldi;
|
||||
|
||||
static uint64_t tsc = 0;
|
||||
|
||||
uint32_t testr[9];
|
||||
int dontprint=0;
|
||||
|
||||
|
|
|
|||
125
src/386_ops.h
125
src/386_ops.h
|
|
@ -76,6 +76,13 @@ static inline uint32_t POP_L()
|
|||
#include "x86_ops_io.h"
|
||||
#include "x86_ops_jump.h"
|
||||
#include "x86_ops_misc.h"
|
||||
#include "x86_ops_mmx.h"
|
||||
#include "x86_ops_mmx_arith.h"
|
||||
#include "x86_ops_mmx_cmp.h"
|
||||
#include "x86_ops_mmx_logic.h"
|
||||
#include "x86_ops_mmx_mov.h"
|
||||
#include "x86_ops_mmx_pack.h"
|
||||
#include "x86_ops_mmx_shift.h"
|
||||
#include "x86_ops_mov.h"
|
||||
#include "x86_ops_mov_ctrl.h"
|
||||
#include "x86_ops_mov_seg.h"
|
||||
|
|
@ -95,6 +102,8 @@ static inline uint32_t POP_L()
|
|||
static int ILLEGAL(uint32_t fetchdat)
|
||||
{
|
||||
pc = oldpc;
|
||||
|
||||
// fatal("Illegal instruction %08X\n", fetchdat);
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -103,13 +112,20 @@ static int op0F_w_a16(uint32_t fetchdat)
|
|||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
pc++;
|
||||
|
||||
if (x86_opcodes_0f[opcode] == ILLEGAL && opcode != 0xff)
|
||||
{
|
||||
fatal("Illegal 0f instruction %02X w_a16\n", opcode);
|
||||
}
|
||||
return x86_opcodes_0f[opcode](fetchdat >> 8);
|
||||
}
|
||||
static int op0F_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
pc++;
|
||||
if (x86_opcodes_0f[opcode | 0x100] == ILLEGAL && opcode != 0xff)
|
||||
{
|
||||
fatal("Illegal 0f instruction %02X l_a16\n", opcode);
|
||||
}
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8);
|
||||
}
|
||||
|
|
@ -117,6 +133,10 @@ static int op0F_w_a32(uint32_t fetchdat)
|
|||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
pc++;
|
||||
if (x86_opcodes_0f[opcode | 0x200] == ILLEGAL && opcode != 0xff)
|
||||
{
|
||||
fatal("Illegal 0f instruction %02X w_a32\n", opcode);
|
||||
}
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8);
|
||||
}
|
||||
|
|
@ -124,6 +144,10 @@ static int op0F_l_a32(uint32_t fetchdat)
|
|||
{
|
||||
int opcode = fetchdat & 0xff;
|
||||
pc++;
|
||||
if (x86_opcodes_0f[opcode | 0x300] == ILLEGAL && opcode != 0xff)
|
||||
{
|
||||
fatal("Illegal 0f instruction %02X l_a32\n", opcode);
|
||||
}
|
||||
|
||||
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
|
||||
}
|
||||
|
|
@ -232,7 +256,7 @@ OpFn ops_386_0f[1024] =
|
|||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
|
@ -254,7 +278,7 @@ OpFn ops_386_0f[1024] =
|
|||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
|
@ -276,7 +300,7 @@ OpFn ops_386_0f[1024] =
|
|||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
|
@ -298,7 +322,7 @@ OpFn ops_386_0f[1024] =
|
|||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
|
@ -316,6 +340,97 @@ OpFn ops_386_0f[1024] =
|
|||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
};
|
||||
|
||||
OpFn ops_winchip_0f[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,ILLEGAL, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a16,opMOV_r_DRx_a16,opMOV_CRx_r_a16,opMOV_DRx_r_a16,opMOV_r_TRx_a16,opMOV_TRx_r_a16,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a16,opMOVQ_mm_q_a16,
|
||||
|
||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||
/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, opSETNLE_a16,
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16,
|
||||
/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16,
|
||||
/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL,
|
||||
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w,
|
||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,ILLEGAL, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*20*/ opMOV_r_CRx_a32,opMOV_r_DRx_a32,opMOV_CRx_r_a32,opMOV_DRx_r_a32,opMOV_r_TRx_a32,opMOV_TRx_r_a32,ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
|
||||
/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
|
||||
/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
|
||||
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opMOVD_mm_l_a32,opMOVQ_mm_q_a32,
|
||||
|
||||
/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l,
|
||||
/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, opSETNLE_a32,
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32,
|
||||
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
|
||||
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
||||
};
|
||||
|
||||
OpFn ops_286[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
|
|
|
|||
124
src/cpu.c
124
src/cpu.c
|
|
@ -4,6 +4,14 @@
|
|||
#include "io.h"
|
||||
#include "x86_ops.h"
|
||||
|
||||
enum
|
||||
{
|
||||
CPUID_FPU = (1 << 0),
|
||||
CPUID_TSC = (1 << 4),
|
||||
CPUID_MSR = (1 << 5),
|
||||
CPUID_MMX = (1 << 23)
|
||||
};
|
||||
|
||||
int cpu = 3, cpu_manufacturer = 0;
|
||||
CPU *cpu_s;
|
||||
int cpu_multi;
|
||||
|
|
@ -11,6 +19,8 @@ int cpu_iscyrix;
|
|||
int cpu_16bitbus;
|
||||
int cpu_busspeed;
|
||||
int cpu_hasrdtsc;
|
||||
int cpu_hasMMX, cpu_hasMSR;
|
||||
uint64_t tsc = 0;
|
||||
|
||||
int timing_rr;
|
||||
int timing_mr, timing_mrl;
|
||||
|
|
@ -18,6 +28,14 @@ int timing_rm, timing_rml;
|
|||
int timing_mm, timing_mml;
|
||||
int timing_bt, timing_bnt;
|
||||
|
||||
static struct
|
||||
{
|
||||
uint32_t tr1, tr12;
|
||||
uint32_t cesr;
|
||||
uint32_t fcr;
|
||||
uint64_t fcr2, fcr3;
|
||||
} msr;
|
||||
|
||||
/*Available cpuspeeds :
|
||||
0 = 16 MHz
|
||||
1 = 20 MHz
|
||||
|
|
@ -239,6 +257,8 @@ void cpu_set()
|
|||
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
|
||||
cpu_multi = cpu_s->multi;
|
||||
cpu_hasrdtsc = 0;
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 0;
|
||||
|
||||
if (cpu_iscyrix)
|
||||
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
|
||||
|
|
@ -250,6 +270,8 @@ void cpu_set()
|
|||
|
||||
x86_setopcodes(ops_386, ops_386_0f);
|
||||
|
||||
memset(&msr, 0, sizeof(msr));
|
||||
|
||||
switch (cpu_s->cpu_type)
|
||||
{
|
||||
case CPU_8088:
|
||||
|
|
@ -370,6 +392,7 @@ void cpu_set()
|
|||
break;
|
||||
|
||||
case CPU_WINCHIP:
|
||||
x86_setopcodes(ops_386, ops_winchip_0f);
|
||||
timing_rr = 1; /*register dest - register src*/
|
||||
timing_rm = 2; /*register dest - memory src*/
|
||||
timing_mr = 3; /*memory dest - register src*/
|
||||
|
|
@ -380,6 +403,8 @@ void cpu_set()
|
|||
timing_bt = 3-1; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
cpu_hasrdtsc = 1;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = cpu_hasMSR = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -403,7 +428,7 @@ void cpu_CPUID()
|
|||
{
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = 1; /*FPU*/
|
||||
EDX = CPUID_FPU; /*FPU*/
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
|
|
@ -438,7 +463,7 @@ void cpu_CPUID()
|
|||
{
|
||||
EAX = CPUID;
|
||||
EBX = ECX = 0;
|
||||
EDX = 1; /*FPU*/
|
||||
EDX = CPUID_FPU; /*FPU*/
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
|
|
@ -448,15 +473,26 @@ void cpu_CPUID()
|
|||
if (!EAX)
|
||||
{
|
||||
EAX = 1;
|
||||
EBX = 0x746e6543; /*CentaurHauls*/
|
||||
ECX = 0x736c7561;
|
||||
EDX = 0x48727561;
|
||||
if (msr.fcr2 & (1 << 14))
|
||||
{
|
||||
EBX = msr.fcr3 >> 32;
|
||||
ECX = msr.fcr3 & 0xffffffff;
|
||||
EDX = msr.fcr2 >> 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
EBX = 0x746e6543; /*CentaurHauls*/
|
||||
ECX = 0x736c7561;
|
||||
EDX = 0x48727561;
|
||||
}
|
||||
}
|
||||
else if (EAX == 1)
|
||||
{
|
||||
EAX = CPUID;
|
||||
EAX = 0x540;
|
||||
EBX = ECX = 0;
|
||||
EDX = 1; /*FPU*/
|
||||
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
|
||||
if (msr.fcr & (1 << 9))
|
||||
EDX |= CPUID_MMX;
|
||||
}
|
||||
else
|
||||
EAX = 0;
|
||||
|
|
@ -464,6 +500,80 @@ void cpu_CPUID()
|
|||
}
|
||||
}
|
||||
|
||||
void cpu_RDMSR()
|
||||
{
|
||||
switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
|
||||
{
|
||||
case CPU_WINCHIP:
|
||||
EAX = EDX = 0;
|
||||
switch (ECX)
|
||||
{
|
||||
case 0x02:
|
||||
EAX = msr.tr1;
|
||||
break;
|
||||
case 0x0e:
|
||||
EAX = msr.tr12;
|
||||
break;
|
||||
case 0x10:
|
||||
EAX = tsc & 0xffffffff;
|
||||
EDX = tsc >> 32;
|
||||
break;
|
||||
case 0x11:
|
||||
EAX = msr.cesr;
|
||||
break;
|
||||
case 0x107:
|
||||
EAX = msr.fcr;
|
||||
break;
|
||||
case 0x108:
|
||||
EAX = msr.fcr2 & 0xffffffff;
|
||||
EDX = msr.fcr2 >> 32;
|
||||
break;
|
||||
case 0x10a:
|
||||
EAX = cpu_multi & 3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_WRMSR()
|
||||
{
|
||||
switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
|
||||
{
|
||||
case CPU_WINCHIP:
|
||||
EAX = EDX = 0;
|
||||
switch (ECX)
|
||||
{
|
||||
case 0x02:
|
||||
msr.tr1 = EAX & 2;
|
||||
break;
|
||||
case 0x0e:
|
||||
msr.tr12 = EAX & 0x228;
|
||||
break;
|
||||
case 0x10:
|
||||
tsc = EAX | ((uint64_t)EDX << 32);
|
||||
break;
|
||||
case 0x11:
|
||||
msr.cesr = EAX & 0xff00ff;
|
||||
break;
|
||||
case 0x107:
|
||||
msr.fcr = EAX;
|
||||
cpu_hasMMX = EAX & (1 << 9);
|
||||
if (EAX & (1 << 29))
|
||||
CPUID = 0;
|
||||
else
|
||||
CPUID = models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model;
|
||||
break;
|
||||
case 0x108:
|
||||
msr.fcr2 = EAX | ((uint64_t)EDX << 32);
|
||||
break;
|
||||
case 0x109:
|
||||
msr.fcr3 = EAX | ((uint64_t)EDX << 32);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int cyrix_addr;
|
||||
|
||||
|
|
|
|||
|
|
@ -71,8 +71,15 @@ extern int cpu_busspeed;
|
|||
extern int cpu_multi;
|
||||
|
||||
extern int cpu_hasrdtsc;
|
||||
extern int cpu_hasMSR;
|
||||
extern int cpu_hasMMX;
|
||||
|
||||
extern uint64_t tsc;
|
||||
|
||||
void cyrix_write(uint16_t addr, uint8_t val, void *priv);
|
||||
uint8_t cyrix_read(uint16_t addr, void *priv);
|
||||
|
||||
extern int is8086;
|
||||
|
||||
void cpu_RDMSR();
|
||||
void cpu_WRMSR();
|
||||
|
|
|
|||
|
|
@ -10,3 +10,5 @@ extern OpFn ops_286_0f[1024];
|
|||
|
||||
extern OpFn ops_386[1024];
|
||||
extern OpFn ops_386_0f[1024];
|
||||
|
||||
extern OpFn ops_winchip_0f[1024];
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
static int opESCAPE_ ## num ##_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
flags_rebuild(); \
|
||||
if ((cr0 & 6) == 4) \
|
||||
if (cr0 & 0xc) \
|
||||
{ \
|
||||
x86_int(7); \
|
||||
} \
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
static int opESCAPE_ ## num ## _a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
flags_rebuild(); \
|
||||
if ((cr0 & 6) == 4) \
|
||||
if (cr0 & 0xc) \
|
||||
{ \
|
||||
x86_int(7); \
|
||||
} \
|
||||
|
|
@ -55,6 +55,11 @@ opESCAPE(df);
|
|||
|
||||
static int opWAIT(uint32_t fetchdat)
|
||||
{
|
||||
if ((cr0 & 0xa) == 0xa)
|
||||
{
|
||||
x86_int(7);
|
||||
return 0;
|
||||
}
|
||||
cycles -= 4;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -675,4 +675,29 @@ static int opCPUID(uint32_t fetchdat)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int opRDMSR(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_hasMSR)
|
||||
{
|
||||
cpu_RDMSR();
|
||||
cycles -= 9;
|
||||
return 0;
|
||||
}
|
||||
pc = oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opWRMSR(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_hasMSR)
|
||||
{
|
||||
cpu_WRMSR();
|
||||
cycles -= 9;
|
||||
return 0;
|
||||
}
|
||||
pc = oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
49
src/x86_ops_mmx.h
Normal file
49
src/x86_ops_mmx.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val)))
|
||||
#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val)))
|
||||
#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val)))
|
||||
#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val)))
|
||||
|
||||
#define MMX_GETSRC() \
|
||||
if (mod == 3) \
|
||||
{ \
|
||||
src = MM[rm]; \
|
||||
cycles--; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
src.l[0] = readmeml(easeg, eaaddr); \
|
||||
src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; \
|
||||
cycles -= 2; \
|
||||
}
|
||||
|
||||
#define MMX_ENTER() \
|
||||
if (!cpu_hasMMX) \
|
||||
{ \
|
||||
pc = oldpc; \
|
||||
x86illegal(); \
|
||||
return 0; \
|
||||
} \
|
||||
if (cr0 & 0xc) \
|
||||
{ \
|
||||
x86_int(7); \
|
||||
return 0; \
|
||||
} \
|
||||
x87_set_mmx()
|
||||
|
||||
int opEMMS(uint32_t fetchdat)
|
||||
{
|
||||
if (!cpu_hasMMX)
|
||||
{
|
||||
pc = oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
if (cr0 & 4)
|
||||
{
|
||||
x86_int(7);
|
||||
return 0;
|
||||
}
|
||||
x87_emms();
|
||||
cycles -= 100; /*Guess*/
|
||||
return 0;
|
||||
}
|
||||
625
src/x86_ops_mmx_arith.h
Normal file
625
src/x86_ops_mmx_arith.h
Normal file
|
|
@ -0,0 +1,625 @@
|
|||
int opPADDB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] += src.b[0];
|
||||
MM[reg].b[1] += src.b[1];
|
||||
MM[reg].b[2] += src.b[2];
|
||||
MM[reg].b[3] += src.b[3];
|
||||
MM[reg].b[4] += src.b[4];
|
||||
MM[reg].b[5] += src.b[5];
|
||||
MM[reg].b[6] += src.b[6];
|
||||
MM[reg].b[7] += src.b[7];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPADDB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] += src.b[0];
|
||||
MM[reg].b[1] += src.b[1];
|
||||
MM[reg].b[2] += src.b[2];
|
||||
MM[reg].b[3] += src.b[3];
|
||||
MM[reg].b[4] += src.b[4];
|
||||
MM[reg].b[5] += src.b[5];
|
||||
MM[reg].b[6] += src.b[6];
|
||||
MM[reg].b[7] += src.b[7];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPADDW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] += src.w[0];
|
||||
MM[reg].w[1] += src.w[1];
|
||||
MM[reg].w[2] += src.w[2];
|
||||
MM[reg].w[3] += src.w[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPADDW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] += src.w[0];
|
||||
MM[reg].w[1] += src.w[1];
|
||||
MM[reg].w[2] += src.w[2];
|
||||
MM[reg].w[3] += src.w[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPADDD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] += src.l[0];
|
||||
MM[reg].l[1] += src.l[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPADDD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] += src.l[0];
|
||||
MM[reg].l[1] += src.l[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPADDSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sb[0] = SSATB(MM[reg].sb[0] + src.sb[0]);
|
||||
MM[reg].sb[1] = SSATB(MM[reg].sb[1] + src.sb[1]);
|
||||
MM[reg].sb[2] = SSATB(MM[reg].sb[2] + src.sb[2]);
|
||||
MM[reg].sb[3] = SSATB(MM[reg].sb[3] + src.sb[3]);
|
||||
MM[reg].sb[4] = SSATB(MM[reg].sb[4] + src.sb[4]);
|
||||
MM[reg].sb[5] = SSATB(MM[reg].sb[5] + src.sb[5]);
|
||||
MM[reg].sb[6] = SSATB(MM[reg].sb[6] + src.sb[6]);
|
||||
MM[reg].sb[7] = SSATB(MM[reg].sb[7] + src.sb[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPADDSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sb[0] = SSATB(MM[reg].sb[0] + src.sb[0]);
|
||||
MM[reg].sb[1] = SSATB(MM[reg].sb[1] + src.sb[1]);
|
||||
MM[reg].sb[2] = SSATB(MM[reg].sb[2] + src.sb[2]);
|
||||
MM[reg].sb[3] = SSATB(MM[reg].sb[3] + src.sb[3]);
|
||||
MM[reg].sb[4] = SSATB(MM[reg].sb[4] + src.sb[4]);
|
||||
MM[reg].sb[5] = SSATB(MM[reg].sb[5] + src.sb[5]);
|
||||
MM[reg].sb[6] = SSATB(MM[reg].sb[6] + src.sb[6]);
|
||||
MM[reg].sb[7] = SSATB(MM[reg].sb[7] + src.sb[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPADDUSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = USATB(MM[reg].b[0] + src.b[0]);
|
||||
MM[reg].b[1] = USATB(MM[reg].b[1] + src.b[1]);
|
||||
MM[reg].b[2] = USATB(MM[reg].b[2] + src.b[2]);
|
||||
MM[reg].b[3] = USATB(MM[reg].b[3] + src.b[3]);
|
||||
MM[reg].b[4] = USATB(MM[reg].b[4] + src.b[4]);
|
||||
MM[reg].b[5] = USATB(MM[reg].b[5] + src.b[5]);
|
||||
MM[reg].b[6] = USATB(MM[reg].b[6] + src.b[6]);
|
||||
MM[reg].b[7] = USATB(MM[reg].b[7] + src.b[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPADDUSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = USATB(MM[reg].b[0] + src.b[0]);
|
||||
MM[reg].b[1] = USATB(MM[reg].b[1] + src.b[1]);
|
||||
MM[reg].b[2] = USATB(MM[reg].b[2] + src.b[2]);
|
||||
MM[reg].b[3] = USATB(MM[reg].b[3] + src.b[3]);
|
||||
MM[reg].b[4] = USATB(MM[reg].b[4] + src.b[4]);
|
||||
MM[reg].b[5] = USATB(MM[reg].b[5] + src.b[5]);
|
||||
MM[reg].b[6] = USATB(MM[reg].b[6] + src.b[6]);
|
||||
MM[reg].b[7] = USATB(MM[reg].b[7] + src.b[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPADDSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sw[0] = SSATW(MM[reg].sw[0] + src.sw[0]);
|
||||
MM[reg].sw[1] = SSATW(MM[reg].sw[1] + src.sw[1]);
|
||||
MM[reg].sw[2] = SSATW(MM[reg].sw[2] + src.sw[2]);
|
||||
MM[reg].sw[3] = SSATW(MM[reg].sw[3] + src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPADDSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sw[0] = SSATW(MM[reg].sw[0] + src.sw[0]);
|
||||
MM[reg].sw[1] = SSATW(MM[reg].sw[1] + src.sw[1]);
|
||||
MM[reg].sw[2] = SSATW(MM[reg].sw[2] + src.sw[2]);
|
||||
MM[reg].sw[3] = SSATW(MM[reg].sw[3] + src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPADDUSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = USATW(MM[reg].w[0] + src.w[0]);
|
||||
MM[reg].w[1] = USATW(MM[reg].w[1] + src.w[1]);
|
||||
MM[reg].w[2] = USATW(MM[reg].w[2] + src.w[2]);
|
||||
MM[reg].w[3] = USATW(MM[reg].w[3] + src.w[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPADDUSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = USATW(MM[reg].w[0] + src.w[0]);
|
||||
MM[reg].w[1] = USATW(MM[reg].w[1] + src.w[1]);
|
||||
MM[reg].w[2] = USATW(MM[reg].w[2] + src.w[2]);
|
||||
MM[reg].w[3] = USATW(MM[reg].w[3] + src.w[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPMADDWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
if (MM[reg].l[0] == 0x80008000 && src.l[0] == 0x80008000)
|
||||
MM[reg].l[0] = 0x80000000;
|
||||
else
|
||||
MM[reg].sl[0] = ((int32_t)MM[reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)MM[reg].sw[1] * (int32_t)src.sw[1]);
|
||||
|
||||
if (MM[reg].l[1] == 0x80008000 && src.l[1] == 0x80008000)
|
||||
MM[reg].l[1] = 0x80000000;
|
||||
else
|
||||
MM[reg].sl[1] = ((int32_t)MM[reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)MM[reg].sw[3] * (int32_t)src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPMADDWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
if (MM[reg].l[0] == 0x80008000 && src.l[0] == 0x80008000)
|
||||
MM[reg].l[0] = 0x80000000;
|
||||
else
|
||||
MM[reg].sl[0] = ((int32_t)MM[reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)MM[reg].sw[1] * (int32_t)src.sw[1]);
|
||||
|
||||
if (MM[reg].l[1] == 0x80008000 && src.l[1] == 0x80008000)
|
||||
MM[reg].l[1] = 0x80000000;
|
||||
else
|
||||
MM[reg].sl[1] = ((int32_t)MM[reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)MM[reg].sw[3] * (int32_t)src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int opPMULLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].w[0] *= MM[rm].w[0];
|
||||
MM[reg].w[1] *= MM[rm].w[1];
|
||||
MM[reg].w[2] *= MM[rm].w[2];
|
||||
MM[reg].w[3] *= MM[rm].w[3];
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
src.l[0] = readmeml(easeg, eaaddr);
|
||||
src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
MM[reg].w[0] *= src.w[0];
|
||||
MM[reg].w[1] *= src.w[1];
|
||||
MM[reg].w[2] *= src.w[2];
|
||||
MM[reg].w[3] *= src.w[3];
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int opPMULLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].w[0] *= MM[rm].w[0];
|
||||
MM[reg].w[1] *= MM[rm].w[1];
|
||||
MM[reg].w[2] *= MM[rm].w[2];
|
||||
MM[reg].w[3] *= MM[rm].w[3];
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
src.l[0] = readmeml(easeg, eaaddr);
|
||||
src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
MM[reg].w[0] *= src.w[0];
|
||||
MM[reg].w[1] *= src.w[1];
|
||||
MM[reg].w[2] *= src.w[2];
|
||||
MM[reg].w[3] *= src.w[3];
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPMULHW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)MM[rm].sw[0]) >> 16;
|
||||
MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)MM[rm].sw[1]) >> 16;
|
||||
MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)MM[rm].sw[2]) >> 16;
|
||||
MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)MM[rm].sw[3]) >> 16;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
src.l[0] = readmeml(easeg, eaaddr);
|
||||
src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)src.sw[0]) >> 16;
|
||||
MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)src.sw[1]) >> 16;
|
||||
MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)src.sw[2]) >> 16;
|
||||
MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)src.sw[3]) >> 16;
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int opPMULHW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)MM[rm].sw[0]) >> 16;
|
||||
MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)MM[rm].sw[1]) >> 16;
|
||||
MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)MM[rm].sw[2]) >> 16;
|
||||
MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)MM[rm].sw[3]) >> 16;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
src.l[0] = readmeml(easeg, eaaddr);
|
||||
src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)src.sw[0]) >> 16;
|
||||
MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)src.sw[1]) >> 16;
|
||||
MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)src.sw[2]) >> 16;
|
||||
MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)src.sw[3]) >> 16;
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSUBB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] -= src.b[0];
|
||||
MM[reg].b[1] -= src.b[1];
|
||||
MM[reg].b[2] -= src.b[2];
|
||||
MM[reg].b[3] -= src.b[3];
|
||||
MM[reg].b[4] -= src.b[4];
|
||||
MM[reg].b[5] -= src.b[5];
|
||||
MM[reg].b[6] -= src.b[6];
|
||||
MM[reg].b[7] -= src.b[7];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSUBB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] -= src.b[0];
|
||||
MM[reg].b[1] -= src.b[1];
|
||||
MM[reg].b[2] -= src.b[2];
|
||||
MM[reg].b[3] -= src.b[3];
|
||||
MM[reg].b[4] -= src.b[4];
|
||||
MM[reg].b[5] -= src.b[5];
|
||||
MM[reg].b[6] -= src.b[6];
|
||||
MM[reg].b[7] -= src.b[7];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSUBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] -= src.w[0];
|
||||
MM[reg].w[1] -= src.w[1];
|
||||
MM[reg].w[2] -= src.w[2];
|
||||
MM[reg].w[3] -= src.w[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSUBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] -= src.w[0];
|
||||
MM[reg].w[1] -= src.w[1];
|
||||
MM[reg].w[2] -= src.w[2];
|
||||
MM[reg].w[3] -= src.w[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSUBD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] -= src.l[0];
|
||||
MM[reg].l[1] -= src.l[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSUBD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] -= src.l[0];
|
||||
MM[reg].l[1] -= src.l[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSUBSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sb[0] = SSATB(MM[reg].sb[0] - src.sb[0]);
|
||||
MM[reg].sb[1] = SSATB(MM[reg].sb[1] - src.sb[1]);
|
||||
MM[reg].sb[2] = SSATB(MM[reg].sb[2] - src.sb[2]);
|
||||
MM[reg].sb[3] = SSATB(MM[reg].sb[3] - src.sb[3]);
|
||||
MM[reg].sb[4] = SSATB(MM[reg].sb[4] - src.sb[4]);
|
||||
MM[reg].sb[5] = SSATB(MM[reg].sb[5] - src.sb[5]);
|
||||
MM[reg].sb[6] = SSATB(MM[reg].sb[6] - src.sb[6]);
|
||||
MM[reg].sb[7] = SSATB(MM[reg].sb[7] - src.sb[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSUBSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sb[0] = SSATB(MM[reg].sb[0] - src.sb[0]);
|
||||
MM[reg].sb[1] = SSATB(MM[reg].sb[1] - src.sb[1]);
|
||||
MM[reg].sb[2] = SSATB(MM[reg].sb[2] - src.sb[2]);
|
||||
MM[reg].sb[3] = SSATB(MM[reg].sb[3] - src.sb[3]);
|
||||
MM[reg].sb[4] = SSATB(MM[reg].sb[4] - src.sb[4]);
|
||||
MM[reg].sb[5] = SSATB(MM[reg].sb[5] - src.sb[5]);
|
||||
MM[reg].sb[6] = SSATB(MM[reg].sb[6] - src.sb[6]);
|
||||
MM[reg].sb[7] = SSATB(MM[reg].sb[7] - src.sb[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSUBUSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = USATB(MM[reg].b[0] - src.b[0]);
|
||||
MM[reg].b[1] = USATB(MM[reg].b[1] - src.b[1]);
|
||||
MM[reg].b[2] = USATB(MM[reg].b[2] - src.b[2]);
|
||||
MM[reg].b[3] = USATB(MM[reg].b[3] - src.b[3]);
|
||||
MM[reg].b[4] = USATB(MM[reg].b[4] - src.b[4]);
|
||||
MM[reg].b[5] = USATB(MM[reg].b[5] - src.b[5]);
|
||||
MM[reg].b[6] = USATB(MM[reg].b[6] - src.b[6]);
|
||||
MM[reg].b[7] = USATB(MM[reg].b[7] - src.b[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSUBUSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = USATB(MM[reg].b[0] - src.b[0]);
|
||||
MM[reg].b[1] = USATB(MM[reg].b[1] - src.b[1]);
|
||||
MM[reg].b[2] = USATB(MM[reg].b[2] - src.b[2]);
|
||||
MM[reg].b[3] = USATB(MM[reg].b[3] - src.b[3]);
|
||||
MM[reg].b[4] = USATB(MM[reg].b[4] - src.b[4]);
|
||||
MM[reg].b[5] = USATB(MM[reg].b[5] - src.b[5]);
|
||||
MM[reg].b[6] = USATB(MM[reg].b[6] - src.b[6]);
|
||||
MM[reg].b[7] = USATB(MM[reg].b[7] - src.b[7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSUBSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sw[0] = SSATW(MM[reg].sw[0] - src.sw[0]);
|
||||
MM[reg].sw[1] = SSATW(MM[reg].sw[1] - src.sw[1]);
|
||||
MM[reg].sw[2] = SSATW(MM[reg].sw[2] - src.sw[2]);
|
||||
MM[reg].sw[3] = SSATW(MM[reg].sw[3] - src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSUBSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].sw[0] = SSATW(MM[reg].sw[0] - src.sw[0]);
|
||||
MM[reg].sw[1] = SSATW(MM[reg].sw[1] - src.sw[1]);
|
||||
MM[reg].sw[2] = SSATW(MM[reg].sw[2] - src.sw[2]);
|
||||
MM[reg].sw[3] = SSATW(MM[reg].sw[3] - src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSUBUSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = USATW(MM[reg].w[0] - src.w[0]);
|
||||
MM[reg].w[1] = USATW(MM[reg].w[1] - src.w[1]);
|
||||
MM[reg].w[2] = USATW(MM[reg].w[2] - src.w[2]);
|
||||
MM[reg].w[3] = USATW(MM[reg].w[3] - src.w[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSUBUSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = USATW(MM[reg].w[0] - src.w[0]);
|
||||
MM[reg].w[1] = USATW(MM[reg].w[1] - src.w[1]);
|
||||
MM[reg].w[2] = USATW(MM[reg].w[2] - src.w[2]);
|
||||
MM[reg].w[3] = USATW(MM[reg].w[3] - src.w[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
205
src/x86_ops_mmx_cmp.h
Normal file
205
src/x86_ops_mmx_cmp.h
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
static int opPCMPEQB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = (MM[reg].b[0] == src.b[0]) ? 0xff : 0;
|
||||
MM[reg].b[1] = (MM[reg].b[1] == src.b[1]) ? 0xff : 0;
|
||||
MM[reg].b[2] = (MM[reg].b[2] == src.b[2]) ? 0xff : 0;
|
||||
MM[reg].b[3] = (MM[reg].b[3] == src.b[3]) ? 0xff : 0;
|
||||
MM[reg].b[4] = (MM[reg].b[4] == src.b[4]) ? 0xff : 0;
|
||||
MM[reg].b[5] = (MM[reg].b[5] == src.b[5]) ? 0xff : 0;
|
||||
MM[reg].b[6] = (MM[reg].b[6] == src.b[6]) ? 0xff : 0;
|
||||
MM[reg].b[7] = (MM[reg].b[7] == src.b[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPEQB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = (MM[reg].b[0] == src.b[0]) ? 0xff : 0;
|
||||
MM[reg].b[1] = (MM[reg].b[1] == src.b[1]) ? 0xff : 0;
|
||||
MM[reg].b[2] = (MM[reg].b[2] == src.b[2]) ? 0xff : 0;
|
||||
MM[reg].b[3] = (MM[reg].b[3] == src.b[3]) ? 0xff : 0;
|
||||
MM[reg].b[4] = (MM[reg].b[4] == src.b[4]) ? 0xff : 0;
|
||||
MM[reg].b[5] = (MM[reg].b[5] == src.b[5]) ? 0xff : 0;
|
||||
MM[reg].b[6] = (MM[reg].b[6] == src.b[6]) ? 0xff : 0;
|
||||
MM[reg].b[7] = (MM[reg].b[7] == src.b[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPGTB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = (MM[reg].sb[0] > src.sb[0]) ? 0xff : 0;
|
||||
MM[reg].b[1] = (MM[reg].sb[1] > src.sb[1]) ? 0xff : 0;
|
||||
MM[reg].b[2] = (MM[reg].sb[2] > src.sb[2]) ? 0xff : 0;
|
||||
MM[reg].b[3] = (MM[reg].sb[3] > src.sb[3]) ? 0xff : 0;
|
||||
MM[reg].b[4] = (MM[reg].sb[4] > src.sb[4]) ? 0xff : 0;
|
||||
MM[reg].b[5] = (MM[reg].sb[5] > src.sb[5]) ? 0xff : 0;
|
||||
MM[reg].b[6] = (MM[reg].sb[6] > src.sb[6]) ? 0xff : 0;
|
||||
MM[reg].b[7] = (MM[reg].sb[7] > src.sb[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPGTB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = (MM[reg].sb[0] > src.sb[0]) ? 0xff : 0;
|
||||
MM[reg].b[1] = (MM[reg].sb[1] > src.sb[1]) ? 0xff : 0;
|
||||
MM[reg].b[2] = (MM[reg].sb[2] > src.sb[2]) ? 0xff : 0;
|
||||
MM[reg].b[3] = (MM[reg].sb[3] > src.sb[3]) ? 0xff : 0;
|
||||
MM[reg].b[4] = (MM[reg].sb[4] > src.sb[4]) ? 0xff : 0;
|
||||
MM[reg].b[5] = (MM[reg].sb[5] > src.sb[5]) ? 0xff : 0;
|
||||
MM[reg].b[6] = (MM[reg].sb[6] > src.sb[6]) ? 0xff : 0;
|
||||
MM[reg].b[7] = (MM[reg].sb[7] > src.sb[7]) ? 0xff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPEQW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = (MM[reg].w[0] == src.w[0]) ? 0xffff : 0;
|
||||
MM[reg].w[1] = (MM[reg].w[1] == src.w[1]) ? 0xffff : 0;
|
||||
MM[reg].w[2] = (MM[reg].w[2] == src.w[2]) ? 0xffff : 0;
|
||||
MM[reg].w[3] = (MM[reg].w[3] == src.w[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPEQW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = (MM[reg].w[0] == src.w[0]) ? 0xffff : 0;
|
||||
MM[reg].w[1] = (MM[reg].w[1] == src.w[1]) ? 0xffff : 0;
|
||||
MM[reg].w[2] = (MM[reg].w[2] == src.w[2]) ? 0xffff : 0;
|
||||
MM[reg].w[3] = (MM[reg].w[3] == src.w[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPGTW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = (MM[reg].sw[0] > src.sw[0]) ? 0xffff : 0;
|
||||
MM[reg].w[1] = (MM[reg].sw[1] > src.sw[1]) ? 0xffff : 0;
|
||||
MM[reg].w[2] = (MM[reg].sw[2] > src.sw[2]) ? 0xffff : 0;
|
||||
MM[reg].w[3] = (MM[reg].sw[3] > src.sw[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPGTW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = (MM[reg].sw[0] > src.sw[0]) ? 0xffff : 0;
|
||||
MM[reg].w[1] = (MM[reg].sw[1] > src.sw[1]) ? 0xffff : 0;
|
||||
MM[reg].w[2] = (MM[reg].sw[2] > src.sw[2]) ? 0xffff : 0;
|
||||
MM[reg].w[3] = (MM[reg].sw[3] > src.sw[3]) ? 0xffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPEQD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] = (MM[reg].l[0] == src.l[0]) ? 0xffffffff : 0;
|
||||
MM[reg].l[1] = (MM[reg].l[1] == src.l[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPEQD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] = (MM[reg].l[0] == src.l[0]) ? 0xffffffff : 0;
|
||||
MM[reg].l[1] = (MM[reg].l[1] == src.l[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opPCMPGTD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] = (MM[reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
|
||||
MM[reg].l[1] = (MM[reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int opPCMPGTD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] = (MM[reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
|
||||
MM[reg].l[1] = (MM[reg].sl[1] > src.sl[1]) ? 0xffffffff : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
91
src/x86_ops_mmx_logic.h
Normal file
91
src/x86_ops_mmx_logic.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
int opPAND_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q &= src.q;
|
||||
return 0;
|
||||
}
|
||||
int opPAND_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q &= src.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPANDN_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q &= ~src.q;
|
||||
return 0;
|
||||
}
|
||||
int opPANDN_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q &= ~src.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q |= src.q;
|
||||
return 0;
|
||||
}
|
||||
int opPOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q |= src.q;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPXOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q ^= src.q;
|
||||
return 0;
|
||||
}
|
||||
int opPXOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].q ^= src.q;
|
||||
return 0;
|
||||
}
|
||||
163
src/x86_ops_mmx_mov.h
Normal file
163
src/x86_ops_mmx_mov.h
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
int opMOVD_l_mm_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].l[0] = regs[rm].l;
|
||||
MM[reg].l[1] = 0;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst;
|
||||
|
||||
dst = readmeml(easeg, eaaddr); if (abrt) return 0;
|
||||
MM[reg].l[0] = dst;
|
||||
MM[reg].l[1] = 0;
|
||||
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int opMOVD_l_mm_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].l[0] = regs[rm].l;
|
||||
MM[reg].l[1] = 0;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst;
|
||||
|
||||
dst = readmeml(easeg, eaaddr); if (abrt) return 0;
|
||||
MM[reg].l[0] = dst;
|
||||
MM[reg].l[1] = 0;
|
||||
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opMOVD_mm_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
regs[rm].l = MM[reg].l[0];
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int opMOVD_mm_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
regs[rm].l = MM[reg].l[0];
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opMOVQ_q_mm_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].q = MM[rm].q;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst[2];
|
||||
|
||||
dst[0] = readmeml(easeg, eaaddr);
|
||||
dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
MM[reg].l[0] = dst[0];
|
||||
MM[reg].l[1] = dst[1];
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int opMOVQ_q_mm_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].q = MM[rm].q;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t dst[2];
|
||||
|
||||
dst[0] = readmeml(easeg, eaaddr);
|
||||
dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0;
|
||||
MM[reg].l[0] = dst[0];
|
||||
MM[reg].l[1] = dst[1];
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opMOVQ_mm_q_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[rm].q = MM[reg].q;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]);
|
||||
writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int opMOVQ_mm_q_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[rm].q = MM[reg].q;
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememl(easeg, eaaddr, MM[reg].l[0]);
|
||||
writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0;
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
322
src/x86_ops_mmx_pack.h
Normal file
322
src/x86_ops_mmx_pack.h
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
int opPUNPCKLDQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].l[1] = MM[rm].l[0];
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t src;
|
||||
|
||||
src = readmeml(easeg, eaaddr); if (abrt) return 0;
|
||||
MM[reg].l[1] = src;
|
||||
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int opPUNPCKLDQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (mod == 3)
|
||||
{
|
||||
MM[reg].l[1] = MM[rm].l[0];
|
||||
cycles--;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t src;
|
||||
|
||||
src = readmeml(easeg, eaaddr); if (abrt) return 0;
|
||||
MM[reg].l[1] = src;
|
||||
|
||||
cycles -= 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPUNPCKHDQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] = src.l[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPUNPCKHDQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].l[0] = src.l[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPUNPCKLBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[7] = src.b[3];
|
||||
MM[reg].b[6] = MM[reg].b[3];
|
||||
MM[reg].b[5] = src.b[2];
|
||||
MM[reg].b[4] = MM[reg].b[2];
|
||||
MM[reg].b[3] = src.b[1];
|
||||
MM[reg].b[2] = MM[reg].b[1];
|
||||
MM[reg].b[1] = src.b[0];
|
||||
MM[reg].b[0] = MM[reg].b[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPUNPCKLBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[7] = src.b[3];
|
||||
MM[reg].b[6] = MM[reg].b[3];
|
||||
MM[reg].b[5] = src.b[2];
|
||||
MM[reg].b[4] = MM[reg].b[2];
|
||||
MM[reg].b[3] = src.b[1];
|
||||
MM[reg].b[2] = MM[reg].b[1];
|
||||
MM[reg].b[1] = src.b[0];
|
||||
MM[reg].b[0] = MM[reg].b[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPUNPCKHBW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = MM[reg].b[4];
|
||||
MM[reg].b[1] = src.b[4];
|
||||
MM[reg].b[2] = MM[reg].b[5];
|
||||
MM[reg].b[3] = src.b[5];
|
||||
MM[reg].b[4] = MM[reg].b[6];
|
||||
MM[reg].b[5] = src.b[6];
|
||||
MM[reg].b[6] = MM[reg].b[7];
|
||||
MM[reg].b[7] = src.b[7];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPUNPCKHBW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].b[0] = MM[reg].b[4];
|
||||
MM[reg].b[1] = src.b[4];
|
||||
MM[reg].b[2] = MM[reg].b[5];
|
||||
MM[reg].b[3] = src.b[5];
|
||||
MM[reg].b[4] = MM[reg].b[6];
|
||||
MM[reg].b[5] = src.b[6];
|
||||
MM[reg].b[6] = MM[reg].b[7];
|
||||
MM[reg].b[7] = src.b[7];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPUNPCKLWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[3] = src.w[1];
|
||||
MM[reg].w[2] = MM[reg].w[1];
|
||||
MM[reg].w[1] = src.w[0];
|
||||
MM[reg].w[0] = MM[reg].w[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPUNPCKLWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[3] = src.w[1];
|
||||
MM[reg].w[2] = MM[reg].w[1];
|
||||
MM[reg].w[1] = src.w[0];
|
||||
MM[reg].w[0] = MM[reg].w[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPUNPCKHWD_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = MM[reg].w[2];
|
||||
MM[reg].w[1] = src.w[2];
|
||||
MM[reg].w[2] = MM[reg].w[3];
|
||||
MM[reg].w[3] = src.w[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPUNPCKHWD_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
MM[reg].w[0] = MM[reg].w[2];
|
||||
MM[reg].w[1] = src.w[2];
|
||||
MM[reg].w[2] = MM[reg].w[3];
|
||||
MM[reg].w[3] = src.w[3];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPACKSSWB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = MM[reg];
|
||||
|
||||
MM[reg].sb[0] = SSATB(dst.sw[0]);
|
||||
MM[reg].sb[1] = SSATB(dst.sw[1]);
|
||||
MM[reg].sb[2] = SSATB(dst.sw[2]);
|
||||
MM[reg].sb[3] = SSATB(dst.sw[3]);
|
||||
MM[reg].sb[4] = SSATB(src.sw[0]);
|
||||
MM[reg].sb[5] = SSATB(src.sw[1]);
|
||||
MM[reg].sb[6] = SSATB(src.sw[2]);
|
||||
MM[reg].sb[7] = SSATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPACKSSWB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = MM[reg];
|
||||
|
||||
MM[reg].sb[0] = SSATB(dst.sw[0]);
|
||||
MM[reg].sb[1] = SSATB(dst.sw[1]);
|
||||
MM[reg].sb[2] = SSATB(dst.sw[2]);
|
||||
MM[reg].sb[3] = SSATB(dst.sw[3]);
|
||||
MM[reg].sb[4] = SSATB(src.sw[0]);
|
||||
MM[reg].sb[5] = SSATB(src.sw[1]);
|
||||
MM[reg].sb[6] = SSATB(src.sw[2]);
|
||||
MM[reg].sb[7] = SSATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPACKUSWB_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = MM[reg];
|
||||
|
||||
MM[reg].b[0] = USATB(dst.sw[0]);
|
||||
MM[reg].b[1] = USATB(dst.sw[1]);
|
||||
MM[reg].b[2] = USATB(dst.sw[2]);
|
||||
MM[reg].b[3] = USATB(dst.sw[3]);
|
||||
MM[reg].b[4] = USATB(src.sw[0]);
|
||||
MM[reg].b[5] = USATB(src.sw[1]);
|
||||
MM[reg].b[6] = USATB(src.sw[2]);
|
||||
MM[reg].b[7] = USATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPACKUSWB_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = MM[reg];
|
||||
|
||||
MM[reg].b[0] = USATB(dst.sw[0]);
|
||||
MM[reg].b[1] = USATB(dst.sw[1]);
|
||||
MM[reg].b[2] = USATB(dst.sw[2]);
|
||||
MM[reg].b[3] = USATB(dst.sw[3]);
|
||||
MM[reg].b[4] = USATB(src.sw[0]);
|
||||
MM[reg].b[5] = USATB(src.sw[1]);
|
||||
MM[reg].b[6] = USATB(src.sw[2]);
|
||||
MM[reg].b[7] = USATB(src.sw[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPACKSSDW_a16(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = MM[reg];
|
||||
|
||||
MM[reg].sw[0] = SSATW(dst.sl[0]);
|
||||
MM[reg].sw[1] = SSATW(dst.sl[1]);
|
||||
MM[reg].sw[2] = SSATW(src.sl[0]);
|
||||
MM[reg].sw[3] = SSATW(src.sl[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPACKSSDW_a32(uint32_t fetchdat)
|
||||
{
|
||||
MMX_REG src, dst;
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
dst = MM[reg];
|
||||
|
||||
MM[reg].sw[0] = SSATW(dst.sl[0]);
|
||||
MM[reg].sw[1] = SSATW(dst.sl[1]);
|
||||
MM[reg].sw[2] = SSATW(src.sl[0]);
|
||||
MM[reg].sw[3] = SSATW(src.sl[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
452
src/x86_ops_mmx_shift.h
Normal file
452
src/x86_ops_mmx_shift.h
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
#define MMX_GETSHIFT() \
|
||||
if (mod == 3) \
|
||||
{ \
|
||||
shift = MM[rm].b[0]; \
|
||||
cycles--; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
shift = readmemb(easeg, eaaddr); if (abrt) return 0; \
|
||||
cycles -= 2; \
|
||||
}
|
||||
|
||||
int opPSxxW_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
|
||||
pc += 2;
|
||||
MMX_ENTER();
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x10: /*PSRLW*/
|
||||
if (shift > 15)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].w[0] >>= shift;
|
||||
MM[reg].w[1] >>= shift;
|
||||
MM[reg].w[2] >>= shift;
|
||||
MM[reg].w[3] >>= shift;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
MM[reg].sw[0] >>= shift;
|
||||
MM[reg].sw[1] >>= shift;
|
||||
MM[reg].sw[2] >>= shift;
|
||||
MM[reg].sw[3] >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
if (shift > 15)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].w[0] <<= shift;
|
||||
MM[reg].w[1] <<= shift;
|
||||
MM[reg].w[2] <<= shift;
|
||||
MM[reg].w[3] <<= shift;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pclog("Bad PSxxW (0F 71) instruction %02X\n", op);
|
||||
pc = oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cycles--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSLLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].w[0] <<= shift;
|
||||
MM[reg].w[1] <<= shift;
|
||||
MM[reg].w[2] <<= shift;
|
||||
MM[reg].w[3] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSLLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].w[0] <<= shift;
|
||||
MM[reg].w[1] <<= shift;
|
||||
MM[reg].w[2] <<= shift;
|
||||
MM[reg].w[3] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSRLW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].w[0] >>= shift;
|
||||
MM[reg].w[1] >>= shift;
|
||||
MM[reg].w[2] >>= shift;
|
||||
MM[reg].w[3] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSRLW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].w[0] >>= shift;
|
||||
MM[reg].w[1] >>= shift;
|
||||
MM[reg].w[2] >>= shift;
|
||||
MM[reg].w[3] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSRAW_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
|
||||
MM[reg].sw[0] >>= shift;
|
||||
MM[reg].sw[1] >>= shift;
|
||||
MM[reg].sw[2] >>= shift;
|
||||
MM[reg].sw[3] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSRAW_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
|
||||
MM[reg].sw[0] >>= shift;
|
||||
MM[reg].sw[1] >>= shift;
|
||||
MM[reg].sw[2] >>= shift;
|
||||
MM[reg].sw[3] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSxxD_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
|
||||
pc += 2;
|
||||
MMX_ENTER();
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x10: /*PSRLD*/
|
||||
if (shift > 31)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].l[0] >>= shift;
|
||||
MM[reg].l[1] >>= shift;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*PSRAD*/
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
MM[reg].sl[0] >>= shift;
|
||||
MM[reg].sl[1] >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLD*/
|
||||
if (shift > 31)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].l[0] <<= shift;
|
||||
MM[reg].l[1] <<= shift;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pclog("Bad PSxxD (0F 72) instruction %02X\n", op);
|
||||
pc = oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cycles--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSLLD_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].l[0] <<= shift;
|
||||
MM[reg].l[1] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSLLD_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].l[0] <<= shift;
|
||||
MM[reg].l[1] <<= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSRLD_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].l[0] >>= shift;
|
||||
MM[reg].l[1] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSRLD_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
{
|
||||
MM[reg].l[0] >>= shift;
|
||||
MM[reg].l[1] >>= shift;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSRAD_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
|
||||
MM[reg].sl[0] >>= shift;
|
||||
MM[reg].sl[1] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSRAD_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
|
||||
MM[reg].sl[0] >>= shift;
|
||||
MM[reg].sl[1] >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSxxQ_imm(uint32_t fetchdat)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
int op = fetchdat & 0x38;
|
||||
int shift = (fetchdat >> 8) & 0xff;
|
||||
|
||||
pc += 2;
|
||||
MMX_ENTER();
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case 0x10: /*PSRLW*/
|
||||
if (shift > 63)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
MM[reg].q >>= shift;
|
||||
break;
|
||||
case 0x20: /*PSRAW*/
|
||||
if (shift > 63)
|
||||
shift = 63;
|
||||
MM[reg].sq >>= shift;
|
||||
break;
|
||||
case 0x30: /*PSLLW*/
|
||||
if (shift > 63)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
MM[reg].q <<= shift;
|
||||
break;
|
||||
default:
|
||||
pclog("Bad PSxxQ (0F 73) instruction %02X\n", op);
|
||||
pc = oldpc;
|
||||
x86illegal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
cycles--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSLLQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
MM[reg].q <<= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSLLQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
MM[reg].q <<= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opPSRLQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
MM[reg].q >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int opPSRLQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
int shift;
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSHIFT();
|
||||
|
||||
if (shift > 63)
|
||||
MM[reg].q = 0;
|
||||
else
|
||||
MM[reg].q >>= shift;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2394,7 +2394,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
|||
|
||||
|
||||
cr3=new_cr3;
|
||||
pclog("TS New CR3 %08X\n",cr3);
|
||||
// pclog("TS New CR3 %08X\n",cr3);
|
||||
flushmmucache();
|
||||
|
||||
|
||||
|
|
|
|||
205
src/x87.c
205
src/x87.c
|
|
@ -60,6 +60,8 @@ static inline uint32_t geteal()
|
|||
|
||||
|
||||
double ST[8];
|
||||
MMX_REG MM[8];
|
||||
int ismmx = 0;
|
||||
uint16_t npxs,npxc,tag;
|
||||
|
||||
int TOP;
|
||||
|
|
@ -90,6 +92,19 @@ int TOP;
|
|||
dst = src1 / (double)src2; \
|
||||
} while (0)
|
||||
|
||||
void x87_set_mmx()
|
||||
{
|
||||
TOP = 0;
|
||||
tag = 0;
|
||||
ismmx = 1;
|
||||
}
|
||||
|
||||
void x87_emms()
|
||||
{
|
||||
tag = 0xffff;
|
||||
ismmx = 0;
|
||||
}
|
||||
|
||||
void x87_checkexceptions()
|
||||
{
|
||||
}
|
||||
|
|
@ -100,15 +115,31 @@ void x87_reset()
|
|||
|
||||
void x87_dumpregs()
|
||||
{
|
||||
pclog("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",ST[TOP],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7]);
|
||||
if (ismmx)
|
||||
{
|
||||
pclog("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", MM[0].q, MM[1].q, MM[2].q, MM[3].q);
|
||||
pclog("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", MM[4].q, MM[5].q, MM[6].q, MM[7].q);
|
||||
}
|
||||
else
|
||||
{
|
||||
pclog("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",ST[TOP],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7]);
|
||||
}
|
||||
pclog("Status = %04X Control = %04X Tag = %04X\n",npxs,npxc,tag);
|
||||
}
|
||||
|
||||
void x87_print()
|
||||
{
|
||||
pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",ST[TOP&7],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t TOP=%i CR=%04X SR=%04X TAG=%04X\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7], TOP, npxc, npxs, tag);
|
||||
if (ismmx)
|
||||
{
|
||||
pclog("\tMM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\t", MM[0].q, MM[1].q, MM[2].q, MM[3].q);
|
||||
pclog("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", MM[4].q, MM[5].q, MM[6].q, MM[7].q);
|
||||
}
|
||||
else
|
||||
{
|
||||
pclog("\tST(0)=%.20f\tST(1)=%.20f\tST(2)=%f\tST(3)=%f\t",ST[TOP&7],ST[(TOP+1)&7],ST[(TOP+2)&7],ST[(TOP+3)&7]);
|
||||
pclog("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t TOP=%i CR=%04X SR=%04X TAG=%04X\n",ST[(TOP+4)&7],ST[(TOP+5)&7],ST[(TOP+6)&7],ST[(TOP+7)&7], TOP, npxc, npxs, tag);
|
||||
}
|
||||
}
|
||||
|
||||
void x87_push(double i)
|
||||
|
|
@ -215,6 +246,20 @@ void x87_st80(double d)
|
|||
writememw(easeg,eaaddr+8,test.begin);
|
||||
}
|
||||
|
||||
void x87_ldmmx(MMX_REG *r)
|
||||
{
|
||||
r->l[0] = readmeml(easeg, eaaddr);
|
||||
r->l[1] = readmeml(easeg, eaaddr + 4);
|
||||
r->w[4] = readmemw(easeg, eaaddr + 8);
|
||||
}
|
||||
|
||||
void x87_stmmx(MMX_REG r)
|
||||
{
|
||||
writememl(easeg, eaaddr, r.l[0]);
|
||||
writememl(easeg, eaaddr + 4, r.l[1]);
|
||||
writememw(easeg, eaaddr + 8, 0xffff);
|
||||
}
|
||||
|
||||
void x87_d8()
|
||||
{
|
||||
union
|
||||
|
|
@ -545,7 +590,7 @@ void x87_d9()
|
|||
cycles-=7;
|
||||
return;
|
||||
case 3: /*FSTP single-precision*/
|
||||
if (fplog) pclog("FSTPs %08X:%08X\n", easeg, eaaddr);
|
||||
if (fplog) pclog("FSTPs %08X:%08X %f\n", easeg, eaaddr, ST(0));
|
||||
ts.s=(float)ST(0);
|
||||
seteal(ts.i); if (abrt) { pclog("FSTP sp abort\n"); return; }
|
||||
// if (pc==0x3f50c) pclog("FSTP %f %f %08X\n",ST(0),ts.s,ts.i);
|
||||
|
|
@ -969,7 +1014,6 @@ void x87_dd()
|
|||
cycles-=8;
|
||||
return;
|
||||
case 4: /*FRSTOR*/
|
||||
if (fplog) pclog("FRSTOR %08X:%08X\n", easeg, eaaddr);
|
||||
switch ((cr0&1)|(op32&0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
|
|
@ -989,23 +1033,33 @@ void x87_dd()
|
|||
eaaddr+=28;
|
||||
break;
|
||||
}
|
||||
ST(0)=x87_ld80(); eaaddr+=10;
|
||||
ST(1)=x87_ld80(); eaaddr+=10;
|
||||
ST(2)=x87_ld80(); eaaddr+=10;
|
||||
ST(3)=x87_ld80(); eaaddr+=10;
|
||||
ST(4)=x87_ld80(); eaaddr+=10;
|
||||
ST(5)=x87_ld80(); eaaddr+=10;
|
||||
ST(6)=x87_ld80(); eaaddr+=10;
|
||||
ST(7)=x87_ld80();
|
||||
x87_ldmmx(&MM[0]); ST(0)=x87_ld80(); eaaddr += 10;
|
||||
x87_ldmmx(&MM[1]); ST(1)=x87_ld80(); eaaddr += 10;
|
||||
x87_ldmmx(&MM[2]); ST(2)=x87_ld80(); eaaddr += 10;
|
||||
x87_ldmmx(&MM[3]); ST(3)=x87_ld80(); eaaddr += 10;
|
||||
x87_ldmmx(&MM[4]); ST(4)=x87_ld80(); eaaddr += 10;
|
||||
x87_ldmmx(&MM[5]); ST(5)=x87_ld80(); eaaddr += 10;
|
||||
x87_ldmmx(&MM[6]); ST(6)=x87_ld80(); eaaddr += 10;
|
||||
x87_ldmmx(&MM[7]); ST(7)=x87_ld80();
|
||||
ismmx = 0;
|
||||
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
|
||||
something like this is needed*/
|
||||
if (MM[0].w == 0xffff && MM[1].w == 0xffff && MM[2].w == 0xffff && MM[3].w == 0xffff &&
|
||||
MM[4].w == 0xffff && MM[5].w == 0xffff && MM[6].w == 0xffff && MM[7].w == 0xffff &&
|
||||
!TOP && !tag)
|
||||
ismmx = 1;
|
||||
|
||||
cycles-=(cr0&1)?34:44;
|
||||
if (fplog) pclog("FRSTOR %08X:%08X %i %i %04X\n", easeg, eaaddr, ismmx, TOP, tag);
|
||||
/* pclog("new TOP %i\n", TOP);
|
||||
pclog("%04X %04X %04X %f %f %f %f %f %f %f %f\n", npxc, npxs, tag, ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7));*/
|
||||
return;
|
||||
case 6: /*FSAVE*/
|
||||
if (fplog) pclog("FSAVE %08X:%08X\n", easeg, eaaddr);
|
||||
if (fplog) pclog("FSAVE %08X:%08X %i\n", easeg, eaaddr, ismmx);
|
||||
npxs = (npxs & ~(7 << 11)) | (TOP << 11);
|
||||
/* pclog("old TOP %i %04X\n", TOP, npxs);
|
||||
pclog("%04X %04X %04X %f %f %f %f %f %f %f %f\n", npxc, npxs, tag, ST(0), ST(1), ST(2), ST(3), ST(4), ST(5), ST(6), ST(7));*/
|
||||
|
||||
switch ((cr0&1)|(op32&0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
|
|
@ -1015,14 +1069,28 @@ void x87_dd()
|
|||
writememw(easeg,eaaddr+6,x87_pc_off);
|
||||
writememw(easeg,eaaddr+10,x87_op_off);
|
||||
eaaddr+=14;
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
if (ismmx)
|
||||
{
|
||||
x87_stmmx(MM[0]); eaaddr+=10;
|
||||
x87_stmmx(MM[1]); eaaddr+=10;
|
||||
x87_stmmx(MM[2]); eaaddr+=10;
|
||||
x87_stmmx(MM[3]); eaaddr+=10;
|
||||
x87_stmmx(MM[4]); eaaddr+=10;
|
||||
x87_stmmx(MM[5]); eaaddr+=10;
|
||||
x87_stmmx(MM[6]); eaaddr+=10;
|
||||
x87_stmmx(MM[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
}
|
||||
break;
|
||||
case 0x001: /*16-bit protected mode*/
|
||||
writememw(easeg,eaaddr,npxc);
|
||||
|
|
@ -1033,14 +1101,28 @@ void x87_dd()
|
|||
writememw(easeg,eaaddr+10,x87_op_off);
|
||||
writememw(easeg,eaaddr+12,x87_op_seg);
|
||||
eaaddr+=14;
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
if (ismmx)
|
||||
{
|
||||
x87_stmmx(MM[0]); eaaddr+=10;
|
||||
x87_stmmx(MM[1]); eaaddr+=10;
|
||||
x87_stmmx(MM[2]); eaaddr+=10;
|
||||
x87_stmmx(MM[3]); eaaddr+=10;
|
||||
x87_stmmx(MM[4]); eaaddr+=10;
|
||||
x87_stmmx(MM[5]); eaaddr+=10;
|
||||
x87_stmmx(MM[6]); eaaddr+=10;
|
||||
x87_stmmx(MM[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
}
|
||||
break;
|
||||
case 0x100: /*32-bit real mode*/
|
||||
writememw(easeg,eaaddr,npxc);
|
||||
|
|
@ -1050,14 +1132,28 @@ void x87_dd()
|
|||
writememw(easeg,eaaddr+20,x87_op_off);
|
||||
writememl(easeg,eaaddr+24,(x87_op_off>>16)<<12);
|
||||
eaaddr+=28;
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
if (ismmx)
|
||||
{
|
||||
x87_stmmx(MM[0]); eaaddr+=10;
|
||||
x87_stmmx(MM[1]); eaaddr+=10;
|
||||
x87_stmmx(MM[2]); eaaddr+=10;
|
||||
x87_stmmx(MM[3]); eaaddr+=10;
|
||||
x87_stmmx(MM[4]); eaaddr+=10;
|
||||
x87_stmmx(MM[5]); eaaddr+=10;
|
||||
x87_stmmx(MM[6]); eaaddr+=10;
|
||||
x87_stmmx(MM[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
}
|
||||
break;
|
||||
case 0x101: /*32-bit protected mode*/
|
||||
writememw(easeg,eaaddr,npxc);
|
||||
|
|
@ -1068,14 +1164,28 @@ void x87_dd()
|
|||
writememl(easeg,eaaddr+20,x87_op_off);
|
||||
writememl(easeg,eaaddr+24,x87_op_seg);
|
||||
eaaddr+=28;
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
if (ismmx)
|
||||
{
|
||||
x87_stmmx(MM[0]); eaaddr+=10;
|
||||
x87_stmmx(MM[1]); eaaddr+=10;
|
||||
x87_stmmx(MM[2]); eaaddr+=10;
|
||||
x87_stmmx(MM[3]); eaaddr+=10;
|
||||
x87_stmmx(MM[4]); eaaddr+=10;
|
||||
x87_stmmx(MM[5]); eaaddr+=10;
|
||||
x87_stmmx(MM[6]); eaaddr+=10;
|
||||
x87_stmmx(MM[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
x87_st80(ST(0)); eaaddr+=10;
|
||||
x87_st80(ST(1)); eaaddr+=10;
|
||||
x87_st80(ST(2)); eaaddr+=10;
|
||||
x87_st80(ST(3)); eaaddr+=10;
|
||||
x87_st80(ST(4)); eaaddr+=10;
|
||||
x87_st80(ST(5)); eaaddr+=10;
|
||||
x87_st80(ST(6)); eaaddr+=10;
|
||||
x87_st80(ST(7));
|
||||
}
|
||||
break;
|
||||
}
|
||||
cycles-=(cr0&1)?56:67;
|
||||
|
|
@ -1293,3 +1403,4 @@ void x87_df()
|
|||
// fatal("Bad x87 DF opcode %i %02X\n",reg,rmdat32&0xFF);
|
||||
x86illegal();
|
||||
}
|
||||
|
||||
|
|
|
|||
17
src/x87.h
17
src/x87.h
|
|
@ -1,3 +1,20 @@
|
|||
uint32_t x87_pc_off,x87_op_off;
|
||||
uint16_t x87_pc_seg,x87_op_seg;
|
||||
extern uint32_t op32;
|
||||
|
||||
typedef union MMX_REG
|
||||
{
|
||||
uint64_t q;
|
||||
int64_t sq;
|
||||
uint32_t l[2];
|
||||
int32_t sl[2];
|
||||
uint16_t w[5];
|
||||
int16_t sw[4];
|
||||
uint8_t b[8];
|
||||
int8_t sb[8];
|
||||
} MMX_REG;
|
||||
|
||||
extern MMX_REG MM[8];
|
||||
|
||||
void x87_set_mmx();
|
||||
void x87_emms();
|
||||
|
|
|
|||
Loading…
Reference in a new issue