diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-04-11 13:01:51 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-04-11 13:01:51 +0000 |
| commit | e96b1c810672a2493050a36d32f4961b3158901c (patch) | |
| tree | 6af9594d202a62567c1cbbc63859b87e3af6d19c /src | |
| parent | fdb6908474979b6602fa2c23087cf4ddc4c988e7 (diff) | |
| download | box64-e96b1c810672a2493050a36d32f4961b3158901c.tar.gz box64-e96b1c810672a2493050a36d32f4961b3158901c.zip | |
[RV64_DYNAREC] Added 0F BC/BD opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 74 | ||||
| -rw-r--r-- | src/include/bitutils.h | 3 | ||||
| -rw-r--r-- | src/tools/bitutils.c | 7 |
3 files changed, 83 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index e0ec682f..9b267061 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -18,6 +18,7 @@ #include "dynarec_native.h" #include "my_cpuid.h" #include "emu/x87emu_private.h" +#include "bitutils.h" #include "rv64_printer.h" #include "dynarec_rv64_private.h" @@ -629,6 +630,79 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SMWRITE(); } break; + case 0xBC: + INST_NAME("BSF Gd, Ed"); + SETFLAGS(X_ZF, SF_SUBSET); + SET_DFNONE(); + nextop = F8; + GETED(0); + GETGD; + if(!rex.w && MODREG) { + AND(x4, ed, xMASK); + ed = x4; + } + BNE_MARK(ed, xZR); + ORI(xFlags, xFlags, 1<<F_ZF); + B_NEXT_nocond; + MARK; + NEG(x2, ed); + AND(x2, x2, ed); + TABLE64(x3, 0x03f79d71b4ca8b09ULL); + MUL(x2, x2, x3); + SRLI(x2, x2, 64-6); + TABLE64(x1, (uintptr_t)&deBruijn64tab); + ADD(x1, x1, x2); + LBU(gd, x1, 0); + ANDI(xFlags, xFlags, ~(1<<F_ZF)); + break; + case 0xBD: + INST_NAME("BSR Gd, Ed"); + SETFLAGS(X_ZF, SF_SUBSET); + SET_DFNONE(); + nextop = F8; + GETED(0); + GETGD; + if(!rex.w && MODREG) { + AND(x4, ed, xMASK); + ed = x4; + } + BNE_MARK(ed, xZR); + ORI(xFlags, xFlags, 1<<F_ZF); + B_NEXT_nocond; + MARK; + ANDI(xFlags, xFlags, ~(1<<F_ZF)); + if(ed!=gd) + u8 = gd; + else + u8 = x1; + ADDI(u8, xZR, 0); + if(rex.w) { + MV(x2, ed); + SRLI(x3, x2, 32); + BEQZ(x3, 4+2*4); + ADDI(u8, u8, 32); + MV(x2, x3); + } else { + AND(x2, ed, xMASK); + } + SRLI(x3, x2, 16); + BEQZ(x3, 4+2*4); + ADDI(u8, u8, 16); + MV(x2, x3); + SRLI(x3, x2, 8); + BEQZ(x3, 4+2*4); + ADDI(u8, u8, 8); + MV(x2, x3); + SRLI(x3, x2, 4); + BEQZ(x3, 4+2*4); + ADDI(u8, u8, 4); + MV(x2, x3); + ANDI(x2, x2, 0b1111); + TABLE64(x3, (uintptr_t)&lead0tab); + ADD(x3, x3, x2); + LBU(x2, x3, 0); + ADD(gd, u8, x2); + break; case 0xBE: INST_NAME("MOVSX Gd, Eb"); nextop = F8; diff --git a/src/include/bitutils.h b/src/include/bitutils.h index 075e8e0b..50622da6 100644 --- a/src/include/bitutils.h +++ b/src/include/bitutils.h @@ -2,6 +2,9 @@ #define __BITUTILS_H_ #include <stdint.h> +extern const uint8_t deBruijn64tab[64]; +extern const uint8_t lead0tab[16]; + int TrailingZeros64(uint64_t x); #endif //__BITUTILS_H_ diff --git a/src/tools/bitutils.c b/src/tools/bitutils.c index 518085c2..fc8879af 100644 --- a/src/tools/bitutils.c +++ b/src/tools/bitutils.c @@ -1,6 +1,5 @@ #include <stdint.h> -const uint64_t deBruijn64 = 0x03f79d71b4ca8b09; const uint8_t deBruijn64tab[64] = { 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4, 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5, @@ -9,9 +8,15 @@ const uint8_t deBruijn64tab[64] = { }; int TrailingZeros64(uint64_t x) { + static const uint64_t deBruijn64 = 0x03f79d71b4ca8b09ULL; if (x == 0) { return 64; } return (int)deBruijn64tab[(x&-x)*deBruijn64>>(64-6)]; } + +const uint8_t lead0tab[16] = { + //0b0000 0b0001 0b0010 0b0011 0b0100 0b0101 0b0110 0b0111 0b1000... + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 +}; \ No newline at end of file |