[project @ 1998-01-29 11:38:20 by simonm]
[ghc-hetmet.git] / ghc / includes / COptWraps.lh
index da57a40..96f84bc 100644 (file)
@@ -69,9 +69,23 @@ but unfortunately, we have to cater to ANSI C as well.)
     do {SaveAllStgRegs(); PerformGC(args); RestoreAllStgRegs();} while(0)
 #define DO_STACKOVERFLOW(headroom,args)            \
     do {SaveAllStgRegs(); StackOverflow(headroom,args); RestoreAllStgRegs();} while(0)
+
+#if defined(GRAN)
+
+#define DO_YIELD(args)   DO_GRAN_YIELD(args)
+#define DO_GRAN_YIELD(liveness)                    \
+    do {SaveAllStgRegs(); Yield(liveness); RestoreAllStgRegs();} while(0)
+
+#define DO_PERFORM_RESCHEDULE(liveness_mask,reenter)               \
+    do {SaveAllStgRegs(); PerformReschedule(liveness_mask,reenter); RestoreAllStgRegs();} while(0)
+
+#else
+
 #define DO_YIELD(args)             \
     do {SaveAllStgRegs(); Yield(args); RestoreAllStgRegs();} while(0)
 
+#endif   /* GRAN */
+
 \end{code}
 
 %************************************************************************
@@ -168,12 +182,35 @@ extern void callWrapper_safe(STG_NO_ARGS);
 void PerformGC_wrapper PROTO((W_));
 void StackOverflow_wrapper PROTO((W_, W_));
 void Yield_wrapper PROTO((W_));
+#  ifdef GRAN
+void PerformReschedule_wrapper PROTO((W_, W_));
+void GranSimAllocate_wrapper PROTO((I_, P_, W_));
+void GranSimUnallocate_wrapper PROTO((I_, P_, W_));
+void GranSimFetch_wrapper PROTO((P_));
+void GranSimExec_wrapper PROTO((W_, W_, W_, W_, W_));
+#  endif
 #endif
 
 #define DO_GC(args)                    PerformGC_wrapper(args)
 #define DO_STACKOVERFLOW(headroom,args) StackOverflow_wrapper(headroom,args)
+
+#  ifdef GRAN
+
+#define DO_YIELD(args)   DO_GRAN_YIELD(args)
+#define DO_GRAN_YIELD(liveness)                        Yield_wrapper(liveness)
+
+#define DO_PERFORMRESCHEDULE(liveness, always_reenter_node) PerformReschedule_wrapper(liveness, always_reenter_node)
+#define DO_GRANSIMALLOCATE(n, node, liveness)   GranSimAllocate_wrapper(n, node, liveness)
+#define DO_GRANSIMUNALLOCATE(n, node, liveness) GranSimUnallocate_wrapper(n, node, liveness)
+#define DO_GRANSIMFETCH(node)                   GranSimFetch_wrapper(node)
+#define DO_GRANSIMEXEC(arith,branch,load,store,floats) GranSimExec_wrapper(arith,branch,load,store,floats)
+
+#  else
+
 #define DO_YIELD(args)                 Yield_wrapper(args)
 
+#  endif
+
 #endif /* __GNUC__ && __STG_GCC_REGS__ */
 \end{code}
 
@@ -195,7 +232,8 @@ in the end.
 
 Getting this right requires three extremely @MAGIC@ macros, no doubt
 chock full of assembly gook for the current platform.  These are
-@MAGIC_CALL_SETUP@, which gets ready for one of these magic calls,
+@MAGIC_CALL_SET
+UP@, which gets ready for one of these magic calls,
 @MAGIC_CALL@, which performs the call and stashes away all possible
 results, and @MAGIC_RETURN@, which collects all possible results back
 up again.
@@ -377,7 +415,7 @@ gets whatever it's after.
 
 #define WRAPPER_NAME(f) /*nothing*/
 
-#ifdef solaris2_TARGET_OS
+#if defined(solaris2_TARGET_OS) || defined(linux_TARGET_OS)
 #define REAL_NAME(f)   #f
 #else
 #define REAL_NAME(f)   "_" #f
@@ -503,6 +541,13 @@ gets whatever it's after.
 
 #define WRAPPER_NAME(f)          /* nothing */
 
