Skip to content

Commit

Permalink
Added AMD K6-2+ and K6-III+ 3DNow! DSP Extensions.
Browse files Browse the repository at this point in the history
  • Loading branch information
OBattler committed Nov 6, 2022
1 parent 95210fa commit fc53fce
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 9 deletions.
12 changes: 10 additions & 2 deletions src/cpu/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ enum {
};

/*Addition flags returned by CPUID function 0x80000001*/
#define CPUID_3DNOW (1UL << 31UL)
#define CPUID_3DNOW (1UL << 31UL)
#define CPUID_3DNOWE (1UL << 30UL)

/* Make sure this is as low as possible. */
cpu_state_t cpu_state;
Expand Down Expand Up @@ -1167,6 +1168,11 @@ cpu_set(void)
# endif
#endif

if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) {
x86_opcodes_3DNOW = ops_3DNOWE;
x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE;
}

timing_rr = 1; /* register dest - register src */
timing_rm = 2; /* register dest - memory src */
timing_mr = 3; /* memory dest - register src */
Expand Down Expand Up @@ -1202,6 +1208,8 @@ cpu_set(void)
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
if (cpu_s->cpu_type >= CPU_K6_2)
cpu_features |= CPU_FEATURE_3DNOW;
if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P))
cpu_features |= CPU_FEATURE_3DNOWE;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
#if defined(DEV_BRANCH) && defined(USE_AMD_K5)
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE;
Expand Down Expand Up @@ -1831,7 +1839,7 @@ cpu_CPUID(void)
case 0x80000001:
EAX = CPUID + 0x100;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW;
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_MCE | CPUID_CMPXCHG8B | CPUID_AMDSEP | CPUID_MMX | CPUID_3DNOW | CPUID_3DNOWE;
break;
case 0x80000002: /* Processor name string */
EAX = 0x2d444d41; /* AMD-K6(tm)-III P */
Expand Down
15 changes: 8 additions & 7 deletions src/cpu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,14 +503,15 @@ extern int isibm486;
extern int is_nec;
extern int is_rapidcad;
extern int hasfpu;
#define CPU_FEATURE_RDTSC (1 << 0)
#define CPU_FEATURE_MSR (1 << 1)
#define CPU_FEATURE_MMX (1 << 2)
#define CPU_FEATURE_CR4 (1 << 3)
#define CPU_FEATURE_VME (1 << 4)
#define CPU_FEATURE_CX8 (1 << 5)
#define CPU_FEATURE_3DNOW (1 << 6)
#define CPU_FEATURE_RDTSC (1 << 0)
#define CPU_FEATURE_MSR (1 << 1)
#define CPU_FEATURE_MMX (1 << 2)
#define CPU_FEATURE_CR4 (1 << 3)
#define CPU_FEATURE_VME (1 << 4)
#define CPU_FEATURE_CX8 (1 << 5)
#define CPU_FEATURE_3DNOW (1 << 6)
#define CPU_FEATURE_SYSCALL (1 << 7)
#define CPU_FEATURE_3DNOWE (1 << 8)

extern uint32_t cpu_features;

Expand Down
2 changes: 2 additions & 0 deletions src/cpu/x86_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ extern const OpFn dynarec_ops_fpu_686_df_a32[256];
extern const OpFn dynarec_ops_REPE[1024];
extern const OpFn dynarec_ops_REPNE[1024];
extern const OpFn dynarec_ops_3DNOW[256];
extern const OpFn dynarec_ops_3DNOWE[256];
#else
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f);
#endif
Expand Down Expand Up @@ -250,6 +251,7 @@ extern const OpFn ops_fpu_686_df_a32[256];
extern const OpFn ops_REPE[1024];
extern const OpFn ops_REPNE[1024];
extern const OpFn ops_3DNOW[256];
extern const OpFn ops_3DNOWE[256];

#define C0 (1<<8)
#define C1 (1<<9)
Expand Down
87 changes: 87 additions & 0 deletions src/cpu/x86_ops_3dnow.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ static int opPF2ID(uint32_t fetchdat)

return 0;
}
static int opPF2IW(uint32_t fetchdat)
{
MMX_REG src;

MMX_GETSRC();

cpu_state.MM[cpu_reg].sw[0] = (int32_t)src.f[0];
cpu_state.MM[cpu_reg].sw[1] = (int32_t)src.f[1];

return 0;
}
static int opPFACC(uint32_t fetchdat)
{
MMX_REG src;
Expand All @@ -71,6 +82,47 @@ static int opPFACC(uint32_t fetchdat)

return 0;
}
static int opPFNACC(uint32_t fetchdat)
{
MMX_REG src;
float tempf;

MMX_GETSRC();

tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1];
cpu_state.MM[cpu_reg].f[0] = tempf;

return 0;
}
static int opPFPNACC(uint32_t fetchdat)
{
MMX_REG src;
float tempf;

MMX_GETSRC();

tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1];
cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1];
cpu_state.MM[cpu_reg].f[0] = tempf;

return 0;
}
static int opPSWAPD(uint32_t fetchdat)
{
MMX_REG src;
float tempf, tempf2;

MMX_GETSRC();

/* We have to do this in case source and destination overlap. */
tempf = src.f[0];
tempf2 = src.f[1];
cpu_state.MM[cpu_reg].f[1] = tempf;
cpu_state.MM[cpu_reg].f[0] = tempf2;

return 0;
}
static int opPFADD(uint32_t fetchdat)
{
MMX_REG src;
Expand Down Expand Up @@ -268,6 +320,17 @@ static int opPI2FD(uint32_t fetchdat)

return 0;
}
static int opPI2FW(uint32_t fetchdat)
{
MMX_REG src;

MMX_GETSRC();

cpu_state.MM[cpu_reg].f[0] = (float)src.sw[0];
cpu_state.MM[cpu_reg].f[1] = (float)src.sw[1];

return 0;
}
static int opPMULHRW(uint32_t fetchdat)
{
if (cpu_mod == 3)
Expand Down Expand Up @@ -318,6 +381,30 @@ const OpFn OP_TABLE(3DNOW)[256] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};

const OpFn OP_TABLE(3DNOWE)[256] =
{
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FW, opPI2FD, ILLEGAL, ILLEGAL,
/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2IW, opPF2ID, ILLEGAL, ILLEGAL,
/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,

/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPFNACC, ILLEGAL, ILLEGAL, ILLEGAL, opPFPNACC, ILLEGAL,
/*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT, ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL,
/*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1, ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL,
/*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW, ILLEGAL, ILLEGAL, ILLEGAL, opPSWAPD, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB,

/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};

static int op3DNOW_a16(uint32_t fetchdat)
{
uint8_t opcode;
Expand Down

0 comments on commit fc53fce

Please sign in to comment.