    module GHC.CmmToAsm.SPARC.Imm (
            -- immediate values
            Imm(..),
            strImmLit,
            litToImm
    )

    where

    import GHC.Prelude

    import GHC.Cmm
    import GHC.Cmm.CLabel

    import GHC.Utils.Outputable
    import GHC.Utils.Panic

    -- | An immediate value.
    --      Not all of these are directly representable by the machine.
    --      Things like ImmLit are slurped out and put in a data segment instead.
    --
    data Imm
            = ImmInt        Int

            -- Sigh.
            | ImmInteger    Integer

            -- AbstractC Label (with baggage)
            | ImmCLbl       CLabel

            -- Simple string
            | ImmLit        SDoc
            | ImmIndex      CLabel Int
            | ImmFloat      Rational
            | ImmDouble     Rational

            | ImmConstantSum  Imm Imm
            | ImmConstantDiff Imm Imm

            | LO    Imm
            | HI    Imm

    -- | Create a ImmLit containing this string.
    strImmLit :: String -> Imm
    strImmLit :: String -> Imm
    strImmLit String
    s = SDoc -> Imm
    ImmLit (String -> SDoc
    text String
    s)

    -- | Convert a CmmLit to an Imm.
    --      Narrow to the width: a CmmInt might be out of
    --      range, but we assume that ImmInteger only contains
    --      in-range values.  A signed value should be fine here.
    --
    litToImm :: CmmLit -> Imm
    litToImm :: CmmLit -> Imm
    litToImm CmmLit
    lit
     = case CmmLit
    lit of
            CmmInt Integer
    i Width
    w              -> Integer -> Imm
    ImmInteger (Width -> Integer -> Integer
    narrowS Width
    w Integer
    i)
            CmmFloat Rational
    f Width
    W32          -> Rational -> Imm
    ImmFloat Rational
    f
            CmmFloat Rational
    f Width
    W64          -> Rational -> Imm
    ImmDouble Rational
    f
            CmmLabel CLabel
    l              -> CLabel -> Imm
    ImmCLbl CLabel
    l
            CmmLabelOff CLabel
    l Int
    off       -> CLabel -> Int -> Imm
    ImmIndex CLabel
    l Int
    off

            CmmLabelDiffOff CLabel
    l1 CLabel
    l2 Int
    off Width
    _
             -> Imm -> Imm -> Imm
    ImmConstantSum
                    (Imm -> Imm -> Imm
    ImmConstantDiff (CLabel -> Imm
    ImmCLbl CLabel
    l1) (CLabel -> Imm
    ImmCLbl CLabel
    l2))
                    (Int -> Imm
    ImmInt Int
    off)

            CmmLit
    _               -> String -> Imm
    forall a. String -> a
    panic String
    "SPARC.Regs.litToImm: no match"