diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-06-01 13:33:20 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-06-01 13:33:20 +0200 |
| commit | 0336f6a9872d5c95959a8566d5e0391890761794 (patch) | |
| tree | f089a012956eac892c4448a20560f8a5b24b01cf /src | |
| parent | 6d68975ba51bc2db7cff709c596487527cd115fd (diff) | |
| download | box64-0336f6a9872d5c95959a8566d5e0391890761794.tar.gz box64-0336f6a9872d5c95959a8566d5e0391890761794.zip | |
[ARM64_DYNAREC] Added a few 67 prefixed opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67.c | 61 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_67_avx.c | 112 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 | ||||
| -rw-r--r-- | src/emu/x64run67.c | 6 |
4 files changed, 181 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index 6d8c336e..efe989fb 100644 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -1093,6 +1093,53 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } break; + case 0xC4: + nextop = F8; + if(rex.is32bits && !(MODREG)) { + DEFAULT; + } else { + if(rex.is32bits) { + DEFAULT; + return addr; + } + vex_t vex = {0}; + vex.rex = rex; + u8 = nextop; + vex.m = u8&0b00011111; + vex.rex.b = (u8&0b00100000)?0:1; + vex.rex.x = (u8&0b01000000)?0:1; + vex.rex.r = (u8&0b10000000)?0:1; + u8 = F8; + vex.p = u8&0b00000011; + vex.l = (u8>>2)&1; + vex.v = ((~u8)>>3)&0b1111; + vex.rex.w = (u8>>7)&1; + addr = dynarec64_67_AVX(dyn, addr, ip, ninst, vex, ok, need_epilog); + } + break; + case 0xC5: + nextop = F8; + if(rex.is32bits && !(MODREG)) { + DEFAULT; + } else { + if(rex.is32bits) { + DEFAULT; + return addr; + } + vex_t vex = {0}; + vex.rex = rex; + u8 = nextop; + vex.p = u8&0b00000011; + vex.l = (u8>>2)&1; + vex.v = ((~u8)>>3)&0b1111; + vex.rex.r = (u8&0b10000000)?0:1; + vex.rex.b = 0; + vex.rex.x = 0; + vex.rex.w = 0; + vex.m = VEX_M_0F; + addr = dynarec64_67_AVX(dyn, addr, ip, ninst, vex, ok, need_epilog); + } + break; case 0xC6: INST_NAME("MOV Eb, Ib"); nextop=F8; @@ -1344,6 +1391,20 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xFF: nextop = F8; switch((nextop>>3)&7) { + case 0: // INC Ed + INST_NAME("INC Ed"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING); + GETED32(0); + emit_inc32(dyn, ninst, rex, ed, x3, x4); + WBACK; + break; + case 1: //DEC Ed + INST_NAME("DEC Ed"); + SETFLAGS(X_ALL&~X_CF, SF_SUBSET_PENDING); + GETED32(0); + emit_dec32(dyn, ninst, rex, ed, x3, x4); + WBACK; + break; case 2: // CALL Ed INST_NAME("CALL Ed"); PASS2IF((box64_dynarec_safeflags>1) || diff --git a/src/dynarec/arm64/dynarec_arm64_67_avx.c b/src/dynarec/arm64/dynarec_arm64_67_avx.c new file mode 100644 index 00000000..1e1e5926 --- /dev/null +++ b/src/dynarec/arm64/dynarec_arm64_67_avx.c @@ -0,0 +1,112 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.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 "arm64_printer.h" +#include "dynarec_arm64_private.h" +#include "dynarec_arm64_functions.h" +#include "dynarec_arm64_helper.h" + +static const char* avx_prefix_string(uint16_t p) +{ + switch(p) { + case VEX_P_NONE: return "0"; + case VEX_P_66: return "66"; + case VEX_P_F2: return "F2"; + case VEX_P_F3: return "F3"; + default: return "??"; + } +} +static const char* avx_map_string(uint16_t m) +{ + switch(m) { + case VEX_M_NONE: return "0"; + case VEX_M_0F: return "0F"; + case VEX_M_0F38: return "0F38"; + case VEX_M_0F3A: return "0F3A"; + default: return "??"; + } +} + +uintptr_t dynarec64_67_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) +{ + (void)ip; (void)need_epilog; + uint8_t opcode = F8; + uint8_t nextop, u8; + uint8_t gd, ed, vd; + uint8_t wback, wb1, wb2; + uint8_t eb1, eb2, gb1, gb2; + int32_t i32, i32_; + int cacheupd = 0; + int v0, v1, v2; + int q0, q1, q2; + int d0, d1, d2; + int s0; + uint64_t tmp64u; + int64_t j64; + int64_t fixedaddress; + int unscaled; + MAYUSE(wb1); + MAYUSE(wb2); + MAYUSE(eb1); + MAYUSE(eb2); + MAYUSE(gb1); + MAYUSE(gb2); + MAYUSE(q0); + MAYUSE(q1); + MAYUSE(d0); + MAYUSE(d1); + MAYUSE(s0); + MAYUSE(j64); + MAYUSE(cacheupd); + + rex_t rex = vex.rex; + + if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2)) { + switch(opcode) { + + case 0xF6: + INST_NAME("MULX Gd, Vd, Ed (,RDX)"); + nextop = F8; + GETGD; + GETED32(0); + GETVD; + if(rex.w) { + // 64bits mul + UMULH(x3, xRDX, ed); + MULx(vd, xRDX, ed); + MOVx_REG(gd, x3); + } else { + // 32bits mul + UMULL(x3, xRDX, ed); + MOVw_REG(vd, x3); + LSRx(gd, x3, 32); + } + break; + + default: + DEFAULT; + } + + } + else {DEFAULT;} + + if((*ok==-1) && (box64_dynarec_log>=LOG_INFO || box64_dynarec_dump || box64_dynarec_missing)) { + dynarec_log(LOG_NONE, "Dynarec unimplemented AVX opcode size %d prefix %s map %s opcode %02X ", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode); + } + return addr; +} diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index ce7136ef..96d0c6c7 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1101,6 +1101,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define dynarec64_66 STEPNAME(dynarec64_66) #define dynarec64_67 STEPNAME(dynarec64_67) #define dynarec64_67_32 STEPNAME(dynarec64_67_32) +#define dynarec64_67_AVX STEPNAME(dynarec64_67_AVX) #define dynarec64_6764_32 STEPNAME(dynarec64_6764_32) #define dynarec64_D8 STEPNAME(dynarec64_D8) #define dynarec64_D9 STEPNAME(dynarec64_D9) @@ -1527,6 +1528,7 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uintptr_t dynarec64_66(dynarec_arm_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_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_67_32(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +uintptr_t dynarec64_67_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); uintptr_t dynarec64_6764_32(dynarec_arm_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_D8(dynarec_arm_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_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); diff --git a/src/emu/x64run67.c b/src/emu/x64run67.c index c17db227..f808517d 100644 --- a/src/emu/x64run67.c +++ b/src/emu/x64run67.c @@ -337,6 +337,9 @@ uintptr_t Run67(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) if(rex.is32bits && !(MODREG)) { return 0; } else { + if(rex.is32bits) { + return 0; + } vex_t vex = {0}; vex.rex = rex; tmp8u = nextop; @@ -361,6 +364,9 @@ uintptr_t Run67(x64emu_t *emu, rex_t rex, int rep, uintptr_t addr) if(rex.is32bits && !(MODREG)) { return 0; } else { + if(rex.is32bits) { + return 0; + } vex_t vex = {0}; vex.rex = rex; tmp8u = nextop; |