about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-04-17 17:57:02 +0000
committerptitSeb <sebastien.chev@gmail.com>2023-04-17 17:57:02 +0000
commit9a97898ea4be010c36dcc78536bdf0ed1d3f0121 (patch)
treed1030c0918709c2853907209be833f86b6d0a215
parentcce1fa89280c1104d2a6007b76477eaa68447e6c (diff)
downloadbox64-9a97898ea4be010c36dcc78536bdf0ed1d3f0121.tar.gz
box64-9a97898ea4be010c36dcc78536bdf0ed1d3f0121.zip
[RV64_DYNAREC] Added F3 0F BD and 66 29 opcodes
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c9
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f30f.c58
2 files changed, 67 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index 0bcebef5..55c79e9b 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -154,6 +154,15 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             AND(xRAX, xRAX, x3);
             OR(xRAX, xRAX, x1);
             break;
+        case 0x29:
+            INST_NAME("SUB Ex, Gw");
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETGW(x1);
+            GETEW(x2, 0);
+            emit_sub16(dyn, ninst, x2, x1, x3, x4, x5);
+            EWBACK;
+            break;
         case 0x2B:
             INST_NAME("SUB Gw, Ew");
             SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c
index d1b51258..d9700507 100644
--- a/src/dynarec/rv64/dynarec_rv64_f30f.c
+++ b/src/dynarec/rv64/dynarec_rv64_f30f.c
@@ -16,6 +16,7 @@
 #include "emu/x64run_private.h"
 #include "x64trace.h"
 #include "dynarec_native.h"
+#include "bitutils.h"
 
 #include "rv64_printer.h"
 #include "dynarec_rv64_private.h"
@@ -223,6 +224,63 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             SSE_LOOP_MV_Q2(x3);
             if(!MODREG) SMWRITE2();
             break;
+
+        case 0xBD:
+            INST_NAME("LZCNT Gd, Ed");
+            SETFLAGS(X_ZF|X_CF, SF_SUBSET);
+            SET_DFNONE();
+            nextop = F8;
+            GETED(0);
+            GETGD;
+            if(!rex.w && MODREG) {
+                AND(x4, ed, xMASK);
+                ed = x4;
+            }
+            BNE_MARK(ed, xZR);
+            MOV32w(gd, 0);
+            B_MARK2_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);
+            MARK2;
+            ANDI(xFlags, xFlags, ~((1<<F_ZF) | (1<<F_CF)));
+            BNE(gd, xZR, 4+4);
+            ORI(xFlags, xFlags, 1<<F_ZF);
+            MOV32w(x2, rex.w?64:32);
+            BNE(gd, x2, 4+4);
+            ORI(xFlags, xFlags, 1<<F_CF);
+            break;
+
         case 0xC2:
             INST_NAME("CMPSS Gx, Ex, Ib");
             nextop = F8;