diff options
| author | xctan <xctan@cirno.icu> | 2023-04-11 23:20:55 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-11 17:20:55 +0200 |
| commit | 4330b61217e80d127644e849c52124bde5c6e711 (patch) | |
| tree | b716eb16805356473bed979b0596630809758364 /src | |
| parent | 97410042bd24205ef8b4201746df611737e248b4 (diff) | |
| download | box64-4330b61217e80d127644e849c52124bde5c6e711.tar.gz box64-4330b61217e80d127644e849c52124bde5c6e711.zip | |
[RV64_DYNAREC] Added more opcodes for SV (#687)
* [RV64_DYNAREC] Added F9 STC opcode * [RV64_DYNAREC] Fixed F0 09 LOCK OR opcode * [RV64_DYNAREC] Added C1 /0 ROL opcode * [RV64_DYNAREC] Fixed F0 09 LOCK OR opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 15 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_shift.c | 45 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f0.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
4 files changed, 65 insertions, 5 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 97defd9a..3adc4646 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -1189,6 +1189,14 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xC1: nextop = F8; switch((nextop>>3)&7) { + case 0: + INST_NAME("ROL Ed, Ib"); + SETFLAGS(X_OF|X_CF, SF_SUBSET_PENDING); + GETED(1); + u8 = (F8)&(rex.w?0x3f:0x1f); + emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4); + if(u8) { WBACK; } + break; case 4: case 6: INST_NAME("SHL Ed, Ib"); @@ -1880,6 +1888,13 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni }; break; + case 0xF9: + INST_NAME("STC"); + SETFLAGS(X_CF, SF_SUBSET); + SET_DFNONE(); + ORI(xFlags, xFlags, 1 << F_CF); + break; + case 0xFF: nextop = F8; switch((nextop>>3)&7) { diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c index 6af7aad7..ae7e6ebe 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c @@ -307,6 +307,51 @@ void emit_sar32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, } } +// emit ROL32 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch +void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4) +{ + IFX(X_CF) { + ANDI(xFlags, xFlags, ~(1UL<<F_CF)); + } + + IFX(X_PEND) { + MOV32w(s3, c); + SDxw(s3, xEmu, offsetof(x64emu_t, op2)); + SET_DF(s4, rex.w?d_rol64:d_rol32); + } else IFX(X_ALL) { + SET_DFNONE(); + } + if(!c) { + IFX(X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, res)); + } + return; + } + SLLI(s3, s1, c); + if (!rex.w) { + AND(s3, xMASK, s3); + } + SRLI(s1, s1, (rex.w?64:32)-c); + OR(s1, s3, s1); + IFX(X_PEND) { + SDxw(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_CF) { + // F_CF=0 + ANDI(s4, s1, 1); + OR(xFlags, xFlags, s4); + } + IFX(X_OF) { + if(c==1) { + SRLIxw(s3, s1, rex.w?63:31); + XOR(s3, s3, s1); + ANDI(s3, s3, 1); + SLLI(s3, s3, F_OF2); + OR(xFlags, xFlags, s3); + } + } +} + // emit SHRD32 instruction, from s1, fill s2 , constant c, store result in s1 using s3 and s4 as scratch void emit_shrd32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4) { diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index ef46e9eb..e78756e5 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -70,15 +70,15 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); MARKLOCK; LRxw(x1, wback, 1, 1); - OR(x1, x1, gd); - SCxw(x3, x1, wback, 1, 1); + OR(x4, x1, gd); + SCxw(x3, x4, wback, 1, 1); BNEZ_MARKLOCK(x3); - IFX(X_ALL|X_PEND) { + IFX(X_ALL|X_PEND) emit_or32(dyn, ninst, rex, x1, gd, x3, x4); - } } SMDMB(); break; + case 0x0F: nextop = F8; switch(nextop) { diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 40985d8c..a1bfbc8a 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -954,7 +954,7 @@ void emit_shl32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, void emit_shr32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); void emit_shr32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); void emit_sar32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); -//void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); +void emit_rol32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); //void emit_ror32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, int s3, int s4); void emit_shrd32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4); //void emit_shld32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, uint32_t c, int s3, int s4); |