about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-04-11 13:01:51 +0000
committerptitSeb <sebastien.chev@gmail.com>2023-04-11 13:01:51 +0000
commite96b1c810672a2493050a36d32f4961b3158901c (patch)
tree6af9594d202a62567c1cbbc63859b87e3af6d19c /src
parentfdb6908474979b6602fa2c23087cf4ddc4c988e7 (diff)
downloadbox64-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.c74
-rw-r--r--src/include/bitutils.h3
-rw-r--r--src/tools/bitutils.c7
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