[project @ 1996-06-05 06:44:31 by partain]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgUpdate.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[CgUpdate]{Manipulating update frames}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module CgUpdate ( pushUpdateFrame ) where
10
11 IMP_Ubiq(){-uitous-}
12
13 import CgMonad
14 import AbsCSyn
15
16 import CgCompInfo       ( sTD_UF_SIZE, sCC_STD_UF_SIZE )
17 import CgStackery       ( allocUpdateFrame )
18 import CmdLineOpts      ( opt_SccProfilingOn )
19 import Util             ( assertPanic )
20 \end{code}
21
22
23 %********************************************************
24 %*                                                      *
25 %*              Setting up update frames                *
26 %*                                                      *
27 %********************************************************
28 \subsection[setting-update-frames]{Setting up update frames}
29
30 @pushUpdateFrame@ $updatee$ pushes a general update frame which
31 points to $updatee$ as the thing to be updated.  It is only used
32 when a thunk has just been entered, so the (real) stack pointers
33 are guaranteed to be nicely aligned with the top of stack.
34 @pushUpdateFrame@ adjusts the virtual and tail stack pointers
35 to reflect the frame pushed.
36
37 \begin{code}
38 pushUpdateFrame :: CAddrMode -> CAddrMode -> Code -> Code
39
40 pushUpdateFrame updatee vector code
41   = let
42         profiling_on = opt_SccProfilingOn
43
44         -- frame_size *includes* the return address
45         frame_size = if profiling_on
46                      then sCC_STD_UF_SIZE
47                      else sTD_UF_SIZE
48     in
49     getEndOfBlockInfo                   `thenFC` \ eob_info ->
50     ASSERT(case eob_info of { EndOfBlockInfo _ _ InRetReg -> True; _ -> False})
51     allocUpdateFrame frame_size vector (\ _ ->
52
53                 -- Emit the push macro
54             absC (CMacroStmt PUSH_STD_UPD_FRAME [
55                         updatee,
56                         int_CLit0,      -- Known to be zero because we have just
57                         int_CLit0       -- entered a thunk
58             ])
59             `thenC` code
60     )
61
62 int_CLit0 = mkIntCLit 0 -- out here to avoid pushUpdateFrame CAF (sigh)
63
64 {- ---------------------
65     What actually happens is something like this; but it got macro-ised
66
67   = pushOnBStack (CReg CurCostCentre)                   `thenFC` \ _ ->
68     pushOnBStack (CReg SuA)                             `thenFC` \ _ ->
69     pushOnBStack (CReg SuB)                             `thenFC` \ _ ->
70     pushOnBStack updatee                                `thenFC` \ _ ->
71     pushOnBStack (CLabel sTD_UPD_RET_VEC_LABEL CodePtrRep) `thenFC` \ _ ->
72
73         -- MAKE SuA, SuB POINT TO TOP OF A,B STACKS
74         -- Remember, SpB hasn't yet been incremented to account for the
75         -- 4-word update frame which has been pushed.
76         -- This code seems crude, but effective...
77     absC (AbsCStmts (CAssign (CReg SuA) (CReg SpA))
78                     (CAssign (CReg SuB) (CAddr (SpBRel 0 4))))
79 -------------------------- -}
80 \end{code}