Simplify generation of PR dictionaries for products
[ghc-hetmet.git] / 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, getDynFlagsNat
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 import DynFlags
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                         natm_dflags  :: DynFlags
35                 }
36
37 newtype NatM result = NatM (NatM_State -> (result, NatM_State))
38
39 unNat (NatM a) = a
40
41 mkNatM_State :: UniqSupply -> Int -> DynFlags -> NatM_State
42 mkNatM_State us delta dflags = NatM_State us delta [] Nothing dflags
43
44 initNat :: NatM_State -> NatM a -> (a, NatM_State)
45 initNat init_st m = case unNat m init_st of { (r,st) -> (r,st) }
46
47 instance Monad NatM where
48   (>>=) = thenNat
49   return = returnNat
50
51 thenNat :: NatM a -> (a -> NatM b) -> NatM b
52 thenNat expr cont
53   = NatM $ \st -> case unNat expr st of
54                         (result, st') -> unNat (cont result) st'
55
56 returnNat :: a -> NatM a
57 returnNat result = NatM $ \st ->  (result, st)
58
59 mapAccumLNat :: (acc -> x -> NatM (acc, y))
60                 -> acc
61                 -> [x]
62                 -> NatM (acc, [y])
63
64 mapAccumLNat f b []
65   = return (b, [])
66 mapAccumLNat f b (x:xs)
67   = do (b__2, x__2)  <- f b x
68        (b__3, xs__2) <- mapAccumLNat f b__2 xs
69        return (b__3, x__2:xs__2)
70
71 getUniqueNat :: NatM Unique
72 getUniqueNat = NatM $ \ (NatM_State us delta imports pic dflags) ->
73     case splitUniqSupply us of
74          (us1,us2) -> (uniqFromSupply us1, (NatM_State us2 delta imports pic dflags))
75
76
77 getDynFlagsNat :: NatM DynFlags
78 getDynFlagsNat = NatM $ \ (NatM_State us delta imports pic dflags) ->
79                           (dflags, (NatM_State us delta imports pic dflags))
80
81 getDeltaNat :: NatM Int
82 getDeltaNat = NatM $ \ st -> (natm_delta st, st)
83
84 setDeltaNat :: Int -> NatM ()
85 setDeltaNat delta = NatM $ \ (NatM_State us _ imports pic dflags) ->
86    ((), NatM_State us delta imports pic dflags)
87
88 addImportNat :: CLabel -> NatM ()
89 addImportNat imp = NatM $ \ (NatM_State us delta imports pic dflags) ->
90    ((), NatM_State us delta (imp:imports) pic dflags)
91
92 getBlockIdNat :: NatM BlockId
93 getBlockIdNat = do u <- getUniqueNat; return (BlockId u)
94
95 getNewLabelNat :: NatM CLabel
96 getNewLabelNat = do u <- getUniqueNat; return (mkAsmTempLabel u)
97
98 getNewRegNat :: MachRep -> NatM Reg
99 getNewRegNat rep = do u <- getUniqueNat; return (mkVReg u rep)
100
101 getNewRegPairNat :: MachRep -> NatM (Reg,Reg)
102 getNewRegPairNat rep = do 
103   u <- getUniqueNat
104   let lo = mkVReg u rep; hi = getHiVRegFromLo lo
105   return (lo,hi)
106
107 getPicBaseMaybeNat :: NatM (Maybe Reg)
108 getPicBaseMaybeNat = NatM (\state -> (natm_pic state, state))
109
110 getPicBaseNat :: MachRep -> NatM Reg
111 getPicBaseNat rep = do
112   mbPicBase <- getPicBaseMaybeNat
113   case mbPicBase of
114         Just picBase -> return picBase
115         Nothing -> do
116             reg <- getNewRegNat rep
117             NatM (\state -> (reg, state { natm_pic = Just reg }))