Skip to content

Commit

Permalink
[DYNAREC] Added BOX86_DYNAREC_FORWARD parameter, with a default value…
Browse files Browse the repository at this point in the history
… to 128 (unfortunatly, it doesn't seems to help performances much on box86)
  • Loading branch information
ptitSeb committed Mar 7, 2023
1 parent a320c37 commit a4752af
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 12 deletions.
5 changes: 5 additions & 0 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ Enables/Disables Box86's Dynarec building BigBlock.
* 1 : Build Dynarec block as big as possible (Default.)
* 2 : Build Dynarec block bigger (don't stop when block overlaps)

#### BOX86_DYNAREC_FORWARD *
Define Box86's Dynarec max allowed forward value when building Block.
* 0 : No forward value. When current block end, don't try to go further even if there are previous forward jumps
* XXX : Allow up to XXXX bytes of gap when building a Block after the block end to next forward jump (Default: 128)

#### BOX86_DYNAREC_STRONGMEM *
Enable/Disable simulation of Strong Memory model
* 0 : Don't try anything special (Default.)
Expand Down
9 changes: 6 additions & 3 deletions src/dynarec/dynarec_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,12 +298,15 @@ static void fillPredecessors(dynarec_arm_t* dyn)
}
// fill pred
for(int i=0; i<dyn->size; ++i) {
if(i!=dyn->size-1 && dyn->insts[i].x86.has_next && (!i || dyn->insts[i].pred_sz))
if((i!=dyn->size-1) && dyn->insts[i].x86.has_next)
dyn->insts[i+1].pred[dyn->insts[i+1].pred_sz++] = i;
if(dyn->insts[i].x86.jmp && dyn->insts[i].x86.jmp_insts!=-1)
dyn->insts[dyn->insts[i].x86.jmp_insts].pred[dyn->insts[dyn->insts[i].x86.jmp_insts].pred_sz++] = i;
if(dyn->insts[i].x86.jmp && (dyn->insts[i].x86.jmp_insts!=-1)) {
int j = dyn->insts[i].x86.jmp_insts;
dyn->insts[j].pred[dyn->insts[j].pred_sz++] = i;
}
}


}

// updateNeed goes backward, from last intruction to top
Expand Down
47 changes: 39 additions & 8 deletions src/dynarec/dynarec_arm_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "dynarec_arm_functions.h"
#include "dynarec_arm_helper.h"
#include "custommem.h"
#include "elfloader.h"

