about summary refs log tree commit diff stats
path: root/rebuild_wrappers.py
diff options
context:
space:
mode:
Diffstat (limited to 'rebuild_wrappers.py')
-rwxr-xr-xrebuild_wrappers.py200
1 files changed, 127 insertions, 73 deletions
diff --git a/rebuild_wrappers.py b/rebuild_wrappers.py
index e22c52d6..7067a8e1 100755
--- a/rebuild_wrappers.py
+++ b/rebuild_wrappers.py
@@ -150,12 +150,12 @@ class FunctionConvention(object):
 		self.ident = ident
 		self.name = convname
 		self.values = valid_chars
-# Free letters:  B   FG  J      QR T   XYZab  e gh jk mno qrst   xyz
+# Free letters:  B   FG  J      QR T   XYZa   e gh jk mno qrst   xyz
 conventions = {
-	'F': FunctionConvention('F', "System V", ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X']),
+	'F': FunctionConvention('F', "System V", ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', 'b']),
 	'W': FunctionConvention('W', "Windows",  ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd',      'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M',      'P', 'A'])
 }
-sortedvalues = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', '0', '1']
+sortedvalues = ['E', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', 'N', 'M', 'H', 'P', 'A', 'x', 'X', 'b', '0', '1']
 assert(all(all(c not in conv.values[:i] and c in sortedvalues for i, c in enumerate(conv.values)) for conv in conventions.values()))
 
 class FunctionType(str):
@@ -830,7 +830,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
 	return_x87: str = "DK"
 	
 	# Sanity checks
-	forbidden_simple: str = "EDKVOSNMHPAxX"
+	forbidden_simple: str = "EDKVOSNMHPAxXb"
 	assert(len(allowed_simply) + len(allowed_regs) + len(allowed_fpr) + len(forbidden_simple) == len(allowed_conv.values))
 	assert(all(c not in allowed_regs for c in allowed_simply))
 	assert(all(c not in allowed_simply + allowed_regs for c in allowed_fpr))
@@ -918,6 +918,8 @@ def main(root: str, files: Iterable[Filename], ver: str):
 		#define ST0val ST0.d
 		
 		int of_convert(int);
+		void* align_xcb_connection(void* src);
+		void unalign_xcb_connection(void* src, void* dst);
 		
 		""",
 		"wrapper.h": """
@@ -954,6 +956,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
 		// 0 = constant 0, 1 = constant 1
 		// x = float complex
 		// X = double complex
+		// b = xcb_connection_t*
 		
 		""",
 		"fntypes.h": """
@@ -1015,8 +1018,8 @@ def main(root: str, files: Iterable[Filename], ver: str):
 	# Rewrite the wrapper.c file:
 	# i and u should only be 32 bits
 	td_types = {
-		#      E            v       c         w          i          I          C          W           u           U           f        d         D              K         l           L            p        V        O          S        N      M      H                    P        A			x				X
-		'F': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...", "unsigned __int128", "void*", "void*", "complexf_t", "complex_t"],
+		#      E            v       c         w          i          I          C          W           u           U           f        d         D              K         l           L            p        V        O          S        N      M      H                    P        A			x				X         b
+		'F': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...", "unsigned __int128", "void*", "void*", "complexf_t", "complex_t", "void*"],
 		#      E            v       c         w          i          I          C          W           u           U           f        d         K         l           L            p        V        O          S        N      M      P        A
 		'W': ["x64emu_t*", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "...", "...", "void*", "void*"]
 	}
@@ -1074,8 +1077,9 @@ def main(root: str, files: Iterable[Filename], ver: str):
 				"unsigned __int128 u128 = fn({0}); R_RAX=(u128&0xFFFFFFFFFFFFFFFFL); R_RDX=(u128>>64)&0xFFFFFFFFFFFFFFFFL;", # H
 				"\n#error Invalid return type: pointer in the stack\n",    # P
 				"\n#error Invalid return type: va_list\n",                 # A
-				'from_complexf(emu, fn({0})));', 	                          # x
-				'from_complex(emu, fn({0})));'                             # X
+				'from_complexf(emu, fn({0})));', 	                       # x
+				'from_complex(emu, fn({0})));',                            # X
+				"\n#error Invalid return type: xcb_connection_t*\n",       # b
 			],
 			conventions['W']: [
 				"\n#error Invalid return type: emulator\n",                # E
@@ -1105,17 +1109,17 @@ def main(root: str, files: Iterable[Filename], ver: str):
 		}
 		
 		# vreg: value is in a general register
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X
-		vreg   = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 2, 2, 0, 1, 0, 0]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  b
+		vreg   = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 2, 2, 0, 1, 0, 0, 1]
 		# vxmm: value is in a XMM register
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X
-		vxmm   = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  b
+		vxmm   = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0]
 		# vother: value is elsewere
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X
-		vother = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  b
+		vother = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
 		# vstack: value is on the stack (or out of register)