+/* 
+   Threaded code needs to be able to grab the return address, in case we have
+   an intervening context switch.
+ */
+
+#define SET_RETADDR(loc)  { register StgFunPtrFunPtr ra __asm__ ("$31"); loc = ra; }
+
 #define WRAPPER_SETUP(f,ignore1,ignore2)  SaveAllStgContext();
 
 #define WRAPPER_RETURN(x)  \
@@ -520,39 +565,45 @@ gets whatever it's after.
 %************************************************************************
 
 \begin{code}
-#if powerpc_TARGET_ARCH
-
-/* shift 4 arg registers down one */
+#if powerpc_TARGET_ARCH || rs6000_TARGET_ARCH
 
 #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"               \
+    "not used!!!????\n"                        \
     : : : "$2" );
 
 #define MAGIC_CALL             \
     (*f)();                    \
      __asm__ volatile (                \
-    "subu $sp,$sp,4\n"         \
-    "\ts.d $f0, -8($sp)\n"     \
-    "\tsw  $2, -12($sp)");
+    "not used!!!????\n");
 
 #define MAGIC_RETURN           \
     __asm__ volatile (         \
-    "l.d $f0, -8($sp)\n"       \
-    "\tlw  $2, -12($sp)");
+    "not used!!!????\n");
 
 #define WRAPPER_NAME(f)          /* nothing */
 
+#define SET_RETADDR(loc)       \
+    __asm__ volatile (         \
+       "mflr 0\n"              \
+       "\tst 0,%0"             \
+       :"=m" (loc) :: "0");
+/*    __asm__ volatile ("st %%r0, %0" : "=m" ((void *)(loc))); */
+
 #define WRAPPER_SETUP(f,ignore1,ignore2)  SaveAllStgContext();
 
+/* we have to make sure the STG registers are restored. 
+GCC tries to restore the value the registers had in
+the beginning of the current call, which we don't want. 
+We defeat it by saving the registers in the stack again. :-( */
+
 #define WRAPPER_RETURN(x)  \
-    do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0);
+    do {RestoreAllStgRegs(); if(x) JMP_(EnterNodeCode);} while(0); \
+    __asm__ volatile (         \
+       "cal 1,136(1)\n" \
+        "\tstm 14,-72(1)\n" \
+       "\tstu 1,-136(1)");
 
 #define SEPARATE_WRAPPER_RESTORE    /* none */
 
@@ -566,7 +617,6 @@ gets whatever it's after.
 %************************************************************************
 
 \begin{code}
-
 #if sparc_TARGET_ARCH
 
 #define MAGIC_CALL_SETUP       \
@@ -577,6 +627,10 @@ gets whatever it's after.
        "\tstd %i2,[%fp-32]\n"  \
        "\tstd %i4,[%fp-24]");
 
+/* Lest GCC attempt to stick something in
+   the delay slot: with compile with
+   -fno-delayed-branch.  A weak solution. WDP 96/07
+*/
 #define MAGIC_CALL             \
     __asm__ volatile (         \
         "ld [%%fp-40],%%o5\n"  \
@@ -590,6 +644,30 @@ gets whatever it's after.
     __asm__ volatile (         \
        "std %f0,[%fp-40]\n"    \
        "\tstd %o0,[%fp-32]");
+#if 0
+/* We leave nothing to chance here; we have seen
+   GCC stick "unwanted" code in the branch delay
+   slot, causing mischief (WDP 96/05)
+*/
+/* the problem with this one: GCC has no way of
+   knowing there is a "call" in there, so it
+   does not do any calling-convention stuff
+   (e.g., saving used regs).  WDP 96/07
+*/
+#define MAGIC_CALL             \
+    __asm__ volatile (         \
+        "ld [%%fp-40],%%o5\n"  \
+       "\tld [%%fp-36],%%o0\n" \
+       "\tld [%%fp-32],%%o1\n" \
+       "\tld [%%fp-28],%%o2\n" \
+       "\tld [%%fp-24],%%o3\n" \
+       "\tld [%%fp-20],%%o4\n" \
+       "\tcall %%o5\n"         \
+       "\tnop\n"               \
+       "\tstd %%f0,[%%fp-40]\n"\
+       "\tstd %%o0,[%%fp-32]"  \
+       : : : "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%o7", "%f0", "memory");
+#endif /* 0 */
 
 #define MAGIC_RETURN           \
     __asm__ volatile (         \