diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-07-05 00:47:45 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-04 18:47:45 +0200 |
| commit | 2c0bbc06b7b05c2f5f06ef3ccc7d2e4cfb9117f1 (patch) | |
| tree | 569e96cef7c1e16f6b5f19a790ee6f2ce721026a /src | |
| parent | 299551428f2f68a720e0148f0176840f55976dc4 (diff) | |
| download | box64-2c0bbc06b7b05c2f5f06ef3ccc7d2e4cfb9117f1.tar.gz box64-2c0bbc06b7b05c2f5f06ef3ccc7d2e4cfb9117f1.zip | |
[DYNAREC] Fixed IMUL sign extension issue (#1639)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 6 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 4 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_printer.c | 14 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_1.c | 6 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 30 |
5 files changed, 26 insertions, 34 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index a7207003..ba441913 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -529,7 +529,8 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { // 32bits imul UFLAG_IF { - MUL_D(gd, ed, x4); + SLLI_W(x3, ed, 0); + MUL_D(gd, x3, x4); UFLAG_RES(gd); SRLI_D(x3, gd, 32); UFLAG_OP1(x3); @@ -568,7 +569,8 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { // 32bits imul UFLAG_IF { - MUL_D(gd, ed, x4); + SLLI_W(x3, ed, 0); + MUL_D(gd, x3, x4); UFLAG_RES(gd); SRLI_D(x3, gd, 32); UFLAG_OP1(x3); diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 0c40f766..2bdc22a1 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -784,7 +784,9 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if (la64_lbt) { X64_MUL_W(gd, ed); } - MUL_D(gd, gd, ed); + SLLI_W(gd, gd, 0); + SLLI_W(x3, ed, 0); + MUL_D(gd, gd, x3); SRLI_D(x3, gd, 32); SLLI_W(gd, gd, 0); IFX (X_PEND) { diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c index 5c58541c..aae90869 100644 --- a/src/dynarec/la64/la64_printer.c +++ b/src/dynarec/la64/la64_printer.c @@ -2237,31 +2237,31 @@ const char* la64_print(uint32_t opcode, uintptr_t addr) return buff; } if (isMask(opcode, "00000000001111101kkkkkjjjjj00001", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]); + snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.H", Xt[Rj], Xt[Rk]); return buff; } if (isMask(opcode, "00000000001111101kkkkkjjjjj00010", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]); + snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.W", Xt[Rj], Xt[Rk]); return buff; } if (isMask(opcode, "00000000001111101kkkkkjjjjj00011", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]); + snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.D", Xt[Rj], Xt[Rk]); return buff; } if (isMask(opcode, "00000000001111101kkkkkjjjjj00100", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]); + snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.BU", Xt[Rj], Xt[Rk]); return buff; } if (isMask(opcode, "00000000001111101kkkkkjjjjj00101", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]); + snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.HU", Xt[Rj], Xt[Rk]); return buff; } if (isMask(opcode, "00000000001111101kkkkkjjjjj00110", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]); + snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.WU", Xt[Rj], Xt[Rk]); return buff; } if (isMask(opcode, "00000000001111101kkkkkjjjjj00111", &a)) { - snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.B", Xt[Rj], Xt[Rk]); + snprintf(buff, sizeof(buff), "%-15s %s, %s", "X64MUL.DU", Xt[Rj], Xt[Rk]); return buff; } if (isMask(opcode, "00000000001111110kkkkkjjjjj00000", &a)) { diff --git a/src/dynarec/rv64/dynarec_rv64_00_1.c b/src/dynarec/rv64/dynarec_rv64_00_1.c index 08c39829..a361af5f 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_1.c +++ b/src/dynarec/rv64/dynarec_rv64_00_1.c @@ -212,7 +212,8 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } else { // 32bits imul UFLAG_IF { - MUL(gd, ed, x4); + SEXT_W(x3, ed); + MUL(gd, x3, x4); UFLAG_RES(gd); SRLI(x3, gd, 32); UFLAG_OP1(x3); @@ -251,7 +252,8 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } else { // 32bits imul UFLAG_IF { - MUL(gd, ed, x4); + SEXT_W(x3, ed); + MUL(gd, x3, x4); UFLAG_RES(gd); SRLI(x3, gd, 32); UFLAG_OP1(x3); diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 26e64d3d..f7565a7e 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -1894,43 +1894,29 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETED(0); if (rex.w) { // 64bits imul - UFLAG_IF - { + UFLAG_IF { MULH(x3, gd, ed); MUL(gd, gd, ed); UFLAG_OP1(x3); UFLAG_RES(gd); UFLAG_DF(x3, d_imul64); - } - else - { + } else { MULxw(gd, gd, ed); } } else { // 32bits imul - UFLAG_IF - { - SLLI(gd, gd, 32); - SRAI(gd, gd, 32); - if(MODREG) { - SLLI(x1, ed, 32); - ed = x1; - } else { - SLLI(ed, ed, 32); - } - SRAI(ed, ed, 32); - MUL(gd, gd, ed); + UFLAG_IF { + SEXT_W(gd, gd); + SEXT_W(x3, ed); + MUL(gd, gd, x3); UFLAG_RES(gd); SRLI(x3, gd, 32); UFLAG_OP1(x3); UFLAG_DF(x3, d_imul32); - } - else - { + } else { MULxw(gd, gd, ed); } - SLLI(gd, gd, 32); - SRLI(gd, gd, 32); + ZEROUP(gd); } break; case 0xB3: |