Hoopl: remove dependency on Hoopl package
[ghc.git] / compiler / nativeGen / Instruction.hs
1
2 module Instruction (
3 RegUsage(..),
4 noUsage,
5 GenBasicBlock(..), blockId,
6 ListGraph(..),
7 NatCmm,
8 NatCmmDecl,
9 NatBasicBlock,
10 topInfoTable,
11 entryBlocks,
12 Instruction(..)
13 )
14
15 where
16
17 import Reg
18
19 import BlockId
20 import Hoopl.Collections
21 import Hoopl.Label
22 import DynFlags
23 import Cmm hiding (topInfoTable)
24 import Platform
25
26 -- | Holds a list of source and destination registers used by a
27 -- particular instruction.
28 --
29 -- Machine registers that are pre-allocated to stgRegs are filtered
30 -- out, because they are uninteresting from a register allocation
31 -- standpoint. (We wouldn't want them to end up on the free list!)
32 --
33 -- As far as we are concerned, the fixed registers simply don't exist
34 -- (for allocation purposes, anyway).
35 --
36 data RegUsage
37 = RU [Reg] [Reg]
38
39 -- | No regs read or written to.
40 noUsage :: RegUsage
41 noUsage = RU [] []
42
43 -- Our flavours of the Cmm types
44 -- Type synonyms for Cmm populated with native code
45 type NatCmm instr
46 = GenCmmGroup
47 CmmStatics
48 (LabelMap CmmStatics)
49 (ListGraph instr)
50
51 type NatCmmDecl statics instr
52 = GenCmmDecl
53 statics
54 (LabelMap CmmStatics)
55 (ListGraph instr)
56
57
58 type NatBasicBlock instr
59 = GenBasicBlock instr
60
61
62 -- | Returns the info table associated with the CmmDecl's entry point,
63 -- if any.
64 topInfoTable :: GenCmmDecl a (LabelMap i) (ListGraph b) -> Maybe i
65 topInfoTable (CmmProc infos _ _ (ListGraph (b:_)))
66 = mapLookup (blockId b) infos
67 topInfoTable _
68 = Nothing
69
70 -- | Return the list of BlockIds in a CmmDecl that are entry points
71 -- for this proc (i.e. they may be jumped to from outside this proc).
72 entryBlocks :: GenCmmDecl a (LabelMap i) (ListGraph b) -> [BlockId]
73 entryBlocks (CmmProc info _ _ (ListGraph code)) = entries
74 where
75 infos = mapKeys info
76 entries = case code of
77 [] -> infos
78 BasicBlock entry _ : _ -- first block is the entry point
79 | entry `elem` infos -> infos
80 | otherwise -> entry : infos
81 entryBlocks _ = []
82
83 -- | Common things that we can do with instructions, on all architectures.
84 -- These are used by the shared parts of the native code generator,
85 -- specifically the register allocators.
86 --
87 class Instruction instr where
88
89 -- | Get the registers that are being used by this instruction.
90 -- regUsage doesn't need to do any trickery for jumps and such.
91 -- Just state precisely the regs read and written by that insn.
92 -- The consequences of control flow transfers, as far as register
93 -- allocation goes, are taken care of by the register allocator.
94 --
95 regUsageOfInstr
96 :: Platform
97 -> instr
98 -> RegUsage
99
100
101 -- | Apply a given mapping to all the register references in this
102 -- instruction.
103 patchRegsOfInstr
104 :: instr
105 -> (Reg -> Reg)
106 -> instr
107
108
109 -- | Checks whether this instruction is a jump/branch instruction.
110 -- One that can change the flow of control in a way that the
111 -- register allocator needs to worry about.
112 isJumpishInstr
113 :: instr -> Bool
114
115
116 -- | Give the possible destinations of this jump instruction.
117 -- Must be defined for all jumpish instructions.
118 jumpDestsOfInstr
119 :: instr -> [BlockId]
120
121
122 -- | Change the destination of this jump instruction.
123 -- Used in the linear allocator when adding fixup blocks for join
124 -- points.
125 patchJumpInstr
126 :: instr
127 -> (BlockId -> BlockId)
128 -> instr
129
130
131 -- | An instruction to spill a register into a spill slot.
132 mkSpillInstr
133 :: DynFlags
134 -> Reg -- ^ the reg to spill
135 -> Int -- ^ the current stack delta
136 -> Int -- ^ spill slot to use
137 -> instr
138
139
140 -- | An instruction to reload a register from a spill slot.
141 mkLoadInstr
142 :: DynFlags
143 -> Reg -- ^ the reg to reload.
144 -> Int -- ^ the current stack delta
145 -> Int -- ^ the spill slot to use
146 -> instr
147
148 -- | See if this instruction is telling us the current C stack delta
149 takeDeltaInstr
150 :: instr
151 -> Maybe Int
152
153 -- | Check whether this instruction is some meta thing inserted into
154 -- the instruction stream for other purposes.
155 --
156 -- Not something that has to be treated as a real machine instruction
157 -- and have its registers allocated.
158 --
159 -- eg, comments, delta, ldata, etc.
160 isMetaInstr
161 :: instr
162 -> Bool
163
164
165
166 -- | Copy the value in a register to another one.
167 -- Must work for all register classes.
168 mkRegRegMoveInstr
169 :: Platform
170 -> Reg -- ^ source register
171 -> Reg -- ^ destination register
172 -> instr
173
174 -- | Take the source and destination from this reg -> reg move instruction
175 -- or Nothing if it's not one
176 takeRegRegMoveInstr
177 :: instr
178 -> Maybe (Reg, Reg)
179
180 -- | Make an unconditional jump instruction.
181 -- For architectures with branch delay slots, its ok to put
182 -- a NOP after the jump. Don't fill the delay slot with an
183 -- instruction that references regs or you'll confuse the
184 -- linear allocator.
185 mkJumpInstr
186 :: BlockId
187 -> [instr]
188
189
190 -- Subtract an amount from the C stack pointer
191 mkStackAllocInstr
192 :: Platform -- TODO: remove (needed by x86/x86_64
193 -- because they share an Instr type)
194 -> Int
195 -> instr
196
197 -- Add an amount to the C stack pointer
198 mkStackDeallocInstr
199 :: Platform -- TODO: remove (needed by x86/x86_64
200 -- because they share an Instr type)
201 -> Int
202 -> instr