createAdjustor for Alpha (and Sparc)

Hello again, It seems that I have a registerised GHC mostly working on the Alpha. The main missing piece is createAdjustor. My understanding of (the _ccall rather than _stdcall part of) createAdjustor is as follows: Given "hptr" and "wptr" of types void *hptr; {return type} (*wptr)(void *, void *, {more arguments}); createAdjustor creates "adjustor" of the type {return type} (*adjustor)({more arguments}); such that calling (*adjustor)({argument values}) is equivalent to calling (*wptr)(hptr, {undefined/ignored pointer}, {argument values}). This goal seems difficult to achieve on the Alpha, since its complicated calling convention puts arguments in registers, and we don't know how many arguments there are, let alone how to adjust the stack if needed. But wait! There's a Sparc port of createAdjustor already, and the Sparc passes arguments in registers too! How was that done? I pored over the #ifdef sparc_TARGET_ARCH code in Adjustor.c, and couldn't understand. It puts hptr in %o0 and wptr in %o1, where I assume %o0 is where the first argument is expected in _ccall, but what about shifting over {more arguments}? In any case, given that many architectures pass arguments in registers nowadays, what seems like a more universally workable approach to me is to pass hptr not as a regular function call argument but inside a special register that the called stub function (i.e., *wptr) knows about. This register must be caller-save and must not be involved in the usual prologue sequence generated by gcc. I'd guess that the following would work: i386 %eax alpha $0 = $v0 sparc %g7 This new scheme would involve changing DsForeign.lhs to output different _ccall stub code. Would it work? Any demystification would be greatly appreciated. (By the way, why can't we use $0 and $1 on the Alpha? Only $2 and up are assigned in MachRegs.h.) -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig « ne gâche pas ta vie pour leur idée de patrie » le bouton me dit

Ken Shan wrote:
such that calling
(*adjustor)({argument values})
is equivalent to calling
(*wptr)(hptr, {undefined/ignored pointer}, {argument values}).
This goal seems difficult to achieve on the Alpha, since its complicated calling convention puts arguments in registers, and we don't know how many arguments there are, let alone how to adjust the stack if needed.
And it's very complicated on the MIPS too where the argument passing convention depends on the type of the arguments. Perhaps the GHC way is too simplistic? I did these kinds of things for a number of platforms many years (8?) ago and came to the conclusion that the most realiable way was to create a fast array of functions for different argument combinations. Once you get beyond a certain number of arguments all platforms start using the stack and then you are safe again. But it's a mess. -- Lennart
participants (2)
-
Ken Shan
-
Lennart Augustsson