[INTERPRETER] Added avx (F3 0F) 6F and (66 0F) 70

This commit is contained in:
ptitSeb 2024-05-26 12:57:59 +02:00
parent da7474b1de
commit 95b516127a
9 changed files with 266 additions and 18 deletions

View File

@ -396,6 +396,9 @@ set(INTERPRETER
"${BOX64_ROOT}/src/emu/x64runf20f.c"
"${BOX64_ROOT}/src/emu/x64runf30f.c"
"${BOX64_ROOT}/src/emu/x64runavx.c"
"${BOX64_ROOT}/src/emu/x64runavx0f.c"
"${BOX64_ROOT}/src/emu/x64runavx660f.c"
"${BOX64_ROOT}/src/emu/x64runavxf30f.c"
)
if(STATICBUILD)

View File

@ -1,3 +1,5 @@
#include <stddef.h>
#define F8 *(uint8_t*)(addr++)
#define F8S *(int8_t*)(addr++)
#define F16 *(uint16_t*)(addr+=2, addr-2)
@ -41,6 +43,8 @@
#define GETEX32(D) opex=TestEx32O(test, &addr, rex, nextop, D, 0)
#define GETEX_OFFS(D, O) opex=TestExO(test, &addr, rex, nextop, D, O)
#define GETGX opgx=GetGx(test->emu, &addr, rex, nextop)
#define GETGY opgy=GetGy(emu, &addr, rex, nextop)
#define GETEY opey=(opex>=&emu->xmm[0] && opex<=&emu->xmm[15])?((sse_regs_t*)((uintptr_t)opex+offsetof(x64emu_t, ymm)-offsetof(x64emu_t, xmm))):((sse_regs_t*)((uintptr_t)opex+16))
#define GETEM(D) opem=TestEm(test, &addr, rex, nextop, D)
#define GETEM32(D) opem=TestEm32O(test, &addr, rex, nextop, D, 0)
#define GETGM opgm=GetGm(test->emu, &addr, rex, nextop)
@ -67,6 +71,8 @@
#define GETEX32(D) opex=GetEx32O(emu, &addr, rex, nextop, D, 0)
#define GETEX_OFFS(D, O) opex=GetExO(emu, &addr, rex, nextop, D, O)
#define GETGX opgx=GetGx(emu, &addr, rex, nextop)
#define GETGY opgy=GetGy(emu, &addr, rex, nextop)
#define GETEY opey=(opex>=&emu->xmm[0] && opex<=&emu->xmm[15])?((sse_regs_t*)((uintptr_t)opex+offsetof(x64emu_t, ymm)-offsetof(x64emu_t, xmm))):((sse_regs_t*)((uintptr_t)opex+16))
#define GETEM(D) opem=GetEm(emu, &addr, rex, nextop, D)
#define GETEM32(D) opem=GetEm32O(emu, &addr, rex, nextop, D, 0)
#define GETGM opgm=GetGm(emu, &addr, rex, nextop)
@ -79,6 +85,8 @@
#define GW opgd
#define EX opex
#define GX opgx
#define EY opey
#define GY opgy
#define EM opem
#define GM opgm
#define FAKEED(D) GetEd(emu, &addr, rex, nextop, D)

View File

@ -38,7 +38,7 @@ typedef struct x64test_s {
int test;
int clean;
int notest;
uint8_t mem[16];
uint8_t mem[32];
} x64test_t;
typedef struct emu_flags_s {

View File

@ -2002,3 +2002,9 @@ sse_regs_t* GetGx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
uint8_t m = (v&0x38)>>3;
return &emu->xmm[(m&7)+(rex.r<<3)];
}
sse_regs_t* GetGy(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v)
{
uint8_t m = (v&0x38)>>3;
return &emu->ymm[(m&7)+(rex.r<<3)];
}

View File

@ -138,6 +138,7 @@ mmx87_regs_t* GetGm(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v);
mmx87_regs_t* GetEm32O(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
mmx87_regs_t* TestEm32O(x64test_t *test, uintptr_t* addr, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
sse_regs_t* GetGx(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v);
sse_regs_t* GetGy(x64emu_t *emu, uintptr_t* addr, rex_t rex, uint8_t v);
void UpdateFlags(x64emu_t *emu);
@ -172,6 +173,9 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr);
uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step);
uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr);
uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
uintptr_t Test0F(x64test_t *test, rex_t rex, uintptr_t addr, int *step);
@ -202,6 +206,9 @@ uintptr_t TestF0(x64test_t *test, rex_t rex, uintptr_t addr);
uintptr_t TestF20F(x64test_t *test, rex_t rex, uintptr_t addr, int *step);
uintptr_t TestF30F(x64test_t *test, rex_t rex, uintptr_t addr);
uintptr_t TestAVX(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
uintptr_t TestAVX_OF(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
uintptr_t TestAVX_66OF(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
uintptr_t TestAVX_F3OF(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
void x64Syscall(x64emu_t *emu);

View File

@ -51,22 +51,12 @@ uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
#ifdef TEST_INTERPRETER
x64emu_t *emu = test->emu;
#endif
opcode = F8;
if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_NONE))
return RunAVX_0F(emu, vex, addr, step);
if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_66))
return RunAVX_660F(emu, vex, addr, step);
if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F3))
return RunAVX_F30F(emu, vex, addr, step);
switch(opcode) {
case 0x77:
if(!vex.l && (vex.m==VEX_M_0F) && (vex.p==VEX_P_NONE)) {
if(vex.v!=0) {
emit_signal(emu, SIGILL, (void*)R_RIP, 0);
} else {
memset(emu->ymm, 0, sizeof(sse_regs_t)*(vex.rex.is32bits)?16:8);
}
} else
return 0;
break;
default:
return 0;
}
return addr;
return 0;
}

