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();