summaryrefslogtreecommitdiff
path: root/ghc/rts/Adjustor.c
diff options
context:
space:
mode:
authorpanne <unknown>2002-04-25 18:18:56 +0000
committerpanne <unknown>2002-04-25 18:18:56 +0000
commit17deccb787981d77615106b8157e5ac26f2c8ddb (patch)
tree658dd0d1060516e976bb56a6609455fd954053ff /ghc/rts/Adjustor.c
parent699c37dc5053af5983c41a52dc7c5a9e03fc82e4 (diff)
downloadhaskell-17deccb787981d77615106b8157e5ac26f2c8ddb.tar.gz
[project @ 2002-04-25 18:18:56 by panne]
Highly untested fixes for SPARC: * Commented on "fully correct" solution * Flush cache * Fixed freeHaskellFunctionPtr FYI: http://www.cs.unm.edu/~maccabe/classes/341/labman/node12.html contains a good "Dummy's Guide" to the SPARC stack frame layout. Just if you can't dig this info up on e.g. SUN's site, because they've hidden everything useful... :-]
Diffstat (limited to 'ghc/rts/Adjustor.c')
-rw-r--r--ghc/rts/Adjustor.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/ghc/rts/Adjustor.c b/ghc/rts/Adjustor.c
index b0448c7942..b6887ad642 100644
--- a/ghc/rts/Adjustor.c
+++ b/ghc/rts/Adjustor.c
@@ -192,6 +192,10 @@ 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: Alas, the "fully correct" solution above is only
+ half correct: "%sp has to be 16-byte aligned at all time", the
+ almighty ABI spec says...
*/
if ((adjustor = stgMallocBytes(4*(8+1), "createAdjustor")) != NULL) {
unsigned long *const adj_code = (unsigned long *)adjustor;
@@ -222,6 +226,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
@@ -377,13 +393,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);