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