a good deal of salutory renaming
[ghc.git] / compiler / cmm / CmmExpr.hs
1 {-# OPTIONS -Wall -fno-warn-name-shadowing #-}
2
3 module CmmExpr
4 ( CmmExpr(..), cmmExprRep, maybeInvertCmmExpr
5 , CmmReg(..), cmmRegRep
6 , CmmLit(..), cmmLitRep
7 , LocalReg(..), localRegRep, localRegGCFollow, GCKind(..)
8 , GlobalReg(..), globalRegRep, spReg, hpReg, spLimReg, nodeReg, node
9 , UserOfLocalRegs, foldRegsUsed
10 , RegSet, emptyRegSet, elemRegSet, extendRegSet, deleteFromRegSet, mkRegSet
11 , plusRegSet, minusRegSet
12 )
13 where
14
15 import CLabel
16 import MachOp
17 import Unique
18 import UniqSet
19
20 -----------------------------------------------------------------------------
21 -- CmmExpr
22 -- An expression. Expressions have no side effects.
23 -----------------------------------------------------------------------------
24
25 data CmmExpr
26 = CmmLit CmmLit -- Literal
27 | CmmLoad CmmExpr MachRep -- Read memory location
28 | CmmReg CmmReg -- Contents of register
29 | CmmMachOp MachOp [CmmExpr] -- Machine operation (+, -, *, etc.)
30 | CmmRegOff CmmReg Int
31 -- CmmRegOff reg i
32 -- ** is shorthand only, meaning **
33 -- CmmMachOp (MO_S_Add rep (CmmReg reg) (CmmLit (CmmInt i rep)))
34 -- where rep = cmmRegRep reg
35 deriving Eq
36
37 data CmmReg
38 = CmmLocal LocalReg
39 | CmmGlobal GlobalReg
40 deriving( Eq )
41
42 data CmmLit
43 = CmmInt Integer MachRep
44 -- Interpretation: the 2's complement representation of the value
45 -- is truncated to the specified size. This is easier than trying
46 -- to keep the value within range, because we don't know whether
47 -- it will be used as a signed or unsigned value (the MachRep doesn't
48 -- distinguish between signed & unsigned).
49 | CmmFloat Rational MachRep
50 | CmmLabel CLabel -- Address of label
51 | CmmLabelOff CLabel Int -- Address of label + byte offset
52
53 -- Due to limitations in the C backend, the following
54 -- MUST ONLY be used inside the info table indicated by label2
55 -- (label2 must be the info label), and label1 must be an
56 -- SRT, a slow entrypoint or a large bitmap (see the Mangler)
57 -- Don't use it at all unless tablesNextToCode.
58 -- It is also used inside the NCG during when generating
59 -- position-independent code.
60 | CmmLabelDiffOff CLabel CLabel Int -- label1 - label2 + offset
61 deriving Eq
62
63 instance Eq LocalReg where
64 (LocalReg u1 _ _) == (LocalReg u2 _ _) = u1 == u2
65
66 instance Uniquable LocalReg where
67 getUnique (LocalReg uniq _ _) = uniq
68
69 --------
70 --- Negation for conditional branches
71
72 maybeInvertCmmExpr :: CmmExpr -> Maybe CmmExpr
73 maybeInvertCmmExpr (CmmMachOp op args) = do op' <- maybeInvertComparison op
74 return (CmmMachOp op' args)
75 maybeInvertCmmExpr _ = Nothing
76
77 -----------------------------------------------------------------------------
78 -- Local registers
79 -----------------------------------------------------------------------------
80
81 -- | Whether a 'LocalReg' is a GC followable pointer
82 data GCKind = GCKindPtr | GCKindNonPtr deriving (Eq)
83
84 data LocalReg
85 = LocalReg
86 !Unique -- ^ Identifier
87 MachRep -- ^ Type
88 GCKind -- ^ Should the GC follow as a pointer
89
90 -- | Sets of local registers
91
92 type RegSet = UniqSet LocalReg
93 emptyRegSet :: RegSet
94 elemRegSet :: LocalReg -> RegSet -> Bool
95 extendRegSet :: RegSet -> LocalReg -> RegSet
96 deleteFromRegSet :: RegSet -> LocalReg -> RegSet
97 mkRegSet :: [LocalReg] -> RegSet
98 minusRegSet, plusRegSet :: RegSet -> RegSet -> RegSet
99
100 emptyRegSet = emptyUniqSet
101 elemRegSet = elementOfUniqSet
102 extendRegSet = addOneToUniqSet
103 deleteFromRegSet = delOneFromUniqSet
104 mkRegSet = mkUniqSet
105 minusRegSet = minusUniqSet
106 plusRegSet = unionUniqSets
107
108 -----------------------------------------------------------------------------
109 -- Register-use information for expressions and other types
110 -----------------------------------------------------------------------------
111
112 class UserOfLocalRegs a where
113 foldRegsUsed :: (b -> LocalReg -> b) -> b -> a -> b
114
115 instance UserOfLocalRegs CmmReg where
116 foldRegsUsed f z (CmmLocal reg) = f z reg
117 foldRegsUsed _ z (CmmGlobal _) = z
118
119 instance UserOfLocalRegs LocalReg where
120 foldRegsUsed f z r = f z r
121
122 instance UserOfLocalRegs CmmExpr where
123 foldRegsUsed f z e = expr z e
124 where expr z (CmmLit _) = z
125 expr z (CmmLoad addr _) = foldRegsUsed f z addr
126 expr z (CmmReg r) = foldRegsUsed f z r
127 expr z (CmmMachOp _ exprs) = foldRegsUsed f z exprs
128 expr z (CmmRegOff r _) = foldRegsUsed f z r
129
130 instance UserOfLocalRegs a => UserOfLocalRegs [a] where
131 foldRegsUsed _ set [] = set
132 foldRegsUsed f set (x:xs) = foldRegsUsed f (foldRegsUsed f set x) xs
133
134 -----------------------------------------------------------------------------
135 -- MachRep
136 -----------------------------------------------------------------------------
137
138
139
140 cmmExprRep :: CmmExpr -> MachRep
141 cmmExprRep (CmmLit lit) = cmmLitRep lit
142 cmmExprRep (CmmLoad _ rep) = rep
143 cmmExprRep (CmmReg reg) = cmmRegRep reg
144 cmmExprRep (CmmMachOp op _) = resultRepOfMachOp op
145 cmmExprRep (CmmRegOff reg _) = cmmRegRep reg
146
147 cmmRegRep :: CmmReg -> MachRep
148 cmmRegRep (CmmLocal reg) = localRegRep reg
149 cmmRegRep (CmmGlobal reg) = globalRegRep reg
150
151 localRegRep :: LocalReg -> MachRep
152 localRegRep (LocalReg _ rep _) = rep
153
154
155 localRegGCFollow :: LocalReg -> GCKind
156 localRegGCFollow (LocalReg _ _ p) = p
157
158 cmmLitRep :: CmmLit -> MachRep
159 cmmLitRep (CmmInt _ rep) = rep
160 cmmLitRep (CmmFloat _ rep) = rep
161 cmmLitRep (CmmLabel _) = wordRep
162 cmmLitRep (CmmLabelOff _ _) = wordRep
163 cmmLitRep (CmmLabelDiffOff _ _ _) = wordRep
164
165 -----------------------------------------------------------------------------
166 -- Global STG registers
167 -----------------------------------------------------------------------------
168
169 data GlobalReg
170 -- Argument and return registers
171 = VanillaReg -- pointers, unboxed ints and chars
172 {-# UNPACK #-} !Int -- its number
173
174 | FloatReg -- single-precision floating-point registers
175 {-# UNPACK #-} !Int -- its number
176
177 | DoubleReg -- double-precision floating-point registers
178 {-# UNPACK #-} !Int -- its number
179
180 | LongReg -- long int registers (64-bit, really)
181 {-# UNPACK #-} !Int -- its number
182
183 -- STG registers
184 | Sp -- Stack ptr; points to last occupied stack location.
185 | SpLim -- Stack limit
186 | Hp -- Heap ptr; points to last occupied heap location.
187 | HpLim -- Heap limit register
188 | CurrentTSO -- pointer to current thread's TSO
189 | CurrentNursery -- pointer to allocation area
190 | HpAlloc -- allocation count for heap check failure
191
192 -- We keep the address of some commonly-called
193 -- functions in the register table, to keep code
194 -- size down:
195 | GCEnter1 -- stg_gc_enter_1
196 | GCFun -- stg_gc_fun
197
198 -- Base offset for the register table, used for accessing registers
199 -- which do not have real registers assigned to them. This register
200 -- will only appear after we have expanded GlobalReg into memory accesses
201 -- (where necessary) in the native code generator.
202 | BaseReg
203
204 -- Base Register for PIC (position-independent code) calculations
205 -- Only used inside the native code generator. It's exact meaning differs
206 -- from platform to platform (see module PositionIndependentCode).
207 | PicBaseReg
208
209 deriving( Eq , Show )
210
211 -- convenient aliases
212 spReg, hpReg, spLimReg, nodeReg :: CmmReg
213 spReg = CmmGlobal Sp
214 hpReg = CmmGlobal Hp
215 spLimReg = CmmGlobal SpLim
216 nodeReg = CmmGlobal node
217
218 node :: GlobalReg
219 node = VanillaReg 1
220
221 globalRegRep :: GlobalReg -> MachRep
222 globalRegRep (VanillaReg _) = wordRep
223 globalRegRep (FloatReg _) = F32
224 globalRegRep (DoubleReg _) = F64
225 globalRegRep (LongReg _) = I64
226 globalRegRep _ = wordRep