diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-05 18:34:12 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-05 18:34:12 +0100 |
| commit | 7694594f8b346cda6c9f79014ca7e563496d86f7 (patch) | |
| tree | ba9a1baf650ad6d6fa7a5e1c19e4d5f054cd8f29 /src | |
| parent | 51194642742de3f182328815c8aabdd6256a562e (diff) | |
| download | box64-7694594f8b346cda6c9f79014ca7e563496d86f7.tar.gz box64-7694594f8b346cda6c9f79014ca7e563496d86f7.zip | |
Added F2/F3 prefix handling and a bunch of F2 0F and F3 0F opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/modrm.h | 4 | ||||
| -rwxr-xr-x | src/emu/x64run.c | 29 | ||||
| -rwxr-xr-x | src/emu/x64run_private.h | 2 | ||||
| -rw-r--r-- | src/emu/x64runf20f.c | 63 | ||||
| -rw-r--r-- | src/emu/x64runf30f.c | 83 |
5 files changed, 178 insertions, 3 deletions
diff --git a/src/emu/modrm.h b/src/emu/modrm.h index b2c0580e..233b1bb8 100644 --- a/src/emu/modrm.h +++ b/src/emu/modrm.h @@ -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: \ diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 35dc865a..96bf5aa8 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -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; diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h index 6dda57ec..4d53a98e 100755 --- a/src/emu/x64run_private.h +++ b/src/emu/x64run_private.h @@ -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); diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c new file mode 100644 index 00000000..4188e0fd --- /dev/null +++ b/src/emu/x64runf20f.c @@ -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; +} \ No newline at end of file diff --git a/src/emu/x64runf30f.c b/src/emu/x64runf30f.c new file mode 100644 index 00000000..e712d362 --- /dev/null +++ b/src/emu/x64runf30f.c @@ -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; +} \ No newline at end of file |