Fix a bug with standalone deriving of Generic instances.
[ghc-hetmet.git] / compiler / nativeGen / Instruction.hs
1
2 module Instruction (
3         RegUsage(..),
4         noUsage,
5         NatCmm,
6         NatCmmTop,
7         NatBasicBlock,
8         Instruction(..)
9 )
10
11 where
12
13 import Reg
14
15 import BlockId
16 import OldCmm
17
18 -- | Holds a list of source and destination registers used by a
19 --      particular instruction. 
20 --
21 --   Machine registers that are pre-allocated to stgRegs are filtered
22 --      out, because they are uninteresting from a register allocation
23 --      standpoint.  (We wouldn't want them to end up on the free list!) 
24 --
25 --   As far as we are concerned, the fixed registers simply don't exist
26 --      (for allocation purposes, anyway).
27 --
28 data RegUsage 
29         = RU [Reg] [Reg]
30
31 -- | No regs read or written to.
32 noUsage :: RegUsage
33 noUsage  = RU [] []
34
35
36 -- Our flavours of the Cmm types
37 -- Type synonyms for Cmm populated with native code
38 type NatCmm instr
39         = GenCmm
40                 CmmStatic
41                 [CmmStatic]
42                 (ListGraph instr)
43
44 type NatCmmTop instr
45         = GenCmmTop
46                 CmmStatic
47                 [CmmStatic]
48                 (ListGraph instr)
49
50
51 type NatBasicBlock instr
52         = GenBasicBlock instr
53
54
55
56
57 -- | Common things that we can do with instructions, on all architectures.
58 --      These are used by the shared parts of the native code generator,
59 --      specifically the register allocators.
60 --
61 class   Instruction instr where
62         
63         -- | Get the registers that are being used by this instruction.
64         --      regUsage doesn't need to do any trickery for jumps and such.  
65         --      Just state precisely the regs read and written by that insn.  
66         --      The consequences of control flow transfers, as far as register
67         --      allocation goes, are taken care of by the register allocator.
68         --
69         regUsageOfInstr
70                 :: instr        
71                 -> RegUsage
72
73
74         -- | Apply a given mapping to all the register references in this
75         --      instruction.
76         patchRegsOfInstr
77                 :: instr 
78                 -> (Reg -> Reg) 
79                 -> instr
80
81         
82         -- | Checks whether this instruction is a jump/branch instruction. 
83         --      One that can change the flow of control in a way that the 
84         --      register allocator needs to worry about. 
85         isJumpishInstr
86                 :: instr -> Bool
87
88
89         -- | Give the possible destinations of this jump instruction.
90         --      Must be defined for all jumpish instructions.
91         jumpDestsOfInstr
92                 :: instr -> [BlockId]
93         
94
95         -- | Change the destination of this jump instruction.
96         --      Used in the linear allocator when adding fixup blocks for join
97         --      points.
98         patchJumpInstr
99                 :: instr
100                 -> (BlockId -> BlockId)
101                 -> instr
102
103                 
104         -- | An instruction to spill a register into a spill slot.
105         mkSpillInstr    
106                 :: Reg          -- ^ the reg to spill
107                 -> Int          -- ^ the current stack delta
108                 -> Int          -- ^ spill slot to use
109                 -> instr
110
111                 
112         -- | An instruction to reload a register from a spill slot.
113         mkLoadInstr     
114                 :: Reg          -- ^ the reg to reload.
115                 -> Int          -- ^ the current stack delta
116                 -> Int          -- ^ the spill slot to use
117                 -> instr
118
119         -- | See if this instruction is telling us the current C stack delta
120         takeDeltaInstr 
121                 :: instr
122                 -> Maybe Int
123
124         -- | Check whether this instruction is some meta thing inserted into 
125         --      the instruction stream for other purposes.
126         --
127         --      Not something that has to be treated as a real machine instruction
128         --      and have its registers allocated.
129         --
130         --      eg, comments, delta, ldata, etc. 
131         isMetaInstr     
132                 :: instr
133                 -> Bool
134                 
135
136                 
137         -- | Copy the value in a register to another one.
138         --      Must work for all register classes.
139         mkRegRegMoveInstr
140                 :: Reg          -- ^ source register
141                 -> Reg          -- ^ destination register
142                 -> instr
143
144         -- | Take the source and destination from this reg -> reg move instruction
145         --      or Nothing if it's not one
146         takeRegRegMoveInstr
147                 :: instr
148                 -> Maybe (Reg, Reg)
149                 
150         -- | Make an unconditional jump instruction.
151         --      For architectures with branch delay slots, its ok to put
152         --      a NOP after the jump. Don't fill the delay slot with an
153         --      instruction that references regs or you'll confuse the 
154         --      linear allocator.
155         mkJumpInstr     
156                 :: BlockId
157                 -> [instr]
158                 
159