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
13 initNat, addImportNat, getUniqueNat,
14 mapAccumLNat, setDeltaNat, getDeltaNat,
15 getBlockIdNat, getNewLabelNat, getNewRegNat, getNewRegPairNat,
16 getPicBaseMaybeNat, getPicBaseNat, getDynFlagsNat
19 #include "HsVersions.h"
21 import Cmm ( BlockId(..) )
22 import CLabel ( CLabel, mkAsmTempLabel )
24 import MachOp ( MachRep )
26 import Unique ( Unique )
29 data NatM_State = NatM_State {
30 natm_us :: UniqSupply,
32 natm_imports :: [(CLabel)],
33 natm_pic :: Maybe Reg,
34 natm_dflags :: DynFlags
37 newtype NatM result = NatM (NatM_State -> (result, NatM_State))
41 mkNatM_State :: UniqSupply -> Int -> DynFlags -> NatM_State
42 mkNatM_State us delta dflags = NatM_State us delta [] Nothing dflags
44 initNat :: NatM_State -> NatM a -> (a, NatM_State)
45 initNat init_st m = case unNat m init_st of { (r,st) -> (r,st) }
47 instance Monad NatM where
51 thenNat :: NatM a -> (a -> NatM b) -> NatM b
53 = NatM $ \st -> case unNat expr st of
54 (result, st') -> unNat (cont result) st'
56 returnNat :: a -> NatM a
57 returnNat result = NatM $ \st -> (result, st)
59 mapAccumLNat :: (acc -> x -> NatM (acc, y))
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)
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))
77 getDynFlagsNat :: NatM DynFlags
78 getDynFlagsNat = NatM $ \ (NatM_State us delta imports pic dflags) ->
79 (dflags, (NatM_State us delta imports pic dflags))
81 getDeltaNat :: NatM Int
82 getDeltaNat = NatM $ \ st -> (natm_delta st, st)
84 setDeltaNat :: Int -> NatM ()
85 setDeltaNat delta = NatM $ \ (NatM_State us _ imports pic dflags) ->
86 ((), NatM_State us delta imports pic dflags)
88 addImportNat :: CLabel -> NatM ()
89 addImportNat imp = NatM $ \ (NatM_State us delta imports pic dflags) ->
90 ((), NatM_State us delta (imp:imports) pic dflags)
92 getBlockIdNat :: NatM BlockId
93 getBlockIdNat = do u <- getUniqueNat; return (BlockId u)
95 getNewLabelNat :: NatM CLabel
96 getNewLabelNat = do u <- getUniqueNat; return (mkAsmTempLabel u)
98 getNewRegNat :: MachRep -> NatM Reg
99 getNewRegNat rep = do u <- getUniqueNat; return (mkVReg u rep)
101 getNewRegPairNat :: MachRep -> NatM (Reg,Reg)
102 getNewRegPairNat rep = do
104 let lo = mkVReg u rep; hi = getHiVRegFromLo lo
107 getPicBaseMaybeNat :: NatM (Maybe Reg)
108 getPicBaseMaybeNat = NatM (\state -> (natm_pic state, state))
110 getPicBaseNat :: MachRep -> NatM Reg
111 getPicBaseNat rep = do
112 mbPicBase <- getPicBaseMaybeNat
114 Just picBase -> return picBase
116 reg <- getNewRegNat rep
117 NatM (\state -> (reg, state { natm_pic = Just reg }))