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