diff options
Diffstat (limited to 'src/dynarec/arm64/dynarec_arm64_functions.c')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_functions.c | 68 |
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; |