Skip to content

Commit

Permalink
Implement Cyrix EMMI extensions and 4 FPU instructions
Browse files Browse the repository at this point in the history
PADDSIW, PSUBSIW, PMULHRW (named PMULHRWC in the code as recognized by some assemblers), PMULHRIW, PDISTIB, PMACHRIW, PAVEB, PMAGW, PMVZB, PMVNZB, PMVLZB, PMVGEZB, FTSTP, FRINT2, FRINEAR, FRICHOP are implemented for Cyrix 6x86MX. Cyrix 6x86(L) only has the last 4 instructions.
  • Loading branch information
Cacodemon345 committed Mar 5, 2025
1 parent 6a380af commit 5f3641e
Show file tree
Hide file tree
Showing 10 changed files with 1,744 additions and 41 deletions.
9 changes: 5 additions & 4 deletions src/cpu/386_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ extern void x386_dynarec_log(const char *fmt, ...);
# include "x86_ops_mmx_mov.h"
# include "x86_ops_mmx_pack.h"
# include "x86_ops_mmx_shift.h"
# include "x86_ops_mmx_emmi.h"
#endif
#include "x86_ops_mov.h"
#ifdef OPS_286_386
Expand Down Expand Up @@ -1857,7 +1858,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

/*40*/ opCMOVO_w_a16, opCMOVNO_w_a16, opCMOVB_w_a16, opCMOVNB_w_a16, opCMOVE_w_a16, opCMOVNE_w_a16, opCMOVBE_w_a16, opCMOVNBE_w_a16,opCMOVS_w_a16, opCMOVNS_w_a16, opCMOVP_w_a16, opCMOVNP_w_a16, opCMOVL_w_a16, opCMOVNL_w_a16, opCMOVLE_w_a16, opCMOVNLE_w_a16,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*50*/ opPAVEB_a16, opPADDSIW_a16, opPMAGW_a16, ILLEGAL, opPDISTIB_a16, opPSUBSIW_a16, ILLEGAL, ILLEGAL, opPMVZB_a16, opPMULHRWC_a16, opPMVNZB_a16, opPMVLZB_a16, opPMVGEZB_a16, opPMULHRIW_a16, opPMACHRIW_a16, ILLEGAL,
/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16,

Expand All @@ -1879,7 +1880,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a16, opWRSHR_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

/*40*/ opCMOVO_l_a16, opCMOVNO_l_a16, opCMOVB_l_a16, opCMOVNB_l_a16, opCMOVE_l_a16, opCMOVNE_l_a16, opCMOVBE_l_a16, opCMOVNBE_l_a16,opCMOVS_l_a16, opCMOVNS_l_a16, opCMOVP_l_a16, opCMOVNP_l_a16, opCMOVL_l_a16, opCMOVNL_l_a16, opCMOVLE_l_a16, opCMOVNLE_l_a16,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*50*/ opPAVEB_a16, opPADDSIW_a16, opPMAGW_a16, ILLEGAL, opPDISTIB_a16, opPSUBSIW_a16, ILLEGAL, ILLEGAL, opPMVZB_a16, opPMULHRWC_a16, opPMVNZB_a16, opPMVLZB_a16, opPMVGEZB_a16, opPMULHRIW_a16, opPMACHRIW_a16, ILLEGAL,
/*60*/ opPUNPCKLBW_a16,opPUNPCKLWD_a16,opPUNPCKLDQ_a16,opPACKSSWB_a16, opPCMPGTB_a16, opPCMPGTW_a16, opPCMPGTD_a16, opPACKUSWB_a16, opPUNPCKHBW_a16,opPUNPCKHWD_a16,opPUNPCKHDQ_a16,opPACKSSDW_a16, ILLEGAL, ILLEGAL, opMOVD_l_mm_a16,opMOVQ_q_mm_a16,
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a16, opPCMPEQW_a16, opPCMPEQD_a16, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a16_cx,opMOVQ_mm_q_a16,

Expand All @@ -1901,7 +1902,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

