Added F2/F3 prefix handling and a bunch of F2 0F and F3 0F opcodes

This commit is contained in:
ptitSeb 2021-03-05 18:34:12 +01:00
parent 5119464274
commit 7694594f8b
6 changed files with 180 additions and 3 deletions

View File

@ -113,6 +113,8 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/emu/x64run66.c"
"${BOX64_ROOT}/src/emu/x64rund9.c"
"${BOX64_ROOT}/src/emu/x64rundb.c"
"${BOX64_ROOT}/src/emu/x64runf20f.c"
"${BOX64_ROOT}/src/emu/x64runf30f.c"
"${BOX64_ROOT}/src/emu/x64run_private.c"
"${BOX64_ROOT}/src/emu/x64syscall.c"
"${BOX64_ROOT}/src/emu/x64tls.c"

View File

@ -19,12 +19,16 @@
#define GETGB opgd=GetGb(emu, rex, nextop)
#define GETEW oped=GetEw(emu, rex, nextop)
#define GETGW opgd=GetGw(emu, rex, nextop)
#define GETEX opex=GetEx(emu, rex, nextop)
#define GETGX opgx=GetGx(emu, rex, nextop)
#define ED oped
#define GD opgd
#define EB oped
#define GB opgd->byte[0]
#define EW oped
#define GW opgd
#define EX opex
#define GX opgx
#define GOCOND(BASE, PREFIX, CONDITIONAL) \
case BASE+0x0: \

View File

@ -40,6 +40,7 @@ int Run(x64emu_t *emu, int step)
uint64_t tmp64u;
int32_t tmp32s;
rex_t rex;
int rep; // 0 none, 1=F2 prefix, 2=F3 prefix
int unimp = 0;
if(emu->quit)
@ -62,6 +63,12 @@ x64emurun:
emu->old_ip = R_RIP;
opcode = F8;
rep = 0;
while((opcode==0xF2) || (opcode==0xF3)) {
rep = opcode-0xF1;
opcode = F8;
}
if(opcode>=0x40 && opcode<=0x4f) {
rex.rex = opcode;
opcode = F8;
@ -114,9 +121,25 @@ x64emurun:
GO(0x00, add) /* ADD 0x00 -> 0x05 */
GO(0x08, or) /* OR 0x08 -> 0x0D */
case 0x0F: /* More instructions */
if(Run0F(emu, rex)) {
unimp = 1;
goto fini;
switch(rep) {
case 1:
if(RunF20F(emu, rex)) {
unimp = 1;
goto fini;
}
break;
case 2:
if(RunF30F(emu, rex)) {
unimp = 1;
goto fini;
}
break;
default:
if(Run0F(emu, rex)) {
unimp = 1;
goto fini;
}
break;
}
if(emu->quit)
goto fini;

View File

@ -231,6 +231,8 @@ int Run66(x64emu_t *emu, rex_t rex);
//int Run67(x64emu_t *emu, rex_t rex);
int RunD9(x64emu_t *emu, rex_t rex);
int RunDB(x64emu_t *emu, rex_t rex);
int RunF20F(x64emu_t *emu, rex_t rex);
int RunF30F(x64emu_t *emu, rex_t rex);
//void Run660F(x64emu_t *emu);
//void Run66D9(x64emu_t *emu); // x87
//void Run6766(x64emu_t *emu);

63
src/emu/x64runf20f.c Normal file
View File

@ -0,0 +1,63 @@
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.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"
#ifdef DYNAREC
#include "../dynarec/arm_lock_helper.h"
#endif
#include "modrm.h"
int RunF20F(x64emu_t *emu, rex_t rex)
{
uint8_t opcode;
uint8_t nextop;
int32_t tmp32s;
reg64_t *oped, *opgd;
sse_regs_t *opex, *opgx;
opcode = F8;
switch(opcode) {
case 0x10: /* MOVSD Gx, Ex */
nextop = F8;
GETEX;
GETGX;
GX->q[0] = EX->q[0];
if((nextop&0xC0)!=0xC0) {
// EX is not a register
GX->q[1] = 0;
}
break;
case 0x11: /* MOVSD Ex, Gx */
nextop = F8;
GETEX;
GETGX;
EX->q[0] = GX->q[0];
break;
default:
return 1;
}
return 0;
}

83
src/emu/x64runf30f.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 <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"
#ifdef DYNAREC
#include "../dynarec/arm_lock_helper.h"
#endif
#include "modrm.h"
int RunF30F(x64emu_t *emu, rex_t rex)
{
uint8_t opcode;
uint8_t nextop;
int32_t tmp32s;
reg64_t *oped, *opgd;
sse_regs_t *opex, *opgx;
opcode = F8;
switch(opcode) {
case 0x10: /* MOVSS Gx Ex */
nextop = F8;
GETEX;
GETGX;
GX->ud[0] = EX->ud[0];
if((nextop&0xC0)!=0xC0) {
// EX is not a register (reg to reg only move 31:0)
GX->ud[1] = GX->ud[2] = GX->ud[3] = 0;
}
break;
case 0x11: /* MOVSS Ex Gx */
nextop = F8;
GETEX;
GETGX;
EX->ud[0] = GX->ud[0];
break;
case 0x2A: /* CVTSI2SS Gx, Ed */
nextop = F8;
GETED;
GETGX;
GX->f[0] = ED->sdword[0];
break;
case 0x59: /* MULSS Gx, Ex */
nextop = F8;
GETEX;
GETGX;
GX->f[0] *= EX->f[0];
break;
case 0x5A: /* CVTSS2SD Gx, Ex */
nextop = F8;
GETEX;
GETGX;
GX->d[0] = EX->f[0];
break;
default:
return 1;
}
return 0;
}