
Justin Bailey wrote:
I'm trying to get a feel for the assembly output by GHC on my platform. Below is a module containing one function and the associated assembly. I've put in comments what I think is going on, but I'd appreciate it if anyone could give me some pointers. I'd really like to know three things:
* Why does _Add_unsafeShiftR_info check if (%esi) is 3? * What's going on in _s86_info? * At the end of _s87_info, 8 is added to %ebp and then jumped to. Is that a jump to the I# constructor and, if so, how did it's address get to that offset from %ebp?
One point that seems to irritate you is that ghc does pointer tagging; the lower 2 bits of a pointer are zero if it points to an unevaluated closure (a thunk); otherwise they encode a constructor. (I'm not sure what happens in the case when there are more than 3 constructors. But in your case there's only one, I#, with tag 01.) Register usage (as far as I can see): %ebp - STG stack pointer %edi - Heap pointer (in particular cmpl 92(%ebx),%edi is a heap check and will trigger a GC) %esi - at start of *_info, points to most recently evaluated value. %ebx - points to some RTS global variables. Rough outline of the code: _Add_unsafeShiftR_info: find first argument, and evaluate it if it's not yet fully evaluated. continue at _s86_info. (note that a pointer to _s86_info, a continuation, is stored on the control stack) _s86_info: store the first argument value on the stack, load the second one, and evaluate it if necessary. continue at _s87_info. _s87_info: load both arguments, and compute result. The result is fully evaluated, so a tagged pointer is returned. (the -3 is -4, plus 1 for the tag) clean up the stack (the space for the two arguments is no longer needed) and jump to the continuation stored by the caller. HTH, Bertram