diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-05-23 02:00:22 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-22 20:00:22 +0200 |
| commit | 229cae16d1801b83bdee0a95c5515858df209876 (patch) | |
| tree | b887d9b22e9c92e2abc3f20f319d48c482420d95 | |
| parent | 9edb89fc222e06e76e3299871bd7c34c9910879f (diff) | |
| download | box64-229cae16d1801b83bdee0a95c5515858df209876.tar.gz box64-229cae16d1801b83bdee0a95c5515858df209876.zip | |
[LA64_DYNAREC] Fixed some non-lbt flags comutation issues (#1520)
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_math.c | 8 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_shift.c | 3 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 16 |
3 files changed, 17 insertions, 10 deletions
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index bee0acfa..50a8b103 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -285,7 +285,7 @@ void emit_add8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4) IFX(X_AF | X_OF) { ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2) - OR(s3, s3, s2); // cc = (~res & (op1 | op2)) | (op1 & op2) + OR(s3, s3, s4); // cc = (~res & (op1 | op2)) | (op1 & op2) IFX(X_AF) { ANDI(s4, s3, 0x08); // AF: cc & 0x08 BEQZ(s4, 8); @@ -985,7 +985,7 @@ void emit_neg32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s return; } - CLEAR_FLAGS(s3); + CLEAR_FLAGS(s2); IFX (X_CF) { BEQZ(s1, 8); ORI(xFlags, xFlags, 1 << F_CF); @@ -1059,6 +1059,8 @@ void emit_adc32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s AND(s5, xMASK, s1); AND(s4, xMASK, s2); ADD_D(s5, s5, s4); // lo + ANDI(s3, xFlags, 1); + ADD_D(s5, s5, s3); // add carry SRLI_D(s3, s1, 0x20); SRLI_D(s4, s2, 0x20); ADD_D(s4, s4, s3); @@ -1069,6 +1071,8 @@ void emit_adc32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s AND(s3, s1, xMASK); AND(s4, s2, xMASK); ADD_D(s5, s3, s4); + ANDI(s3, xFlags, 1); + ADD_D(s5, s5, s3); // add carry SRLI_D(s6, s5, 0x20); } } diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c index 28f8b849..1fe8aba8 100644 --- a/src/dynarec/la64/dynarec_la64_emit_shift.c +++ b/src/dynarec/la64/dynarec_la64_emit_shift.c @@ -721,6 +721,9 @@ void emit_rol32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s ANDI(s4, s2, 0x1f); } + if (!rex.w) ZEROUP(s1); + BEQ_NEXT(s4, xZR); + SLLxw(s3, s1, s4); NEG_D(s4, s4); ADDI_D(s4, s4, rex.w ? 64 : 32); diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index 29713ca6..6e2139e3 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -362,14 +362,14 @@ f24-f31 fs0-fs7 Static registers Callee } \ } while (0) // Shift Right Logical Immediate -#define SRLIxw(rd, rs1, imm) \ - do { \ - if (rex.w) { \ - SRLI_D(rd, rs1, imm); \ - } else { \ - SRLI_W(rd, rs1, imm); \ - if (imm == 0) ZEROUP(rd); \ - } \ +#define SRLIxw(rd, rs1, imm) \ + do { \ + if (rex.w) { \ + SRLI_D(rd, rs1, imm); \ + } else { \ + SRLI_W(rd, rs1, imm); \ + if ((imm) == 0) ZEROUP(rd); \ + } \ } while (0) // Shift Right Arithmetic Immediate |