CmmExpr: remove unused `vgcFlag` function
[ghc.git] / compiler / cmm / CmmExpr.hs
1 {-# LANGUAGE CPP #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE MultiParamTypeClasses #-}
5 {-# LANGUAGE UndecidableInstances #-}
6
7 module CmmExpr
8 ( CmmExpr(..), cmmExprType, cmmExprWidth, maybeInvertCmmExpr
9 , CmmReg(..), cmmRegType
10 , CmmLit(..), cmmLitType
11 , LocalReg(..), localRegType
12 , GlobalReg(..), isArgReg, globalRegType, spReg, hpReg, spLimReg, nodeReg, node, baseReg
13 , VGcPtr(..)
14
15 , DefinerOfRegs, UserOfRegs
16 , foldRegsDefd, foldRegsUsed, filterRegsUsed
17 , foldLocalRegsDefd, foldLocalRegsUsed
18
19 , RegSet, LocalRegSet, GlobalRegSet
20 , emptyRegSet, elemRegSet, extendRegSet, deleteFromRegSet, mkRegSet
21 , plusRegSet, minusRegSet, timesRegSet, sizeRegSet, nullRegSet
22 , regSetToList
23
24 , Area(..)
25 , module CmmMachOp
26 , module CmmType
27 )
28 where
29
30 #include "HsVersions.h"
31
32 import CmmType
33 import CmmMachOp
34 import BlockId
35 import CLabel
36 import DynFlags
37 import Unique
38 import Outputable (panic)
39
40 import Data.Set (Set)
41 import qualified Data.Set as Set
42
43 -----------------------------------------------------------------------------
44 -- CmmExpr
45 -- An expression. Expressions have no side effects.
46 -----------------------------------------------------------------------------
47
48 data CmmExpr
49 = CmmLit CmmLit -- Literal
50 | CmmLoad !CmmExpr !CmmType -- Read memory location
51 | CmmReg !CmmReg -- Contents of register
52 | CmmMachOp MachOp [CmmExpr] -- Machine operation (+, -, *, etc.)
53 | CmmStackSlot Area {-# UNPACK #-} !Int
54 -- addressing expression of a stack slot
55 -- See Note [CmmStackSlot aliasing]
56 | CmmRegOff !CmmReg Int
57 -- CmmRegOff reg i
58 -- ** is shorthand only, meaning **
59 -- CmmMachOp (MO_Add rep) [x, CmmLit (CmmInt (fromIntegral i) rep)]
60 -- where rep = typeWidth (cmmRegType reg)
61
62 instance Eq CmmExpr where -- Equality ignores the types
63 CmmLit l1 == CmmLit l2 = l1==l2
64 CmmLoad e1 _ == CmmLoad e2 _ = e1==e2
65 CmmReg r1 == CmmReg r2 = r1==r2
66 CmmRegOff r1 i1 == CmmRegOff r2 i2 = r1==r2 && i1==i2
67 CmmMachOp op1 es1 == CmmMachOp op2 es2 = op1==op2 && es1==es2
68 CmmStackSlot a1 i1 == CmmStackSlot a2 i2 = a1==a2 && i1==i2
69 _e1 == _e2 = False
70
71 data CmmReg
72 = CmmLocal {-# UNPACK #-} !LocalReg
73 | CmmGlobal GlobalReg
74 deriving( Eq, Ord )
75
76 -- | A stack area is either the stack slot where a variable is spilled
77 -- or the stack space where function arguments and results are passed.
78 data Area
79 = Old -- See Note [Old Area]
80 | Young {-# UNPACK #-} !BlockId -- Invariant: must be a continuation BlockId
81 -- See Note [Continuation BlockId] in CmmNode.
82 deriving (Eq, Ord)
83
84 {- Note [Old Area]
85 ~~~~~~~~~~~~~~~~~~
86 There is a single call area 'Old', allocated at the extreme old
87 end of the stack frame (ie just younger than the return address)
88 which holds:
89 * incoming (overflow) parameters,
90 * outgoing (overflow) parameter to tail calls,
91 * outgoing (overflow) result values
92 * the update frame (if any)
93
94 Its size is the max of all these requirements. On entry, the stack
95 pointer will point to the youngest incoming parameter, which is not
96 necessarily at the young end of the Old area.
97
98 End of note -}
99
100
101 {- Note [CmmStackSlot aliasing]
102 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103 When do two CmmStackSlots alias?
104
105 - T[old+N] aliases with U[young(L)+M] for all T, U, L, N and M
106 - T[old+N] aliases with U[old+M] only if the areas actually overlap
107
108 Or more informally, different Areas may overlap with each other.
109
110 An alternative semantics, that we previously had, was that different
111 Areas do not overlap. The problem that lead to redefining the
112 semantics of stack areas is described below.
113
114 e.g. if we had
115
116 x = Sp[old + 8]
117 y = Sp[old + 16]
118
119 Sp[young(L) + 8] = L
120 Sp[young(L) + 16] = y
121 Sp[young(L) + 24] = x
122 call f() returns to L
123
124 if areas semantically do not overlap, then we might optimise this to
125
126 Sp[young(L) + 8] = L
127 Sp[young(L) + 16] = Sp[old + 8]
128 Sp[young(L) + 24] = Sp[old + 16]
129 call f() returns to L
130
131 and now young(L) cannot be allocated at the same place as old, and we
132 are doomed to use more stack.
133
134 - old+8 conflicts with young(L)+8
135 - old+16 conflicts with young(L)+16 and young(L)+8
136
137 so young(L)+8 == old+24 and we get
138
139 Sp[-8] = L
140 Sp[-16] = Sp[8]
141 Sp[-24] = Sp[0]
142 Sp -= 24
143 call f() returns to L
144
145 However, if areas are defined to be "possibly overlapping" in the
146 semantics, then we cannot commute any loads/stores of old with
147 young(L), and we will be able to re-use both old+8 and old+16 for
148 young(L).
149
150 x = Sp[8]
151 y = Sp[0]
152
153 Sp[8] = L
154 Sp[0] = y
155 Sp[-8] = x
156 Sp = Sp - 8
157 call f() returns to L
158
159 Now, the assignments of y go away,
160
161 x = Sp[8]
162 Sp[8] = L
163 Sp[-8] = x
164 Sp = Sp - 8
165 call f() returns to L
166 -}
167
168 data CmmLit
169 = CmmInt !Integer Width
170 -- Interpretation: the 2's complement representation of the value
171 -- is truncated to the specified size. This is easier than trying
172 -- to keep the value within range, because we don't know whether
173 -- it will be used as a signed or unsigned value (the CmmType doesn't
174 -- distinguish between signed & unsigned).
175 | CmmFloat Rational Width
176 | CmmVec [CmmLit] -- Vector literal
177 | CmmLabel CLabel -- Address of label
178 | CmmLabelOff CLabel Int -- Address of label + byte offset
179
180 -- Due to limitations in the C backend, the following
181 -- MUST ONLY be used inside the info table indicated by label2
182 -- (label2 must be the info label), and label1 must be an
183 -- SRT, a slow entrypoint or a large bitmap (see the Mangler)
184 -- Don't use it at all unless tablesNextToCode.
185 -- It is also used inside the NCG during when generating
186 -- position-independent code.
187 | CmmLabelDiffOff CLabel CLabel Int -- label1 - label2 + offset
188
189 | CmmBlock {-# UNPACK #-} !BlockId -- Code label
190 -- Invariant: must be a continuation BlockId
191 -- See Note [Continuation BlockId] in CmmNode.
192
193 | CmmHighStackMark -- A late-bound constant that stands for the max
194 -- #bytes of stack space used during a procedure.
195 -- During the stack-layout pass, CmmHighStackMark
196 -- is replaced by a CmmInt for the actual number
197 -- of bytes used
198 deriving Eq
199
200 cmmExprType :: DynFlags -> CmmExpr -> CmmType
201 cmmExprType dflags (CmmLit lit) = cmmLitType dflags lit
202 cmmExprType _ (CmmLoad _ rep) = rep
203 cmmExprType dflags (CmmReg reg) = cmmRegType dflags reg
204 cmmExprType dflags (CmmMachOp op args) = machOpResultType dflags op (map (cmmExprType dflags) args)
205 cmmExprType dflags (CmmRegOff reg _) = cmmRegType dflags reg
206 cmmExprType dflags (CmmStackSlot _ _) = bWord dflags -- an address
207 -- Careful though: what is stored at the stack slot may be bigger than
208 -- an address
209
210 cmmLitType :: DynFlags -> CmmLit -> CmmType
211 cmmLitType _ (CmmInt _ width) = cmmBits width
212 cmmLitType _ (CmmFloat _ width) = cmmFloat width
213 cmmLitType _ (CmmVec []) = panic "cmmLitType: CmmVec []"
214 cmmLitType cflags (CmmVec (l:ls)) = let ty = cmmLitType cflags l
215 in if all (`cmmEqType` ty) (map (cmmLitType cflags) ls)
216 then cmmVec (1+length ls) ty
217 else panic "cmmLitType: CmmVec"
218 cmmLitType dflags (CmmLabel lbl) = cmmLabelType dflags lbl
219 cmmLitType dflags (CmmLabelOff lbl _) = cmmLabelType dflags lbl
220 cmmLitType dflags (CmmLabelDiffOff {}) = bWord dflags
221 cmmLitType dflags (CmmBlock _) = bWord dflags
222 cmmLitType dflags (CmmHighStackMark) = bWord dflags
223
224 cmmLabelType :: DynFlags -> CLabel -> CmmType
225 cmmLabelType dflags lbl
226 | isGcPtrLabel lbl = gcWord dflags
227 | otherwise = bWord dflags
228
229 cmmExprWidth :: DynFlags -> CmmExpr -> Width
230 cmmExprWidth dflags e = typeWidth (cmmExprType dflags e)
231
232 --------
233 --- Negation for conditional branches
234
235 maybeInvertCmmExpr :: CmmExpr -> Maybe CmmExpr
236 maybeInvertCmmExpr (CmmMachOp op args) = do op' <- maybeInvertComparison op
237 return (CmmMachOp op' args)
238 maybeInvertCmmExpr _ = Nothing
239
240 -----------------------------------------------------------------------------
241 -- Local registers
242 -----------------------------------------------------------------------------
243
244 data LocalReg
245 = LocalReg {-# UNPACK #-} !Unique CmmType
246 -- ^ Parameters:
247 -- 1. Identifier
248 -- 2. Type
249
250 instance Eq LocalReg where
251 (LocalReg u1 _) == (LocalReg u2 _) = u1 == u2
252
253 -- This is non-deterministic but we do not currently support deterministic
254 -- code-generation. See Note [Unique Determinism and code generation]
255 -- See Note [No Ord for Unique]
256 instance Ord LocalReg where
257 compare (LocalReg u1 _) (LocalReg u2 _) = nonDetCmpUnique u1 u2
258
259 instance Uniquable LocalReg where
260 getUnique (LocalReg uniq _) = uniq
261
262 cmmRegType :: DynFlags -> CmmReg -> CmmType
263 cmmRegType _ (CmmLocal reg) = localRegType reg
264 cmmRegType dflags (CmmGlobal reg) = globalRegType dflags reg
265
266 localRegType :: LocalReg -> CmmType
267 localRegType (LocalReg _ rep) = rep
268
269 -----------------------------------------------------------------------------
270 -- Register-use information for expressions and other types
271 -----------------------------------------------------------------------------
272
273 -- | Sets of registers
274
275 -- These are used for dataflow facts, and a common operation is taking
276 -- the union of two RegSets and then asking whether the union is the
277 -- same as one of the inputs. UniqSet isn't good here, because
278 -- sizeUniqSet is O(n) whereas Set.size is O(1), so we use ordinary
279 -- Sets.
280
281 type RegSet r = Set r
282 type LocalRegSet = RegSet LocalReg
283 type GlobalRegSet = RegSet GlobalReg
284
285 emptyRegSet :: RegSet r
286 nullRegSet :: RegSet r -> Bool
287 elemRegSet :: Ord r => r -> RegSet r -> Bool
288 extendRegSet :: Ord r => RegSet r -> r -> RegSet r
289 deleteFromRegSet :: Ord r => RegSet r -> r -> RegSet r
290 mkRegSet :: Ord r => [r] -> RegSet r
291 minusRegSet, plusRegSet, timesRegSet :: Ord r => RegSet r -> RegSet r -> RegSet r
292 sizeRegSet :: RegSet r -> Int
293 regSetToList :: RegSet r -> [r]
294
295 emptyRegSet = Set.empty
296 nullRegSet = Set.null
297 elemRegSet = Set.member
298 extendRegSet = flip Set.insert
299 deleteFromRegSet = flip Set.delete
300 mkRegSet = Set.fromList
301 minusRegSet = Set.difference
302 plusRegSet = Set.union
303 timesRegSet = Set.intersection
304 sizeRegSet = Set.size
305 regSetToList = Set.toList
306
307 class Ord r => UserOfRegs r a where
308 foldRegsUsed :: DynFlags -> (b -> r -> b) -> b -> a -> b
309
310 foldLocalRegsUsed :: UserOfRegs LocalReg a
311 => DynFlags -> (b -> LocalReg -> b) -> b -> a -> b
312 foldLocalRegsUsed = foldRegsUsed
313
314 class Ord r => DefinerOfRegs r a where
315 foldRegsDefd :: DynFlags -> (b -> r -> b) -> b -> a -> b
316
317 foldLocalRegsDefd :: DefinerOfRegs LocalReg a
318 => DynFlags -> (b -> LocalReg -> b) -> b -> a -> b
319 foldLocalRegsDefd = foldRegsDefd
320
321 filterRegsUsed :: UserOfRegs r e => DynFlags -> (r -> Bool) -> e -> RegSet r
322 filterRegsUsed dflags p e =
323 foldRegsUsed dflags
324 (\regs r -> if p r then extendRegSet regs r else regs)
325 emptyRegSet e
326
327 instance UserOfRegs LocalReg CmmReg where
328 foldRegsUsed _ f z (CmmLocal reg) = f z reg
329 foldRegsUsed _ _ z (CmmGlobal _) = z
330
331 instance DefinerOfRegs LocalReg CmmReg where
332 foldRegsDefd _ f z (CmmLocal reg) = f z reg
333 foldRegsDefd _ _ z (CmmGlobal _) = z
334
335 instance UserOfRegs GlobalReg CmmReg where
336 foldRegsUsed _ _ z (CmmLocal _) = z
337 foldRegsUsed _ f z (CmmGlobal reg) = f z reg
338
339 instance DefinerOfRegs GlobalReg CmmReg where
340 foldRegsDefd _ _ z (CmmLocal _) = z
341 foldRegsDefd _ f z (CmmGlobal reg) = f z reg
342
343 instance Ord r => UserOfRegs r r where
344 foldRegsUsed _ f z r = f z r
345
346 instance Ord r => DefinerOfRegs r r where
347 foldRegsDefd _ f z r = f z r
348
349 instance Ord r => UserOfRegs r (RegSet r) where
350 foldRegsUsed _ f = Set.fold (flip f)
351
352 instance (Ord r, UserOfRegs r CmmReg) => UserOfRegs r CmmExpr where
353 -- The (Ord r) in the context is necessary here
354 -- See Note [Recursive superclasses] in TcInstDcls
355 foldRegsUsed dflags f z e = expr z e
356 where expr z (CmmLit _) = z
357 expr z (CmmLoad addr _) = foldRegsUsed dflags f z addr
358 expr z (CmmReg r) = foldRegsUsed dflags f z r
359 expr z (CmmMachOp _ exprs) = foldRegsUsed dflags f z exprs
360 expr z (CmmRegOff r _) = foldRegsUsed dflags f z r
361 expr z (CmmStackSlot _ _) = z
362
363 instance UserOfRegs r a => UserOfRegs r (Maybe a) where
364 foldRegsUsed dflags f z (Just x) = foldRegsUsed dflags f z x
365 foldRegsUsed _ _ z Nothing = z
366
367 instance UserOfRegs r a => UserOfRegs r [a] where
368 foldRegsUsed _ _ set [] = set
369 foldRegsUsed dflags f set (x:xs) = foldRegsUsed dflags f (foldRegsUsed dflags f set x) xs
370
371 instance DefinerOfRegs r a => DefinerOfRegs r [a] where
372 foldRegsDefd _ _ set [] = set
373 foldRegsDefd dflags f set (x:xs) = foldRegsDefd dflags f (foldRegsDefd dflags f set x) xs
374
375 instance DefinerOfRegs r a => DefinerOfRegs r (Maybe a) where
376 foldRegsDefd _ _ set Nothing = set
377 foldRegsDefd dflags f set (Just x) = foldRegsDefd dflags f set x
378
379 -----------------------------------------------------------------------------
380 -- Global STG registers
381 -----------------------------------------------------------------------------
382
383 data VGcPtr = VGcPtr | VNonGcPtr deriving( Eq, Show )
384
385 -----------------------------------------------------------------------------
386 -- Global STG registers
387 -----------------------------------------------------------------------------
388 {-
389 Note [Overlapping global registers]
390
391 The backend might not faithfully implement the abstraction of the STG
392 machine with independent registers for different values of type
393 GlobalReg. Specifically, certain pairs of registers (r1, r2) may
394 overlap in the sense that a store to r1 invalidates the value in r2,
395 and vice versa.
396
397 Currently this occurs only on the x86_64 architecture where FloatReg n
398 and DoubleReg n are assigned the same microarchitectural register, in
399 order to allow functions to receive more Float# or Double# arguments
400 in registers (as opposed to on the stack).
401
402 There are no specific rules about which registers might overlap with
403 which other registers, but presumably it's safe to assume that nothing
404 will overlap with special registers like Sp or BaseReg.
405
406 Use CmmUtils.regsOverlap to determine whether two GlobalRegs overlap
407 on a particular platform. The instance Eq GlobalReg is syntactic
408 equality of STG registers and does not take overlap into
409 account. However it is still used in UserOfRegs/DefinerOfRegs and
410 there are likely still bugs there, beware!
411 -}
412
413 data GlobalReg
414 -- Argument and return registers
415 = VanillaReg -- pointers, unboxed ints and chars
416 {-# UNPACK #-} !Int -- its number
417 VGcPtr
418
419 | FloatReg -- single-precision floating-point registers
420 {-# UNPACK #-} !Int -- its number
421
422 | DoubleReg -- double-precision floating-point registers
423 {-# UNPACK #-} !Int -- its number
424
425 | LongReg -- long int registers (64-bit, really)
426 {-# UNPACK #-} !Int -- its number
427
428 | XmmReg -- 128-bit SIMD vector register
429 {-# UNPACK #-} !Int -- its number
430
431 | YmmReg -- 256-bit SIMD vector register
432 {-# UNPACK #-} !Int -- its number
433
434 | ZmmReg -- 512-bit SIMD vector register
435 {-# UNPACK #-} !Int -- its number
436
437 -- STG registers
438 | Sp -- Stack ptr; points to last occupied stack location.
439 | SpLim -- Stack limit
440 | Hp -- Heap ptr; points to last occupied heap location.
441 | HpLim -- Heap limit register
442 | CCCS -- Current cost-centre stack
443 | CurrentTSO -- pointer to current thread's TSO
444 | CurrentNursery -- pointer to allocation area
445 | HpAlloc -- allocation count for heap check failure
446
447 -- We keep the address of some commonly-called
448 -- functions in the register table, to keep code
449 -- size down:
450 | EagerBlackholeInfo -- stg_EAGER_BLACKHOLE_info
451 | GCEnter1 -- stg_gc_enter_1
452 | GCFun -- stg_gc_fun
453
454 -- Base offset for the register table, used for accessing registers
455 -- which do not have real registers assigned to them. This register
456 -- will only appear after we have expanded GlobalReg into memory accesses
457 -- (where necessary) in the native code generator.
458 | BaseReg
459
460 -- The register used by the platform for the C stack pointer. This is
461 -- a break in the STG abstraction used exclusively to setup stack unwinding
462 -- information.
463 | MachSp
464
465 -- The is a dummy register used to indicate to the stack unwinder where
466 -- a routine would return to.
467 | UnwindReturnReg
468
469 -- Base Register for PIC (position-independent code) calculations
470 -- Only used inside the native code generator. It's exact meaning differs
471 -- from platform to platform (see module PositionIndependentCode).
472 | PicBaseReg
473
474 deriving( Show )
475
476 instance Eq GlobalReg where
477 VanillaReg i _ == VanillaReg j _ = i==j -- Ignore type when seeking clashes
478 FloatReg i == FloatReg j = i==j
479 DoubleReg i == DoubleReg j = i==j
480 LongReg i == LongReg j = i==j
481 XmmReg i == XmmReg j = i==j
482 YmmReg i == YmmReg j = i==j
483 ZmmReg i == ZmmReg j = i==j
484 Sp == Sp = True
485 SpLim == SpLim = True
486 Hp == Hp = True
487 HpLim == HpLim = True
488 CCCS == CCCS = True
489 CurrentTSO == CurrentTSO = True
490 CurrentNursery == CurrentNursery = True
491 HpAlloc == HpAlloc = True
492 EagerBlackholeInfo == EagerBlackholeInfo = True
493 GCEnter1 == GCEnter1 = True
494 GCFun == GCFun = True
495 BaseReg == BaseReg = True
496 MachSp == MachSp = True
497 UnwindReturnReg == UnwindReturnReg = True
498 PicBaseReg == PicBaseReg = True
499 _r1 == _r2 = False
500
501 instance Ord GlobalReg where
502 compare (VanillaReg i _) (VanillaReg j _) = compare i j
503 -- Ignore type when seeking clashes
504 compare (FloatReg i) (FloatReg j) = compare i j
505 compare (DoubleReg i) (DoubleReg j) = compare i j
506 compare (LongReg i) (LongReg j) = compare i j
507 compare (XmmReg i) (XmmReg j) = compare i j
508 compare (YmmReg i) (YmmReg j) = compare i j
509 compare (ZmmReg i) (ZmmReg j) = compare i j
510 compare Sp Sp = EQ
511 compare SpLim SpLim = EQ
512 compare Hp Hp = EQ
513 compare HpLim HpLim = EQ
514 compare CCCS CCCS = EQ
515 compare CurrentTSO CurrentTSO = EQ
516 compare CurrentNursery CurrentNursery = EQ
517 compare HpAlloc HpAlloc = EQ
518 compare EagerBlackholeInfo EagerBlackholeInfo = EQ
519 compare GCEnter1 GCEnter1 = EQ
520 compare GCFun GCFun = EQ
521 compare BaseReg BaseReg = EQ
522 compare MachSp MachSp = EQ
523 compare UnwindReturnReg UnwindReturnReg = EQ
524 compare PicBaseReg PicBaseReg = EQ
525 compare (VanillaReg _ _) _ = LT
526 compare _ (VanillaReg _ _) = GT
527 compare (FloatReg _) _ = LT
528 compare _ (FloatReg _) = GT
529 compare (DoubleReg _) _ = LT
530 compare _ (DoubleReg _) = GT
531 compare (LongReg _) _ = LT
532 compare _ (LongReg _) = GT
533 compare (XmmReg _) _ = LT
534 compare _ (XmmReg _) = GT
535 compare (YmmReg _) _ = LT
536 compare _ (YmmReg _) = GT
537 compare (ZmmReg _) _ = LT
538 compare _ (ZmmReg _) = GT
539 compare Sp _ = LT
540 compare _ Sp = GT
541 compare SpLim _ = LT
542 compare _ SpLim = GT
543 compare Hp _ = LT
544 compare _ Hp = GT
545 compare HpLim _ = LT
546 compare _ HpLim = GT
547 compare CCCS _ = LT
548 compare _ CCCS = GT
549 compare CurrentTSO _ = LT
550 compare _ CurrentTSO = GT
551 compare CurrentNursery _ = LT
552 compare _ CurrentNursery = GT
553 compare HpAlloc _ = LT
554 compare _ HpAlloc = GT
555 compare GCEnter1 _ = LT
556 compare _ GCEnter1 = GT
557 compare GCFun _ = LT
558 compare _ GCFun = GT
559 compare BaseReg _ = LT
560 compare _ BaseReg = GT
561 compare MachSp _ = LT
562 compare _ MachSp = GT
563 compare UnwindReturnReg _ = LT
564 compare _ UnwindReturnReg = GT
565 compare EagerBlackholeInfo _ = LT
566 compare _ EagerBlackholeInfo = GT
567
568 -- convenient aliases
569 baseReg, spReg, hpReg, spLimReg, nodeReg :: CmmReg
570 baseReg = CmmGlobal BaseReg
571 spReg = CmmGlobal Sp
572 hpReg = CmmGlobal Hp
573 spLimReg = CmmGlobal SpLim
574 nodeReg = CmmGlobal node
575
576 node :: GlobalReg
577 node = VanillaReg 1 VGcPtr
578
579 globalRegType :: DynFlags -> GlobalReg -> CmmType
580 globalRegType dflags (VanillaReg _ VGcPtr) = gcWord dflags
581 globalRegType dflags (VanillaReg _ VNonGcPtr) = bWord dflags
582 globalRegType _ (FloatReg _) = cmmFloat W32
583 globalRegType _ (DoubleReg _) = cmmFloat W64
584 globalRegType _ (LongReg _) = cmmBits W64
585 globalRegType _ (XmmReg _) = cmmVec 4 (cmmBits W32)
586 globalRegType _ (YmmReg _) = cmmVec 8 (cmmBits W32)
587 globalRegType _ (ZmmReg _) = cmmVec 16 (cmmBits W32)
588
589 globalRegType dflags Hp = gcWord dflags
590 -- The initialiser for all
591 -- dynamically allocated closures
592 globalRegType dflags _ = bWord dflags
593
594 isArgReg :: GlobalReg -> Bool
595 isArgReg (VanillaReg {}) = True
596 isArgReg (FloatReg {}) = True
597 isArgReg (DoubleReg {}) = True
598 isArgReg (LongReg {}) = True
599 isArgReg (XmmReg {}) = True
600 isArgReg (YmmReg {}) = True
601 isArgReg (ZmmReg {}) = True
602 isArgReg _ = False