diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-02-21 16:03:19 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-21 09:03:19 +0100 |
| commit | cb42b3b00f3d999a10d44a0b48d806128ccf5cfa (patch) | |
| tree | de7c93e160fd813450d8abee29696c8e689d39a8 /src | |
| parent | 61362b06ecea0af9164f1a70992ad610633531a0 (diff) | |
| download | box64-cb42b3b00f3d999a10d44a0b48d806128ccf5cfa.tar.gz box64-cb42b3b00f3d999a10d44a0b48d806128ccf5cfa.zip | |
[RV64_DYNAREC] Added more MMX opcodes for vector and fixes too (#2399)
* [RV64_DYNAREC] Fixed fallback to scalar messge * [RV64_DYNAREC] Added more MMX opcodes for vector and fixes too
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f_vector.c | 114 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass3.h | 28 |
2 files changed, 124 insertions, 18 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c index 40a5d8df..ddcf0b80 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c @@ -289,6 +289,9 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, SMWRITE2(); } break; + case 0x2E: + case 0x2F: + return 0; case 0x50: INST_NAME("MOVMSKPS Gd, Ex"); nextop = F8; @@ -683,13 +686,105 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, VMV_S_X(v0, x4); } break; + case 0x71: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("PSRLW Em, Ib"); + SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1); + GETEM_vector(q0, 1); + u8 = F8; + if (u8 > 15) { + VXOR_VV(q0, q0, q0, VECTOR_UNMASKED); + PUTEM_vector(q0); + } else if (u8) { + MOV64x(x4, u8); + VSRL_VX(q0, q0, x4, VECTOR_UNMASKED); + PUTEM_vector(q0); + } + break; + case 4: + INST_NAME("PSRAW Em, Ib"); + SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1); + GETEM_vector(q0, 1); + u8 = F8; + if (u8 > 15) u8 = 15; + if (u8) { + MOV64x(x4, u8); + VSRA_VX(q0, q0, x4, VECTOR_UNMASKED); + PUTEM_vector(q0); + } + break; + case 6: + INST_NAME("PSLLW Em, Ib"); + SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1); + GETEM_vector(q0, 1); + u8 = F8; + if (u8 > 15) { + VXOR_VV(q0, q0, q0, VECTOR_UNMASKED); + PUTEM_vector(q0); + } else if (u8) { + MOV64x(x4, u8); + VSLL_VX(q0, q0, x4, VECTOR_UNMASKED); + PUTEM_vector(q0); + } + break; + default: DEFAULT_VECTOR; + } + break; + case 0x72: + nextop = F8; + switch ((nextop >> 3) & 7) { + case 2: + INST_NAME("PSRLD Em, Ib"); + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETEM_vector(q0, 1); + u8 = F8; + if (u8 > 31) { + VXOR_VV(q0, q0, q0, VECTOR_UNMASKED); + PUTEM_vector(q0); + } else if (u8) { + MOV64x(x4, u8); + VSRL_VX(q0, q0, x4, VECTOR_UNMASKED); + PUTEM_vector(q0); + } + break; + case 4: + INST_NAME("PSRAD Em, Ib"); + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETEM_vector(q0, 1); + u8 = F8; + if (u8 > 31) u8 = 31; + if (u8) { + MOV64x(x4, u8); + VSRA_VX(q0, q0, x4, VECTOR_UNMASKED); + } + PUTEM_vector(q0); + break; + case 6: + INST_NAME("PSLLD Em, Ib"); + SET_ELEMENT_WIDTH(x1, VECTOR_SEW32, 1); + GETEM_vector(q0, 1); + u8 = F8; + if (u8 > 31) { + VXOR_VV(q0, q0, q0, VECTOR_UNMASKED); + PUTEM_vector(q0); + } else if (u8) { + MOV64x(x4, u8); + VSLL_VX(q0, q0, x4, VECTOR_UNMASKED); + PUTEM_vector(q0); + } + break; + default: DEFAULT_VECTOR; + } + break; case 0x73: nextop = F8; switch ((nextop >> 3) & 7) { case 2: INST_NAME("PSRLQ Em, Ib"); SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); - GETEM_vector(q0, 0); + GETEM_vector(q0, 1); u8 = F8; if (u8) { if (u8 > 63) { @@ -704,7 +799,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, case 6: INST_NAME("PSLLQ Em, Ib"); SET_ELEMENT_WIDTH(x1, VECTOR_SEW64, 1); - GETEM_vector(q0, 0); + GETEM_vector(q0, 1); u8 = F8; if (u8) { if (u8 > 63) { @@ -861,7 +956,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, VMV_X_S(x4, v1); } else { SMREAD(); - addr = geted(dyn, addr, ninst, nextop, &wback, v1, x3, &fixedaddress, rex, NULL, 1, 0); + addr = geted(dyn, addr, ninst, nextop, &wback, x1, x3, &fixedaddress, rex, NULL, 1, 0); LD(x4, wback, fixedaddress); } SET_ELEMENT_WIDTH(x1, u8, 1); @@ -961,6 +1056,17 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, SET_ELEMENT_WIDTH(x1, VECTOR_SEW16, 1); VMULH_VV(v0, v0, v1, VECTOR_UNMASKED); break; + case 0xE7: + INST_NAME("MOVNTQ Em, Gm"); + nextop = F8; + if (MODREG) { + DEFAULT; + } else { + GETGM_vector(v0); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, x3, &fixedaddress, rex, NULL, 1, 0); + PUTEM_vector(v0); + } + break; case 0xE8: INST_NAME("PSUBSB Gm, Em"); nextop = F8; @@ -1046,7 +1152,7 @@ uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, VMV_X_S(x4, v1); } else { SMREAD(); - addr = geted(dyn, addr, ninst, nextop, &wback, v1, x3, &fixedaddress, rex, NULL, 1, 0); + addr = geted(dyn, addr, ninst, nextop, &wback, x1, x3, &fixedaddress, rex, NULL, 1, 0); LD(x4, wback, fixedaddress); } SET_ELEMENT_WIDTH(x1, u8, 1); diff --git a/src/dynarec/rv64/dynarec_rv64_pass3.h b/src/dynarec/rv64/dynarec_rv64_pass3.h index 4b92fd79..1fec3dcb 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass3.h +++ b/src/dynarec/rv64/dynarec_rv64_pass3.h @@ -43,18 +43,18 @@ FLD(A, x1, SPLIT12(val64offset)); \ } -#define DEFAULT_VECTOR \ - if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing) == 2) { \ - dynarec_log(LOG_NONE, "%p: Dynarec stopped because of %s Opcode ", (void*)ip, rex.is32bits ? "x86" : "x64"); \ - zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec; \ - if (dec) { \ - dynarec_log_prefix(0, LOG_NONE, "%s", DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 1)); \ - } else { \ - dynarec_log_prefix(0, LOG_NONE, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", \ - PKip(0), PKip(1), PKip(2), PKip(3), PKip(4), PKip(5), PKip(6), PKip(7), PKip(8), PKip(9), \ - PKip(10), PKip(11), PKip(12), PKip(13), PKip(14)); \ - } \ - printFunctionAddr(ip, " => "); \ - dynarec_log_prefix(0, LOG_NONE, "\n"); \ - } \ +#define DEFAULT_VECTOR \ + if (BOX64ENV(dynarec_log) >= LOG_INFO || BOX64DRENV(dynarec_dump) || BOX64ENV(dynarec_missing) == 2) { \ + dynarec_log(LOG_NONE, "%p: Dynarec fallback to scalar version because of %s Opcode ", (void*)ip, rex.is32bits ? "x86" : "x64"); \ + zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec; \ + if (dec) { \ + dynarec_log_prefix(0, LOG_NONE, "%s", DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 1)); \ + } else { \ + dynarec_log_prefix(0, LOG_NONE, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", \ + PKip(0), PKip(1), PKip(2), PKip(3), PKip(4), PKip(5), PKip(6), PKip(7), PKip(8), PKip(9), \ + PKip(10), PKip(11), PKip(12), PKip(13), PKip(14)); \ + } \ + printFunctionAddr(ip, " => "); \ + dynarec_log_prefix(0, LOG_NONE, "\n"); \ + } \ return 0 |