about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorxctan <xctan@cirno.icu>2023-03-21 17:18:33 +0800
committerGitHub <noreply@github.com>2023-03-21 10:18:33 +0100
commit244eca4b38e73bff405df03125db6cdc14a6ce6e (patch)
tree9468272c59a71f570d56bd2bb3cfef3e1b621c62 /src
parent67690748bdcaca0e5191a53ce91783a9a50f4e37 (diff)
downloadbox64-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.c24
-rw-r--r--src/dynarec/rv64/dynarec_rv64_emit_logic.c39
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h16
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);