mirror of
https://github.com/ptitSeb/box64.git
synced 2026-11-08 17:39:19 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9243ea4ca1 | ||
|
|
2e871fc68a | ||
|
|
30eb08f8af | ||
|
|
7f51495877 | ||
|
|
112bc0d83f | ||
|
|
501a4a8956 | ||
|
|
bb4c06f107 | ||
|
|
65fae1077f | ||
|
|
e3a36591aa | ||
|
|
a597f6701f | ||
|
|
3b19a7fe1d | ||
|
|
ccf9775658 | ||
|
|
762a499648 | ||
|
|
aa56188e7e | ||
|
|
1d92e65fcc | ||
|
|
a6f132f6da | ||
|
|
cb75b670b6 | ||
|
|
7bb9dd18da | ||
|
|
140254f311 | ||
|
|
56401f6675 | ||
|
|
99ba7707f6 | ||
|
|
ea1ef4e602 | ||
|
|
78b6113d8b |
No files matched your search
@@ -1,3 +1,12 @@
|
||||
v0.1.2
|
||||
======
|
||||
* OpenSource!
|
||||
* A few more opcode added to the Interpretor and the Dynarec
|
||||
* Improved Native Function calling
|
||||
* Added some function to limit allocated memory to 47bits space (for Wine)
|
||||
* Improved and Fixed the functions to limit allocated memory to 32bits space
|
||||
* Wine is starting now, but not everything and every version works
|
||||
|
||||
v0.1.0
|
||||
======
|
||||
* Improvement to ElfLoader
|
||||
|
||||
+8
-2
@@ -7,7 +7,7 @@ option(RK3326 "Set to ON if targeting an Rockchip RK3326 based device" ${RK3326}
|
||||
option(RK3399 "Set to ON if targeting an Rockchip RK3399 based device" ${RK3399})
|
||||
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
|
||||
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
|
||||
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box64" ${NO_LOADAADR})
|
||||
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box64" OFF)
|
||||
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
|
||||
if(RK3399 OR RPI4ARM64 OR RK3326)
|
||||
set(LD80BITS OFF CACHE BOOL "")
|
||||
@@ -74,7 +74,8 @@ else()
|
||||
set(BOX64 box64)
|
||||
endif()
|
||||
|
||||
set(BOX64_ELF_ADDRESS "0x500062800000") #random load address...
|
||||
#set(BOX64_ELF_ADDRESS "0x500062800000") #random load address...
|
||||
set(BOX64_ELF_ADDRESS "0x64800000") #low address
|
||||
|
||||
if(LD80BITS)
|
||||
add_definitions(-DHAVE_LD80BITS)
|
||||
@@ -513,6 +514,11 @@ add_test(test16 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref16.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
add_test(test17 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64}
|
||||
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test17 -D TEST_OUTPUT=tmpfile.txt
|
||||
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref17.txt
|
||||
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
|
||||
|
||||
file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c")
|
||||
foreach(file ${extension_tests})
|
||||
get_filename_component(testname "${file}" NAME_WE)
|
||||
|
||||
@@ -7,9 +7,11 @@ Linux Userspace x86_64 Emulator with a twist
|
||||
|
||||
Box64 lets you run x86_64 Linux programs (such as games) on non-x86_64 Linux systems, like ARM (host system needs to be 64bit little-endian).
|
||||
|
||||
Because Box64 uses the native versions of some "system" libraries, like libc, libm, SDL, and OpenGL, it's easy to integrate and use with most applications, and performance can be surprisingly high in some cases.
|
||||
You can find many more Box64 video on Youtube in the [MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ), [Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g) or [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA) Channels
|
||||
|
||||
Box64 integrates a DynaRec (dynamic recompiler) for the ARM64 platform, providing a speed boost between 5 to 10 times faster than only using the interpreter.
|
||||
Because Box64 uses the native versions of some "system" libraries, like libc, libm, SDL, and OpenGL, it's easy to integrate and use with most applications, and performance can be surprisingly high in many cases. Take a look at thoses bench analysis for an example [here](https://box86.org/index.php/2021/06/game-performances/).
|
||||
|
||||
Box64 integrates a DynaRec (dynamic recompiler) for the ARM64 platform, providing a speed boost between 5 to 10 times faster than only using the interpreter. Some high level information on how the Dynarec work can be found [here](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/).
|
||||
|
||||
Some x86 internal opcodes use parts of "Realmode X86 Emulator Library", see [x86primop.c](src/emu/x86primop.c) for copyright details
|
||||
|
||||
|
||||
+7
-4
@@ -503,7 +503,7 @@ def main(root: str, files: Sequence[Filename], ver: str):
|
||||
pass
|
||||
|
||||
# Detect simple wrappings
|
||||
simple_wraps: Dict[ClausesStr, List[FunctionType]] = {}
|
||||
simple_wraps: Dict[ClausesStr, List[Tuple[FunctionType, int]]] = {}
|
||||
|
||||
# H could be allowed maybe?
|
||||
allowed_simply: str = "v"
|
||||
@@ -537,9 +537,12 @@ def main(root: str, files: Sequence[Filename], ver: str):
|
||||
break
|
||||
else:
|
||||
# No character in forbidden_simply
|
||||
if (regs_count <= 6) and (fpr_count <= 4):
|
||||
if (regs_count <= 6) and (fpr_count <= 8):
|
||||
# All checks passed!
|
||||
simple_wraps.setdefault(k, []).append(v)
|
||||
ret_val = 1 + fpr_count
|
||||
if v[0] in allowed_fpr:
|
||||
ret_val = -ret_val
|
||||
simple_wraps.setdefault(k, []).append((v, ret_val))
|
||||
simple_idxs = list(simple_wraps.keys())
|
||||
simple_idxs.sort(key=lambda x: Clauses(x).splitdef())
|
||||
|
||||
@@ -911,7 +914,7 @@ int isSimpleWrapper(wrapper_t fun);
|
||||
if k != "()":
|
||||
file.write("#if " + k + "\n")
|
||||
for v in simple_wraps[k]:
|
||||
file.write("\tif (fun == &" + v + ") return 1;\n")
|
||||
file.write("\tif (fun == &" + v[0] + ") return " + str(v[1]) + ";\n")
|
||||
if k != "()":
|
||||
file.write("#endif\n")
|
||||
file.write("\treturn 0;\n}\n")
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@
|
||||
|
||||
#define BOX64_MAJOR 0
|
||||
#define BOX64_MINOR 1
|
||||
#define BOX64_REVISION 0
|
||||
#define BOX64_REVISION 2
|
||||
|
||||
#endif //__BOX64_VERSION_H_
|
||||
+138
-33
@@ -826,6 +826,51 @@ void setProtection(uintptr_t addr, size_t size, uint32_t prot)
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
}
|
||||
|
||||
void allocProtection(uintptr_t addr, size_t size, uint32_t prot)
|
||||
{
|
||||
dynarec_log(LOG_DEBUG, "allocProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
|
||||
uintptr_t idx = (addr>>MEMPROT_SHIFT);
|
||||
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
|
||||
int ret;
|
||||
pthread_mutex_lock(&mutex_prot);
|
||||
for (uintptr_t i=idx; i<=end; ++i) {
|
||||
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
|
||||
khint_t k = kh_put(memprot, memprot, key, &ret);
|
||||
if(ret) {
|
||||
uint8_t *m = (uint8_t*)calloc(1, MEMPROT_SIZE);
|
||||
kh_value(memprot, k) = m;
|
||||
}
|
||||
const uintptr_t start = i&(MEMPROT_SIZE-1);
|
||||
const uintptr_t finish = (((i|(MEMPROT_SIZE-1))<end)?(MEMPROT_SIZE-1):end)&(MEMPROT_SIZE-1);
|
||||
uint8_t* block = kh_value(memprot, k);
|
||||
for(uintptr_t ii = start; ii<=finish; ++ii) {
|
||||
if(!block[ii])
|
||||
block[ii] = prot;
|
||||
}
|
||||
i+=finish-start; // +1 from the "for" loop
|
||||
}
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
}
|
||||
|
||||
void loadProtectionFromMap()
|
||||
{
|
||||
char buf[500];
|
||||
FILE *f = fopen("/proc/self/maps", "r");
|
||||
if(!f)
|
||||
return;
|
||||
while(!feof(f)) {
|
||||
char* ret = fgets(buf, sizeof(buf), f);
|
||||
(void)ret;
|
||||
char r, w, x;
|
||||
uintptr_t s, e;
|
||||
if(sscanf(buf, "%lx-%lx %c%c%c", &s, &e, &r, &w, &x)==5) {
|
||||
int prot = ((r=='r')?PROT_READ:0)|((w=='w')?PROT_WRITE:0)|((x=='x')?PROT_EXEC:0);
|
||||
allocProtection(s, e-s, prot);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static int blockempty(uint8_t* mem)
|
||||
{
|
||||
for (int i=0; i<(MEMPROT_SIZE); ++i)
|
||||
@@ -881,52 +926,112 @@ int availableBlock(uint8_t* p, size_t n)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static uintptr_t nextFree(uintptr_t addr)
|
||||
{
|
||||
do {
|
||||
const uint32_t key = (addr>>32)&0xffffffff;
|
||||
khint_t k = kh_get(memprot, memprot, key);
|
||||
if(k==kh_end(memprot)) {
|
||||
return addr;
|
||||
}
|
||||
uint8_t *block = kh_value(memprot, k);
|
||||
for (uintptr_t i=(addr&0xffffffffLL)>>MEMPROT_SHIFT; i<MEMPROT_SIZE; ++i)
|
||||
if(!block[i]) {
|
||||
return (addr&~0xffffffffLL)+(i<<MEMPROT_SHIFT);
|
||||
}
|
||||
addr += 0x100000000LL;
|
||||
addr &= ~0xffffffffLL;
|
||||
} while(1);
|
||||
}
|
||||
static uintptr_t maxFree(uintptr_t addr, uintptr_t sz)
|
||||
{
|
||||
uintptr_t mfree = 0;
|
||||
do {
|
||||
const uint32_t key = (addr>>32)&0xffffffff;
|
||||
khint_t k = kh_get(memprot, memprot, key);
|
||||
if(k==kh_end(memprot)) {
|
||||
mfree+=0x100000000LL;
|
||||
if(mfree>sz) {
|
||||
return addr;
|
||||
}
|
||||
} else {
|
||||
uint8_t *block = kh_value(memprot, k);
|
||||
for (uintptr_t i=(addr&0xffffffffLL)>>MEMPROT_SHIFT; i<MEMPROT_SIZE; ++i)
|
||||
if(!block[i]) {
|
||||
mfree+=1<<MEMPROT_SHIFT;
|
||||
} else
|
||||
return mfree;
|
||||
}
|
||||
addr += 0x100000000LL;
|
||||
addr &= ~0xffffffffLL;
|
||||
} while(1);
|
||||
}
|
||||
void* find32bitBlock(size_t size)
|
||||
{
|
||||
return findBlockNearHint(LOWEST, size);
|
||||
}
|
||||
void* find47bitBlock(size_t size)
|
||||
{
|
||||
// slow iterative search... Would need something better one day
|
||||
const uint32_t key = 0; // upper value is 0 by request
|
||||
uintptr_t addr = 0x100000000LL;
|
||||
pthread_mutex_lock(&mutex_prot);
|
||||
khint_t k = kh_get(memprot, memprot, key);
|
||||
if(k==kh_end(memprot)) {
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
return LOWEST;
|
||||
}
|
||||
uint8_t *prot = kh_val(memprot, k);
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
void* p = (void*)LOWEST;
|
||||
int pages = (size+MEMPROT_SIZE-1)>>MEMPROT_SHIFT;
|
||||
do {
|
||||
const uintptr_t idx = ((uintptr_t)p)>>MEMPROT_SHIFT;
|
||||
if(availableBlock(prot+idx, pages))
|
||||
return p;
|
||||
p += 0x10000;
|
||||
} while(p!=(void*)0xffff0000);
|
||||
addr = nextFree(addr);
|
||||
uintptr_t sz = maxFree(addr, size);
|
||||
if(sz>=size) {
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
return (void*)addr;
|
||||
}
|
||||
addr += sz;
|
||||
} while(addr<0x800000000000LL);
|
||||
// search in 32bits as a backup
|
||||
addr = (uintptr_t)LOWEST;
|
||||
do {
|
||||
addr = nextFree(addr);
|
||||
uintptr_t sz = maxFree(addr, size);
|
||||
if(sz>=size) {
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
return (void*)addr;
|
||||
}
|
||||
addr += sz;
|
||||
} while(addr<0x100000000LL);
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 47bits address space\n", size);
|
||||
return NULL;
|
||||
}
|
||||
void* find47bitBlockNearHint(void* hint, size_t size)
|
||||
{
|
||||
// slow iterative search... Would need something better one day
|
||||
uintptr_t addr = (uintptr_t)hint;
|
||||
pthread_mutex_lock(&mutex_prot);
|
||||
do {
|
||||
addr = nextFree(addr);
|
||||
uintptr_t sz = maxFree(addr, size);
|
||||
if(sz>=size) {
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
return (void*)addr;
|
||||
}
|
||||
addr += sz;
|
||||
} while(addr<0x800000000000LL);
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 32bits address space\n", size);
|
||||
return NULL;
|
||||
}
|
||||
void* findBlockNearHint(void* hint, size_t size)
|
||||
{
|
||||
// slow iterative search... Would need something better one day
|
||||
if(!hint) hint=LOWEST;
|
||||
const uint32_t key = (((uintptr_t)hint)>>32)&0xffffffff;
|
||||
uintptr_t addr = (uintptr_t)hint;
|
||||
pthread_mutex_lock(&mutex_prot);
|
||||
khint_t k = kh_get(memprot, memprot, key);
|
||||
if(k==kh_end(memprot)) {
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
return hint;
|
||||
}
|
||||
uint8_t *prot = kh_val(memprot, k);
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
void* p = hint;
|
||||
void* end = (void*)((uintptr_t)hint+0x100000000LL);
|
||||
uintptr_t step = (size+0xfff)&~0xfff;
|
||||
int pages = (size+MEMPROT_SIZE-1)>>MEMPROT_SHIFT;
|
||||
do {
|
||||
const uintptr_t idx = (((uintptr_t)p)&0xffffffff)>>MEMPROT_SHIFT;
|
||||
if(availableBlock(prot+idx, pages))
|
||||
return p;
|
||||
p += step;
|
||||
} while(p!=end);
|
||||
addr = nextFree(addr);
|
||||
uintptr_t sz = maxFree(addr, size);
|
||||
if(sz>=size) {
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
return (void*)addr;
|
||||
}
|
||||
addr += sz;
|
||||
} while(addr<0x100000000LL);
|
||||
pthread_mutex_unlock(&mutex_prot);
|
||||
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 32bits address space\n", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ arm64_next:
|
||||
stp x14, x15, [sp, (8 * 6)]
|
||||
stp x16, x17, [sp, (8 * 8)]
|
||||
str x18, [sp, (8 * 10)]
|
||||
|
||||
mov x2, lr // "from" is in lr, so put in x2
|
||||
// call the function
|
||||
bl LinkNext
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "dynarec_arm64_functions.h"
|
||||
#include "dynarec_arm64_helper.h"
|
||||
|
||||
int isSimpleWrapper(wrapper_t fun);
|
||||
|
||||
uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
|
||||
{
|
||||
uint8_t nextop, opcode;
|
||||
@@ -1556,19 +1558,26 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip)));
|
||||
x87_forget(dyn, ninst, x3, x4, 0);
|
||||
sse_purge07cache(dyn, ninst, x3);
|
||||
GETIP(ip+1); // read the 0xCC
|
||||
STORE_XEMU_CALL(xRIP);
|
||||
CALL_S(x64Int3, -1);
|
||||
LOAD_XEMU_CALL(xRIP);
|
||||
addr+=8+8;
|
||||
TABLE64(x3, addr); // expected return address
|
||||
CMPSx_REG(xRIP, x3);
|
||||
B_MARK(cNE);
|
||||
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
|
||||
CBZw_NEXT(w1);
|
||||
MARK;
|
||||
LOAD_XEMU_REM();
|
||||
jump_to_epilog(dyn, 0, xRIP, ninst);
|
||||
tmp = isSimpleWrapper(*(wrapper_t*)(addr));
|
||||
if(box64_log<2 && tmp) {
|
||||
//GETIP(ip+3+8+8); // read the 0xCC
|
||||
call_n(dyn, ninst, *(void**)(addr+8), tmp);
|
||||
addr+=8+8;
|
||||
} else {
|
||||
GETIP(ip+1); // read the 0xCC
|
||||
STORE_XEMU_CALL(xRIP);
|
||||
CALL_S(x64Int3, -1);
|
||||
LOAD_XEMU_CALL(xRIP);
|
||||
addr+=8+8;
|
||||
TABLE64(x3, addr); // expected return address
|
||||
CMPSx_REG(xRIP, x3);
|
||||
B_MARK(cNE);
|
||||
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
|
||||
CBZw_NEXT(w1);
|
||||
MARK;
|
||||
LOAD_XEMU_REM();
|
||||
jump_to_epilog(dyn, 0, xRIP, ninst);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#if 1
|
||||
@@ -1587,6 +1596,15 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xCF:
|
||||
INST_NAME("IRET");
|
||||
SETFLAGS(X_ALL, SF_SET); // Not a hack, EFLAGS are restored
|
||||
BARRIER(2);
|
||||
iret_to_epilog(dyn, ninst, rex.w);
|
||||
*need_epilog = 0;
|
||||
*ok = 0;
|
||||
break;
|
||||
case 0xD0:
|
||||
case 0xD2: // TODO: Jump if CL is 0
|
||||
nextop = F8;
|
||||
@@ -1979,26 +1997,32 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall-1)), dyn->insts[ninst].retn);
|
||||
// calling a native function
|
||||
sse_purge07cache(dyn, ninst, x3);
|
||||
GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already
|
||||
STORE_XEMU_CALL(xRIP);
|
||||
CALL_S(x64Int3, -1);
|
||||
LOAD_XEMU_CALL(xRIP);
|
||||
TABLE64(x3, dyn->insts[ninst].natcall);
|
||||
ADDx_U12(x3, x3, 2+8+8);
|
||||
CMPSx_REG(xRIP, x3);
|
||||
B_MARK(cNE); // Not the expected address, exit dynarec block
|
||||
POP1(xRIP); // pop the return address
|
||||
if(dyn->insts[ninst].retn) {
|
||||
ADDx_U12(xRSP, xRSP, dyn->insts[ninst].retn);
|
||||
if(box64_log<2 && dyn->insts && (tmp=isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2)))) {
|
||||
//GETIP(ip+3+8+8); // read the 0xCC
|
||||
call_n(dyn, ninst, *(void**)(dyn->insts[ninst].natcall+2+8), tmp);
|
||||
POP1(xRIP); // pop the return address
|
||||
} else {
|
||||
GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already
|
||||
STORE_XEMU_CALL(xRIP);
|
||||
CALL_S(x64Int3, -1);
|
||||
LOAD_XEMU_CALL(xRIP);
|
||||
TABLE64(x3, dyn->insts[ninst].natcall);
|
||||
ADDx_U12(x3, x3, 2+8+8);
|
||||
CMPSx_REG(xRIP, x3);
|
||||
B_MARK(cNE); // Not the expected address, exit dynarec block
|
||||
POP1(xRIP); // pop the return address
|
||||
if(dyn->insts[ninst].retn) {
|
||||
ADDx_U12(xRSP, xRSP, dyn->insts[ninst].retn);
|
||||
}
|
||||
TABLE64(x3, addr);
|
||||
CMPSx_REG(xRIP, x3);
|
||||
B_MARK(cNE); // Not the expected address again
|
||||
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
|
||||
CBZw_NEXT(w1); // not quitting, so lets continue
|
||||
MARK;
|
||||
LOAD_XEMU_REM(); // load remaining register, has they have changed
|
||||
jump_to_epilog(dyn, 0, xRIP, ninst);
|
||||
}
|
||||
TABLE64(x3, addr);
|
||||
CMPSx_REG(xRIP, x3);
|
||||
B_MARK(cNE); // Not the expected address again
|
||||
LDRw_U12(w1, xEmu, offsetof(x64emu_t, quit));
|
||||
CBZw_NEXT(w1); // not quitting, so lets continue
|
||||
MARK;
|
||||
LOAD_XEMU_REM(); // load remaining register, has they have changed
|
||||
jump_to_epilog(dyn, 0, xRIP, ninst);
|
||||
break;
|
||||
default:
|
||||
if(ninst && dyn->insts && dyn->insts[ninst-1].x64.set_flags) {
|
||||
@@ -2214,7 +2238,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
} else {
|
||||
GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
|
||||
CBZxw_MARK(xRDX);
|
||||
if(ed!=x1) {MOVxw_REG(x1, ed);}
|
||||
if(ed!=x1) {MOVx_REG(x1, ed);}
|
||||
CALL(div64, -1);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
@@ -2240,24 +2264,25 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
} else {
|
||||
if(ninst && dyn->insts
|
||||
&& dyn->insts[ninst-1].x64.addr
|
||||
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x99) {
|
||||
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x48
|
||||
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) {
|
||||
SET_DFNONE(x2)
|
||||
GETED(0);
|
||||
SDIVx(x2, xRAX, ed);
|
||||
MSUBx(xRDX, x2, ed, xRAX);
|
||||
MOVw_REG(xRAX, x2);
|
||||
MOVx_REG(xRAX, x2);
|
||||
} else {
|
||||
GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
|
||||
CBZxw_MARK(xRDX);
|
||||
MVNx_REG(x2, xRDX);
|
||||
CBZxw_MARK(x2);
|
||||
if(ed!=x1) {MOVxw_REG(x1, ed);}
|
||||
if(ed!=x1) {MOVx_REG(x1, ed);}
|
||||
CALL((void*)idiv64, -1);
|
||||
B_NEXT_nocond;
|
||||
MARK;
|
||||
SDIVx(x2, xRAX, ed);
|
||||
MSUBx(xRDX, x2, ed, xRAX);
|
||||
MOVw_REG(xRAX, x2);
|
||||
MOVx_REG(xRAX, x2);
|
||||
SET_DFNONE(x2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +151,39 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xAF:
|
||||
INST_NAME("IMUL Gd, Ed");
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
nextop = F8;
|
||||
grab_segdata(dyn, addr, ninst, x4, seg);
|
||||
GETGD;
|
||||
GETEDO(x4, 0);
|
||||
if(rex.w) {
|
||||
// 64bits imul
|
||||
UFLAG_IF {
|
||||
SMULH(x3, gd, ed);
|
||||
MULx(gd, gd, ed);
|
||||
UFLAG_OP1(x3);
|
||||
UFLAG_RES(gd);
|
||||
UFLAG_DF(x3, d_imul64);
|
||||
} else {
|
||||
MULxw(gd, gd, ed);
|
||||
}
|
||||
} else {
|
||||
// 32bits imul
|
||||
UFLAG_IF {
|
||||
SMULL(gd, gd, ed);
|
||||
UFLAG_RES(gd);
|
||||
LSRx(x3, gd, 32);
|
||||
UFLAG_OP1(x3);
|
||||
UFLAG_DF(x3, d_imul32);
|
||||
MOVw_REG(gd, gd);
|
||||
} else {
|
||||
MULxw(gd, gd, ed);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
@@ -388,6 +421,210 @@ uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xD1:
|
||||
nextop = F8;
|
||||
grab_segdata(dyn, addr, ninst, x6, seg);
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("ROL Ed, 1");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET);
|
||||
GETEDO(x6, 0);
|
||||
emit_rol32c(dyn, ninst, rex, ed, 1, x3, x4);
|
||||
WBACKO(x6);
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("ROR Ed, 1");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET);
|
||||
GETEDO(x6, 0);
|
||||
emit_ror32c(dyn, ninst, rex, ed, 1, x3, x4);
|
||||
WBACKO(x6);
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("RCL Ed, 1");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
MOV32w(x2, 1);
|
||||
GETEDO(x6, 0);
|
||||
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
|
||||
if(ed!=x1) {MOVxw_REG(x1, ed);}
|
||||
CALL_(rcl32, ed, x6);
|
||||
WBACK;
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("RCR Ed, 1");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
MOV32w(x2, 1);
|
||||
GETEDO(x6, 0);
|
||||
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
|
||||
if(ed!=x1) {MOVxw_REG(x1, ed);}
|
||||
CALL_(rcr32, ed, x6);
|
||||
WBACK;
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
INST_NAME("SHL Ed, 1");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
GETEDO(x6, 0);
|
||||
emit_shl32c(dyn, ninst, rex, ed, 1, x3, x4);
|
||||
WBACKO(x6);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("SHR Ed, 1");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
GETEDO(x6, 0);
|
||||
emit_shr32c(dyn, ninst, rex, ed, 1, x3, x4);
|
||||
WBACKO(x6);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("SAR Ed, 1");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
GETEDO(x6, 0);
|
||||
emit_sar32c(dyn, ninst, rex, ed, 1, x3, x4);
|
||||
WBACKO(x6);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xD3:
|
||||
nextop = F8;
|
||||
grab_segdata(dyn, addr, ninst, x6, seg);
|
||||
switch((nextop>>3)&7) {
|
||||
case 0:
|
||||
INST_NAME("ROL Ed, CL");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET);
|
||||
if(rex.w) {
|
||||
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
|
||||
} else {
|
||||
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
|
||||
}
|
||||
MOV64xw(x4, (rex.w?64:32));
|
||||
SUBx_REG(x3, x4, x3);
|
||||
GETEDO(x6, 0);
|
||||
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
|
||||
B_NEXT(cEQ);
|
||||
RORxw_REG(ed, ed, x3);
|
||||
WBACKO(x6);
|
||||
UFLAG_IF { // calculate flags directly
|
||||
CMPSw_U12(x3, rex.w?63:31);
|
||||
B_MARK(cNE);
|
||||
LSRxw(x4, ed, rex.w?63:31);
|
||||
ADDxw_REG(x4, x4, ed);
|
||||
BFIw(xFlags, x4, F_OF, 1);
|
||||
MARK;
|
||||
BFIw(xFlags, ed, F_CF, 1);
|
||||
UFLAG_DF(x2, d_none);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
INST_NAME("ROR Ed, CL");
|
||||
SETFLAGS(X_OF|X_CF, SF_SUBSET);
|
||||
if(rex.w) {
|
||||
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
|
||||
} else {
|
||||
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
|
||||
}
|
||||
GETEDO(x6, 0);
|
||||
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
|
||||
B_NEXT(cEQ);
|
||||
RORxw_REG(ed, ed, x3);
|
||||
WBACKO(x6);
|
||||
UFLAG_IF { // calculate flags directly
|
||||
CMPSw_U12(x3, 1);
|
||||
B_MARK(cNE);
|
||||
LSRxw(x2, ed, rex.w?62:30); // x2 = d>>30
|
||||
EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1))
|
||||
BFIw(xFlags, x2, F_OF, 1);
|
||||
MARK;
|
||||
LSRxw(x2, ed, rex.w?63:31);
|
||||
BFIw(xFlags, x2, F_CF, 1);
|
||||
UFLAG_DF(x2, d_none);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
INST_NAME("RCL Ed, CL");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
if(rex.w) {
|
||||
ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
|
||||
} else {
|
||||
ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
|
||||
}
|
||||
GETEDO(x6, 0);
|
||||
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
|
||||
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
|
||||
B_NEXT(cEQ);
|
||||
CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x6);
|
||||
WBACK;
|
||||
break;
|
||||
case 3:
|
||||
INST_NAME("RCR Ed, CL");
|
||||
MESSAGE(LOG_DUMP, "Need Optimization\n");
|
||||
READFLAGS(X_CF);
|
||||
SETFLAGS(X_OF|X_CF, SF_SET);
|
||||
if(rex.w) {
|
||||
ANDSx_mask(x2, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
|
||||
} else {
|
||||
ANDSw_mask(x2, xRCX, 0, 0b00100); //mask=0x00000001f
|
||||
}
|
||||
GETEDO(x6, 0);
|
||||
if(wback) {ADDx_REG(x6, x6, wback); wback=x6;}
|
||||
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
|
||||
B_NEXT(cEQ);
|
||||
CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x6);
|
||||
WBACK;
|
||||
break;
|
||||
case 4:
|
||||
case 6:
|
||||
INST_NAME("SHL Ed, CL");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
if(rex.w) {
|
||||
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
|
||||
} else {
|
||||
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
|
||||
}
|
||||
GETEDO(x6, 0);
|
||||
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
|
||||
B_NEXT(cEQ);
|
||||
emit_shl32(dyn, ninst, rex, ed, x3, x5, x4);
|
||||
WBACKO(x6);
|
||||
break;
|
||||
case 5:
|
||||
INST_NAME("SHR Ed, CL");
|
||||
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
|
||||
if(rex.w) {
|
||||
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
|
||||
} else {
|
||||
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
|
||||
}
|
||||
GETEDO(x6, 0);
|
||||
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
|
||||
B_NEXT(cEQ);
|
||||
emit_shr32(dyn, ninst, rex, ed, x3, x5, x4);
|
||||
WBACKO(x6);
|
||||
break;
|
||||
case 7:
|
||||
INST_NAME("SAR Ed, CL");
|
||||
SETFLAGS(X_ALL, SF_PENDING);
|
||||
if(rex.w) {
|
||||
ANDSx_mask(x3, xRCX, 1, 0, 0b00101); //mask=0x000000000000003f
|
||||
} else {
|
||||
ANDSw_mask(x3, xRCX, 0, 0b00100); //mask=0x00000001f
|
||||
}
|
||||
GETEDO(x6, 0);
|
||||
if(!rex.w && MODREG) {MOVw_REG(ed, ed);}
|
||||
B_NEXT(cEQ);
|
||||
UFLAG_OP12(ed, x3);
|
||||
ASRxw_REG(ed, ed, x3);
|
||||
WBACKO(x6);
|
||||
UFLAG_RES(ed);
|
||||
UFLAG_DF(x3, rex.w?d_sar64:d_sar32);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEFAULT;
|
||||
}
|
||||
|
||||
@@ -458,6 +458,12 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
|
||||
INST_NAME("NOP");
|
||||
break;
|
||||
|
||||
case 0x98:
|
||||
INST_NAME("CBW");
|
||||
SXTBw(x1, xRAX);
|
||||
BFIw(xRAX, x1, 0, 16);
|
||||
break;
|
||||
|
||||
case 0xA1:
|
||||
INST_NAME("MOV EAX,Od");
|
||||
u64 = F64;
|
||||
|
||||
@@ -450,8 +450,9 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n)
|
||||
BLR(x2); // save LR
|
||||
}
|
||||
|
||||
void iret_to_epilog(dynarec_arm_t* dyn, int ninst)
|
||||
void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits)
|
||||
{
|
||||
#warning TODO: is64bits
|
||||
MAYUSE(ninst);
|
||||
MESSAGE(LOG_DUMP, "IRet to epilog\n");
|
||||
// POP IP
|
||||
@@ -480,7 +481,7 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int save
|
||||
if(saveflags) {
|
||||
STRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
|
||||
}
|
||||
fpu_pushcache(dyn, ninst, reg);
|
||||
fpu_pushcache(dyn, ninst, reg, 0);
|
||||
if(ret!=-2) {
|
||||
STPx_S7_preindex(xEmu, savereg, xSP, -16); // ARM64 stack needs to be 16byte aligned
|
||||
STPx_S7_offset(xRAX, xRCX, xEmu, offsetof(x64emu_t, regs[_AX])); // x9..x15, x16,x17,x18 those needs to be saved by caller
|
||||
@@ -510,13 +511,59 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int save
|
||||
GO(R8, R9);
|
||||
#undef GO
|
||||
}
|
||||
fpu_popcache(dyn, ninst, reg);
|
||||
fpu_popcache(dyn, ninst, reg, 0);
|
||||
if(saveflags) {
|
||||
LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
|
||||
}
|
||||
SET_NODF();
|
||||
}
|
||||
|
||||
void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w)
|
||||
{
|
||||
MAYUSE(fnc);
|
||||
STRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
|
||||
fpu_pushcache(dyn, ninst, x3, 1);
|
||||
// x9..x15, x16,x17,x18 those needs to be saved by caller
|
||||
// RDI, RSI, RDX, RCX, R8, R9 are used for function call
|
||||
STPx_S7_preindex(xEmu, xRBX, xSP, -16); // ARM64 stack needs to be 16byte aligned
|
||||
STPx_S7_offset(xRSP, xRBP, xEmu, offsetof(x64emu_t, regs[_SP]));
|
||||
// float and double args
|
||||
if(abs(w)>1) {
|
||||
MESSAGE(LOG_DUMP, "Getting %d XMM args\n", abs(w)-1);
|
||||
for(int i=0; i<abs(w)-1; ++i) {
|
||||
sse_get_reg(dyn, ninst, x7, i);
|
||||
}
|
||||
}
|
||||
if(w<0) {
|
||||
MESSAGE(LOG_DUMP, "Return in XMM0\n");
|
||||
sse_get_reg_empty(dyn, ninst, x7, 0);
|
||||
}
|
||||
// prepare regs for native call
|
||||
MOVx_REG(0, xRDI);
|
||||
MOVx_REG(x1, xRSI);
|
||||
MOVx_REG(x2, xRDX);
|
||||
MOVx_REG(x3, xRCX);
|
||||
MOVx_REG(x4, xR8);
|
||||
MOVx_REG(x5, xR9);
|
||||
// native call
|
||||
TABLE64(16, (uintptr_t)fnc); // using x16 as scratch regs for call address
|
||||
BLR(16);
|
||||
// put return value in x86 regs
|
||||
if(w>0) {
|
||||
MOVx_REG(xRAX, 0);
|
||||
MOVx_REG(xRDX, x1);
|
||||
}
|
||||
// all done, restore all regs
|
||||
LDPx_S7_postindex(xEmu, xRBX, xSP, 16);
|
||||
#define GO(A, B) LDPx_S7_offset(x##A, x##B, xEmu, offsetof(x64emu_t, regs[_##A]))
|
||||
GO(RSP, RBP);
|
||||
#undef GO
|
||||
|
||||
fpu_popcache(dyn, ninst, x3, 1);
|
||||
LDRx_U12(xFlags, xEmu, offsetof(x64emu_t, eflags));
|
||||
SET_NODF();
|
||||
}
|
||||
|
||||
void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment)
|
||||
{
|
||||
(void)addr;
|
||||
@@ -1121,19 +1168,20 @@ static void sse_reflectcache(dynarec_arm_t* dyn, int ninst, int s1)
|
||||
}
|
||||
#endif
|
||||
|
||||
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1)
|
||||
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
|
||||
{
|
||||
(void) ninst; (void)s1;
|
||||
#if STEP > 1
|
||||
int start = not07?8:0;
|
||||
// only SSE regs needs to be push back to xEmu
|
||||
int n=0;
|
||||
for (int i=0; i<16; i++)
|
||||
for (int i=start; i<16; i++)
|
||||
if(dyn->ssecache[i]!=-1)
|
||||
++n;
|
||||
if(!n)
|
||||
return;
|
||||
MESSAGE(LOG_DUMP, "\tPush XMM Cache (%d)------\n", n);
|
||||
for (int i=0; i<16; ++i)
|
||||
for (int i=start; i<16; ++i)
|
||||
if(dyn->ssecache[i]!=-1) {
|
||||
VSTR128_U12(dyn->ssecache[i], xEmu, offsetof(x64emu_t, xmm[i]));
|
||||
}
|
||||
@@ -1143,19 +1191,20 @@ void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1)
|
||||
#endif
|
||||
}
|
||||
|
||||
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1)
|
||||
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
|
||||
{
|
||||
(void) ninst; (void)s1;
|
||||
#if STEP > 1
|
||||
int start = not07?8:0;
|
||||
// only SSE regs needs to be pop back from xEmu
|
||||
int n=0;
|
||||
for (int i=0; i<16; i++)
|
||||
for (int i=start; i<16; i++)
|
||||
if(dyn->ssecache[i]!=-1)
|
||||
++n;
|
||||
if(!n)
|
||||
return;
|
||||
MESSAGE(LOG_DUMP, "\tPop XMM Cache (%d)------\n", n);
|
||||
for (int i=0; i<16; ++i)
|
||||
for (int i=start; i<16; ++i)
|
||||
if(dyn->ssecache[i]!=-1) {
|
||||
VLDR128_U12(dyn->ssecache[i], xEmu, offsetof(x64emu_t, xmm[i]));
|
||||
}
|
||||
|
||||
@@ -635,6 +635,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
|
||||
#define retn_to_epilog STEPNAME(retn_to_epilog)
|
||||
#define iret_to_epilog STEPNAME(iret_to_epilog)
|
||||
#define call_c STEPNAME(call_c)
|
||||
#define call_n STEPNAME(call_n)
|
||||
#define grab_segdata STEPNAME(grab_segdata)
|
||||
#define emit_cmp8 STEPNAME(emit_cmp8)
|
||||
#define emit_cmp16 STEPNAME(emit_cmp16)
|
||||
@@ -751,8 +752,9 @@ void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
|
||||
void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
|
||||
void ret_to_epilog(dynarec_arm_t* dyn, int ninst);
|
||||
void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n);
|
||||
void iret_to_epilog(dynarec_arm_t* dyn, int ninst);
|
||||
void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits);
|
||||
void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg);
|
||||
void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w);
|
||||
void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment);
|
||||
void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
|
||||
void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5);
|
||||
@@ -878,8 +880,8 @@ void x87_purgecache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3);
|
||||
#ifdef HAVE_TRACE
|
||||
void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3);
|
||||
#endif
|
||||
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1);
|
||||
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1);
|
||||
void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07);
|
||||
void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07);
|
||||
|
||||
uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
|
||||
uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
|
||||
|
||||
@@ -235,6 +235,8 @@ int AllocElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
|
||||
}
|
||||
} else {
|
||||
// vaddr is 0, load everything has a One block
|
||||
if(!offs && box64_wine)
|
||||
offs = (uintptr_t)find47bitBlock(head->memsz); // limit to 47bits...
|
||||
printf_log(LOG_DEBUG, "Allocating 0x%lx memory @%p for Elf \"%s\"\n", head->memsz, (void*)offs, head->name);
|
||||
void* p = mmap((void*)offs, head->memsz
|
||||
, PROT_READ | PROT_WRITE | PROT_EXEC
|
||||
@@ -1532,7 +1534,7 @@ EXPORT void PltResolver(x64emu_t* emu)
|
||||
GetGlobalSymbolStartEnd(my_context->maplib, symname, &offs, &end, h, -1, NULL);
|
||||
|
||||
if (!offs) {
|
||||
printf_log(LOG_NONE, "Error: PltReolver: Symbol %s(ver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p (%p) in %s\n", symname, version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name);
|
||||
printf_log(LOG_NONE, "Error: PltResolver: Symbol %s(ver %d: %s%s%s) not found, cannot apply R_X86_64_JUMP_SLOT %p (%p) in %s\n", symname, version, symname, vername?"@":"", vername?vername:"", p, *(void**)p, h->name);
|
||||
emu->quit = 1;
|
||||
return;
|
||||
} else {
|
||||
@@ -1540,7 +1542,7 @@ EXPORT void PltResolver(x64emu_t* emu)
|
||||
printf_dump(LOG_DEBUG, " Apply %s R_X86_64_JUMP_SLOT %p with sym=%s(ver %d: %s%s%s) (%p -> %p / %s)\n", (bind==STB_LOCAL)?"Local":"Global", p, symname, version, symname, vername?"@":"", vername?vername:"",*(void**)p, (void*)offs, ElfName(FindElfAddress(my_context, offs)));
|
||||
*p = offs;
|
||||
} else {
|
||||
printf_log(LOG_NONE, "PltReolver: Warning, Symbol %s(ver %d: %s%s%s) found, but Jump Slot Offset is NULL \n", symname, version, symname, vername?"@":"", vername?vername:"");
|
||||
printf_log(LOG_NONE, "PltResolver: Warning, Symbol %s(ver %d: %s%s%s) found, but Jump Slot Offset is NULL \n", symname, version, symname, vername?"@":"", vername?vername:"");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ typedef struct x64emu_s {
|
||||
reg64_t regs[16];
|
||||
x64flags_t eflags;
|
||||
reg64_t ip;
|
||||
uintptr_t old_ip;
|
||||
// sse
|
||||
sse_regs_t xmm[16];
|
||||
// fpu / mmx
|
||||
mmx87_regs_t mmx87[8];
|
||||
uint16_t cw,cw_mask_all;
|
||||
@@ -42,8 +43,8 @@ typedef struct x64emu_s {
|
||||
fpu_ld_t fpu_ld[8]; // for long double emulation / 80bits fld fst
|
||||
fpu_ll_t fpu_ll[8]; // for 64bits fild / fist sequence
|
||||
fpu_p_reg_t p_regs[8];
|
||||
// sse
|
||||
sse_regs_t xmm[16];
|
||||
// old ip
|
||||
uintptr_t old_ip;
|
||||
// defered flags
|
||||
int dummy1; // to align on 64bits with df
|
||||
defered_flags_t df;
|
||||
|
||||
@@ -1051,6 +1051,14 @@ x64emurun:
|
||||
if(emu->quit) goto fini;
|
||||
break;
|
||||
|
||||
case 0xCF: /* IRET */
|
||||
R_RIP = Pop(emu);
|
||||
emu->segs[_CS] = Pop(emu);
|
||||
emu->segs_serial[_CS] = 0;
|
||||
emu->eflags.x64 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
|
||||
RESET_FLAGS(emu);
|
||||
goto fini; // exit, to recompute CS if needed
|
||||
break;
|
||||
case 0xD0: /* GRP2 Eb,1 */
|
||||
case 0xD2: /* GRP2 Eb,CL */
|
||||
nextop = F8;
|
||||
|
||||
@@ -181,6 +181,16 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xAF: /* IMUL Gd,Ed */
|
||||
nextop = F8;
|
||||
GETED_OFFS(0, tlsdata);
|
||||
GETGD;
|
||||
if(rex.w)
|
||||
GD->q[0] = imul64(emu, GD->q[0], ED->q[0]);
|
||||
else
|
||||
GD->q[0] = imul32(emu, GD->dword[0], ED->dword[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
@@ -354,6 +364,48 @@ int Run64(x64emu_t *emu, rex_t rex, int seg)
|
||||
ED->dword[0] = F32;
|
||||
break;
|
||||
|
||||
case 0xD1: /* GRP2 Ed,1 */
|
||||
case 0xD3: /* GRP2 Ed,CL */
|
||||
nextop = F8;
|
||||
GETED_OFFS(0, tlsdata);
|
||||
tmp8u = (opcode==0xD1)?1:R_CL;
|
||||
if(rex.w) {
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: ED->q[0] = rol64(emu, ED->q[0], tmp8u); break;
|
||||
case 1: ED->q[0] = ror64(emu, ED->q[0], tmp8u); break;
|
||||
case 2: ED->q[0] = rcl64(emu, ED->q[0], tmp8u); break;
|
||||
case 3: ED->q[0] = rcr64(emu, ED->q[0], tmp8u); break;
|
||||
case 4:
|
||||
case 6: ED->q[0] = shl64(emu, ED->q[0], tmp8u); break;
|
||||
case 5: ED->q[0] = shr64(emu, ED->q[0], tmp8u); break;
|
||||
case 7: ED->q[0] = sar64(emu, ED->q[0], tmp8u); break;
|
||||
}
|
||||
} else {
|
||||
if(MODREG)
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: ED->q[0] = rol32(emu, ED->dword[0], tmp8u); break;
|
||||
case 1: ED->q[0] = ror32(emu, ED->dword[0], tmp8u); break;
|
||||
case 2: ED->q[0] = rcl32(emu, ED->dword[0], tmp8u); break;
|
||||
case 3: ED->q[0] = rcr32(emu, ED->dword[0], tmp8u); break;
|
||||
case 4:
|
||||
case 6: ED->q[0] = shl32(emu, ED->dword[0], tmp8u); break;
|
||||
case 5: ED->q[0] = shr32(emu, ED->dword[0], tmp8u); break;
|
||||
case 7: ED->q[0] = sar32(emu, ED->dword[0], tmp8u); break;
|
||||
}
|
||||
else
|
||||
switch((nextop>>3)&7) {
|
||||
case 0: ED->dword[0] = rol32(emu, ED->dword[0], tmp8u); break;
|
||||
case 1: ED->dword[0] = ror32(emu, ED->dword[0], tmp8u); break;
|
||||
case 2: ED->dword[0] = rcl32(emu, ED->dword[0], tmp8u); break;
|
||||
case 3: ED->dword[0] = rcr32(emu, ED->dword[0], tmp8u); break;
|
||||
case 4:
|
||||
case 6: ED->dword[0] = shl32(emu, ED->dword[0], tmp8u); break;
|
||||
case 5: ED->dword[0] = shr32(emu, ED->dword[0], tmp8u); break;
|
||||
case 7: ED->dword[0] = sar32(emu, ED->dword[0], tmp8u); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot);
|
||||
void setProtection(uintptr_t addr, size_t size, uint32_t prot);
|
||||
void freeProtection(uintptr_t addr, size_t size);
|
||||
uint32_t getProtection(uintptr_t addr);
|
||||
void loadProtectionFromMap();
|
||||
#ifdef DYNAREC
|
||||
void protectDB(uintptr_t addr, size_t size);
|
||||
void protectDBnolock(uintptr_t addr, size_t size);
|
||||
@@ -51,6 +52,8 @@ void unlockDB();
|
||||
#endif
|
||||
void* find32bitBlock(size_t size);
|
||||
void* findBlockNearHint(void* hint, size_t size);
|
||||
void* find47bitBlock(size_t size);
|
||||
void* find47bitBlockNearHint(void* hint, size_t size);
|
||||
|
||||
// unlock mutex that are locked by current thread (for signal handling). Return a mask of unlock mutex
|
||||
int unlockCustommemMutex();
|
||||
|
||||
@@ -24,6 +24,7 @@ extern char* trace_func;
|
||||
#endif
|
||||
extern int allow_missing_libs;
|
||||
extern int box64_steam;
|
||||
extern int box64_wine;
|
||||
extern int box64_nopulse; // disabling the use of wrapped pulseaudio
|
||||
extern int box64_nogtk; // disabling the use of wrapped gtk
|
||||
extern int box64_novulkan; // disabling the use of wrapped vulkan
|
||||
|
||||
@@ -247,6 +247,7 @@ typedef union {
|
||||
} mmx87_regs_t;
|
||||
|
||||
typedef union {
|
||||
__uint128_t u128;
|
||||
uint64_t q[2];
|
||||
int64_t sq[2];
|
||||
double d[2];
|
||||
|
||||
@@ -707,6 +707,17 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
void* rsp = NULL;
|
||||
#ifdef __aarch64__
|
||||
void * pc = (void*)p->uc_mcontext.pc;
|
||||
struct fpsimd_context *fpsimd = NULL;
|
||||
// find fpsimd struct
|
||||
{
|
||||
struct _aarch64_ctx * ff = (struct _aarch64_ctx*)p->uc_mcontext.__reserved;
|
||||
while (ff->magic && !fpsimd) {
|
||||
if(ff->magic==FPSIMD_MAGIC)
|
||||
fpsimd = (struct fpsimd_context*)ff;
|
||||
else
|
||||
ff = (struct _aarch64_ctx*)((uintptr_t)ff + ff->size);
|
||||
}
|
||||
}
|
||||
#elif defined __x86_64__
|
||||
void * pc = (void*)p->uc_mcontext.gregs[X64_RIP];
|
||||
#elif defined __powerpc64__
|
||||
@@ -747,6 +758,12 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
ejb->emu->regs[_R13].q[0] = p->uc_mcontext.regs[23];
|
||||
ejb->emu->regs[_R14].q[0] = p->uc_mcontext.regs[24];
|
||||
ejb->emu->regs[_R15].q[0] = p->uc_mcontext.regs[25];
|
||||
if(fpsimd) {
|
||||
ejb->emu->xmm[0].u128 = fpsimd->vregs[0];
|
||||
ejb->emu->xmm[1].u128 = fpsimd->vregs[1];
|
||||
ejb->emu->xmm[2].u128 = fpsimd->vregs[2];
|
||||
ejb->emu->xmm[3].u128 = fpsimd->vregs[3];
|
||||
}
|
||||
ejb->emu->ip.q[0] = getX64Address(db, (uintptr_t)pc);
|
||||
ejb->emu->eflags.x64 = p->uc_mcontext.regs[26];
|
||||
if(addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) {
|
||||
|
||||
+15
-4
@@ -8,6 +8,7 @@
|
||||
#include <dirent.h>
|
||||
#include <signal.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "build_info.h"
|
||||
#include "debug.h"
|
||||
@@ -52,12 +53,13 @@ char* trace_func = NULL;
|
||||
int box64_dynarec_trace = 0;
|
||||
#endif
|
||||
#endif
|
||||
int box64_zoom = 0;
|
||||
int x11threads = 0;
|
||||
int x11glx = 1;
|
||||
int allow_missing_libs = 0;
|
||||
int fix_64bit_inodes = 0;
|
||||
int box64_zoom = 0;
|
||||
int box64_steam = 0;
|
||||
int box64_wine = 0;
|
||||
int box64_nopulse = 0;
|
||||
int box64_nogtk = 0;
|
||||
int box64_novulkan = 0;
|
||||
@@ -731,7 +733,8 @@ int main(int argc, const char **argv, const char **env) {
|
||||
if(!box64_nobanner)
|
||||
PrintBox64Version();
|
||||
// precheck, for win-preload
|
||||
if(strstr(prog, "wine-preloader")==(prog+strlen(prog)-strlen("wine-preloader"))) {
|
||||
if(strstr(prog, "wine-preloader")==(prog+strlen(prog)-strlen("wine-preloader"))
|
||||
|| strstr(prog, "wine64-preloader")==(prog+strlen(prog)-strlen("wine64-preloader"))) {
|
||||
// wine-preloader detecter, skipping it if next arg exist and is an x86 binary
|
||||
int x64 = (nextarg<argc)?FileIsX64ELF(argv[nextarg]):0;
|
||||
if(x64) {
|
||||
@@ -741,9 +744,11 @@ int main(int argc, const char **argv, const char **env) {
|
||||
}
|
||||
}
|
||||
// check if this is wine
|
||||
if(!strcmp(prog, "wine") || (strlen(prog)>5 && !strcmp(prog+strlen(prog)-strlen("/wine"), "/wine"))) {
|
||||
if(!strcmp(prog, "wine64")
|
||||
|| !strcmp(prog, "wine64-development")
|
||||
|| (strlen(prog)>5 && !strcmp(prog+strlen(prog)-strlen("/wine64"), "/wine64"))) {
|
||||
const char* prereserve = getenv("WINEPRELOADRESERVE");
|
||||
printf_log(LOG_INFO, "BOX64: Wine detected, WINEPRELOADRESERVE=\"%s\"\n", prereserve?prereserve:"");
|
||||
printf_log(LOG_INFO, "BOX64: Wine64 detected, WINEPRELOADRESERVE=\"%s\"\n", prereserve?prereserve:"");
|
||||
if(wine_preloaded)
|
||||
wine_prereserve(prereserve);
|
||||
// special case for winedbg, doesn't work anyway
|
||||
@@ -751,6 +756,11 @@ int main(int argc, const char **argv, const char **env) {
|
||||
printf_log(LOG_NONE, "winedbg detected, not launching it!\n");
|
||||
exit(0); // exiting, it doesn't work anyway
|
||||
}
|
||||
box64_wine = 1;
|
||||
}
|
||||
// check if this is wineserver
|
||||
if(!strcmp(prog, "wineserver") || !strcmp(prog, "wineserver64") || (strlen(prog)>9 && !strcmp(prog+strlen(prog)-strlen("/wineserver"), "/wineserver"))) {
|
||||
box64_wine = 1;
|
||||
}
|
||||
// Create a new context
|
||||
my_context = NewBox64Context(argc - nextarg);
|
||||
@@ -1045,6 +1055,7 @@ int main(int argc, const char **argv, const char **env) {
|
||||
#endif
|
||||
|
||||
atexit(endBox64);
|
||||
loadProtectionFromMap();
|
||||
|
||||
// emulate!
|
||||
printf_log(LOG_DEBUG, "Start x64emu on Main\n");
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#() uFv
|
||||
#() uFi
|
||||
#() uFu
|
||||
#() uFU
|
||||
#() uFd
|
||||
#() uFp
|
||||
#() UFv
|
||||
@@ -946,6 +947,7 @@
|
||||
#() iFpppipp
|
||||
#() iFpppuii
|
||||
#() iFpppupu
|
||||
#() iFpppLpp
|
||||
#() iFppppii
|
||||
#() iFppppip
|
||||
#() iFppppup
|
||||
@@ -1048,6 +1050,7 @@
|
||||
#() iFpiiuuiu
|
||||
#() iFpiuiipp
|
||||
#() iFpiupiii
|
||||
#() iFpippLpp
|
||||
#() iFpippppp
|
||||
#() iFpuuiuui
|
||||
#() iFpuupppp
|
||||
@@ -1130,6 +1133,7 @@
|
||||
#() iFLLLLLLLL
|
||||
#() iFpiiiiipi
|
||||
#() iFpWCuWCuu
|
||||
#() iFpuippLpp
|
||||
#() iFpuuiiiii
|
||||
#() iFpupppppp
|
||||
#() iFppIIIppp
|
||||
|
||||
+157
-134
@@ -68,6 +68,7 @@ typedef uint16_t (*WFp_t)(void*);
|
||||
typedef uint64_t (*uFv_t)(void);
|
||||
typedef uint64_t (*uFi_t)(int64_t);
|
||||
typedef uint64_t (*uFu_t)(uint64_t);
|
||||
typedef uint64_t (*uFU_t)(uint64_t);
|
||||
typedef uint64_t (*uFd_t)(double);
|
||||
typedef uint64_t (*uFp_t)(void*);
|
||||
typedef uint64_t (*UFv_t)(void);
|
||||
@@ -980,6 +981,7 @@ typedef int64_t (*iFpppipi_t)(void*, void*, void*, int64_t, void*, int64_t);
|
||||
typedef int64_t (*iFpppipp_t)(void*, void*, void*, int64_t, void*, void*);
|
||||
typedef int64_t (*iFpppuii_t)(void*, void*, void*, uint64_t, int64_t, int64_t);
|
||||
typedef int64_t (*iFpppupu_t)(void*, void*, void*, uint64_t, void*, uint64_t);
|
||||
typedef int64_t (*iFpppLpp_t)(void*, void*, void*, uintptr_t, void*, void*);
|
||||
typedef int64_t (*iFppppii_t)(void*, void*, void*, void*, int64_t, int64_t);
|
||||
typedef int64_t (*iFppppip_t)(void*, void*, void*, void*, int64_t, void*);
|
||||
typedef int64_t (*iFppppup_t)(void*, void*, void*, void*, uint64_t, void*);
|
||||
@@ -1082,6 +1084,7 @@ typedef int64_t (*iFpiiiLwp_t)(void*, int64_t, int64_t, int64_t, uintptr_t, int1
|
||||
typedef int64_t (*iFpiiuuiu_t)(void*, int64_t, int64_t, uint64_t, uint64_t, int64_t, uint64_t);
|
||||
typedef int64_t (*iFpiuiipp_t)(void*, int64_t, uint64_t, int64_t, int64_t, void*, void*);
|
||||
typedef int64_t (*iFpiupiii_t)(void*, int64_t, uint64_t, void*, int64_t, int64_t, int64_t);
|
||||
typedef int64_t (*iFpippLpp_t)(void*, int64_t, void*, void*, uintptr_t, void*, void*);
|
||||
typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*);
|
||||
typedef int64_t (*iFpuuiuui_t)(void*, uint64_t, uint64_t, int64_t, uint64_t, uint64_t, int64_t);
|
||||
typedef int64_t (*iFpuupppp_t)(void*, uint64_t, uint64_t, void*, void*, void*, void*);
|
||||
@@ -1164,6 +1167,7 @@ typedef int64_t (*iFuiifpppp_t)(uint64_t, int64_t, int64_t, float, void*, void*,
|
||||
typedef int64_t (*iFLLLLLLLL_t)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
typedef int64_t (*iFpiiiiipi_t)(void*, int64_t, int64_t, int64_t, int64_t, int64_t, void*, int64_t);
|
||||
typedef int64_t (*iFpWCuWCuu_t)(void*, uint16_t, uint8_t, uint64_t, uint16_t, uint8_t, uint64_t, uint64_t);
|
||||
typedef int64_t (*iFpuippLpp_t)(void*, uint64_t, int64_t, void*, void*, uintptr_t, void*, void*);
|
||||
typedef int64_t (*iFpuuiiiii_t)(void*, uint64_t, uint64_t, int64_t, int64_t, int64_t, int64_t, int64_t);
|
||||
typedef int64_t (*iFpupppppp_t)(void*, uint64_t, void*, void*, void*, void*, void*, void*);
|
||||
typedef int64_t (*iFppIIIppp_t)(void*, void*, int64_t, int64_t, int64_t, void*, void*, void*);
|
||||
@@ -1366,6 +1370,7 @@ void WFp(x64emu_t *emu, uintptr_t fcn) { WFp_t fn = (WFp_t)fcn; R_RAX=(unsigned
|
||||
void uFv(x64emu_t *emu, uintptr_t fcn) { uFv_t fn = (uFv_t)fcn; R_RAX=(uint64_t)fn(); }
|
||||
void uFi(x64emu_t *emu, uintptr_t fcn) { uFi_t fn = (uFi_t)fcn; R_RAX=(uint64_t)fn((int64_t)R_RDI); }
|
||||
void uFu(x64emu_t *emu, uintptr_t fcn) { uFu_t fn = (uFu_t)fcn; R_RAX=(uint64_t)fn((uint64_t)R_RDI); }
|
||||
void uFU(x64emu_t *emu, uintptr_t fcn) { uFU_t fn = (uFU_t)fcn; R_RAX=(uint64_t)fn((uint64_t)R_RDI); }
|
||||
void uFd(x64emu_t *emu, uintptr_t fcn) { uFd_t fn = (uFd_t)fcn; R_RAX=(uint64_t)fn(emu->xmm[0].d[0]); }
|
||||
void uFp(x64emu_t *emu, uintptr_t fcn) { uFp_t fn = (uFp_t)fcn; R_RAX=(uint64_t)fn((void*)R_RDI); }
|
||||
void UFv(x64emu_t *emu, uintptr_t fcn) { UFv_t fn = (UFv_t)fcn; R_RAX=fn(); }
|
||||
@@ -2278,6 +2283,7 @@ void iFpppipi(x64emu_t *emu, uintptr_t fcn) { iFpppipi_t fn = (iFpppipi_t)fcn; R
|
||||
void iFpppipp(x64emu_t *emu, uintptr_t fcn) { iFpppipp_t fn = (iFpppipp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (int64_t)R_RCX, (void*)R_R8, (void*)R_R9); }
|
||||
void iFpppuii(x64emu_t *emu, uintptr_t fcn) { iFpppuii_t fn = (iFpppuii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9); }
|
||||
void iFpppupu(x64emu_t *emu, uintptr_t fcn) { iFpppupu_t fn = (iFpppupu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uint64_t)R_RCX, (void*)R_R8, (uint64_t)R_R9); }
|
||||
void iFpppLpp(x64emu_t *emu, uintptr_t fcn) { iFpppLpp_t fn = (iFpppLpp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (uintptr_t)R_RCX, (void*)R_R8, (void*)R_R9); }
|
||||
void iFppppii(x64emu_t *emu, uintptr_t fcn) { iFppppii_t fn = (iFppppii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int64_t)R_R8, (int64_t)R_R9); }
|
||||
void iFppppip(x64emu_t *emu, uintptr_t fcn) { iFppppip_t fn = (iFppppip_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (int64_t)R_R8, (void*)R_R9); }
|
||||
void iFppppup(x64emu_t *emu, uintptr_t fcn) { iFppppup_t fn = (iFppppup_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (void*)R_RDX, (void*)R_RCX, (uint64_t)R_R8, (void*)R_R9); }
|
||||
@@ -2380,6 +2386,7 @@ void iFpiiiLwp(x64emu_t *emu, uintptr_t fcn) { iFpiiiLwp_t fn = (iFpiiiLwp_t)fcn
|
||||
void iFpiiuuiu(x64emu_t *emu, uintptr_t fcn) { iFpiiuuiu_t fn = (iFpiiuuiu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (uint64_t)R_RCX, (uint64_t)R_R8, (int64_t)R_R9, *(uint64_t*)(R_RSP + 8)); }
|
||||
void iFpiuiipp(x64emu_t *emu, uintptr_t fcn) { iFpiuiipp_t fn = (iFpiuiipp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (uint64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
|
||||
void iFpiupiii(x64emu_t *emu, uintptr_t fcn) { iFpiupiii_t fn = (iFpiupiii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(int64_t*)(R_RSP + 8)); }
|
||||
void iFpippLpp(x64emu_t *emu, uintptr_t fcn) { iFpippLpp_t fn = (iFpippLpp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (uintptr_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
|
||||
void iFpippppp(x64emu_t *emu, uintptr_t fcn) { iFpippppp_t fn = (iFpippppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
|
||||
void iFpuuiuui(x64emu_t *emu, uintptr_t fcn) { iFpuuiuui_t fn = (iFpuuiuui_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (int64_t)R_RCX, (uint64_t)R_R8, (uint64_t)R_R9, *(int64_t*)(R_RSP + 8)); }
|
||||
void iFpuupppp(x64emu_t *emu, uintptr_t fcn) { iFpuupppp_t fn = (iFpuupppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8)); }
|
||||
@@ -2462,6 +2469,7 @@ void iFuiifpppp(x64emu_t *emu, uintptr_t fcn) { iFuiifpppp_t fn = (iFuiifpppp_t)
|
||||
void iFLLLLLLLL(x64emu_t *emu, uintptr_t fcn) { iFLLLLLLLL_t fn = (iFLLLLLLLL_t)fcn; R_RAX=(int64_t)fn((uintptr_t)R_RDI, (uintptr_t)R_RSI, (uintptr_t)R_RDX, (uintptr_t)R_RCX, (uintptr_t)R_R8, (uintptr_t)R_R9, *(uintptr_t*)(R_RSP + 8), *(uintptr_t*)(R_RSP + 16)); }
|
||||
void iFpiiiiipi(x64emu_t *emu, uintptr_t fcn) { iFpiiiiipi_t fn = (iFpiiiiipi_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (int64_t)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(void**)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
|
||||
void iFpWCuWCuu(x64emu_t *emu, uintptr_t fcn) { iFpWCuWCuu_t fn = (iFpWCuWCuu_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint16_t)R_RSI, (uint8_t)R_RDX, (uint64_t)R_RCX, (uint16_t)R_R8, (uint8_t)R_R9, *(uint64_t*)(R_RSP + 8), *(uint64_t*)(R_RSP + 16)); }
|
||||
void iFpuippLpp(x64emu_t *emu, uintptr_t fcn) { iFpuippLpp_t fn = (iFpuippLpp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (int64_t)R_RDX, (void*)R_RCX, (void*)R_R8, (uintptr_t)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
|
||||
void iFpuuiiiii(x64emu_t *emu, uintptr_t fcn) { iFpuuiiiii_t fn = (iFpuuiiiii_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (uint64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (int64_t)R_R9, *(int64_t*)(R_RSP + 8), *(int64_t*)(R_RSP + 16)); }
|
||||
void iFpupppppp(x64emu_t *emu, uintptr_t fcn) { iFpupppppp_t fn = (iFpupppppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (uint64_t)R_RSI, (void*)R_RDX, (void*)R_RCX, (void*)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
|
||||
void iFppIIIppp(x64emu_t *emu, uintptr_t fcn) { iFppIIIppp_t fn = (iFppIIIppp_t)fcn; R_RAX=(int64_t)fn((void*)R_RDI, (void*)R_RSI, (int64_t)R_RDX, (int64_t)R_RCX, (int64_t)R_R8, (void*)R_R9, *(void**)(R_RSP + 8), *(void**)(R_RSP + 16)); }
|
||||
@@ -2643,27 +2651,27 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFv) return 1;
|
||||
if (fun == &vFi) return 1;
|
||||
if (fun == &vFu) return 1;
|
||||
if (fun == &vFf) return 1;
|
||||
if (fun == &vFd) return 1;
|
||||
if (fun == &vFf) return 2;
|
||||
if (fun == &vFd) return 2;
|
||||
if (fun == &vFl) return 1;
|
||||
if (fun == &vFL) return 1;
|
||||
if (fun == &vFp) return 1;
|
||||
if (fun == &cFv) return 1;
|
||||
if (fun == &cFi) return 1;
|
||||
if (fun == &cFu) return 1;
|
||||
if (fun == &cFf) return 1;
|
||||
if (fun == &cFf) return 2;
|
||||
if (fun == &cFp) return 1;
|
||||
if (fun == &wFp) return 1;
|
||||
if (fun == &iFv) return 1;
|
||||
if (fun == &iFw) return 1;
|
||||
if (fun == &iFi) return 1;
|
||||
if (fun == &iFu) return 1;
|
||||
if (fun == &iFf) return 1;
|
||||
if (fun == &iFd) return 1;
|
||||
if (fun == &iFf) return 2;
|
||||
if (fun == &iFd) return 2;
|
||||
if (fun == &iFL) return 1;
|
||||
if (fun == &iFp) return 1;
|
||||
if (fun == &IFf) return 1;
|
||||
if (fun == &IFd) return 1;
|
||||
if (fun == &IFf) return 2;
|
||||
if (fun == &IFd) return 2;
|
||||
if (fun == &IFp) return 1;
|
||||
if (fun == &CFp) return 1;
|
||||
if (fun == &WFi) return 1;
|
||||
@@ -2672,18 +2680,19 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &uFv) return 1;
|
||||
if (fun == &uFi) return 1;
|
||||
if (fun == &uFu) return 1;
|
||||
if (fun == &uFd) return 1;
|
||||
if (fun == &uFU) return 1;
|
||||
if (fun == &uFd) return 2;
|
||||
if (fun == &uFp) return 1;
|
||||
if (fun == &UFv) return 1;
|
||||
if (fun == &UFp) return 1;
|
||||
if (fun == &fFi) return 1;
|
||||
if (fun == &fFf) return 1;
|
||||
if (fun == &fFp) return 1;
|
||||
if (fun == &dFv) return 1;
|
||||
if (fun == &dFi) return 1;
|
||||
if (fun == &dFu) return 1;
|
||||
if (fun == &dFd) return 1;
|
||||
if (fun == &dFp) return 1;
|
||||
if (fun == &fFi) return -1;
|
||||
if (fun == &fFf) return -2;
|
||||
if (fun == &fFp) return -1;
|
||||
if (fun == &dFv) return -1;
|
||||
if (fun == &dFi) return -1;
|
||||
if (fun == &dFu) return -1;
|
||||
if (fun == &dFd) return -2;
|
||||
if (fun == &dFp) return -1;
|
||||
if (fun == &lFv) return 1;
|
||||
if (fun == &lFi) return 1;
|
||||
if (fun == &lFl) return 1;
|
||||
@@ -2695,32 +2704,32 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &pFi) return 1;
|
||||
if (fun == &pFW) return 1;
|
||||
if (fun == &pFu) return 1;
|
||||
if (fun == &pFd) return 1;
|
||||
if (fun == &pFd) return 2;
|
||||
if (fun == &pFl) return 1;
|
||||
if (fun == &pFL) return 1;
|
||||
if (fun == &pFp) return 1;
|
||||
if (fun == &vFii) return 1;
|
||||
if (fun == &vFiu) return 1;
|
||||
if (fun == &vFif) return 1;
|
||||
if (fun == &vFid) return 1;
|
||||
if (fun == &vFif) return 2;
|
||||
if (fun == &vFid) return 2;
|
||||
if (fun == &vFip) return 1;
|
||||
if (fun == &vFWW) return 1;
|
||||
if (fun == &vFWp) return 1;
|
||||
if (fun == &vFui) return 1;
|
||||
if (fun == &vFuu) return 1;
|
||||
if (fun == &vFuf) return 1;
|
||||
if (fun == &vFud) return 1;
|
||||
if (fun == &vFuf) return 2;
|
||||
if (fun == &vFud) return 2;
|
||||
if (fun == &vFup) return 1;
|
||||
if (fun == &vFfi) return 1;
|
||||
if (fun == &vFff) return 1;
|
||||
if (fun == &vFfp) return 1;
|
||||
if (fun == &vFdd) return 1;
|
||||
if (fun == &vFfi) return 2;
|
||||
if (fun == &vFff) return 3;
|
||||
if (fun == &vFfp) return 2;
|
||||
if (fun == &vFdd) return 3;
|
||||
if (fun == &vFlp) return 1;
|
||||
if (fun == &vFLp) return 1;
|
||||
if (fun == &vFpi) return 1;
|
||||
if (fun == &vFpu) return 1;
|
||||
if (fun == &vFpf) return 1;
|
||||
if (fun == &vFpd) return 1;
|
||||
if (fun == &vFpf) return 2;
|
||||
if (fun == &vFpd) return 2;
|
||||
if (fun == &vFpl) return 1;
|
||||
if (fun == &vFpL) return 1;
|
||||
if (fun == &vFpp) return 1;
|
||||
@@ -2746,8 +2755,8 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &iFpC) return 1;
|
||||
if (fun == &iFpu) return 1;
|
||||
if (fun == &iFpU) return 1;
|
||||
if (fun == &iFpf) return 1;
|
||||
if (fun == &iFpd) return 1;
|
||||
if (fun == &iFpf) return 2;
|
||||
if (fun == &iFpd) return 2;
|
||||
if (fun == &iFpl) return 1;
|
||||
if (fun == &iFpL) return 1;
|
||||
if (fun == &iFpp) return 1;
|
||||
@@ -2770,18 +2779,18 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &UFii) return 1;
|
||||
if (fun == &UFUp) return 1;
|
||||
if (fun == &UFpp) return 1;
|
||||
if (fun == &fFif) return 1;
|
||||
if (fun == &fFfi) return 1;
|
||||
if (fun == &fFff) return 1;
|
||||
if (fun == &fFfp) return 1;
|
||||
if (fun == &fFpp) return 1;
|
||||
if (fun == &dFid) return 1;
|
||||
if (fun == &dFdi) return 1;
|
||||
if (fun == &dFdd) return 1;
|
||||
if (fun == &dFdp) return 1;
|
||||
if (fun == &dFLL) return 1;
|
||||
if (fun == &dFpi) return 1;
|
||||
if (fun == &dFpp) return 1;
|
||||
if (fun == &fFif) return -2;
|
||||
if (fun == &fFfi) return -2;
|
||||
if (fun == &fFff) return -3;
|
||||
if (fun == &fFfp) return -2;
|
||||
if (fun == &fFpp) return -1;
|
||||
if (fun == &dFid) return -2;
|
||||
if (fun == &dFdi) return -2;
|
||||
if (fun == &dFdd) return -3;
|
||||
if (fun == &dFdp) return -2;
|
||||
if (fun == &dFLL) return -1;
|
||||
if (fun == &dFpi) return -1;
|
||||
if (fun == &dFpp) return -1;
|
||||
if (fun == &lFll) return 1;
|
||||
if (fun == &lFpi) return 1;
|
||||
if (fun == &lFpp) return 1;
|
||||
@@ -2798,7 +2807,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &pFui) return 1;
|
||||
if (fun == &pFuu) return 1;
|
||||
if (fun == &pFup) return 1;
|
||||
if (fun == &pFdd) return 1;
|
||||
if (fun == &pFdd) return 3;
|
||||
if (fun == &pFlp) return 1;
|
||||
if (fun == &pFLL) return 1;
|
||||
if (fun == &pFpi) return 1;
|
||||
@@ -2812,47 +2821,47 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFiui) return 1;
|
||||
if (fun == &vFiuu) return 1;
|
||||
if (fun == &vFiup) return 1;
|
||||
if (fun == &vFiff) return 1;
|
||||
if (fun == &vFidd) return 1;
|
||||
if (fun == &vFiff) return 3;
|
||||
if (fun == &vFidd) return 3;
|
||||
if (fun == &vFipi) return 1;
|
||||
if (fun == &vFipu) return 1;
|
||||
if (fun == &vFipp) return 1;
|
||||
if (fun == &vFuii) return 1;
|
||||
if (fun == &vFuiI) return 1;
|
||||
if (fun == &vFuiu) return 1;
|
||||
if (fun == &vFuif) return 1;
|
||||
if (fun == &vFuid) return 1;
|
||||
if (fun == &vFuif) return 2;
|
||||
if (fun == &vFuid) return 2;
|
||||
if (fun == &vFuip) return 1;
|
||||
if (fun == &vFuui) return 1;
|
||||
if (fun == &vFuuu) return 1;
|
||||
if (fun == &vFuuf) return 1;
|
||||
if (fun == &vFuud) return 1;
|
||||
if (fun == &vFuuf) return 2;
|
||||
if (fun == &vFuud) return 2;
|
||||
if (fun == &vFuup) return 1;
|
||||
if (fun == &vFuff) return 1;
|
||||
if (fun == &vFudd) return 1;
|
||||
if (fun == &vFuff) return 3;
|
||||
if (fun == &vFudd) return 3;
|
||||
if (fun == &vFull) return 1;
|
||||
if (fun == &vFupu) return 1;
|
||||
if (fun == &vFfff) return 1;
|
||||
if (fun == &vFfpp) return 1;
|
||||
if (fun == &vFddd) return 1;
|
||||
if (fun == &vFdpp) return 1;
|
||||
if (fun == &vFfff) return 4;
|
||||
if (fun == &vFfpp) return 2;
|
||||
if (fun == &vFddd) return 4;
|
||||
if (fun == &vFdpp) return 2;
|
||||
if (fun == &vFLpp) return 1;
|
||||
if (fun == &vFpii) return 1;
|
||||
if (fun == &vFpiu) return 1;
|
||||
if (fun == &vFpif) return 1;
|
||||
if (fun == &vFpid) return 1;
|
||||
if (fun == &vFpif) return 2;
|
||||
if (fun == &vFpid) return 2;
|
||||
if (fun == &vFpip) return 1;
|
||||
if (fun == &vFpui) return 1;
|
||||
if (fun == &vFpuI) return 1;
|
||||
if (fun == &vFpuu) return 1;
|
||||
if (fun == &vFpup) return 1;
|
||||
if (fun == &vFpdd) return 1;
|
||||
if (fun == &vFpdd) return 3;
|
||||
if (fun == &vFpll) return 1;
|
||||
if (fun == &vFpLi) return 1;
|
||||
if (fun == &vFpLL) return 1;
|
||||
if (fun == &vFppi) return 1;
|
||||
if (fun == &vFppu) return 1;
|
||||
if (fun == &vFppd) return 1;
|
||||
if (fun == &vFppd) return 2;
|
||||
if (fun == &vFppL) return 1;
|
||||
if (fun == &vFppp) return 1;
|
||||
if (fun == &iFwww) return 1;
|
||||
@@ -2870,9 +2879,9 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &iFipp) return 1;
|
||||
if (fun == &iFuuu) return 1;
|
||||
if (fun == &iFuup) return 1;
|
||||
if (fun == &iFuff) return 1;
|
||||
if (fun == &iFuff) return 3;
|
||||
if (fun == &iFuLL) return 1;
|
||||
if (fun == &iFfff) return 1;
|
||||
if (fun == &iFfff) return 4;
|
||||
if (fun == &iFLwp) return 1;
|
||||
if (fun == &iFLip) return 1;
|
||||
if (fun == &iFLLp) return 1;
|
||||
@@ -2890,9 +2899,9 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &iFpup) return 1;
|
||||
if (fun == &iFpUi) return 1;
|
||||
if (fun == &iFpUU) return 1;
|
||||
if (fun == &iFpfu) return 1;
|
||||
if (fun == &iFpff) return 1;
|
||||
if (fun == &iFpdd) return 1;
|
||||
if (fun == &iFpfu) return 2;
|
||||
if (fun == &iFpff) return 3;
|
||||
if (fun == &iFpdd) return 3;
|
||||
if (fun == &iFpli) return 1;
|
||||
if (fun == &iFpll) return 1;
|
||||
if (fun == &iFplp) return 1;
|
||||
@@ -2904,7 +2913,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &iFppC) return 1;
|
||||
if (fun == &iFppW) return 1;
|
||||
if (fun == &iFppu) return 1;
|
||||
if (fun == &iFppd) return 1;
|
||||
if (fun == &iFppd) return 2;
|
||||
if (fun == &iFppl) return 1;
|
||||
if (fun == &iFppL) return 1;
|
||||
if (fun == &iFppp) return 1;
|
||||
@@ -2924,14 +2933,14 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &uFppu) return 1;
|
||||
if (fun == &uFppp) return 1;
|
||||
if (fun == &UFppi) return 1;
|
||||
if (fun == &fFuii) return 1;
|
||||
if (fun == &fFfff) return 1;
|
||||
if (fun == &fFffp) return 1;
|
||||
if (fun == &fFppL) return 1;
|
||||
if (fun == &dFddd) return 1;
|
||||
if (fun == &dFddp) return 1;
|
||||
if (fun == &dFppi) return 1;
|
||||
if (fun == &dFppp) return 1;
|
||||
if (fun == &fFuii) return -1;
|
||||
if (fun == &fFfff) return -4;
|
||||
if (fun == &fFffp) return -3;
|
||||
if (fun == &fFppL) return -1;
|
||||
if (fun == &dFddd) return -4;
|
||||
if (fun == &dFddp) return -3;
|
||||
if (fun == &dFppi) return -1;
|
||||
if (fun == &dFppp) return -1;
|
||||
if (fun == &lFipi) return 1;
|
||||
if (fun == &lFipL) return 1;
|
||||
if (fun == &lFlll) return 1;
|
||||
@@ -2960,7 +2969,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &pFupi) return 1;
|
||||
if (fun == &pFupL) return 1;
|
||||
if (fun == &pFUpi) return 1;
|
||||
if (fun == &pFddd) return 1;
|
||||
if (fun == &pFddd) return 4;
|
||||
if (fun == &pFpii) return 1;
|
||||
if (fun == &pFpiu) return 1;
|
||||
if (fun == &pFpil) return 1;
|
||||
@@ -2979,7 +2988,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &pFpLp) return 1;
|
||||
if (fun == &pFppi) return 1;
|
||||
if (fun == &pFppu) return 1;
|
||||
if (fun == &pFppf) return 1;
|
||||
if (fun == &pFppf) return 2;
|
||||
if (fun == &pFppl) return 1;
|
||||
if (fun == &pFppL) return 1;
|
||||
if (fun == &pFppp) return 1;
|
||||
@@ -2989,8 +2998,8 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFiuuu) return 1;
|
||||
if (fun == &vFiulp) return 1;
|
||||
if (fun == &vFiupu) return 1;
|
||||
if (fun == &vFifff) return 1;
|
||||
if (fun == &vFiddd) return 1;
|
||||
if (fun == &vFifff) return 4;
|
||||
if (fun == &vFiddd) return 4;
|
||||
if (fun == &vFipii) return 1;
|
||||
if (fun == &vFipup) return 1;
|
||||
if (fun == &vFippi) return 1;
|
||||
@@ -3000,9 +3009,9 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFuiui) return 1;
|
||||
if (fun == &vFuiuu) return 1;
|
||||
if (fun == &vFuiup) return 1;
|
||||
if (fun == &vFuifi) return 1;
|
||||
if (fun == &vFuiff) return 1;
|
||||
if (fun == &vFuidd) return 1;
|
||||
if (fun == &vFuifi) return 2;
|
||||
if (fun == &vFuiff) return 3;
|
||||
if (fun == &vFuidd) return 3;
|
||||
if (fun == &vFuipi) return 1;
|
||||
if (fun == &vFuipu) return 1;
|
||||
if (fun == &vFuipp) return 1;
|
||||
@@ -3011,18 +3020,18 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFuuip) return 1;
|
||||
if (fun == &vFuuui) return 1;
|
||||
if (fun == &vFuuuu) return 1;
|
||||
if (fun == &vFuuuf) return 1;
|
||||
if (fun == &vFuuud) return 1;
|
||||
if (fun == &vFuuuf) return 2;
|
||||
if (fun == &vFuuud) return 2;
|
||||
if (fun == &vFuuup) return 1;
|
||||
if (fun == &vFuupi) return 1;
|
||||
if (fun == &vFuupp) return 1;
|
||||
if (fun == &vFufff) return 1;
|
||||
if (fun == &vFuddd) return 1;
|
||||
if (fun == &vFufff) return 4;
|
||||
if (fun == &vFuddd) return 4;
|
||||
if (fun == &vFupii) return 1;
|
||||
if (fun == &vFuppi) return 1;
|
||||
if (fun == &vFUUpi) return 1;
|
||||
if (fun == &vFffff) return 1;
|
||||
if (fun == &vFdddd) return 1;
|
||||
if (fun == &vFffff) return 5;
|
||||
if (fun == &vFdddd) return 5;
|
||||
if (fun == &vFpiii) return 1;
|
||||
if (fun == &vFpiip) return 1;
|
||||
if (fun == &vFpiuL) return 1;
|
||||
@@ -3030,18 +3039,18 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFpipi) return 1;
|
||||
if (fun == &vFpipp) return 1;
|
||||
if (fun == &vFpuuu) return 1;
|
||||
if (fun == &vFpudd) return 1;
|
||||
if (fun == &vFpudd) return 3;
|
||||
if (fun == &vFpupp) return 1;
|
||||
if (fun == &vFpdii) return 1;
|
||||
if (fun == &vFpddd) return 1;
|
||||
if (fun == &vFpdii) return 2;
|
||||
if (fun == &vFpddd) return 4;
|
||||
if (fun == &vFpLLL) return 1;
|
||||
if (fun == &vFppii) return 1;
|
||||
if (fun == &vFppid) return 1;
|
||||
if (fun == &vFppid) return 2;
|
||||
if (fun == &vFppip) return 1;
|
||||
if (fun == &vFppui) return 1;
|
||||
if (fun == &vFppuu) return 1;
|
||||
if (fun == &vFppup) return 1;
|
||||
if (fun == &vFppdd) return 1;
|
||||
if (fun == &vFppdd) return 3;
|
||||
if (fun == &vFpppi) return 1;
|
||||
if (fun == &vFpppu) return 1;
|
||||
if (fun == &vFpppL) return 1;
|
||||
@@ -3068,12 +3077,12 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &iFippL) return 1;
|
||||
if (fun == &iFippp) return 1;
|
||||
if (fun == &iFuipp) return 1;
|
||||
if (fun == &iFuuff) return 1;
|
||||
if (fun == &iFuuff) return 3;
|
||||
if (fun == &iFuppi) return 1;
|
||||
if (fun == &iFuppp) return 1;
|
||||
if (fun == &iFpiii) return 1;
|
||||
if (fun == &iFpiiu) return 1;
|
||||
if (fun == &iFpiid) return 1;
|
||||
if (fun == &iFpiid) return 2;
|
||||
if (fun == &iFpiiL) return 1;
|
||||
if (fun == &iFpiip) return 1;
|
||||
if (fun == &iFpiuL) return 1;
|
||||
@@ -3115,7 +3124,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &iFpppL) return 1;
|
||||
if (fun == &iFpppp) return 1;
|
||||
if (fun == &IFppip) return 1;
|
||||
if (fun == &uFifff) return 1;
|
||||
if (fun == &uFifff) return 4;
|
||||
if (fun == &uFuuuu) return 1;
|
||||
if (fun == &uFpipu) return 1;
|
||||
if (fun == &uFpipp) return 1;
|
||||
@@ -3126,7 +3135,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &uFpppi) return 1;
|
||||
if (fun == &uFpppp) return 1;
|
||||
if (fun == &UFpipp) return 1;
|
||||
if (fun == &dFppiL) return 1;
|
||||
if (fun == &dFppiL) return -1;
|
||||
if (fun == &lFiipL) return 1;
|
||||
if (fun == &lFipiI) return 1;
|
||||
if (fun == &lFipLi) return 1;
|
||||
@@ -3151,8 +3160,8 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &pFippL) return 1;
|
||||
if (fun == &pFuiii) return 1;
|
||||
if (fun == &pFulli) return 1;
|
||||
if (fun == &pFdddd) return 1;
|
||||
if (fun == &pFlfff) return 1;
|
||||
if (fun == &pFdddd) return 5;
|
||||
if (fun == &pFlfff) return 4;
|
||||
if (fun == &pFpiii) return 1;
|
||||
if (fun == &pFpiip) return 1;
|
||||
if (fun == &pFpiuu) return 1;
|
||||
@@ -3188,8 +3197,8 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFiuipi) return 1;
|
||||
if (fun == &vFiuuuu) return 1;
|
||||
if (fun == &vFiulpp) return 1;
|
||||
if (fun == &vFiffff) return 1;
|
||||
if (fun == &vFidddd) return 1;
|
||||
if (fun == &vFiffff) return 5;
|
||||
if (fun == &vFidddd) return 5;
|
||||
if (fun == &vFilill) return 1;
|
||||
if (fun == &vFipipu) return 1;
|
||||
if (fun == &vFipipp) return 1;
|
||||
@@ -3198,7 +3207,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFuiiiu) return 1;
|
||||
if (fun == &vFuiiip) return 1;
|
||||
if (fun == &vFuiiup) return 1;
|
||||
if (fun == &vFuiifi) return 1;
|
||||
if (fun == &vFuiifi) return 2;
|
||||
if (fun == &vFuiIII) return 1;
|
||||
if (fun == &vFuiuii) return 1;
|
||||
if (fun == &vFuiuiu) return 1;
|
||||
@@ -3207,8 +3216,8 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFuiuup) return 1;
|
||||
if (fun == &vFuiupi) return 1;
|
||||
if (fun == &vFuiupu) return 1;
|
||||
if (fun == &vFuifff) return 1;
|
||||
if (fun == &vFuiddd) return 1;
|
||||
if (fun == &vFuifff) return 4;
|
||||
if (fun == &vFuiddd) return 4;
|
||||
if (fun == &vFuipii) return 1;
|
||||
if (fun == &vFuipip) return 1;
|
||||
if (fun == &vFuipup) return 1;
|
||||
@@ -3227,19 +3236,20 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFuuuuu) return 1;
|
||||
if (fun == &vFuuuup) return 1;
|
||||
if (fun == &vFuupii) return 1;
|
||||
if (fun == &vFuffff) return 1;
|
||||
if (fun == &vFudddd) return 1;
|
||||
if (fun == &vFuffff) return 5;
|
||||
if (fun == &vFudddd) return 5;
|
||||
if (fun == &vFupupi) return 1;
|
||||
if (fun == &vFuppip) return 1;
|
||||
if (fun == &vFupppp) return 1;
|
||||
if (fun == &vFddddp) return 1;
|
||||
if (fun == &vFfffff) return 6;
|
||||
if (fun == &vFddddp) return 5;
|
||||
if (fun == &vFpiiii) return 1;
|
||||
if (fun == &vFpiipp) return 1;
|
||||
if (fun == &vFpipii) return 1;
|
||||
if (fun == &vFpuipp) return 1;
|
||||
if (fun == &vFpuddd) return 1;
|
||||
if (fun == &vFpddii) return 1;
|
||||
if (fun == &vFpdddd) return 1;
|
||||
if (fun == &vFpuddd) return 4;
|
||||
if (fun == &vFpddii) return 3;
|
||||
if (fun == &vFpdddd) return 5;
|
||||
if (fun == &vFpliil) return 1;
|
||||
if (fun == &vFppiii) return 1;
|
||||
if (fun == &vFppiip) return 1;
|
||||
@@ -3337,7 +3347,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &pFpuuip) return 1;
|
||||
if (fun == &pFpuuWW) return 1;
|
||||
if (fun == &pFpuuup) return 1;
|
||||
if (fun == &pFpdddd) return 1;
|
||||
if (fun == &pFpdddd) return 5;
|
||||
if (fun == &pFppiii) return 1;
|
||||
if (fun == &pFppiip) return 1;
|
||||
if (fun == &pFppipi) return 1;
|
||||
@@ -3353,8 +3363,8 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFiiiiii) return 1;
|
||||
if (fun == &vFiiiuil) return 1;
|
||||
if (fun == &vFiuippp) return 1;
|
||||
if (fun == &vFiffiff) return 1;
|
||||
if (fun == &vFiddidd) return 1;
|
||||
if (fun == &vFiffiff) return 5;
|
||||
if (fun == &vFiddidd) return 5;
|
||||
if (fun == &vFuiiiii) return 1;
|
||||
if (fun == &vFuiiiip) return 1;
|
||||
if (fun == &vFuiiuii) return 1;
|
||||
@@ -3366,8 +3376,8 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFuiuuuu) return 1;
|
||||
if (fun == &vFuiupii) return 1;
|
||||
if (fun == &vFuiupiu) return 1;
|
||||
if (fun == &vFuiffff) return 1;
|
||||
if (fun == &vFuidddd) return 1;
|
||||
if (fun == &vFuiffff) return 5;
|
||||
if (fun == &vFuidddd) return 5;
|
||||
if (fun == &vFuipiup) return 1;
|
||||
if (fun == &vFuuiiii) return 1;
|
||||
if (fun == &vFuuiuii) return 1;
|
||||
@@ -3380,21 +3390,25 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &vFuuuuii) return 1;
|
||||
if (fun == &vFuuuuip) return 1;
|
||||
if (fun == &vFuuuuuu) return 1;
|
||||
if (fun == &vFuuuuff) return 1;
|
||||
if (fun == &vFuuuuff) return 3;
|
||||
if (fun == &vFuuuppi) return 1;
|
||||
if (fun == &vFuuuppp) return 1;
|
||||
if (fun == &vFuuffff) return 1;
|
||||
if (fun == &vFuudddd) return 1;
|
||||
if (fun == &vFuffiip) return 1;
|
||||
if (fun == &vFuddiip) return 1;
|
||||
if (fun == &vFuuffff) return 5;
|
||||
if (fun == &vFuudddd) return 5;
|
||||
if (fun == &vFuffiip) return 3;
|
||||
if (fun == &vFufffff) return 6;
|
||||
if (fun == &vFuddiip) return 3;
|
||||
if (fun == &vFupupip) return 1;
|
||||
if (fun == &vFuppppp) return 1;
|
||||
if (fun == &vFffffff) return 7;
|
||||
if (fun == &vFdddddd) return 7;
|
||||
if (fun == &vFpiiiii) return 1;
|
||||
if (fun == &vFpiiuuu) return 1;
|
||||
if (fun == &vFpiippp) return 1;
|
||||
if (fun == &vFpipppi) return 1;
|
||||
if (fun == &vFpudddd) return 1;
|
||||
if (fun == &vFpdddii) return 1;
|
||||
if (fun == &vFpudddd) return 5;
|
||||
if (fun == &vFpdddii) return 4;
|
||||
if (fun == &vFpddddd) return 6;
|
||||
if (fun == &vFppiiii) return 1;
|
||||
if (fun == &vFppiiip) return 1;
|
||||
if (fun == &vFppiipi) return 1;
|
||||
@@ -3447,6 +3461,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &iFpppipp) return 1;
|
||||
if (fun == &iFpppuii) return 1;
|
||||
if (fun == &iFpppupu) return 1;
|
||||
if (fun == &iFpppLpp) return 1;
|
||||
if (fun == &iFppppii) return 1;
|
||||
if (fun == &iFppppip) return 1;
|
||||
if (fun == &iFppppup) return 1;
|
||||
@@ -3461,6 +3476,7 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &LFpipipi) return 1;
|
||||
if (fun == &pFiiiiii) return 1;
|
||||
if (fun == &pFiCiiCi) return 1;
|
||||
if (fun == &pFdddddd) return 7;
|
||||
if (fun == &pFpiiiiu) return 1;
|
||||
if (fun == &pFpiiCCC) return 1;
|
||||
if (fun == &pFpippip) return 1;
|
||||
@@ -3474,20 +3490,27 @@ int isSimpleWrapper(wrapper_t fun) {
|
||||
if (fun == &pFppippp) return 1;
|
||||
if (fun == &pFpppppu) return 1;
|
||||
if (fun == &pFpppppp) return 1;
|
||||
if (fun == &vFiiffffp) return 1;
|
||||
if (fun == &vFuipffff) return 1;
|
||||
if (fun == &vFuipdddd) return 1;
|
||||
if (fun == &vFuuuufff) return 1;
|
||||
if (fun == &vFuuuffff) return 1;
|
||||
if (fun == &vFuuudddd) return 1;
|
||||
if (fun == &vFuuffiip) return 1;
|
||||
if (fun == &vFuuddiip) return 1;
|
||||
if (fun == &vFpddiidd) return 1;
|
||||
if (fun == &iFppppdpi) return 1;
|
||||
if (fun == &pFifffppp) return 1;
|
||||
if (fun == &vFuuuuufff) return 1;
|
||||
if (fun == &iFdddpppppp) return 1;
|
||||
if (fun == &vFuffiiffiip) return 1;
|
||||
if (fun == &vFuddiiddiip) return 1;
|
||||
if (fun == &vFiiffffp) return 5;
|
||||
if (fun == &vFuipffff) return 5;
|
||||
if (fun == &vFuipdddd) return 5;
|
||||
if (fun == &vFuuuufff) return 4;
|
||||
if (fun == &vFuuuffff) return 5;
|
||||
if (fun == &vFuuudddd) return 5;
|
||||
if (fun == &vFuuffiip) return 3;
|
||||
if (fun == &vFuuddiip) return 3;
|
||||
if (fun == &vFuffffff) return 7;
|
||||
if (fun == &vFudddddd) return 7;
|
||||
if (fun == &vFpddiidd) return 5;
|
||||
if (fun == &vFpdddddd) return 7;
|
||||
if (fun == &iFppppdpi) return 2;
|
||||
if (fun == &pFifffppp) return 4;
|
||||
if (fun == &vFuuuuufff) return 4;
|
||||
if (fun == &vFffffffff) return 9;
|
||||
if (fun == &vFuffffffff) return 9;
|
||||
if (fun == &vFffuuuufff) return 6;
|
||||
if (fun == &iFdddpppppp) return 4;
|
||||
if (fun == &vFuffiiffiip) return 5;
|
||||
if (fun == &vFuddiiddiip) return 5;
|
||||
if (fun == &vFppdddddddd) return 9;
|
||||
return 0;
|
||||
}
|
||||
@@ -64,6 +64,7 @@ void WFp(x64emu_t *emu, uintptr_t fnc);
|
||||
void uFv(x64emu_t *emu, uintptr_t fnc);
|
||||
void uFi(x64emu_t *emu, uintptr_t fnc);
|
||||
void uFu(x64emu_t *emu, uintptr_t fnc);
|
||||
void uFU(x64emu_t *emu, uintptr_t fnc);
|
||||
void uFd(x64emu_t *emu, uintptr_t fnc);
|
||||
void uFp(x64emu_t *emu, uintptr_t fnc);
|
||||
void UFv(x64emu_t *emu, uintptr_t fnc);
|
||||
@@ -976,6 +977,7 @@ void iFpppipi(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpppipp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpppuii(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpppupu(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpppLpp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFppppii(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFppppip(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFppppup(x64emu_t *emu, uintptr_t fnc);
|
||||
@@ -1078,6 +1080,7 @@ void iFpiiiLwp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpiiuuiu(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpiuiipp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpiupiii(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpippLpp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpippppp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpuuiuui(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpuupppp(x64emu_t *emu, uintptr_t fnc);
|
||||
@@ -1160,6 +1163,7 @@ void iFuiifpppp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFLLLLLLLL(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpiiiiipi(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpWCuWCuu(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpuippLpp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpuuiiiii(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFpupppppp(x64emu_t *emu, uintptr_t fnc);
|
||||
void iFppIIIppp(x64emu_t *emu, uintptr_t fnc);
|
||||
|
||||
@@ -1958,7 +1958,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
|
||||
(void)emu;
|
||||
if(prot&PROT_WRITE)
|
||||
prot|=PROT_READ; // PROT_READ is implicit with PROT_WRITE on i386
|
||||
if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "mmap64(%p, %lu, 0x%x, 0x%x, %d, %ld) =>", addr, length, prot, flags, fd, offset);}
|
||||
if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "mmap64(%p, %lu, 0x%x, 0x%x, %d, %ld) => ", addr, length, prot, flags, fd, offset);}
|
||||
#ifndef NOALIGN
|
||||
if(flags&0x40) {
|
||||
// 0x40 is MAP_32BIT, wich only exist on x86_64!
|
||||
@@ -1967,6 +1967,9 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
|
||||
addr = find32bitBlock(length);
|
||||
else
|
||||
addr = findBlockNearHint(addr, length);
|
||||
} else if (box64_wine) {
|
||||
if(!addr)
|
||||
addr = find47bitBlock(length);
|
||||
}
|
||||
#endif
|
||||
void* ret = mmap64(addr, length, prot, flags, fd, offset);
|
||||
|
||||
@@ -15,7 +15,7 @@ GO(accept, iFipp)
|
||||
//GO(accept4,
|
||||
GOW(access, iFpi)
|
||||
//GO(acct,
|
||||
//GOW(addmntent,
|
||||
GOW(addmntent, iFpp)
|
||||
//GOW(addseverity,
|
||||
//GOW(adjtime,
|
||||
//GO(__adjtimex,
|
||||
@@ -153,7 +153,7 @@ GOW(close, iFi)
|
||||
GOW(closedir, iFp)
|
||||
GO(closelog, vFv)
|
||||
//GO(__close_nocancel,
|
||||
//GO(__cmsg_nxthdr,
|
||||
GO(__cmsg_nxthdr, pFpp)
|
||||
GO(confstr, LFipL)
|
||||
//GO(__confstr_chk,
|
||||
GOW(__connect, iFipu)
|
||||
@@ -233,9 +233,9 @@ GOW(duplocale, pFp)
|
||||
//GO(endaliasent,
|
||||
//GO(endfsent,
|
||||
//GO(endgrent,
|
||||
//GO(endhostent,
|
||||
//GO(__endmntent,
|
||||
//GOW(endmntent,
|
||||
GO(endhostent, vFv)
|
||||
GO(__endmntent, iFp)
|
||||
GOW(endmntent, iFp)
|
||||
//GO(endnetent,
|
||||
//GO(endnetgrent,
|
||||
GO(endprotoent, vFv)
|
||||
@@ -452,7 +452,7 @@ GO(fts_set, iFppi)
|
||||
GOM(ftw, iFEppi)
|
||||
GOM(ftw64, iFEppi)
|
||||
GOW(funlockfile, vFp)
|
||||
//GO(futimens,
|
||||
GO(futimens, iFip)
|
||||
//GOW(futimes,
|
||||
//GO(futimesat,
|
||||
//GO(fwide,
|
||||
@@ -517,14 +517,14 @@ GO(getgrent, pFv)
|
||||
//GO(getgrouplist,
|
||||
GOW(getgroups, iFip)
|
||||
//GO(__getgroups_chk,
|
||||
//GO(gethostbyaddr,
|
||||
//GO(gethostbyaddr_r,
|
||||
GO(gethostbyaddr, pFpui)
|
||||
GO(gethostbyaddr_r, iFpuippLpp)
|
||||
GO(gethostbyname, pFp)
|
||||
//GO(gethostbyname2,
|
||||
//GO(gethostbyname2_r,
|
||||
//GO(gethostbyname_r,
|
||||
//GO(gethostent,
|
||||
//GO(gethostent_r,
|
||||
GO(gethostbyname2, pFpi)
|
||||
GO(gethostbyname2_r, iFpippLpp)
|
||||
GO(gethostbyname_r, iFpppLpp)
|
||||
GO(gethostent, pFv)
|
||||
GO(gethostent_r, iFppLpp)
|
||||
//GO(gethostid,
|
||||
GOW(gethostname, iFpL)
|
||||
//GO(__gethostname_chk,
|
||||
@@ -537,9 +537,9 @@ GOW(getline, iFppp)
|
||||
GO(getlogin, pFv)
|
||||
GOW(getlogin_r, iFpL)
|
||||
//GO(__getlogin_r_chk,
|
||||
//GO(getmntent,
|
||||
//GO(__getmntent_r,
|
||||
//GOW(getmntent_r,
|
||||
GO(getmntent, pFp)
|
||||
GO(__getmntent_r, pFpppi)
|
||||
GOW(getmntent_r, pFpppi)
|
||||
//GO(getmsg,
|
||||
//GO(get_myaddress,
|
||||
GO(getnameinfo, iFpupLpLi)
|
||||
@@ -655,16 +655,16 @@ GOW(globfree64, vFp)
|
||||
GO(gmtime, pFp)
|
||||
GO(__gmtime_r, pFpp)
|
||||
GOW(gmtime_r, pFpp)
|
||||
//GOW(gnu_dev_major,
|
||||
//GOW(gnu_dev_makedev,
|
||||
//GOW(gnu_dev_minor,
|
||||
//GOW(gnu_get_libc_release,
|
||||
//GOW(gnu_get_libc_version,
|
||||
GOW(gnu_dev_major, uFU)
|
||||
GOW(gnu_dev_makedev, UFii)
|
||||
GOW(gnu_dev_minor, uFU)
|
||||
GOW(gnu_get_libc_release, pFv)
|
||||
GOW(gnu_get_libc_version, pFv)
|
||||
//GO(grantpt,
|
||||
//GOW(group_member,
|
||||
//GOW(gsignal,
|
||||
//GO(gtty,
|
||||
//GOW(hasmntopt,
|
||||
GOW(hasmntopt, pFpp)
|
||||
//GO(hcreate,
|
||||
//GOW(hcreate_r,
|
||||
//GOW(hdestroy,
|
||||
@@ -672,7 +672,7 @@ GOW(gmtime_r, pFpp)
|
||||
//DATA(h_errlist,
|
||||
//DATAB(__h_errno,
|
||||
//GO(__h_errno_location,
|
||||
//GO(herror,
|
||||
GO(herror, vFp)
|
||||
//GO(host2netname,
|
||||
//GO(hsearch,
|
||||
//GOW(hsearch_r,
|
||||
@@ -684,9 +684,9 @@ GO(iconv_close, iFL)
|
||||
GO(iconv_open, LFpp)
|
||||
//GO(__idna_from_dns_encoding,
|
||||
//GO(__idna_to_dns_encoding,
|
||||
//GOW(if_freenameindex,
|
||||
GOW(if_freenameindex, vFp)
|
||||
GOW(if_indextoname, pFup)
|
||||
//GOW(if_nameindex,
|
||||
GOW(if_nameindex, pFv)
|
||||
GOW(if_nametoindex, uFp)
|
||||
//GOW(imaxabs,
|
||||
//GOW(imaxdiv,
|
||||
@@ -1617,7 +1617,7 @@ GO(seteuid, iFu)
|
||||
GOW(setgid, iFp)
|
||||
//GO(setgrent,
|
||||
//GO(setgroups,
|
||||
//GO(sethostent,
|
||||
GO(sethostent, vFi)
|
||||
//GO(sethostid,
|
||||
GO(sethostname, iFpL)
|
||||
//GO(setipv4sourcefilter,
|
||||
@@ -1628,8 +1628,8 @@ GO(setlinebuf, vFp)
|
||||
GO(setlocale, pFip)
|
||||
//GO(setlogin,
|
||||
GO(setlogmask, iFi)
|
||||
//GO(__setmntent,
|
||||
//GOW(setmntent,
|
||||
GO(__setmntent, pFpp)
|
||||
GOW(setmntent, pFpp)
|
||||
//GO(setnetent,
|
||||
//GO(setnetgrent,
|
||||
//GO(setns,
|
||||
@@ -2035,7 +2035,7 @@ GOW(uselocale, pFp)
|
||||
GO(usleep, iFu)
|
||||
//GO(ustat,
|
||||
GO(utime, iFpp)
|
||||
//GO(utimensat,
|
||||
GO(utimensat, iFippi)
|
||||
GOW(utimes, iFpp)
|
||||
//GOW(utmpname,
|
||||
//GO(utmpxname,
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
div 1, 1 => 1 / 0
|
||||
div 10, 5 => 2 / 0
|
||||
div 10, 3 => 3 / 1
|
||||
div 1, 18446744073709551615 => 0 / 1
|
||||
div 10, 18446744073709551613 => 0 / 10
|
||||
div 18446744073709551606, 18446744073709551613 => 0 / 18446744073709551606
|
||||
idiv 1, 1 => 1 / 0
|
||||
idiv 10, 5 => 2 / 0
|
||||
idiv 10, 3 => 3 / 1
|
||||
idiv 1, -1 => -1 / 0
|
||||
idiv 10, -3 => -3 / 1
|
||||
idiv -10, -3 => 3 / -1
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(__x86_64__)
|
||||
uint64_t _div_(uint64_t a, uint64_t b, uint64_t *r)
|
||||
{
|
||||
uint64_t ret, rem;
|
||||
asm volatile (
|
||||
"xor %%rdx, %%rdx\n"
|
||||
"div %%rcx\n"
|
||||
"mov %%rdx, %%rbx\n"
|
||||
:"=a" (ret), "=b" (rem):"a" (a), "c" (b):"rdx","cc");
|
||||
*r = rem;
|
||||
return ret;
|
||||
}
|
||||
uint64_t _idiv_(uint64_t a, uint64_t b, uint64_t *r)
|
||||
{
|
||||
uint64_t ret, rem;
|
||||
asm volatile (
|
||||
"cqo\n"
|
||||
"idiv %%rcx\n"
|
||||
"mov %%rdx, %%rbx\n"
|
||||
:"=a" (ret), "=b" (rem):"a" (a), "c" (b):"rdx","cc");
|
||||
*r = rem;
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#endif
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
uint64_t datas[][2] = {{1,1},{10,5},{10,3},{1, (uint64_t)-1}, {10, (uint64_t)-3}, {(uint64_t)-10, (uint64_t)-3}};
|
||||
|
||||
int sz = sizeof(datas)/sizeof(datas[0]);
|
||||
for(int i=0; i<sz; ++i) {
|
||||
uint64_t rem = 0;
|
||||
uint64_t d = _div_(datas[i][0], datas[i][1], &rem);
|
||||
printf("div %llu, %llu => %llu / %llu\n", datas[i][0], datas[i][1], d, rem);
|
||||
}
|
||||
for(int i=0; i<sz; ++i) {
|
||||
uint64_t rem = 0;
|
||||
uint64_t d = _idiv_(datas[i][0], datas[i][1], &rem);
|
||||
printf("idiv %lld, %lld => %lld / %lld\n", datas[i][0], datas[i][1], d, rem);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user