summaryrefslogtreecommitdiff
path: root/compiler/codeGen/CgTailCall.lhs
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2009-06-09 15:11:55 +0000
committerDuncan Coutts <duncan@well-typed.com>2009-06-09 15:11:55 +0000
commitcbbee4e8727c583daf32d9bf17f00afaa839ef10 (patch)
treeb86e3e566d90444803eb6fc7592cf2a162d04d94 /compiler/codeGen/CgTailCall.lhs
parent5b7e2a875b089f31cd8dedb52d47ef9a93f276be (diff)
downloadhaskell-cbbee4e8727c583daf32d9bf17f00afaa839ef10.tar.gz
Add PrimCall to the STG layer and update Core -> STG translation
It adds a third case to StgOp which already hold StgPrimOp and StgFCallOp. The code generation for the new StgPrimCallOp case is almost exactly the same as for out-of-line primops. They now share the tailCallPrim function. In the Core -> STG translation we map foreign calls using the "prim" calling convention to the StgPrimCallOp case. This is because in Core we represent prim calls using the ForeignCall stuff. At the STG level however the prim calls are really much more like primops than foreign calls.
Diffstat (limited to 'compiler/codeGen/CgTailCall.lhs')
-rw-r--r--compiler/codeGen/CgTailCall.lhs13
1 files changed, 11 insertions, 2 deletions
diff --git a/compiler/codeGen/CgTailCall.lhs b/compiler/codeGen/CgTailCall.lhs
index 60a856177c..89c050406f 100644
--- a/compiler/codeGen/CgTailCall.lhs
+++ b/compiler/codeGen/CgTailCall.lhs
@@ -11,6 +11,7 @@ module CgTailCall (
returnUnboxedTuple, ccallReturnUnboxedTuple,
pushUnboxedTuple,
tailCallPrimOp,
+ tailCallPrimCall,
pushReturnAddress
) where
@@ -382,13 +383,21 @@ ccallReturnUnboxedTuple amodes before_jump
-- Calling an out-of-line primop
tailCallPrimOp :: PrimOp -> [StgArg] -> Code
-tailCallPrimOp op args
+tailCallPrimOp op
+ = tailCallPrim (mkRtsPrimOpLabel op)
+
+tailCallPrimCall :: PrimCall -> [StgArg] -> Code
+tailCallPrimCall primcall
+ = tailCallPrim (mkPrimCallLabel primcall)
+
+tailCallPrim :: CLabel -> [StgArg] -> Code
+tailCallPrim lbl args
= do { -- We're going to perform a normal-looking tail call,
-- except that *all* the arguments will be in registers.
-- Hence the ASSERT( null leftovers )
arg_amodes <- getArgAmodes args
; let (arg_regs, leftovers) = assignPrimOpCallRegs arg_amodes
- jump_to_primop = jumpToLbl (mkRtsPrimOpLabel op)
+ jump_to_primop = jumpToLbl lbl
; ASSERT(null leftovers) -- no stack-resident args
emitSimultaneously (assignToRegs arg_regs)