Calling an unknown function from low-level Cmm
Hi all, I’m trying to understand how to properly call an unknown function from low-level Cmm code. If I’m just applying a function to a state token, it’s easy; I can just do R1 = io; jump stg_ap_v_fast [R1]; since the calling convention is consistent in that case. But what if my function takes actual arguments? I can’t do R1 = fun; R2 = arg; jump stg_ap_p_fast [R1, R2]; because if the calling convention doesn’t pass any arguments in registers, that would be wrong. I could check if NO_ARG_REGS is defined and generate different code in that situation, but that seems extreme. One option I think would work would be to do R1 = fun; Sp_adj(-2); Sp(1) = arg; jump RET_LBL(stg_ap_p) [R1]; but that seems wasteful if I have the argument in a register already anyway. Am I missing something? Thanks, Alexis
I don’t know the answer to this, but Alexis when you find out can I ask (I know I'm a broken record on this) that you write a Note to explain, with pointers from the various places you looked when you were trying to find out the answer? Thanks! Simon | -----Original Message----- | From: ghc-devs <ghc-devs-bounces@haskell.org> On Behalf Of Alexis King | Sent: 14 February 2020 19:53 | To: ghc-devs <ghc-devs@haskell.org> | Subject: Calling an unknown function from low-level Cmm | | Hi all, | | I’m trying to understand how to properly call an unknown function from | low-level Cmm code. If I’m just applying a function to a state token, it’s | easy; I can just do | | R1 = io; | jump stg_ap_v_fast [R1]; | | since the calling convention is consistent in that case. But what if my | function takes actual arguments? I can’t do | | R1 = fun; | R2 = arg; | jump stg_ap_p_fast [R1, R2]; | | because if the calling convention doesn’t pass any arguments in registers, | that would be wrong. I could check if NO_ARG_REGS is defined and generate | different code in that situation, but that seems extreme. One option I | think would work would be to do | | R1 = fun; | Sp_adj(-2); | Sp(1) = arg; | jump RET_LBL(stg_ap_p) [R1]; | | but that seems wasteful if I have the argument in a register already | anyway. Am I missing something? | | Thanks, | Alexis | _______________________________________________ | ghc-devs mailing list | ghc-devs@haskell.org | https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.hask | ell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc- | devs&data=02%7C01%7Csimonpj%40microsoft.com%7Cbc07f87bae6d4bb96b8d08d7 | b187813d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637173067859470793&a | mp;sdata=uVYlDXXGfB1vN0MD%2FM%2BBsUflWvrfkYPTEFtVJk2N7Y4%3D&reserved=0
On Feb 24, 2020, at 20:03, Simon Peyton Jones <simonpj@microsoft.com> wrote:
I don’t know the answer to this, but Alexis when you find out can I ask (I know I'm a broken record on this) that you write a Note to explain, with pointers from the various places you looked when you were trying to find out the answer?
If I do find out, I will! However, I’ve interpreted the lack of response to mean there isn’t one: the only easy way to do this is to pass the arguments on the stack using one of the stg_ap closures. I’m not sure if that non-answer is worth writing someplace, and if it is, I’m not quite sure where it ought to go. (Perhaps in GHC/Cmm/Parser.y?)
participants (2)
-
Alexis King -
Simon Peyton Jones