/*40*/ opCMOVO_w_a32, opCMOVNO_w_a32, opCMOVB_w_a32, opCMOVNB_w_a32, opCMOVE_w_a32, opCMOVNE_w_a32, opCMOVBE_w_a32, opCMOVNBE_w_a32,opCMOVS_w_a32, opCMOVNS_w_a32, opCMOVP_w_a32, opCMOVNP_w_a32, opCMOVL_w_a32, opCMOVNL_w_a32, opCMOVLE_w_a32, opCMOVNLE_w_a32,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*50*/ opPAVEB_a32, opPADDSIW_a32, opPMAGW_a32, ILLEGAL, opPDISTIB_a32, opPSUBSIW_a32, ILLEGAL, ILLEGAL, opPMVZB_a32, opPMULHRWC_a32, opPMVNZB_a32, opPMVLZB_a32, opPMVGEZB_a32, opPMULHRIW_a32, opPMACHRIW_a32, ILLEGAL,
/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32,

Expand All @@ -1923,7 +1924,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = {
/*30*/ opWRMSR, opRDTSC, opRDMSR, opRDPMC, ILLEGAL, ILLEGAL, opRDSHR_a32, opWRSHR_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

/*40*/ opCMOVO_l_a32, opCMOVNO_l_a32, opCMOVB_l_a32, opCMOVNB_l_a32, opCMOVE_l_a32, opCMOVNE_l_a32, opCMOVBE_l_a32, opCMOVNBE_l_a32,opCMOVS_l_a32, opCMOVNS_l_a32, opCMOVP_l_a32, opCMOVNP_l_a32, opCMOVL_l_a32, opCMOVNL_l_a32, opCMOVLE_l_a32, opCMOVNLE_l_a32,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*50*/ opPAVEB_a32, opPADDSIW_a32, opPMAGW_a32, ILLEGAL, opPDISTIB_a32, opPSUBSIW_a32, ILLEGAL, ILLEGAL, opPMVZB_a32, opPMULHRWC_a32, opPMVNZB_a32, opPMVLZB_a32, opPMVGEZB_a32, opPMULHRIW_a32, opPMACHRIW_a32, ILLEGAL,
/*60*/ opPUNPCKLBW_a32,opPUNPCKLWD_a32,opPUNPCKLDQ_a32,opPACKSSWB_a32, opPCMPGTB_a32, opPCMPGTW_a32, opPCMPGTD_a32, opPACKUSWB_a32, opPUNPCKHBW_a32,opPUNPCKHWD_a32,opPUNPCKHDQ_a32,opPACKSSDW_a32, ILLEGAL, ILLEGAL, opMOVD_l_mm_a32,opMOVQ_q_mm_a32,
/*70*/ ILLEGAL, opPSxxW_imm, opPSxxD_imm, opPSxxQ_imm, opPCMPEQB_a32, opPCMPEQW_a32, opPCMPEQD_a32, opEMMS, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opMOVD_mm_l_a32_cx,opMOVQ_mm_q_a32,

Expand Down
47 changes: 31 additions & 16 deletions src/cpu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,14 @@ uint8_t do_translate2 = 0;

void (*cpu_exec)(int32_t cycs);

static uint8_t ccr0;
static uint8_t ccr1;
static uint8_t ccr2;
static uint8_t ccr3;
static uint8_t ccr4;
static uint8_t ccr5;
static uint8_t ccr6;
uint8_t ccr0;
uint8_t ccr1;
uint8_t ccr2;
uint8_t ccr3;
uint8_t ccr4;
uint8_t ccr5;
uint8_t ccr6;
uint8_t ccr7;

static int cyrix_addr;

Expand Down Expand Up @@ -557,7 +558,8 @@ cpu_set(void)
cpu_busspeed = cpu_s->rspeed;
cpu_multi = (int) ceil(cpu_s->multi);
cpu_dmulti = cpu_s->multi;
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0;
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = ccr7 = 0;
ccr4 = 0x85;

cpu_update_waitstates();

Expand Down Expand Up @@ -1442,19 +1444,27 @@ cpu_set(void)
}
# endif /* USE_DYNAREC */
if (fpu_softfloat) {
x86_opcodes_d9_a16 = ops_sf_fpu_cyrix_d9_a16;
x86_opcodes_d9_a32 = ops_sf_fpu_cyrix_d9_a32;
x86_opcodes_da_a16 = ops_sf_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_sf_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_sf_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_sf_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_sf_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_686_df_a32;
x86_opcodes_db_a16 = ops_sf_fpu_cyrix_686_db_a16;
x86_opcodes_db_a32 = ops_sf_fpu_cyrix_686_db_a32;
x86_opcodes_dd_a16 = ops_sf_fpu_cyrix_dd_a16;
x86_opcodes_dd_a32 = ops_sf_fpu_cyrix_dd_a32;
x86_opcodes_df_a16 = ops_sf_fpu_cyrix_686_df_a16;
x86_opcodes_df_a32 = ops_sf_fpu_cyrix_686_df_a32;
} else {
x86_opcodes_d9_a16 = ops_fpu_cyrix_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_cyrix_d9_a32;
x86_opcodes_da_a16 = ops_fpu_686_da_a16;
x86_opcodes_da_a32 = ops_fpu_686_da_a32;
x86_opcodes_db_a16 = ops_fpu_686_db_a16;
x86_opcodes_db_a32 = ops_fpu_686_db_a32;
x86_opcodes_df_a16 = ops_fpu_686_df_a16;
x86_opcodes_df_a32 = ops_fpu_686_df_a32;
x86_opcodes_db_a16 = ops_fpu_cyrix_686_db_a16;
x86_opcodes_db_a32 = ops_fpu_cyrix_686_db_a32;
x86_opcodes_dd_a16 = ops_fpu_cyrix_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_cyrix_dd_a32;
x86_opcodes_df_a16 = ops_fpu_cyrix_686_df_a16;
x86_opcodes_df_a32 = ops_fpu_cyrix_686_df_a32;
}
}

