diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-04-10 20:10:58 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-10 14:10:58 +0200 |
| commit | 9b3511cc88ea3c03590ccd9158095086de53c9ed (patch) | |
| tree | 5fd07d08586578d5c31c6e07cd01211471b45373 /src | |
| parent | 48f80ebc930e66968e36e75425dae44490040a97 (diff) | |
| download | box64-9b3511cc88ea3c03590ccd9158095086de53c9ed.tar.gz box64-9b3511cc88ea3c03590ccd9158095086de53c9ed.zip | |
[RV64_DYNAREC] Added more opcode for SV and some fixes (#683)
* [RV64_DYNAREC] Added 66 0F 67 PACKUSWB opcode * [RV64_DYNAREC] Added 66 0F 6B PACKSSDW opcode * [INTERP] Fixed typos * [RV64_DYNAREC] Fixed 0F BA /7 BTC opcode * [RV64_DYNAREC] Added 0F BB BTC opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 40 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 65 | ||||
| -rw-r--r-- | src/emu/x64run0f.c | 14 |
3 files changed, 112 insertions, 7 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index a1ef5734..b2bf4df4 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -538,11 +538,51 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni MOV64xw(x3, (1LL << u8)); XOR(ed, ed, x3); } + if(wback) { + SDxw(ed, wback, fixedaddress); + SMWRITE(); + } break; default: DEFAULT; } break; + case 0xBB: + INST_NAME("BTC Ed, Gd"); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(); + nextop = F8; + GETGD; + if (MODREG) { + ed = xRAX+(nextop&7)+(rex.b<<3); + wback = 0; + } else { + SMREAD(); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); + SRAI(x1, gd, 5+rex.w); + SLLI(x1, x1, 2+rex.w); + ADD(x3, wback, x1); + LDxw(x1, x3, fixedaddress); + ed = x1; + wback = x3; + } + if (rex.w) { + ANDI(x2, gd, 0x3f); + } else { + ANDI(x2, gd, 0x1f); + } + SRL(x4, ed, x2); + ANDI(x4, x4, 1); // F_CF is 1 + ANDI(xFlags, xFlags, ~1); + OR(xFlags, xFlags, x4); + ADDI(x3, xZR, 1); + SLL(x3, x3, x2); + XOR(ed, ed, x3); + if(wback) { + SDxw(ed, wback, fixedaddress); + SMWRITE(); + } + break; case 0xBE: INST_NAME("MOVSX Gd, Eb"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 9c32068f..a2212e9a 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -244,6 +244,39 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGX(x2); SSE_LOOP_DS(x3, x4, SLT(x4, x4, x3); SLLI(x3, x4, 63); SRAI(x3, x3, 63)); break; + case 0x67: + INST_NAME("PACKUSWB Gx, Ex"); + nextop = F8; + GETEX(x1, 0); + GETGX(x2); + ADDI(x5, xZR, 0xFF); + for(int i=0; i<8; ++i) { + // GX->ub[i] = (GX->sw[i]<0)?0:((GX->sw[i]>0xff)?0xff:GX->sw[i]); + LH(x3, gback, i*2); + BGE(x5, x3, 8); + ADDI(x3, xZR, 0xFF); + NOT(x4, x3); + SRAI(x4, x4, 63); + AND(x3, x3, x4); + SB(x3, gback, i); + } + if (MODREG && (ed==gd)) { + // GX->q[1] = GX->q[0]; + LD(x3, gback, 0*8); + SD(x3, gback, 1*8); + } else { + for(int i=0; i<8; ++i) { + // GX->ub[8+i] = (EX->sw[i]<0)?0:((EX->sw[i]>0xff)?0xff:EX->sw[i]); + LH(x3, wback, fixedaddress+i*2); + BGE(x5, x3, 8); + ADDI(x3, xZR, 0xFF); + NOT(x4, x3); + SRAI(x4, x4, 63); + AND(x3, x3, x4); + SB(x3, gback, 8+i); + } + } + break; case 0x69: INST_NAME("PUNPCKHWD Gx,Ex"); nextop = F8; @@ -288,6 +321,38 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SW(x3, gback, 3*4); } break; + case 0x6B: + INST_NAME("PACKSSDW Gx,Ex"); + nextop = F8; + GETEX(x1, 0); + GETGX(x2); + MOV64x(x5, 32768); + NEG(x6, x5); + for(int i=0; i<4; ++i) { + // GX->sw[i] = (GX->sd[i]<-32768)?-32768:((GX->sd[i]>32767)?32767:GX->sd[i]); + LW(x3, gback, i*4); + BGE(x5, x3, 8); + ADDI(x3, x5, -1); + BGE(x3, x6, 8); + MV(x3, x6); + SH(x3, gback, i*2); + } + if (MODREG && (ed==gd)) { + // GX->q[1] = GX->q[0]; + LD(x3, gback, 0*8); + SD(x3, gback, 1*8); + } else { + for(int i=0; i<4; ++i) { + // GX->sw[4+i] = (EX->sd[i]<-32768)?-32768:((EX->sd[i]>32767)?32767:EX->sd[i]); + LW(x3, wback, fixedaddress+i*4); + BGE(x5, x3, 8); + ADDI(x3, x5, -1); + BGE(x3, x6, 8); + MV(x3, x6); + SH(x3, gback, (4+i)*2); + } + } + break; case 0x6C: INST_NAME("PUNPCKLQDQ Gx,Ex"); nextop = F8; diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c index 8cd5b312..5f46db5d 100644 --- a/src/emu/x64run0f.c +++ b/src/emu/x64run0f.c @@ -876,13 +876,13 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) if(!MODREG) { #ifdef TEST_INTERPRETER - test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); + test->memaddr=((test->memaddr)+(tmp64s<<(rex.w?3:2))); if(rex.w) *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; else *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; #else - ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2))); + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); #endif } if(rex.w) { @@ -1022,13 +1022,13 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) if(!MODREG) { #ifdef TEST_INTERPRETER - test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); + test->memaddr=((test->memaddr)+(tmp64s<<(rex.w?3:2))); if(rex.w) *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; else *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; #else - ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2))); + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); #endif } if(rex.w) { @@ -1160,13 +1160,13 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) if(!MODREG) { #ifdef TEST_INTERPRETER - test->memaddr=((test->memaddr)+(tmp32s<<(rex.w?3:2))); + test->memaddr=((test->memaddr)+(tmp64s<<(rex.w?3:2))); if(rex.w) *(uint64_t*)test->mem = *(uint64_t*)test->memaddr; else *(uint32_t*)test->mem = *(uint32_t*)test->memaddr; #else - ED=(reg64_t*)(((uintptr_t)(ED))+(tmp32s<<(rex.w?3:2))); + ED=(reg64_t*)(((uintptr_t)(ED))+(tmp64s<<(rex.w?3:2))); #endif } if(rex.w) { @@ -1729,4 +1729,4 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step) return 0; } return addr; -} \ No newline at end of file +} |