Beef up cmmMiniInline a tiny bit
[ghc-hetmet.git] / compiler / cmm / CmmExpr.hs
1
2 module CmmExpr
3     ( CmmType   -- Abstract 
4     , b8, b16, b32, b64, f32, f64, bWord, bHalfWord, gcWord
5     , cInt, cLong
6     , cmmBits, cmmFloat
7     , typeWidth, cmmEqType, cmmEqType_ignoring_ptrhood
8     , isFloatType, isGcPtrType, isWord32, isWord64, isFloat64, isFloat32
9  
10     , Width(..)
11     , widthInBits, widthInBytes, widthInLog, widthFromBytes
12     , wordWidth, halfWordWidth, cIntWidth, cLongWidth
13     , narrowU, narrowS
14  
15     , CmmExpr(..), cmmExprType, cmmExprWidth, maybeInvertCmmExpr
16     , CmmReg(..), cmmRegType
17     , CmmLit(..), cmmLitType
18     , LocalReg(..), localRegType
19     , GlobalReg(..), globalRegType, spReg, hpReg, spLimReg, nodeReg, node
20     , VGcPtr(..), vgcFlag       -- Temporary!
21     , DefinerOfLocalRegs, UserOfLocalRegs, foldRegsDefd, foldRegsUsed, filterRegsUsed
22     , DefinerOfSlots, UserOfSlots, foldSlotsDefd, foldSlotsUsed
23     , RegSet, emptyRegSet, elemRegSet, extendRegSet, deleteFromRegSet, mkRegSet
24             , plusRegSet, minusRegSet, timesRegSet
25     , regUsedIn
26     , Area(..), AreaId(..), SubArea, SubAreaSet, AreaMap, isStackSlotOf
27  
28    -- MachOp
29     , MachOp(..) 
30     , pprMachOp, isCommutableMachOp, isAssociativeMachOp
31     , isComparisonMachOp, machOpResultType
32     , machOpArgReps, maybeInvertComparison
33  
34    -- MachOp builders
35     , mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot
36     , mo_wordSRem, mo_wordSNeg, mo_wordUQuot, mo_wordURem
37     , mo_wordSGe, mo_wordSLe, mo_wordSGt, mo_wordSLt, mo_wordUGe 
38     , mo_wordULe, mo_wordUGt, mo_wordULt
39     , mo_wordAnd, mo_wordOr, mo_wordXor, mo_wordNot, mo_wordShl, mo_wordSShr, mo_wordUShr
40     , mo_u_8To32, mo_s_8To32, mo_u_16To32, mo_s_16To32
41     , mo_u_8ToWord, mo_s_8ToWord, mo_u_16ToWord, mo_s_16ToWord, mo_u_32ToWord, mo_s_32ToWord
42     , mo_32To8, mo_32To16, mo_WordTo8, mo_WordTo16, mo_WordTo32
43    )
44 where
45
46 #include "HsVersions.h"
47
48 import BlockId
49 import CLabel
50 import Constants
51 import FastString
52 import FiniteMap
53 import Outputable
54 import Unique
55 import UniqSet
56
57 import Data.Word
58 import Data.Int
59
60 -----------------------------------------------------------------------------
61 --              CmmExpr
62 -- An expression.  Expressions have no side effects.
63 -----------------------------------------------------------------------------
64
65 data CmmExpr
66   = CmmLit CmmLit               -- Literal
67   | CmmLoad CmmExpr CmmType     -- Read memory location
68   | CmmReg CmmReg               -- Contents of register
69   | CmmMachOp MachOp [CmmExpr]  -- Machine operation (+, -, *, etc.)
70   | CmmStackSlot Area Int       -- addressing expression of a stack slot
71   | CmmRegOff CmmReg Int        
72         -- CmmRegOff reg i
73         --        ** is shorthand only, meaning **
74         -- CmmMachOp (MO_S_Add rep (CmmReg reg) (CmmLit (CmmInt i rep)))
75         --      where rep = cmmRegType reg
76
77 instance Eq CmmExpr where       -- Equality ignores the types
78   CmmLit l1         == CmmLit l2         = l1==l2
79   CmmLoad e1 _      == CmmLoad e2 _      = e1==e2
80   CmmReg r1         == CmmReg r2         = r1==r2
81   CmmRegOff r1 i1   == CmmRegOff r2 i2   = r1==r2 && i1==i2
82   CmmMachOp op1 es1 == CmmMachOp op2 es2 = op1==op2 && es1==es2
83   CmmStackSlot a1 i1 == CmmStackSlot a2 i2 = a1==a2 && i1==i2
84   _e1               == _e2               = False
85
86 data CmmReg 
87   = CmmLocal  LocalReg
88   | CmmGlobal GlobalReg
89   deriving( Eq, Ord )
90
91 -- | A stack area is either the stack slot where a variable is spilled
92 -- or the stack space where function arguments and results are passed.
93 data Area
94   = RegSlot  LocalReg
95   | CallArea AreaId
96   deriving (Eq, Ord)
97
98 data AreaId
99   = Old            -- See Note [Old Area]
100   | Young BlockId
101   deriving (Eq, Ord)
102
103 {- Note [Old Area] 
104 ~~~~~~~~~~~~~~~~~~
105 There is a single call area 'Old', allocated at the extreme old
106 end of the stack frame (ie just younger than the return address)
107 which holds:
108   * incoming (overflow) parameters, 
109   * outgoing (overflow) parameter to tail calls,
110   * outgoing (overflow) result values 
111   * the update frame (if any)
112
113 Its size is the max of all these requirements.  On entry, the stack
114 pointer will point to the youngest incoming parameter, which is not
115 necessarily at the young end of the Old area.
116
117 End of note -}
118
119 type SubArea    = (Area, Int, Int) -- area, offset, width
120 type SubAreaSet = FiniteMap Area [SubArea]
121
122 type AreaMap    = FiniteMap Area Int
123      -- Byte offset of the oldest byte of the Area, 
124      -- relative to the oldest byte of the Old Area
125
126 data CmmLit
127   = CmmInt Integer  Width
128         -- Interpretation: the 2's complement representation of the value
129         -- is truncated to the specified size.  This is easier than trying
130         -- to keep the value within range, because we don't know whether
131         -- it will be used as a signed or unsigned value (the CmmType doesn't
132         -- distinguish between signed & unsigned).
133   | CmmFloat  Rational Width
134   | CmmLabel    CLabel                  -- Address of label
135   | CmmLabelOff CLabel Int              -- Address of label + byte offset
136   
137         -- Due to limitations in the C backend, the following
138         -- MUST ONLY be used inside the info table indicated by label2
139         -- (label2 must be the info label), and label1 must be an
140         -- SRT, a slow entrypoint or a large bitmap (see the Mangler)
141         -- Don't use it at all unless tablesNextToCode.
142         -- It is also used inside the NCG during when generating
143         -- position-independent code. 
144   | CmmLabelDiffOff CLabel CLabel Int   -- label1 - label2 + offset
145   | CmmBlock BlockId                    -- Code label
146   | CmmHighStackMark -- stands for the max stack space used during a procedure
147   deriving Eq
148
149 cmmExprType :: CmmExpr -> CmmType
150 cmmExprType (CmmLit lit)        = cmmLitType lit
151 cmmExprType (CmmLoad _ rep)     = rep
152 cmmExprType (CmmReg reg)        = cmmRegType reg
153 cmmExprType (CmmMachOp op args) = machOpResultType op (map cmmExprType args)
154 cmmExprType (CmmRegOff reg _)   = cmmRegType reg
155 cmmExprType (CmmStackSlot _ _)  = bWord -- an address
156
157 cmmLitType :: CmmLit -> CmmType
158 cmmLitType (CmmInt _ width)     = cmmBits  width
159 cmmLitType (CmmFloat _ width)   = cmmFloat width
160 cmmLitType (CmmLabel lbl)       = cmmLabelType lbl
161 cmmLitType (CmmLabelOff lbl _)  = cmmLabelType lbl
162 cmmLitType (CmmLabelDiffOff {}) = bWord
163 cmmLitType (CmmBlock _)         = bWord
164 cmmLitType (CmmHighStackMark)   = bWord
165
166 cmmLabelType :: CLabel -> CmmType
167 cmmLabelType lbl | isGcPtrLabel lbl = gcWord
168                  | otherwise        = bWord
169
170 cmmExprWidth :: CmmExpr -> Width
171 cmmExprWidth e = typeWidth (cmmExprType e)
172
173 --------
174 --- Negation for conditional branches
175
176 maybeInvertCmmExpr :: CmmExpr -> Maybe CmmExpr
177 maybeInvertCmmExpr (CmmMachOp op args) = do op' <- maybeInvertComparison op
178                                             return (CmmMachOp op' args)
179 maybeInvertCmmExpr _ = Nothing
180
181 -----------------------------------------------------------------------------
182 --              Local registers
183 -----------------------------------------------------------------------------
184
185 data LocalReg
186   = LocalReg !Unique CmmType
187     -- ^ Parameters:
188     --   1. Identifier
189     --   2. Type
190
191 instance Eq LocalReg where
192   (LocalReg u1 _) == (LocalReg u2 _) = u1 == u2
193
194 instance Ord LocalReg where
195   compare (LocalReg u1 _) (LocalReg u2 _) = compare u1 u2
196
197 instance Uniquable LocalReg where
198   getUnique (LocalReg uniq _) = uniq
199
200 cmmRegType :: CmmReg -> CmmType
201 cmmRegType (CmmLocal  reg)      = localRegType reg
202 cmmRegType (CmmGlobal reg)      = globalRegType reg
203
204 localRegType :: LocalReg -> CmmType
205 localRegType (LocalReg _ rep) = rep
206
207 -----------------------------------------------------------------------------
208 --    Register-use information for expressions and other types 
209 -----------------------------------------------------------------------------
210
211 -- | Sets of local registers
212 type RegSet              =  UniqSet LocalReg
213 emptyRegSet             :: RegSet
214 elemRegSet              :: LocalReg -> RegSet -> Bool
215 extendRegSet            :: RegSet -> LocalReg -> RegSet
216 deleteFromRegSet        :: RegSet -> LocalReg -> RegSet
217 mkRegSet                :: [LocalReg] -> RegSet
218 minusRegSet, plusRegSet, timesRegSet :: RegSet -> RegSet -> RegSet
219
220 emptyRegSet      = emptyUniqSet
221 elemRegSet       = elementOfUniqSet
222 extendRegSet     = addOneToUniqSet
223 deleteFromRegSet = delOneFromUniqSet
224 mkRegSet         = mkUniqSet
225 minusRegSet      = minusUniqSet
226 plusRegSet       = unionUniqSets
227 timesRegSet      = intersectUniqSets
228
229 class UserOfLocalRegs a where
230   foldRegsUsed :: (b -> LocalReg -> b) -> b -> a -> b
231
232 class DefinerOfLocalRegs a where
233   foldRegsDefd :: (b -> LocalReg -> b) -> b -> a -> b
234
235 filterRegsUsed :: UserOfLocalRegs e => (LocalReg -> Bool) -> e -> RegSet
236 filterRegsUsed p e =
237     foldRegsUsed (\regs r -> if p r then extendRegSet regs r else regs)
238                  emptyRegSet e
239
240 instance UserOfLocalRegs CmmReg where
241     foldRegsUsed f z (CmmLocal reg) = f z reg
242     foldRegsUsed _ z (CmmGlobal _)  = z
243
244 instance DefinerOfLocalRegs CmmReg where
245     foldRegsDefd f z (CmmLocal reg) = f z reg
246     foldRegsDefd _ z (CmmGlobal _)  = z
247
248 instance UserOfLocalRegs LocalReg where
249     foldRegsUsed f z r = f z r
250
251 instance DefinerOfLocalRegs LocalReg where
252     foldRegsDefd f z r = f z r
253
254 instance UserOfLocalRegs RegSet where
255     foldRegsUsed f = foldUniqSet (flip f)
256
257 instance UserOfLocalRegs CmmExpr where
258   foldRegsUsed f z e = expr z e
259     where expr z (CmmLit _)          = z
260           expr z (CmmLoad addr _)    = foldRegsUsed f z addr
261           expr z (CmmReg r)          = foldRegsUsed f z r
262           expr z (CmmMachOp _ exprs) = foldRegsUsed f z exprs
263           expr z (CmmRegOff r _)     = foldRegsUsed f z r
264           expr z (CmmStackSlot _ _)  = z
265
266 instance UserOfLocalRegs a => UserOfLocalRegs [a] where
267   foldRegsUsed _ set [] = set
268   foldRegsUsed f set (x:xs) = foldRegsUsed f (foldRegsUsed f set x) xs
269
270 instance DefinerOfLocalRegs a => DefinerOfLocalRegs [a] where
271   foldRegsDefd _ set [] = set
272   foldRegsDefd f set (x:xs) = foldRegsDefd f (foldRegsDefd f set x) xs
273
274 instance DefinerOfLocalRegs a => DefinerOfLocalRegs (Maybe a) where
275   foldRegsDefd _ set Nothing  = set
276   foldRegsDefd f set (Just x) = foldRegsDefd f set x
277
278 -----------------------------------------------------------------------------
279 -- Another reg utility
280
281 regUsedIn :: CmmReg -> CmmExpr -> Bool
282 _   `regUsedIn` CmmLit _         = False
283 reg `regUsedIn` CmmLoad e  _     = reg `regUsedIn` e
284 reg `regUsedIn` CmmReg reg'      = reg == reg'
285 reg `regUsedIn` CmmRegOff reg' _ = reg == reg'
286 reg `regUsedIn` CmmMachOp _ es   = any (reg `regUsedIn`) es
287 _   `regUsedIn` CmmStackSlot _ _ = False
288
289 -----------------------------------------------------------------------------
290 --    Stack slots
291 -----------------------------------------------------------------------------
292
293 isStackSlotOf :: CmmExpr -> LocalReg -> Bool
294 isStackSlotOf (CmmStackSlot (RegSlot r) _) r' = r == r'
295 isStackSlotOf _ _ = False
296
297 -----------------------------------------------------------------------------
298 --    Stack slot use information for expressions and other types [_$_]
299 -----------------------------------------------------------------------------
300
301 -- Fold over the area, the offset into the area, and the width of the subarea.
302 class UserOfSlots a where
303   foldSlotsUsed :: (b -> SubArea -> b) -> b -> a -> b
304
305 class DefinerOfSlots a where
306   foldSlotsDefd :: (b -> SubArea -> b) -> b -> a -> b
307
308 instance UserOfSlots CmmExpr where
309   foldSlotsUsed f z e = expr z e
310     where expr z (CmmLit _)          = z
311           expr z (CmmLoad (CmmStackSlot a i) ty) = f z (a, i, widthInBytes $ typeWidth ty)
312           expr z (CmmLoad addr _)    = foldSlotsUsed f z addr
313           expr z (CmmReg _)          = z
314           expr z (CmmMachOp _ exprs) = foldSlotsUsed f z exprs
315           expr z (CmmRegOff _ _)     = z
316           expr z (CmmStackSlot _ _)  = z
317
318 instance UserOfSlots a => UserOfSlots [a] where
319   foldSlotsUsed _ set [] = set
320   foldSlotsUsed f set (x:xs) = foldSlotsUsed f (foldSlotsUsed f set x) xs
321
322
323 -----------------------------------------------------------------------------
324 --              Global STG registers
325 -----------------------------------------------------------------------------
326
327 data VGcPtr = VGcPtr | VNonGcPtr deriving( Eq, Show )
328         -- TEMPORARY!!!
329
330 -----------------------------------------------------------------------------
331 --              Global STG registers
332 -----------------------------------------------------------------------------
333 vgcFlag :: CmmType -> VGcPtr
334 vgcFlag ty | isGcPtrType ty = VGcPtr
335            | otherwise      = VNonGcPtr
336
337 data GlobalReg
338   -- Argument and return registers
339   = VanillaReg                  -- pointers, unboxed ints and chars
340         {-# UNPACK #-} !Int     -- its number
341         VGcPtr
342
343   | FloatReg            -- single-precision floating-point registers
344         {-# UNPACK #-} !Int     -- its number
345
346   | DoubleReg           -- double-precision floating-point registers
347         {-# UNPACK #-} !Int     -- its number
348
349   | LongReg             -- long int registers (64-bit, really)
350         {-# UNPACK #-} !Int     -- its number
351
352   -- STG registers
353   | Sp                  -- Stack ptr; points to last occupied stack location.
354   | SpLim               -- Stack limit
355   | Hp                  -- Heap ptr; points to last occupied heap location.
356   | HpLim               -- Heap limit register
357   | CurrentTSO          -- pointer to current thread's TSO
358   | CurrentNursery      -- pointer to allocation area
359   | HpAlloc             -- allocation count for heap check failure
360
361                 -- We keep the address of some commonly-called 
362                 -- functions in the register table, to keep code
363                 -- size down:
364   | EagerBlackholeInfo  -- stg_EAGER_BLACKHOLE_info
365   | GCEnter1            -- stg_gc_enter_1
366   | GCFun               -- stg_gc_fun
367
368   -- Base offset for the register table, used for accessing registers
369   -- which do not have real registers assigned to them.  This register
370   -- will only appear after we have expanded GlobalReg into memory accesses
371   -- (where necessary) in the native code generator.
372   | BaseReg
373
374   -- Base Register for PIC (position-independent code) calculations
375   -- Only used inside the native code generator. It's exact meaning differs
376   -- from platform to platform (see module PositionIndependentCode).
377   | PicBaseReg
378
379   deriving( Show )
380
381 instance Eq GlobalReg where
382    VanillaReg i _ == VanillaReg j _ = i==j      -- Ignore type when seeking clashes
383    FloatReg i == FloatReg j = i==j
384    DoubleReg i == DoubleReg j = i==j
385    LongReg i == LongReg j = i==j
386    Sp == Sp = True
387    SpLim == SpLim = True
388    Hp == Hp = True
389    HpLim == HpLim = True
390    CurrentTSO == CurrentTSO = True
391    CurrentNursery == CurrentNursery = True
392    HpAlloc == HpAlloc = True
393    GCEnter1 == GCEnter1 = True
394    GCFun == GCFun = True
395    BaseReg == BaseReg = True
396    PicBaseReg == PicBaseReg = True
397    _r1 == _r2 = False
398
399 instance Ord GlobalReg where
400    compare (VanillaReg i _) (VanillaReg j _) = compare i j
401      -- Ignore type when seeking clashes
402    compare (FloatReg i)  (FloatReg  j) = compare i j
403    compare (DoubleReg i) (DoubleReg j) = compare i j
404    compare (LongReg i)   (LongReg   j) = compare i j
405    compare Sp Sp = EQ
406    compare SpLim SpLim = EQ
407    compare Hp Hp = EQ
408    compare HpLim HpLim = EQ
409    compare CurrentTSO CurrentTSO = EQ
410    compare CurrentNursery CurrentNursery = EQ
411    compare HpAlloc HpAlloc = EQ
412    compare EagerBlackholeInfo EagerBlackholeInfo = EQ
413    compare GCEnter1 GCEnter1 = EQ
414    compare GCFun GCFun = EQ
415    compare BaseReg BaseReg = EQ
416    compare PicBaseReg PicBaseReg = EQ
417    compare (VanillaReg _ _) _ = LT
418    compare _ (VanillaReg _ _) = GT
419    compare (FloatReg _) _     = LT
420    compare _ (FloatReg _)     = GT
421    compare (DoubleReg _) _    = LT
422    compare _ (DoubleReg _)    = GT
423    compare (LongReg _) _      = LT
424    compare _ (LongReg _)      = GT
425    compare Sp _ = LT
426    compare _ Sp = GT
427    compare SpLim _ = LT
428    compare _ SpLim = GT
429    compare Hp _ = LT
430    compare _ Hp = GT
431    compare HpLim _ = LT
432    compare _ HpLim = GT
433    compare CurrentTSO _ = LT
434    compare _ CurrentTSO = GT
435    compare CurrentNursery _ = LT
436    compare _ CurrentNursery = GT
437    compare HpAlloc _ = LT
438    compare _ HpAlloc = GT
439    compare GCEnter1 _ = LT
440    compare _ GCEnter1 = GT
441    compare GCFun _ = LT
442    compare _ GCFun = GT
443    compare BaseReg _ = LT
444    compare _ BaseReg = GT
445    compare EagerBlackholeInfo _ = LT
446    compare _ EagerBlackholeInfo = GT
447
448 -- convenient aliases
449 spReg, hpReg, spLimReg, nodeReg :: CmmReg
450 spReg = CmmGlobal Sp
451 hpReg = CmmGlobal Hp
452 spLimReg = CmmGlobal SpLim
453 nodeReg = CmmGlobal node
454
455 node :: GlobalReg
456 node = VanillaReg 1 VGcPtr
457
458 globalRegType :: GlobalReg -> CmmType
459 globalRegType (VanillaReg _ VGcPtr)    = gcWord
460 globalRegType (VanillaReg _ VNonGcPtr) = bWord
461 globalRegType (FloatReg _)      = cmmFloat W32
462 globalRegType (DoubleReg _)     = cmmFloat W64
463 globalRegType (LongReg _)       = cmmBits W64
464 globalRegType Hp                = gcWord        -- The initialiser for all 
465                                                 -- dynamically allocated closures
466 globalRegType _                 = bWord
467
468
469 -----------------------------------------------------------------------------
470 --              CmmType
471 -----------------------------------------------------------------------------
472
473   -- NOTE: CmmType is an abstract type, not exported from this
474   --       module so you can easily change its representation
475   --
476   -- However Width is exported in a concrete way, 
477   -- and is used extensively in pattern-matching
478
479 data CmmType    -- The important one!
480   = CmmType CmmCat Width 
481
482 data CmmCat     -- "Category" (not exported)
483    = GcPtrCat   -- GC pointer
484    | BitsCat    -- Non-pointer
485    | FloatCat   -- Float
486    deriving( Eq )
487         -- See Note [Signed vs unsigned] at the end
488
489 instance Outputable CmmType where
490   ppr (CmmType cat wid) = ppr cat <> ppr (widthInBits wid)
491
492 instance Outputable CmmCat where
493   ppr FloatCat  = ptext $ sLit("F")
494   ppr _         = ptext $ sLit("I")
495 -- Temp Jan 08
496 --  ppr FloatCat        = ptext $ sLit("float")
497 --  ppr BitsCat   = ptext $ sLit("bits")
498 --  ppr GcPtrCat  = ptext $ sLit("gcptr")
499
500 -- Why is CmmType stratified?  For native code generation, 
501 -- most of the time you just want to know what sort of register
502 -- to put the thing in, and for this you need to know how
503 -- many bits thing has and whether it goes in a floating-point
504 -- register.  By contrast, the distinction between GcPtr and
505 -- GcNonPtr is of interest to only a few parts of the code generator.
506
507 -------- Equality on CmmType --------------
508 -- CmmType is *not* an instance of Eq; sometimes we care about the
509 -- Gc/NonGc distinction, and sometimes we don't
510 -- So we use an explicit function to force you to think about it
511 cmmEqType :: CmmType -> CmmType -> Bool -- Exact equality
512 cmmEqType (CmmType c1 w1) (CmmType c2 w2) = c1==c2 && w1==w2
513
514 cmmEqType_ignoring_ptrhood :: CmmType -> CmmType -> Bool
515   -- This equality is temporary; used in CmmLint
516   -- but the RTS files are not yet well-typed wrt pointers
517 cmmEqType_ignoring_ptrhood (CmmType c1 w1) (CmmType c2 w2)
518    = c1 `weak_eq` c2 && w1==w2
519    where
520       FloatCat `weak_eq` FloatCat = True 
521       FloatCat `weak_eq` _other   = False
522       _other   `weak_eq` FloatCat = False
523       _word1   `weak_eq` _word2   = True        -- Ignores GcPtr
524
525 --- Simple operations on CmmType -----
526 typeWidth :: CmmType -> Width
527 typeWidth (CmmType _ w) = w
528
529 cmmBits, cmmFloat :: Width -> CmmType
530 cmmBits  = CmmType BitsCat
531 cmmFloat = CmmType FloatCat
532
533 -------- Common CmmTypes ------------
534 -- Floats and words of specific widths
535 b8, b16, b32, b64, f32, f64 :: CmmType
536 b8     = cmmBits W8
537 b16    = cmmBits W16
538 b32    = cmmBits W32
539 b64    = cmmBits W64
540 f32    = cmmFloat W32
541 f64    = cmmFloat W64
542
543 -- CmmTypes of native word widths
544 bWord, bHalfWord, gcWord :: CmmType
545 bWord     = cmmBits wordWidth
546 bHalfWord = cmmBits halfWordWidth
547 gcWord    = CmmType GcPtrCat wordWidth
548
549 cInt, cLong :: CmmType
550 cInt  = cmmBits cIntWidth
551 cLong = cmmBits cLongWidth
552
553
554 ------------ Predicates ----------------
555 isFloatType, isGcPtrType :: CmmType -> Bool
556 isFloatType (CmmType FloatCat    _) = True
557 isFloatType _other                  = False
558
559 isGcPtrType (CmmType GcPtrCat _) = True
560 isGcPtrType _other               = False
561
562 isWord32, isWord64, isFloat32, isFloat64 :: CmmType -> Bool
563 -- isWord64 is true of 64-bit non-floats (both gc-ptrs and otherwise)
564 -- isFloat32 and 64 are obvious
565
566 isWord64 (CmmType BitsCat  W64) = True
567 isWord64 (CmmType GcPtrCat W64) = True
568 isWord64 _other                 = False
569
570 isWord32 (CmmType BitsCat  W32) = True
571 isWord32 (CmmType GcPtrCat W32) = True
572 isWord32 _other                 = False
573
574 isFloat32 (CmmType FloatCat W32) = True
575 isFloat32 _other                 = False
576
577 isFloat64 (CmmType FloatCat W64) = True
578 isFloat64 _other                 = False
579
580 -----------------------------------------------------------------------------
581 --              Width
582 -----------------------------------------------------------------------------
583
584 data Width   = W8 | W16 | W32 | W64 
585              | W80      -- Extended double-precision float, 
586                         -- used in x86 native codegen only.
587                         -- (we use Ord, so it'd better be in this order)
588              | W128
589              deriving (Eq, Ord, Show)
590
591 instance Outputable Width where
592    ppr rep = ptext (mrStr rep)
593
594 mrStr :: Width -> LitString
595 mrStr W8   = sLit("W8")
596 mrStr W16  = sLit("W16")
597 mrStr W32  = sLit("W32")
598 mrStr W64  = sLit("W64")
599 mrStr W128 = sLit("W128")
600 mrStr W80  = sLit("W80")
601
602
603 -------- Common Widths  ------------
604 wordWidth, halfWordWidth :: Width
605 wordWidth | wORD_SIZE == 4 = W32
606           | wORD_SIZE == 8 = W64
607           | otherwise      = panic "MachOp.wordRep: Unknown word size"
608
609 halfWordWidth | wORD_SIZE == 4 = W16
610               | wORD_SIZE == 8 = W32
611               | otherwise      = panic "MachOp.halfWordRep: Unknown word size"
612
613 -- cIntRep is the Width for a C-language 'int'
614 cIntWidth, cLongWidth :: Width
615 #if SIZEOF_INT == 4
616 cIntWidth = W32
617 #elif  SIZEOF_INT == 8
618 cIntWidth = W64
619 #endif
620
621 #if SIZEOF_LONG == 4
622 cLongWidth = W32
623 #elif  SIZEOF_LONG == 8
624 cLongWidth = W64
625 #endif
626
627 widthInBits :: Width -> Int
628 widthInBits W8   = 8
629 widthInBits W16  = 16
630 widthInBits W32  = 32
631 widthInBits W64  = 64
632 widthInBits W128 = 128
633 widthInBits W80  = 80
634
635 widthInBytes :: Width -> Int
636 widthInBytes W8   = 1
637 widthInBytes W16  = 2
638 widthInBytes W32  = 4
639 widthInBytes W64  = 8
640 widthInBytes W128 = 16
641 widthInBytes W80  = 10
642
643 widthFromBytes :: Int -> Width
644 widthFromBytes 1  = W8
645 widthFromBytes 2  = W16
646 widthFromBytes 4  = W32
647 widthFromBytes 8  = W64
648 widthFromBytes 16 = W128
649 widthFromBytes 10 = W80
650 widthFromBytes n  = pprPanic "no width for given number of bytes" (ppr n)
651
652 -- log_2 of the width in bytes, useful for generating shifts.
653 widthInLog :: Width -> Int
654 widthInLog W8   = 0
655 widthInLog W16  = 1
656 widthInLog W32  = 2
657 widthInLog W64  = 3
658 widthInLog W128 = 4
659 widthInLog W80  = panic "widthInLog: F80"
660
661 -- widening / narrowing
662
663 narrowU :: Width -> Integer -> Integer
664 narrowU W8  x = fromIntegral (fromIntegral x :: Word8)
665 narrowU W16 x = fromIntegral (fromIntegral x :: Word16)
666 narrowU W32 x = fromIntegral (fromIntegral x :: Word32)
667 narrowU W64 x = fromIntegral (fromIntegral x :: Word64)
668 narrowU _ _ = panic "narrowTo"
669
670 narrowS :: Width -> Integer -> Integer
671 narrowS W8  x = fromIntegral (fromIntegral x :: Int8)
672 narrowS W16 x = fromIntegral (fromIntegral x :: Int16)
673 narrowS W32 x = fromIntegral (fromIntegral x :: Int32)
674 narrowS W64 x = fromIntegral (fromIntegral x :: Int64)
675 narrowS _ _ = panic "narrowTo"
676
677 -----------------------------------------------------------------------------
678 --              MachOp
679 -----------------------------------------------------------------------------
680
681 {- 
682 Implementation notes:
683
684 It might suffice to keep just a width, without distinguishing between
685 floating and integer types.  However, keeping the distinction will
686 help the native code generator to assign registers more easily.
687 -}
688
689
690 {- |
691 Machine-level primops; ones which we can reasonably delegate to the
692 native code generators to handle.  Basically contains C's primops
693 and no others.
694
695 Nomenclature: all ops indicate width and signedness, where
696 appropriate.  Widths: 8\/16\/32\/64 means the given size, obviously.
697 Nat means the operation works on STG word sized objects.
698 Signedness: S means signed, U means unsigned.  For operations where
699 signedness is irrelevant or makes no difference (for example
700 integer add), the signedness component is omitted.
701
702 An exception: NatP is a ptr-typed native word.  From the point of
703 view of the native code generators this distinction is irrelevant,
704 but the C code generator sometimes needs this info to emit the
705 right casts.  
706 -}
707
708 data MachOp
709   -- Integer operations (insensitive to signed/unsigned)
710   = MO_Add Width
711   | MO_Sub Width
712   | MO_Eq  Width
713   | MO_Ne  Width
714   | MO_Mul Width                -- low word of multiply
715
716   -- Signed multiply/divide
717   | MO_S_MulMayOflo Width       -- nonzero if signed multiply overflows
718   | MO_S_Quot Width             -- signed / (same semantics as IntQuotOp)
719   | MO_S_Rem  Width             -- signed % (same semantics as IntRemOp)
720   | MO_S_Neg  Width             -- unary -
721
722   -- Unsigned multiply/divide
723   | MO_U_MulMayOflo Width       -- nonzero if unsigned multiply overflows
724   | MO_U_Quot Width             -- unsigned / (same semantics as WordQuotOp)
725   | MO_U_Rem  Width             -- unsigned % (same semantics as WordRemOp)
726
727   -- Signed comparisons
728   | MO_S_Ge Width
729   | MO_S_Le Width
730   | MO_S_Gt Width
731   | MO_S_Lt Width
732
733   -- Unsigned comparisons
734   | MO_U_Ge Width
735   | MO_U_Le Width
736   | MO_U_Gt Width
737   | MO_U_Lt Width
738
739   -- Floating point arithmetic
740   | MO_F_Add  Width
741   | MO_F_Sub  Width
742   | MO_F_Neg  Width             -- unary -
743   | MO_F_Mul  Width
744   | MO_F_Quot Width
745
746   -- Floating point comparison
747   | MO_F_Eq Width
748   | MO_F_Ne Width
749   | MO_F_Ge Width
750   | MO_F_Le Width
751   | MO_F_Gt Width
752   | MO_F_Lt Width
753
754   -- Bitwise operations.  Not all of these may be supported 
755   -- at all sizes, and only integral Widths are valid.
756   | MO_And   Width
757   | MO_Or    Width
758   | MO_Xor   Width
759   | MO_Not   Width
760   | MO_Shl   Width
761   | MO_U_Shr Width      -- unsigned shift right
762   | MO_S_Shr Width      -- signed shift right
763
764   -- Conversions.  Some of these will be NOPs.
765   -- Floating-point conversions use the signed variant.
766   | MO_SF_Conv Width Width      -- Signed int -> Float
767   | MO_FS_Conv Width Width      -- Float -> Signed int
768   | MO_SS_Conv Width Width      -- Signed int -> Signed int
769   | MO_UU_Conv Width Width      -- unsigned int -> unsigned int
770   | MO_FF_Conv Width Width      -- Float -> Float
771   deriving (Eq, Show)
772
773 pprMachOp :: MachOp -> SDoc
774 pprMachOp mo = text (show mo)
775
776
777
778 -- -----------------------------------------------------------------------------
779 -- Some common MachReps
780
781 -- A 'wordRep' is a machine word on the target architecture
782 -- Specifically, it is the size of an Int#, Word#, Addr# 
783 -- and the unit of allocation on the stack and the heap
784 -- Any pointer is also guaranteed to be a wordRep.
785
786 mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot
787     , mo_wordSRem, mo_wordSNeg, mo_wordUQuot, mo_wordURem
788     , mo_wordSGe, mo_wordSLe, mo_wordSGt, mo_wordSLt, mo_wordUGe 
789     , mo_wordULe, mo_wordUGt, mo_wordULt
790     , mo_wordAnd, mo_wordOr, mo_wordXor, mo_wordNot, mo_wordShl, mo_wordSShr, mo_wordUShr
791     , mo_u_8To32, mo_s_8To32, mo_u_16To32, mo_s_16To32
792     , mo_u_8ToWord, mo_s_8ToWord, mo_u_16ToWord, mo_s_16ToWord, mo_u_32ToWord, mo_s_32ToWord
793     , mo_32To8, mo_32To16, mo_WordTo8, mo_WordTo16, mo_WordTo32
794     :: MachOp
795
796 mo_wordAdd      = MO_Add wordWidth
797 mo_wordSub      = MO_Sub wordWidth
798 mo_wordEq       = MO_Eq  wordWidth
799 mo_wordNe       = MO_Ne  wordWidth
800 mo_wordMul      = MO_Mul wordWidth
801 mo_wordSQuot    = MO_S_Quot wordWidth
802 mo_wordSRem     = MO_S_Rem wordWidth
803 mo_wordSNeg     = MO_S_Neg wordWidth
804 mo_wordUQuot    = MO_U_Quot wordWidth
805 mo_wordURem     = MO_U_Rem wordWidth
806
807 mo_wordSGe      = MO_S_Ge  wordWidth
808 mo_wordSLe      = MO_S_Le  wordWidth
809 mo_wordSGt      = MO_S_Gt  wordWidth
810 mo_wordSLt      = MO_S_Lt  wordWidth
811
812 mo_wordUGe      = MO_U_Ge  wordWidth
813 mo_wordULe      = MO_U_Le  wordWidth
814 mo_wordUGt      = MO_U_Gt  wordWidth
815 mo_wordULt      = MO_U_Lt  wordWidth
816
817 mo_wordAnd      = MO_And wordWidth
818 mo_wordOr       = MO_Or  wordWidth
819 mo_wordXor      = MO_Xor wordWidth
820 mo_wordNot      = MO_Not wordWidth
821 mo_wordShl      = MO_Shl wordWidth
822 mo_wordSShr     = MO_S_Shr wordWidth 
823 mo_wordUShr     = MO_U_Shr wordWidth 
824
825 mo_u_8To32      = MO_UU_Conv W8 W32
826 mo_s_8To32      = MO_SS_Conv W8 W32
827 mo_u_16To32     = MO_UU_Conv W16 W32
828 mo_s_16To32     = MO_SS_Conv W16 W32
829
830 mo_u_8ToWord    = MO_UU_Conv W8  wordWidth
831 mo_s_8ToWord    = MO_SS_Conv W8  wordWidth
832 mo_u_16ToWord   = MO_UU_Conv W16 wordWidth
833 mo_s_16ToWord   = MO_SS_Conv W16 wordWidth
834 mo_s_32ToWord   = MO_SS_Conv W32 wordWidth
835 mo_u_32ToWord   = MO_UU_Conv W32 wordWidth
836
837 mo_WordTo8      = MO_UU_Conv wordWidth W8
838 mo_WordTo16     = MO_UU_Conv wordWidth W16
839 mo_WordTo32     = MO_UU_Conv wordWidth W32
840
841 mo_32To8        = MO_UU_Conv W32 W8
842 mo_32To16       = MO_UU_Conv W32 W16
843
844
845 -- ----------------------------------------------------------------------------
846 -- isCommutableMachOp
847
848 {- |
849 Returns 'True' if the MachOp has commutable arguments.  This is used
850 in the platform-independent Cmm optimisations.
851
852 If in doubt, return 'False'.  This generates worse code on the
853 native routes, but is otherwise harmless.
854 -}
855 isCommutableMachOp :: MachOp -> Bool
856 isCommutableMachOp mop = 
857   case mop of
858         MO_Add _                -> True
859         MO_Eq _                 -> True
860         MO_Ne _                 -> True
861         MO_Mul _                -> True
862         MO_S_MulMayOflo _       -> True
863         MO_U_MulMayOflo _       -> True
864         MO_And _                -> True
865         MO_Or _                 -> True
866         MO_Xor _                -> True
867         _other                  -> False
868
869 -- ----------------------------------------------------------------------------
870 -- isAssociativeMachOp
871
872 {- |
873 Returns 'True' if the MachOp is associative (i.e. @(x+y)+z == x+(y+z)@)
874 This is used in the platform-independent Cmm optimisations.
875
876 If in doubt, return 'False'.  This generates worse code on the
877 native routes, but is otherwise harmless.
878 -}
879 isAssociativeMachOp :: MachOp -> Bool
880 isAssociativeMachOp mop = 
881   case mop of
882         MO_Add {} -> True       -- NB: does not include
883         MO_Mul {} -> True --     floatint point!
884         MO_And {} -> True
885         MO_Or  {} -> True
886         MO_Xor {} -> True
887         _other    -> False
888
889 -- ----------------------------------------------------------------------------
890 -- isComparisonMachOp
891
892 {- | 
893 Returns 'True' if the MachOp is a comparison.
894
895 If in doubt, return False.  This generates worse code on the
896 native routes, but is otherwise harmless.
897 -}
898 isComparisonMachOp :: MachOp -> Bool
899 isComparisonMachOp mop = 
900   case mop of
901     MO_Eq   _  -> True
902     MO_Ne   _  -> True
903     MO_S_Ge _  -> True
904     MO_S_Le _  -> True
905     MO_S_Gt _  -> True
906     MO_S_Lt _  -> True
907     MO_U_Ge _  -> True
908     MO_U_Le _  -> True
909     MO_U_Gt _  -> True
910     MO_U_Lt _  -> True
911     MO_F_Eq  {} -> True
912     MO_F_Ne  {} -> True
913     MO_F_Ge  {} -> True
914     MO_F_Le  {} -> True
915     MO_F_Gt  {} -> True
916     MO_F_Lt  {} -> True
917     _other     -> False
918
919 -- -----------------------------------------------------------------------------
920 -- Inverting conditions
921
922 -- Sometimes it's useful to be able to invert the sense of a
923 -- condition.  Not all conditional tests are invertible: in
924 -- particular, floating point conditionals cannot be inverted, because
925 -- there exist floating-point values which return False for both senses
926 -- of a condition (eg. !(NaN > NaN) && !(NaN /<= NaN)).
927
928 maybeInvertComparison :: MachOp -> Maybe MachOp
929 maybeInvertComparison op
930   = case op of  -- None of these Just cases include floating point
931         MO_Eq r   -> Just (MO_Ne r)
932         MO_Ne r   -> Just (MO_Eq r)
933         MO_U_Lt r -> Just (MO_U_Ge r)
934         MO_U_Gt r -> Just (MO_U_Le r)
935         MO_U_Le r -> Just (MO_U_Gt r)
936         MO_U_Ge r -> Just (MO_U_Lt r)
937         MO_S_Lt r -> Just (MO_S_Ge r)
938         MO_S_Gt r -> Just (MO_S_Le r)
939         MO_S_Le r -> Just (MO_S_Gt r)
940         MO_S_Ge r -> Just (MO_S_Lt r)
941         MO_F_Eq r -> Just (MO_F_Ne r)
942         MO_F_Ne r -> Just (MO_F_Eq r)
943         MO_F_Ge r -> Just (MO_F_Le r)
944         MO_F_Le r -> Just (MO_F_Ge r)   
945         MO_F_Gt r -> Just (MO_F_Lt r)   
946         MO_F_Lt r -> Just (MO_F_Gt r)   
947         _other    -> Nothing
948
949 -- ----------------------------------------------------------------------------
950 -- machOpResultType
951
952 {- |
953 Returns the MachRep of the result of a MachOp.
954 -}
955 machOpResultType :: MachOp -> [CmmType] -> CmmType
956 machOpResultType mop tys =
957   case mop of
958     MO_Add {}           -> ty1  -- Preserve GC-ptr-hood
959     MO_Sub {}           -> ty1  -- of first arg
960     MO_Mul    r         -> cmmBits r
961     MO_S_MulMayOflo r   -> cmmBits r
962     MO_S_Quot r         -> cmmBits r
963     MO_S_Rem  r         -> cmmBits r
964     MO_S_Neg  r         -> cmmBits r
965     MO_U_MulMayOflo r   -> cmmBits r
966     MO_U_Quot r         -> cmmBits r
967     MO_U_Rem  r         -> cmmBits r
968
969     MO_Eq {}            -> comparisonResultRep
970     MO_Ne {}            -> comparisonResultRep
971     MO_S_Ge {}          -> comparisonResultRep
972     MO_S_Le {}          -> comparisonResultRep
973     MO_S_Gt {}          -> comparisonResultRep
974     MO_S_Lt {}          -> comparisonResultRep
975
976     MO_U_Ge {}          -> comparisonResultRep
977     MO_U_Le {}          -> comparisonResultRep
978     MO_U_Gt {}          -> comparisonResultRep
979     MO_U_Lt {}          -> comparisonResultRep
980
981     MO_F_Add r          -> cmmFloat r
982     MO_F_Sub r          -> cmmFloat r
983     MO_F_Mul r          -> cmmFloat r
984     MO_F_Quot r         -> cmmFloat r
985     MO_F_Neg r          -> cmmFloat r
986     MO_F_Eq  {}         -> comparisonResultRep
987     MO_F_Ne  {}         -> comparisonResultRep
988     MO_F_Ge  {}         -> comparisonResultRep
989     MO_F_Le  {}         -> comparisonResultRep
990     MO_F_Gt  {}         -> comparisonResultRep
991     MO_F_Lt  {}         -> comparisonResultRep
992
993     MO_And {}           -> ty1  -- Used for pointer masking
994     MO_Or {}            -> ty1
995     MO_Xor {}           -> ty1
996     MO_Not   r          -> cmmBits r
997     MO_Shl   r          -> cmmBits r
998     MO_U_Shr r          -> cmmBits r
999     MO_S_Shr r          -> cmmBits r
1000
1001     MO_SS_Conv _ to     -> cmmBits to
1002     MO_UU_Conv _ to     -> cmmBits to
1003     MO_FS_Conv _ to     -> cmmBits to
1004     MO_SF_Conv _ to     -> cmmFloat to
1005     MO_FF_Conv _ to     -> cmmFloat to
1006   where
1007     (ty1:_) = tys
1008
1009 comparisonResultRep :: CmmType
1010 comparisonResultRep = bWord  -- is it?
1011
1012
1013 -- -----------------------------------------------------------------------------
1014 -- machOpArgReps
1015
1016 -- | This function is used for debugging only: we can check whether an
1017 -- application of a MachOp is "type-correct" by checking that the MachReps of
1018 -- its arguments are the same as the MachOp expects.  This is used when 
1019 -- linting a CmmExpr.
1020
1021 machOpArgReps :: MachOp -> [Width]
1022 machOpArgReps op = 
1023   case op of
1024     MO_Add    r         -> [r,r]
1025     MO_Sub    r         -> [r,r]
1026     MO_Eq     r         -> [r,r]
1027     MO_Ne     r         -> [r,r]
1028     MO_Mul    r         -> [r,r]
1029     MO_S_MulMayOflo r   -> [r,r]
1030     MO_S_Quot r         -> [r,r]
1031     MO_S_Rem  r         -> [r,r]
1032     MO_S_Neg  r         -> [r]
1033     MO_U_MulMayOflo r   -> [r,r]
1034     MO_U_Quot r         -> [r,r]
1035     MO_U_Rem  r         -> [r,r]
1036
1037     MO_S_Ge r           -> [r,r]
1038     MO_S_Le r           -> [r,r]
1039     MO_S_Gt r           -> [r,r]
1040     MO_S_Lt r           -> [r,r]
1041
1042     MO_U_Ge r           -> [r,r]
1043     MO_U_Le r           -> [r,r]
1044     MO_U_Gt r           -> [r,r]
1045     MO_U_Lt r           -> [r,r]
1046
1047     MO_F_Add r          -> [r,r]
1048     MO_F_Sub r          -> [r,r]
1049     MO_F_Mul r          -> [r,r]
1050     MO_F_Quot r         -> [r,r]
1051     MO_F_Neg r          -> [r]
1052     MO_F_Eq  r          -> [r,r]
1053     MO_F_Ne  r          -> [r,r]
1054     MO_F_Ge  r          -> [r,r]
1055     MO_F_Le  r          -> [r,r]
1056     MO_F_Gt  r          -> [r,r]
1057     MO_F_Lt  r          -> [r,r]
1058
1059     MO_And   r          -> [r,r]
1060     MO_Or    r          -> [r,r]
1061     MO_Xor   r          -> [r,r]
1062     MO_Not   r          -> [r]
1063     MO_Shl   r          -> [r,wordWidth]
1064     MO_U_Shr r          -> [r,wordWidth]
1065     MO_S_Shr r          -> [r,wordWidth]
1066
1067     MO_SS_Conv from _   -> [from]
1068     MO_UU_Conv from _   -> [from]
1069     MO_SF_Conv from _   -> [from]
1070     MO_FS_Conv from _   -> [from]
1071     MO_FF_Conv from _   -> [from]
1072
1073
1074 -------------------------------------------------------------------------
1075 {-      Note [Signed vs unsigned]
1076         ~~~~~~~~~~~~~~~~~~~~~~~~~
1077 Should a CmmType include a signed vs. unsigned distinction?
1078
1079 This is very much like a "hint" in C-- terminology: it isn't necessary
1080 in order to generate correct code, but it might be useful in that the
1081 compiler can generate better code if it has access to higher-level
1082 hints about data.  This is important at call boundaries, because the
1083 definition of a function is not visible at all of its call sites, so
1084 the compiler cannot infer the hints.
1085
1086 Here in Cmm, we're taking a slightly different approach.  We include
1087 the int vs. float hint in the MachRep, because (a) the majority of
1088 platforms have a strong distinction between float and int registers,
1089 and (b) we don't want to do any heavyweight hint-inference in the
1090 native code backend in order to get good code.  We're treating the
1091 hint more like a type: our Cmm is always completely consistent with
1092 respect to hints.  All coercions between float and int are explicit.
1093
1094 What about the signed vs. unsigned hint?  This information might be
1095 useful if we want to keep sub-word-sized values in word-size
1096 registers, which we must do if we only have word-sized registers.
1097
1098 On such a system, there are two straightforward conventions for
1099 representing sub-word-sized values:
1100
1101 (a) Leave the upper bits undefined.  Comparison operations must
1102     sign- or zero-extend both operands before comparing them,
1103     depending on whether the comparison is signed or unsigned.
1104
1105 (b) Always keep the values sign- or zero-extended as appropriate.
1106     Arithmetic operations must narrow the result to the appropriate
1107     size.
1108
1109 A clever compiler might not use either (a) or (b) exclusively, instead
1110 it would attempt to minimize the coercions by analysis: the same kind
1111 of analysis that propagates hints around.  In Cmm we don't want to
1112 have to do this, so we plump for having richer types and keeping the
1113 type information consistent.
1114
1115 If signed/unsigned hints are missing from MachRep, then the only
1116 choice we have is (a), because we don't know whether the result of an
1117 operation should be sign- or zero-extended.
1118
1119 Many architectures have extending load operations, which work well
1120 with (b).  To make use of them with (a), you need to know whether the
1121 value is going to be sign- or zero-extended by an enclosing comparison
1122 (for example), which involves knowing above the context.  This is
1123 doable but more complex.
1124
1125 Further complicating the issue is foreign calls: a foreign calling
1126 convention can specify that signed 8-bit quantities are passed as
1127 sign-extended 32 bit quantities, for example (this is the case on the
1128 PowerPC).  So we *do* need sign information on foreign call arguments.
1129
1130 Pros for adding signed vs. unsigned to MachRep:
1131
1132   - It would let us use convention (b) above, and get easier
1133     code generation for extending loads.
1134
1135   - Less information required on foreign calls.
1136   
1137   - MachOp type would be simpler
1138
1139 Cons:
1140
1141   - More complexity
1142
1143   - What is the MachRep for a VanillaReg?  Currently it is
1144     always wordRep, but now we have to decide whether it is
1145     signed or unsigned.  The same VanillaReg can thus have
1146     different MachReps in different parts of the program.
1147
1148   - Extra coercions cluttering up expressions.
1149
1150 Currently for GHC, the foreign call point is moot, because we do our
1151 own promotion of sub-word-sized values to word-sized values.  The Int8
1152 type is represnted by an Int# which is kept sign-extended at all times
1153 (this is slightly naughty, because we're making assumptions about the
1154 C calling convention rather early on in the compiler).  However, given
1155 this, the cons outweigh the pros.
1156
1157 -}
1158