Expand Down Expand Up @@ -4291,6 +4301,9 @@ cpu_write(uint16_t addr, uint8_t val, UNUSED(void *priv))
if ((ccr3 & 0xf0) == 0x10)
ccr6 = val;
break;
case 0xeb: /* CCR7 */
ccr7 = val & 5;
break;
}
}

Expand Down Expand Up @@ -4319,6 +4332,8 @@ cpu_read(uint16_t addr, UNUSED(void *priv))
return ((ccr3 & 0xf0) == 0x10) ? ccr5 : 0xff;
case 0xea:
return ((ccr3 & 0xf0) == 0x10) ? ccr6 : 0xff;
case 0xeb:
return ccr7;
case 0xfe:
return cpu_s->cyrix_id & 0xff;
case 0xff:
Expand Down
10 changes: 10 additions & 0 deletions src/cpu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,16 @@ extern uint32_t _tr[8];
extern uint32_t cache_index;
extern uint8_t _cache[2048];

/* For the Cyrix 6x86(MX) */
extern uint8_t ccr0;
extern uint8_t ccr1;
extern uint8_t ccr2;
extern uint8_t ccr3;
extern uint8_t ccr4;
extern uint8_t ccr5;
extern uint8_t ccr6;
extern uint8_t ccr7;

/*Segments -
_cs,_ds,_es,_ss are the segment structures
CS,DS,ES,SS is the 16-bit data
Expand Down
4 changes: 4 additions & 0 deletions src/cpu/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ reset_common(int hard)
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
msw = 0;
new_ne = 0;

ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = ccr7 = 0;
ccr4 = 0x85;

if (hascache)
cr0 = 1 << 30;
else
Expand Down
18 changes: 18 additions & 0 deletions src/cpu/x86_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,20 @@ extern const OpFn ops_sf_fpu_d8_a16[32];
extern const OpFn ops_sf_fpu_d8_a32[32];
extern const OpFn ops_sf_fpu_d9_a16[256];
extern const OpFn ops_sf_fpu_d9_a32[256];
extern const OpFn ops_sf_fpu_cyrix_d9_a16[256];
extern const OpFn ops_sf_fpu_cyrix_d9_a32[256];
extern const OpFn ops_sf_fpu_da_a16[256];
extern const OpFn ops_sf_fpu_da_a32[256];
extern const OpFn ops_sf_fpu_db_a16[256];
extern const OpFn ops_sf_fpu_db_a32[256];
extern const OpFn ops_sf_fpu_cyrix_686_db_a16[256];
extern const OpFn ops_sf_fpu_cyrix_686_db_a32[256];
extern const OpFn ops_sf_fpu_dc_a16[32];
extern const OpFn ops_sf_fpu_dc_a32[32];
extern const OpFn ops_sf_fpu_dd_a16[256];
extern const OpFn ops_sf_fpu_dd_a32[256];
extern const OpFn ops_sf_fpu_cyrix_dd_a16[256];
extern const OpFn ops_sf_fpu_cyrix_dd_a32[256];
extern const OpFn ops_sf_fpu_de_a16[256];
extern const OpFn ops_sf_fpu_de_a32[256];
extern const OpFn ops_sf_fpu_df_a16[256];
Expand All @@ -297,6 +303,8 @@ extern const OpFn ops_fpu_d8_a16[32];
extern const OpFn ops_fpu_d8_a32[32];
extern const OpFn ops_fpu_d9_a16[256];
extern const OpFn ops_fpu_d9_a32[256];
extern const OpFn ops_fpu_cyrix_d9_a16[256];
extern const OpFn ops_fpu_cyrix_d9_a32[256];
extern const OpFn ops_fpu_da_a16[256];
extern const OpFn ops_fpu_da_a32[256];
extern const OpFn ops_fpu_db_a16[256];
Expand All @@ -305,6 +313,8 @@ extern const OpFn ops_fpu_dc_a16[32];
extern const OpFn ops_fpu_dc_a32[32];
extern const OpFn ops_fpu_dd_a16[256];
extern const OpFn ops_fpu_dd_a32[256];
extern const OpFn ops_fpu_cyrix_dd_a16[256];
extern const OpFn ops_fpu_cyrix_dd_a32[256];
extern const OpFn ops_fpu_de_a16[256];
extern const OpFn ops_fpu_de_a32[256];
extern const OpFn ops_fpu_df_a16[256];
Expand All @@ -316,15 +326,23 @@ extern const OpFn ops_sf_fpu_686_da_a16[256];
extern const OpFn ops_sf_fpu_686_da_a32[256];
extern const OpFn ops_sf_fpu_686_db_a16[256];
extern const OpFn ops_sf_fpu_686_db_a32[256];
extern const OpFn ops_sf_fpu_cyrix_686_db_a16[256];
extern const OpFn ops_sf_fpu_cyrix_686_db_a32[256];
extern const OpFn ops_sf_fpu_686_df_a16[256];
extern const OpFn ops_sf_fpu_686_df_a32[256];
extern const OpFn ops_sf_fpu_cyrix_686_df_a16[256];
extern const OpFn ops_sf_fpu_cyrix_686_df_a32[256];

extern const OpFn ops_fpu_686_da_a16[256];
extern const OpFn ops_fpu_686_da_a32[256];
extern const OpFn ops_fpu_686_db_a16[256];
extern const OpFn ops_fpu_686_db_a32[256];
extern const OpFn ops_fpu_cyrix_686_db_a16[256];
extern const OpFn ops_fpu_cyrix_686_db_a32[256];
extern const OpFn ops_fpu_686_df_a16[256];
extern const OpFn ops_fpu_686_df_a32[256];
extern const OpFn ops_fpu_cyrix_686_df_a16[256];
extern const OpFn ops_fpu_cyrix_686_df_a32[256];

extern const OpFn ops_REPE[1024];
extern const OpFn ops_REPNE[1024];
Expand Down
Loading

0 comments on commit 5f3641e

Please sign in to comment.