summaryrefslogtreecommitdiff
path: root/compiler/GHC/CmmToAsm/SPARC/CodeGen/Base.hs
blob: 0662fd06afbc1b1975d29b62d47c989fdb9e83b5 (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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
module GHC.CmmToAsm.SPARC.CodeGen.Base (
        InstrBlock,
        CondCode(..),
        ChildCode64(..),
        Amode(..),

        Register(..),
        setFormatOfRegister,

        getRegisterReg,
        mangleIndexTree
)

where

import GHC.Prelude

import GHC.CmmToAsm.SPARC.Instr
import GHC.CmmToAsm.SPARC.Cond
import GHC.CmmToAsm.SPARC.AddrMode
import GHC.CmmToAsm.SPARC.Regs
import GHC.CmmToAsm.Format
import GHC.Platform.Reg

import GHC.Platform.Regs
import GHC.Cmm
import GHC.Cmm.Ppr.Expr () -- For Outputable instances
import GHC.Platform

import GHC.Utils.Outputable
import GHC.Data.OrdList

--------------------------------------------------------------------------------
-- | 'InstrBlock's are the insn sequences generated by the insn selectors.
--      They are really trees of insns to facilitate fast appending, where a
--      left-to-right traversal yields the insns in the correct order.
--
type InstrBlock
        = OrdList Instr


-- | Condition codes passed up the tree.
--
data CondCode
        = CondCode Bool Cond InstrBlock


-- | a.k.a \"Register64\"
--      Reg is the lower 32-bit temporary which contains the result.
--      Use getHiVRegFromLo to find the other VRegUnique.
--
--      Rules of this simplified insn selection game are therefore that
--      the returned Reg may be modified
--
data ChildCode64
   = ChildCode64
        InstrBlock
        Reg


-- | Holds code that references a memory address.
data Amode
        = Amode
                -- the AddrMode we can use in the instruction
                --      that does the real load\/store.
                AddrMode

                -- other setup code we have to run first before we can use the
                --      above AddrMode.
                InstrBlock



--------------------------------------------------------------------------------
-- | Code to produce a result into a register.
--      If the result must go in a specific register, it comes out as Fixed.
--      Otherwise, the parent can decide which register to put it in.
--
data Register
        = Fixed Format Reg InstrBlock
        | Any   Format (Reg -> InstrBlock)


-- | Change the format field in a Register.
setFormatOfRegister
        :: Register -> Format -> Register

setFormatOfRegister reg format
 = case reg of
        Fixed _ reg code        -> Fixed format reg code
        Any _ codefn            -> Any   format codefn


--------------------------------------------------------------------------------
-- | Grab the Reg for a CmmReg
getRegisterReg :: Platform -> CmmReg -> Reg

getRegisterReg _ (CmmLocal (LocalReg u pk))
        = RegVirtual $ mkVirtualReg u (cmmTypeFormat pk)

getRegisterReg platform (CmmGlobal mid)
  = case globalRegMaybe platform mid of
        Just reg -> RegReal reg
        Nothing  -> pprPanic
                        "SPARC.CodeGen.Base.getRegisterReg: global is in memory"
                        (ppr $ CmmGlobal mid)


-- Expand CmmRegOff.  ToDo: should we do it this way around, or convert
-- CmmExprs into CmmRegOff?
mangleIndexTree :: Platform -> CmmExpr -> CmmExpr

mangleIndexTree platform (CmmRegOff reg off)
        = CmmMachOp (MO_Add width) [CmmReg reg, CmmLit (CmmInt (fromIntegral off) width)]
        where width = typeWidth (cmmRegType platform reg)

mangleIndexTree _ _
        = panic "SPARC.CodeGen.Base.mangleIndexTree: no match"