8f8a977ac7eb820b03a4900b399f0a532a65c3e5
[ghc-hetmet.git] / compiler / nativeGen / SPARC / RegInfo.hs
1
2 -----------------------------------------------------------------------------
3 --
4 -- Machine-specific parts of the register allocator
5 --
6 -- (c) The University of Glasgow 1996-2004
7 --
8 -----------------------------------------------------------------------------
9
10 module SPARC.RegInfo (
11         -- machine specific 
12         RegUsage(..),
13         noUsage,
14         regUsage,
15         patchRegs,
16         jumpDests,
17         isJumpish,
18         patchJump,
19         isRegRegMove,
20
21         JumpDest(..), 
22         canShortcut, 
23         shortcutJump, 
24
25         mkSpillInstr,
26         mkLoadInstr,
27         mkRegRegMoveInstr,
28         mkBranchInstr,
29         
30         spillSlotSize,
31         maxSpillSlots,
32         spillSlotToOffset               
33 )
34
35 where
36
37 #include "nativeGen/NCG.h"
38 #include "HsVersions.h"
39
40 import SPARC.Instr
41 import SPARC.Regs
42 import RegsBase
43
44 import BlockId
45 import Outputable
46 import Constants        ( rESERVED_C_STACK_BYTES )
47 import FastBool
48
49
50 -- | Represents what regs are read and written to in an instruction.
51 --      
52 data RegUsage 
53         = RU    [Reg]   -- regs read from
54                 [Reg]   -- regs written to
55
56
57 -- | No regs read or written to.
58 noUsage :: RegUsage
59 noUsage  = RU [] []
60
61
62 -- | regUsage returns the sets of src and destination registers used
63 --      by a particular instruction.  Machine registers that are
64 --      pre-allocated to stgRegs are filtered out, because they are
65 --      uninteresting from a register allocation standpoint.  (We wouldn't
66 --      want them to end up on the free list!)  As far as we are concerned,
67 --      the fixed registers simply don't exist (for allocation purposes,
68 --      anyway).
69
70 --      regUsage doesn't need to do any trickery for jumps and such.  Just
71 --      state precisely the regs read and written by that insn.  The
72 --      consequences of control flow transfers, as far as register
73 --      allocation goes, are taken care of by the register allocator.
74 --
75 regUsage :: Instr -> RegUsage
76 regUsage instr 
77  = case instr of
78     SPILL  reg _                -> usage ([reg], [])
79     RELOAD _   reg              -> usage ([], [reg])
80
81     LD    _ addr reg            -> usage (regAddr addr,         [reg])
82     ST    _ reg addr            -> usage (reg : regAddr addr,   [])
83     ADD   _ _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
84     SUB   _ _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
85     UMUL    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
86     SMUL    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
87     UDIV    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
88     SDIV    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
89     RDY       rd                -> usage ([],                   [rd])
90     WRY       r1 r2             -> usage ([r1, r2],             [])
91     AND     _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
92     ANDN    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
93     OR      _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
94     ORN     _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
95     XOR     _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
96     XNOR    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
97     SLL       r1 ar r2          -> usage (r1 : regRI ar,        [r2])
98     SRL       r1 ar r2          -> usage (r1 : regRI ar,        [r2])
99     SRA       r1 ar r2          -> usage (r1 : regRI ar,        [r2])
100     SETHI   _ reg               -> usage ([],                   [reg])
101     FABS    _ r1 r2             -> usage ([r1],                 [r2])
102     FADD    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
103     FCMP    _ _  r1 r2          -> usage ([r1, r2],             [])
104     FDIV    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
105     FMOV    _ r1 r2             -> usage ([r1],                 [r2])
106     FMUL    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
107     FNEG    _ r1 r2             -> usage ([r1],                 [r2])
108     FSQRT   _ r1 r2             -> usage ([r1],                 [r2])
109     FSUB    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
110     FxTOy   _ _  r1 r2          -> usage ([r1],                 [r2])
111
112     JMP     addr                -> usage (regAddr addr, [])
113     JMP_TBL addr _              -> usage (regAddr addr, [])
114
115     CALL  (Left _  )  _ True    -> noUsage
116     CALL  (Left _  )  n False   -> usage (argRegs n, callClobberedRegs)
117     CALL  (Right reg) _ True    -> usage ([reg], [])
118     CALL  (Right reg) n False   -> usage (reg : (argRegs n), callClobberedRegs)
119     _                           -> noUsage
120
121   where
122     usage (src, dst) 
123      = RU (filter interesting src) (filter interesting dst)
124
125     regAddr (AddrRegReg r1 r2)  = [r1, r2]
126     regAddr (AddrRegImm r1 _)   = [r1]
127
128     regRI (RIReg r)             = [r]
129     regRI  _                    = []
130
131
132 -- | Interesting regs are virtuals, or ones that are allocatable 
133 --      by the register allocator.
134 interesting :: Reg -> Bool
135 interesting reg
136  = case reg of
137         VirtualRegI  _  -> True
138         VirtualRegHi _  -> True
139         VirtualRegF  _  -> True
140         VirtualRegD  _  -> True
141         RealReg i       -> isFastTrue (freeReg i)
142
143
144
145 -- | Apply a given mapping to tall the register references in this instruction.
146
147 patchRegs :: Instr -> (Reg -> Reg) -> Instr
148 patchRegs instr env = case instr of
149     SPILL reg slot              -> SPILL  (env reg) slot
150     RELOAD slot reg             -> RELOAD slot (env reg)
151
152     LD    sz addr reg           -> LD sz (fixAddr addr) (env reg)
153     ST    sz reg addr           -> ST sz (env reg) (fixAddr addr)
154
155     ADD   x cc r1 ar r2         -> ADD   x cc  (env r1) (fixRI ar) (env r2)
156     SUB   x cc r1 ar r2         -> SUB   x cc  (env r1) (fixRI ar) (env r2)
157     UMUL    cc r1 ar r2         -> UMUL    cc  (env r1) (fixRI ar) (env r2)
158     SMUL    cc r1 ar r2         -> SMUL    cc  (env r1) (fixRI ar) (env r2)
159     UDIV    cc r1 ar r2         -> UDIV    cc  (env r1) (fixRI ar) (env r2)
160     SDIV    cc r1 ar r2         -> SDIV    cc  (env r1) (fixRI ar) (env r2)
161     RDY   rd                    -> RDY         (env rd)
162     WRY   r1 r2                 -> WRY         (env r1) (env r2)
163     AND   b r1 ar r2            -> AND   b     (env r1) (fixRI ar) (env r2)
164     ANDN  b r1 ar r2            -> ANDN  b     (env r1) (fixRI ar) (env r2)
165     OR    b r1 ar r2            -> OR    b     (env r1) (fixRI ar) (env r2)
166     ORN   b r1 ar r2            -> ORN   b     (env r1) (fixRI ar) (env r2)
167     XOR   b r1 ar r2            -> XOR   b     (env r1) (fixRI ar) (env r2)
168     XNOR  b r1 ar r2            -> XNOR  b     (env r1) (fixRI ar) (env r2)
169     SLL   r1 ar r2              -> SLL         (env r1) (fixRI ar) (env r2)
170     SRL   r1 ar r2              -> SRL         (env r1) (fixRI ar) (env r2)
171     SRA   r1 ar r2              -> SRA         (env r1) (fixRI ar) (env r2)
172
173     SETHI imm reg               -> SETHI imm (env reg)
174
175     FABS  s r1 r2               -> FABS    s   (env r1) (env r2)
176     FADD  s r1 r2 r3            -> FADD    s   (env r1) (env r2) (env r3)
177     FCMP  e s r1 r2             -> FCMP e  s   (env r1) (env r2)
178     FDIV  s r1 r2 r3            -> FDIV    s   (env r1) (env r2) (env r3)
179     FMOV  s r1 r2               -> FMOV    s   (env r1) (env r2)
180     FMUL  s r1 r2 r3            -> FMUL    s   (env r1) (env r2) (env r3)
181     FNEG  s r1 r2               -> FNEG    s   (env r1) (env r2)
182     FSQRT s r1 r2               -> FSQRT   s   (env r1) (env r2)
183     FSUB  s r1 r2 r3            -> FSUB    s   (env r1) (env r2) (env r3)
184     FxTOy s1 s2 r1 r2           -> FxTOy s1 s2 (env r1) (env r2)
185
186     JMP     addr                -> JMP     (fixAddr addr)
187     JMP_TBL addr ids            -> JMP_TBL (fixAddr addr) ids
188
189     CALL  (Left i) n t          -> CALL (Left i) n t
190     CALL  (Right r) n t         -> CALL (Right (env r)) n t
191     _                           -> instr
192
193   where
194     fixAddr (AddrRegReg r1 r2)  = AddrRegReg   (env r1) (env r2)
195     fixAddr (AddrRegImm r1 i)   = AddrRegImm   (env r1) i
196
197     fixRI (RIReg r)             = RIReg (env r)
198     fixRI other                 = other
199
200
201 -- -----------------------------------------------------------------------------
202 -- Determine the possible destinations from the current instruction.
203
204 -- (we always assume that the next instruction is also a valid destination;
205 -- if this isn't the case then the jump should be at the end of the basic
206 -- block).
207
208 jumpDests :: Instr -> [BlockId] -> [BlockId]
209 jumpDests insn acc
210   = case insn of
211         BI   _ _ id     -> id : acc
212         BF   _ _ id     -> id : acc
213         JMP_TBL _ ids   -> ids ++ acc
214         _other          -> acc
215
216
217 -- | Check whether a particular instruction is a jump, branch or call instruction (jumpish)
218 --      We can't just use jumpDests above because the jump might take its arg,
219 --      so the instr won't contain a blockid.
220 --
221 isJumpish :: Instr -> Bool
222 isJumpish instr
223  = case instr of
224         BI{}            -> True
225         BF{}            -> True
226         JMP{}           -> True
227         JMP_TBL{}       -> True
228         CALL{}          -> True
229         _               -> False
230
231
232 -- | Change the destination of this jump instruction
233 --      Used in joinToTargets in the linear allocator, when emitting fixup code
234 --      for join points.
235 patchJump :: Instr -> BlockId -> BlockId -> Instr
236 patchJump insn old new
237   = case insn of
238         BI cc annul id
239          | id == old    -> BI cc annul new
240          
241         BF cc annul id
242          | id == old    -> BF cc annul new
243
244         _other          -> insn
245
246
247
248
249 data JumpDest = DestBlockId BlockId | DestImm Imm
250
251 canShortcut :: Instr -> Maybe JumpDest
252 canShortcut _ = Nothing
253
254 shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
255 shortcutJump _ other = other
256
257
258
259 -- | Make a spill instruction.
260 --      On SPARC we spill below frame pointer leaving 2 words/spill
261 mkSpillInstr
262         :: Reg          -- ^ register to spill
263         -> Int          -- ^ current stack delta
264         -> Int          -- ^ spill slot to use
265         -> Instr
266
267 mkSpillInstr reg _ slot
268  = let  off     = spillSlotToOffset slot
269         off_w   = 1 + (off `div` 4)
270         sz      = case regClass reg of
271                         RcInteger -> II32
272                         RcFloat   -> FF32
273                         RcDouble  -> FF64
274                 
275     in ST sz reg (fpRel (negate off_w))
276
277
278 -- | Make a spill reload instruction.
279 mkLoadInstr
280         :: Reg          -- ^ register to load
281         -> Int          -- ^ current stack delta
282         -> Int          -- ^ spill slot to use
283         -> Instr
284
285 mkLoadInstr reg _ slot
286   = let off     = spillSlotToOffset slot
287         off_w   = 1 + (off `div` 4)
288         sz      = case regClass reg of
289                         RcInteger -> II32
290                         RcFloat   -> FF32
291                         RcDouble  -> FF64
292
293         in LD sz (fpRel (- off_w)) reg
294
295
296 -- | Make a reg-reg move instruction.
297 --      On SPARC v8 there are no instructions to move directly between
298 --      floating point and integer regs. If we need to do that then we
299 --      have to go via memory.
300 --
301 mkRegRegMoveInstr
302         :: Reg
303         -> Reg
304         -> Instr
305
306 mkRegRegMoveInstr src dst
307  = case regClass src of
308         RcInteger -> ADD  False False src (RIReg g0) dst
309         RcDouble  -> FMOV FF64 src dst
310         RcFloat   -> FMOV FF32 src dst
311
312
313 -- | Check whether an instruction represents a reg-reg move.
314 --      The register allocator attempts to eliminate reg->reg moves whenever it can,
315 --      by assigning the src and dest temporaries to the same real register.
316 --
317 isRegRegMove :: Instr -> Maybe (Reg,Reg)
318 isRegRegMove instr
319  = case instr of
320         ADD False False src (RIReg src2) dst
321          | g0 == src2           -> Just (src, dst)
322
323         FMOV FF64 src dst       -> Just (src, dst)
324         FMOV FF32  src dst      -> Just (src, dst)
325         _                       -> Nothing
326
327
328 -- | Make an unconditional branch instruction.
329 mkBranchInstr
330         :: BlockId
331         -> [Instr]
332
333 mkBranchInstr id 
334  =       [BI ALWAYS False id
335         , NOP]                  -- fill the branch delay slot.
336
337
338 -- | TODO: Why do we need 8 bytes per slot?? -BL 2009/02
339 spillSlotSize :: Int
340 spillSlotSize = 8
341
342
343 -- | The maximum number of spill slots available on the C stack.
344 --      If we use up all of the slots, then we're screwed.
345 maxSpillSlots :: Int
346 maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
347
348
349 -- | Convert a spill slot number to a *byte* offset, with no sign.
350 --
351 spillSlotToOffset :: Int -> Int
352 spillSlotToOffset slot
353         | slot >= 0 && slot < maxSpillSlots
354         = 64 + spillSlotSize * slot
355
356         | otherwise
357         = pprPanic "spillSlotToOffset:" 
358                       (   text "invalid spill location: " <> int slot
359                       $$  text "maxSpillSlots:          " <> int maxSpillSlots)
360