about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-23 10:00:29 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-23 10:00:29 +0100
commit2b6fa580df14e02e9bfdf9a3b23e56b7515d5c2a (patch)
tree161592b3cfb7c03706172eda1551a79af8bf70c5 /src
parent7f750e7ac1bf23bd91073691cae31e1191312d82 (diff)
downloadbox64-2b6fa580df14e02e9bfdf9a3b23e56b7515d5c2a.tar.gz
box64-2b6fa580df14e02e9bfdf9a3b23e56b7515d5c2a.zip
[DYNAREC] Added F3 0F C2 opcode
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h11
-rwxr-xr-xsrc/dynarec/arm64_printer.c10
-rwxr-xr-xsrc/dynarec/dynarec_arm64_f30f.c25
3 files changed, 46 insertions, 0 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index 102a381a..3f1533df 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -346,6 +346,17 @@
 #define CSETw(Rd, cond)                     CSINCw(Rd, xZR, xZR, invCond(cond))
 #define CSETxw(Rd, cond)                    CSINCxw(Rd, xZR, xZR, invCond(cond))
 
+#define CSINV_gen(sf, Rm, cond, Rn, Rd)     ((sf)<<31 | 1<<30 | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | (Rd))
+#define CSINVx(Rd, Rn, Rm, cond)            EMIT(CSINV_gen(1, Rm, cond, Rn, Rd))
+#define CSINVw(Rd, Rn, Rm, cond)            EMIT(CSINV_gen(0, Rm, cond, Rn, Rd))
+#define CSINVxw(Rd, Rn, Rm, cond)           EMIT(CSINV_gen(rex.w?, Rm, cond, Rn, Rd))
+#define CINVx(Rd, Rn, cond)                 CSINVx(Rd, Rn, Rn, invertCond(cond))
+#define CINVw(Rd, Rn, cond)                 CSINVw(Rd, Rn, Rn, invertCond(cond))
+#define CINVxw(Rd, Rn, cond)                CSINVxw(Rd, Rn, Rn, invertCond(cond))
+#define CSETMx(Rd, cond)                    CSINVx(Rd, xZR, xZR, invCond(cond))
+#define CSETMw(Rd, cond)                    CSINVw(Rd, xZR, xZR, invCond(cond))
+#define CSETMxw(Rd, cond)                   CSINVxw(Rd, xZR, xZR, invCond(cond))
+
 #define CSEL_gen(sf, Rm, cond, Rn, Rd)      ((sf<<31) | 0b11010100<<21 | (Rm)<<16 | (cond)<<12 | (Rn)<<5 | Rd)
 #define CSELx(Rd, Rn, Rm, cond)             EMIT(CSEL_gen(1, Rm, cond, Rn, Rd))
 #define CSELw(Rd, Rn, Rm, cond)             EMIT(CSEL_gen(0, Rm, cond, Rn, Rd))
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index 14255e48..8d9aedfe 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -699,6 +699,16 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         return buff;

     }

 

+    if(isMask(opcode, "f1011010100mmmmmdddd00nnnnnddddd", &a)) {

+        if(Rm!=31 && (cond&0b1110)!=0b1110 && Rn!=31 && Rn==Rm)

+            snprintf(buff, sizeof(buff), "CINV %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond^1]);    

+        else if(Rm==31 && (cond&0b1110)!=0b1110 && Rn==31)

+            snprintf(buff, sizeof(buff), "CSETM %s,%s", sf?Xt[Rd]:Wt[Rd], conds[cond^1]);    

+        else

+            snprintf(buff, sizeof(buff), "CSINV %s, %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], sf?Xt[Rm]:Wt[Rm], conds[cond]);

+        return buff;

+    }

+

     if(isMask(opcode, "f1011010100mmmmmcccc01nnnnnddddd", &a)) {

         if((cond&0b1110)!=0b1110 && Rn==Rm)

             snprintf(buff, sizeof(buff), "CNEG %s, %s, %s", sf?Xt[Rd]:Wt[Rd], sf?Xt[Rn]:Wt[Rn], conds[cond^1]);    

diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c
index 5b0352f7..c24346a6 100755
--- a/src/dynarec/dynarec_arm64_f30f.c
+++ b/src/dynarec/dynarec_arm64_f30f.c
@@ -188,6 +188,31 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             }

             break;

 

+        case 0xC2:

+            INST_NAME("CMPSS Gx, Ex, Ib");

+            nextop = F8;

+            GETGX(v0);

+            GETEX(v1, 1);

+            u8 = F8;

+            if((u8&7)==6){

+                FCMPS(v1, v0);

+            } else {

+                FCMPS(v0, v1);

+            }

+            MOV32w(x2, 0);

+            switch(u8&7) {

+                case 0: CSETMw(x2, cEQ); break;   // Equal

+                case 1: CSETMw(x2, cMI); break;   // Less than

+                case 2: CSETMw(x2, cLE); break;   // Less or equal

+                case 3: CSETMw(x2, cVS); break;   // NaN

+                case 4: CSETMw(x2, cNE); break;   // Not Equal (or unordered on ARM, not on X86...)

+                case 5: CSETMw(x2, cCS); break;   // Greater or equal or unordered

+                case 6: CSETMw(x2, cLT); break;   // Greater or unordered, test inverted, N!=V so unordereded or less than (inverted)

+                case 7: CSETMw(x2, cVC); break;   // not NaN

+            }

+            VMOVQSfrom(v0, 0, x2);

+            break;

+

         default:

             DEFAULT;

     }