diff options
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_emit_math.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 18 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_math.c | 42 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
4 files changed, 61 insertions, 3 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_emit_math.c b/src/dynarec/arm64/dynarec_arm64_emit_math.c index 8d952d50..96b1127f 100755 --- a/src/dynarec/arm64/dynarec_arm64_emit_math.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_math.c @@ -432,7 +432,7 @@ void emit_sub8c(dynarec_arm_t* dyn, int ninst, int s1, int c, int s3, int s4, in } IFX(X_PEND) { STRB_U12(s1, xEmu, offsetof(x64emu_t, op1)); - STRB_U12(s3, xEmu, offsetof(x64emu_t, op2)); + STRB_U12(s5, xEmu, offsetof(x64emu_t, op2)); SET_DF(s3, d_sub8); } else IFX(X_ALL) { SET_DFNONE(s3); diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index c0416ceb..630666e7 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -172,7 +172,15 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETED(0); emit_sub32(dyn, ninst, rex, gd, ed, x3, x4, x5); break; - + case 0x2C: + INST_NAME("SUB AL, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + u8 = F8; + ANDI(x1, xRAX, 0xff); + emit_sub8c(dyn, ninst, x1, u8, x2, x3, x4, x5); + ANDI(xRAX, xRAX, ~0xff); + OR(xRAX, xRAX, x1); + break; case 0x31: INST_NAME("XOR Ed, Gd"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -436,6 +444,14 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_and8c(dyn, ninst, x1, u8, x3, x4); EBBACK(x3); break; + case 5: // SUB + INST_NAME("SUB Eb, Ib"); + SETFLAGS(X_ALL, SF_SET_PENDING); + GETEB(x1, 1); + u8 = F8; + emit_sub8c(dyn, ninst, x1, u8, x2, x3, x4, x5); + EBBACK(x3); + break; case 7: // CMP INST_NAME("CMP Eb, Ib"); 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 36ef6e29..91cece12 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_math.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_math.c @@ -316,6 +316,48 @@ void emit_add8c(dynarec_rv64_t* dyn, int ninst, int s1, int c, int s2, int s3, i } +// emit SUB8 instruction, from s1, constant c, store result in s1 using s3 and s4 as scratch +void emit_sub8c(dynarec_rv64_t* dyn, int ninst, int s1, int c, int s2, int s3, int s4, int s5) +{ + CLEAR_FLAGS(); + + IFX(X_ALL|X_PEND) { + MOV32w(s5, c&0xff); + } + + IFX(X_PEND) { + SB(s1, xEmu, offsetof(x64emu_t, op1)); + SB(s5, xEmu, offsetof(x64emu_t, op2)); + SET_DF(s3, d_sub8); + } else IFX(X_ALL) { + SET_DFNONE(); + } + + IFX(X_AF | X_CF | X_OF) { + // for later flag calculation + NOT(s5, s1); + } + + SUBW(s1, s1, s3); + ANDI(s1, s1, 0xff); + + IFX(X_PEND) { + SB(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_SF) { + BGE(s1, xZR, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + CALC_SUB_FLAGS(s5, s2, s1, s3, s4, 8); + IFX(X_ZF) { + BNEZ(s1, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} + // emit SUB32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_sub32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 39bbc507..17247fb7 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -747,7 +747,7 @@ void emit_add8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s2, int s void emit_sub32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); void emit_sub32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s2, int s3, int s4, int s5); //void emit_sub8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); -//void emit_sub8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4, int s5); +void emit_sub8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s2, int s3, int s4, int s5); void emit_or32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); void emit_or32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4); void emit_xor32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); |