72
src/emu/x64runavx0f.c Normal file
View File

@ -0,0 +1,72 @@
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fenv.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include "debug.h"
#include "box64stack.h"
#include "x64emu.h"
#include "x64run.h"
#include "x64emu_private.h"
#include "x64run_private.h"
#include "x64primop.h"
#include "x64trace.h"
#include "x87emu_private.h"
#include "box64context.h"
#include "my_cpuid.h"
#include "bridge.h"
#include "signals.h"
#include "x64shaext.h"
#ifdef DYNAREC
#include "custommem.h"
#include "../dynarec/native_lock.h"
#endif
#include "modrm.h"
#ifdef TEST_INTERPRETER
uintptr_t TestAVX_0F(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
#else
uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
#endif
{
uint8_t opcode;
uint8_t nextop;
uint8_t tmp8u;
int8_t tmp8s;
int32_t tmp32s, tmp32s2;
uint32_t tmp32u, tmp32u2;
uint64_t tmp64u, tmp64u2;
int64_t tmp64s;
reg64_t *oped, *opgd;
sse_regs_t *opex, *opgx, eax1;
mmx87_regs_t *opem, *opgm, eam1;
#ifdef TEST_INTERPRETER
x64emu_t *emu = test->emu;
#endif
opcode = F8;
switch(opcode) {
case 0x77:
if(!vex.l) { // VZEROUPPER
if(vex.v!=0) {
emit_signal(emu, SIGILL, (void*)R_RIP, 0);
} else {
memset(emu->ymm, 0, sizeof(sse_regs_t)*(vex.rex.is32bits)?16:8);
}
} else
return 0;
break;
default:
return 0;
}
return addr;
}

83
src/emu/x64runavx660f.c Normal file
View File

@ -0,0 +1,83 @@
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fenv.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include "debug.h"
#include "box64stack.h"
#include "x64emu.h"
#include "x64run.h"
#include "x64emu_private.h"
#include "x64run_private.h"
#include "x64primop.h"
#include "x64trace.h"
#include "x87emu_private.h"
#include "box64context.h"
#include "my_cpuid.h"
#include "bridge.h"
#include "signals.h"
#include "x64shaext.h"
#ifdef DYNAREC
#include "custommem.h"
#include "../dynarec/native_lock.h"
#endif
#include "modrm.h"
#ifdef TEST_INTERPRETER
uintptr_t TestAVX_660F(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
#else
uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
#endif
{
uint8_t opcode;
uint8_t nextop;
uint8_t tmp8u;
int8_t tmp8s;
int32_t tmp32s, tmp32s2;
uint32_t tmp32u, tmp32u2;
uint64_t tmp64u, tmp64u2;
int64_t tmp64s;
reg64_t *oped, *opgd;
sse_regs_t *opex, *opgx, eax1;
sse_regs_t *opey, *opgy, eay1;
#ifdef TEST_INTERPRETER
x64emu_t *emu = test->emu;
#endif
opcode = F8;
rex_t rex = vex.rex;
switch(opcode) {
case 0x70: /* PSHUFD Gx,Ex,Ib */
nextop = F8;
GETEX(1);
GETGX;
tmp8u = F8;
GETGY;
if(vex.l) {
GETEY;
if(EY==GY) {eay1 = *GY; EY = &eay1;} // copy is needed
for (int i=0; i<4; ++i)
GY->ud[4+i] = EY->ud[4+(tmp8u>>(i*2))&3];
} else
memset(GY, 0, 16);
if(EX==GX) {eax1 = *GX; EX = &eax1;} // copy is needed
for (int i=0; i<4; ++i)
GX->ud[i] = EX->ud[(tmp8u>>(i*2))&3];
break;
default:
return 0;
}
return addr;
}

79
src/emu/x64runavxf30f.c Normal file
View File

@ -0,0 +1,79 @@
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fenv.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include "debug.h"
#include "box64stack.h"
#include "x64emu.h"
#include "x64run.h"
#include "x64emu_private.h"
#include "x64run_private.h"
#include "x64primop.h"
#include "x64trace.h"
#include "x87emu_private.h"
#include "box64context.h"
#include "my_cpuid.h"
#include "bridge.h"
#include "signals.h"
#include "x64shaext.h"
#ifdef DYNAREC
#include "custommem.h"
#include "../dynarec/native_lock.h"
#endif
#include "modrm.h"
#ifdef TEST_INTERPRETER
uintptr_t TestAVX_F30F(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
#else
uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
#endif
{
uint8_t opcode;
uint8_t nextop;
uint8_t tmp8u;
int8_t tmp8s;
int32_t tmp32s, tmp32s2;
uint32_t tmp32u, tmp32u2;
uint64_t tmp64u, tmp64u2;
int64_t tmp64s;
reg64_t *oped, *opgd;
sse_regs_t *opex, *opgx, eax1;
sse_regs_t *opey, *opgy, eay1;
#ifdef TEST_INTERPRETER
x64emu_t *emu = test->emu;
#endif
opcode = F8;
rex_t rex = vex.rex;
switch(opcode) {
case 0x6F: // VMOVDQU
nextop = F8;
GETEX(0);
GETGX;
memcpy(GX, EX, 16); // unaligned...
if(vex.l) {
GETGY;
GETEY;
if(MODREG)
memcpy(GY, EY, 16);
else
memset(GY, 0, 16);
}
break;
default:
return 0;
}
return addr;
}