summaryrefslogtreecommitdiff
path: root/compiler/nativeGen/SPARC/Imm.hs
blob: bd2d4ab1316f35f1965a19404a47905b0f3b4b78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
module SPARC.Imm (
        -- immediate values
        Imm(..),
        strImmLit,
        litToImm
)

where

import GhcPrelude

import Cmm
import CLabel

import Outputable

-- | 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 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)

        _               -> panic "SPARC.Regs.litToImm: no match"