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

    where

    import Cmm
    import CLabel
    import BlockId

    import Pretty
    import 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	Doc
    	| 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 s = ImmLit (text 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 lit
     = case lit of
     	CmmInt i w		-> ImmInteger (narrowS w i)
    	CmmFloat f W32		-> ImmFloat f
    	CmmFloat f W64		-> ImmDouble f
    	CmmLabel l		-> ImmCLbl l
    	CmmLabelOff l off	-> ImmIndex l off

    	CmmLabelDiffOff l1 l2 off
    	 -> ImmConstantSum
    		(ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
    		(ImmInt off)

    	CmmBlock id	-> ImmCLbl (infoTblLbl id)
    	_		-> panic "SPARC.Regs.litToImm: no match"