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