#ifndef STEP
#error No STEP defined
Expand All @@ -39,9 +40,13 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
// Clean up (because there are multiple passes)
dyn->f.pending = 0;
dyn->f.dfnone = 0;
dyn->forward = 0;
dyn->forward_to = 0;
dyn->forward_size = 0;
dyn->forward_ninst = 0;
fpu_reset(dyn);
int reset_n = -1;
// ok, go now
int stopblock = 2+(FindElfAddress(my_context, addr)?0:1); // if block is in elf_memory, it can be extended with bligblocks==2, else it needs 3 // ok, go now
INIT;
while(ok) {
ip = addr;
Expand Down Expand Up @@ -178,13 +183,33 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
#ifndef PROT_READ
#define PROT_READ 1
#endif
if(!ok && !need_epilog && box86_dynarec_bigblock && (getProtection(addr+3)&PROT_READ))
if(dyn->forward) {
if(dyn->forward_to == addr) {
// we made it!
if(box86_dynarec_dump) dynarec_log(LOG_NONE, "Forward extend block %p -> %p\n", (void*)dyn->forward, (void*)dyn->forward_to);
dyn->forward = 0;
dyn->forward_to = 0;
dyn->forward_size = 0;
dyn->forward_ninst = 0;
} else if ((dyn->forward_to < addr) || !ok) {
// something when wrong! rollback
if(box86_dynarec_dump) dynarec_log(LOG_NONE, "Could not forward extend block %p -> %p\n", (void*)dyn->forward, (void*)dyn->forward_to);
ok = 0;
dyn->size = dyn->forward_size;
ninst = dyn->forward_ninst;
addr = dyn->forward;
dyn->forward = 0;
dyn->forward_to = 0;
dyn->forward_size = 0;
dyn->forward_ninst = 0;
}
// else just continue
} else if(!ok && !need_epilog && box86_dynarec_bigblock && (getProtection(addr+3)&PROT_READ))
if(*(uint32_t*)addr!=0) { // check if need to continue (but is next 4 bytes are 0, stop)
uintptr_t next = get_closest_next(dyn, addr);
if(next && (
(((next-addr)<15) && is_nops(dyn, addr, next-addr))
&& (((box86_dynarec_bigblock<2) && isJumpTableDefault((void*)next)) || (box86_dynarec_bigblock>1))
/*||(((next-addr)<30) && is_instructions(dyn, addr, next-addr))*/ ))
/*&& box86_dynarec_bigblock*/))
{
ok = 1;
// need to find back that instruction to copy the caches, as previous version cannot be used anymore
Expand All @@ -195,17 +220,23 @@ uintptr_t arm_pass(dynarec_arm_t* dyn, uintptr_t addr)
ii=ninst;
}
if(box86_dynarec_dump) dynarec_log(LOG_NONE, "Extend block %p, %p -> %p (ninst=%d, jump from %d)\n", dyn, (void*)addr, (void*)next, ninst, reset_n);
} else if(next && (next-addr)<30) {
if(box86_dynarec_dump) dynarec_log(LOG_NONE, "Cannot extend block %p -> %p (%02X %02X %02X %02X %02X %02X %02X %02x)\n", (void*)addr, (void*)next, PK(0), PK(1), PK(2), PK(3), PK(4), PK(5), PK(6), PK(7));
} else if(next && (next-addr<box86_dynarec_forward)
&& (getProtection(next)&PROT_READ)/*box86_dynarec_bigblock>=forwardblock*/) {
dyn->forward = addr;
dyn->forward_to = next;
dyn->forward_size = dyn->size;
dyn->forward_ninst = ninst;
reset_n = -2;
ok = 1;
}
}
#endif
if(ok<0) {ok = 0; need_epilog=1;}
++ninst;
#if STEP == 0
if(ok && (((box86_dynarec_bigblock<2) && !isJumpTableDefault((void*)addr))
if(ok && (((box86_dynarec_bigblock<stopblock) && !isJumpTableDefault((void*)addr))
|| (addr>=box86_nodynarec_start && addr<box86_nodynarec_end)
|| (dyn->size >= 2000)))
/*|| (dyn->size >= 2000)*/)) // is this still needed? maybe it should be a parameter?
#else
if(ok && (ninst==dyn->size))
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/dynarec/dynarec_arm_pass0.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#define INST_EPILOG \
dyn->insts[ninst].f_exit = dyn->f; \
dyn->insts[ninst].n = dyn->n; \
dyn->insts[ninst].x86.has_next = ok;
dyn->insts[ninst].x86.has_next = (ok>0)?1:0;
#define INST_NAME(name)
#define DEFAULT \
--dyn->size; \
Expand Down
4 changes: 4 additions & 0 deletions src/dynarec/dynarec_arm_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ typedef struct dynarec_arm_s {
dynablock_t* dynablock;
uint8_t smread; // for strongmem model emulation
uint8_t smwrite; // for strongmem model emulation
uintptr_t forward; // address of the last end of code while testing forward
uintptr_t forward_to; // address of the next jump to (to check if everything is ok)
int32_t forward_size; // size at the forward point
int forward_ninst; // ninst at the forward point
} dynarec_arm_t;

