diff options
| author | xctan <xctan@cirno.icu> | 2023-03-21 17:18:33 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-21 10:18:33 +0100 |
| commit | 244eca4b38e73bff405df03125db6cdc14a6ce6e (patch) | |
| tree | 9468272c59a71f570d56bd2bb3cfef3e1b621c62 /src | |
| parent | 67690748bdcaca0e5191a53ce91783a9a50f4e37 (diff) | |
| download | box64-244eca4b38e73bff405df03125db6cdc14a6ce6e.tar.gz box64-244eca4b38e73bff405df03125db6cdc14a6ce6e.zip | |
[RV64_DYNAREC] Added some opcodes (#608)
* [RV64_DYNAREC] Added 05 ADD opcode * [RV64_DYNAREC] Added 0D OR opcode * [RV64_DYNAREC] Added 0A OR opcode * [RV64_DYNAREC] Fixed F_ZF in emit logic
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 24 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_logic.c | 39 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 16 |
3 files changed, 73 insertions, 6 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 9aec9fb6..d91a3216 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -72,6 +72,13 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni emit_add32(dyn, ninst, rex, gd, ed, x3, x4, x5); break; + case 0x05: + INST_NAME("ADD EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_add32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5, x6); + break; + case 0x09: INST_NAME("OR Ed, Gd"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -82,6 +89,23 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni WBACK; break; + case 0x0A: + INST_NAME("OR Gb, Eb"); + SETFLAGS(X_ALL, SF_SET_PENDING); + nextop = F8; + GETEB(x2, 0); + GETGB(x1); + emit_or8(dyn, ninst, x1, x2, x3, x4); + GBBACK(x5); + break; + + case 0x0D: + INST_NAME("OR EAX, Id"); + SETFLAGS(X_ALL, SF_SET_PENDING); + i64 = F32S; + emit_or32c(dyn, ninst, rex, xRAX, i64, x3, x4); + break; + case 0x0F: switch(rep) { case 0: diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c index f1e92b83..78bdac67 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_logic.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c @@ -50,7 +50,7 @@ void emit_xor32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s IFX(X_ZF) { BNEZ(s1, 8); - ORI(xFlags, xFlags, F_ZF); + ORI(xFlags, xFlags, 1 << F_ZF); } IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -89,7 +89,7 @@ void emit_xor32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i IFX(X_ZF) { BNEZ(s1, 8); - ORI(xFlags, xFlags, F_ZF); + ORI(xFlags, xFlags, 1 << F_ZF); } IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -120,7 +120,7 @@ void emit_or16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4) { IFX(X_ZF) { BNEZ(s1, 8); - ORI(xFlags, xFlags, F_ZF); + ORI(xFlags, xFlags, 1 << F_ZF); } IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -155,7 +155,7 @@ void emit_or32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 IFX(X_ZF) { BNEZ(s1, 8); - ORI(xFlags, xFlags, F_ZF); + ORI(xFlags, xFlags, 1 << F_ZF); } IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -193,7 +193,7 @@ void emit_or32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in IFX(X_ZF) { BNEZ(s1, 8); - ORI(xFlags, xFlags, F_ZF); + ORI(xFlags, xFlags, 1 << F_ZF); } IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); @@ -293,3 +293,32 @@ void emit_and32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i emit_pf(dyn, ninst, s1, s3, s4); } } + +// emit OR8 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed) +void emit_or8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4) +{ + CLEAR_FLAGS(); + IFX(X_PEND) { + SET_DF(s3, d_or8); + } else IFX(X_ALL) { + SET_DFNONE(); + } + + OR(s1, s1, s2); + + IFX(X_PEND) { + SB(s1, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_SF) { + SRLI(s3, s1, 7); + BEQZ(s3, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + IFX(X_ZF) { + BNEZ(s1, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + emit_pf(dyn, ninst, s1, s3, s4); + } +} \ No newline at end of file diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index efd9054a..d1c5dc2e 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -213,6 +213,20 @@ if (gb2) SRLI(gd, gd, gb2*8); \ ANDI(gd, gd, 0xff); +// Write gb (gd) back to original register / memory, using s1 as scratch +#define GBBACK(s1) if(gb2) { \ + assert(gb2 == 8); \ + MOV64x(s1, 0xffffffffffff00ffLL); \ + AND(gb1, gb1, s1); \ + ANDI(gd, gd, 0xff); \ + SLLI(s1, gd, 8); \ + OR(gb1, gb1, s1); \ + } else { \ + ANDI(gb1, gb1, ~0xff); \ + ANDI(gd, gd, 0xff); \ + OR(gb1, gb1, gd); \ + } + // Write eb (ed) back to original register / memory, using s1 as scratch #define EBBACK(s1) if(wb1) { \ SB(ed, wback, fixedaddress); \ @@ -701,7 +715,7 @@ void emit_xor32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s void emit_xor32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4); void emit_and32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4); void emit_and32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, int s3, int s4); -//void emit_or8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); +void emit_or8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_or8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); //void emit_xor8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4); //void emit_xor8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4); |