changeset 754:cfa402c6ced8

Handle far calls in call_args and call_args_abi
author Michael Pavone <pavone@retrodev.com>
date Sat, 27 Jun 2015 11:39:55 -0700
parents cee1275f5d08
children 7306b3967c51
files gen_x86.c
diffstat 1 files changed, 24 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/gen_x86.c	Thu Jun 25 09:02:42 2015 -0700
+++ b/gen_x86.c	Sat Jun 27 11:39:55 2015 -0700
@@ -2003,6 +2003,27 @@
 	code->cur = out;
 }
 
+void call_raxfallback(code_info *code, code_ptr fun)
+{
+	check_alloc_code(code, 5);
+	code_ptr out = code->cur;
+	ptrdiff_t disp = fun-(out+5);
+	if (disp <= 0x7FFFFFFF && disp >= -2147483648) {
+		*(out++) = OP_CALL;
+		*(out++) = disp;
+		disp >>= 8;
+		*(out++) = disp;
+		disp >>= 8;
+		*(out++) = disp;
+		disp >>= 8;
+		*(out++) = disp;
+	} else {
+		mov_ir(code, fun, RAX, SZ_PTR);
+		call_r(code, RAX);
+	}
+	code->cur = out;
+}
+
 void call_r(code_info *code, uint8_t dst)
 {
 	check_alloc_code(code, 2);
@@ -2091,7 +2112,7 @@
 	va_start(args, num_args);
 	uint32_t adjust = prep_args(code, num_args, args);
 	va_end(args);
-	call(code, fun);
+	call_raxfallback(code, fun);
 	if (adjust) {
 		add_ir(code, adjust, RSP, SZ_PTR);
 	}
@@ -2108,7 +2129,7 @@
 	code_ptr do_adjust_rsp = code->cur + 1;
 	jcc(code, CC_NZ, code->cur + 2);
 #endif
-	call(code, fun);
+	call_raxfallback(code, fun);
 	if (adjust) {
 		add_ir(code, adjust, RSP, SZ_PTR);
 	}
@@ -2117,7 +2138,7 @@
 	jmp(code, code->cur + 2);
 	*do_adjust_rsp = code->cur - (do_adjust_rsp+1);
 	sub_ir(code, 8, RSP, SZ_PTR);
-	call(code, fun);
+	call_raxfallback(code, fun);
 	add_ir(code, adjust + 8 , RSP, SZ_PTR);
 	*no_adjust_rsp = code->cur - (no_adjust_rsp+1);
 #endif