diff gen_x86.c @ 894:a7774fc2de4b

Partially working change to do proper stack alignment rather than doing a lame alignment check when calling a C compile dfunction. 68K core seems okay, but Z80 is busted.
author Michael Pavone <pavone@retrodev.com>
date Wed, 25 Nov 2015 08:40:45 -0800
parents 724bbec47f86
children 07bfbbbb4b2e
line wrap: on
line diff
--- a/gen_x86.c	Sun Nov 22 14:43:51 2015 -0800
+++ b/gen_x86.c	Wed Nov 25 08:40:45 2015 -0800
@@ -1592,6 +1592,7 @@
 	}
 	*(out++) = OP_PUSH | reg;
 	code->cur = out;
+	code->stack_off += sizeof(void *);
 }
 
 void push_rdisp(code_info *code, uint8_t base, int32_t disp)
@@ -1599,6 +1600,7 @@
 	//This instruction has no explicit size, so we pass SZ_B
 	//to avoid any prefixes or bits being set
 	x86_rdisp_size(code, OP_SINGLE_EA, OP_EX_PUSH_EA, base, disp, SZ_B);
+	code->stack_off += sizeof(void *);
 }
 
 void pop_r(code_info *code, uint8_t reg)
@@ -1611,6 +1613,7 @@
 	}
 	*(out++) = OP_POP | reg;
 	code->cur = out;
+	code->stack_off -= sizeof(void *);
 }
 
 void pop_rind(code_info *code, uint8_t reg)
@@ -1624,6 +1627,7 @@
 	*(out++) = PRE_XOP;
 	*(out++) = MODE_REG_INDIRECT | reg;
 	code->cur = out;
+	code->stack_off -=  sizeof(void *);
 }
 
 void setcc_r(code_info *code, uint8_t cc, uint8_t dst)
@@ -1966,6 +1970,13 @@
 
 void call(code_info *code, code_ptr fun)
 {
+	code->stack_off += sizeof(void *);
+	int32_t adjust = 0;
+	if (code->stack_off & 0xF) {
+		adjust = 16 - (code->stack_off & 0xF);
+		code->stack_off += adjust;
+		sub_ir(code, adjust, RSP, SZ_PTR);
+	}
 	check_alloc_code(code, 5);
 	code_ptr out = code->cur;
 	ptrdiff_t disp = fun-(out+5);
@@ -1983,6 +1994,10 @@
 		fatal_error("call: %p - %p = %lX which is out of range for a 32-bit displacement\n", fun, out + 5, (long)disp);
 	}
 	code->cur = out;
+	if (adjust) {
+		add_ir(code, adjust, RSP, SZ_PTR);
+	}
+	code->stack_off -= sizeof(void *) + adjust;
 }
 
 void call_raxfallback(code_info *code, code_ptr fun)
@@ -2008,11 +2023,22 @@
 
 void call_r(code_info *code, uint8_t dst)
 {
+	code->stack_off += sizeof(void *);
+	int32_t adjust = 0;
+	if (code->stack_off & 0xF) {
+		adjust = 16 - (code->stack_off & 0xF);
+		code->stack_off += adjust;
+		sub_ir(code, adjust, RSP, SZ_PTR);
+	}
 	check_alloc_code(code, 2);
 	code_ptr out = code->cur;
 	*(out++) = OP_SINGLE_EA;
 	*(out++) = MODE_REG_DIRECT | dst | (OP_EX_CALL_EA << 3);
 	code->cur = out;
+	if (adjust) {
+		add_ir(code, adjust, RSP, SZ_PTR);
+	}
+	code->stack_off -= sizeof(void *) + adjust;
 }
 
 void retn(code_info *code)
@@ -2084,8 +2110,15 @@
 	{
 		push_r(code, arg_arr[i]);
 	}
+	uint32_t stack_off_call = code->stack_off + sizeof(void *);
+	uint32_t adjust = 0;
+	if (stack_off_call & 0xF) {
+		adjust = 16 - (stack_off_call & 0xF);
+		sub_ir(code, adjust, RSP, SZ_PTR);
+		code->stack_off += adjust;
+	}
 
-	return stack_args * sizeof(void *);
+	return stack_args * sizeof(void *) + adjust;
 }
 
 void call_args(code_info *code, code_ptr fun, uint32_t num_args, ...)
@@ -2097,9 +2130,10 @@
 	call_raxfallback(code, fun);
 	if (adjust) {
 		add_ir(code, adjust, RSP, SZ_PTR);
+		code->stack_off -= adjust;
 	}
 }
-
+/*
 void call_args_abi(code_info *code, code_ptr fun, uint32_t num_args, ...)
 {
 	va_list args;
@@ -2125,7 +2159,7 @@
 	*no_adjust_rsp = code->cur - (no_adjust_rsp+1);
 #endif
 }
-
+*/
 void save_callee_save_regs(code_info *code)
 {
 	push_r(code, RBX);