about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xrebuild_wrappers.py23
-rwxr-xr-xsrc/dynarec/arm64/dynarec_arm64_00.c9
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_0.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c5
-rw-r--r--src/wrapped/generated/wrapper.c18
-rw-r--r--src/wrapped/generated/wrapper.h1
8 files changed, 54 insertions, 8 deletions
diff --git a/rebuild_wrappers.py b/rebuild_wrappers.py
index a9659b59..b017fef6 100755
--- a/rebuild_wrappers.py
+++ b/rebuild_wrappers.py
@@ -867,6 +867,19 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			simple_wraps[k] = tmp
 	simple_idxs = sorted(simple_wraps.keys(), key=lambda x: Clauses(x).splitdef())
 	
+	retx87_wraps: Dict[ClausesStr, List[Tuple[FunctionType, int]]] = {}
+	return_x87: str = "DK"
+	def check_return_x87(v: FunctionType) -> bool:
+		if v[0] in return_x87:
+			return True
+		return False
+
+	for k in gbls:
+		tmp = [ (v, ret_val) for v, ret_val in map(lambda v: (v, check_return_x87(v)), gbls[k]) if ret_val is not False ]
+		if tmp:
+			retx87_wraps[k] = tmp
+	retx87_idxs = sorted(retx87_wraps.keys(), key=lambda x: Clauses(x).splitdef())
+
 	# Now the files rebuilding part
 	# File headers and guards
 	files_header = {
@@ -1380,6 +1393,16 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			if k != str(Clauses()):
 				file.write("#endif\n")
 		file.write("\treturn 0;\n}\n")
+		# Write the isRetX87Wrapper function
+		file.write("\nint isRetX87Wrapper(wrapper_t fun) {\n")
+		for k in retx87_idxs:
+			if k != str(Clauses()):
+				file.write("#if " + k + "\n")
+			for vf, val in retx87_wraps[k]:
+				file.write("\tif (fun == &" + vf + ") return 1;\n")
+			if k != str(Clauses()):
+				file.write("#endif\n")
+		file.write("\treturn 0;\n}\n")
 		
 		file.write(files_guard["wrapper.c"].format(lbr="{", rbr="}", version=ver))
 	
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 10d4b41b..9ba035fe 100755
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -25,6 +25,7 @@
 #include "dynarec_arm64_helper.h"
 
 int isSimpleWrapper(wrapper_t fun);
+int isRetX87Wrapper(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)
 {
@@ -1901,6 +1902,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     x87_forget(dyn, ninst, x3, x4, 0);
                     sse_purge07cache(dyn, ninst, x3);
                     tmp = isSimpleWrapper(*(wrapper_t*)(addr));
+                    if(isRetX87Wrapper(*(wrapper_t*)(addr)))
+                        x87_do_push_empty(dyn, ninst, x3);
                     if((box64_log<2 && !cycle_log) && tmp) {
                         //GETIP(ip+3+8+8); // read the 0xCC
                         call_n(dyn, ninst, *(void**)(addr+8), tmp);
@@ -2392,9 +2395,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     SKIPTEST(x1);    // disable test as this hack dos 2 instructions for 1
                     // calling a native function
                     sse_purge07cache(dyn, ninst, x3);
-                    if((box64_log<2 && !cycle_log) && dyn->insts[ninst].natcall)
+                    if((box64_log<2 && !cycle_log) && dyn->insts[ninst].natcall) {
                         tmp=isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2));
-                    else
+                        if(isRetX87Wrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2)))
+                            x87_do_push_empty(dyn, ninst, x3);
+                    } else
                         tmp=0;
                     if((box64_log<2 && !cycle_log) && dyn->insts[ninst].natcall && tmp) {
                         //GETIP(ip+3+8+8); // read the 0xCC
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c
index 684aa490..5f529fb7 100644
--- a/src/dynarec/rv64/dynarec_rv64_00.c
+++ b/src/dynarec/rv64/dynarec_rv64_00.c
@@ -25,8 +25,6 @@
 #include "dynarec_rv64_functions.h"
 #include "dynarec_rv64_helper.h"
 
-int isSimpleWrapper(wrapper_t fun);
-
 uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
     uint8_t opcode;
diff --git a/src/dynarec/rv64/dynarec_rv64_00_0.c b/src/dynarec/rv64/dynarec_rv64_00_0.c
index c9356618..a0ff3746 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_0.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_0.c
@@ -25,8 +25,6 @@
 #include "dynarec_rv64_functions.h"
 #include "dynarec_rv64_helper.h"
 
-int isSimpleWrapper(wrapper_t fun);
-
 uintptr_t dynarec64_00_0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
     uint8_t nextop, opcode;
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index 7a5794b9..20333f96 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -25,8 +25,6 @@
 #include "dynarec_rv64_functions.h"
 #include "dynarec_rv64_helper.h"
 
-int isSimpleWrapper(wrapper_t fun);
-
 uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
     uint8_t nextop, opcode;
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index a2744912..ad4e932e 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -26,6 +26,7 @@
 #include "dynarec_rv64_helper.h"
 
 int isSimpleWrapper(wrapper_t fun);
+int isRetX87Wrapper(wrapper_t fun);
 
 uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
 {
@@ -307,6 +308,8 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     // disabling isSimpleWrapper because all signed value less than 64bits needs to be sign extended
                     // and return value needs to be cleanned up
                     tmp = 0;//isSimpleWrapper(*(wrapper_t*)(addr));
+                    if(isRetX87Wrapper(*(wrapper_t*)(addr)))
+                        x87_do_push_empty(dyn, ninst, x3);
                     if(tmp<0 || tmp>1)
                         tmp=0;  //TODO: removed when FP is in place
                     if((box64_log<2 && !cycle_log) && tmp) {
@@ -655,6 +658,8 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         tmp=0;//isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2));
                         if(tmp>1 || tmp<0)
                             tmp=0;  // float paramters not ready!
+                        if(isRetX87Wrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2)))
+                            x87_do_push_empty(dyn, ninst, x3);
                     } else
                         tmp=0;
                     if((box64_log<2 && !cycle_log) && dyn->insts[ninst].natcall && tmp) {
diff --git a/src/wrapped/generated/wrapper.c b/src/wrapped/generated/wrapper.c
index 219119ec..1c6e79d1 100644
--- a/src/wrapped/generated/wrapper.c
+++ b/src/wrapped/generated/wrapper.c
@@ -7455,3 +7455,21 @@ int isSimpleWrapper(wrapper_t fun) {
 #endif
 	return 0;
 }
+
+int isRetX87Wrapper(wrapper_t fun) {
+	if (fun == &DFDi) return 1;
+	if (fun == &DFDD) return 1;
+	if (fun == &DFDp) return 1;
+	if (fun == &DFpp) return 1;
+	if (fun == &DFppi) return 1;
+	if (fun == &DFppp) return 1;
+#if defined(HAVE_LD80BITS)
+	if (fun == &DFD) return 1;
+#endif
+#if !defined(HAVE_LD80BITS)
+	if (fun == &KFK) return 1;
+	if (fun == &KFKK) return 1;
+	if (fun == &KFKp) return 1;
+#endif
+	return 0;
+}
diff --git a/src/wrapped/generated/wrapper.h b/src/wrapped/generated/wrapper.h
index 8bd47ed1..6bf6617d 100644
--- a/src/wrapped/generated/wrapper.h
+++ b/src/wrapped/generated/wrapper.h
@@ -2870,5 +2870,6 @@ void iFEpvvppp(x64emu_t *emu, uintptr_t fnc);
 void iFEpuvvppp(x64emu_t *emu, uintptr_t fnc);
 
 int isSimpleWrapper(wrapper_t fun);
+int isRetX87Wrapper(wrapper_t fun);
 
 #endif // __WRAPPER_H_