about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-03-20 15:17:54 +0800
committerGitHub <noreply@github.com>2023-03-20 08:17:54 +0100
commitc56ad76d18a9693908c70614e4a7d5f2f69e5d34 (patch)
treeff64b86388ad5516b698049082eddb70d96f2f96 /src
parentb5dd04aa1216b67f0c8d05a968f209dfe9bdfef7 (diff)
downloadbox64-c56ad76d18a9693908c70614e4a7d5f2f69e5d34.tar.gz
box64-c56ad76d18a9693908c70614e4a7d5f2f69e5d34.zip
[RV64_DYNAREC] Added 80 /4 AND opcode (#594)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00.c9
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_logic.c29
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h17
3 files changed, 54 insertions, 1 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c
index a0a0c9a5..4db2ce60 100644
--- a/src/dynarec/rv64/dynarec_rv64_00.c
+++ b/src/dynarec/rv64/dynarec_rv64_00.c
@@ -4,6 +4,7 @@
 #include <pthread.h>
 #include <errno.h>
 #include <signal.h>
+#include <assert.h>
 
 #include "debug.h"
 #include "box64context.h"
@@ -299,6 +300,14 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0x80:
             nextop = F8;
             switch((nextop>>3)&7) {
+                case 4: // AND
+                    INST_NAME("AND Eb, Ib");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEB(x1, 1);
+                    u8 = F8;
+                    emit_and8c(dyn, ninst, x1, u8, x2, x4);
+                    EBBACK(x2);
+                    break;
                 case 7: // CMP
                     INST_NAME("CMP Eb, Ib");
                     SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c
index 6076a159..1baf214c 100644
--- a/src/dynarec/rv64/dynarec_rv64_emit_logic.c
+++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c
@@ -200,6 +200,35 @@ void emit_or32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in
     }
 }
 
+// emit AND8 instruction, from s1 , constant c, store result in s1 using s3 and s4 as scratch
+void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4)
+{
+    CLEAR_FLAGS();
+    IFX(X_PEND) {
+        SET_DF(s3, d_and8);
+    } else IFX(X_ALL) {
+        SET_DFNONE(s3);
+    }
+
+    ANDI(s1, s1, c&0xff);
+
+    IFX(X_PEND) {
+        SD(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);
+    }
+}
+
 // emit AND32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch
 void emit_and32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4)
 {
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index f4a7a9a2..9532b9f2 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -190,6 +190,21 @@
                 if (gb2) SRLI(gd, gd, gb2*8);                 \
                 ANDI(gd, gd, 0xff);
 
+// Write eb (ed) back to original register / memory, using s1 as scratch
+#define EBBACK(s1) if(wb1) {                            \
+                    SB(ed, wback, fixedaddress);        \
+                    SMWRITE();                          \
+                } else if(wb2) {                        \
+                    assert(wb2 == 8);                   \
+                    MOV64x(s1, 0xffffffffffff00ffLL);   \
+                    AND(wback, wback, s1);              \
+                    SLLI(s1, ed, 8);                    \
+                    OR(wback, wback, s1);               \
+                } else {                                \
+                    ANDI(wback, wback, ~0xff);          \
+                    OR(wback, wback, ed);               \
+                }
+
 // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2
 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0)
@@ -663,7 +678,7 @@ void emit_and32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
 //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);
 //void emit_and8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
-//void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
+void emit_and8c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
 //void emit_add16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);
 //void emit_add16c(dynarec_rv64_t* dyn, int ninst, int s1, int32_t c, int s3, int s4);
 //void emit_sub16(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4);