[project @ 2005-03-24 15:22:33 by simonmar]
[ghc-hetmet.git] / ghc / compiler / nativeGen / NCGMonad.hs
1 -- -----------------------------------------------------------------------------
2 --
3 -- (c) The University of Glasgow 1993-2004
4 -- 
5 -- The native code generator's monad.
6 --
7 -- -----------------------------------------------------------------------------
8
9 module NCGMonad (
10         NatM_State(..), mkNatM_State,
11
12         NatM, -- instance Monad
13         initNat, addImportNat, getUniqueNat,
14         mapAccumLNat, setDeltaNat, getDeltaNat,
15         getBlockIdNat, getNewLabelNat, getNewRegNat, getNewRegPairNat,
16         getPicBaseMaybeNat, getPicBaseNat
17  ) where
18   
19 #include "HsVersions.h"
20
21 import Cmm              ( BlockId(..) )
22 import CLabel           ( CLabel, mkAsmTempLabel )
23 import MachRegs
24 import MachOp           ( MachRep )
25 import UniqSupply
26 import Unique           ( Unique )
27
28
29 data NatM_State = NatM_State {
30                         natm_us      :: UniqSupply,
31                         natm_delta   :: Int,
32                         natm_imports :: [(CLabel)],
33                         natm_pic     :: Maybe Reg
34                 }
35
36 newtype NatM result = NatM (NatM_State -> (result, NatM_State))
37
38 unNat (NatM a) = a
39
40 mkNatM_State :: UniqSupply -> Int -> NatM_State
41 mkNatM_State us delta = NatM_State us delta [] Nothing
42
43 initNat :: NatM_State -> NatM a -> (a, NatM_State)
44 initNat init_st m = case unNat m init_st of { (r,st) -> (r,st) }
45
46 instance Monad NatM where
47   (>>=) = thenNat
48   return = returnNat
49
50 thenNat :: NatM a -> (a -> NatM b) -> NatM b
51 thenNat expr cont
52   = NatM $ \st -> case unNat expr st of
53                         (result, st') -> unNat (cont result) st'
54
55 returnNat :: a -> NatM a
56 returnNat result = NatM $ \st ->  (result, st)
57
58 mapAccumLNat :: (acc -> x -> NatM (acc, y))
59                 -> acc
60                 -> [x]
61                 -> NatM (acc, [y])
62
63 mapAccumLNat f b []
64   = return (b, [])
65 mapAccumLNat f b (x:xs)
66   = do (b__2, x__2)  <- f b x
67        (b__3, xs__2) <- mapAccumLNat f b__2 xs
68        return (b__3, x__2:xs__2)
69
70 getUniqueNat :: NatM Unique
71 getUniqueNat = NatM $ \ (NatM_State us delta imports pic) ->
72     case splitUniqSupply us of
73          (us1,us2) -> (uniqFromSupply us1, (NatM_State us2 delta imports pic))
74
75 getDeltaNat :: NatM Int
76 getDeltaNat = NatM $ \ st -> (natm_delta st, st)
77
78 setDeltaNat :: Int -> NatM ()
79 setDeltaNat delta = NatM $ \ (NatM_State us _ imports pic) ->
80    ((), NatM_State us delta imports pic)
81
82 addImportNat :: CLabel -> NatM ()
83 addImportNat imp = NatM $ \ (NatM_State us delta imports pic) -> 
84    ((), NatM_State us delta (imp:imports) pic)
85
86 getBlockIdNat :: NatM BlockId
87 getBlockIdNat = do u <- getUniqueNat; return (BlockId u)
88
89 getNewLabelNat :: NatM CLabel
90 getNewLabelNat = do u <- getUniqueNat; return (mkAsmTempLabel u)
91
92 getNewRegNat :: MachRep -> NatM Reg
93 getNewRegNat rep = do u <- getUniqueNat; return (mkVReg u rep)
94
95 getNewRegPairNat :: MachRep -> NatM (Reg,Reg)
96 getNewRegPairNat rep = do 
97   u <- getUniqueNat
98   let lo = mkVReg u rep; hi = getHiVRegFromLo lo
99   return (lo,hi)
100
101 getPicBaseMaybeNat :: NatM (Maybe Reg)
102 getPicBaseMaybeNat = NatM (\state -> (natm_pic state, state))
103
104 getPicBaseNat :: MachRep -> NatM Reg
105 getPicBaseNat rep = do
106   mbPicBase <- getPicBaseMaybeNat
107   case mbPicBase of
108         Just picBase -> return picBase
109         Nothing -> do
110             reg <- getNewRegNat rep
111             NatM (\state -> (reg, state { natm_pic = Just reg }))