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