-		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X
-		vstack = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 2]
+		#         E  v  c  w  i  I  C  W  u  U  f  d  D  K  l  L  p  V  O  S  N  M  H  P  A  x  X  b
+		vstack = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1]
 		arg_r = [
 			"",                            # E
 			"",                            # v
@@ -1144,64 +1148,67 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"(void*){p}, ",                # A
 			"",	                           # x
 			"",                            # X
+			"aligned_xcb, ",               # b
 		]
 		arg_x = [
-			"",                      # E
-			"",                      # v
-			"",                      # c
-			"",                      # w
-			"",                      # i
-			"",                      # I
-			"",                      # C
-			"",                      # W
-			"",                      # u
-			"",                      # U
-			"emu->xmm[{p}].f[0], ",  # f
-			"emu->xmm[{p}].d[0], ",  # d
-			"",                      # D
-			"",                      # K
-			"",                      # l
-			"",                      # L
-			"",                      # p
-			"",                      # V
-			"",                      # O
-			"",                      # S
-			"",                      # N
-			"",                      # M
-			"",                      # H
-			"",                      # P
-			"",                      # A
-			"to_complexf(emu, {p}),",# x
-			"to_complex(emu, {p}),"  # X
+			"",                       # E
+			"",                       # v
+			"",                       # c
+			"",                       # w
+			"",                       # i
+			"",                       # I
+			"",                       # C
+			"",                       # W
+			"",                       # u
+			"",                       # U
+			"emu->xmm[{p}].f[0], ",   # f
+			"emu->xmm[{p}].d[0], ",   # d
+			"",                       # D
+			"",                       # K
+			"",                       # l
+			"",                       # L
+			"",                       # p
+			"",                       # V
+			"",                       # O
+			"",                       # S
+			"",                       # N
+			"",                       # M
+			"",                       # H
+			"",                       # P
+			"",                       # A
+			"to_complexf(emu, {p}),", # x
+			"to_complex(emu, {p}),",  # X
+			"",                       # b
 		]
 		arg_o = [
-			"emu, ",                   # E
-			"",                        # v
-			"",                        # c
-			"",                        # w
-			"",                        # i
-			"",                        # I
-			"",                        # C
-			"",                        # W
-			"",                        # u
-			"",                        # U
-			"",                        # f
-			"",                        # d
-			"",                        # D
-			"",                        # K
-			"",                        # l
-			"",                        # L
-			"",                        # p
-			"(void*)(R_RSP + {p}), ",  # V
-			"",                        # O
-			"",                        # S
-			"",                        # N
-			"",                        # M
-			"",                        # H
-			"",                        # P
-			"",                        # A
-			"",                        # x
-			"",                        # X
+			"emu, ",                  # E
+			"",                       # v
+			"",                       # c
+			"",                       # w
+			"",                       # i
+			"",                       # I
+			"",                       # C
+			"",                       # W
+			"",                       # u
+			"",                       # U
+			"",                       # f
+			"",                       # d
+			"",                       # D
+			"",                       # K
+			"",                       # l
+			"",                       # L
+			"",                       # p
+			"(void*)(R_RSP + {p}), ", # V
+			"",                       # O
+			"",                       # S
+			"",                       # N
+			"",                       # M
+			"",                       # H
+			"",                       # P
+			"",                       # A
+			"",                       # x
+			"",                       # X
+			"",                       # b
 		]
 		arg_s = [
 			"",                                         # E
@@ -1231,6 +1238,7 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			"*(void**)(R_RSP + {p}), ",                 # A
 			"*(complexf_t*)(R_RSP + {p}), ",            # x
 			"*(complex_t*)(R_RSP + {p}), ",             # X
+			"aligned_xcb, ",                            # b
 		]
 		
 		# Asserts
