    -- | Sizes on this architecture
    --      A Size is a combination of width and class
    --
    --      TODO:   Rename this to "Format" instead of "Size" to reflect
    --              the fact that it represents floating point vs integer.
    --
    --      TODO:   Signed vs unsigned?
    --
    --      TODO:   This module is currenly shared by all architectures because
    --              NCGMonad need to know about it to make a VReg. It would be better
    --              to have architecture specific formats, and do the overloading
    --              properly. eg SPARC doesn't care about FF80.
    --
    module Size (
        Size(..),
        intSize,
        floatSize,
        isFloatSize,
        cmmTypeSize,
        sizeToWidth,
        sizeInBytes
    )

    where

    import Cmm
    import Outputable

    -- It looks very like the old MachRep, but it's now of purely local
    -- significance, here in the native code generator.  You can change it
    -- without global consequences.
    --
    -- A major use is as an opcode qualifier; thus the opcode
    --      mov.l a b
    -- might be encoded
    --      MOV II32 a b
    -- where the Size field encodes the ".l" part.

    -- ToDo: it's not clear to me that we need separate signed-vs-unsigned sizes
    --        here.  I've removed them from the x86 version, we'll see what happens --SDM

    -- ToDo: quite a few occurrences of Size could usefully be replaced by Width

    data Size
            = II8
            | II16
            | II32
            | II64
            | FF32
            | FF64
            | FF80
            deriving (Show, Eq)

    -- | Get the integer size of this width.
    intSize :: Width -> Size
    intSize width
     = case width of
            W8      -> II8
            W16     -> II16
            W32     -> II32
            W64     -> II64
            other   -> pprPanic "Size.intSize" (ppr other)

    -- | Get the float size of this width.
    floatSize :: Width -> Size
    floatSize width
     = case width of
            W32     -> FF32
            W64     -> FF64
            other   -> pprPanic "Size.floatSize" (ppr other)

    -- | Check if a size represents a floating point value.
    isFloatSize :: Size -> Bool
    isFloatSize size
     = case size of
            FF32    -> True
            FF64    -> True
            FF80    -> True
            _       -> False

    -- | Convert a Cmm type to a Size.
    cmmTypeSize :: CmmType -> Size
    cmmTypeSize ty
            | isFloatType ty        = floatSize (typeWidth ty)
            | otherwise             = intSize (typeWidth ty)

    -- | Get the Width of a Size.
    sizeToWidth :: Size -> Width
    sizeToWidth size
     = case size of
            II8             -> W8
            II16            -> W16
            II32            -> W32
            II64            -> W64
            FF32            -> W32
            FF64            -> W64
            FF80            -> W80

    sizeInBytes :: Size -> Int
    sizeInBytes = widthInBytes . sizeToWidth