diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-01-09 22:26:54 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-09 15:26:54 +0100 |
| commit | d787f67ab8d8450b362932aa56044ce6e1452dc0 (patch) | |
| tree | 35df5fe6aca9ee5f1d50bef250e19fc3922e2283 | |
| parent | 16de80f46a20d9e2ab5efbe4eb14c67303079d40 (diff) | |
| download | box64-d787f67ab8d8450b362932aa56044ce6e1452dc0.tar.gz box64-d787f67ab8d8450b362932aa56044ce6e1452dc0.zip | |
[DYNAREC_RV64] Added more opcodes and fixed X87_PUSH/POP macros (#1194)
* [DYNAREC_RV64] Added DB F0..F7 FCOMI opcodes * [DYNAREC_RV64] Added more DA opcodes * Try to fix X87_PUSH_OR_FAIL * [DYNAREC_RV64] Added D7 XLAT opcode * Fix X87_PUSH_OR_FAIL for aarch64 too
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 12 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_da.c | 67 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_db.c | 9 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 12 |
5 files changed, 92 insertions, 16 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index de7a02e3..38b2b4e3 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -768,22 +768,22 @@ #define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \ if (dyn->n.stack == +8) { \ - *ok = 0; \ - break; \ + DEFAULT; \ + return addr; \ } \ var = x87_do_push(dyn, ninst, scratch, t); #define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \ if (dyn->n.stack == +8) { \ - *ok = 0; \ - break; \ + DEFAULT; \ + return addr; \ } \ x87_do_push_empty(dyn, ninst, scratch); #define X87_POP_OR_FAIL(dyn, ninst, scratch) \ if (dyn->n.stack == -8) { \ - *ok = 0; \ - break; \ + DEFAULT; \ + return addr; \ } \ x87_do_pop(dyn, ninst, scratch); diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 6d1296bd..1a468389 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -707,6 +707,14 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } break; + case 0xD7: + INST_NAME("XLAT"); + ANDI(x1, xRAX, 0xff); + ADD(x1, xRBX, x1); + LBU(x1, x1, 0); + ANDI(xRAX, xRAX, ~0xff); + OR(xRAX, xRAX, x1); + break; case 0xD8: addr = dynarec64_D8(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; diff --git a/src/dynarec/rv64/dynarec_rv64_da.c b/src/dynarec/rv64/dynarec_rv64_da.c index 61584090..648a5f91 100644 --- a/src/dynarec/rv64/dynarec_rv64_da.c +++ b/src/dynarec/rv64/dynarec_rv64_da.c @@ -146,17 +146,78 @@ uintptr_t dynarec64_DA(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni default: switch ((nextop >> 3) & 7) { + case 0: + INST_NAME("FIADD ST0, Ed"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LW(x1, ed, fixedaddress); + FCVTDW(v2, x1, RD_RNE); // i32 -> double + FADDD(v1, v1, v2); + break; + case 1: + INST_NAME("FIMUL ST0, Ed"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LW(x1, ed, fixedaddress); + FCVTDW(v2, x1, RD_RNE); // i32 -> double + FMULD(v1, v1, v2); + break; + case 2: + INST_NAME("FICOM ST0, Ed"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LW(x1, ed, fixedaddress); + FCVTDW(v2, x1, RD_RNE); // i32 -> double + FCOMD(v1, v2, x1, x2, x3, x4, x5); + break; + case 3: + INST_NAME("FICOMP ST0, Ed"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LW(x1, ed, fixedaddress); + FCVTDW(v2, x1, RD_RNE); // i32 -> double + FCOMD(v1, v2, x1, x2, x3, x4, x5); + X87_POP_OR_FAIL(dyn, ninst, x3); + break; + case 4: + INST_NAME("FISUB ST0, Ed"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LW(x1, ed, fixedaddress); + FCVTDW(v2, x1, RD_RNE); // i32 -> double + FSUBD(v1, v1, v2); + break; + case 5: + INST_NAME("FISUBR ST0, Ed"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LW(x1, ed, fixedaddress); + FCVTDW(v2, x1, RD_RNE); // i32 -> double + FSUBD(v1, v2, v1); + break; case 6: INST_NAME("FIDIV ST0, Ed"); v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); v2 = fpu_get_scratch(dyn); addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); LW(x1, ed, fixedaddress); - FCVTDW(v2, x1, RD_RNE); + FCVTDW(v2, x1, RD_RNE); // i32 -> double FDIVD(v1, v1, v2); break; - default: - DEFAULT; + case 7: + INST_NAME("FIDIVR ST0, Ed"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + v2 = fpu_get_scratch(dyn); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LW(x1, ed, fixedaddress); + FCVTDW(v2, x1, RD_RNE); // i32 -> double + FDIVD(v1, v2, v1); break; } } diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c index d60fcfbd..71d77451 100644 --- a/src/dynarec/rv64/dynarec_rv64_db.c +++ b/src/dynarec/rv64/dynarec_rv64_db.c @@ -198,7 +198,14 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xF6: case 0xF7: INST_NAME("FCOMI ST0, STx"); - DEFAULT; + SETFLAGS(X_ALL, SF_SET); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop & 7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop & 7, X87_COMBINE(0, nextop & 7)); + if (ST_IS_F(0)) { + FCOMS(v1, v2, x1, x2, x3, x4, x5); + } else { + FCOMS(v1, v2, x1, x2, x3, x4, x5); + } break; case 0xE0: diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index e521e135..1e0bed93 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -884,22 +884,22 @@ #define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \ if (dyn->e.stack == +8) { \ - *ok = 0; \ - break; \ + DEFAULT; \ + return addr; \ } \ var = x87_do_push(dyn, ninst, scratch, t); #define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \ if (dyn->e.stack == +8) { \ - *ok = 0; \ - break; \ + DEFAULT; \ + return addr; \ } \ x87_do_push_empty(dyn, ninst, scratch); #define X87_POP_OR_FAIL(dyn, ninst, scratch) \ if (dyn->e.stack == -8) { \ - *ok = 0; \ - break; \ + DEFAULT; \ + return addr; \ } \ x87_do_pop(dyn, ninst, scratch); |