diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-16 20:06:18 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-16 20:06:18 +0000 |
| commit | cc9191382f73841b8577cb4811c9ed85466ce8b0 (patch) | |
| tree | 3e77b444c4f422275ee5125e6cf9510b6cdb6a2e /src | |
| parent | 0e86633cde3bd660cc052ab0da6b443c3121e759 (diff) | |
| download | box64-cc9191382f73841b8577cb4811c9ed85466ce8b0.tar.gz box64-cc9191382f73841b8577cb4811c9ed85466ce8b0.zip | |
[RV64_DYNAREC] Added some 66 0F prefixed opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 92 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 87 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 4 |
4 files changed, 185 insertions, 2 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index b3d75989..293f054f 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -133,6 +133,10 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } break; + case 0x66: + addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + break; + case 0x68: INST_NAME("PUSH Id"); i64 = F32S; diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c new file mode 100644 index 00000000..f42ca1fb --- /dev/null +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -0,0 +1,92 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <pthread.h> +#include <errno.h> + +#include "debug.h" +#include "box64context.h" +#include "dynarec.h" +#include "emu/x64emu_private.h" +#include "emu/x64run_private.h" +#include "x64run.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "dynarec_native.h" + +#include "rv64_printer.h" +#include "dynarec_rv64_private.h" +#include "dynarec_rv64_helper.h" +#include "dynarec_rv64_functions.h" + + +uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) +{ + uint8_t opcode = F8; + uint8_t nextop, u8; + int16_t i16; + uint16_t u16; + uint64_t u64; + int32_t i32; + int64_t j64; + uint8_t gd, ed; + uint8_t wback, wb1; + int64_t fixedaddress; + int unscaled; + int lock; + MAYUSE(u8); + MAYUSE(u16); + MAYUSE(u64); + MAYUSE(j64); + MAYUSE(lock); + + while((opcode==0x2E) || (opcode==0x36) || (opcode==0x66)) // ignoring CS:, SS: or multiple 0x66 + opcode = F8; + + while((opcode==0xF2) || (opcode==0xF3)) { + rep = opcode-0xF1; + opcode = F8; + } + // REX prefix before the 66 are ignored + rex.rex = 0; + while(opcode>=0x40 && opcode<=0x4f) { + rex.rex = opcode; + opcode = F8; + } + + if(rex.w && opcode!=0x0f) // rex.w cancels "66", but not for 66 0f type of prefix + return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog); // addr-1, to "put back" opcode + + switch(opcode) { + + case 0x0F: + addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog); + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: + // just use regular conditional jump + return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog); + + default: + DEFAULT; + } + return addr; +} diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c new file mode 100644 index 00000000..8210a27d --- /dev/null +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -0,0 +1,87 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <pthread.h> +#include <errno.h> + +#include "debug.h" +#include "box64context.h" +#include "dynarec.h" +#include "emu/x64emu_private.h" +#include "emu/x64run_private.h" +#include "x64run.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "dynarec_native.h" + +#include "rv64_printer.h" +#include "dynarec_rv64_private.h" +#include "dynarec_rv64_functions.h" +#include "dynarec_rv64_helper.h" + +uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) +{ + (void)ip; (void)need_epilog; + + uint8_t opcode = F8; + uint8_t nextop, u8; + int32_t i32; + uint8_t gd, ed; + uint8_t wback, wb1, wb2; + uint8_t eb1, eb2; + int64_t j64; + uint64_t tmp64u, tmp64u2; + int v0, v1; + int q0, q1; + int d0, d1; + int64_t fixedaddress; + int unscaled; + + MAYUSE(d0); + MAYUSE(d1); + MAYUSE(q0); + MAYUSE(q1); + MAYUSE(eb1); + MAYUSE(eb2); + MAYUSE(j64); + + switch(opcode) { + + case 0x1F: + INST_NAME("NOP (multibyte)"); + nextop = F8; + FAKEED; + break; + + #define GO(GETFLAGS, NO, YES, F) \ + READFLAGS(F); \ + GETFLAGS; \ + nextop=F8; \ + GETGD; \ + if(MODREG) { \ + ed = xRAX+(nextop&7)+(rex.b<<3); \ + SLLI(x4, ed, 48); \ + SRLI(x4, x4, 48); \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \ + LHU(x4, ed, fixedaddress); \ + ed = x4; \ + } \ + B##NO(x1, 4+4*4); \ + ADDI(x3, xZR, -1); \ + SRLI(x3, x3, 48); \ + AND(gd, gd, x3); \ + OR(gd, gd, ed); + + GOCOND(0x40, "CMOV", "Gw, Ew"); + #undef GO + + default: + DEFAULT; + } + return addr; +} diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index ece99d3f..741577d0 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -663,7 +663,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); //uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog); //uintptr_t dynarec64_65(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog); -//uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); @@ -674,7 +674,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni //uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); -//uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); //uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog); //uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); |