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