diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-05-13 07:47:11 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-05-13 07:47:11 +0000 |
| commit | 6ac2376aacf1f7c69a50169dba4fefca9f62f8c5 (patch) | |
| tree | 39df06f9cf9fad7a31259893ceb5ce5964625f20 /src | |
| parent | 4fadb26cf6e98e637a5f02cbb2e816faee097a29 (diff) | |
| download | box64-6ac2376aacf1f7c69a50169dba4fefca9f62f8c5.tar.gz box64-6ac2376aacf1f7c69a50169dba4fefca9f62f8c5.zip | |
[RV64_DYNAREC] Fixed ADC and SBC opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_0.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_64.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_67.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_math.c | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
6 files changed, 21 insertions, 21 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_0.c b/src/dynarec/rv64/dynarec_rv64_00_0.c index 0320107d..1127bf79 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_0.c +++ b/src/dynarec/rv64/dynarec_rv64_00_0.c @@ -178,7 +178,7 @@ uintptr_t dynarec64_00_0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int nextop = F8; GETGD; GETED(0); - emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5); + emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5, x6); WBACK; break; diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index 427ed4a9..22c83db3 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -157,7 +157,7 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETED((opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; MOV64xw(x5, i64); - emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x6); + emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x6, x9); WBACK; break; case 3: // SBB diff --git a/src/dynarec/rv64/dynarec_rv64_64.c b/src/dynarec/rv64/dynarec_rv64_64.c index 7155ca00..9ab951e4 100644 --- a/src/dynarec/rv64/dynarec_rv64_64.c +++ b/src/dynarec/rv64/dynarec_rv64_64.c @@ -212,7 +212,7 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(opcode==0x81) i64 = F32S; else i64 = F8S; MOV64xw(x5, i64); SD(x6, xEmu, offsetof(x64emu_t, scratch)); - emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x6); + emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x6, x9); LD(x6, xEmu, offsetof(x64emu_t, scratch)); WBACKO(x6); break; diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c index 14544463..fcbac89a 100644 --- a/src/dynarec/rv64/dynarec_rv64_67.c +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -191,7 +191,7 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGD; GETED32(0); - emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5); + emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5, x6); WBACK; break; @@ -202,7 +202,7 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGD; GETED32(0); - emit_adc32(dyn, ninst, rex, gd, ed, x3, x4, x5); + emit_adc32(dyn, ninst, rex, gd, ed, x3, x4, x5, x6); break; case 0x15: @@ -211,7 +211,7 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SETFLAGS(X_ALL, SF_SET_PENDING); i64 = F32S; MOV64xw(x1, i64); - emit_adc32(dyn, ninst, rex, xRAX, x1, x3, x4, x5); + emit_adc32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6); break; case 0x19: @@ -437,7 +437,7 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETED32((opcode==0x81)?4:1); if(opcode==0x81) i64 = F32S; else i64 = F8S; MOV64xw(x5, i64); - emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x5); + emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x5, x6); WBACK; break; case 3: //SBB diff --git a/src/dynarec/rv64/dynarec_rv64_emit_math.c b/src/dynarec/rv64/dynarec_rv64_emit_math.c index 1942a34b..f6a7d88b 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_math.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_math.c @@ -922,7 +922,6 @@ void emit_dec16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, // emit SBB8 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch void emit_sbb8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) { - CLEAR_FLAGS(); IFX(X_PEND) { SB(s1, xEmu, offsetof(x64emu_t, op1)); SB(s2, xEmu, offsetof(x64emu_t, op2)); @@ -941,6 +940,7 @@ void emit_sbb8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i SUBW(s1, s1, s3); ANDI(s1, s1, 0xff); + CLEAR_FLAGS(); IFX(X_PEND) { SB(s1, xEmu, offsetof(x64emu_t, res)); } @@ -962,7 +962,6 @@ void emit_sbb8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i // emit ADC8 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_adc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) { - CLEAR_FLAGS(); IFX(X_PEND) { SH(s1, xEmu, offsetof(x64emu_t, op1)); SH(s2, xEmu, offsetof(x64emu_t, op2)); @@ -979,6 +978,7 @@ void emit_adc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i ANDI(s3, xFlags, 1 << F_CF); ADD(s1, s1, s3); + CLEAR_FLAGS(); IFX(X_PEND) { SW(s1, xEmu, offsetof(x64emu_t, res)); } @@ -1042,7 +1042,6 @@ void emit_sbb8c(dynarec_rv64_t* dyn, int ninst, int s1, int c, int s3, int s4, i // emit SBB16 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch void emit_sbb16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) { - CLEAR_FLAGS(); IFX(X_PEND) { SH(s1, xEmu, offsetof(x64emu_t, op1)); SH(s2, xEmu, offsetof(x64emu_t, op2)); @@ -1060,6 +1059,7 @@ void emit_sbb16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, ANDI(s3, xFlags, 1 << F_CF); SUBW(s1, s1, s3); + CLEAR_FLAGS(); SLLIW(s1, s1, 16); IFX(X_SF) { BGE(s1, xZR, 8); @@ -1084,7 +1084,6 @@ void emit_sbb16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, // emit SBB32 instruction, from s1, s2, store result in s1 using s3, s4 and s5 as scratch void emit_sbb32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) { - CLEAR_FLAGS(); IFX(X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, op1)); SDxw(s2, xEmu, offsetof(x64emu_t, op2)); @@ -1102,6 +1101,7 @@ void emit_sbb32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s ANDI(s3, xFlags, 1 << F_CF); SUBxw(s1, s1, s3); + CLEAR_FLAGS(); IFX(X_SF) { BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); @@ -1297,7 +1297,6 @@ void emit_neg8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3) // emit ADC16 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_adc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) { - CLEAR_FLAGS(); IFX(X_PEND) { SH(s1, xEmu, offsetof(x64emu_t, op1)); SH(s2, xEmu, offsetof(x64emu_t, op2)); @@ -1314,6 +1313,7 @@ void emit_adc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, ANDI(s3, xFlags, 1 << F_CF); ADD(s1, s1, s3); + CLEAR_FLAGS(); IFX(X_PEND) { SW(s1, xEmu, offsetof(x64emu_t, res)); } @@ -1362,9 +1362,8 @@ void emit_adc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, } // emit ADC32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch -void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) +void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5, int s6) { - CLEAR_FLAGS(); IFX(X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, op1)); SDxw(s2, xEmu, offsetof(x64emu_t, op2)); @@ -1381,14 +1380,10 @@ void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s ADD(s4, s4, s3); SRLI(s5, s5, 0x20); ADD(s5, s5, s4); // hi - SRAI(s5, s5, 0x20); - BEQZ(s5, 8); - ORI(xFlags, xFlags, 1 << F_CF); + SRAI(s6, s5, 0x20); } else { ADD(s5, s1, s2); - SRLI(s5, s5, 0x20); - BEQZ(s5, 8); - ORI(xFlags, xFlags, 1 << F_CF); + SRLI(s6, s5, 0x20); } } IFX(X_AF | X_OF) { @@ -1400,9 +1395,14 @@ void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s ANDI(s3, xFlags, 1 << F_CF); ADDxw(s1, s1, s3); + CLEAR_FLAGS(); IFX(X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } + IFX(X_CF) { + BEQZ(s6, 8); + ORI(xFlags, xFlags, 1 << F_CF); + } IFX(X_AF | X_OF) { if(rv64_zbb) { ANDN(s3, s1, s4); // s3 = ~res & (op1 | op2) diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 598a26b9..d76bd552 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -1042,7 +1042,7 @@ void emit_inc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); void emit_dec32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); void emit_dec16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_dec8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); -void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); +void emit_adc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5, int s6); //void emit_adc32c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); void emit_adc8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_adc8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4, int s5, int s6); |