Merging in the new codegen branch
[ghc-hetmet.git] / compiler / nativeGen / NCGMonad.hs
1 {-# OPTIONS -w #-}
2 -- The above warning supression flag is a temporary kludge.
3 -- While working on this module you are encouraged to remove it and fix
4 -- any warnings in the module. See
5 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
6 -- for details
7
8 -- -----------------------------------------------------------------------------
9 --
10 -- (c) The University of Glasgow 1993-2004
11 -- 
12 -- The native code generator's monad.
13 --
14 -- -----------------------------------------------------------------------------
15
16 module NCGMonad (
17         NatM_State(..), mkNatM_State,
18
19         NatM, -- instance Monad
20         initNat, addImportNat, getUniqueNat,
21         mapAccumLNat, setDeltaNat, getDeltaNat,
22         getBlockIdNat, getNewLabelNat, getNewRegNat, getNewRegPairNat,
23         getPicBaseMaybeNat, getPicBaseNat, getDynFlagsNat
24  ) where
25   
26 #include "HsVersions.h"
27
28 import BlockId
29 import CLabel           ( CLabel, mkAsmTempLabel )
30 import MachRegs
31 import UniqSupply
32 import Unique           ( Unique )
33 import DynFlags
34
35 data NatM_State = NatM_State {
36                         natm_us      :: UniqSupply,
37                         natm_delta   :: Int,
38                         natm_imports :: [(CLabel)],
39                         natm_pic     :: Maybe Reg,
40                         natm_dflags  :: DynFlags
41                 }
42
43 newtype NatM result = NatM (NatM_State -> (result, NatM_State))
44
45 unNat (NatM a) = a
46
47 mkNatM_State :: UniqSupply -> Int -> DynFlags -> NatM_State
48 mkNatM_State us delta dflags = NatM_State us delta [] Nothing dflags
49
50 initNat :: NatM_State -> NatM a -> (a, NatM_State)
51 initNat init_st m = case unNat m init_st of { (r,st) -> (r,st) }
52
53 instance Monad NatM where
54   (>>=) = thenNat
55   return = returnNat
56
57 thenNat :: NatM a -> (a -> NatM b) -> NatM b
58 thenNat expr cont
59   = NatM $ \st -> case unNat expr st of
60                         (result, st') -> unNat (cont result) st'
61
62 returnNat :: a -> NatM a
63 returnNat result = NatM $ \st ->  (result, st)
64
65 mapAccumLNat :: (acc -> x -> NatM (acc, y))
66                 -> acc
67                 -> [x]
68                 -> NatM (acc, [y])
69
70 mapAccumLNat f b []
71   = return (b, [])
72 mapAccumLNat f b (x:xs)
73   = do (b__2, x__2)  <- f b x
74        (b__3, xs__2) <- mapAccumLNat f b__2 xs
75        return (b__3, x__2:xs__2)
76
77 getUniqueNat :: NatM Unique
78 getUniqueNat = NatM $ \ (NatM_State us delta imports pic dflags) ->
79     case splitUniqSupply us of
80          (us1,us2) -> (uniqFromSupply us1, (NatM_State us2 delta imports pic dflags))
81
82
83 getDynFlagsNat :: NatM DynFlags
84 getDynFlagsNat = NatM $ \ (NatM_State us delta imports pic dflags) ->
85                           (dflags, (NatM_State us delta imports pic dflags))
86
87 getDeltaNat :: NatM Int
88 getDeltaNat = NatM $ \ st -> (natm_delta st, st)
89
90 setDeltaNat :: Int -> NatM ()
91 setDeltaNat delta = NatM $ \ (NatM_State us _ imports pic dflags) ->
92    ((), NatM_State us delta imports pic dflags)
93
94 addImportNat :: CLabel -> NatM ()
95 addImportNat imp = NatM $ \ (NatM_State us delta imports pic dflags) ->
96    ((), NatM_State us delta (imp:imports) pic dflags)
97
98 getBlockIdNat :: NatM BlockId
99 getBlockIdNat = do u <- getUniqueNat; return (BlockId u)
100
101 getNewLabelNat :: NatM CLabel
102 getNewLabelNat = do u <- getUniqueNat; return (mkAsmTempLabel u)
103
104 getNewRegNat :: Size -> NatM Reg
105 getNewRegNat rep = do u <- getUniqueNat; return (mkVReg u rep)
106
107 getNewRegPairNat :: Size -> NatM (Reg,Reg)
108 getNewRegPairNat rep = do 
109   u <- getUniqueNat
110   let lo = mkVReg u rep; hi = getHiVRegFromLo lo
111   return (lo,hi)
112
113 getPicBaseMaybeNat :: NatM (Maybe Reg)
114 getPicBaseMaybeNat = NatM (\state -> (natm_pic state, state))
115
116 getPicBaseNat :: Size -> NatM Reg
117 getPicBaseNat rep = do
118   mbPicBase <- getPicBaseMaybeNat
119   case mbPicBase of
120         Just picBase -> return picBase
121         Nothing -> do
122             reg <- getNewRegNat rep
123             NatM (\state -> (reg, state { natm_pic = Just reg }))