1 -- -----------------------------------------------------------------------------
3 -- (c) The University of Glasgow 1993-2004
5 -- The native code generator's monad.
7 -- -----------------------------------------------------------------------------
10 NatM_State(..), mkNatM_State,
12 NatM, -- instance Monad
30 #include "HsVersions.h"
37 import CLabel ( CLabel, mkAsmTempLabel )
39 import Unique ( Unique )
44 natm_us :: UniqSupply,
46 natm_imports :: [(CLabel)],
47 natm_pic :: Maybe Reg,
48 natm_dflags :: DynFlags
51 newtype NatM result = NatM (NatM_State -> (result, NatM_State))
53 unNat :: NatM a -> NatM_State -> (a, NatM_State)
56 mkNatM_State :: UniqSupply -> Int -> DynFlags -> NatM_State
57 mkNatM_State us delta dflags
58 = NatM_State us delta [] Nothing dflags
60 initNat :: NatM_State -> NatM a -> (a, NatM_State)
62 = case unNat m init_st of { (r,st) -> (r,st) }
65 instance Monad NatM where
70 thenNat :: NatM a -> (a -> NatM b) -> NatM b
72 = NatM $ \st -> case unNat expr st of
73 (result, st') -> unNat (cont result) st'
75 returnNat :: a -> NatM a
77 = NatM $ \st -> (result, st)
79 mapAccumLNat :: (acc -> x -> NatM (acc, y))
86 mapAccumLNat f b (x:xs)
87 = do (b__2, x__2) <- f b x
88 (b__3, xs__2) <- mapAccumLNat f b__2 xs
89 return (b__3, x__2:xs__2)
91 getUniqueNat :: NatM Unique
92 getUniqueNat = NatM $ \ (NatM_State us delta imports pic dflags) ->
93 case splitUniqSupply us of
94 (us1,us2) -> (uniqFromSupply us1, (NatM_State us2 delta imports pic dflags))
97 getDynFlagsNat :: NatM DynFlags
99 = NatM $ \ (NatM_State us delta imports pic dflags) ->
100 (dflags, (NatM_State us delta imports pic dflags))
103 getDeltaNat :: NatM Int
105 = NatM $ \ st -> (natm_delta st, st)
108 setDeltaNat :: Int -> NatM ()
110 = NatM $ \ (NatM_State us _ imports pic dflags) ->
111 ((), NatM_State us delta imports pic dflags)
114 addImportNat :: CLabel -> NatM ()
116 = NatM $ \ (NatM_State us delta imports pic dflags) ->
117 ((), NatM_State us delta (imp:imports) pic dflags)
120 getBlockIdNat :: NatM BlockId
122 = do u <- getUniqueNat
126 getNewLabelNat :: NatM CLabel
128 = do u <- getUniqueNat
129 return (mkAsmTempLabel u)
132 getNewRegNat :: Size -> NatM Reg
134 = do u <- getUniqueNat
135 return (RegVirtual $ targetMkVirtualReg u rep)
138 getNewRegPairNat :: Size -> NatM (Reg,Reg)
140 = do u <- getUniqueNat
141 let vLo = targetMkVirtualReg u rep
142 let lo = RegVirtual $ targetMkVirtualReg u rep
143 let hi = RegVirtual $ getHiVirtualRegFromLo vLo
147 getPicBaseMaybeNat :: NatM (Maybe Reg)
149 = NatM (\state -> (natm_pic state, state))
152 getPicBaseNat :: Size -> NatM Reg
154 = do mbPicBase <- getPicBaseMaybeNat
156 Just picBase -> return picBase
159 reg <- getNewRegNat rep
160 NatM (\state -> (reg, state { natm_pic = Just reg }))