diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-25 10:21:46 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-25 10:21:46 +0000 |
| commit | 206bc9afb659eeb4e8393170e0dc8bcb87792c3c (patch) | |
| tree | a501c0467d326360d0e6108a715ff3b7f46967e9 /src | |
| parent | ffcfa5b2cbdae6087d1c6bf790b5e2165d9ab580 (diff) | |
| download | box64-206bc9afb659eeb4e8393170e0dc8bcb87792c3c.tar.gz box64-206bc9afb659eeb4e8393170e0dc8bcb87792c3c.zip | |
[RV64_DYNAREC] Added 66 0F EF PXOR opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 23 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 19 |
3 files changed, 43 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index aabaa019..03e44fc8 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -122,6 +122,29 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int OR(gd, gd, x1); break; + case 0xEF: + INST_NAME("PXOR Gx, Ex"); + nextop = F8; + GETGX(x1); + GETEX(x2, 0); + if(gd==ed) { + // just zero dest + SD(xZR, x1, 0); + SD(xZR, x1, 8); + } else { + //1st + LD(x3, x1, 0); + LD(x4, x2, 0); + XOR(x3, x3, x4); + SD(x3, x1, 0); + // 2nd + LD(x3, x1, 8); + LD(x4, x2, 8); + XOR(x3, x3, x4); + SD(x3, x1, 8); + } + break; + default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index fe7d0804..6a45f9bb 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -1116,7 +1116,7 @@ int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single) dyn->e.ssecache[a].single = single; return dyn->e.ssecache[a].reg; } -// forget ext register for a SSE reg, create the entry if needed +// forget ext register for a SSE reg, does nothing if the regs is not loaded void sse_forget_reg(dynarec_rv64_t* dyn, int ninst, int a) { if(dyn->e.ssecache[a].v==-1) diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 4a6147ac..32e509b4 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -292,6 +292,25 @@ FLW(a, ed, fixedaddress); \ } +// Will get pointer to GX in general register a, will purge SS or SD if loaded +#define GETGX(a) \ + gd = ((nextop&0x38)>>3)+(rex.r<<3); \ + sse_forget_reg(dyn, ninst, gd); \ + ADDI(a, xEmu, offsetof(x64emu_t, xmm[gd])) + +// Get Ex address in regenal register a, will purge SS or SD or it's reg and is loaded. May use x3 +#define GETEX(a, D) \ + if(MODREG) { \ + ed = (nextop&7)+(rex.b<<3); \ + sse_forget_reg(dyn, ninst, ed); \ + fixedaddress = 0; \ + ADDI(a, xEmu, offsetof(x64emu_t, xmm[ed])); \ + } else { \ + SMREAD(); \ + ed=16; \ + addr = geted(dyn, addr, ninst, nextop, &wback, a, x3, &fixedaddress, rex, NULL, 1, D); \ + } + // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1) // R0 will not be pushed/popd if ret is -2 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0) |