diff options
author | panne <unknown> | 2002-04-25 18:18:56 +0000 |
---|---|---|
committer | panne <unknown> | 2002-04-25 18:18:56 +0000 |
commit | 17deccb787981d77615106b8157e5ac26f2c8ddb (patch) | |
tree | 658dd0d1060516e976bb56a6609455fd954053ff /ghc/rts/Adjustor.c | |
parent | 699c37dc5053af5983c41a52dc7c5a9e03fc82e4 (diff) | |
download | haskell-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.c | 20 |
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); |