diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/dynarec_arch.h | 13 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_functions.c | 67 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_functions.h | 3 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.c | 19 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_pass0.h | 13 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_pass1.h | 12 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_functions.c | 2 | ||||
| -rw-r--r-- | src/include/dynarec_la64.h | 10 | ||||
| -rw-r--r-- | src/include/dynarec_rv64.h | 10 |
9 files changed, 103 insertions, 46 deletions
diff --git a/src/dynarec/dynarec_arch.h b/src/dynarec/dynarec_arch.h index 26207428..f89125a7 100644 --- a/src/dynarec/dynarec_arch.h +++ b/src/dynarec/dynarec_arch.h @@ -22,16 +22,17 @@ #define instruction_native_t instruction_la64_t #define dynarec_native_t dynarec_la64_t -#define ADDITIONNAL_DEFINITION() +#define ADDITIONNAL_DEFINITION() \ + int fpuCacheNeedsTransform(dynarec_native_t* dyn, int ninst); -// TODO -#define OTHER_CACHE() +#define OTHER_CACHE() \ + if (fpuCacheNeedsTransform(dyn, ninst)) ret |= 2; #include "la64/la64_printer.h" #include "la64/dynarec_la64_private.h" #include "la64/dynarec_la64_functions.h" -// TODO -#define MAXBLOCK_SIZE ((1<<19)-200) +// Limit here is unconditionnal jump, that is signed 28bits +#define MAXBLOCK_SIZE ((1 << 27) - 200) #elif defined(RV64) #define instruction_native_t instruction_rv64_t @@ -46,7 +47,7 @@ #include "rv64/rv64_printer.h" #include "rv64/dynarec_rv64_private.h" #include "rv64/dynarec_rv64_functions.h" -// Limit here is unconditionnal jump, thjat is signed 21bits +// Limit here is unconditionnal jump, that is signed 21bits #define MAXBLOCK_SIZE ((1<<20)-200) #else #error Unsupported platform diff --git a/src/dynarec/la64/dynarec_la64_functions.c b/src/dynarec/la64/dynarec_la64_functions.c index 01eaee06..7568b453 100644 --- a/src/dynarec/la64/dynarec_la64_functions.c +++ b/src/dynarec/la64/dynarec_la64_functions.c @@ -20,7 +20,7 @@ #include "emu/x87emu_private.h" #include "x64trace.h" #include "signals.h" -#include "dynarec_la64.h" +#include "dynarec_native.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" #include "custommem.h" @@ -82,6 +82,71 @@ void fpu_reset_reg(dynarec_la64_t* dyn) fpu_reset_reg_lsxcache(&dyn->lsx); } +static int isCacheEmpty(dynarec_native_t* dyn, int ninst) +{ + if (dyn->insts[ninst].lsx.stack_next) { + return 0; + } + for (int i = 0; i < 24; ++i) + if (dyn->insts[ninst].lsx.lsxcache[i].v) { // there is something at ninst for i + if (!( + (dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_ST_F + || dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_ST_D + || dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_ST_I64) + && dyn->insts[ninst].lsx.lsxcache[i].n < dyn->insts[ninst].lsx.stack_pop)) + return 0; + } + return 1; +} + +int fpuCacheNeedsTransform(dynarec_la64_t* dyn, int ninst) +{ + int i2 = dyn->insts[ninst].x64.jmp_insts; + if (i2 < 0) + return 1; + if ((dyn->insts[i2].x64.barrier & BARRIER_FLOAT)) + // if the barrier as already been apply, no transform needed + return ((dyn->insts[ninst].x64.barrier & BARRIER_FLOAT)) ? 0 : (isCacheEmpty(dyn, ninst) ? 0 : 1); + int ret = 0; + if (!i2) { // just purge + if (dyn->insts[ninst].lsx.stack_next) { + return 1; + } + for (int i = 0; i < 24 && !ret; ++i) + if (dyn->insts[ninst].lsx.lsxcache[i].v) { // there is something at ninst for i + if (!( + (dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_ST_F + || dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_ST_D + || dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_ST_I64) + && dyn->insts[ninst].lsx.lsxcache[i].n < dyn->insts[ninst].lsx.stack_pop)) + ret = 1; + } + return ret; + } + // Check if ninst can be compatible to i2 + if (dyn->insts[ninst].lsx.stack_next != dyn->insts[i2].lsx.stack - dyn->insts[i2].lsx.stack_push) { + return 1; + } + lsxcache_t cache_i2 = dyn->insts[i2].lsx; + lsxcacheUnwind(&cache_i2); + + for (int i = 0; i < 24; ++i) { + if (dyn->insts[ninst].lsx.lsxcache[i].v) { // there is something at ninst for i + if (!cache_i2.lsxcache[i].v) { // but there is nothing at i2 for i + ret = 1; + } else if (dyn->insts[ninst].lsx.lsxcache[i].v != cache_i2.lsxcache[i].v) { // there is something different + if (dyn->insts[ninst].lsx.lsxcache[i].n != cache_i2.lsxcache[i].n) { // not the same x64 reg + ret = 1; + } else if (dyn->insts[ninst].lsx.lsxcache[i].t == LSX_CACHE_XMMR && cache_i2.lsxcache[i].t == LSX_CACHE_XMMW) { /* nothing */ + } else + ret = 1; + } + } else if (cache_i2.lsxcache[i].v) + ret = 1; + } + return ret; +} + void lsxcacheUnwind(lsxcache_t* cache) { if (cache->swapped) { diff --git a/src/dynarec/la64/dynarec_la64_functions.h b/src/dynarec/la64/dynarec_la64_functions.h index 2badba4d..b674983f 100644 --- a/src/dynarec/la64/dynarec_la64_functions.h +++ b/src/dynarec/la64/dynarec_la64_functions.h @@ -19,6 +19,9 @@ void fpu_free_reg(dynarec_la64_t* dyn, int reg); // Reset fpu regs counter void fpu_reset_reg(dynarec_la64_t* dyn); +// FPU Cache transformation (for loops) // Specific, need to be written by backend +int fpuCacheNeedsTransform(dynarec_la64_t* dyn, int ninst); + // Undo the changes of a lsxcache to get the status before the instruction void lsxcacheUnwind(lsxcache_t* cache); diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index 917b0d6c..8965002d 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -10,6 +10,7 @@ #include "dynarec.h" #include "emu/x64emu_private.h" #include "emu/x64run_private.h" +#include "la64_emitter.h" #include "x64run.h" #include "x64emu.h" #include "box64stack.h" @@ -25,6 +26,8 @@ #include "dynarec_la64_functions.h" #include "dynarec_la64_helper.h" +#define SCRATCH 31 + static uintptr_t geted_32(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, int* l, int i12); /* setup r2 to address pointed by ED, also fixaddress is an optionnal delta in the range [-absmax, +absmax], with delta&mask==0 to be added to ed for LDR/STR */ @@ -848,7 +851,6 @@ static void swapCache(dynarec_la64_t* dyn, int ninst, int i, int j, lsxcache_t* MESSAGE(LOG_DUMP, "\t - Swapping %d <-> %d\n", i, j); // There is no VSWP in Arm64 NEON to swap 2 register contents! // so use a scratch... -#define SCRATCH 31 if (quad) { VOR_V(SCRATCH, i, i); VOR_V(i, j, j); @@ -861,7 +863,6 @@ static void swapCache(dynarec_la64_t* dyn, int ninst, int i, int j, lsxcache_t* VXOR_V(j, j, j); VEXTRINS_D(j, SCRATCH, 0); } -#undef SCRATCH tmp.v = cache->lsxcache[i].v; cache->lsxcache[i].v = cache->lsxcache[j].v; cache->lsxcache[j].v = tmp.v; @@ -895,7 +896,9 @@ static void loadCache(dynarec_la64_t* dyn, int ninst, int stack_cnt, int s1, int break; case LSX_CACHE_MM: MESSAGE(LOG_DUMP, "\t - Loading %s\n", getCacheName(t, n)); - VLD(i, xEmu, offsetof(x64emu_t, mmx[n])); + FLD_D(SCRATCH, xEmu, offsetof(x64emu_t, mmx[n])); + VXOR_V(i, i, i); + VEXTRINS_D(i, SCRATCH, 0); break; case LSX_CACHE_ST_D: case LSX_CACHE_ST_F: @@ -925,7 +928,7 @@ static void unloadCache(dynarec_la64_t* dyn, int ninst, int stack_cnt, int s1, i break; case LSX_CACHE_MM: MESSAGE(LOG_DUMP, "\t - Unloading %s\n", getCacheName(t, n)); - VST(i, xEmu, offsetof(x64emu_t, mmx[n])); + FST_D(i, xEmu, offsetof(x64emu_t, mmx[n])); break; case LSX_CACHE_ST_D: case LSX_CACHE_ST_F: @@ -1070,7 +1073,7 @@ static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1) if(dyn->f.dfnone) // flags are fully known, nothing we can do more return; MESSAGE(LOG_DUMP, "\tFlags fetch ---- ninst=%d -> %d\n", ninst, jmp); - int go = 0; + int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone)?1:0; switch (dyn->insts[jmp].f_entry.pending) { case SF_UNKNOWN: break; case SF_SET: @@ -1088,12 +1091,10 @@ static void flagsCacheTransform(dynarec_la64_t* dyn, int ninst, int s1) && dyn->f.pending!=SF_SET_PENDING && dyn->f.pending!=SF_PENDING) go = 1; - else - go = (dyn->insts[jmp].f_entry.dfnone == dyn->f.dfnone)?0:1; + else if (dyn->insts[jmp].f_entry.dfnone !=dyn->f.dfnone) + go = 1; break; } - if(dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone) - go = 1; if(go) { if(dyn->f.pending!=SF_PENDING) { LD_W(s1, xEmu, offsetof(x64emu_t, df)); diff --git a/src/dynarec/la64/dynarec_la64_pass0.h b/src/dynarec/la64/dynarec_la64_pass0.h index 1eef76bf..99a897a6 100644 --- a/src/dynarec/la64/dynarec_la64_pass0.h +++ b/src/dynarec/la64/dynarec_la64_pass0.h @@ -24,14 +24,17 @@ } else \ dyn->insts[ninst].barrier_maybe = 1 #define SET_HASCALLRET() dyn->insts[ninst].x64.has_callret = 1 -#define NEW_INST \ - ++dyn->size; \ - memset(&dyn->insts[ninst], 0, sizeof(instruction_native_t)); \ - dyn->insts[ninst].x64.addr = ip; \ - dyn->insts[ninst].f_entry = dyn->f; \ +#define NEW_INST \ + ++dyn->size; \ + dyn->insts[ninst].x64.addr = ip; \ + dyn->lsx.combined1 = dyn->lsx.combined2 = 0; \ + dyn->lsx.swapped = 0; \ + dyn->lsx.barrier = 0; \ + dyn->insts[ninst].f_entry = dyn->f; \ if (ninst) { dyn->insts[ninst - 1].x64.size = dyn->insts[ninst].x64.addr - dyn->insts[ninst - 1].x64.addr; } #define INST_EPILOG \ dyn->insts[ninst].f_exit = dyn->f; \ + dyn->insts[ninst].lsx = dyn->lsx; \ dyn->insts[ninst].x64.has_next = (ok > 0) ? 1 : 0; #define INST_NAME(name) #define DEFAULT \ diff --git a/src/dynarec/la64/dynarec_la64_pass1.h b/src/dynarec/la64/dynarec_la64_pass1.h index 7d616b22..af69ceca 100644 --- a/src/dynarec/la64/dynarec_la64_pass1.h +++ b/src/dynarec/la64/dynarec_la64_pass1.h @@ -2,10 +2,14 @@ #define FINI #define MESSAGE(A, ...) #define EMIT(A) -#define NEW_INST \ - dyn->insts[ninst].f_entry = dyn->f; +#define NEW_INST \ + dyn->insts[ninst].f_entry = dyn->f; \ + dyn->lsx.combined1 = dyn->lsx.combined2 = 0; \ + dyn->lsx.swapped = 0; \ + dyn->lsx.barrier = 0 -#define INST_EPILOG \ +#define INST_EPILOG \ + dyn->insts[ninst].lsx = dyn->lsx; \ dyn->insts[ninst].f_exit = dyn->f -#define INST_NAME(name) \ No newline at end of file +#define INST_NAME(name) diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c index b016e45b..9965b438 100644 --- a/src/dynarec/rv64/dynarec_rv64_functions.c +++ b/src/dynarec/rv64/dynarec_rv64_functions.c @@ -20,7 +20,7 @@ #include "emu/x87emu_private.h" #include "x64trace.h" #include "signals.h" -#include "dynarec_rv64.h" +#include "dynarec_native.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" #include "custommem.h" diff --git a/src/include/dynarec_la64.h b/src/include/dynarec_la64.h deleted file mode 100644 index cf8946f0..00000000 --- a/src/include/dynarec_la64.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __DYNAREC_LA64_H_ -#define __DYNAREC_LA64_H_ - -typedef struct dynablock_s dynablock_t; -typedef struct x64emu_s x64emu_t; - -void CancelBlock64(void); -void* FillBlock64(dynablock_t* block, uintptr_t addr); - -#endif //__DYNAREC_LA64_H_ \ No newline at end of file diff --git a/src/include/dynarec_rv64.h b/src/include/dynarec_rv64.h deleted file mode 100644 index dd3b734e..00000000 --- a/src/include/dynarec_rv64.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __DYNAREC_RV64_H_ -#define __DYNAREC_RV64_H_ - -typedef struct dynablock_s dynablock_t; -typedef struct x64emu_s x64emu_t; - -void CancelBlock64(void); -void* FillBlock64(dynablock_t* block, uintptr_t addr); - -#endif //__DYNAREC_RV64_H_ \ No newline at end of file |