| 1 | -- ----------------------------------------------------------------------------- |
|---|
| 2 | -- |
|---|
| 3 | -- (c) The University of Glasgow 1993-2004 |
|---|
| 4 | -- |
|---|
| 5 | -- The native code generator's monad. |
|---|
| 6 | -- |
|---|
| 7 | -- ----------------------------------------------------------------------------- |
|---|
| 8 | |
|---|
| 9 | {-# OPTIONS -fno-warn-tabs #-} |
|---|
| 10 | -- The above warning supression flag is a temporary kludge. |
|---|
| 11 | -- While working on this module you are encouraged to remove it and |
|---|
| 12 | -- detab the module (please do the detabbing in a separate patch). See |
|---|
| 13 | -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces |
|---|
| 14 | -- for details |
|---|
| 15 | |
|---|
| 16 | module NCGMonad ( |
|---|
| 17 | NatM_State(..), mkNatM_State, |
|---|
| 18 | |
|---|
| 19 | NatM, -- instance Monad |
|---|
| 20 | initNat, |
|---|
| 21 | addImportNat, |
|---|
| 22 | getUniqueNat, |
|---|
| 23 | mapAccumLNat, |
|---|
| 24 | setDeltaNat, |
|---|
| 25 | getDeltaNat, |
|---|
| 26 | getBlockIdNat, |
|---|
| 27 | getNewLabelNat, |
|---|
| 28 | getNewRegNat, |
|---|
| 29 | getNewRegPairNat, |
|---|
| 30 | getPicBaseMaybeNat, |
|---|
| 31 | getPicBaseNat, |
|---|
| 32 | getDynFlags |
|---|
| 33 | ) |
|---|
| 34 | |
|---|
| 35 | where |
|---|
| 36 | |
|---|
| 37 | #include "HsVersions.h" |
|---|
| 38 | |
|---|
| 39 | import Reg |
|---|
| 40 | import Size |
|---|
| 41 | import TargetReg |
|---|
| 42 | |
|---|
| 43 | import BlockId |
|---|
| 44 | import CLabel ( CLabel, mkAsmTempLabel ) |
|---|
| 45 | import UniqSupply |
|---|
| 46 | import Unique ( Unique ) |
|---|
| 47 | import DynFlags |
|---|
| 48 | |
|---|
| 49 | data NatM_State |
|---|
| 50 | = NatM_State { |
|---|
| 51 | natm_us :: UniqSupply, |
|---|
| 52 | natm_delta :: Int, |
|---|
| 53 | natm_imports :: [(CLabel)], |
|---|
| 54 | natm_pic :: Maybe Reg, |
|---|
| 55 | natm_dflags :: DynFlags |
|---|
| 56 | } |
|---|
| 57 | |
|---|
| 58 | newtype NatM result = NatM (NatM_State -> (result, NatM_State)) |
|---|
| 59 | |
|---|
| 60 | unNat :: NatM a -> NatM_State -> (a, NatM_State) |
|---|
| 61 | unNat (NatM a) = a |
|---|
| 62 | |
|---|
| 63 | mkNatM_State :: UniqSupply -> Int -> DynFlags -> NatM_State |
|---|
| 64 | mkNatM_State us delta dflags |
|---|
| 65 | = NatM_State us delta [] Nothing dflags |
|---|
| 66 | |
|---|
| 67 | initNat :: NatM_State -> NatM a -> (a, NatM_State) |
|---|
| 68 | initNat init_st m |
|---|
| 69 | = case unNat m init_st of { (r,st) -> (r,st) } |
|---|
| 70 | |
|---|
| 71 | |
|---|
| 72 | instance Monad NatM where |
|---|
| 73 | (>>=) = thenNat |
|---|
| 74 | return = returnNat |
|---|
| 75 | |
|---|
| 76 | |
|---|
| 77 | thenNat :: NatM a -> (a -> NatM b) -> NatM b |
|---|
| 78 | thenNat expr cont |
|---|
| 79 | = NatM $ \st -> case unNat expr st of |
|---|
| 80 | (result, st') -> unNat (cont result) st' |
|---|
| 81 | |
|---|
| 82 | returnNat :: a -> NatM a |
|---|
| 83 | returnNat result |
|---|
| 84 | = NatM $ \st -> (result, st) |
|---|
| 85 | |
|---|
| 86 | mapAccumLNat :: (acc -> x -> NatM (acc, y)) |
|---|
| 87 | -> acc |
|---|
| 88 | -> [x] |
|---|
| 89 | -> NatM (acc, [y]) |
|---|
| 90 | |
|---|
| 91 | mapAccumLNat _ b [] |
|---|
| 92 | = return (b, []) |
|---|
| 93 | mapAccumLNat f b (x:xs) |
|---|
| 94 | = do (b__2, x__2) <- f b x |
|---|
| 95 | (b__3, xs__2) <- mapAccumLNat f b__2 xs |
|---|
| 96 | return (b__3, x__2:xs__2) |
|---|
| 97 | |
|---|
| 98 | getUniqueNat :: NatM Unique |
|---|
| 99 | getUniqueNat = NatM $ \ (NatM_State us delta imports pic dflags) -> |
|---|
| 100 | case takeUniqFromSupply us of |
|---|
| 101 | (uniq, us') -> (uniq, (NatM_State us' delta imports pic dflags)) |
|---|
| 102 | |
|---|
| 103 | instance HasDynFlags NatM where |
|---|
| 104 | getDynFlags = NatM $ \ (NatM_State us delta imports pic dflags) -> |
|---|
| 105 | (dflags, (NatM_State us delta imports pic dflags)) |
|---|
| 106 | |
|---|
| 107 | |
|---|
| 108 | getDeltaNat :: NatM Int |
|---|
| 109 | getDeltaNat |
|---|
| 110 | = NatM $ \ st -> (natm_delta st, st) |
|---|
| 111 | |
|---|
| 112 | |
|---|
| 113 | setDeltaNat :: Int -> NatM () |
|---|
| 114 | setDeltaNat delta |
|---|
| 115 | = NatM $ \ (NatM_State us _ imports pic dflags) -> |
|---|
| 116 | ((), NatM_State us delta imports pic dflags) |
|---|
| 117 | |
|---|
| 118 | |
|---|
| 119 | addImportNat :: CLabel -> NatM () |
|---|
| 120 | addImportNat imp |
|---|
| 121 | = NatM $ \ (NatM_State us delta imports pic dflags) -> |
|---|
| 122 | ((), NatM_State us delta (imp:imports) pic dflags) |
|---|
| 123 | |
|---|
| 124 | |
|---|
| 125 | getBlockIdNat :: NatM BlockId |
|---|
| 126 | getBlockIdNat |
|---|
| 127 | = do u <- getUniqueNat |
|---|
| 128 | return (mkBlockId u) |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | getNewLabelNat :: NatM CLabel |
|---|
| 132 | getNewLabelNat |
|---|
| 133 | = do u <- getUniqueNat |
|---|
| 134 | return (mkAsmTempLabel u) |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | getNewRegNat :: Size -> NatM Reg |
|---|
| 138 | getNewRegNat rep |
|---|
| 139 | = do u <- getUniqueNat |
|---|
| 140 | dflags <- getDynFlags |
|---|
| 141 | return (RegVirtual $ targetMkVirtualReg (targetPlatform dflags) u rep) |
|---|
| 142 | |
|---|
| 143 | |
|---|
| 144 | getNewRegPairNat :: Size -> NatM (Reg,Reg) |
|---|
| 145 | getNewRegPairNat rep |
|---|
| 146 | = do u <- getUniqueNat |
|---|
| 147 | dflags <- getDynFlags |
|---|
| 148 | let vLo = targetMkVirtualReg (targetPlatform dflags) u rep |
|---|
| 149 | let lo = RegVirtual $ targetMkVirtualReg (targetPlatform dflags) u rep |
|---|
| 150 | let hi = RegVirtual $ getHiVirtualRegFromLo vLo |
|---|
| 151 | return (lo, hi) |
|---|
| 152 | |
|---|
| 153 | |
|---|
| 154 | getPicBaseMaybeNat :: NatM (Maybe Reg) |
|---|
| 155 | getPicBaseMaybeNat |
|---|
| 156 | = NatM (\state -> (natm_pic state, state)) |
|---|
| 157 | |
|---|
| 158 | |
|---|
| 159 | getPicBaseNat :: Size -> NatM Reg |
|---|
| 160 | getPicBaseNat rep |
|---|
| 161 | = do mbPicBase <- getPicBaseMaybeNat |
|---|
| 162 | case mbPicBase of |
|---|
| 163 | Just picBase -> return picBase |
|---|
| 164 | Nothing |
|---|
| 165 | -> do |
|---|
| 166 | reg <- getNewRegNat rep |
|---|
| 167 | NatM (\state -> (reg, state { natm_pic = Just reg })) |
|---|