diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-03-21 04:10:31 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-20 21:10:31 +0100 |
| commit | 39ec81117d6706fc2415aa964f2ab75604b13d92 (patch) | |
| tree | 2315f53f8078b7727ff1253848576b66c09ad9ad /src | |
| parent | 70f91204b1345e08a7cf39e0622b4b94f158de66 (diff) | |
| download | box64-39ec81117d6706fc2415aa964f2ab75604b13d92.tar.gz box64-39ec81117d6706fc2415aa964f2ab75604b13d92.zip | |
[RV64_DYNAREC] Added 19 SBB opcode (#605)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 10 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_math.c | 45 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
3 files changed, 54 insertions, 3 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 3a4d087c..1c0f5918 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -94,6 +94,16 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0x19: + INST_NAME("SBB Ed, Gd"); + READFLAGS(X_CF); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETGD; + GETED(0); + emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4, x5); + WBACK; + break; case 0x21: INST_NAME("AND Ed, Gd"); SETFLAGS(X_ALL, SF_SET_PENDING); diff --git a/src/dynarec/rv64/dynarec_rv64_emit_math.c b/src/dynarec/rv64/dynarec_rv64_emit_math.c index ed213f55..9b25e423 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_math.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_math.c @@ -370,8 +370,7 @@ void emit_sbb8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, i SUBW(s1, s1, s2); ANDI(s1, s1, 0xff); ANDI(s3, xFlags, 1 << F_CF); - BEQZ(s3, 12); - ADDIW(s1, s1, -1); + SUBW(s1, s1, s3); ANDI(s1, s1, 0xff); IFX(X_PEND) { @@ -399,3 +398,45 @@ void emit_sbb8c(dynarec_rv64_t* dyn, int ninst, int s1, int c, int s3, int s4, i MOV32w(s6, c&0xff); emit_sbb8(dyn, ninst, s1, s6, s3, s4, s5); } + +// emit SBB32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch +void emit_sbb32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) +{ + IFX(X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, op1)); + SDxw(s2, xEmu, offsetof(x64emu_t, op2)); + SET_DF(s3, rex.w?d_sbb64:d_sbb32); + } else IFX(X_ALL) { + SET_DFNONE(); + } + + IFX(X_AF | X_CF | X_OF) { + // for later flag calculation + NOT(s5, s1); + } + + SUBxw(s1, s1, s2); + ANDI(s3, xFlags, 1 << F_CF); + SUBxw(s1, s1, s3); + + IFX(X_SF) { + BGE(s1, xZR, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + if (!rex.w) { + ZEROUP(s1); + } + + IFX(X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, res)); + } + + CALC_SUB_FLAGS(s5, s2, s1, s3, s4, rex.w?64:32); + IFX(X_ZF) { + BNEZ(s1, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index e5a21853..efd9054a 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -729,7 +729,7 @@ void emit_inc32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s //void emit_adc8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4, int s5); //void emit_adc16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_adc16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); -//void emit_sbb32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); +void emit_sbb32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); //void emit_sbb32c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); void emit_sbb8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_sbb8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4, int s5, int s6); |