summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/NCGMonad.hs
blob: 71250a245228606345095a06f01d2bd6eb2de422 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
-- -----------------------------------------------------------------------------
--
-- (c) The University of Glasgow 1993-2004
-- 
-- The native code generator's monad.
--
-- -----------------------------------------------------------------------------

{-# OPTIONS -fno-warn-tabs #-}
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and
-- detab the module (please do the detabbing in a separate patch). See
--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
-- for details

module NCGMonad (
	NatM_State(..), mkNatM_State,

	NatM, -- instance Monad
	initNat, 
	addImportNat, 
	getUniqueNat,
	mapAccumLNat, 
	setDeltaNat, 
	getDeltaNat,
	getBlockIdNat, 
	getNewLabelNat, 
	getNewRegNat, 
	getNewRegPairNat,
	getPicBaseMaybeNat, 
	getPicBaseNat, 
	getDynFlagsNat
) 
 
where
  
#include "HsVersions.h"

import Reg
import Size
import TargetReg

import BlockId
import CLabel		( CLabel, mkAsmTempLabel )
import UniqSupply
import Unique		( Unique )
import DynFlags

data NatM_State 
	= NatM_State {
		natm_us      :: UniqSupply,
		natm_delta   :: Int,
		natm_imports :: [(CLabel)],
		natm_pic     :: Maybe Reg,
		natm_dflags  :: DynFlags
	}

newtype NatM result = NatM (NatM_State -> (result, NatM_State))

unNat :: NatM a -> NatM_State -> (a, NatM_State)
unNat (NatM a) = a

mkNatM_State :: UniqSupply -> Int -> DynFlags -> NatM_State
mkNatM_State us delta dflags 
	= NatM_State us delta [] Nothing dflags

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 _ 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 dflags) ->
    case takeUniqFromSupply us of
         (uniq, us') -> (uniq, (NatM_State us' delta imports pic dflags))


getDynFlagsNat :: NatM DynFlags
getDynFlagsNat 
	= NatM $ \ (NatM_State us delta imports pic dflags) ->
	          (dflags, (NatM_State us delta imports pic dflags))


getDeltaNat :: NatM Int
getDeltaNat 
	= NatM $ \ st -> (natm_delta st, st)


setDeltaNat :: Int -> NatM ()
setDeltaNat delta 
	= NatM $ \ (NatM_State us _ imports pic dflags) ->
		   ((), NatM_State us delta imports pic dflags)


addImportNat :: CLabel -> NatM ()
addImportNat imp 
	= NatM $ \ (NatM_State us delta imports pic dflags) ->
		   ((), NatM_State us delta (imp:imports) pic dflags)


getBlockIdNat :: NatM BlockId
getBlockIdNat 
 = do	u <- getUniqueNat
 	return (mkBlockId u)


getNewLabelNat :: NatM CLabel
getNewLabelNat 
 = do 	u <- getUniqueNat
 	return (mkAsmTempLabel u)


getNewRegNat :: Size -> NatM Reg
getNewRegNat rep
 = do u <- getUniqueNat
      dflags <- getDynFlagsNat
      return (RegVirtual $ targetMkVirtualReg (targetPlatform dflags) u rep)


getNewRegPairNat :: Size -> NatM (Reg,Reg)
getNewRegPairNat rep
 = do u <- getUniqueNat
      dflags <- getDynFlagsNat
      let vLo = targetMkVirtualReg (targetPlatform dflags) u rep
      let lo  = RegVirtual $ targetMkVirtualReg (targetPlatform dflags) u rep
      let hi  = RegVirtual $ getHiVirtualRegFromLo vLo
      return (lo, hi)


getPicBaseMaybeNat :: NatM (Maybe Reg)
getPicBaseMaybeNat 
	= NatM (\state -> (natm_pic state, state))


getPicBaseNat :: Size -> 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 }))