adding new files to do with new cmm functionality
[ghc-hetmet.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, Kind(..)
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 Kind = KindPtr | KindNonPtr deriving (Eq)
83
84 data LocalReg
85   = LocalReg
86       !Unique   -- ^ Identifier
87       MachRep   -- ^ Type
88       Kind      -- ^ 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 -> Kind
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
210 #ifdef DEBUG
211         , Show
212 #endif
213          )
214
215 -- convenient aliases
216 spReg, hpReg, spLimReg, nodeReg :: CmmReg
217 spReg = CmmGlobal Sp
218 hpReg = CmmGlobal Hp
219 spLimReg = CmmGlobal SpLim
220 nodeReg = CmmGlobal node
221
222 node :: GlobalReg
223 node = VanillaReg 1
224
225 globalRegRep :: GlobalReg -> MachRep
226 globalRegRep (VanillaReg _)     = wordRep
227 globalRegRep (FloatReg _)       = F32
228 globalRegRep (DoubleReg _)      = F64
229 globalRegRep (LongReg _)        = I64
230 globalRegRep _                  = wordRep