changeset 485:b449af228c63

Follow amd64 ABI stack alignment requirements in places it matters so we can call sprintf with floating point arguments without crashing
author Mike Pavone <pavone@retrodev.com>
date Thu, 03 Oct 2013 21:21:47 -0700
parents 0bf5e6b672fe
children db5880d8ea03
files m68k_to_x86.c runtime.S
diffstat 2 files changed, 58 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/m68k_to_x86.c	Thu Oct 03 21:20:29 2013 -0700
+++ b/m68k_to_x86.c	Thu Oct 03 21:21:47 2013 -0700
@@ -1,6 +1,6 @@
 /*
  Copyright 2013 Michael Pavone
- This file is part of BlastEm. 
+ This file is part of BlastEm.
  BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
 */
 #include "gen_x86.h"
@@ -4246,7 +4246,17 @@
 						dst = push_r(dst, CONTEXT);
 						dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
 					}
+					dst = test_ir(dst, 8, RSP, SZ_D);
+					uint8_t *adjust_rsp = dst+1;
+					dst = jcc(dst, CC_NZ, dst+2);
 					dst = call(dst, cfun);
+					uint8_t *no_adjust = dst+1;
+					dst = jmp(dst, dst+2);
+					*adjust_rsp = dst - (adjust_rsp + 1);
+					dst = sub_ir(dst, 8, RSP, SZ_Q);
+					dst = call(dst, cfun);
+					dst = add_ir(dst, 8, RSP, SZ_Q);
+					*no_adjust = dst - (no_adjust + 1);
 					if (is_write) {
 						dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
 					} else {
@@ -4339,7 +4349,17 @@
 				dst = push_r(dst, CONTEXT);
 				dst = mov_rr(dst, SCRATCH1, RDI, SZ_D);
 			}
+			dst = test_ir(dst, 8, RSP, SZ_D);
+			uint8_t *adjust_rsp = dst+1;
+			dst = jcc(dst, CC_NZ, dst+2);
 			dst = call(dst, cfun);
+			uint8_t *no_adjust = dst+1;
+			dst = jmp(dst, dst+2);
+			*adjust_rsp = dst - (adjust_rsp + 1);
+			dst = sub_ir(dst, 8, RSP, SZ_Q);
+			dst = call(dst, cfun);
+			dst = add_ir(dst, 8, RSP, SZ_Q);
+			*no_adjust = dst - (no_adjust+1);
 			if (is_write) {
 				dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
 			} else {
@@ -4444,7 +4464,17 @@
 	dst = call(dst, (uint8_t *)m68k_save_context);
 	dst = mov_rr(dst, CONTEXT, RDI, SZ_Q);
 	dst = mov_rr(dst, SCRATCH1, RSI, SZ_D);
+	dst = test_ir(dst, 8, RSP, SZ_D);
+	uint8_t *adjust_rsp = dst+1;
+	dst = jcc(dst, CC_NZ, dst+2);
 	dst = call(dst, (uint8_t *)sync_components);
+	uint8_t *no_adjust = dst+1;
+	dst = jmp(dst, dst+2);
+	*adjust_rsp = dst - (adjust_rsp + 1);
+	dst = sub_ir(dst, 8, RSP, SZ_Q);
+	dst = call(dst, (uint8_t *)sync_components);
+	dst = add_ir(dst, 8, RSP, SZ_Q);
+	*no_adjust = dst - (no_adjust+1);
 	dst = mov_rr(dst, RAX, CONTEXT, SZ_Q);
 	dst = jmp(dst, (uint8_t *)m68k_load_context);
 	*skip_sync = dst - (skip_sync+1);
--- a/runtime.S	Thu Oct 03 21:20:29 2013 -0700
+++ b/runtime.S	Thu Oct 03 21:21:47 2013 -0700
@@ -10,14 +10,22 @@
 	call m68k_save_context
 	mov %rsi, %rdi
 	xor %esi, %esi
+	test $8, %esp
+	jnz adjust_rsp
 	call sync_components
+	jmp done_adjust
+adjust_rsp:
+	sub $8, %rsp
+	call sync_components
+	add $8, %rsp
+done_adjust:
 	mov %rax, %rsi
 	call m68k_load_context
 	pop %rdi
 	pop %rcx
 skip_sync:
 	ret
-	
+
 sr_msg_int:
 	.asciz "SR set to $%X due to interrupt\n"
 debug_print_sr_int:
@@ -47,7 +55,7 @@
 
 invalid_msg:
 	.asciz "Invalid instruction at %X\n"
-	
+
 	.global m68k_invalid
 m68k_invalid:
 	lea invalid_msg(%rip), %rdi
@@ -60,7 +68,7 @@
 	.global bcd_add
 bcd_add:
 	xchg %rax, %rdi
-	
+
 	mov %cl, %ch
 	mov %al, %ah
 	and $0xF, %ch
@@ -82,14 +90,14 @@
 	add $0x60, %cl
 	mov $1, %ch
 no_adjust_h:
-	
+
 	mov %rdi, %rax
 	ret
 
 	.global bcd_sub
 bcd_sub:
 	xchg %rax, %rdi
-	
+
 	mov %cl, %ch
 	mov %al, %ah
 	and $0xF, %ch
@@ -111,7 +119,7 @@
 	sub $0x60, %cl
 	mov $1, %ch
 no_adjust_hs:
-	
+
 	mov %rdi, %rax
 	ret
 
@@ -168,7 +176,7 @@
 	and $1, %cl
 	mov %cl, (%rsi)
 	ret
-	
+
 	.global m68k_modified_ret_addr
 m68k_modified_ret_addr:
 	add $16, %rsp
@@ -181,7 +189,15 @@
 	push %rcx
 	mov %rsi, %rdi
 	xor %esi, %esi
+	test $8, %rsp
+	jnz adjust_rsp_na
 	call sync_components
+	jmp no_adjust_rsp_na
+adjust_rsp_na:
+	sub $8, %rsp
+	call sync_components
+	add $8, %rsp
+no_adjust_rsp_na:
 	pop %rsi
 	push %rax
 	mov %rax, %rdi
@@ -202,7 +218,7 @@
 	pop %rsi
 	call m68k_load_context
 	ret
-	
+
 	.global m68k_retrans_stub
 m68k_retrans_stub:
 	call m68k_save_context
@@ -255,15 +271,15 @@
 	push %r13
 	push %r14
 	push %r15
-	
+
 	call m68k_load_context
 	call *%rdi
 	call m68k_save_context
-	
+
 	pop %r15
 	pop %r14
 	pop %r13
 	pop %r12
 	pop %rbp
-	
+
 	ret