Implement SSE2 floating-point support in the x86 native code generator (#594)
[ghc-hetmet.git] / compiler / nativeGen / SPARC / Regs.hs
1 -- -----------------------------------------------------------------------------
2 --
3 -- (c) The University of Glasgow 1994-2004
4 -- 
5 -- -----------------------------------------------------------------------------
6
7 module SPARC.Regs (
8         -- registers
9         showReg,
10         virtualRegSqueeze,
11         realRegSqueeze,
12         classOfRealReg,
13         allRealRegs,
14
15         -- machine specific info
16         gReg, iReg, lReg, oReg, fReg,
17         fp, sp, g0, g1, g2, o0, o1, f0, f1, f6, f8, f22, f26, f27,
18
19         -- allocatable
20         allocatableRegs,
21         get_GlobalReg_reg_or_addr,
22
23         -- args
24         argRegs, 
25         allArgRegs, 
26         callClobberedRegs,
27
28         -- 
29         mkVirtualReg,
30         regDotColor
31 )
32
33 where
34
35
36 import SPARC.RegPlate
37 import Reg
38 import RegClass
39 import Size
40
41 import Cmm
42 import PprCmm           ()
43 import CgUtils          ( get_GlobalReg_addr )
44
45 import Unique
46 import Outputable
47 import FastTypes
48 import FastBool
49
50 {-
51         The SPARC has 64 registers of interest; 32 integer registers and 32
52         floating point registers.  The mapping of STG registers to SPARC
53         machine registers is defined in StgRegs.h.  We are, of course,
54         prepared for any eventuality.
55
56         The whole fp-register pairing thing on sparcs is a huge nuisance.  See
57         includes/stg/MachRegs.h for a description of what's going on
58         here.
59 -}
60
61
62 -- | Get the standard name for the register with this number.
63 showReg :: RegNo -> String
64 showReg n
65         | n >= 0  && n < 8   = "%g" ++ show n
66         | n >= 8  && n < 16  = "%o" ++ show (n-8)
67         | n >= 16 && n < 24  = "%l" ++ show (n-16)
68         | n >= 24 && n < 32  = "%i" ++ show (n-24)
69         | n >= 32 && n < 64  = "%f" ++ show (n-32)
70         | otherwise          = panic "SPARC.Regs.showReg: unknown sparc register"
71
72
73 -- Get the register class of a certain real reg
74 classOfRealReg :: RealReg -> RegClass
75 classOfRealReg reg
76  = case reg of
77         RealRegSingle i
78                 | i < 32        -> RcInteger
79                 | otherwise     -> RcFloat
80                 
81         RealRegPair{}           -> RcDouble
82
83
84 -- | regSqueeze_class reg
85 --      Calculuate the maximum number of register colors that could be
86 --      denied to a node of this class due to having this reg 
87 --      as a neighbour.
88 --
89 {-# INLINE virtualRegSqueeze #-}
90 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
91
92 virtualRegSqueeze cls vr
93  = case cls of
94         RcInteger
95          -> case vr of
96                 VirtualRegI{}           -> _ILIT(1)
97                 VirtualRegHi{}          -> _ILIT(1)
98                 _other                  -> _ILIT(0)
99
100         RcFloat
101          -> case vr of
102                 VirtualRegF{}           -> _ILIT(1)
103                 VirtualRegD{}           -> _ILIT(2)
104                 _other                  -> _ILIT(0)
105
106         RcDouble
107          -> case vr of
108                 VirtualRegF{}           -> _ILIT(1)
109                 VirtualRegD{}           -> _ILIT(1)
110                 _other                  -> _ILIT(0)
111
112         _other -> _ILIT(0)
113
114 {-# INLINE realRegSqueeze #-}
115 realRegSqueeze :: RegClass -> RealReg -> FastInt
116
117 realRegSqueeze cls rr
118  = case cls of
119         RcInteger
120          -> case rr of
121                 RealRegSingle regNo
122                         | regNo < 32    -> _ILIT(1)
123                         | otherwise     -> _ILIT(0)
124                         
125                 RealRegPair{}           -> _ILIT(0)
126
127         RcFloat
128          -> case rr of
129                 RealRegSingle regNo
130                         | regNo < 32    -> _ILIT(0)
131                         | otherwise     -> _ILIT(1)
132                         
133                 RealRegPair{}           -> _ILIT(2)
134
135         RcDouble
136          -> case rr of
137                 RealRegSingle regNo
138                         | regNo < 32    -> _ILIT(0)
139                         | otherwise     -> _ILIT(1)
140                         
141                 RealRegPair{}           -> _ILIT(1)
142                                         
143         _other -> _ILIT(0)
144         
145 -- | All the allocatable registers in the machine, 
146 --      including register pairs.
147 allRealRegs :: [RealReg]
148 allRealRegs  
149         =  [ (RealRegSingle i)          | i <- [0..63] ]
150         ++ [ (RealRegPair   i (i+1))    | i <- [32, 34 .. 62 ] ]
151
152
153 -- | Get the regno for this sort of reg
154 gReg, lReg, iReg, oReg, fReg :: Int -> RegNo
155
156 gReg x  = x             -- global regs
157 oReg x  = (8 + x)       -- output regs
158 lReg x  = (16 + x)      -- local regs
159 iReg x  = (24 + x)      -- input regs
160 fReg x  = (32 + x)      -- float regs
161
162
163 -- | Some specific regs used by the code generator.
164 g0, g1, g2, fp, sp, o0, o1, f0, f1, f6, f8, f22, f26, f27 :: Reg
165
166 f6  = RegReal (RealRegSingle (fReg 6))
167 f8  = RegReal (RealRegSingle (fReg 8))
168 f22 = RegReal (RealRegSingle (fReg 22))
169 f26 = RegReal (RealRegSingle (fReg 26))
170 f27 = RegReal (RealRegSingle (fReg 27))
171
172 -- g0 is always zero, and writes to it vanish.
173 g0  = RegReal (RealRegSingle (gReg 0))
174 g1  = RegReal (RealRegSingle (gReg 1))
175 g2  = RegReal (RealRegSingle (gReg 2))
176
177 -- FP, SP, int and float return (from C) regs.
178 fp  = RegReal (RealRegSingle (iReg 6))
179 sp  = RegReal (RealRegSingle (oReg 6))
180 o0  = RegReal (RealRegSingle (oReg 0))
181 o1  = RegReal (RealRegSingle (oReg 1))
182 f0  = RegReal (RealRegSingle (fReg 0))
183 f1  = RegReal (RealRegSingle (fReg 1))
184
185 -- | Produce the second-half-of-a-double register given the first half.
186 {-
187 fPair :: Reg -> Maybe Reg
188 fPair (RealReg n) 
189         | n >= 32 && n `mod` 2 == 0  = Just (RealReg (n+1))
190
191 fPair (VirtualRegD u)
192         = Just (VirtualRegHi u)
193
194 fPair reg
195         = trace ("MachInstrs.fPair: can't get high half of supposed double reg " ++ showPpr reg)
196                 Nothing
197 -}
198
199
200 -- | All the regs that the register allocator can allocate to, 
201 --      with the the fixed use regs removed.
202 -- 
203 allocatableRegs :: [RealReg]
204 allocatableRegs
205    = let isFree rr 
206            = case rr of
207                 RealRegSingle r         
208                         -> isFastTrue (freeReg r)
209
210                 RealRegPair   r1 r2     
211                         -> isFastTrue (freeReg r1) 
212                         && isFastTrue (freeReg r2)
213
214      in filter isFree allRealRegs
215
216
217
218 -- We map STG registers onto appropriate CmmExprs.  Either they map
219 -- to real machine registers or stored as offsets from BaseReg.  Given
220 -- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real
221 -- register it is in, on this platform, or a CmmExpr denoting the
222 -- address in the register table holding it.
223 -- (See also get_GlobalReg_addr in CgUtils.)
224
225 get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr
226 get_GlobalReg_reg_or_addr mid
227    = case globalRegMaybe mid of
228         Just rr -> Left  rr
229         Nothing -> Right (get_GlobalReg_addr mid)
230
231
232 -- | The registers to place arguments for function calls, 
233 --      for some number of arguments.
234 --
235 argRegs :: RegNo -> [Reg]
236 argRegs r
237  = case r of
238         0       -> []
239         1       -> map (RegReal . RealRegSingle . oReg) [0]
240         2       -> map (RegReal . RealRegSingle . oReg) [0,1]
241         3       -> map (RegReal . RealRegSingle . oReg) [0,1,2]
242         4       -> map (RegReal . RealRegSingle . oReg) [0,1,2,3]
243         5       -> map (RegReal . RealRegSingle . oReg) [0,1,2,3,4]
244         6       -> map (RegReal . RealRegSingle . oReg) [0,1,2,3,4,5]
245         _       -> panic "MachRegs.argRegs(sparc): don't know about >6 arguments!"
246
247
248 -- | All all the regs that could possibly be returned by argRegs
249 --
250 allArgRegs :: [Reg]
251 allArgRegs 
252         = map (RegReal . RealRegSingle) [oReg i | i <- [0..5]]
253
254
255 -- These are the regs that we cannot assume stay alive over a C call.  
256 --      TODO: Why can we assume that o6 isn't clobbered? -- BL 2009/02
257 --
258 callClobberedRegs :: [Reg]
259 callClobberedRegs
260         = map (RegReal . RealRegSingle)
261                 (  oReg 7 :
262                   [oReg i | i <- [0..5]] ++
263                   [gReg i | i <- [1..7]] ++
264                   [fReg i | i <- [0..31]] )
265
266
267
268 -- | Make a virtual reg with this size.
269 mkVirtualReg :: Unique -> Size -> VirtualReg
270 mkVirtualReg u size
271         | not (isFloatSize size) 
272         = VirtualRegI u
273
274         | otherwise
275         = case size of
276                 FF32    -> VirtualRegF u
277                 FF64    -> VirtualRegD u
278                 _       -> panic "mkVReg"
279
280
281 regDotColor :: RealReg -> SDoc
282 regDotColor reg
283  = case classOfRealReg reg of
284         RcInteger       -> text "blue"
285         RcFloat         -> text "red"
286         _other          -> text "green"
287
288
289
290
291 -- Hard coded freeReg / globalRegMaybe -----------------------------------------
292 -- This isn't being used at the moment because we're generating
293 --      these functions from the information in
294 --      includes/stg/MachRegs.hs via RegPlate.hs
295         
296 -- | Check whether a machine register is free for allocation.
297 --      This needs to match the info in includes/stg/MachRegs.h
298 --      otherwise modules compiled with the NCG won't be compatible
299 --      with via-C ones.
300 --
301 {-
302 freeReg :: RegNo -> FastBool
303 freeReg regno
304  = case regno of
305         -- %g0(r0) is always 0.
306         0       -> fastBool False       
307
308         -- %g1(r1) - %g4(r4) are allocable -----------------
309
310         -- %g5(r5) - %g7(r7) 
311         --      are reserved for the OS
312         5       -> fastBool False
313         6       -> fastBool False
314         7       -> fastBool False
315
316         -- %o0(r8) - %o5(r13) are allocable ----------------
317
318         -- %o6(r14) 
319         --      is the C stack pointer
320         14      -> fastBool False
321
322         -- %o7(r15) 
323         --      holds C return addresses (???)
324         15      -> fastBool False
325
326         -- %l0(r16) is allocable ---------------------------
327
328         -- %l1(r17) - %l5(r21) 
329         --      are STG regs R1 - R5
330         17      -> fastBool False
331         18      -> fastBool False
332         19      -> fastBool False
333         20      -> fastBool False
334         21      -> fastBool False
335         
336         -- %l6(r22) - %l7(r23) are allocable --------------
337         
338         -- %i0(r24) - %i5(r29)
339         --      are STG regs Sp, Base, SpLim, Hp, R6
340         24      -> fastBool False
341         25      -> fastBool False
342         26      -> fastBool False
343         27      -> fastBool False
344
345         -- %i5(r28) is allocable --------------------------
346
347         29      -> fastBool False
348         
349         -- %i6(r30) 
350         --      is the C frame pointer
351         30      -> fastBool False
352
353         -- %i7(r31) 
354         --      is used for C return addresses
355         31      -> fastBool False
356         
357         -- %f0(r32) - %f1(r33)
358         --      are C fp return registers
359         32      -> fastBool False
360         33      -> fastBool False
361
362         -- %f2(r34) - %f5(r37)
363         --      are STG regs D1 - D2
364         34      -> fastBool False
365         35      -> fastBool False
366         36      -> fastBool False
367         37      -> fastBool False
368
369         -- %f22(r54) - %f25(r57)
370         --      are STG regs F1 - F4
371         54      -> fastBool False
372         55      -> fastBool False
373         56      -> fastBool False
374         57      -> fastBool False
375
376         -- regs not matched above are allocable.
377         _       -> fastBool True
378
379 -}
380
381 -- | Returns Just the real register that a global register is stored in.
382 --      Returns Nothing if the global has no real register, and is stored
383 --      in the in-memory register table instead.
384 --
385 {-
386 globalRegMaybe  :: GlobalReg -> Maybe Reg
387 globalRegMaybe gg
388  = case gg of
389         -- Argument and return regs
390         VanillaReg 1 _  -> Just (RealReg 17)    -- %l1
391         VanillaReg 2 _  -> Just (RealReg 18)    -- %l2
392         VanillaReg 3 _  -> Just (RealReg 19)    -- %l3
393         VanillaReg 4 _  -> Just (RealReg 20)    -- %l4
394         VanillaReg 5 _  -> Just (RealReg 21)    -- %l5
395         VanillaReg 6 _  -> Just (RealReg 29)    -- %i5
396
397         FloatReg 1      -> Just (RealReg 54)    -- %f22
398         FloatReg 2      -> Just (RealReg 55)    -- %f23
399         FloatReg 3      -> Just (RealReg 56)    -- %f24
400         FloatReg 4      -> Just (RealReg 57)    -- %f25
401
402         DoubleReg 1     -> Just (RealReg 34)    -- %f2
403         DoubleReg 2     -> Just (RealReg 36)    -- %f4
404
405         -- STG Regs
406         Sp              -> Just (RealReg 24)    -- %i0
407         SpLim           -> Just (RealReg 26)    -- %i2
408         Hp              -> Just (RealReg 27)    -- %i3
409
410         BaseReg         -> Just (RealReg 25)    -- %i1
411                 
412         _               -> Nothing      
413 -}