diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-05-23 09:09:04 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-05-23 09:09:04 +0200 |
| commit | 537ca9f724696fe0fb61c12cbb9a2c46aa029884 (patch) | |
| tree | e2ef437dd03e968a3215885252971bac6f6d3d0a /src | |
| parent | fc5f5dab29c614a15a9cd96715ad70145f02eed5 (diff) | |
| download | box64-537ca9f724696fe0fb61c12cbb9a2c46aa029884.tar.gz box64-537ca9f724696fe0fb61c12cbb9a2c46aa029884.zip | |
Added 64 F3 0F 10 opcode ([DYNAREC] too)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/dynarec_arm64_64.c | 54 | ||||
| -rw-r--r-- | src/emu/x64run64.c | 26 |
2 files changed, 80 insertions, 0 deletions
diff --git a/src/dynarec/dynarec_arm64_64.c b/src/dynarec/dynarec_arm64_64.c index 077411ce..a8a7c6e6 100644 --- a/src/dynarec/dynarec_arm64_64.c +++ b/src/dynarec/dynarec_arm64_64.c @@ -22,6 +22,7 @@ #include "dynarec_arm64_helper.h" #include "dynarec_arm64_functions.h" +#define GETG gd = ((nextop&0x38)>>3)+(rex.r<<3) uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { @@ -33,12 +34,18 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uint8_t gd, ed, eb1, eb2; uint8_t wback, wb1, wb2; int64_t i64, j64; + int v0; + int q0; + int d0; int64_t fixedaddress; MAYUSE(eb1); MAYUSE(eb2); MAYUSE(wb1); MAYUSE(wb2); MAYUSE(j64); + MAYUSE(d0); + MAYUSE(q0); + MAYUSE(v0); while((opcode==0xF2) || (opcode==0xF3)) { rep = opcode-0xF1; @@ -63,6 +70,53 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin emit_add32(dyn, ninst, rex, gd, ed, x3, x4); break; + case 0x0F: + opcode = F8; + switch(opcode) { + case 0x10: + switch(rep) { + case 1: + INST_NAME("MOVSD Gx, Ex"); + nextop = F8; + GETG; + if(MODREG) { + ed = (nextop&7)+ (rex.b<<3); + v0 = sse_get_reg(dyn, ninst, x1, gd); + d0 = sse_get_reg(dyn, ninst, x1, ed); + VMOVeD(v0, 0, d0, 0); + } else { + grab_segdata(dyn, addr, ninst, x4, _FS); + v0 = sse_get_reg_empty(dyn, ninst, x1, gd); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0); + ADDx_REG(x4, x4, ed); + VLDR64_U12(v0, x4, fixedaddress); // upper part reseted + } + break; + case 2: + INST_NAME("MOVSS Gx, Ex"); + nextop = F8; + GETG; + if(MODREG) { + v0 = sse_get_reg(dyn, ninst, x1, gd); + q0 = sse_get_reg(dyn, ninst, x1, (nextop&7) + (rex.b<<3)); + VMOVeS(v0, 0, q0, 0); + } else { + grab_segdata(dyn, addr, ninst, x4, _FS); + v0 = sse_get_reg_empty(dyn, ninst, x1, gd); + addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<2, 3, rex, 0, 0); + ADDx_REG(x4, x4, ed); + VLDR32_U12(v0, x4, fixedaddress); + } + break; + default: + DEFAULT; + } + break; + default: + DEFAULT; + } + break; + case 0x33: INST_NAME("XOR Gd, FS:Ed"); SETFLAGS(X_ALL, SF_SET); diff --git a/src/emu/x64run64.c b/src/emu/x64run64.c index 3b6bb4f2..1708bb79 100644 --- a/src/emu/x64run64.c +++ b/src/emu/x64run64.c @@ -108,6 +108,32 @@ int Run64(x64emu_t *emu, rex_t rex) opcode = F8; switch(opcode) { + case 0x10: + switch(rep) { + case 1: /* MOVSD Gx, FS:Ex */ + nextop = F8; + GETEX_OFFS(0, tlsdata); + GETGX; + GX->q[0] = EX->q[0]; + if((nextop&0xC0)!=0xC0) { + // EX is not a register + GX->q[1] = 0; + } + break; + case 2: /* MOVSS Gx, FS:Ex */ + nextop = F8; + GETEX_OFFS(0, tlsdata); + GETGX; + GX->ud[0] = EX->ud[0]; + if((nextop&0xC0)!=0xC0) { + // EX is not a register (reg to reg only move 31:0) + GX->ud[1] = GX->ud[2] = GX->ud[3] = 0; + } + break; + default: + return 1; + } + break; case 0x11: switch(rep) { case 1: /* MOVSD Ex, Gx */ |