@@ -1282,6 +1290,50 @@ def main(root: str, files: Iterable[Filename], ver: str):
 		
 		# Helper functions to write the function definitions
 		systemVconv = conventions['F']
+		def function_pre_systemV(args: FunctionType, d: int = 8, r: int = 0, x: int = 0) -> (Optional[str], str):
+			# args: string of argument types
+			# d: delta (in the stack)
+			# r: general register no
+			# x: XMM register no
+			if len(args) == 0:
+				return None, ""
+			
+			# Redirections
+			if args[0] == "0":
+				return function_pre_systemV(args[1:], d, r, x)
+			elif args[0] == "1":
+				return function_pre_systemV(args[1:], d, r, x)
+			
+			idx = systemVconv.values.index(args[0])
+			# Name of the registers
+			reg_arg = ["R_RDI", "R_RSI", "R_RDX", "R_RCX", "R_R8", "R_R9"]
+			if args[0] == "b":
+				if 'b' in args[1:]:
+					raise NotImplementedError("Multiple XCB connections unsupported")
+				content = ""
+				if r < len(reg_arg):
+					content = reg_arg[r]
+				else:
+					content = "(R_RSP + " + str(d) + ")"
+				return "(void*)" + content, f"void *aligned_xcb = align_xcb_connection((void*){content}); "
+			elif (r < len(reg_arg)) and (vreg[idx] > 0):
+				for _ in range(vreg[idx]):
+					if r < len(reg_arg):
+						r = r + 1
+					else:
+						d = d + 8
+				return function_pre_systemV(args[1:], d, r, x)
+			elif (x < 8) and (vxmm[idx] > 0):
+				return function_pre_systemV(args[1:], d, r, x+1)
+			elif vstack[idx] > 0:
+				return function_pre_systemV(args[1:], d+8*vstack[idx], r, x)
+			else:
+				return function_pre_systemV(args[1:], d, r, x)
+		def function_post_systemV(content: Optional[str]) -> str:
+			if content is not None:
+				return f" unalign_xcb_connection(aligned_xcb, {content});"
+			else:
+				return ""
 		def function_args_systemV(args: FunctionType, d: int = 8, r: int = 0, x: int = 0) -> str:
 			# args: string of argument types
 			# d: delta (in the stack)
@@ -1361,9 +1413,11 @@ def main(root: str, files: Iterable[Filename], ver: str):
 			# Generic function
 			conv = N.get_convention()
 			if conv is systemVconv:
-				f.write(vals[conv][conv.values.index(N[0])].format(function_args_systemV(N[2:])[:-2]) + " }\n")
+				prepost, pre = function_pre_systemV(N[2:])
+				f.write(pre + vals[conv][conv.values.index(N[0])].format(function_args_systemV(N[2:])[:-2]) + function_post_systemV(prepost))
 			else:
-				f.write(vals[conv][conv.values.index(N[0])].format(function_args_windows(N[2:])[:-2]) + " }\n")
+				f.write(vals[conv][conv.values.index(N[0])].format(function_args_windows(N[2:])[:-2]))
+			f.write(" }\n")
 		
 		for k in gbls:
 			if k != str(Clauses()):
@@ -1480,6 +1534,6 @@ if __name__ == '__main__':
 		if v == "--":
 			limit.append(i)
 	Define.defines = list(map(DefineType, sys.argv[2:limit[0]]))
-	if main(sys.argv[1], sys.argv[limit[0]+1:], "2.2.0.18") != 0:
+	if main(sys.argv[1], sys.argv[limit[0]+1:], "2.3.0.19") != 0:
 		exit(2)
 	exit(0)