about summary refs log tree commit diff stats
path: root/src/dynarec/arm64/dynarec_arm64_functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynarec/arm64/dynarec_arm64_functions.c')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c68
1 files changed, 53 insertions, 15 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index 2a7c9b34..6944b785 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -1,7 +1,6 @@
 #define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
-#include <pthread.h>
 #include <errno.h>
 #include <string.h>
 #include <math.h>
@@ -13,7 +12,6 @@
 #include "box64context.h"
 #include "dynarec.h"
 #include "emu/x64emu_private.h"
-#include "tools/bridge_private.h"
 #include "x64run.h"
 #include "x64emu.h"
 #include "box64stack.h"
@@ -60,7 +58,7 @@ void fpu_free_reg(dynarec_arm_t* dyn, int reg)
 {
     // TODO: check upper limit?
     dyn->n.fpuused[reg] = 0;
-    if(dyn->n.neoncache[reg].t!=NEON_CACHE_ST_F && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_D)
+    if(dyn->n.neoncache[reg].t!=NEON_CACHE_ST_F && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_D && dyn->n.neoncache[reg].t!=NEON_CACHE_ST_I64)
         dyn->n.neoncache[reg].v = 0;
 }
 // Get an MMX double reg
@@ -108,7 +106,8 @@ int neoncache_get_st(dynarec_arm_t* dyn, int ninst, int a)
     }
     for(int i=0; i<24; ++i)
         if((dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F
-         || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D)
+         || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D
+         || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_I64)
          && dyn->insts[ninst].n.neoncache[i].n==a)
             return dyn->insts[ninst].n.neoncache[i].t;
     // not in the cache yet, so will be fetched...
@@ -122,7 +121,8 @@ int neoncache_get_current_st(dynarec_arm_t* dyn, int ninst, int a)
         return NEON_CACHE_ST_D;
     for(int i=0; i<24; ++i)
         if((dyn->n.neoncache[i].t==NEON_CACHE_ST_F
-         || dyn->n.neoncache[i].t==NEON_CACHE_ST_D)
+         || dyn->n.neoncache[i].t==NEON_CACHE_ST_D
+         || dyn->n.neoncache[i].t==NEON_CACHE_ST_I64)
          && dyn->n.neoncache[i].n==a)
             return dyn->n.neoncache[i].t;
     // not in the cache yet, so will be fetched...
@@ -140,6 +140,17 @@ int neoncache_get_st_f(dynarec_arm_t* dyn, int ninst, int a)
             return i;
     return -1;
 } 
+int neoncache_get_st_f_i64(dynarec_arm_t* dyn, int ninst, int a)
+{
+    /*if(a+dyn->insts[ninst].n.stack_next-st<0)
+        // The STx has been pushed at the end of instructon, so stop going back
+        return -1;*/
+    for(int i=0; i<24; ++i)
+        if((dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_I64 || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F)
+         && dyn->insts[ninst].n.neoncache[i].n==a)
+            return i;
+    return -1;
+} 
 int neoncache_get_st_f_noback(dynarec_arm_t* dyn, int ninst, int a)
 {
     for(int i=0; i<24; ++i)
@@ -148,6 +159,14 @@ int neoncache_get_st_f_noback(dynarec_arm_t* dyn, int ninst, int a)
             return i;
     return -1;
 } 
+int neoncache_get_st_f_i64_noback(dynarec_arm_t* dyn, int ninst, int a)
+{
+    for(int i=0; i<24; ++i)
+        if((dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_I64 || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F)
+         && dyn->insts[ninst].n.neoncache[i].n==a)
+            return i;
+    return -1;
+} 
 int neoncache_get_current_st_f(dynarec_arm_t* dyn, int a)
 {
     for(int i=0; i<24; ++i)
@@ -156,6 +175,14 @@ int neoncache_get_current_st_f(dynarec_arm_t* dyn, int a)
             return i;
     return -1;
 } 
