summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/NCGMonad.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/nativeGen/NCGMonad.hs')
-rw-r--r--compiler/nativeGen/NCGMonad.hs111
1 files changed, 111 insertions, 0 deletions
diff --git a/compiler/nativeGen/NCGMonad.hs b/compiler/nativeGen/NCGMonad.hs
new file mode 100644
index 0000000000..8fdcd44024
--- /dev/null
+++ b/compiler/nativeGen/NCGMonad.hs
@@ -0,0 +1,111 @@
+-- -----------------------------------------------------------------------------
+--
+-- (c) The University of Glasgow 1993-2004
+--
+-- The native code generator's monad.
+--
+-- -----------------------------------------------------------------------------
+
+module NCGMonad (
+ NatM_State(..), mkNatM_State,
+
+ NatM, -- instance Monad
+ initNat, addImportNat, getUniqueNat,
+ mapAccumLNat, setDeltaNat, getDeltaNat,
+ getBlockIdNat, getNewLabelNat, getNewRegNat, getNewRegPairNat,
+ getPicBaseMaybeNat, getPicBaseNat
+ ) where
+
+#include "HsVersions.h"
+
+import Cmm ( BlockId(..) )
+import CLabel ( CLabel, mkAsmTempLabel )
+import MachRegs
+import MachOp ( MachRep )
+import UniqSupply
+import Unique ( Unique )
+
+
+data NatM_State = NatM_State {
+ natm_us :: UniqSupply,
+ natm_delta :: Int,
+ natm_imports :: [(CLabel)],
+ natm_pic :: Maybe Reg
+ }
+
+newtype NatM result = NatM (NatM_State -> (result, NatM_State))
+
+unNat (NatM a) = a
+
+mkNatM_State :: UniqSupply -> Int -> NatM_State
+mkNatM_State us delta = NatM_State us delta [] Nothing
+
+initNat :: NatM_State -> NatM a -> (a, NatM_State)
+initNat init_st m = case unNat m init_st of { (r,st) -> (r,st) }
+
+instance Monad NatM where
+ (>>=) = thenNat
+ return = returnNat
+
+thenNat :: NatM a -> (a -> NatM b) -> NatM b
+thenNat expr cont
+ = NatM $ \st -> case unNat expr st of
+ (result, st') -> unNat (cont result) st'
+
+returnNat :: a -> NatM a
+returnNat result = NatM $ \st -> (result, st)
+
+mapAccumLNat :: (acc -> x -> NatM (acc, y))
+ -> acc
+ -> [x]
+ -> NatM (acc, [y])
+
+mapAccumLNat f b []
+ = return (b, [])
+mapAccumLNat f b (x:xs)
+ = do (b__2, x__2) <- f b x
+ (b__3, xs__2) <- mapAccumLNat f b__2 xs
+ return (b__3, x__2:xs__2)
+
+getUniqueNat :: NatM Unique
+getUniqueNat = NatM $ \ (NatM_State us delta imports pic) ->
+ case splitUniqSupply us of
+ (us1,us2) -> (uniqFromSupply us1, (NatM_State us2 delta imports pic))
+
+getDeltaNat :: NatM Int
+getDeltaNat = NatM $ \ st -> (natm_delta st, st)
+
+setDeltaNat :: Int -> NatM ()
+setDeltaNat delta = NatM $ \ (NatM_State us _ imports pic) ->
+ ((), NatM_State us delta imports pic)
+
+addImportNat :: CLabel -> NatM ()
+addImportNat imp = NatM $ \ (NatM_State us delta imports pic) ->
+ ((), NatM_State us delta (imp:imports) pic)
+
+getBlockIdNat :: NatM BlockId
+getBlockIdNat = do u <- getUniqueNat; return (BlockId u)
+
+getNewLabelNat :: NatM CLabel
+getNewLabelNat = do u <- getUniqueNat; return (mkAsmTempLabel u)
+
+getNewRegNat :: MachRep -> NatM Reg
+getNewRegNat rep = do u <- getUniqueNat; return (mkVReg u rep)
+
+getNewRegPairNat :: MachRep -> NatM (Reg,Reg)
+getNewRegPairNat rep = do
+ u <- getUniqueNat
+ let lo = mkVReg u rep; hi = getHiVRegFromLo lo
+ return (lo,hi)
+
+getPicBaseMaybeNat :: NatM (Maybe Reg)
+getPicBaseMaybeNat = NatM (\state -> (natm_pic state, state))
+
+getPicBaseNat :: MachRep -> NatM Reg
+getPicBaseNat rep = do
+ mbPicBase <- getPicBaseMaybeNat
+ case mbPicBase of
+ Just picBase -> return picBase
+ Nothing -> do
+ reg <- getNewRegNat rep
+ NatM (\state -> (reg, state { natm_pic = Just reg }))