summaryrefslogtreecommitdiff
path: root/rts/AdjustorAsm.S
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-04-07 02:05:11 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-04-07 02:05:11 +0000
commit0065d5ab628975892cea1ec7303f968c3338cbe1 (patch)
tree8e2afe0ab48ee33cf95009809d67c9649573ef92 /rts/AdjustorAsm.S
parent28a464a75e14cece5db40f2765a29348273ff2d2 (diff)
downloadhaskell-0065d5ab628975892cea1ec7303f968c3338cbe1.tar.gz
Reorganisation of the source tree
Most of the other users of the fptools build system have migrated to Cabal, and with the move to darcs we can now flatten the source tree without losing history, so here goes. The main change is that the ghc/ subdir is gone, and most of what it contained is now at the top level. The build system now makes no pretense at being multi-project, it is just the GHC build system. No doubt this will break many things, and there will be a period of instability while we fix the dependencies. A straightforward build should work, but I haven't yet fixed binary/source distributions. Changes to the Building Guide will follow, too.
Diffstat (limited to 'rts/AdjustorAsm.S')
-rw-r--r--rts/AdjustorAsm.S189
1 files changed, 189 insertions, 0 deletions
diff --git a/rts/AdjustorAsm.S b/rts/AdjustorAsm.S
new file mode 100644
index 0000000000..cfdef68349
--- /dev/null
+++ b/rts/AdjustorAsm.S
@@ -0,0 +1,189 @@
+#include "../includes/ghcconfig.h"
+
+/* ******************************** PowerPC ******************************** */
+
+#if defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH)
+#if !(defined(powerpc_HOST_ARCH) && defined(linux_HOST_OS))
+ /* The following code applies, with some differences,
+ to all powerpc platforms except for powerpc32-linux,
+ whose calling convention is annoyingly complex.
+ */
+
+
+ /* The code is "almost" the same for
+ 32-bit and for 64-bit
+ */
+#if defined(powerpc64_HOST_ARCH)
+#define WS 8
+#define LOAD ld
+#define STORE std
+#else
+#define WS 4
+#define LOAD lwz
+#define STORE stw
+#endif
+
+ /* Some info about stack frame layout */
+#define LINK_SLOT (2*WS)
+#define LINKAGE_AREA_SIZE (6*WS)
+
+ /* The following defines mirror struct AdjustorStub
+ from Adjustor.c. Make sure to keep these in sync.
+ */
+#if defined(powerpc_HOST_ARCH) && defined(darwin_HOST_OS)
+#define HEADER_WORDS 6
+#elif defined(powerpc64_HOST_ARCH) && defined(darwin_HOST_OS)
+#else
+#define HEADER_WORDS 3
+#endif
+
+#define HPTR_OFF ((HEADER_WORDS )*WS)
+#define WPTR_OFF ((HEADER_WORDS + 1)*WS)
+#define FRAMESIZE_OFF ((HEADER_WORDS + 2)*WS)
+#define EXTRA_WORDS_OFF ((HEADER_WORDS + 3)*WS)
+
+ /* Darwin insists on register names, everyone else prefers
+ to use numbers. */
+#if !defined(darwin_HOST_OS)
+#define r0 0
+#define r1 1
+#define r2 2
+#define r3 3
+#define r4 4
+#define r5 5
+#define r6 6
+#define r7 7
+#define r8 8
+#define r9 9
+#define r10 10
+#define r11 11
+#define r12 12
+
+#define r30 30
+#define r31 31
+#endif
+
+
+.text
+#if LEADING_UNDERSCORE
+ .globl _adjustorCode
+_adjustorCode:
+#else
+ .globl adjustorCode
+ /* Note that we don't build a function descriptor
+ for AIX-derived ABIs here. This will happen at runtime
+ in createAdjustor().
+ */
+adjustorCode:
+#endif
+ /* On entry, r2 will point to the AdjustorStub data structure. */
+
+ /* save the link */
+ mflr r0
+ STORE r0, LINK_SLOT(r1)
+
+ /* set up stack frame */
+ LOAD r12, FRAMESIZE_OFF(r2)
+#ifdef powerpc64_HOST_ARCH
+ stdux r1, r1, r12
+#else
+ stwux r1, r1, r12
+#endif
+
+ /* Save some regs so that we can use them.
+ Note that we use the "Red Zone" below the stack pointer.
+ */
+ STORE r31, -WS(r1)
+ STORE r30, -2*WS(r1)
+
+ mr r31, r1
+ subf r30, r12, r31
+
+ LOAD r12, EXTRA_WORDS_OFF(r2)
+ mtctr r12
+ b 2f
+1:
+ LOAD r0, LINKAGE_AREA_SIZE + 8*WS(r30)
+ STORE r0, LINKAGE_AREA_SIZE + 10*WS(r31)
+ addi r30, r30, WS
+ addi r31, r31, WS
+2:
+ bdnz 1b
+
+ /* Restore r30 and r31 now.
+ */
+ LOAD r31, -WS(r1)
+ LOAD r30, -2*WS(r1)
+
+ STORE r10, LINKAGE_AREA_SIZE + 9*WS(r1)
+ STORE r9, LINKAGE_AREA_SIZE + 8*WS(r1)
+ mr r10, r8
+ mr r9, r7
+ mr r8, r6
+ mr r7, r5
+ mr r6, r4
+ mr r5, r3
+
+ LOAD r3, HPTR_OFF(r2)
+
+ LOAD r12, WPTR_OFF(r2)
+#if defined(darwin_HOST_OS)
+ mtctr r12
+#else
+ LOAD r0, 0(r12)
+ /* The function we're calling will never be a nested function,
+ so we don't load r11.
+ */
+ mtctr r0
+ LOAD r2, WS(r12)
+#endif
+ bctrl
+
+ LOAD r1, 0(r1)
+ LOAD r0, LINK_SLOT(r1)
+ mtlr r0
+ blr
+#endif
+
+/* ********************************* i386 ********************************** */
+
+#elif defined(i386_HOST_ARCH) && defined(darwin_HOST_OS)
+
+#define WS 4
+#define RETVAL_OFF 5
+#define HEADER_BYTES 8
+
+#define HPTR_OFF HEADER_BYTES
+#define WPTR_OFF (HEADER_BYTES + 1*WS)
+#define FRAMESIZE_OFF (HEADER_BYTES + 2*WS)
+#define ARGWORDS_OFF (HEADER_BYTES + 3*WS)
+
+ .globl _adjustorCode
+_adjustorCode:
+ popl %eax
+ subl $RETVAL_OFF, %eax
+
+ pushl %ebp
+ movl %esp, %ebp
+
+ subl FRAMESIZE_OFF(%eax), %esp
+
+ pushl %esi
+ pushl %edi
+
+ leal 8(%ebp), %esi
+ leal 12(%esp), %edi
+ movl ARGWORDS_OFF(%eax), %ecx
+ rep
+ movsl
+
+ popl %edi
+ popl %esi
+
+ pushl HPTR_OFF(%eax)
+ call *WPTR_OFF(%eax)
+
+ leave
+ ret
+#endif
+