void add_next(dynarec_arm_t *dyn, uintptr_t addr);
Expand Down
1 change: 1 addition & 0 deletions src/include/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern int box86_dynarec_trace;
extern int box86_dynarec_forced;
extern int box86_dynarec_largest;
extern int box86_dynarec_bigblock;
extern int box86_dynarec_forward;
extern int box86_dynarec_strongmem;
extern int box86_dynarec_x87double;
extern int box86_dynarec_safeflags;
Expand Down
13 changes: 13 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ int box86_dynarec_dump = 0;
int box86_dynarec_forced = 0;
int box86_dynarec_largest = 0;
int box86_dynarec_bigblock = 1;
int box86_dynarec_forward = 128;
int box86_dynarec_strongmem = 0;
int box86_dynarec_x87double = 0;
int box86_dynarec_fastnan = 1;
Expand Down Expand Up @@ -355,6 +356,18 @@ void LoadLogEnv()
else if (box86_dynarec_bigblock>1)
printf_log(LOG_INFO, "Dynarec will try to make bigger blocks\n");
}
p = getenv("BOX86_DYNAREC_FORWARD");
if(p) {
int val = -1;
if(sscanf(p, "%d", &val)==1) {
if(val>=0)
box86_dynarec_forward = val;
}
if(box86_dynarec_forward)
printf_log(LOG_INFO, "Dynarec will continue block for %d bytes on forward jump\n", box86_dynarec_forward);
else
printf_log(LOG_INFO, "Dynarec will not continue block on forward jump\n");
}
p = getenv("BOX86_DYNAREC_STRONGMEM");
if(p) {
if(strlen(p)==1) {
Expand Down
9 changes: 9 additions & 0 deletions src/tools/rcfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ ENTRYBOOL(BOX86_DYNAREC, box86_dynarec) \
ENTRYINT(BOX86_DYNAREC_DUMP, box86_dynarec_dump, 0, 2, 2) \
ENTRYINT(BOX86_DYNAREC_LOG, box86_dynarec_log, 0, 3, 2) \
ENTRYINT(BOX86_DYNAREC_BIGBLOCK, box86_dynarec_bigblock, 0, 3, 2) \
ENTRYSTRING_(BOX86_DYNAREC_FORWARD, box86_dynarec_forward) \
ENTRYINT(BOX86_DYNAREC_STRONGMEM, box86_dynarec_strongmem, 0, 2, 2) \
ENTRYBOOL(BOX86_DYNAREC_X87DOUBLE, box86_dynarec_x87double) \
ENTRYBOOL(BOX86_DYNAREC_FASTNAN, box86_dynarec_fastnan) \
Expand All @@ -89,6 +90,7 @@ IGNORE(BOX86_DYNAREC) \
IGNORE(BOX86_DYNAREC_DUMP) \
IGNORE(BOX86_DYNAREC_LOG) \
IGNORE(BOX86_DYNAREC_BIGBLOCK) \
IGNORE(BOX64_DYNAREC_FORWARD) \
IGNORE(BOX86_DYNAREC_STRONGMEM) \
IGNORE(BOX86_DYNAREC_X87DOUBLE) \
IGNORE(BOX86_DYNAREC_FASTNAN) \
Expand Down Expand Up @@ -498,6 +500,13 @@ void ApplyParams(const char* name, path_collection_t* preload)
}
}
}
if(param->is_box86_dynarec_forward_present) {
int forward = 0;
if(sscanf(param->box86_dynarec_forward, "%d", &forward)==1) {
box86_dynarec_forward = forward;
printf_log(LOG_INFO, "Appling BOX86_DYNAREC_FORWARD=%d\n", box86_dynarec_forward);
}
}
if(!olddynarec && box86_dynarec)
GatherDynarecExtensions();
#endif
Expand Down
17 changes: 17 additions & 0 deletions system/box86.box86rc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
# Those are safe to use on 7z and give a bit of a boost
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512

[7zz]
# Those are safe to use on 7z and give a bit of a boost
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512

[A_Golden_Wake.bin.x86]
BOX86_PREFER_EMULATED=1
Expand All @@ -34,10 +41,15 @@ BOX86_PREFER_EMULATED=1
[hl2_linux]
#it seems emulated SDL2 have mouse issue for now. That might be a problem with box86
#BOX86_PREFER_EMULATED=1
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512


[retrocityrampage]
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512

[sof-bin]
BOX86_LD_PRELOAD=libX11.so.6
Expand All @@ -54,16 +66,19 @@ BOX86_EMULATED_LIBS=libSDL2-2.0.so.0:libSDL2_ttf-2.0.so.0
[UnrealLinux.bin]
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512

[WorldOfGoo.bin.x86]
# This is the newer 1.53 version
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512

[WorldOfGoo.bin32]
# This is the old version of the game
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512

[X3R_main]
# X3Reunion needs emulated libjpeg
Expand All @@ -72,6 +87,7 @@ BOX86_EMULATED_LIBS=libjpeg.so.62
[zsnes]
BOX86_DYNAREC_SAFEFLAGS=0
BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_FORWARD=512


#
Expand All @@ -83,6 +99,7 @@ BOX86_DYNAREC_BIGBLOCK=2
BOX86_DYNAREC_X87DOUBLE=1
BOX86_DYNAREC_SAFEFLAGS=0 # this will help perf a bit
BOX86_DYNAREC_BIGBLOCK=3 # Wine app will need 3 for bigblock to do anything
BOX86_DYNAREC_FORWARD=512

[VARA.exe]
BOX86_DYNAREC_SAFEFLAGS=2
Expand Down

0 comments on commit a4752af

Please sign in to comment.