Add LANGUAGE pragmas to compiler/ source files
[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 :: Ord r => RegSet r
284 nullRegSet :: Ord r => 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 :: Ord r => RegSet r -> Int
291 regSetToList :: Ord r => 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 UserOfRegs r CmmReg => UserOfRegs r CmmExpr where
351 foldRegsUsed dflags f z e = expr z e
352 where expr z (CmmLit _) = z
353 expr z (CmmLoad addr _) = foldRegsUsed dflags f z addr
354 expr z (CmmReg r) = foldRegsUsed dflags f z r
355 expr z (CmmMachOp _ exprs) = foldRegsUsed dflags f z exprs
356 expr z (CmmRegOff r _) = foldRegsUsed dflags f z r
357 expr z (CmmStackSlot _ _) = z
358
359 instance UserOfRegs r a => UserOfRegs r (Maybe a) where
360 foldRegsUsed dflags f z (Just x) = foldRegsUsed dflags f z x
361 foldRegsUsed _ _ z Nothing = z
362
363 instance UserOfRegs r a => UserOfRegs r [a] where
364 foldRegsUsed _ _ set [] = set
365 foldRegsUsed dflags f set (x:xs) = foldRegsUsed dflags f (foldRegsUsed dflags f set x) xs
366
367 instance DefinerOfRegs r a => DefinerOfRegs r [a] where
368 foldRegsDefd _ _ set [] = set
369 foldRegsDefd dflags f set (x:xs) = foldRegsDefd dflags f (foldRegsDefd dflags f set x) xs
370
371 instance DefinerOfRegs r a => DefinerOfRegs r (Maybe a) where
372 foldRegsDefd _ _ set Nothing = set
373 foldRegsDefd dflags f set (Just x) = foldRegsDefd dflags f set x
374
375 -----------------------------------------------------------------------------
376 -- Another reg utility
377
378 regUsedIn :: CmmReg -> CmmExpr -> Bool
379 _ `regUsedIn` CmmLit _ = False
380 reg `regUsedIn` CmmLoad e _ = reg `regUsedIn` e
381 reg `regUsedIn` CmmReg reg' = reg == reg'
382 reg `regUsedIn` CmmRegOff reg' _ = reg == reg'
383 reg `regUsedIn` CmmMachOp _ es = any (reg `regUsedIn`) es
384 _ `regUsedIn` CmmStackSlot _ _ = False
385
386 -----------------------------------------------------------------------------
387 -- Global STG registers
388 -----------------------------------------------------------------------------
389
390 data VGcPtr = VGcPtr | VNonGcPtr deriving( Eq, Show )
391 -- TEMPORARY!!!
392
393 -----------------------------------------------------------------------------
394 -- Global STG registers
395 -----------------------------------------------------------------------------
396 vgcFlag :: CmmType -> VGcPtr
397 vgcFlag ty | isGcPtrType ty = VGcPtr
398 | otherwise = VNonGcPtr
399
400 data GlobalReg
401 -- Argument and return registers
402 = VanillaReg -- pointers, unboxed ints and chars
403 {-# UNPACK #-} !Int -- its number
404 VGcPtr
405
406 | FloatReg -- single-precision floating-point registers
407 {-# UNPACK #-} !Int -- its number
408
409 | DoubleReg -- double-precision floating-point registers
410 {-# UNPACK #-} !Int -- its number
411
412 | LongReg -- long int registers (64-bit, really)
413 {-# UNPACK #-} !Int -- its number
414
415 | XmmReg -- 128-bit SIMD vector register
416 {-# UNPACK #-} !Int -- its number
417
418 | YmmReg -- 256-bit SIMD vector register
419 {-# UNPACK #-} !Int -- its number
420
421 | ZmmReg -- 512-bit SIMD vector register
422 {-# UNPACK #-} !Int -- its number
423
424 -- STG registers
425 | Sp -- Stack ptr; points to last occupied stack location.
426 | SpLim -- Stack limit
427 | Hp -- Heap ptr; points to last occupied heap location.
428 | HpLim -- Heap limit register
429 | CCCS -- Current cost-centre stack
430 | CurrentTSO -- pointer to current thread's TSO
431 | CurrentNursery -- pointer to allocation area
432 | HpAlloc -- allocation count for heap check failure
433
434 -- We keep the address of some commonly-called
435 -- functions in the register table, to keep code
436 -- size down:
437 | EagerBlackholeInfo -- stg_EAGER_BLACKHOLE_info
438 | GCEnter1 -- stg_gc_enter_1
439 | GCFun -- stg_gc_fun
440
441 -- Base offset for the register table, used for accessing registers
442 -- which do not have real registers assigned to them. This register
443 -- will only appear after we have expanded GlobalReg into memory accesses
444 -- (where necessary) in the native code generator.
445 | BaseReg
446
447 -- Base Register for PIC (position-independent code) calculations
448 -- Only used inside the native code generator. It's exact meaning differs
449 -- from platform to platform (see module PositionIndependentCode).
450 | PicBaseReg
451
452 deriving( Show )
453
454 instance Eq GlobalReg where
455 VanillaReg i _ == VanillaReg j _ = i==j -- Ignore type when seeking clashes
456 FloatReg i == FloatReg j = i==j
457 DoubleReg i == DoubleReg j = i==j
458 LongReg i == LongReg j = i==j
459 XmmReg i == XmmReg j = i==j
460 YmmReg i == YmmReg j = i==j
461 ZmmReg i == ZmmReg j = i==j
462 Sp == Sp = True
463 SpLim == SpLim = True
464 Hp == Hp = True
465 HpLim == HpLim = True
466 CCCS == CCCS = True
467 CurrentTSO == CurrentTSO = True
468 CurrentNursery == CurrentNursery = True
469 HpAlloc == HpAlloc = True
470 EagerBlackholeInfo == EagerBlackholeInfo = True
471 GCEnter1 == GCEnter1 = True
472 GCFun == GCFun = True
473 BaseReg == BaseReg = True
474 PicBaseReg == PicBaseReg = True
475 _r1 == _r2 = False
476
477 instance Ord GlobalReg where
478 compare (VanillaReg i _) (VanillaReg j _) = compare i j
479 -- Ignore type when seeking clashes
480 compare (FloatReg i) (FloatReg j) = compare i j
481 compare (DoubleReg i) (DoubleReg j) = compare i j
482 compare (LongReg i) (LongReg j) = compare i j
483 compare (XmmReg i) (XmmReg j) = compare i j
484 compare (YmmReg i) (YmmReg j) = compare i j
485 compare (ZmmReg i) (ZmmReg j) = compare i j
486 compare Sp Sp = EQ
487 compare SpLim SpLim = EQ
488 compare Hp Hp = EQ
489 compare HpLim HpLim = EQ
490 compare CCCS CCCS = EQ
491 compare CurrentTSO CurrentTSO = EQ
492 compare CurrentNursery CurrentNursery = EQ
493 compare HpAlloc HpAlloc = EQ
494 compare EagerBlackholeInfo EagerBlackholeInfo = EQ
495 compare GCEnter1 GCEnter1 = EQ
496 compare GCFun GCFun = EQ
497 compare BaseReg BaseReg = EQ
498 compare PicBaseReg PicBaseReg = EQ
499 compare (VanillaReg _ _) _ = LT
500 compare _ (VanillaReg _ _) = GT
501 compare (FloatReg _) _ = LT
502 compare _ (FloatReg _) = GT
503 compare (DoubleReg _) _ = LT
504 compare _ (DoubleReg _) = GT
505 compare (LongReg _) _ = LT
506 compare _ (LongReg _) = GT
507 compare (XmmReg _) _ = LT
508 compare _ (XmmReg _) = GT
509 compare (YmmReg _) _ = LT
510 compare _ (YmmReg _) = GT
511 compare (ZmmReg _) _ = LT
512 compare _ (ZmmReg _) = GT
513 compare Sp _ = LT
514 compare _ Sp = GT
515 compare SpLim _ = LT
516 compare _ SpLim = GT
517 compare Hp _ = LT
518 compare _ Hp = GT
519 compare HpLim _ = LT
520 compare _ HpLim = GT
521 compare CCCS _ = LT
522 compare _ CCCS = GT
523 compare CurrentTSO _ = LT
524 compare _ CurrentTSO = GT
525 compare CurrentNursery _ = LT
526 compare _ CurrentNursery = GT
527 compare HpAlloc _ = LT
528 compare _ HpAlloc = GT
529 compare GCEnter1 _ = LT
530 compare _ GCEnter1 = GT
531 compare GCFun _ = LT
532 compare _ GCFun = GT
533 compare BaseReg _ = LT
534 compare _ BaseReg = GT
535 compare EagerBlackholeInfo _ = LT
536 compare _ EagerBlackholeInfo = GT
537
538 -- convenient aliases
539 baseReg, spReg, hpReg, spLimReg, nodeReg :: CmmReg
540 baseReg = CmmGlobal BaseReg
541 spReg = CmmGlobal Sp
542 hpReg = CmmGlobal Hp
543 spLimReg = CmmGlobal SpLim
544 nodeReg = CmmGlobal node
545
546 node :: GlobalReg
547 node = VanillaReg 1 VGcPtr
548
549 globalRegType :: DynFlags -> GlobalReg -> CmmType
550 globalRegType dflags (VanillaReg _ VGcPtr) = gcWord dflags
551 globalRegType dflags (VanillaReg _ VNonGcPtr) = bWord dflags
552 globalRegType _ (FloatReg _) = cmmFloat W32
553 globalRegType _ (DoubleReg _) = cmmFloat W64
554 globalRegType _ (LongReg _) = cmmBits W64
555 globalRegType _ (XmmReg _) = cmmVec 4 (cmmBits W32)
556 globalRegType _ (YmmReg _) = cmmVec 8 (cmmBits W32)
557 globalRegType _ (ZmmReg _) = cmmVec 16 (cmmBits W32)
558
559 globalRegType dflags Hp = gcWord dflags
560 -- The initialiser for all
561 -- dynamically allocated closures
562 globalRegType dflags _ = bWord dflags
563
564 isArgReg :: GlobalReg -> Bool
565 isArgReg (VanillaReg {}) = True
566 isArgReg (FloatReg {}) = True
567 isArgReg (DoubleReg {}) = True
568 isArgReg (LongReg {}) = True
569 isArgReg (XmmReg {}) = True
570 isArgReg (YmmReg {}) = True
571 isArgReg (ZmmReg {}) = True
572 isArgReg _ = False