[project @ 2002-04-25 18:48:02 by panne]
[ghc-hetmet.git] / ghc / rts / Adjustor.c
index b38e72d..72cc3b6 100644 (file)
@@ -192,6 +192,14 @@ createAdjustor(int cconv, StgStablePtr hptr, StgFunPtr wptr)
     place %i4 and %i5 at [%sp+92] and [%sp+96] respectively.  This
     machinery should then work in all cases.  (Or would it?  Perhaps
     it would trash parts of the caller's frame.  Dunno).  
+
+    SUP, 25 Apr 02: We are quite lucky to push a multiple of 8 bytes in
+    front of the existing arguments, because %sp must stay double-word
+    aligned at all times, see: http://www.sparc.org/standards/psABI3rd.pdf
+    Although we extend the *caller's* stack frame, this shouldn't cause
+    any problems for a C-like caller: alloca is implemented similarly, and
+    local variables should be accessed via %fp, not %sp. In a nutshell:
+    This should work. (Famous last words! :-)
   */
     if ((adjustor = stgMallocBytes(4*(8+1), "createAdjustor")) != NULL) {
        unsigned long *const adj_code = (unsigned long *)adjustor;
@@ -222,6 +230,18 @@ createAdjustor(int cconv, StgStablePtr hptr, StgFunPtr wptr)
        adj_code[7] |= ((unsigned long)hptr) & 0x000003ff;
 
        adj_code[8] = (StgStablePtr)hptr;
+
+       /* flush cache */
+       asm("flush %0" : : "r" (adj_code    ));
+       asm("flush %0" : : "r" (adj_code + 2));
+       asm("flush %0" : : "r" (adj_code + 4));
+       asm("flush %0" : : "r" (adj_code + 6));
+
+       /* max. 5 instructions latency, and we need at >= 1 for returning */
+       asm("nop");
+       asm("nop");
+       asm("nop");
+       asm("nop");
     }
 #elif defined(alpha_TARGET_ARCH)
   /* Magic constant computed by inspecting the code length of
@@ -329,7 +349,20 @@ TODO: Depending on how much allocation overhead stgMallocBytes uses for
                adj_code[11] = 0x4e800420;      //bctr
                adj_code[12] = (unsigned long)hptr;
                
-               //MakeDataExecutable(adjustor,4*13);    // don't know if it is _really_ necessary
+               // Flush the Instruction cache:
+               //      MakeDataExecutable(adjustor,4*13);
+                       /* This would require us to link with CoreServices.framework */
+               {               /* this should do the same: */
+                       int n = 13;
+                       unsigned long *p = adj_code;
+                       while(n--)
+                       {
+                               __asm__ volatile ("dcbf 0,%0\n\tsync\n\ticbi 0,%0"
+                                                   : : "g" (p));
+                               p++;
+                       }
+                       __asm__ volatile ("sync\n\tisync");
+               }
        }
 #else
 #error Adjustor creation is not supported on this platform.
@@ -364,13 +397,13 @@ freeHaskellFunctionPtr(void* ptr)
     freeStablePtr(*((StgStablePtr*)((unsigned char*)ptr + 0x02)));
  }    
 #elif defined(sparc_TARGET_ARCH)
- if ( *(unsigned char*)ptr != 0x13 ) {
+ if ( *(unsigned long*)ptr != 0x9A10000B ) {
    fprintf(stderr, "freeHaskellFunctionPtr: not for me, guv! %p\n", ptr);
    return;
  }
 
  /* Free the stable pointer first..*/
- freeStablePtr(*((StgStablePtr*)((unsigned char*)ptr + 0x10)));
+ freeStablePtr(*((StgStablePtr*)((unsigned long*)ptr + 8)));
 #elif defined(alpha_TARGET_ARCH)
  if ( *(StgWord64*)ptr != 0xa77b0018a61b0010L ) {
    fprintf(stderr, "freeHaskellFunctionPtr: not for me, guv! %p\n", ptr);