diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-02-13 20:51:16 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-13 13:51:16 +0100 |
| commit | 2b75a0de556dc67dc0ed3c91fa90b5ffd4d40507 (patch) | |
| tree | 17b4535263f463725f58d64d80b976504b1157e3 /src | |
| parent | 59e1da5f74c0bd72374ff97f2a222d4c220012fb (diff) | |
| download | box64-2b75a0de556dc67dc0ed3c91fa90b5ffd4d40507.tar.gz box64-2b75a0de556dc67dc0ed3c91fa90b5ffd4d40507.zip | |
[RV64_DYNAREC] Minor fixes and improvements to CMP opcodes (#2353)
* [RV64_DYNAREC] Minor fixes and improvements to CMP opcodes * review
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_0.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 11 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_64.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_67.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_tests.c | 18 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
6 files changed, 26 insertions, 21 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_0.c b/src/dynarec/rv64/dynarec_rv64_00_0.c index 1a0290d6..4399c7c1 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_0.c +++ b/src/dynarec/rv64/dynarec_rv64_00_0.c @@ -584,10 +584,10 @@ uintptr_t dynarec64_00_0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); i64 = F32S; if (i64) { - MOV64xw(x2, i64); + MOV64x(x2, i64); emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6); } else - emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4); + emit_cmp32_0(dyn, ninst, rex, nextop, xRAX, x3, x4, x5); break; default: diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index 75d03ad7..e77956ff 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -253,15 +253,10 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int else i64 = F8S; if (i64) { - MOV64xw(x2, i64); + MOV64x(x2, i64); emit_cmp32(dyn, ninst, rex, ed, x2, x3, x4, x5, x6); - } else { - if (!rex.w && MODREG) { - ZEXTW2(x1, ed); - ed = x1; - } - emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); - } + } else + emit_cmp32_0(dyn, ninst, rex, nextop, ed, x3, x4, x5); break; } break; diff --git a/src/dynarec/rv64/dynarec_rv64_64.c b/src/dynarec/rv64/dynarec_rv64_64.c index 8d1e2d7f..6447c7f2 100644 --- a/src/dynarec/rv64/dynarec_rv64_64.c +++ b/src/dynarec/rv64/dynarec_rv64_64.c @@ -372,10 +372,10 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni else i64 = F8S; if (i64) { - MOV64xw(x2, i64); + MOV64x(x2, i64); emit_cmp32(dyn, ninst, rex, ed, x2, x3, x4, x5, x6); } else - emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); + emit_cmp32_0(dyn, ninst, rex, nextop, ed, x3, x4, x5); break; } break; diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c index f079ae49..a42cc19e 100644 --- a/src/dynarec/rv64/dynarec_rv64_67.c +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -458,10 +458,10 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION); i64 = F32S; if (i64) { - MOV64xw(x2, i64); + MOV64x(x2, i64); emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6); } else - emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4); + emit_cmp32_0(dyn, ninst, rex, nextop, xRAX, x3, x4, x5); break; case 0x63: INST_NAME("MOVSXD Gd, Ed"); @@ -638,10 +638,10 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni else i64 = F8S; if (i64) { - MOV64xw(x2, i64); + MOV64x(x2, i64); emit_cmp32(dyn, ninst, rex, ed, x2, x3, x4, x5, x6); } else - emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); + emit_cmp32_0(dyn, ninst, rex, nextop, ed, x3, x4, x5); break; } break; diff --git a/src/dynarec/rv64/dynarec_rv64_emit_tests.c b/src/dynarec/rv64/dynarec_rv64_emit_tests.c index 1fa0b8ab..bc9e79ce 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_tests.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_tests.c @@ -255,7 +255,7 @@ void emit_cmp32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s } // emit CMP32 instruction, from cmp s1, 0, using s3 and s4 as scratch -void emit_cmp32_0(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4) +void emit_cmp32_0(dynarec_rv64_t* dyn, int ninst, rex_t rex, uint8_t nextop, int s1, int s3, int s4, int s5) { CLEAR_FLAGS(); IFX_PENDOR0 { @@ -275,11 +275,18 @@ void emit_cmp32_0(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s3, int SET_FLAGS_NEZ(s3, F_SF, s4); } } + int res = s1; + IFX (X_ZF | X_PF) { + if (!rex.w && MODREG) { + ZEXTW2(s5, s1); + res = s5; + } + } IFX (X_ZF) { - SET_FLAGS_EQZ(s1, F_ZF, s3); + SET_FLAGS_EQZ(res, F_ZF, s3); } IFX (X_PF) { - emit_pf(dyn, ninst, s1, s3, s4); + emit_pf(dyn, ninst, res, s3, s4); } NAT_FLAGS_ENABLE_CARRY(); NAT_FLAGS_ENABLE_SIGN(); @@ -289,10 +296,13 @@ void emit_cmp32_0(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s3, int else { if (dyn->insts[ninst].nat_flags_needsign) { SEXT_W(s3, s1); + NAT_FLAGS_OPS(s3, xZR); + } else if (res == s5) { // zero-up'd case + NAT_FLAGS_OPS(s5, xZR); } else { ZEXTW2(s3, s1); + NAT_FLAGS_OPS(s3, xZR); } - NAT_FLAGS_OPS(s3, xZR); } } } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index ca1e40d0..d1ecd7f7 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -1410,7 +1410,7 @@ void emit_cmp16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, void emit_cmp32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5, int s6); void emit_cmp8_0(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4); void emit_cmp16_0(dynarec_rv64_t* dyn, int ninst, int s1, int s3, int s4); -void emit_cmp32_0(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s3, int s4); +void emit_cmp32_0(dynarec_rv64_t* dyn, int ninst, rex_t rex, uint8_t nextop, int s1, int s3, int s4, int s5); void emit_test8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_test8c(dynarec_rv64_t* dyn, int ninst, int s1, uint8_t c, int s3, int s4, int s5); void emit_test16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); |