Hi,
I have figured out why the dynarec wasn't working on Mac OS X - it's
because the Mac OS X x86 ABI requires the stack to be aligned to a 16
byte boundary on function calls. Below is a patch that allows the
dynarec to work on Mac OS X.
N.B. the dynarec does not work if you compile with llvm-gcc-4.2. The
Xcode project included with my previous patch is set up to use llvm-
gcc-4.2 so you will need to change the build settings if you are using
it. I am currently using gcc-4.2 with -Os.
Have fun!
Francis
Index: codegen_x86.c
===================================================================
--- codegen_x86.c (revision 151)
+++ codegen_x86.c (working copy)
@@ -49,6 +49,31 @@
#define addlong(a) *((unsigned long
*)&rcodeblock[blockpoint2][codeblockpos])=(unsigned long)a; \
codeblockpos+=4
+// Macro to align stack to 16 bytes on Mac OS X, where the ABI
requires it.
+// Defined as no-op on non Mac OS X systems.
+// Based on GPLv2 code from ifftw.h of fftw-3.2
+#if defined(__MACH__)
+#define WITH_ALIGNED_STACK_ON_MACOSX(what) \
+{ \
+ /* \
+ * Use alloca to allocate some memory on the stack. \
+ * This alerts gcc that something funny is going \
+ * on, so that it does not omit the frame pointer \
+ * etc. \
+ */ \
+ (void)__builtin_alloca(16); \
+ \
+ /* \
+ * Now align the stack pointer \
+ */ \
+ __asm__ __volatile__ ("andl $-16, %esp"); \
+ \
+ what \
+}
+#else
+#define WITH_ALIGNED_STACK_ON_MACOSX(what) what
+#endif
+
unsigned char lahftable[256],lahftablesub[256];
#define EAX 0x00
@@ -217,7 +242,7 @@
}
addbyte(0xC3); /*RET*/
-#ifdef __linux__
+#if defined(__linux__)
/* Set memory pages containing rcodeblock[]s executable -
necessary when NX/XD feature is active on CPU(s) */
start = (void *)((long)rcodeblock & pagemask);
@@ -609,29 +634,29 @@
}
#else
int codewritememfb()
-{
+WITH_ALIGNED_STACK_ON_MACOSX({
register uint32_t a asm("edx");
register uint8_t v asm("bl");
writememfb(a,v);
return (armirq&0x40)?1:0;
-}
+})
int codewritememfl()
-{
+WITH_ALIGNED_STACK_ON_MACOSX({
register uint32_t a asm("edx");
register uint32_t v asm("ebx");
writememfl(a,v);
return (armirq&0x40)?1:0;
-}
+})
void codewritememflnt()
-{
+WITH_ALIGNED_STACK_ON_MACOSX({
register uint32_t a asm("edx");
register uint32_t v asm("ebx");
writememfl(a,v);
-}
+})
int codereadmemb()
-{
+WITH_ALIGNED_STACK_ON_MACOSX({
register uint32_t a asm("edx");
register uint32_t v asm("ecx");
v=readmemfb(a);
@@ -641,10 +666,10 @@
: "r" (v)
);
return (armirq&0x40)?1:0;
-}
+})
int codereadmeml()
-{
+WITH_ALIGNED_STACK_ON_MACOSX({
register uint32_t a asm("edx");
register uint32_t v asm("ecx");
v=readmemfl(a);
@@ -654,9 +679,9 @@
: "r" (v)
);
return (armirq&0x40)?1:0;
-}
+})
void codereadmemlnt()
-{
+WITH_ALIGNED_STACK_ON_MACOSX({
register uint32_t a asm("edx");
// register uint32_t v asm("ecx");
a=readmemfl(a);
@@ -665,7 +690,7 @@
:
: "r" (a)
);
-}
+})
/*int mwritemem()
{
@@ -677,7 +702,7 @@
#if 0
int mreadmem()
-{
+WITH_ALIGNED_STACK_ON_MACOSX({
register uint32_t a asm("edi");
register uint32_t v asm("edx");
v=readmeml(a);
@@ -687,7 +712,7 @@
: "r" (v)
);
return (armirq&0x40)?1:0;
-}
+})
#endif
#endif
_______________________________________________
Rpcemu mailing list
[email protected]
http://www.riscos.info/cgi-bin/mailman/listinfo/rpcemu