diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-31 11:17:21 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-31 11:17:21 +0200 |
| commit | d53c9c1e87714d3e68e99790b6787c4d7e10713a (patch) | |
| tree | 5bf978980d25eed0fcb993a14518cbb0f9a1532f /src | |
| parent | 424a08607cdb4bb03e1ba2c443adae55db72243c (diff) | |
| download | box64-d53c9c1e87714d3e68e99790b6787c4d7e10713a.tar.gz box64-d53c9c1e87714d3e68e99790b6787c4d7e10713a.zip | |
[DYNAREC] Added F2 0F 70 opcode
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 1 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f20f.c | 26 |
2 files changed, 27 insertions, 0 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 0446bde6..fc4784ce 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -1117,6 +1117,7 @@ #define TBL_gen(Q, Rm, len, op, Rn, Rd) ((Q)<<30 | 0b001110<<24 | (Rm)<<16 | (len)<<13 | (op)<<12 | (Rn)<<5 | (Rd)) //Use Rm[] to pick from Rn element and store in Rd. Out-of-range element gets 0 #define VTBLQ1_8(Rd, Rn, Rm) EMIT(TBL_gen(1, Rm, 0b00, 0, Rn, Rd)) +#define VTBL1_8(Rd, Rn, Rm) EMIT(TBL_gen(0, Rm, 0b00, 0, Rn, Rd)) //Use Rm[] to pick from Rn, Rn+1 element and store in Rd. Out-of-range element gets 0 #define VTBLQ2_8(Rd, Rn, Rm) EMIT(TBL_gen(1, Rm, 0b01, 0, Rn, Rd)) //Use Rm[] to pick from Rn, Rn+1, Rn+2 element and store in Rd. Out-of-range element gets 0 diff --git a/src/dynarec/dynarec_arm64_f20f.c b/src/dynarec/dynarec_arm64_f20f.c index 8fe7cc3a..ceb212ae 100755 --- a/src/dynarec/dynarec_arm64_f20f.c +++ b/src/dynarec/dynarec_arm64_f20f.c @@ -37,6 +37,9 @@ #define GETGX(a) gd = ((nextop&0x38)>>3)+(rex.r<<3); \ a = sse_get_reg(dyn, ninst, x1, gd) +#define GETGX_empty(a) gd = ((nextop&0x38)>>3)+(rex.r<<3); \ + a = sse_get_reg_empty(dyn, ninst, x1, gd) + uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { uint8_t opcode = F8; @@ -44,6 +47,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n uint8_t gd, ed; uint8_t wback; uint8_t u8; + uint64_t u64; int v0, v1; int q0; int d0, d1; @@ -233,6 +237,28 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n VMOVeD(v0, 0, d0, 0); // to not erase uper part break; + case 0x70: + INST_NAME("PSHUFLW Gx, Ex, Ib"); + nextop = F8; + GETEX(v1, 1); + GETGX_empty(v0); + + u8 = F8; + // only low part need to be suffled. VTBL only handle 8bits value, so the 16bits suffles need to be changed in 8bits + u64 = 0; + for (int i=0; i<4; ++i) { + u64 |= ((uint64_t)((u8>>(i*2))&3)*2+0)<<(i*16+0); + u64 |= ((uint64_t)((u8>>(i*2))&3)*2+1)<<(i*16+8); + } + MOV64x(x2, u64); + d0 = fpu_get_scratch(dyn); + VMOVQDfrom(d0, 0, x2); + VTBL1_8(v0, v1, d0); + if(v0!=v1) { + VMOVeD(v0, 1, v1, 1); + } + break; + case 0x7C: INST_NAME("HADDPS Gx, Ex"); nextop = F8; |