diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-05-30 18:13:01 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-05-30 18:13:01 +0200 |
| commit | 60b625bc0fe12933c34f889d75eb9b48d5c4f76e (patch) | |
| tree | 9402a1f815fc83d24d1dcce821ee6408e0261978 /src/dynarec | |
| parent | d1703b9bc044152a15e74bf1650a2d63dd0fd153 (diff) | |
| download | box64-60b625bc0fe12933c34f889d75eb9b48d5c4f76e.tar.gz box64-60b625bc0fe12933c34f889d75eb9b48d5c4f76e.zip | |
[ARM64_DYNAREC] Added AVX.66.F3A 19 opcodes and some various avx helper fixes
Diffstat (limited to 'src/dynarec')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c | 15 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.c | 9 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 16 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_pass.c | 1 |
4 files changed, 36 insertions, 5 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c index 69dba468..6a90792f 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c @@ -127,6 +127,21 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip if(v0!=v2) VMOVQ((u8&1)?v0:q0, (u8&1)?v2:q2); break; + case 0x19: + INST_NAME("VEXTRACTF128 Ex, Gx, imm8"); + nextop = F8; + u8 = geted_ib(dyn, addr, ninst, nextop); + if(u8&1) {GETG; GETGY(v0, 0, -1, -1, -1);} else {GETGX(v0, 0);} + if(MODREG) { + v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7)+(rex.b<<3)); + VMOVQ(v1, v0); + YMM0((nextop&7)+(rex.b<<3)); + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1); + VST128(v0, ed, fixedaddress); + } + F8; // read u8, but it's been already handled + break; default: DEFAULT; diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index cdf0eeb6..2d08510e 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -1789,6 +1789,15 @@ int ymm_get_reg_empty(dynarec_arm_t* dyn, int ninst, int s1, int a, int k1, int return ret; } +void ymm_mark_zero(dynarec_arm_t* dyn, int ninst, int a) +{ + // look if already exist + for(int i=0; i<32; ++i) + if((dyn->n.neoncache[i].t==NEON_CACHE_YMMR || dyn->n.neoncache[i].t==NEON_CACHE_YMMW) && dyn->n.neoncache[i].n==a) { + dyn->n.neoncache[i].v = 0; // forget it! + } + avx_mark_zero(dyn, ninst, a); +} void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07) { diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index b9f4f01a..6349054b 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -465,6 +465,9 @@ #define GETGY_empty(a, k1, k2, k3) \ a = ymm_get_reg_empty(dyn, ninst, x1, gd, k1, k2, k3) +#define GETGY(a, w, k1, k2, k3) \ + a = ymm_get_reg(dyn, ninst, x1, gd, w, k1, k2, k3) + #define GETGY_empty_VY(a, b, w2, k1, k2) \ b = ymm_get_reg(dyn, ninst, x1, vex.v, w2, gd, k1, k2); \ a = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, k1, k2) @@ -584,7 +587,7 @@ SMWRITE2(); \ } -#define YMM0(a) avx_mark_zero(dyn, ninst, gd); +#define YMM0(a) ymm_mark_zero(dyn, ninst, a); // Get Direction with size Z and based of F_DF flag, on register r ready for LDR/STR fetching // F_DF is 1<<10, so 1 ROR 11*2 (so F_OF) @@ -1209,11 +1212,12 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define mmx_get_reg_empty STEPNAME(mmx_get_reg_empty) #define sse_get_reg STEPNAME(sse_get_reg) #define sse_get_reg_empty STEPNAME(sse_get_reg_empty) -#define sse_forget_reg STEPNAME(sse_forget_reg) -#define sse_purge07cache STEPNAME(sse_purge07cache) -#define sse_reflect_reg STEPNAME(sse_reflect_reg) -#define ymm_get_reg STEPNAME(ymm_get_reg) +#define sse_forget_reg STEPNAME(sse_forget_reg) +#define sse_purge07cache STEPNAME(sse_purge07cache) +#define sse_reflect_reg STEPNAME(sse_reflect_reg) +#define ymm_get_reg STEPNAME(ymm_get_reg) #define ymm_get_reg_empty STEPNAME(ymm_get_reg_empty) +#define ymm_mark_zero STEPNAME(ymm_mark_zero) #define fpu_pushcache STEPNAME(fpu_pushcache) #define fpu_popcache STEPNAME(fpu_popcache) @@ -1465,6 +1469,8 @@ void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07); int ymm_get_reg(dynarec_arm_t* dyn, int ninst, int s1, int a, int forwrite, int k1, int k2, int k3); // get neon register for a SSE reg, but don't try to synch it if it needed to be created int ymm_get_reg_empty(dynarec_arm_t* dyn, int ninst, int s1, int a, int k1, int k2, int k3); +// mark an ymm upper part has zero (forgetting upper part if needed) +void ymm_mark_zero(dynarec_arm_t* dyn, int ninst, int a); uintptr_t dynarec64_00(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/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c index 60c37b4b..c748b47d 100644 --- a/src/dynarec/dynarec_native_pass.c +++ b/src/dynarec/dynarec_native_pass.c @@ -49,6 +49,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int dyn->forward_to = 0; dyn->forward_size = 0; dyn->forward_ninst = 0; + dyn->ymm_zero = 0; #if STEP == 0 memset(&dyn->insts[ninst], 0, sizeof(instruction_native_t)); #endif |