+int neoncache_get_current_st_f_i64(dynarec_arm_t* dyn, int a)
+{
+    for(int i=0; i<24; ++i)
+        if((dyn->n.neoncache[i].t==NEON_CACHE_ST_I64 || dyn->n.neoncache[i].t==NEON_CACHE_ST_F)
+         && dyn->n.neoncache[i].n==a)
+            return i;
+    return -1;
+} 
 static void neoncache_promote_double_forward(dynarec_arm_t* dyn, int ninst, int maxinst, int a);
 static void neoncache_promote_double_internal(dynarec_arm_t* dyn, int ninst, int maxinst, int a);
 static void neoncache_promote_double_combined(dynarec_arm_t* dyn, int ninst, int maxinst, int a)
@@ -165,7 +192,7 @@ static void neoncache_promote_double_combined(dynarec_arm_t* dyn, int ninst, int
             a = dyn->insts[ninst].n.combined2;
         } else 
             a = dyn->insts[ninst].n.combined1;
-        int i = neoncache_get_st_f_noback(dyn, ninst, a);
+        int i = neoncache_get_st_f_i64_noback(dyn, ninst, a);
         //if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_combined, ninst=%d combined%c %d i=%d (stack:%d/%d)\n", ninst, (a == dyn->insts[ninst].n.combined2)?'2':'1', a ,i, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop);
         if(i>=0) {
             dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
@@ -184,7 +211,7 @@ static void neoncache_promote_double_internal(dynarec_arm_t* dyn, int ninst, int
         return;
     while(ninst>=0) {
         a+=dyn->insts[ninst].n.stack_pop;    // adjust Stack depth: add pop'd ST (going backward)
-        int i = neoncache_get_st_f(dyn, ninst, a);
+        int i = neoncache_get_st_f_i64(dyn, ninst, a);
         //if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_internal, ninst=%d, a=%d st=%d:%d, i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, i);
         if(i<0) return;
         dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
@@ -219,7 +246,7 @@ static void neoncache_promote_double_forward(dynarec_arm_t* dyn, int ninst, int
             else if (a==dyn->insts[ninst].n.combined2)
                 a = dyn->insts[ninst].n.combined1;
         }
-        int i = neoncache_get_st_f_noback(dyn, ninst, a);
+        int i = neoncache_get_st_f_i64_noback(dyn, ninst, a);
         //if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double_forward, ninst=%d, a=%d st=%d:%d(%d/%d), i=%d\n", ninst, a, dyn->insts[ninst].n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, -dyn->insts[ninst].n.stack_pop, i);
         if(i<0) return;
         dyn->insts[ninst].n.neoncache[i].t = NEON_CACHE_ST_D;
@@ -240,7 +267,7 @@ static void neoncache_promote_double_forward(dynarec_arm_t* dyn, int ninst, int
 
 void neoncache_promote_double(dynarec_arm_t* dyn, int ninst, int a)
 {
-    int i = neoncache_get_current_st_f(dyn, a);
+    int i = neoncache_get_current_st_f_i64(dyn, a);
     //if(box64_dynarec_dump) dynarec_log(LOG_NONE, "neoncache_promote_double, ninst=%d a=%d st=%d i=%d\n", ninst, a, dyn->n.stack, i);
     if(i<0) return;
     dyn->n.neoncache[i].t = NEON_CACHE_ST_D;
@@ -273,6 +300,10 @@ int neoncache_combine_st(dynarec_arm_t* dyn, int ninst, int a, int b)
     if( neoncache_get_current_st(dyn, ninst, a)==NEON_CACHE_ST_F
      && neoncache_get_current_st(dyn, ninst, b)==NEON_CACHE_ST_F )
         return NEON_CACHE_ST_F;
+    // don't combine i64, it's only for load/store
+    /*if( neoncache_get_current_st(dyn, ninst, a)==NEON_CACHE_ST_I64
+     && neoncache_get_current_st(dyn, ninst, b)==NEON_CACHE_ST_I64 )
+        return NEON_CACHE_ST_I64;*/
     return NEON_CACHE_ST_D;
 }
 
@@ -283,7 +314,9 @@ static int isCacheEmpty(dynarec_native_t* dyn, int ninst) {
     for(int i=0; i<24; ++i)
         if(dyn->insts[ninst].n.neoncache[i].v) {       // there is something at ninst for i
             if(!(
-            (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D)
+            (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F 
+             || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D
+             || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_I64)
             && dyn->insts[ninst].n.neoncache[i].n<dyn->insts[ninst].n.stack_pop))
                 return 0;
         }
@@ -306,7 +339,9 @@ int fpuCacheNeedsTransform(dynarec_arm_t* dyn, int ninst) {
         for(int i=0; i<24 && !ret; ++i)
             if(dyn->insts[ninst].n.neoncache[i].v) {       // there is something at ninst for i
                 if(!(
-                (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D)
+                (dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_F 
+                || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_D
+                || dyn->insts[ninst].n.neoncache[i].t==NEON_CACHE_ST_I64)
                 && dyn->insts[ninst].n.neoncache[i].n<dyn->insts[ninst].n.stack_pop))
                     ret = 1;
             }
@@ -345,7 +380,7 @@ void neoncacheUnwind(neoncache_t* cache)
         int a = -1; 
         int b = -1;
         for(int j=0; j<24 && ((a==-1) || (b==-1)); ++j)
-            if((cache->neoncache[j].t == NEON_CACHE_ST_D || cache->neoncache[j].t == NEON_CACHE_ST_F)) {
+            if((cache->neoncache[j].t == NEON_CACHE_ST_D || cache->neoncache[j].t == NEON_CACHE_ST_F || cache->neoncache[j].t == NEON_CACHE_ST_I64)) {
                 if(cache->neoncache[j].n == cache->combined1)
                     a = j;
                 else if(cache->neoncache[j].n == cache->combined2)
@@ -369,7 +404,7 @@ void neoncacheUnwind(neoncache_t* cache)
     if(cache->stack_push) {
         // unpush
         for(int j=0; j<24; ++j) {
-            if((cache->neoncache[j].t == NEON_CACHE_ST_D || cache->neoncache[j].t == NEON_CACHE_ST_F)) {
+            if((cache->neoncache[j].t == NEON_CACHE_ST_D || cache->neoncache[j].t == NEON_CACHE_ST_F || cache->neoncache[j].t == NEON_CACHE_ST_I64)) {
                 if(cache->neoncache[j].n<cache->stack_push)
                     cache->neoncache[j].v = 0;
                 else
@@ -414,6 +449,7 @@ void neoncacheUnwind(neoncache_t* cache)
                     break;
                 case NEON_CACHE_ST_F:
                 case NEON_CACHE_ST_D:
+                case NEON_CACHE_ST_I64:
                     cache->x87cache[x87reg] = cache->neoncache[i].n;
                     cache->x87reg[x87reg] = i;
                     ++x87reg;
@@ -479,6 +515,7 @@ const char* getCacheName(int t, int n)
     switch(t) {
         case NEON_CACHE_ST_D: sprintf(buff, "ST%d", n); break;
         case NEON_CACHE_ST_F: sprintf(buff, "st%d", n); break;
+        case NEON_CACHE_ST_I64: sprintf(buff, "STi%d", n); break;
         case NEON_CACHE_MM: sprintf(buff, "MM%d", n); break;
         case NEON_CACHE_XMMW: sprintf(buff, "XMM%d", n); break;
         case NEON_CACHE_XMMR: sprintf(buff, "xmm%d", n); break;
@@ -488,10 +525,10 @@ const char* getCacheName(int t, int n)
     return buff;
 }
 
-void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name)
+void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
 {
     if(box64_dynarec_dump) {
-        printf_x64_instruction(my_context->dec, &dyn->insts[ninst].x64, name);
+        printf_x64_instruction(rex.is32bits?my_context->dec32:my_context->dec, &dyn->insts[ninst].x64, name);
         dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d/%d",
             (box64_dynarec_dump>1)?"\e[32m":"",
             (void*)(dyn->native_start+dyn->insts[ninst].address),
@@ -523,6 +560,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name)
             switch(dyn->insts[ninst].n.neoncache[ii].t) {
                 case NEON_CACHE_ST_D: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
                 case NEON_CACHE_ST_F: dynarec_log(LOG_NONE, " S%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+                case NEON_CACHE_ST_I64: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
                 case NEON_CACHE_MM: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
                 case NEON_CACHE_XMMW: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
                 case NEON_CACHE_XMMR: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;