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