[project @ 1996-01-11 14:06:51 by partain]
[ghc-hetmet.git] / ghc / includes / COptWraps.lh
index 7aa8286..da57a40 100644 (file)
@@ -185,7 +185,7 @@ void Yield_wrapper PROTO((W_));
 
 Call wrappers need to be able to call arbitrary functions, regardless of
 their arguments and return types.  (Okay, we actually only allow up to
 
 Call wrappers need to be able to call arbitrary functions, regardless of
 their arguments and return types.  (Okay, we actually only allow up to
-five arguments, because on the sparc it gets more complicated to handle
+five arguments, because on the SPARC it gets more complicated to handle
 any more.)  The nasty bit is that the return value can be in either an
 integer register or a floating point register, and we don't know which.
 (We {\em don't} handle structure returns, and we don't want to.)
 any more.)  The nasty bit is that the return value can be in either an
 integer register or a floating point register, and we don't know which.
 (We {\em don't} handle structure returns, and we don't want to.)
@@ -200,7 +200,7 @@ chock full of assembly gook for the current platform.  These are
 results, and @MAGIC_RETURN@, which collects all possible results back
 up again.
 
 results, and @MAGIC_RETURN@, which collects all possible results back
 up again.
 
-For example, in the sparc version, the @SETUP@ guarantees that we
+For example, in the SPARC version, the @SETUP@ guarantees that we
 have enough space to store all of our argument registers for a wee
 bit, and it gives a `C' name to the register that we're going to use
 for the call.  (It helps to do the call in actual `C' fashion, so that
 have enough space to store all of our argument registers for a wee
 bit, and it gives a `C' name to the register that we're going to use
 for the call.  (It helps to do the call in actual `C' fashion, so that
@@ -223,8 +223,7 @@ gets whatever it's after.
 
 #if defined(__GNUC__) && defined(__STG_GCC_REGS__)
 
 
 #if defined(__GNUC__) && defined(__STG_GCC_REGS__)
 
-#if alpha_dec_osf1_TARGET
-    /* Is this too specific */
+#if alpha_TARGET_ARCH
 
 #define MAGIC_CALL_SETUP       \
     long WeNeedThisSpace[7];   \
 
 #define MAGIC_CALL_SETUP       \
     long WeNeedThisSpace[7];   \
@@ -277,7 +276,7 @@ gets whatever it's after.
 
 #define SET_RETADDR(loc)  { register StgFunPtrFunPtr ra __asm__ ("$26"); loc = ra; }
 
 
 #define SET_RETADDR(loc)  { register StgFunPtrFunPtr ra __asm__ ("$26"); loc = ra; }
 
-#define WRAPPER_SETUP(f)  SaveAllStgContext();
+#define WRAPPER_SETUP(f,ignore1,ignore2)  SaveAllStgContext();
 
 #define WRAPPER_RETURN(x)   \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
 
 #define WRAPPER_RETURN(x)   \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
@@ -296,8 +295,7 @@ gets whatever it's after.
 
 \begin{code}
 
 
 \begin{code}
 
-#if hppa1_1_hp_hpux_TARGET
-    /* Is this too specific */
+#if hppa1_1_TARGET_ARCH
 
 #define MAGIC_CALL_SETUP           \
     long SavedIntArgRegs[4];       \
 
 #define MAGIC_CALL_SETUP           \
     long SavedIntArgRegs[4];       \
@@ -353,7 +351,7 @@ gets whatever it's after.
 
 #define SET_RETADDR(loc)  __asm__ volatile ("stw %%r2, %0" : "=m" ((void *)(loc)));
 
 
 #define SET_RETADDR(loc)  __asm__ volatile ("stw %%r2, %0" : "=m" ((void *)(loc)));
 
-#define WRAPPER_SETUP(f)  SaveAllStgContext();
+#define WRAPPER_SETUP(f,ignore1,ignore2)  SaveAllStgContext();
 
 #define WRAPPER_RETURN(x)   \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
 
 #define WRAPPER_RETURN(x)   \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
@@ -371,65 +369,57 @@ gets whatever it's after.
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-
-#if i386_TARGET_ARCH || i486_TARGET_ARCH
+#if i386_TARGET_ARCH
 
 /* modelled loosely on SPARC stuff */
 
 /* NB: no MAGIC_CALL_SETUP, MAGIC_CALL, or MAGIC_RETURN! */
 
 
 /* modelled loosely on SPARC stuff */
 
 /* NB: no MAGIC_CALL_SETUP, MAGIC_CALL, or MAGIC_RETURN! */
 
-#define WRAPPER_NAME(f)          __asm__("L" #f "_wrapper")
+#define WRAPPER_NAME(f) /*nothing*/
 
 
+#ifdef solaris2_TARGET_OS
+#define REAL_NAME(f)   #f
+#else
 #define REAL_NAME(f)   "_" #f
 #define REAL_NAME(f)   "_" #f
+#endif
 
 
-/* when we come into PerformGC_wrapper:
+/* 
+   Threaded code needs to be able to grab the return address, in case we have
+   an intervening context switch.
+ */
 
 
-    - %esp holds Hp (!); get it into 80(%ebx) -- quick!
+#define SET_RETADDR(loc,val) loc = val;
 
 
-    - %esp needs to be bumped by (at least) 4, because
-      C thinks an argument was passed on the stack
-      (use 64 just for fun)
+/* the grab-%eax-quickly HACK is here because we use a VERY SPECIAL
+   calling convention on iX86 just for calling PerformGC_wrapper.
+   (WDP 95/09)
 
 
-    - %eax holds the argument for PerformGC
+   NB: mangler makes sure that __temp_{eax,esp} get loaded.
+   (This is about as ugly as it can get.)
+*/
 
 
-    - 104(%ebx) hold the return address -- address we want to
-      go back to
+#define WRAPPER_SETUP(f,ret_addr,args)                 \
+    __asm__ volatile (                                 \
+       "movl "   REAL_NAME(__temp_esp)  ",%%edx\n"     \
+       "\tmovl (%%edx),%0\n"                           \
+       "\tmovl " REAL_NAME(__temp_eax) ",%1"           \
+       : "=r" (ret_addr), "=r" (args) );               \
+    SaveAllStgContext(ret_addr);
 
 
-    - 100(%ebx) holds a %esp value that we can re-load with
-      if need be
+/* Note re WRAPPER_SETUP: we have special code just for PerformGC_wrapper;
+   pls see its definition.  WDP 95/09
 
 
+   Also note the EXTREMELY UGLY slamming in of an "sp_offset"; the
+   return address *is* on the stack, but it is hard to get there
+   before GCC has moved the sp pointer... WDP 95/11
 */
 */
-#define WRAPPER_SETUP(f)                       \
-    __asm__ volatile (                         \
-        ".globl " REAL_NAME(f) "_wrapper\n"    \
-        REAL_NAME(f) "_wrapper:\n"             \
-        "\tmovl %%esp,80(%%ebx)\n"             \
-        "\tmovl 100(%%ebx),%%esp\n"            \
-        "\tmovl %%eax,%0\n"                    \
-       "\tincl _SP_stack_ptr\n"                \
-       "\tmovl _SP_stack_ptr,%%eax\n"          \
-       "\tmovl %%esp,_SP_stack(,%%eax,4)\n"    \
-       "\tsubl $64,%%esp"                      \
-       : "=r" (args));                         \
-    SaveAllStgContext();
-
-#define WRAPPER_RETURN(x)                      \
-    do {P_ foo;                                        \
-       RestoreAllStgRegs();                    \
-       if(x) JMP_(EnterNodeCode); /* never used? */ \
-       __asm__ volatile (                      \
-       "movl %1,%0\n"                          \
-       "\tmovl %0,_MainRegTable+100"           \
-       : "=r" (foo) : "m" (SP_stack[SP_stack_ptr--]) ); \
-       __asm__ volatile (                      \
-       "movl 80(%ebx),%esp\n"                  \
-       "\tjmp *104(%ebx)" );                   \
-    } while(0);
+
+#define WRAPPER_RETURN(x)   \
+    do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
 
 #define SEPARATE_WRAPPER_RESTORE    /* none */
 
 #endif /* iX86 */
 
 #define SEPARATE_WRAPPER_RESTORE    /* none */
 
 #endif /* iX86 */
-
 \end{code}
 
 %************************************************************************
 \end{code}
 
 %************************************************************************
@@ -466,7 +456,7 @@ gets whatever it's after.
 
 #define WRAPPER_NAME(f)          /* nothing */
 
 
 #define WRAPPER_NAME(f)          /* nothing */
 
-#define WRAPPER_SETUP(f)  SaveAllStgContext();
+#define WRAPPER_SETUP(f,ignore1,ignore2)  SaveAllStgContext();
 
 #define WRAPPER_RETURN(x)  \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
 
 #define WRAPPER_RETURN(x)  \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
@@ -513,7 +503,7 @@ gets whatever it's after.
 
 #define WRAPPER_NAME(f)          /* nothing */
 
 
 #define WRAPPER_NAME(f)          /* nothing */
 
-#define WRAPPER_SETUP(f)  SaveAllStgContext();
+#define WRAPPER_SETUP(f,ignore1,ignore2)  SaveAllStgContext();
 
 #define WRAPPER_RETURN(x)  \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
 
 #define WRAPPER_RETURN(x)  \
     do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
@@ -525,6 +515,52 @@ gets whatever it's after.
 
 %************************************************************************
 %*                                                                     *
 
 %************************************************************************
 %*                                                                     *
+\subsubsection[powerpc-magic]{Call-wrapper MAGIC for PowerPC}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+#if powerpc_TARGET_ARCH
+
+/* shift 4 arg registers down one */
+
+#define MAGIC_CALL_SETUP  \
+    register void (*f)() __asm__("$2");        \
+    __asm__ volatile (                 \
+    "move $2,$4\n"                     \
+    "\tmove $4,$5\n"                   \
+    "\tmove $5,$6\n"                   \
+    "\tmove $6,$7\n"                   \
+    "\tlw $7,16($sp)\n"                        \
+    "\taddu $sp,$sp,4\n"               \
+    : : : "$2" );
+
+#define MAGIC_CALL             \
+    (*f)();                    \
+     __asm__ volatile (                \
+    "subu $sp,$sp,4\n"         \
+    "\ts.d $f0, -8($sp)\n"     \
+    "\tsw  $2, -12($sp)");
+
+#define MAGIC_RETURN           \
+    __asm__ volatile (         \
+    "l.d $f0, -8($sp)\n"       \
+    "\tlw  $2, -12($sp)");
+
+#define WRAPPER_NAME(f)          /* nothing */
+
+#define WRAPPER_SETUP(f,ignore1,ignore2)  SaveAllStgContext();
+
+#define WRAPPER_RETURN(x)  \
+    do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
+
+#define SEPARATE_WRAPPER_RESTORE    /* none */
+
+#endif /* powerpc */
+\end{code}
+
+%************************************************************************
+%*                                                                     *
 \subsubsection[sparc-magic]{Call-wrapper MAGIC for SPARC}
 %*                                                                     *
 %************************************************************************
 \subsubsection[sparc-magic]{Call-wrapper MAGIC for SPARC}
 %*                                                                     *
 %************************************************************************
@@ -561,10 +597,10 @@ gets whatever it's after.
         "\tldd [%fp-32],%i0");
 
 /* 
         "\tldd [%fp-32],%i0");
 
 /* 
-   We rename the entry points for wrappers so that we can
-   introduce a new entry point after the prologue.  We want to ensure
-   that the register window does not slide!  However, we insert a 
-   call to abort() to make gcc _believe_ that the window slid.
+   We rename the entry points for wrappers so that we can introduce a
+   new entry point after the prologue.  We want to ensure that the
+   register window does not slide!  However, we insert a call to
+   abort() to make gcc _believe_ that the window slid.
  */
 
 #define WRAPPER_NAME(f)          __asm__("L" #f "_wrapper")
  */
 
 #define WRAPPER_NAME(f)          __asm__("L" #f "_wrapper")
@@ -575,7 +611,7 @@ gets whatever it's after.
 #define REAL_NAME(f)   "_" #f
 #endif
 
 #define REAL_NAME(f)   "_" #f
 #endif
 
-#define WRAPPER_SETUP(f)                   \
+#define WRAPPER_SETUP(f,ignore1,ignore2)    \
     __asm__ volatile (                     \
         ".global " REAL_NAME(f) "_wrapper\n"\
         REAL_NAME(f) "_wrapper:\n"         \
     __asm__ volatile (                     \
         ".global " REAL_NAME(f) "_wrapper\n"\
         REAL_NAME(f) "_wrapper:\n"         \
@@ -587,15 +623,17 @@ gets whatever it's after.
        "\tmov %i0,%o0\n"                   \
        "\tmov %i1,%o1");
 /* 
        "\tmov %i0,%o0\n"                   \
        "\tmov %i1,%o1");
 /* 
- * In the above, we want to ensure that the arguments are both in the %i registers
- * and the %o registers, with the assumption that gcc will expect them now to be in
- * one or the other.  This is a terrible hack.
+ * In the above, we want to ensure that the arguments are both in the
+ * %i registers and the %o registers, with the assumption that gcc
+ * will expect them now to be in one or the other.  This is a terrible
+ * hack.
  */
 
 /* 
  */
 
 /* 
-   Threaded code needs to be able to grab the return address, in case we have
-   an intervening context switch.  Note that we want the address of the next
-   instruction to be executed, so we add 8 to the link address.
+   Threaded code needs to be able to grab the return address, in case
+   we have an intervening context switch.  Note that we want the
+   address of the next instruction to be executed, so we add 8 to the
+   link address.
  */
 
 #define SET_RETADDR(loc)       \
  */
 
 #define SET_RETADDR(loc)       \