[project @ 2004-08-13 13:04:50 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  ) where
17   
18 #include "HsVersions.h"
19
20 import Cmm              ( BlockId(..) )
21 import CLabel           ( CLabel, mkAsmTempLabel )
22 import MachRegs
23 import MachOp           ( MachRep )
24 import UniqSupply
25 import Unique           ( Unique )
26
27
28 data NatM_State = NatM_State {
29                         natm_us      :: UniqSupply,
30                         natm_delta   :: Int,
31                         natm_imports :: [(Bool,CLabel)]
32                 }
33
34 newtype NatM result = NatM (NatM_State -> (result, NatM_State))
35
36 unNat (NatM a) = a
37
38 mkNatM_State :: UniqSupply -> Int -> NatM_State
39 mkNatM_State us delta = NatM_State us delta []
40
41 initNat :: NatM_State -> NatM a -> (a, NatM_State)
42 initNat init_st m = case unNat m init_st of { (r,st) -> (r,st) }
43
44 instance Monad NatM where
45   (>>=) = thenNat
46   return = returnNat
47
48 thenNat :: NatM a -> (a -> NatM b) -> NatM b
49 thenNat expr cont
50   = NatM $ \st -> case unNat expr st of
51                         (result, st') -> unNat (cont result) st'
52
53 returnNat :: a -> NatM a
54 returnNat result = NatM $ \st ->  (result, st)
55
56 mapAccumLNat :: (acc -> x -> NatM (acc, y))
57                 -> acc
58                 -> [x]
59                 -> NatM (acc, [y])
60
61 mapAccumLNat f b []
62   = return (b, [])
63 mapAccumLNat f b (x:xs)
64   = do (b__2, x__2)  <- f b x
65        (b__3, xs__2) <- mapAccumLNat f b__2 xs
66        return (b__3, x__2:xs__2)
67
68 getUniqueNat :: NatM Unique
69 getUniqueNat = NatM $ \ (NatM_State us delta imports) ->
70     case splitUniqSupply us of
71          (us1,us2) -> (uniqFromSupply us1, (NatM_State us2 delta imports))
72
73 getDeltaNat :: NatM Int
74 getDeltaNat = NatM $ \ st -> (natm_delta st, st)
75
76 setDeltaNat :: Int -> NatM ()
77 setDeltaNat delta = NatM $ \ (NatM_State us _ imports) ->
78    ((), NatM_State us delta imports)
79
80 addImportNat :: Bool -> CLabel -> NatM ()
81 addImportNat is_code imp = NatM $ \ (NatM_State us delta imports) -> 
82    ((), NatM_State us delta ((is_code,imp):imports))
83
84 getBlockIdNat :: NatM BlockId
85 getBlockIdNat = do u <- getUniqueNat; return (BlockId u)
86
87 getNewLabelNat :: NatM CLabel
88 getNewLabelNat = do u <- getUniqueNat; return (mkAsmTempLabel u)
89
90 getNewRegNat :: MachRep -> NatM Reg
91 getNewRegNat rep = do u <- getUniqueNat; return (mkVReg u rep)
92
93 getNewRegPairNat :: MachRep -> NatM (Reg,Reg)
94 getNewRegPairNat rep = do 
95   u <- getUniqueNat
96   let lo = mkVReg u rep; hi = getHiVRegFromLo lo
97   return (lo,hi)
98