PCem
changeset 15:cdce787defd5
Added MMX emulation (probably some bugs). Implemented RDMSR/WRMSR for Winchip.
| author | TomW |
|---|---|
| date | Sat Aug 03 15:05:50 2013 +0100 |
| parents | 7dbba9693027 |
| children | 18fcddb6b75c |
| files | src/386.c src/386_ops.h src/cpu.c src/cpu.h src/x86_ops.h src/x86_ops_fpu.h src/x86_ops_misc.h src/x86_ops_mmx.h src/x86_ops_mmx_arith.h src/x86_ops_mmx_cmp.h src/x86_ops_mmx_logic.h src/x86_ops_mmx_mov.h src/x86_ops_mmx_pack.h src/x86_ops_mmx_shift.h src/x86seg.c src/x87.c src/x87.h |
| diffstat | 17 files changed, 2362 insertions(+), 65 deletions(-) [+] |
line diff
1.1 --- a/src/386.c Sat Jul 27 17:12:16 2013 +0100 1.2 +++ b/src/386.c Sat Aug 03 15:05:50 2013 +0100 1.3 @@ -1210,8 +1210,6 @@ 1.4 1.5 int oldi; 1.6 1.7 -static uint64_t tsc = 0; 1.8 - 1.9 uint32_t testr[9]; 1.10 int dontprint=0; 1.11
2.1 --- a/src/386_ops.h Sat Jul 27 17:12:16 2013 +0100 2.2 +++ b/src/386_ops.h Sat Aug 03 15:05:50 2013 +0100 2.3 @@ -76,6 +76,13 @@ 2.4 #include "x86_ops_io.h" 2.5 #include "x86_ops_jump.h" 2.6 #include "x86_ops_misc.h" 2.7 +#include "x86_ops_mmx.h" 2.8 +#include "x86_ops_mmx_arith.h" 2.9 +#include "x86_ops_mmx_cmp.h" 2.10 +#include "x86_ops_mmx_logic.h" 2.11 +#include "x86_ops_mmx_mov.h" 2.12 +#include "x86_ops_mmx_pack.h" 2.13 +#include "x86_ops_mmx_shift.h" 2.14 #include "x86_ops_mov.h" 2.15 #include "x86_ops_mov_ctrl.h" 2.16 #include "x86_ops_mov_seg.h" 2.17 @@ -95,6 +102,8 @@ 2.18 static int ILLEGAL(uint32_t fetchdat) 2.19 { 2.20 pc = oldpc; 2.21 + 2.22 +// fatal("Illegal instruction %08X\n", fetchdat); 2.23 x86illegal(); 2.24 return 0; 2.25 } 2.26 @@ -103,13 +112,20 @@ 2.27 { 2.28 int opcode = fetchdat & 0xff; 2.29 pc++; 2.30 - 2.31 + if (x86_opcodes_0f[opcode] == ILLEGAL && opcode != 0xff) 2.32 + { 2.33 + fatal("Illegal 0f instruction %02X w_a16\n", opcode); 2.34 + } 2.35 return x86_opcodes_0f[opcode](fetchdat >> 8); 2.36 } 2.37 static int op0F_l_a16(uint32_t fetchdat) 2.38 { 2.39 int opcode = fetchdat & 0xff; 2.40 pc++; 2.41 + if (x86_opcodes_0f[opcode | 0x100] == ILLEGAL && opcode != 0xff) 2.42 + { 2.43 + fatal("Illegal 0f instruction %02X l_a16\n", opcode); 2.44 + } 2.45 2.46 return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); 2.47 } 2.48 @@ -117,6 +133,10 @@ 2.49 { 2.50 int opcode = fetchdat & 0xff; 2.51 pc++; 2.52 + if (x86_opcodes_0f[opcode | 0x200] == ILLEGAL && opcode != 0xff) 2.53 + { 2.54 + fatal("Illegal 0f instruction %02X w_a32\n", opcode); 2.55 + } 2.56 2.57 return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); 2.58 } 2.59 @@ -124,6 +144,10 @@ 2.60 { 2.61 int opcode = fetchdat & 0xff; 2.62 pc++; 2.63 + if (x86_opcodes_0f[opcode | 0x300] == ILLEGAL && opcode != 0xff) 2.64 + { 2.65 + fatal("Illegal 0f instruction %02X l_a32\n", opcode); 2.66 + } 2.67 2.68 return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); 2.69 } 2.70 @@ -232,7 +256,7 @@ 2.71 /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.72 /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.73 /*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, 2.74 -/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.75 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.76 2.77 /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.78 /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.79 @@ -254,7 +278,7 @@ 2.80 /*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.81 /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.82 /*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, 2.83 -/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.84 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.85 2.86 /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.87 /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.88 @@ -276,7 +300,7 @@ 2.89 /*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.90 /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.91 /*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, 2.92 -/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.93 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.94 2.95 /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.96 /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.97 @@ -298,7 +322,7 @@ 2.98 /*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.99 /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.100 /*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, 2.101 -/*30*/ ILLEGAL, opRDTSC, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.102 +/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.103 2.104 /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.105 /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.106 @@ -316,6 +340,97 @@ 2.107 /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.108 }; 2.109 2.110 +OpFn ops_winchip_0f[1024] = 2.111 +{ 2.112 + /*16-bit data, 16-bit addr*/ 2.113 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 2.114 +/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.115 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.116 +/*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, 2.117 +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.118 + 2.119 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.120 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.121 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.122 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.123 + 2.124 +/*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, 2.125 +/*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, 2.126 +/*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, 2.127 +/*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, 2.128 + 2.129 +/*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, 2.130 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.131 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.132 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.133 + 2.134 + /*32-bit data, 16-bit addr*/ 2.135 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 2.136 +/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.137 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.138 +/*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, 2.139 +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.140 + 2.141 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.142 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.143 +/*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, 2.144 +/*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, 2.145 + 2.146 +/*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, 2.147 +/*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, 2.148 +/*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, 2.149 +/*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, 2.150 + 2.151 +/*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, 2.152 +/*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, 2.153 +/*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, 2.154 +/*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, 2.155 + 2.156 + /*16-bit data, 32-bit addr*/ 2.157 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 2.158 +/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.159 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.160 +/*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, 2.161 +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.162 + 2.163 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.164 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.165 +/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.166 +/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.167 + 2.168 +/*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, 2.169 +/*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, 2.170 +/*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, 2.171 +/*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, 2.172 + 2.173 +/*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, 2.174 +/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.175 +/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.176 +/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.177 + 2.178 + /*32-bit data, 32-bit addr*/ 2.179 +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ 2.180 +/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.181 +/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.182 +/*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, 2.183 +/*30*/ opWRMSR, opRDTSC, opRDMSR, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.184 + 2.185 +/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.186 +/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, 2.187 +/*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, 2.188 +/*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, 2.189 + 2.190 +/*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, 2.191 +/*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, 2.192 +/*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, 2.193 +/*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, 2.194 + 2.195 +/*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, 2.196 +/*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, 2.197 +/*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, 2.198 +/*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, 2.199 +}; 2.200 + 2.201 OpFn ops_286[1024] = 2.202 { 2.203 /*16-bit data, 16-bit addr*/
3.1 --- a/src/cpu.c Sat Jul 27 17:12:16 2013 +0100 3.2 +++ b/src/cpu.c Sat Aug 03 15:05:50 2013 +0100 3.3 @@ -4,6 +4,14 @@ 3.4 #include "io.h" 3.5 #include "x86_ops.h" 3.6 3.7 +enum 3.8 +{ 3.9 + CPUID_FPU = (1 << 0), 3.10 + CPUID_TSC = (1 << 4), 3.11 + CPUID_MSR = (1 << 5), 3.12 + CPUID_MMX = (1 << 23) 3.13 +}; 3.14 + 3.15 int cpu = 3, cpu_manufacturer = 0; 3.16 CPU *cpu_s; 3.17 int cpu_multi; 3.18 @@ -11,6 +19,8 @@ 3.19 int cpu_16bitbus; 3.20 int cpu_busspeed; 3.21 int cpu_hasrdtsc; 3.22 +int cpu_hasMMX, cpu_hasMSR; 3.23 +uint64_t tsc = 0; 3.24 3.25 int timing_rr; 3.26 int timing_mr, timing_mrl; 3.27 @@ -18,6 +28,14 @@ 3.28 int timing_mm, timing_mml; 3.29 int timing_bt, timing_bnt; 3.30 3.31 +static struct 3.32 +{ 3.33 + uint32_t tr1, tr12; 3.34 + uint32_t cesr; 3.35 + uint32_t fcr; 3.36 + uint64_t fcr2, fcr3; 3.37 +} msr; 3.38 + 3.39 /*Available cpuspeeds : 3.40 0 = 16 MHz 3.41 1 = 20 MHz 3.42 @@ -239,6 +257,8 @@ 3.43 cpu_busspeed = cpu_s->rspeed / cpu_s->multi; 3.44 cpu_multi = cpu_s->multi; 3.45 cpu_hasrdtsc = 0; 3.46 + cpu_hasMMX = 0; 3.47 + cpu_hasMSR = 0; 3.48 3.49 if (cpu_iscyrix) 3.50 io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL); 3.51 @@ -250,6 +270,8 @@ 3.52 3.53 x86_setopcodes(ops_386, ops_386_0f); 3.54 3.55 + memset(&msr, 0, sizeof(msr)); 3.56 + 3.57 switch (cpu_s->cpu_type) 3.58 { 3.59 case CPU_8088: 3.60 @@ -370,6 +392,7 @@ 3.61 break; 3.62 3.63 case CPU_WINCHIP: 3.64 + x86_setopcodes(ops_386, ops_winchip_0f); 3.65 timing_rr = 1; /*register dest - register src*/ 3.66 timing_rm = 2; /*register dest - memory src*/ 3.67 timing_mr = 3; /*memory dest - register src*/ 3.68 @@ -380,6 +403,8 @@ 3.69 timing_bt = 3-1; /*branch taken*/ 3.70 timing_bnt = 1; /*branch not taken*/ 3.71 cpu_hasrdtsc = 1; 3.72 + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); 3.73 + cpu_hasMMX = cpu_hasMSR = 1; 3.74 break; 3.75 3.76 default: 3.77 @@ -403,7 +428,7 @@ 3.78 { 3.79 EAX = CPUID; 3.80 EBX = ECX = 0; 3.81 - EDX = 1; /*FPU*/ 3.82 + EDX = CPUID_FPU; /*FPU*/ 3.83 } 3.84 else 3.85 EAX = 0; 3.86 @@ -438,7 +463,7 @@ 3.87 { 3.88 EAX = CPUID; 3.89 EBX = ECX = 0; 3.90 - EDX = 1; /*FPU*/ 3.91 + EDX = CPUID_FPU; /*FPU*/ 3.92 } 3.93 else 3.94 EAX = 0; 3.95 @@ -448,15 +473,26 @@ 3.96 if (!EAX) 3.97 { 3.98 EAX = 1; 3.99 - EBX = 0x746e6543; /*CentaurHauls*/ 3.100 - ECX = 0x736c7561; 3.101 - EDX = 0x48727561; 3.102 + if (msr.fcr2 & (1 << 14)) 3.103 + { 3.104 + EBX = msr.fcr3 >> 32; 3.105 + ECX = msr.fcr3 & 0xffffffff; 3.106 + EDX = msr.fcr2 >> 32; 3.107 + } 3.108 + else 3.109 + { 3.110 + EBX = 0x746e6543; /*CentaurHauls*/ 3.111 + ECX = 0x736c7561; 3.112 + EDX = 0x48727561; 3.113 + } 3.114 } 3.115 else if (EAX == 1) 3.116 { 3.117 - EAX = CPUID; 3.118 + EAX = 0x540; 3.119 EBX = ECX = 0; 3.120 - EDX = 1; /*FPU*/ 3.121 + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; 3.122 + if (msr.fcr & (1 << 9)) 3.123 + EDX |= CPUID_MMX; 3.124 } 3.125 else 3.126 EAX = 0; 3.127 @@ -464,6 +500,80 @@ 3.128 } 3.129 } 3.130 3.131 +void cpu_RDMSR() 3.132 +{ 3.133 + switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type) 3.134 + { 3.135 + case CPU_WINCHIP: 3.136 + EAX = EDX = 0; 3.137 + switch (ECX) 3.138 + { 3.139 + case 0x02: 3.140 + EAX = msr.tr1; 3.141 + break; 3.142 + case 0x0e: 3.143 + EAX = msr.tr12; 3.144 + break; 3.145 + case 0x10: 3.146 + EAX = tsc & 0xffffffff; 3.147 + EDX = tsc >> 32; 3.148 + break; 3.149 + case 0x11: 3.150 + EAX = msr.cesr; 3.151 + break; 3.152 + case 0x107: 3.153 + EAX = msr.fcr; 3.154 + break; 3.155 + case 0x108: 3.156 + EAX = msr.fcr2 & 0xffffffff; 3.157 + EDX = msr.fcr2 >> 32; 3.158 + break; 3.159 + case 0x10a: 3.160 + EAX = cpu_multi & 3; 3.161 + break; 3.162 + } 3.163 + break; 3.164 + } 3.165 +} 3.166 + 3.167 +void cpu_WRMSR() 3.168 +{ 3.169 + switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type) 3.170 + { 3.171 + case CPU_WINCHIP: 3.172 + EAX = EDX = 0; 3.173 + switch (ECX) 3.174 + { 3.175 + case 0x02: 3.176 + msr.tr1 = EAX & 2; 3.177 + break; 3.178 + case 0x0e: 3.179 + msr.tr12 = EAX & 0x228; 3.180 + break; 3.181 + case 0x10: 3.182 + tsc = EAX | ((uint64_t)EDX << 32); 3.183 + break; 3.184 + case 0x11: 3.185 + msr.cesr = EAX & 0xff00ff; 3.186 + break; 3.187 + case 0x107: 3.188 + msr.fcr = EAX; 3.189 + cpu_hasMMX = EAX & (1 << 9); 3.190 + if (EAX & (1 << 29)) 3.191 + CPUID = 0; 3.192 + else 3.193 + CPUID = models[model].cpu[cpu_manufacturer].cpus[cpu].cpuid_model; 3.194 + break; 3.195 + case 0x108: 3.196 + msr.fcr2 = EAX | ((uint64_t)EDX << 32); 3.197 + break; 3.198 + case 0x109: 3.199 + msr.fcr3 = EAX | ((uint64_t)EDX << 32); 3.200 + break; 3.201 + } 3.202 + break; 3.203 + } 3.204 +} 3.205 3.206 static int cyrix_addr; 3.207
4.1 --- a/src/cpu.h Sat Jul 27 17:12:16 2013 +0100 4.2 +++ b/src/cpu.h Sat Aug 03 15:05:50 2013 +0100 4.3 @@ -71,8 +71,15 @@ 4.4 extern int cpu_multi; 4.5 4.6 extern int cpu_hasrdtsc; 4.7 +extern int cpu_hasMSR; 4.8 +extern int cpu_hasMMX; 4.9 + 4.10 +extern uint64_t tsc; 4.11 4.12 void cyrix_write(uint16_t addr, uint8_t val, void *priv); 4.13 uint8_t cyrix_read(uint16_t addr, void *priv); 4.14 4.15 extern int is8086; 4.16 + 4.17 +void cpu_RDMSR(); 4.18 +void cpu_WRMSR();
5.1 --- a/src/x86_ops.h Sat Jul 27 17:12:16 2013 +0100 5.2 +++ b/src/x86_ops.h Sat Aug 03 15:05:50 2013 +0100 5.3 @@ -10,3 +10,5 @@ 5.4 5.5 extern OpFn ops_386[1024]; 5.6 extern OpFn ops_386_0f[1024]; 5.7 + 5.8 +extern OpFn ops_winchip_0f[1024];
6.1 --- a/src/x86_ops_fpu.h Sat Jul 27 17:12:16 2013 +0100 6.2 +++ b/src/x86_ops_fpu.h Sat Aug 03 15:05:50 2013 +0100 6.3 @@ -2,7 +2,7 @@ 6.4 static int opESCAPE_ ## num ##_a16(uint32_t fetchdat) \ 6.5 { \ 6.6 flags_rebuild(); \ 6.7 - if ((cr0 & 6) == 4) \ 6.8 + if (cr0 & 0xc) \ 6.9 { \ 6.10 x86_int(7); \ 6.11 } \ 6.12 @@ -24,7 +24,7 @@ 6.13 static int opESCAPE_ ## num ## _a32(uint32_t fetchdat) \ 6.14 { \ 6.15 flags_rebuild(); \ 6.16 - if ((cr0 & 6) == 4) \ 6.17 + if (cr0 & 0xc) \ 6.18 { \ 6.19 x86_int(7); \ 6.20 } \ 6.21 @@ -55,6 +55,11 @@ 6.22 6.23 static int opWAIT(uint32_t fetchdat) 6.24 { 6.25 + if ((cr0 & 0xa) == 0xa) 6.26 + { 6.27 + x86_int(7); 6.28 + return 0; 6.29 + } 6.30 cycles -= 4; 6.31 return 0; 6.32 }
7.1 --- a/src/x86_ops_misc.h Sat Jul 27 17:12:16 2013 +0100 7.2 +++ b/src/x86_ops_misc.h Sat Aug 03 15:05:50 2013 +0100 7.3 @@ -675,4 +675,29 @@ 7.4 return 0; 7.5 } 7.6 7.7 - 7.8 +static int opRDMSR(uint32_t fetchdat) 7.9 +{ 7.10 + if (cpu_hasMSR) 7.11 + { 7.12 + cpu_RDMSR(); 7.13 + cycles -= 9; 7.14 + return 0; 7.15 + } 7.16 + pc = oldpc; 7.17 + x86illegal(); 7.18 + return 0; 7.19 +} 7.20 + 7.21 +static int opWRMSR(uint32_t fetchdat) 7.22 +{ 7.23 + if (cpu_hasMSR) 7.24 + { 7.25 + cpu_WRMSR(); 7.26 + cycles -= 9; 7.27 + return 0; 7.28 + } 7.29 + pc = oldpc; 7.30 + x86illegal(); 7.31 + return 0; 7.32 +} 7.33 +
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/x86_ops_mmx.h Sat Aug 03 15:05:50 2013 +0100 8.3 @@ -0,0 +1,49 @@ 8.4 +#define SSATB(val) (((val) < -128) ? -128 : (((val) > 127) ? 127 : (val))) 8.5 +#define SSATW(val) (((val) < -32768) ? -32768 : (((val) > 32767) ? 32767 : (val))) 8.6 +#define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) 8.7 +#define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) 8.8 + 8.9 +#define MMX_GETSRC() \ 8.10 + if (mod == 3) \ 8.11 + { \ 8.12 + src = MM[rm]; \ 8.13 + cycles--; \ 8.14 + } \ 8.15 + else \ 8.16 + { \ 8.17 + src.l[0] = readmeml(easeg, eaaddr); \ 8.18 + src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; \ 8.19 + cycles -= 2; \ 8.20 + } 8.21 + 8.22 +#define MMX_ENTER() \ 8.23 + if (!cpu_hasMMX) \ 8.24 + { \ 8.25 + pc = oldpc; \ 8.26 + x86illegal(); \ 8.27 + return 0; \ 8.28 + } \ 8.29 + if (cr0 & 0xc) \ 8.30 + { \ 8.31 + x86_int(7); \ 8.32 + return 0; \ 8.33 + } \ 8.34 + x87_set_mmx() 8.35 + 8.36 +int opEMMS(uint32_t fetchdat) 8.37 +{ 8.38 + if (!cpu_hasMMX) 8.39 + { 8.40 + pc = oldpc; 8.41 + x86illegal(); 8.42 + return 0; 8.43 + } 8.44 + if (cr0 & 4) 8.45 + { 8.46 + x86_int(7); 8.47 + return 0; 8.48 + } 8.49 + x87_emms(); 8.50 + cycles -= 100; /*Guess*/ 8.51 + return 0; 8.52 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/x86_ops_mmx_arith.h Sat Aug 03 15:05:50 2013 +0100 9.3 @@ -0,0 +1,625 @@ 9.4 +int opPADDB_a16(uint32_t fetchdat) 9.5 +{ 9.6 + MMX_REG src; 9.7 + MMX_ENTER(); 9.8 + 9.9 + fetch_ea_16(fetchdat); 9.10 + MMX_GETSRC(); 9.11 + 9.12 + MM[reg].b[0] += src.b[0]; 9.13 + MM[reg].b[1] += src.b[1]; 9.14 + MM[reg].b[2] += src.b[2]; 9.15 + MM[reg].b[3] += src.b[3]; 9.16 + MM[reg].b[4] += src.b[4]; 9.17 + MM[reg].b[5] += src.b[5]; 9.18 + MM[reg].b[6] += src.b[6]; 9.19 + MM[reg].b[7] += src.b[7]; 9.20 + 9.21 + return 0; 9.22 +} 9.23 +int opPADDB_a32(uint32_t fetchdat) 9.24 +{ 9.25 + MMX_REG src; 9.26 + MMX_ENTER(); 9.27 + 9.28 + fetch_ea_32(fetchdat); 9.29 + MMX_GETSRC(); 9.30 + 9.31 + MM[reg].b[0] += src.b[0]; 9.32 + MM[reg].b[1] += src.b[1]; 9.33 + MM[reg].b[2] += src.b[2]; 9.34 + MM[reg].b[3] += src.b[3]; 9.35 + MM[reg].b[4] += src.b[4]; 9.36 + MM[reg].b[5] += src.b[5]; 9.37 + MM[reg].b[6] += src.b[6]; 9.38 + MM[reg].b[7] += src.b[7]; 9.39 + 9.40 + return 0; 9.41 +} 9.42 + 9.43 +int opPADDW_a16(uint32_t fetchdat) 9.44 +{ 9.45 + MMX_REG src; 9.46 + MMX_ENTER(); 9.47 + 9.48 + fetch_ea_16(fetchdat); 9.49 + MMX_GETSRC(); 9.50 + 9.51 + MM[reg].w[0] += src.w[0]; 9.52 + MM[reg].w[1] += src.w[1]; 9.53 + MM[reg].w[2] += src.w[2]; 9.54 + MM[reg].w[3] += src.w[3]; 9.55 + 9.56 + return 0; 9.57 +} 9.58 +int opPADDW_a32(uint32_t fetchdat) 9.59 +{ 9.60 + MMX_REG src; 9.61 + MMX_ENTER(); 9.62 + 9.63 + fetch_ea_32(fetchdat); 9.64 + MMX_GETSRC(); 9.65 + 9.66 + MM[reg].w[0] += src.w[0]; 9.67 + MM[reg].w[1] += src.w[1]; 9.68 + MM[reg].w[2] += src.w[2]; 9.69 + MM[reg].w[3] += src.w[3]; 9.70 + 9.71 + return 0; 9.72 +} 9.73 + 9.74 +int opPADDD_a16(uint32_t fetchdat) 9.75 +{ 9.76 + MMX_REG src; 9.77 + MMX_ENTER(); 9.78 + 9.79 + fetch_ea_16(fetchdat); 9.80 + MMX_GETSRC(); 9.81 + 9.82 + MM[reg].l[0] += src.l[0]; 9.83 + MM[reg].l[1] += src.l[1]; 9.84 + 9.85 + return 0; 9.86 +} 9.87 +int opPADDD_a32(uint32_t fetchdat) 9.88 +{ 9.89 + MMX_REG src; 9.90 + MMX_ENTER(); 9.91 + 9.92 + fetch_ea_32(fetchdat); 9.93 + MMX_GETSRC(); 9.94 + 9.95 + MM[reg].l[0] += src.l[0]; 9.96 + MM[reg].l[1] += src.l[1]; 9.97 + 9.98 + return 0; 9.99 +} 9.100 + 9.101 +int opPADDSB_a16(uint32_t fetchdat) 9.102 +{ 9.103 + MMX_REG src; 9.104 + MMX_ENTER(); 9.105 + 9.106 + fetch_ea_16(fetchdat); 9.107 + MMX_GETSRC(); 9.108 + 9.109 + MM[reg].sb[0] = SSATB(MM[reg].sb[0] + src.sb[0]); 9.110 + MM[reg].sb[1] = SSATB(MM[reg].sb[1] + src.sb[1]); 9.111 + MM[reg].sb[2] = SSATB(MM[reg].sb[2] + src.sb[2]); 9.112 + MM[reg].sb[3] = SSATB(MM[reg].sb[3] + src.sb[3]); 9.113 + MM[reg].sb[4] = SSATB(MM[reg].sb[4] + src.sb[4]); 9.114 + MM[reg].sb[5] = SSATB(MM[reg].sb[5] + src.sb[5]); 9.115 + MM[reg].sb[6] = SSATB(MM[reg].sb[6] + src.sb[6]); 9.116 + MM[reg].sb[7] = SSATB(MM[reg].sb[7] + src.sb[7]); 9.117 + 9.118 + return 0; 9.119 +} 9.120 +int opPADDSB_a32(uint32_t fetchdat) 9.121 +{ 9.122 + MMX_REG src; 9.123 + MMX_ENTER(); 9.124 + 9.125 + fetch_ea_32(fetchdat); 9.126 + MMX_GETSRC(); 9.127 + 9.128 + MM[reg].sb[0] = SSATB(MM[reg].sb[0] + src.sb[0]); 9.129 + MM[reg].sb[1] = SSATB(MM[reg].sb[1] + src.sb[1]); 9.130 + MM[reg].sb[2] = SSATB(MM[reg].sb[2] + src.sb[2]); 9.131 + MM[reg].sb[3] = SSATB(MM[reg].sb[3] + src.sb[3]); 9.132 + MM[reg].sb[4] = SSATB(MM[reg].sb[4] + src.sb[4]); 9.133 + MM[reg].sb[5] = SSATB(MM[reg].sb[5] + src.sb[5]); 9.134 + MM[reg].sb[6] = SSATB(MM[reg].sb[6] + src.sb[6]); 9.135 + MM[reg].sb[7] = SSATB(MM[reg].sb[7] + src.sb[7]); 9.136 + 9.137 + return 0; 9.138 +} 9.139 + 9.140 +int opPADDUSB_a16(uint32_t fetchdat) 9.141 +{ 9.142 + MMX_REG src; 9.143 + MMX_ENTER(); 9.144 + 9.145 + fetch_ea_16(fetchdat); 9.146 + MMX_GETSRC(); 9.147 + 9.148 + MM[reg].b[0] = USATB(MM[reg].b[0] + src.b[0]); 9.149 + MM[reg].b[1] = USATB(MM[reg].b[1] + src.b[1]); 9.150 + MM[reg].b[2] = USATB(MM[reg].b[2] + src.b[2]); 9.151 + MM[reg].b[3] = USATB(MM[reg].b[3] + src.b[3]); 9.152 + MM[reg].b[4] = USATB(MM[reg].b[4] + src.b[4]); 9.153 + MM[reg].b[5] = USATB(MM[reg].b[5] + src.b[5]); 9.154 + MM[reg].b[6] = USATB(MM[reg].b[6] + src.b[6]); 9.155 + MM[reg].b[7] = USATB(MM[reg].b[7] + src.b[7]); 9.156 + 9.157 + return 0; 9.158 +} 9.159 +int opPADDUSB_a32(uint32_t fetchdat) 9.160 +{ 9.161 + MMX_REG src; 9.162 + MMX_ENTER(); 9.163 + 9.164 + fetch_ea_32(fetchdat); 9.165 + MMX_GETSRC(); 9.166 + 9.167 + MM[reg].b[0] = USATB(MM[reg].b[0] + src.b[0]); 9.168 + MM[reg].b[1] = USATB(MM[reg].b[1] + src.b[1]); 9.169 + MM[reg].b[2] = USATB(MM[reg].b[2] + src.b[2]); 9.170 + MM[reg].b[3] = USATB(MM[reg].b[3] + src.b[3]); 9.171 + MM[reg].b[4] = USATB(MM[reg].b[4] + src.b[4]); 9.172 + MM[reg].b[5] = USATB(MM[reg].b[5] + src.b[5]); 9.173 + MM[reg].b[6] = USATB(MM[reg].b[6] + src.b[6]); 9.174 + MM[reg].b[7] = USATB(MM[reg].b[7] + src.b[7]); 9.175 + 9.176 + return 0; 9.177 +} 9.178 + 9.179 +int opPADDSW_a16(uint32_t fetchdat) 9.180 +{ 9.181 + MMX_REG src; 9.182 + MMX_ENTER(); 9.183 + 9.184 + fetch_ea_16(fetchdat); 9.185 + MMX_GETSRC(); 9.186 + 9.187 + MM[reg].sw[0] = SSATW(MM[reg].sw[0] + src.sw[0]); 9.188 + MM[reg].sw[1] = SSATW(MM[reg].sw[1] + src.sw[1]); 9.189 + MM[reg].sw[2] = SSATW(MM[reg].sw[2] + src.sw[2]); 9.190 + MM[reg].sw[3] = SSATW(MM[reg].sw[3] + src.sw[3]); 9.191 + 9.192 + return 0; 9.193 +} 9.194 +int opPADDSW_a32(uint32_t fetchdat) 9.195 +{ 9.196 + MMX_REG src; 9.197 + MMX_ENTER(); 9.198 + 9.199 + fetch_ea_32(fetchdat); 9.200 + MMX_GETSRC(); 9.201 + 9.202 + MM[reg].sw[0] = SSATW(MM[reg].sw[0] + src.sw[0]); 9.203 + MM[reg].sw[1] = SSATW(MM[reg].sw[1] + src.sw[1]); 9.204 + MM[reg].sw[2] = SSATW(MM[reg].sw[2] + src.sw[2]); 9.205 + MM[reg].sw[3] = SSATW(MM[reg].sw[3] + src.sw[3]); 9.206 + 9.207 + return 0; 9.208 +} 9.209 + 9.210 +int opPADDUSW_a16(uint32_t fetchdat) 9.211 +{ 9.212 + MMX_REG src; 9.213 + MMX_ENTER(); 9.214 + 9.215 + fetch_ea_16(fetchdat); 9.216 + MMX_GETSRC(); 9.217 + 9.218 + MM[reg].w[0] = USATW(MM[reg].w[0] + src.w[0]); 9.219 + MM[reg].w[1] = USATW(MM[reg].w[1] + src.w[1]); 9.220 + MM[reg].w[2] = USATW(MM[reg].w[2] + src.w[2]); 9.221 + MM[reg].w[3] = USATW(MM[reg].w[3] + src.w[3]); 9.222 + 9.223 + return 0; 9.224 +} 9.225 +int opPADDUSW_a32(uint32_t fetchdat) 9.226 +{ 9.227 + MMX_REG src; 9.228 + MMX_ENTER(); 9.229 + 9.230 + fetch_ea_32(fetchdat); 9.231 + MMX_GETSRC(); 9.232 + 9.233 + MM[reg].w[0] = USATW(MM[reg].w[0] + src.w[0]); 9.234 + MM[reg].w[1] = USATW(MM[reg].w[1] + src.w[1]); 9.235 + MM[reg].w[2] = USATW(MM[reg].w[2] + src.w[2]); 9.236 + MM[reg].w[3] = USATW(MM[reg].w[3] + src.w[3]); 9.237 + 9.238 + return 0; 9.239 +} 9.240 + 9.241 +int opPMADDWD_a16(uint32_t fetchdat) 9.242 +{ 9.243 + MMX_REG src; 9.244 + MMX_ENTER(); 9.245 + 9.246 + fetch_ea_16(fetchdat); 9.247 + MMX_GETSRC(); 9.248 + 9.249 + if (MM[reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) 9.250 + MM[reg].l[0] = 0x80000000; 9.251 + else 9.252 + 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]); 9.253 + 9.254 + if (MM[reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) 9.255 + MM[reg].l[1] = 0x80000000; 9.256 + else 9.257 + 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]); 9.258 + 9.259 + return 0; 9.260 +} 9.261 +int opPMADDWD_a32(uint32_t fetchdat) 9.262 +{ 9.263 + MMX_REG src; 9.264 + MMX_ENTER(); 9.265 + 9.266 + fetch_ea_32(fetchdat); 9.267 + MMX_GETSRC(); 9.268 + 9.269 + if (MM[reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) 9.270 + MM[reg].l[0] = 0x80000000; 9.271 + else 9.272 + 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]); 9.273 + 9.274 + if (MM[reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) 9.275 + MM[reg].l[1] = 0x80000000; 9.276 + else 9.277 + 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]); 9.278 + 9.279 + return 0; 9.280 +} 9.281 + 9.282 + 9.283 +int opPMULLW_a16(uint32_t fetchdat) 9.284 +{ 9.285 + MMX_ENTER(); 9.286 + 9.287 + fetch_ea_16(fetchdat); 9.288 + if (mod == 3) 9.289 + { 9.290 + MM[reg].w[0] *= MM[rm].w[0]; 9.291 + MM[reg].w[1] *= MM[rm].w[1]; 9.292 + MM[reg].w[2] *= MM[rm].w[2]; 9.293 + MM[reg].w[3] *= MM[rm].w[3]; 9.294 + cycles--; 9.295 + } 9.296 + else 9.297 + { 9.298 + MMX_REG src; 9.299 + 9.300 + src.l[0] = readmeml(easeg, eaaddr); 9.301 + src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 9.302 + MM[reg].w[0] *= src.w[0]; 9.303 + MM[reg].w[1] *= src.w[1]; 9.304 + MM[reg].w[2] *= src.w[2]; 9.305 + MM[reg].w[3] *= src.w[3]; 9.306 + cycles -= 2; 9.307 + } 9.308 + return 0; 9.309 +} 9.310 +int opPMULLW_a32(uint32_t fetchdat) 9.311 +{ 9.312 + MMX_ENTER(); 9.313 + 9.314 + fetch_ea_32(fetchdat); 9.315 + if (mod == 3) 9.316 + { 9.317 + MM[reg].w[0] *= MM[rm].w[0]; 9.318 + MM[reg].w[1] *= MM[rm].w[1]; 9.319 + MM[reg].w[2] *= MM[rm].w[2]; 9.320 + MM[reg].w[3] *= MM[rm].w[3]; 9.321 + cycles--; 9.322 + } 9.323 + else 9.324 + { 9.325 + MMX_REG src; 9.326 + 9.327 + src.l[0] = readmeml(easeg, eaaddr); 9.328 + src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 9.329 + MM[reg].w[0] *= src.w[0]; 9.330 + MM[reg].w[1] *= src.w[1]; 9.331 + MM[reg].w[2] *= src.w[2]; 9.332 + MM[reg].w[3] *= src.w[3]; 9.333 + cycles -= 2; 9.334 + } 9.335 + return 0; 9.336 +} 9.337 + 9.338 +int opPMULHW_a16(uint32_t fetchdat) 9.339 +{ 9.340 + MMX_ENTER(); 9.341 + 9.342 + fetch_ea_16(fetchdat); 9.343 + if (mod == 3) 9.344 + { 9.345 + MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)MM[rm].sw[0]) >> 16; 9.346 + MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)MM[rm].sw[1]) >> 16; 9.347 + MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)MM[rm].sw[2]) >> 16; 9.348 + MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)MM[rm].sw[3]) >> 16; 9.349 + cycles--; 9.350 + } 9.351 + else 9.352 + { 9.353 + MMX_REG src; 9.354 + 9.355 + src.l[0] = readmeml(easeg, eaaddr); 9.356 + src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 9.357 + MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)src.sw[0]) >> 16; 9.358 + MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)src.sw[1]) >> 16; 9.359 + MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)src.sw[2]) >> 16; 9.360 + MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)src.sw[3]) >> 16; 9.361 + cycles -= 2; 9.362 + } 9.363 + return 0; 9.364 +} 9.365 +int opPMULHW_a32(uint32_t fetchdat) 9.366 +{ 9.367 + MMX_ENTER(); 9.368 + 9.369 + fetch_ea_32(fetchdat); 9.370 + if (mod == 3) 9.371 + { 9.372 + MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)MM[rm].sw[0]) >> 16; 9.373 + MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)MM[rm].sw[1]) >> 16; 9.374 + MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)MM[rm].sw[2]) >> 16; 9.375 + MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)MM[rm].sw[3]) >> 16; 9.376 + cycles--; 9.377 + } 9.378 + else 9.379 + { 9.380 + MMX_REG src; 9.381 + 9.382 + src.l[0] = readmeml(easeg, eaaddr); 9.383 + src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 9.384 + MM[reg].w[0] = ((int32_t)MM[reg].sw[0] * (int32_t)src.sw[0]) >> 16; 9.385 + MM[reg].w[1] = ((int32_t)MM[reg].sw[1] * (int32_t)src.sw[1]) >> 16; 9.386 + MM[reg].w[2] = ((int32_t)MM[reg].sw[2] * (int32_t)src.sw[2]) >> 16; 9.387 + MM[reg].w[3] = ((int32_t)MM[reg].sw[3] * (int32_t)src.sw[3]) >> 16; 9.388 + cycles -= 2; 9.389 + } 9.390 + return 0; 9.391 +} 9.392 + 9.393 +int opPSUBB_a16(uint32_t fetchdat) 9.394 +{ 9.395 + MMX_REG src; 9.396 + MMX_ENTER(); 9.397 + 9.398 + fetch_ea_16(fetchdat); 9.399 + MMX_GETSRC(); 9.400 + 9.401 + MM[reg].b[0] -= src.b[0]; 9.402 + MM[reg].b[1] -= src.b[1]; 9.403 + MM[reg].b[2] -= src.b[2]; 9.404 + MM[reg].b[3] -= src.b[3]; 9.405 + MM[reg].b[4] -= src.b[4]; 9.406 + MM[reg].b[5] -= src.b[5]; 9.407 + MM[reg].b[6] -= src.b[6]; 9.408 + MM[reg].b[7] -= src.b[7]; 9.409 + 9.410 + return 0; 9.411 +} 9.412 +int opPSUBB_a32(uint32_t fetchdat) 9.413 +{ 9.414 + MMX_REG src; 9.415 + MMX_ENTER(); 9.416 + 9.417 + fetch_ea_32(fetchdat); 9.418 + MMX_GETSRC(); 9.419 + 9.420 + MM[reg].b[0] -= src.b[0]; 9.421 + MM[reg].b[1] -= src.b[1]; 9.422 + MM[reg].b[2] -= src.b[2]; 9.423 + MM[reg].b[3] -= src.b[3]; 9.424 + MM[reg].b[4] -= src.b[4]; 9.425 + MM[reg].b[5] -= src.b[5]; 9.426 + MM[reg].b[6] -= src.b[6]; 9.427 + MM[reg].b[7] -= src.b[7]; 9.428 + 9.429 + return 0; 9.430 +} 9.431 + 9.432 +int opPSUBW_a16(uint32_t fetchdat) 9.433 +{ 9.434 + MMX_REG src; 9.435 + MMX_ENTER(); 9.436 + 9.437 + fetch_ea_16(fetchdat); 9.438 + MMX_GETSRC(); 9.439 + 9.440 + MM[reg].w[0] -= src.w[0]; 9.441 + MM[reg].w[1] -= src.w[1]; 9.442 + MM[reg].w[2] -= src.w[2]; 9.443 + MM[reg].w[3] -= src.w[3]; 9.444 + 9.445 + return 0; 9.446 +} 9.447 +int opPSUBW_a32(uint32_t fetchdat) 9.448 +{ 9.449 + MMX_REG src; 9.450 + MMX_ENTER(); 9.451 + 9.452 + fetch_ea_32(fetchdat); 9.453 + MMX_GETSRC(); 9.454 + 9.455 + MM[reg].w[0] -= src.w[0]; 9.456 + MM[reg].w[1] -= src.w[1]; 9.457 + MM[reg].w[2] -= src.w[2]; 9.458 + MM[reg].w[3] -= src.w[3]; 9.459 + 9.460 + return 0; 9.461 +} 9.462 + 9.463 +int opPSUBD_a16(uint32_t fetchdat) 9.464 +{ 9.465 + MMX_REG src; 9.466 + MMX_ENTER(); 9.467 + 9.468 + fetch_ea_16(fetchdat); 9.469 + MMX_GETSRC(); 9.470 + 9.471 + MM[reg].l[0] -= src.l[0]; 9.472 + MM[reg].l[1] -= src.l[1]; 9.473 + 9.474 + return 0; 9.475 +} 9.476 +int opPSUBD_a32(uint32_t fetchdat) 9.477 +{ 9.478 + MMX_REG src; 9.479 + MMX_ENTER(); 9.480 + 9.481 + fetch_ea_32(fetchdat); 9.482 + MMX_GETSRC(); 9.483 + 9.484 + MM[reg].l[0] -= src.l[0]; 9.485 + MM[reg].l[1] -= src.l[1]; 9.486 + 9.487 + return 0; 9.488 +} 9.489 + 9.490 +int opPSUBSB_a16(uint32_t fetchdat) 9.491 +{ 9.492 + MMX_REG src; 9.493 + MMX_ENTER(); 9.494 + 9.495 + fetch_ea_16(fetchdat); 9.496 + MMX_GETSRC(); 9.497 + 9.498 + MM[reg].sb[0] = SSATB(MM[reg].sb[0] - src.sb[0]); 9.499 + MM[reg].sb[1] = SSATB(MM[reg].sb[1] - src.sb[1]); 9.500 + MM[reg].sb[2] = SSATB(MM[reg].sb[2] - src.sb[2]); 9.501 + MM[reg].sb[3] = SSATB(MM[reg].sb[3] - src.sb[3]); 9.502 + MM[reg].sb[4] = SSATB(MM[reg].sb[4] - src.sb[4]); 9.503 + MM[reg].sb[5] = SSATB(MM[reg].sb[5] - src.sb[5]); 9.504 + MM[reg].sb[6] = SSATB(MM[reg].sb[6] - src.sb[6]); 9.505 + MM[reg].sb[7] = SSATB(MM[reg].sb[7] - src.sb[7]); 9.506 + 9.507 + return 0; 9.508 +} 9.509 +int opPSUBSB_a32(uint32_t fetchdat) 9.510 +{ 9.511 + MMX_REG src; 9.512 + MMX_ENTER(); 9.513 + 9.514 + fetch_ea_32(fetchdat); 9.515 + MMX_GETSRC(); 9.516 + 9.517 + MM[reg].sb[0] = SSATB(MM[reg].sb[0] - src.sb[0]); 9.518 + MM[reg].sb[1] = SSATB(MM[reg].sb[1] - src.sb[1]); 9.519 + MM[reg].sb[2] = SSATB(MM[reg].sb[2] - src.sb[2]); 9.520 + MM[reg].sb[3] = SSATB(MM[reg].sb[3] - src.sb[3]); 9.521 + MM[reg].sb[4] = SSATB(MM[reg].sb[4] - src.sb[4]); 9.522 + MM[reg].sb[5] = SSATB(MM[reg].sb[5] - src.sb[5]); 9.523 + MM[reg].sb[6] = SSATB(MM[reg].sb[6] - src.sb[6]); 9.524 + MM[reg].sb[7] = SSATB(MM[reg].sb[7] - src.sb[7]); 9.525 + 9.526 + return 0; 9.527 +} 9.528 + 9.529 +int opPSUBUSB_a16(uint32_t fetchdat) 9.530 +{ 9.531 + MMX_REG src; 9.532 + MMX_ENTER(); 9.533 + 9.534 + fetch_ea_16(fetchdat); 9.535 + MMX_GETSRC(); 9.536 + 9.537 + MM[reg].b[0] = USATB(MM[reg].b[0] - src.b[0]); 9.538 + MM[reg].b[1] = USATB(MM[reg].b[1] - src.b[1]); 9.539 + MM[reg].b[2] = USATB(MM[reg].b[2] - src.b[2]); 9.540 + MM[reg].b[3] = USATB(MM[reg].b[3] - src.b[3]); 9.541 + MM[reg].b[4] = USATB(MM[reg].b[4] - src.b[4]); 9.542 + MM[reg].b[5] = USATB(MM[reg].b[5] - src.b[5]); 9.543 + MM[reg].b[6] = USATB(MM[reg].b[6] - src.b[6]); 9.544 + MM[reg].b[7] = USATB(MM[reg].b[7] - src.b[7]); 9.545 + 9.546 + return 0; 9.547 +} 9.548 +int opPSUBUSB_a32(uint32_t fetchdat) 9.549 +{ 9.550 + MMX_REG src; 9.551 + MMX_ENTER(); 9.552 + 9.553 + fetch_ea_32(fetchdat); 9.554 + MMX_GETSRC(); 9.555 + 9.556 + MM[reg].b[0] = USATB(MM[reg].b[0] - src.b[0]); 9.557 + MM[reg].b[1] = USATB(MM[reg].b[1] - src.b[1]); 9.558 + MM[reg].b[2] = USATB(MM[reg].b[2] - src.b[2]); 9.559 + MM[reg].b[3] = USATB(MM[reg].b[3] - src.b[3]); 9.560 + MM[reg].b[4] = USATB(MM[reg].b[4] - src.b[4]); 9.561 + MM[reg].b[5] = USATB(MM[reg].b[5] - src.b[5]); 9.562 + MM[reg].b[6] = USATB(MM[reg].b[6] - src.b[6]); 9.563 + MM[reg].b[7] = USATB(MM[reg].b[7] - src.b[7]); 9.564 + 9.565 + return 0; 9.566 +} 9.567 + 9.568 +int opPSUBSW_a16(uint32_t fetchdat) 9.569 +{ 9.570 + MMX_REG src; 9.571 + MMX_ENTER(); 9.572 + 9.573 + fetch_ea_16(fetchdat); 9.574 + MMX_GETSRC(); 9.575 + 9.576 + MM[reg].sw[0] = SSATW(MM[reg].sw[0] - src.sw[0]); 9.577 + MM[reg].sw[1] = SSATW(MM[reg].sw[1] - src.sw[1]); 9.578 + MM[reg].sw[2] = SSATW(MM[reg].sw[2] - src.sw[2]); 9.579 + MM[reg].sw[3] = SSATW(MM[reg].sw[3] - src.sw[3]); 9.580 + 9.581 + return 0; 9.582 +} 9.583 +int opPSUBSW_a32(uint32_t fetchdat) 9.584 +{ 9.585 + MMX_REG src; 9.586 + MMX_ENTER(); 9.587 + 9.588 + fetch_ea_32(fetchdat); 9.589 + MMX_GETSRC(); 9.590 + 9.591 + MM[reg].sw[0] = SSATW(MM[reg].sw[0] - src.sw[0]); 9.592 + MM[reg].sw[1] = SSATW(MM[reg].sw[1] - src.sw[1]); 9.593 + MM[reg].sw[2] = SSATW(MM[reg].sw[2] - src.sw[2]); 9.594 + MM[reg].sw[3] = SSATW(MM[reg].sw[3] - src.sw[3]); 9.595 + 9.596 + return 0; 9.597 +} 9.598 + 9.599 +int opPSUBUSW_a16(uint32_t fetchdat) 9.600 +{ 9.601 + MMX_REG src; 9.602 + MMX_ENTER(); 9.603 + 9.604 + fetch_ea_16(fetchdat); 9.605 + MMX_GETSRC(); 9.606 + 9.607 + MM[reg].w[0] = USATW(MM[reg].w[0] - src.w[0]); 9.608 + MM[reg].w[1] = USATW(MM[reg].w[1] - src.w[1]); 9.609 + MM[reg].w[2] = USATW(MM[reg].w[2] - src.w[2]); 9.610 + MM[reg].w[3] = USATW(MM[reg].w[3] - src.w[3]); 9.611 + 9.612 + return 0; 9.613 +} 9.614 +int opPSUBUSW_a32(uint32_t fetchdat) 9.615 +{ 9.616 + MMX_REG src; 9.617 + MMX_ENTER(); 9.618 + 9.619 + fetch_ea_32(fetchdat); 9.620 + MMX_GETSRC(); 9.621 + 9.622 + MM[reg].w[0] = USATW(MM[reg].w[0] - src.w[0]); 9.623 + MM[reg].w[1] = USATW(MM[reg].w[1] - src.w[1]); 9.624 + MM[reg].w[2] = USATW(MM[reg].w[2] - src.w[2]); 9.625 + MM[reg].w[3] = USATW(MM[reg].w[3] - src.w[3]); 9.626 + 9.627 + return 0; 9.628 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/x86_ops_mmx_cmp.h Sat Aug 03 15:05:50 2013 +0100 10.3 @@ -0,0 +1,205 @@ 10.4 +static int opPCMPEQB_a16(uint32_t fetchdat) 10.5 +{ 10.6 + MMX_REG src; 10.7 + 10.8 + MMX_ENTER(); 10.9 + 10.10 + fetch_ea_16(fetchdat); 10.11 + MMX_GETSRC(); 10.12 + 10.13 + MM[reg].b[0] = (MM[reg].b[0] == src.b[0]) ? 0xff : 0; 10.14 + MM[reg].b[1] = (MM[reg].b[1] == src.b[1]) ? 0xff : 0; 10.15 + MM[reg].b[2] = (MM[reg].b[2] == src.b[2]) ? 0xff : 0; 10.16 + MM[reg].b[3] = (MM[reg].b[3] == src.b[3]) ? 0xff : 0; 10.17 + MM[reg].b[4] = (MM[reg].b[4] == src.b[4]) ? 0xff : 0; 10.18 + MM[reg].b[5] = (MM[reg].b[5] == src.b[5]) ? 0xff : 0; 10.19 + MM[reg].b[6] = (MM[reg].b[6] == src.b[6]) ? 0xff : 0; 10.20 + MM[reg].b[7] = (MM[reg].b[7] == src.b[7]) ? 0xff : 0; 10.21 + 10.22 + return 0; 10.23 +} 10.24 +static int opPCMPEQB_a32(uint32_t fetchdat) 10.25 +{ 10.26 + MMX_REG src; 10.27 + 10.28 + MMX_ENTER(); 10.29 + 10.30 + fetch_ea_32(fetchdat); 10.31 + MMX_GETSRC(); 10.32 + 10.33 + MM[reg].b[0] = (MM[reg].b[0] == src.b[0]) ? 0xff : 0; 10.34 + MM[reg].b[1] = (MM[reg].b[1] == src.b[1]) ? 0xff : 0; 10.35 + MM[reg].b[2] = (MM[reg].b[2] == src.b[2]) ? 0xff : 0; 10.36 + MM[reg].b[3] = (MM[reg].b[3] == src.b[3]) ? 0xff : 0; 10.37 + MM[reg].b[4] = (MM[reg].b[4] == src.b[4]) ? 0xff : 0; 10.38 + MM[reg].b[5] = (MM[reg].b[5] == src.b[5]) ? 0xff : 0; 10.39 + MM[reg].b[6] = (MM[reg].b[6] == src.b[6]) ? 0xff : 0; 10.40 + MM[reg].b[7] = (MM[reg].b[7] == src.b[7]) ? 0xff : 0; 10.41 + 10.42 + return 0; 10.43 +} 10.44 + 10.45 +static int opPCMPGTB_a16(uint32_t fetchdat) 10.46 +{ 10.47 + MMX_REG src; 10.48 + 10.49 + MMX_ENTER(); 10.50 + 10.51 + fetch_ea_16(fetchdat); 10.52 + MMX_GETSRC(); 10.53 + 10.54 + MM[reg].b[0] = (MM[reg].sb[0] > src.sb[0]) ? 0xff : 0; 10.55 + MM[reg].b[1] = (MM[reg].sb[1] > src.sb[1]) ? 0xff : 0; 10.56 + MM[reg].b[2] = (MM[reg].sb[2] > src.sb[2]) ? 0xff : 0; 10.57 + MM[reg].b[3] = (MM[reg].sb[3] > src.sb[3]) ? 0xff : 0; 10.58 + MM[reg].b[4] = (MM[reg].sb[4] > src.sb[4]) ? 0xff : 0; 10.59 + MM[reg].b[5] = (MM[reg].sb[5] > src.sb[5]) ? 0xff : 0; 10.60 + MM[reg].b[6] = (MM[reg].sb[6] > src.sb[6]) ? 0xff : 0; 10.61 + MM[reg].b[7] = (MM[reg].sb[7] > src.sb[7]) ? 0xff : 0; 10.62 + 10.63 + return 0; 10.64 +} 10.65 +static int opPCMPGTB_a32(uint32_t fetchdat) 10.66 +{ 10.67 + MMX_REG src; 10.68 + 10.69 + MMX_ENTER(); 10.70 + 10.71 + fetch_ea_32(fetchdat); 10.72 + MMX_GETSRC(); 10.73 + 10.74 + MM[reg].b[0] = (MM[reg].sb[0] > src.sb[0]) ? 0xff : 0; 10.75 + MM[reg].b[1] = (MM[reg].sb[1] > src.sb[1]) ? 0xff : 0; 10.76 + MM[reg].b[2] = (MM[reg].sb[2] > src.sb[2]) ? 0xff : 0; 10.77 + MM[reg].b[3] = (MM[reg].sb[3] > src.sb[3]) ? 0xff : 0; 10.78 + MM[reg].b[4] = (MM[reg].sb[4] > src.sb[4]) ? 0xff : 0; 10.79 + MM[reg].b[5] = (MM[reg].sb[5] > src.sb[5]) ? 0xff : 0; 10.80 + MM[reg].b[6] = (MM[reg].sb[6] > src.sb[6]) ? 0xff : 0; 10.81 + MM[reg].b[7] = (MM[reg].sb[7] > src.sb[7]) ? 0xff : 0; 10.82 + 10.83 + return 0; 10.84 +} 10.85 + 10.86 +static int opPCMPEQW_a16(uint32_t fetchdat) 10.87 +{ 10.88 + MMX_REG src; 10.89 + 10.90 + MMX_ENTER(); 10.91 + 10.92 + fetch_ea_16(fetchdat); 10.93 + MMX_GETSRC(); 10.94 + 10.95 + MM[reg].w[0] = (MM[reg].w[0] == src.w[0]) ? 0xffff : 0; 10.96 + MM[reg].w[1] = (MM[reg].w[1] == src.w[1]) ? 0xffff : 0; 10.97 + MM[reg].w[2] = (MM[reg].w[2] == src.w[2]) ? 0xffff : 0; 10.98 + MM[reg].w[3] = (MM[reg].w[3] == src.w[3]) ? 0xffff : 0; 10.99 + 10.100 + return 0; 10.101 +} 10.102 +static int opPCMPEQW_a32(uint32_t fetchdat) 10.103 +{ 10.104 + MMX_REG src; 10.105 + 10.106 + MMX_ENTER(); 10.107 + 10.108 + fetch_ea_32(fetchdat); 10.109 + MMX_GETSRC(); 10.110 + 10.111 + MM[reg].w[0] = (MM[reg].w[0] == src.w[0]) ? 0xffff : 0; 10.112 + MM[reg].w[1] = (MM[reg].w[1] == src.w[1]) ? 0xffff : 0; 10.113 + MM[reg].w[2] = (MM[reg].w[2] == src.w[2]) ? 0xffff : 0; 10.114 + MM[reg].w[3] = (MM[reg].w[3] == src.w[3]) ? 0xffff : 0; 10.115 + 10.116 + return 0; 10.117 +} 10.118 + 10.119 +static int opPCMPGTW_a16(uint32_t fetchdat) 10.120 +{ 10.121 + MMX_REG src; 10.122 + 10.123 + MMX_ENTER(); 10.124 + 10.125 + fetch_ea_16(fetchdat); 10.126 + MMX_GETSRC(); 10.127 + 10.128 + MM[reg].w[0] = (MM[reg].sw[0] > src.sw[0]) ? 0xffff : 0; 10.129 + MM[reg].w[1] = (MM[reg].sw[1] > src.sw[1]) ? 0xffff : 0; 10.130 + MM[reg].w[2] = (MM[reg].sw[2] > src.sw[2]) ? 0xffff : 0; 10.131 + MM[reg].w[3] = (MM[reg].sw[3] > src.sw[3]) ? 0xffff : 0; 10.132 + 10.133 + return 0; 10.134 +} 10.135 +static int opPCMPGTW_a32(uint32_t fetchdat) 10.136 +{ 10.137 + MMX_REG src; 10.138 + 10.139 + MMX_ENTER(); 10.140 + 10.141 + fetch_ea_32(fetchdat); 10.142 + MMX_GETSRC(); 10.143 + 10.144 + MM[reg].w[0] = (MM[reg].sw[0] > src.sw[0]) ? 0xffff : 0; 10.145 + MM[reg].w[1] = (MM[reg].sw[1] > src.sw[1]) ? 0xffff : 0; 10.146 + MM[reg].w[2] = (MM[reg].sw[2] > src.sw[2]) ? 0xffff : 0; 10.147 + MM[reg].w[3] = (MM[reg].sw[3] > src.sw[3]) ? 0xffff : 0; 10.148 + 10.149 + return 0; 10.150 +} 10.151 + 10.152 +static int opPCMPEQD_a16(uint32_t fetchdat) 10.153 +{ 10.154 + MMX_REG src; 10.155 + 10.156 + MMX_ENTER(); 10.157 + 10.158 + fetch_ea_16(fetchdat); 10.159 + MMX_GETSRC(); 10.160 + 10.161 + MM[reg].l[0] = (MM[reg].l[0] == src.l[0]) ? 0xffffffff : 0; 10.162 + MM[reg].l[1] = (MM[reg].l[1] == src.l[1]) ? 0xffffffff : 0; 10.163 + 10.164 + return 0; 10.165 +} 10.166 +static int opPCMPEQD_a32(uint32_t fetchdat) 10.167 +{ 10.168 + MMX_REG src; 10.169 + 10.170 + MMX_ENTER(); 10.171 + 10.172 + fetch_ea_16(fetchdat); 10.173 + MMX_GETSRC(); 10.174 + 10.175 + MM[reg].l[0] = (MM[reg].l[0] == src.l[0]) ? 0xffffffff : 0; 10.176 + MM[reg].l[1] = (MM[reg].l[1] == src.l[1]) ? 0xffffffff : 0; 10.177 + 10.178 + return 0; 10.179 +} 10.180 + 10.181 +static int opPCMPGTD_a16(uint32_t fetchdat) 10.182 +{ 10.183 + MMX_REG src; 10.184 + 10.185 + MMX_ENTER(); 10.186 + 10.187 + fetch_ea_16(fetchdat); 10.188 + MMX_GETSRC(); 10.189 + 10.190 + MM[reg].l[0] = (MM[reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; 10.191 + MM[reg].l[1] = (MM[reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; 10.192 + 10.193 + return 0; 10.194 +} 10.195 +static int opPCMPGTD_a32(uint32_t fetchdat) 10.196 +{ 10.197 + MMX_REG src; 10.198 + 10.199 + MMX_ENTER(); 10.200 + 10.201 + fetch_ea_16(fetchdat); 10.202 + MMX_GETSRC(); 10.203 + 10.204 + MM[reg].l[0] = (MM[reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; 10.205 + MM[reg].l[1] = (MM[reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; 10.206 + 10.207 + return 0; 10.208 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/x86_ops_mmx_logic.h Sat Aug 03 15:05:50 2013 +0100 11.3 @@ -0,0 +1,91 @@ 11.4 +int opPAND_a16(uint32_t fetchdat) 11.5 +{ 11.6 + MMX_REG src; 11.7 + MMX_ENTER(); 11.8 + 11.9 + fetch_ea_16(fetchdat); 11.10 + MMX_GETSRC(); 11.11 + 11.12 + MM[reg].q &= src.q; 11.13 + return 0; 11.14 +} 11.15 +int opPAND_a32(uint32_t fetchdat) 11.16 +{ 11.17 + MMX_REG src; 11.18 + MMX_ENTER(); 11.19 + 11.20 + fetch_ea_32(fetchdat); 11.21 + MMX_GETSRC(); 11.22 + 11.23 + MM[reg].q &= src.q; 11.24 + return 0; 11.25 +} 11.26 + 11.27 +int opPANDN_a16(uint32_t fetchdat) 11.28 +{ 11.29 + MMX_REG src; 11.30 + MMX_ENTER(); 11.31 + 11.32 + fetch_ea_16(fetchdat); 11.33 + MMX_GETSRC(); 11.34 + 11.35 + MM[reg].q &= ~src.q; 11.36 + return 0; 11.37 +} 11.38 +int opPANDN_a32(uint32_t fetchdat) 11.39 +{ 11.40 + MMX_REG src; 11.41 + MMX_ENTER(); 11.42 + 11.43 + fetch_ea_32(fetchdat); 11.44 + MMX_GETSRC(); 11.45 + 11.46 + MM[reg].q &= ~src.q; 11.47 + return 0; 11.48 +} 11.49 + 11.50 +int opPOR_a16(uint32_t fetchdat) 11.51 +{ 11.52 + MMX_REG src; 11.53 + MMX_ENTER(); 11.54 + 11.55 + fetch_ea_16(fetchdat); 11.56 + MMX_GETSRC(); 11.57 + 11.58 + MM[reg].q |= src.q; 11.59 + return 0; 11.60 +} 11.61 +int opPOR_a32(uint32_t fetchdat) 11.62 +{ 11.63 + MMX_REG src; 11.64 + MMX_ENTER(); 11.65 + 11.66 + fetch_ea_32(fetchdat); 11.67 + MMX_GETSRC(); 11.68 + 11.69 + MM[reg].q |= src.q; 11.70 + return 0; 11.71 +} 11.72 + 11.73 +int opPXOR_a16(uint32_t fetchdat) 11.74 +{ 11.75 + MMX_REG src; 11.76 + MMX_ENTER(); 11.77 + 11.78 + fetch_ea_16(fetchdat); 11.79 + MMX_GETSRC(); 11.80 + 11.81 + MM[reg].q ^= src.q; 11.82 + return 0; 11.83 +} 11.84 +int opPXOR_a32(uint32_t fetchdat) 11.85 +{ 11.86 + MMX_REG src; 11.87 + MMX_ENTER(); 11.88 + 11.89 + fetch_ea_32(fetchdat); 11.90 + MMX_GETSRC(); 11.91 + 11.92 + MM[reg].q ^= src.q; 11.93 + return 0; 11.94 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/x86_ops_mmx_mov.h Sat Aug 03 15:05:50 2013 +0100 12.3 @@ -0,0 +1,163 @@ 12.4 +int opMOVD_l_mm_a16(uint32_t fetchdat) 12.5 +{ 12.6 + MMX_ENTER(); 12.7 + 12.8 + fetch_ea_16(fetchdat); 12.9 + if (mod == 3) 12.10 + { 12.11 + MM[reg].l[0] = regs[rm].l; 12.12 + MM[reg].l[1] = 0; 12.13 + cycles--; 12.14 + } 12.15 + else 12.16 + { 12.17 + uint32_t dst; 12.18 + 12.19 + dst = readmeml(easeg, eaaddr); if (abrt) return 0; 12.20 + MM[reg].l[0] = dst; 12.21 + MM[reg].l[1] = 0; 12.22 + 12.23 + cycles -= 2; 12.24 + } 12.25 + return 0; 12.26 +} 12.27 +int opMOVD_l_mm_a32(uint32_t fetchdat) 12.28 +{ 12.29 + MMX_ENTER(); 12.30 + 12.31 + fetch_ea_32(fetchdat); 12.32 + if (mod == 3) 12.33 + { 12.34 + MM[reg].l[0] = regs[rm].l; 12.35 + MM[reg].l[1] = 0; 12.36 + cycles--; 12.37 + } 12.38 + else 12.39 + { 12.40 + uint32_t dst; 12.41 + 12.42 + dst = readmeml(easeg, eaaddr); if (abrt) return 0; 12.43 + MM[reg].l[0] = dst; 12.44 + MM[reg].l[1] = 0; 12.45 + 12.46 + cycles -= 2; 12.47 + } 12.48 + return 0; 12.49 +} 12.50 + 12.51 +int opMOVD_mm_l_a16(uint32_t fetchdat) 12.52 +{ 12.53 + MMX_ENTER(); 12.54 + 12.55 + fetch_ea_16(fetchdat); 12.56 + if (mod == 3) 12.57 + { 12.58 + regs[rm].l = MM[reg].l[0]; 12.59 + cycles--; 12.60 + } 12.61 + else 12.62 + { 12.63 + writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0; 12.64 + cycles -= 2; 12.65 + } 12.66 + return 0; 12.67 +} 12.68 +int opMOVD_mm_l_a32(uint32_t fetchdat) 12.69 +{ 12.70 + MMX_ENTER(); 12.71 + 12.72 + fetch_ea_32(fetchdat); 12.73 + if (mod == 3) 12.74 + { 12.75 + regs[rm].l = MM[reg].l[0]; 12.76 + cycles--; 12.77 + } 12.78 + else 12.79 + { 12.80 + writememl(easeg, eaaddr, MM[reg].l[0]); if (abrt) return 0; 12.81 + cycles -= 2; 12.82 + } 12.83 + return 0; 12.84 +} 12.85 + 12.86 +int opMOVQ_q_mm_a16(uint32_t fetchdat) 12.87 +{ 12.88 + MMX_ENTER(); 12.89 + 12.90 + fetch_ea_16(fetchdat); 12.91 + if (mod == 3) 12.92 + { 12.93 + MM[reg].q = MM[rm].q; 12.94 + cycles--; 12.95 + } 12.96 + else 12.97 + { 12.98 + uint32_t dst[2]; 12.99 + 12.100 + dst[0] = readmeml(easeg, eaaddr); 12.101 + dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 12.102 + MM[reg].l[0] = dst[0]; 12.103 + MM[reg].l[1] = dst[1]; 12.104 + cycles -= 2; 12.105 + } 12.106 + return 0; 12.107 +} 12.108 +int opMOVQ_q_mm_a32(uint32_t fetchdat) 12.109 +{ 12.110 + MMX_ENTER(); 12.111 + 12.112 + fetch_ea_32(fetchdat); 12.113 + if (mod == 3) 12.114 + { 12.115 + MM[reg].q = MM[rm].q; 12.116 + cycles--; 12.117 + } 12.118 + else 12.119 + { 12.120 + uint32_t dst[2]; 12.121 + 12.122 + dst[0] = readmeml(easeg, eaaddr); 12.123 + dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 0; 12.124 + MM[reg].l[0] = dst[0]; 12.125 + MM[reg].l[1] = dst[1]; 12.126 + cycles -= 2; 12.127 + } 12.128 + return 0; 12.129 +} 12.130 + 12.131 +int opMOVQ_mm_q_a16(uint32_t fetchdat) 12.132 +{ 12.133 + MMX_ENTER(); 12.134 + 12.135 + fetch_ea_16(fetchdat); 12.136 + if (mod == 3) 12.137 + { 12.138 + MM[rm].q = MM[reg].q; 12.139 + cycles--; 12.140 + } 12.141 + else 12.142 + { 12.143 + writememl(easeg, eaaddr, MM[reg].l[0]); 12.144 + writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0; 12.145 + cycles -= 2; 12.146 + } 12.147 + return 0; 12.148 +} 12.149 +int opMOVQ_mm_q_a32(uint32_t fetchdat) 12.150 +{ 12.151 + MMX_ENTER(); 12.152 + 12.153 + fetch_ea_32(fetchdat); 12.154 + if (mod == 3) 12.155 + { 12.156 + MM[rm].q = MM[reg].q; 12.157 + cycles--; 12.158 + } 12.159 + else 12.160 + { 12.161 + writememl(easeg, eaaddr, MM[reg].l[0]); 12.162 + writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 0; 12.163 + cycles -= 2; 12.164 + } 12.165 + return 0; 12.166 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/x86_ops_mmx_pack.h Sat Aug 03 15:05:50 2013 +0100 13.3 @@ -0,0 +1,322 @@ 13.4 +int opPUNPCKLDQ_a16(uint32_t fetchdat) 13.5 +{ 13.6 + MMX_ENTER(); 13.7 + 13.8 + fetch_ea_16(fetchdat); 13.9 + if (mod == 3) 13.10 + { 13.11 + MM[reg].l[1] = MM[rm].l[0]; 13.12 + cycles--; 13.13 + } 13.14 + else 13.15 + { 13.16 + uint32_t src; 13.17 + 13.18 + src = readmeml(easeg, eaaddr); if (abrt) return 0; 13.19 + MM[reg].l[1] = src; 13.20 + 13.21 + cycles -= 2; 13.22 + } 13.23 + return 0; 13.24 +} 13.25 +int opPUNPCKLDQ_a32(uint32_t fetchdat) 13.26 +{ 13.27 + MMX_ENTER(); 13.28 + 13.29 + fetch_ea_32(fetchdat); 13.30 + if (mod == 3) 13.31 + { 13.32 + MM[reg].l[1] = MM[rm].l[0]; 13.33 + cycles--; 13.34 + } 13.35 + else 13.36 + { 13.37 + uint32_t src; 13.38 + 13.39 + src = readmeml(easeg, eaaddr); if (abrt) return 0; 13.40 + MM[reg].l[1] = src; 13.41 + 13.42 + cycles -= 2; 13.43 + } 13.44 + return 0; 13.45 +} 13.46 + 13.47 +int opPUNPCKHDQ_a16(uint32_t fetchdat) 13.48 +{ 13.49 + MMX_REG src; 13.50 + MMX_ENTER(); 13.51 + 13.52 + fetch_ea_16(fetchdat); 13.53 + MMX_GETSRC(); 13.54 + 13.55 + MM[reg].l[0] = src.l[1]; 13.56 + 13.57 + return 0; 13.58 +} 13.59 +int opPUNPCKHDQ_a32(uint32_t fetchdat) 13.60 +{ 13.61 + MMX_REG src; 13.62 + MMX_ENTER(); 13.63 + 13.64 + fetch_ea_32(fetchdat); 13.65 + MMX_GETSRC(); 13.66 + 13.67 + MM[reg].l[0] = src.l[1]; 13.68 + 13.69 + return 0; 13.70 +} 13.71 + 13.72 +int opPUNPCKLBW_a16(uint32_t fetchdat) 13.73 +{ 13.74 + MMX_REG src; 13.75 + MMX_ENTER(); 13.76 + 13.77 + fetch_ea_16(fetchdat); 13.78 + MMX_GETSRC(); 13.79 + 13.80 + MM[reg].b[7] = src.b[3]; 13.81 + MM[reg].b[6] = MM[reg].b[3]; 13.82 + MM[reg].b[5] = src.b[2]; 13.83 + MM[reg].b[4] = MM[reg].b[2]; 13.84 + MM[reg].b[3] = src.b[1]; 13.85 + MM[reg].b[2] = MM[reg].b[1]; 13.86 + MM[reg].b[1] = src.b[0]; 13.87 + MM[reg].b[0] = MM[reg].b[0]; 13.88 + 13.89 + return 0; 13.90 +} 13.91 +int opPUNPCKLBW_a32(uint32_t fetchdat) 13.92 +{ 13.93 + MMX_REG src; 13.94 + MMX_ENTER(); 13.95 + 13.96 + fetch_ea_32(fetchdat); 13.97 + MMX_GETSRC(); 13.98 + 13.99 + MM[reg].b[7] = src.b[3]; 13.100 + MM[reg].b[6] = MM[reg].b[3]; 13.101 + MM[reg].b[5] = src.b[2]; 13.102 + MM[reg].b[4] = MM[reg].b[2]; 13.103 + MM[reg].b[3] = src.b[1]; 13.104 + MM[reg].b[2] = MM[reg].b[1]; 13.105 + MM[reg].b[1] = src.b[0]; 13.106 + MM[reg].b[0] = MM[reg].b[0]; 13.107 + 13.108 + return 0; 13.109 +} 13.110 + 13.111 +int opPUNPCKHBW_a16(uint32_t fetchdat) 13.112 +{ 13.113 + MMX_REG src; 13.114 + MMX_ENTER(); 13.115 + 13.116 + fetch_ea_16(fetchdat); 13.117 + MMX_GETSRC(); 13.118 + 13.119 + MM[reg].b[0] = MM[reg].b[4]; 13.120 + MM[reg].b[1] = src.b[4]; 13.121 + MM[reg].b[2] = MM[reg].b[5]; 13.122 + MM[reg].b[3] = src.b[5]; 13.123 + MM[reg].b[4] = MM[reg].b[6]; 13.124 + MM[reg].b[5] = src.b[6]; 13.125 + MM[reg].b[6] = MM[reg].b[7]; 13.126 + MM[reg].b[7] = src.b[7]; 13.127 + 13.128 + return 0; 13.129 +} 13.130 +int opPUNPCKHBW_a32(uint32_t fetchdat) 13.131 +{ 13.132 + MMX_REG src; 13.133 + MMX_ENTER(); 13.134 + 13.135 + fetch_ea_32(fetchdat); 13.136 + MMX_GETSRC(); 13.137 + 13.138 + MM[reg].b[0] = MM[reg].b[4]; 13.139 + MM[reg].b[1] = src.b[4]; 13.140 + MM[reg].b[2] = MM[reg].b[5]; 13.141 + MM[reg].b[3] = src.b[5]; 13.142 + MM[reg].b[4] = MM[reg].b[6]; 13.143 + MM[reg].b[5] = src.b[6]; 13.144 + MM[reg].b[6] = MM[reg].b[7]; 13.145 + MM[reg].b[7] = src.b[7]; 13.146 + 13.147 + return 0; 13.148 +} 13.149 + 13.150 +int opPUNPCKLWD_a16(uint32_t fetchdat) 13.151 +{ 13.152 + MMX_REG src; 13.153 + MMX_ENTER(); 13.154 + 13.155 + fetch_ea_16(fetchdat); 13.156 + MMX_GETSRC(); 13.157 + 13.158 + MM[reg].w[3] = src.w[1]; 13.159 + MM[reg].w[2] = MM[reg].w[1]; 13.160 + MM[reg].w[1] = src.w[0]; 13.161 + MM[reg].w[0] = MM[reg].w[0]; 13.162 + 13.163 + return 0; 13.164 +} 13.165 +int opPUNPCKLWD_a32(uint32_t fetchdat) 13.166 +{ 13.167 + MMX_REG src; 13.168 + MMX_ENTER(); 13.169 + 13.170 + fetch_ea_32(fetchdat); 13.171 + MMX_GETSRC(); 13.172 + 13.173 + MM[reg].w[3] = src.w[1]; 13.174 + MM[reg].w[2] = MM[reg].w[1]; 13.175 + MM[reg].w[1] = src.w[0]; 13.176 + MM[reg].w[0] = MM[reg].w[0]; 13.177 + 13.178 + return 0; 13.179 +} 13.180 + 13.181 +int opPUNPCKHWD_a16(uint32_t fetchdat) 13.182 +{ 13.183 + MMX_REG src; 13.184 + MMX_ENTER(); 13.185 + 13.186 + fetch_ea_16(fetchdat); 13.187 + MMX_GETSRC(); 13.188 + 13.189 + MM[reg].w[0] = MM[reg].w[2]; 13.190 + MM[reg].w[1] = src.w[2]; 13.191 + MM[reg].w[2] = MM[reg].w[3]; 13.192 + MM[reg].w[3] = src.w[3]; 13.193 + 13.194 + return 0; 13.195 +} 13.196 +int opPUNPCKHWD_a32(uint32_t fetchdat) 13.197 +{ 13.198 + MMX_REG src; 13.199 + MMX_ENTER(); 13.200 + 13.201 + fetch_ea_32(fetchdat); 13.202 + MMX_GETSRC(); 13.203 + 13.204 + MM[reg].w[0] = MM[reg].w[2]; 13.205 + MM[reg].w[1] = src.w[2]; 13.206 + MM[reg].w[2] = MM[reg].w[3]; 13.207 + MM[reg].w[3] = src.w[3]; 13.208 + 13.209 + return 0; 13.210 +} 13.211 + 13.212 +int opPACKSSWB_a16(uint32_t fetchdat) 13.213 +{ 13.214 + MMX_REG src, dst; 13.215 + MMX_ENTER(); 13.216 + 13.217 + fetch_ea_16(fetchdat); 13.218 + MMX_GETSRC(); 13.219 + dst = MM[reg]; 13.220 + 13.221 + MM[reg].sb[0] = SSATB(dst.sw[0]); 13.222 + MM[reg].sb[1] = SSATB(dst.sw[1]); 13.223 + MM[reg].sb[2] = SSATB(dst.sw[2]); 13.224 + MM[reg].sb[3] = SSATB(dst.sw[3]); 13.225 + MM[reg].sb[4] = SSATB(src.sw[0]); 13.226 + MM[reg].sb[5] = SSATB(src.sw[1]); 13.227 + MM[reg].sb[6] = SSATB(src.sw[2]); 13.228 + MM[reg].sb[7] = SSATB(src.sw[3]); 13.229 + 13.230 + return 0; 13.231 +} 13.232 +int opPACKSSWB_a32(uint32_t fetchdat) 13.233 +{ 13.234 + MMX_REG src, dst; 13.235 + MMX_ENTER(); 13.236 + 13.237 + fetch_ea_32(fetchdat); 13.238 + MMX_GETSRC(); 13.239 + dst = MM[reg]; 13.240 + 13.241 + MM[reg].sb[0] = SSATB(dst.sw[0]); 13.242 + MM[reg].sb[1] = SSATB(dst.sw[1]); 13.243 + MM[reg].sb[2] = SSATB(dst.sw[2]); 13.244 + MM[reg].sb[3] = SSATB(dst.sw[3]); 13.245 + MM[reg].sb[4] = SSATB(src.sw[0]); 13.246 + MM[reg].sb[5] = SSATB(src.sw[1]); 13.247 + MM[reg].sb[6] = SSATB(src.sw[2]); 13.248 + MM[reg].sb[7] = SSATB(src.sw[3]); 13.249 + 13.250 + return 0; 13.251 +} 13.252 + 13.253 +int opPACKUSWB_a16(uint32_t fetchdat) 13.254 +{ 13.255 + MMX_REG src, dst; 13.256 + MMX_ENTER(); 13.257 + 13.258 + fetch_ea_16(fetchdat); 13.259 + MMX_GETSRC(); 13.260 + dst = MM[reg]; 13.261 + 13.262 + MM[reg].b[0] = USATB(dst.sw[0]); 13.263 + MM[reg].b[1] = USATB(dst.sw[1]); 13.264 + MM[reg].b[2] = USATB(dst.sw[2]); 13.265 + MM[reg].b[3] = USATB(dst.sw[3]); 13.266 + MM[reg].b[4] = USATB(src.sw[0]); 13.267 + MM[reg].b[5] = USATB(src.sw[1]); 13.268 + MM[reg].b[6] = USATB(src.sw[2]); 13.269 + MM[reg].b[7] = USATB(src.sw[3]); 13.270 + 13.271 + return 0; 13.272 +} 13.273 +int opPACKUSWB_a32(uint32_t fetchdat) 13.274 +{ 13.275 + MMX_REG src, dst; 13.276 + MMX_ENTER(); 13.277 + 13.278 + fetch_ea_32(fetchdat); 13.279 + MMX_GETSRC(); 13.280 + dst = MM[reg]; 13.281 + 13.282 + MM[reg].b[0] = USATB(dst.sw[0]); 13.283 + MM[reg].b[1] = USATB(dst.sw[1]); 13.284 + MM[reg].b[2] = USATB(dst.sw[2]); 13.285 + MM[reg].b[3] = USATB(dst.sw[3]); 13.286 + MM[reg].b[4] = USATB(src.sw[0]); 13.287 + MM[reg].b[5] = USATB(src.sw[1]); 13.288 + MM[reg].b[6] = USATB(src.sw[2]); 13.289 + MM[reg].b[7] = USATB(src.sw[3]); 13.290 + 13.291 + return 0; 13.292 +} 13.293 + 13.294 +int opPACKSSDW_a16(uint32_t fetchdat) 13.295 +{ 13.296 + MMX_REG src, dst; 13.297 + MMX_ENTER(); 13.298 + 13.299 + fetch_ea_16(fetchdat); 13.300 + MMX_GETSRC(); 13.301 + dst = MM[reg]; 13.302 + 13.303 + MM[reg].sw[0] = SSATW(dst.sl[0]); 13.304 + MM[reg].sw[1] = SSATW(dst.sl[1]); 13.305 + MM[reg].sw[2] = SSATW(src.sl[0]); 13.306 + MM[reg].sw[3] = SSATW(src.sl[1]); 13.307 + 13.308 + return 0; 13.309 +} 13.310 +int opPACKSSDW_a32(uint32_t fetchdat) 13.311 +{ 13.312 + MMX_REG src, dst; 13.313 + MMX_ENTER(); 13.314 + 13.315 + fetch_ea_32(fetchdat); 13.316 + MMX_GETSRC(); 13.317 + dst = MM[reg]; 13.318 + 13.319 + MM[reg].sw[0] = SSATW(dst.sl[0]); 13.320 + MM[reg].sw[1] = SSATW(dst.sl[1]); 13.321 + MM[reg].sw[2] = SSATW(src.sl[0]); 13.322 + MM[reg].sw[3] = SSATW(src.sl[1]); 13.323 + 13.324 + return 0; 13.325 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/src/x86_ops_mmx_shift.h Sat Aug 03 15:05:50 2013 +0100 14.3 @@ -0,0 +1,452 @@ 14.4 +#define MMX_GETSHIFT() \ 14.5 + if (mod == 3) \ 14.6 + { \ 14.7 + shift = MM[rm].b[0]; \ 14.8 + cycles--; \ 14.9 + } \ 14.10 + else \ 14.11 + { \ 14.12 + shift = readmemb(easeg, eaaddr); if (abrt) return 0; \ 14.13 + cycles -= 2; \ 14.14 + } 14.15 + 14.16 +int opPSxxW_imm(uint32_t fetchdat) 14.17 +{ 14.18 + int reg = fetchdat & 7; 14.19 + int op = fetchdat & 0x38; 14.20 + int shift = (fetchdat >> 8) & 0xff; 14.21 + 14.22 + pc += 2; 14.23 + MMX_ENTER(); 14.24 + 14.25 + switch (op) 14.26 + { 14.27 + case 0x10: /*PSRLW*/ 14.28 + if (shift > 15) 14.29 + MM[reg].q = 0; 14.30 + else 14.31 + { 14.32 + MM[reg].w[0] >>= shift; 14.33 + MM[reg].w[1] >>= shift; 14.34 + MM[reg].w[2] >>= shift; 14.35 + MM[reg].w[3] >>= shift; 14.36 + } 14.37 + break; 14.38 + case 0x20: /*PSRAW*/ 14.39 + if (shift > 15) 14.40 + shift = 15; 14.41 + MM[reg].sw[0] >>= shift; 14.42 + MM[reg].sw[1] >>= shift; 14.43 + MM[reg].sw[2] >>= shift; 14.44 + MM[reg].sw[3] >>= shift; 14.45 + break; 14.46 + case 0x30: /*PSLLW*/ 14.47 + if (shift > 15) 14.48 + MM[reg].q = 0; 14.49 + else 14.50 + { 14.51 + MM[reg].w[0] <<= shift; 14.52 + MM[reg].w[1] <<= shift; 14.53 + MM[reg].w[2] <<= shift; 14.54 + MM[reg].w[3] <<= shift; 14.55 + } 14.56 + break; 14.57 + default: 14.58 + pclog("Bad PSxxW (0F 71) instruction %02X\n", op); 14.59 + pc = oldpc; 14.60 + x86illegal(); 14.61 + return 0; 14.62 + } 14.63 + 14.64 + cycles--; 14.65 + return 0; 14.66 +} 14.67 + 14.68 +int opPSLLW_a16(uint32_t fetchdat) 14.69 +{ 14.70 + int shift; 14.71 + 14.72 + MMX_ENTER(); 14.73 + 14.74 + fetch_ea_16(fetchdat); 14.75 + MMX_GETSHIFT(); 14.76 + 14.77 + if (shift > 15) 14.78 + MM[reg].q = 0; 14.79 + else 14.80 + { 14.81 + MM[reg].w[0] <<= shift; 14.82 + MM[reg].w[1] <<= shift; 14.83 + MM[reg].w[2] <<= shift; 14.84 + MM[reg].w[3] <<= shift; 14.85 + } 14.86 + 14.87 + return 0; 14.88 +} 14.89 +int opPSLLW_a32(uint32_t fetchdat) 14.90 +{ 14.91 + int shift; 14.92 + 14.93 + MMX_ENTER(); 14.94 + 14.95 + fetch_ea_32(fetchdat); 14.96 + MMX_GETSHIFT(); 14.97 + 14.98 + if (shift > 15) 14.99 + MM[reg].q = 0; 14.100 + else 14.101 + { 14.102 + MM[reg].w[0] <<= shift; 14.103 + MM[reg].w[1] <<= shift; 14.104 + MM[reg].w[2] <<= shift; 14.105 + MM[reg].w[3] <<= shift; 14.106 + } 14.107 + 14.108 + return 0; 14.109 +} 14.110 + 14.111 +int opPSRLW_a16(uint32_t fetchdat) 14.112 +{ 14.113 + int shift; 14.114 + 14.115 + MMX_ENTER(); 14.116 + 14.117 + fetch_ea_16(fetchdat); 14.118 + MMX_GETSHIFT(); 14.119 + 14.120 + if (shift > 15) 14.121 + MM[reg].q = 0; 14.122 + else 14.123 + { 14.124 + MM[reg].w[0] >>= shift; 14.125 + MM[reg].w[1] >>= shift; 14.126 + MM[reg].w[2] >>= shift; 14.127 + MM[reg].w[3] >>= shift; 14.128 + } 14.129 + 14.130 + return 0; 14.131 +} 14.132 +int opPSRLW_a32(uint32_t fetchdat) 14.133 +{ 14.134 + int shift; 14.135 + 14.136 + MMX_ENTER(); 14.137 + 14.138 + fetch_ea_32(fetchdat); 14.139 + MMX_GETSHIFT(); 14.140 + 14.141 + if (shift > 15) 14.142 + MM[reg].q = 0; 14.143 + else 14.144 + { 14.145 + MM[reg].w[0] >>= shift; 14.146 + MM[reg].w[1] >>= shift; 14.147 + MM[reg].w[2] >>= shift; 14.148 + MM[reg].w[3] >>= shift; 14.149 + } 14.150 + 14.151 + return 0; 14.152 +} 14.153 + 14.154 +int opPSRAW_a16(uint32_t fetchdat) 14.155 +{ 14.156 + int shift; 14.157 + 14.158 + MMX_ENTER(); 14.159 + 14.160 + fetch_ea_16(fetchdat); 14.161 + MMX_GETSHIFT(); 14.162 + 14.163 + if (shift > 15) 14.164 + shift = 15; 14.165 + 14.166 + MM[reg].sw[0] >>= shift; 14.167 + MM[reg].sw[1] >>= shift; 14.168 + MM[reg].sw[2] >>= shift; 14.169 + MM[reg].sw[3] >>= shift; 14.170 + 14.171 + return 0; 14.172 +} 14.173 +int opPSRAW_a32(uint32_t fetchdat) 14.174 +{ 14.175 + int shift; 14.176 + 14.177 + MMX_ENTER(); 14.178 + 14.179 + fetch_ea_32(fetchdat); 14.180 + MMX_GETSHIFT(); 14.181 + 14.182 + if (shift > 15) 14.183 + shift = 15; 14.184 + 14.185 + MM[reg].sw[0] >>= shift; 14.186 + MM[reg].sw[1] >>= shift; 14.187 + MM[reg].sw[2] >>= shift; 14.188 + MM[reg].sw[3] >>= shift; 14.189 + 14.190 + return 0; 14.191 +} 14.192 + 14.193 +int opPSxxD_imm(uint32_t fetchdat) 14.194 +{ 14.195 + int reg = fetchdat & 7; 14.196 + int op = fetchdat & 0x38; 14.197 + int shift = (fetchdat >> 8) & 0xff; 14.198 + 14.199 + pc += 2; 14.200 + MMX_ENTER(); 14.201 + 14.202 + switch (op) 14.203 + { 14.204 + case 0x10: /*PSRLD*/ 14.205 + if (shift > 31) 14.206 + MM[reg].q = 0; 14.207 + else 14.208 + { 14.209 + MM[reg].l[0] >>= shift; 14.210 + MM[reg].l[1] >>= shift; 14.211 + } 14.212 + break; 14.213 + case 0x20: /*PSRAD*/ 14.214 + if (shift > 31) 14.215 + shift = 31; 14.216 + MM[reg].sl[0] >>= shift; 14.217 + MM[reg].sl[1] >>= shift; 14.218 + break; 14.219 + case 0x30: /*PSLLD*/ 14.220 + if (shift > 31) 14.221 + MM[reg].q = 0; 14.222 + else 14.223 + { 14.224 + MM[reg].l[0] <<= shift; 14.225 + MM[reg].l[1] <<= shift; 14.226 + } 14.227 + break; 14.228 + default: 14.229 + pclog("Bad PSxxD (0F 72) instruction %02X\n", op); 14.230 + pc = oldpc; 14.231 + x86illegal(); 14.232 + return 0; 14.233 + } 14.234 + 14.235 + cycles--; 14.236 + return 0; 14.237 +} 14.238 + 14.239 +int opPSLLD_a16(uint32_t fetchdat) 14.240 +{ 14.241 + int shift; 14.242 + 14.243 + MMX_ENTER(); 14.244 + 14.245 + fetch_ea_16(fetchdat); 14.246 + MMX_GETSHIFT(); 14.247 + 14.248 + if (shift > 31) 14.249 + MM[reg].q = 0; 14.250 + else 14.251 + { 14.252 + MM[reg].l[0] <<= shift; 14.253 + MM[reg].l[1] <<= shift; 14.254 + } 14.255 + 14.256 + return 0; 14.257 +} 14.258 +int opPSLLD_a32(uint32_t fetchdat) 14.259 +{ 14.260 + int shift; 14.261 + 14.262 + MMX_ENTER(); 14.263 + 14.264 + fetch_ea_32(fetchdat); 14.265 + MMX_GETSHIFT(); 14.266 + 14.267 + if (shift > 31) 14.268 + MM[reg].q = 0; 14.269 + else 14.270 + { 14.271 + MM[reg].l[0] <<= shift; 14.272 + MM[reg].l[1] <<= shift; 14.273 + } 14.274 + 14.275 + return 0; 14.276 +} 14.277 + 14.278 +int opPSRLD_a16(uint32_t fetchdat) 14.279 +{ 14.280 + int shift; 14.281 + 14.282 + MMX_ENTER(); 14.283 + 14.284 + fetch_ea_16(fetchdat); 14.285 + MMX_GETSHIFT(); 14.286 + 14.287 + if (shift > 31) 14.288 + MM[reg].q = 0; 14.289 + else 14.290 + { 14.291 + MM[reg].l[0] >>= shift; 14.292 + MM[reg].l[1] >>= shift; 14.293 + } 14.294 + 14.295 + return 0; 14.296 +} 14.297 +int opPSRLD_a32(uint32_t fetchdat) 14.298 +{ 14.299 + int shift; 14.300 + 14.301 + MMX_ENTER(); 14.302 + 14.303 + fetch_ea_32(fetchdat); 14.304 + MMX_GETSHIFT(); 14.305 + 14.306 + if (shift > 31) 14.307 + MM[reg].q = 0; 14.308 + else 14.309 + { 14.310 + MM[reg].l[0] >>= shift; 14.311 + MM[reg].l[1] >>= shift; 14.312 + } 14.313 + 14.314 + return 0; 14.315 +} 14.316 + 14.317 +int opPSRAD_a16(uint32_t fetchdat) 14.318 +{ 14.319 + int shift; 14.320 + 14.321 + MMX_ENTER(); 14.322 + 14.323 + fetch_ea_16(fetchdat); 14.324 + MMX_GETSHIFT(); 14.325 + 14.326 + if (shift > 31) 14.327 + shift = 31; 14.328 + 14.329 + MM[reg].sl[0] >>= shift; 14.330 + MM[reg].sl[1] >>= shift; 14.331 + 14.332 + return 0; 14.333 +} 14.334 +int opPSRAD_a32(uint32_t fetchdat) 14.335 +{ 14.336 + int shift; 14.337 + 14.338 + MMX_ENTER(); 14.339 + 14.340 + fetch_ea_32(fetchdat); 14.341 + MMX_GETSHIFT(); 14.342 + 14.343 + if (shift > 31) 14.344 + shift = 31; 14.345 + 14.346 + MM[reg].sl[0] >>= shift; 14.347 + MM[reg].sl[1] >>= shift; 14.348 + 14.349 + return 0; 14.350 +} 14.351 + 14.352 +int opPSxxQ_imm(uint32_t fetchdat) 14.353 +{ 14.354 + int reg = fetchdat & 7; 14.355 + int op = fetchdat & 0x38; 14.356 + int shift = (fetchdat >> 8) & 0xff; 14.357 + 14.358 + pc += 2; 14.359 + MMX_ENTER(); 14.360 + 14.361 + switch (op) 14.362 + { 14.363 + case 0x10: /*PSRLW*/ 14.364 + if (shift > 63) 14.365 + MM[reg].q = 0; 14.366 + else 14.367 + MM[reg].q >>= shift; 14.368 + break; 14.369 + case 0x20: /*PSRAW*/ 14.370 + if (shift > 63) 14.371 + shift = 63; 14.372 + MM[reg].sq >>= shift; 14.373 + break; 14.374 + case 0x30: /*PSLLW*/ 14.375 + if (shift > 63) 14.376 + MM[reg].q = 0; 14.377 + else 14.378 + MM[reg].q <<= shift; 14.379 + break; 14.380 + default: 14.381 + pclog("Bad PSxxQ (0F 73) instruction %02X\n", op); 14.382 + pc = oldpc; 14.383 + x86illegal(); 14.384 + return 0; 14.385 + } 14.386 + 14.387 + cycles--; 14.388 + return 0; 14.389 +} 14.390 + 14.391 +int opPSLLQ_a16(uint32_t fetchdat) 14.392 +{ 14.393 + int shift; 14.394 + 14.395 + MMX_ENTER(); 14.396 + 14.397 + fetch_ea_16(fetchdat); 14.398 + MMX_GETSHIFT(); 14.399 + 14.400 + if (shift > 63) 14.401 + MM[reg].q = 0; 14.402 + else 14.403 + MM[reg].q <<= shift; 14.404 + 14.405 + return 0; 14.406 +} 14.407 +int opPSLLQ_a32(uint32_t fetchdat) 14.408 +{ 14.409 + int shift; 14.410 + 14.411 + MMX_ENTER(); 14.412 + 14.413 + fetch_ea_32(fetchdat); 14.414 + MMX_GETSHIFT(); 14.415 + 14.416 + if (shift > 63) 14.417 + MM[reg].q = 0; 14.418 + else 14.419 + MM[reg].q <<= shift; 14.420 + 14.421 + return 0; 14.422 +} 14.423 + 14.424 +int opPSRLQ_a16(uint32_t fetchdat) 14.425 +{ 14.426 + int shift; 14.427 + 14.428 + MMX_ENTER(); 14.429 + 14.430 + fetch_ea_16(fetchdat); 14.431 + MMX_GETSHIFT(); 14.432 + 14.433 + if (shift > 63) 14.434 + MM[reg].q = 0; 14.435 + else 14.436 + MM[reg].q >>= shift; 14.437 + 14.438 + return 0; 14.439 +} 14.440 +int opPSRLQ_a32(uint32_t fetchdat) 14.441 +{ 14.442 + int shift; 14.443 + 14.444 + MMX_ENTER(); 14.445 + 14.446 + fetch_ea_32(fetchdat); 14.447 + MMX_GETSHIFT(); 14.448 + 14.449 + if (shift > 63) 14.450 + MM[reg].q = 0; 14.451 + else 14.452 + MM[reg].q >>= shift; 14.453 + 14.454 + return 0; 14.455 +}
15.1 --- a/src/x86seg.c Sat Jul 27 17:12:16 2013 +0100 15.2 +++ b/src/x86seg.c Sat Aug 03 15:05:50 2013 +0100 15.3 @@ -2394,7 +2394,7 @@ 15.4 15.5 15.6 cr3=new_cr3; 15.7 - pclog("TS New CR3 %08X\n",cr3); 15.8 +// pclog("TS New CR3 %08X\n",cr3); 15.9 flushmmucache(); 15.10 15.11
16.1 --- a/src/x87.c Sat Jul 27 17:12:16 2013 +0100 16.2 +++ b/src/x87.c Sat Aug 03 15:05:50 2013 +0100 16.3 @@ -60,6 +60,8 @@ 16.4 16.5 16.6 double ST[8]; 16.7 +MMX_REG MM[8]; 16.8 +int ismmx = 0; 16.9 uint16_t npxs,npxc,tag; 16.10 16.11 int TOP; 16.12 @@ -90,6 +92,19 @@ 16.13 dst = src1 / (double)src2; \ 16.14 } while (0) 16.15 16.16 +void x87_set_mmx() 16.17 +{ 16.18 + TOP = 0; 16.19 + tag = 0; 16.20 + ismmx = 1; 16.21 +} 16.22 + 16.23 +void x87_emms() 16.24 +{ 16.25 + tag = 0xffff; 16.26 + ismmx = 0; 16.27 +} 16.28 + 16.29 void x87_checkexceptions() 16.30 { 16.31 } 16.32 @@ -100,15 +115,31 @@ 16.33 16.34 void x87_dumpregs() 16.35 { 16.36 - 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]); 16.37 - 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]); 16.38 + if (ismmx) 16.39 + { 16.40 + pclog("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", MM[0].q, MM[1].q, MM[2].q, MM[3].q); 16.41 + pclog("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", MM[4].q, MM[5].q, MM[6].q, MM[7].q); 16.42 + } 16.43 + else 16.44 + { 16.45 + 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]); 16.46 + 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]); 16.47 + } 16.48 pclog("Status = %04X Control = %04X Tag = %04X\n",npxs,npxc,tag); 16.49 } 16.50 16.51 void x87_print() 16.52 { 16.53 - 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]); 16.54 - 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); 16.55 + if (ismmx) 16.56 + { 16.57 + pclog("\tMM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\t", MM[0].q, MM[1].q, MM[2].q, MM[3].q); 16.58 + pclog("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", MM[4].q, MM[5].q, MM[6].q, MM[7].q); 16.59 + } 16.60 + else 16.61 + { 16.62 + 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]); 16.63 + 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); 16.64 + } 16.65 } 16.66 16.67 void x87_push(double i) 16.68 @@ -215,6 +246,20 @@ 16.69 writememw(easeg,eaaddr+8,test.begin); 16.70 } 16.71 16.72 +void x87_ldmmx(MMX_REG *r) 16.73 +{ 16.74 + r->l[0] = readmeml(easeg, eaaddr); 16.75 + r->l[1] = readmeml(easeg, eaaddr + 4); 16.76 + r->w[4] = readmemw(easeg, eaaddr + 8); 16.77 +} 16.78 + 16.79 +void x87_stmmx(MMX_REG r) 16.80 +{ 16.81 + writememl(easeg, eaaddr, r.l[0]); 16.82 + writememl(easeg, eaaddr + 4, r.l[1]); 16.83 + writememw(easeg, eaaddr + 8, 0xffff); 16.84 +} 16.85 + 16.86 void x87_d8() 16.87 { 16.88 union 16.89 @@ -545,7 +590,7 @@ 16.90 cycles-=7; 16.91 return; 16.92 case 3: /*FSTP single-precision*/ 16.93 - if (fplog) pclog("FSTPs %08X:%08X\n", easeg, eaaddr); 16.94 + if (fplog) pclog("FSTPs %08X:%08X %f\n", easeg, eaaddr, ST(0)); 16.95 ts.s=(float)ST(0); 16.96 seteal(ts.i); if (abrt) { pclog("FSTP sp abort\n"); return; } 16.97 // if (pc==0x3f50c) pclog("FSTP %f %f %08X\n",ST(0),ts.s,ts.i); 16.98 @@ -969,7 +1014,6 @@ 16.99 cycles-=8; 16.100 return; 16.101 case 4: /*FRSTOR*/ 16.102 - if (fplog) pclog("FRSTOR %08X:%08X\n", easeg, eaaddr); 16.103 switch ((cr0&1)|(op32&0x100)) 16.104 { 16.105 case 0x000: /*16-bit real mode*/ 16.106 @@ -989,23 +1033,33 @@ 16.107 eaaddr+=28; 16.108 break; 16.109 } 16.110 - ST(0)=x87_ld80(); eaaddr+=10; 16.111 - ST(1)=x87_ld80(); eaaddr+=10; 16.112 - ST(2)=x87_ld80(); eaaddr+=10; 16.113 - ST(3)=x87_ld80(); eaaddr+=10; 16.114 - ST(4)=x87_ld80(); eaaddr+=10; 16.115 - ST(5)=x87_ld80(); eaaddr+=10; 16.116 - ST(6)=x87_ld80(); eaaddr+=10; 16.117 - ST(7)=x87_ld80(); 16.118 + x87_ldmmx(&MM[0]); ST(0)=x87_ld80(); eaaddr += 10; 16.119 + x87_ldmmx(&MM[1]); ST(1)=x87_ld80(); eaaddr += 10; 16.120 + x87_ldmmx(&MM[2]); ST(2)=x87_ld80(); eaaddr += 10; 16.121 + x87_ldmmx(&MM[3]); ST(3)=x87_ld80(); eaaddr += 10; 16.122 + x87_ldmmx(&MM[4]); ST(4)=x87_ld80(); eaaddr += 10; 16.123 + x87_ldmmx(&MM[5]); ST(5)=x87_ld80(); eaaddr += 10; 16.124 + x87_ldmmx(&MM[6]); ST(6)=x87_ld80(); eaaddr += 10; 16.125 + x87_ldmmx(&MM[7]); ST(7)=x87_ld80(); 16.126 + ismmx = 0; 16.127 + /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times 16.128 + something like this is needed*/ 16.129 + if (MM[0].w == 0xffff && MM[1].w == 0xffff && MM[2].w == 0xffff && MM[3].w == 0xffff && 16.130 + MM[4].w == 0xffff && MM[5].w == 0xffff && MM[6].w == 0xffff && MM[7].w == 0xffff && 16.131 + !TOP && !tag) 16.132 + ismmx = 1; 16.133 + 16.134 cycles-=(cr0&1)?34:44; 16.135 + if (fplog) pclog("FRSTOR %08X:%08X %i %i %04X\n", easeg, eaaddr, ismmx, TOP, tag); 16.136 /* pclog("new TOP %i\n", TOP); 16.137 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));*/ 16.138 return; 16.139 case 6: /*FSAVE*/ 16.140 - if (fplog) pclog("FSAVE %08X:%08X\n", easeg, eaaddr); 16.141 + if (fplog) pclog("FSAVE %08X:%08X %i\n", easeg, eaaddr, ismmx); 16.142 npxs = (npxs & ~(7 << 11)) | (TOP << 11); 16.143 /* pclog("old TOP %i %04X\n", TOP, npxs); 16.144 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));*/ 16.145 + 16.146 switch ((cr0&1)|(op32&0x100)) 16.147 { 16.148 case 0x000: /*16-bit real mode*/ 16.149 @@ -1015,14 +1069,28 @@ 16.150 writememw(easeg,eaaddr+6,x87_pc_off); 16.151 writememw(easeg,eaaddr+10,x87_op_off); 16.152 eaaddr+=14; 16.153 - x87_st80(ST(0)); eaaddr+=10; 16.154 - x87_st80(ST(1)); eaaddr+=10; 16.155 - x87_st80(ST(2)); eaaddr+=10; 16.156 - x87_st80(ST(3)); eaaddr+=10; 16.157 - x87_st80(ST(4)); eaaddr+=10; 16.158 - x87_st80(ST(5)); eaaddr+=10; 16.159 - x87_st80(ST(6)); eaaddr+=10; 16.160 - x87_st80(ST(7)); 16.161 + if (ismmx) 16.162 + { 16.163 + x87_stmmx(MM[0]); eaaddr+=10; 16.164 + x87_stmmx(MM[1]); eaaddr+=10; 16.165 + x87_stmmx(MM[2]); eaaddr+=10; 16.166 + x87_stmmx(MM[3]); eaaddr+=10; 16.167 + x87_stmmx(MM[4]); eaaddr+=10; 16.168 + x87_stmmx(MM[5]); eaaddr+=10; 16.169 + x87_stmmx(MM[6]); eaaddr+=10; 16.170 + x87_stmmx(MM[7]); 16.171 + } 16.172 + else 16.173 + { 16.174 + x87_st80(ST(0)); eaaddr+=10; 16.175 + x87_st80(ST(1)); eaaddr+=10; 16.176 + x87_st80(ST(2)); eaaddr+=10; 16.177 + x87_st80(ST(3)); eaaddr+=10; 16.178 + x87_st80(ST(4)); eaaddr+=10; 16.179 + x87_st80(ST(5)); eaaddr+=10; 16.180 + x87_st80(ST(6)); eaaddr+=10; 16.181 + x87_st80(ST(7)); 16.182 + } 16.183 break; 16.184 case 0x001: /*16-bit protected mode*/ 16.185 writememw(easeg,eaaddr,npxc); 16.186 @@ -1033,14 +1101,28 @@ 16.187 writememw(easeg,eaaddr+10,x87_op_off); 16.188 writememw(easeg,eaaddr+12,x87_op_seg); 16.189 eaaddr+=14; 16.190 - x87_st80(ST(0)); eaaddr+=10; 16.191 - x87_st80(ST(1)); eaaddr+=10; 16.192 - x87_st80(ST(2)); eaaddr+=10; 16.193 - x87_st80(ST(3)); eaaddr+=10; 16.194 - x87_st80(ST(4)); eaaddr+=10; 16.195 - x87_st80(ST(5)); eaaddr+=10; 16.196 - x87_st80(ST(6)); eaaddr+=10; 16.197 - x87_st80(ST(7)); 16.198 + if (ismmx) 16.199 + { 16.200 + x87_stmmx(MM[0]); eaaddr+=10; 16.201 + x87_stmmx(MM[1]); eaaddr+=10; 16.202 + x87_stmmx(MM[2]); eaaddr+=10; 16.203 + x87_stmmx(MM[3]); eaaddr+=10; 16.204 + x87_stmmx(MM[4]); eaaddr+=10; 16.205 + x87_stmmx(MM[5]); eaaddr+=10; 16.206 + x87_stmmx(MM[6]); eaaddr+=10; 16.207 + x87_stmmx(MM[7]); 16.208 + } 16.209 + else 16.210 + { 16.211 + x87_st80(ST(0)); eaaddr+=10; 16.212 + x87_st80(ST(1)); eaaddr+=10; 16.213 + x87_st80(ST(2)); eaaddr+=10; 16.214 + x87_st80(ST(3)); eaaddr+=10; 16.215 + x87_st80(ST(4)); eaaddr+=10; 16.216 + x87_st80(ST(5)); eaaddr+=10; 16.217 + x87_st80(ST(6)); eaaddr+=10; 16.218 + x87_st80(ST(7)); 16.219 + } 16.220 break; 16.221 case 0x100: /*32-bit real mode*/ 16.222 writememw(easeg,eaaddr,npxc); 16.223 @@ -1050,14 +1132,28 @@ 16.224 writememw(easeg,eaaddr+20,x87_op_off); 16.225 writememl(easeg,eaaddr+24,(x87_op_off>>16)<<12); 16.226 eaaddr+=28; 16.227 - x87_st80(ST(0)); eaaddr+=10; 16.228 - x87_st80(ST(1)); eaaddr+=10; 16.229 - x87_st80(ST(2)); eaaddr+=10; 16.230 - x87_st80(ST(3)); eaaddr+=10; 16.231 - x87_st80(ST(4)); eaaddr+=10; 16.232 - x87_st80(ST(5)); eaaddr+=10; 16.233 - x87_st80(ST(6)); eaaddr+=10; 16.234 - x87_st80(ST(7)); 16.235 + if (ismmx) 16.236 + { 16.237 + x87_stmmx(MM[0]); eaaddr+=10; 16.238 + x87_stmmx(MM[1]); eaaddr+=10; 16.239 + x87_stmmx(MM[2]); eaaddr+=10; 16.240 + x87_stmmx(MM[3]); eaaddr+=10; 16.241 + x87_stmmx(MM[4]); eaaddr+=10; 16.242 + x87_stmmx(MM[5]); eaaddr+=10; 16.243 + x87_stmmx(MM[6]); eaaddr+=10; 16.244 + x87_stmmx(MM[7]); 16.245 + } 16.246 + else 16.247 + { 16.248 + x87_st80(ST(0)); eaaddr+=10; 16.249 + x87_st80(ST(1)); eaaddr+=10; 16.250 + x87_st80(ST(2)); eaaddr+=10; 16.251 + x87_st80(ST(3)); eaaddr+=10; 16.252 + x87_st80(ST(4)); eaaddr+=10; 16.253 + x87_st80(ST(5)); eaaddr+=10; 16.254 + x87_st80(ST(6)); eaaddr+=10; 16.255 + x87_st80(ST(7)); 16.256 + } 16.257 break; 16.258 case 0x101: /*32-bit protected mode*/ 16.259 writememw(easeg,eaaddr,npxc); 16.260 @@ -1068,14 +1164,28 @@ 16.261 writememl(easeg,eaaddr+20,x87_op_off); 16.262 writememl(easeg,eaaddr+24,x87_op_seg); 16.263 eaaddr+=28; 16.264 - x87_st80(ST(0)); eaaddr+=10; 16.265 - x87_st80(ST(1)); eaaddr+=10; 16.266 - x87_st80(ST(2)); eaaddr+=10; 16.267 - x87_st80(ST(3)); eaaddr+=10; 16.268 - x87_st80(ST(4)); eaaddr+=10; 16.269 - x87_st80(ST(5)); eaaddr+=10; 16.270 - x87_st80(ST(6)); eaaddr+=10; 16.271 - x87_st80(ST(7)); 16.272 + if (ismmx) 16.273 + { 16.274 + x87_stmmx(MM[0]); eaaddr+=10; 16.275 + x87_stmmx(MM[1]); eaaddr+=10; 16.276 + x87_stmmx(MM[2]); eaaddr+=10; 16.277 + x87_stmmx(MM[3]); eaaddr+=10; 16.278 + x87_stmmx(MM[4]); eaaddr+=10; 16.279 + x87_stmmx(MM[5]); eaaddr+=10; 16.280 + x87_stmmx(MM[6]); eaaddr+=10; 16.281 + x87_stmmx(MM[7]); 16.282 + } 16.283 + else 16.284 + { 16.285 + x87_st80(ST(0)); eaaddr+=10; 16.286 + x87_st80(ST(1)); eaaddr+=10; 16.287 + x87_st80(ST(2)); eaaddr+=10; 16.288 + x87_st80(ST(3)); eaaddr+=10; 16.289 + x87_st80(ST(4)); eaaddr+=10; 16.290 + x87_st80(ST(5)); eaaddr+=10; 16.291 + x87_st80(ST(6)); eaaddr+=10; 16.292 + x87_st80(ST(7)); 16.293 + } 16.294 break; 16.295 } 16.296 cycles-=(cr0&1)?56:67; 16.297 @@ -1293,3 +1403,4 @@ 16.298 // fatal("Bad x87 DF opcode %i %02X\n",reg,rmdat32&0xFF); 16.299 x86illegal(); 16.300 } 16.301 +
17.1 --- a/src/x87.h Sat Jul 27 17:12:16 2013 +0100 17.2 +++ b/src/x87.h Sat Aug 03 15:05:50 2013 +0100 17.3 @@ -1,3 +1,20 @@ 17.4 uint32_t x87_pc_off,x87_op_off; 17.5 uint16_t x87_pc_seg,x87_op_seg; 17.6 extern uint32_t op32; 17.7 + 17.8 +typedef union MMX_REG 17.9 +{ 17.10 + uint64_t q; 17.11 + int64_t sq; 17.12 + uint32_t l[2]; 17.13 + int32_t sl[2]; 17.14 + uint16_t w[5]; 17.15 + int16_t sw[4]; 17.16 + uint8_t b[8]; 17.17 + int8_t sb[8]; 17.18 +} MMX_REG; 17.19 + 17.20 +extern MMX_REG MM[8]; 17.21 + 17.22 +void x87_set_mmx(); 17.23 +void x87_emms();
