SPARC NCG: Reorganise Reg and RegInfo
[ghc-hetmet.git] / compiler / nativeGen / SPARC / Instr.hs
1 -----------------------------------------------------------------------------
2 --
3 -- Machine-dependent assembly language
4 --
5 -- (c) The University of Glasgow 1993-2004
6 --
7 -----------------------------------------------------------------------------
8
9 #include "HsVersions.h"
10 #include "nativeGen/NCG.h"
11
12 module SPARC.Instr (
13         RI(..),
14         riZero,
15
16         fpRelEA,
17         moveSp,
18         
19         Instr(..),
20         maxSpillSlots
21 )
22
23 where
24
25 import SPARC.Stack
26 import SPARC.Imm
27 import SPARC.AddrMode
28 import SPARC.Cond
29 import SPARC.Regs
30 import SPARC.Base
31 import Instruction
32 import RegClass
33 import Reg
34 import Size
35
36 import BlockId
37 import Cmm
38 import FastString
39 import FastBool
40
41 import GHC.Exts
42
43
44 -- | Register or immediate
45 data RI 
46         = RIReg Reg
47         | RIImm Imm
48
49 -- | Check if a RI represents a zero value.
50 --      - a literal zero
51 --      - register %g0, which is always zero.
52 --
53 riZero :: RI -> Bool
54 riZero (RIImm (ImmInt 0))           = True
55 riZero (RIImm (ImmInteger 0))       = True
56 riZero (RIReg (RealReg 0))          = True
57 riZero _                            = False
58
59
60 -- | Calculate the effective address which would be used by the
61 --      corresponding fpRel sequence. 
62 fpRelEA :: Int -> Reg -> Instr
63 fpRelEA n dst
64    = ADD False False fp (RIImm (ImmInt (n * wordLength))) dst
65
66
67 -- | Code to shift the stack pointer by n words.
68 moveSp :: Int -> Instr
69 moveSp n
70    = ADD False False sp (RIImm (ImmInt (n * wordLength))) sp
71
72
73 -- | instance for sparc instruction set
74 instance Instruction Instr where
75         regUsageOfInstr         = sparc_regUsageOfInstr
76         patchRegsOfInstr        = sparc_patchRegsOfInstr
77         isJumpishInstr          = sparc_isJumpishInstr
78         jumpDestsOfInstr        = sparc_jumpDestsOfInstr
79         patchJumpInstr          = sparc_patchJumpInstr
80         mkSpillInstr            = sparc_mkSpillInstr
81         mkLoadInstr             = sparc_mkLoadInstr
82         takeDeltaInstr          = sparc_takeDeltaInstr
83         isMetaInstr             = sparc_isMetaInstr
84         mkRegRegMoveInstr       = sparc_mkRegRegMoveInstr
85         takeRegRegMoveInstr     = sparc_takeRegRegMoveInstr
86         mkJumpInstr             = sparc_mkJumpInstr
87
88
89 -- | SPARC instruction set.
90 --      Not complete. This is only the ones we need.
91 --
92 data Instr
93
94         -- meta ops --------------------------------------------------
95         -- comment pseudo-op
96         = COMMENT FastString            
97
98         -- some static data spat out during code generation.
99         -- Will be extracted before pretty-printing.
100         | LDATA   Section [CmmStatic]   
101
102         -- Start a new basic block.  Useful during codegen, removed later.
103         -- Preceding instruction should be a jump, as per the invariants
104         -- for a BasicBlock (see Cmm).
105         | NEWBLOCK BlockId              
106
107         -- specify current stack offset for benefit of subsequent passes.
108         | DELTA   Int
109
110         -- real instrs -----------------------------------------------
111         -- Loads and stores.
112         | LD            Size AddrMode Reg               -- size, src, dst
113         | ST            Size Reg AddrMode               -- size, src, dst
114
115         -- Int Arithmetic.
116         | ADD           Bool Bool Reg RI Reg            -- x?, cc?, src1, src2, dst
117         | SUB           Bool Bool Reg RI Reg            -- x?, cc?, src1, src2, dst
118
119         | UMUL          Bool Reg RI Reg                 --     cc?, src1, src2, dst
120         | SMUL          Bool Reg RI Reg                 --     cc?, src1, src2, dst
121
122
123         -- The SPARC divide instructions perform 64bit by 32bit division
124         --   The Y register is xored into the first operand.
125
126         --   On _some implementations_ the Y register is overwritten by
127         --   the remainder, so we have to make sure it is 0 each time.
128
129         --   dst <- ((Y `shiftL` 32) `or` src1) `div` src2
130         | UDIV          Bool Reg RI Reg                 --     cc?, src1, src2, dst
131         | SDIV          Bool Reg RI Reg                 --     cc?, src1, src2, dst
132
133         | RDY           Reg                             -- move contents of Y register to reg
134         | WRY           Reg  Reg                        -- Y <- src1 `xor` src2
135         
136         -- Logic operations.
137         | AND           Bool Reg RI Reg                 -- cc?, src1, src2, dst
138         | ANDN          Bool Reg RI Reg                 -- cc?, src1, src2, dst
139         | OR            Bool Reg RI Reg                 -- cc?, src1, src2, dst
140         | ORN           Bool Reg RI Reg                 -- cc?, src1, src2, dst
141         | XOR           Bool Reg RI Reg                 -- cc?, src1, src2, dst
142         | XNOR          Bool Reg RI Reg                 -- cc?, src1, src2, dst
143         | SLL           Reg RI Reg                      -- src1, src2, dst
144         | SRL           Reg RI Reg                      -- src1, src2, dst
145         | SRA           Reg RI Reg                      -- src1, src2, dst
146
147         -- Load immediates.
148         | SETHI         Imm Reg                         -- src, dst
149
150         -- Do nothing.
151         -- Implemented by the assembler as SETHI 0, %g0, but worth an alias
152         | NOP                                           
153
154         -- Float Arithmetic.
155         -- Note that we cheat by treating F{ABS,MOV,NEG} of doubles as single
156         -- instructions right up until we spit them out.
157         --
158         | FABS          Size Reg Reg                    -- src dst
159         | FADD          Size Reg Reg Reg                -- src1, src2, dst
160         | FCMP          Bool Size Reg Reg               -- exception?, src1, src2, dst
161         | FDIV          Size Reg Reg Reg                -- src1, src2, dst
162         | FMOV          Size Reg Reg                    -- src, dst
163         | FMUL          Size Reg Reg Reg                -- src1, src2, dst
164         | FNEG          Size Reg Reg                    -- src, dst
165         | FSQRT         Size Reg Reg                    -- src, dst
166         | FSUB          Size Reg Reg Reg                -- src1, src2, dst
167         | FxTOy         Size Size Reg Reg               -- src, dst
168
169         -- Jumping around.
170         | BI            Cond Bool BlockId               -- cond, annul?, target
171         | BF            Cond Bool BlockId               -- cond, annul?, target
172
173         | JMP           AddrMode                        -- target
174
175         -- With a tabled jump we know all the possible destinations.
176         -- We also need this info so we can work out what regs are live across the jump.
177         -- 
178         | JMP_TBL       AddrMode [BlockId]
179
180         | CALL          (Either Imm Reg) Int Bool       -- target, args, terminal
181
182
183 -- | regUsage returns the sets of src and destination registers used
184 --      by a particular instruction.  Machine registers that are
185 --      pre-allocated to stgRegs are filtered out, because they are
186 --      uninteresting from a register allocation standpoint.  (We wouldn't
187 --      want them to end up on the free list!)  As far as we are concerned,
188 --      the fixed registers simply don't exist (for allocation purposes,
189 --      anyway).
190
191 --      regUsage doesn't need to do any trickery for jumps and such.  Just
192 --      state precisely the regs read and written by that insn.  The
193 --      consequences of control flow transfers, as far as register
194 --      allocation goes, are taken care of by the register allocator.
195 --
196 sparc_regUsageOfInstr :: Instr -> RegUsage
197 sparc_regUsageOfInstr instr 
198  = case instr of
199     LD    _ addr reg            -> usage (regAddr addr,         [reg])
200     ST    _ reg addr            -> usage (reg : regAddr addr,   [])
201     ADD   _ _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
202     SUB   _ _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
203     UMUL    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
204     SMUL    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
205     UDIV    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
206     SDIV    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
207     RDY       rd                -> usage ([],                   [rd])
208     WRY       r1 r2             -> usage ([r1, r2],             [])
209     AND     _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
210     ANDN    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
211     OR      _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
212     ORN     _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
213     XOR     _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
214     XNOR    _ r1 ar r2          -> usage (r1 : regRI ar,        [r2])
215     SLL       r1 ar r2          -> usage (r1 : regRI ar,        [r2])
216     SRL       r1 ar r2          -> usage (r1 : regRI ar,        [r2])
217     SRA       r1 ar r2          -> usage (r1 : regRI ar,        [r2])
218     SETHI   _ reg               -> usage ([],                   [reg])
219     FABS    _ r1 r2             -> usage ([r1],                 [r2])
220     FADD    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
221     FCMP    _ _  r1 r2          -> usage ([r1, r2],             [])
222     FDIV    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
223     FMOV    _ r1 r2             -> usage ([r1],                 [r2])
224     FMUL    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
225     FNEG    _ r1 r2             -> usage ([r1],                 [r2])
226     FSQRT   _ r1 r2             -> usage ([r1],                 [r2])
227     FSUB    _ r1 r2 r3          -> usage ([r1, r2],             [r3])
228     FxTOy   _ _  r1 r2          -> usage ([r1],                 [r2])
229
230     JMP     addr                -> usage (regAddr addr, [])
231     JMP_TBL addr _              -> usage (regAddr addr, [])
232
233     CALL  (Left _  )  _ True    -> noUsage
234     CALL  (Left _  )  n False   -> usage (argRegs n, callClobberedRegs)
235     CALL  (Right reg) _ True    -> usage ([reg], [])
236     CALL  (Right reg) n False   -> usage (reg : (argRegs n), callClobberedRegs)
237     _                           -> noUsage
238
239   where
240     usage (src, dst) 
241      = RU (filter interesting src) (filter interesting dst)
242
243     regAddr (AddrRegReg r1 r2)  = [r1, r2]
244     regAddr (AddrRegImm r1 _)   = [r1]
245
246     regRI (RIReg r)             = [r]
247     regRI  _                    = []
248
249
250 -- | Interesting regs are virtuals, or ones that are allocatable 
251 --      by the register allocator.
252 interesting :: Reg -> Bool
253 interesting reg
254  = case reg of
255         VirtualRegI  _  -> True
256         VirtualRegHi _  -> True
257         VirtualRegF  _  -> True
258         VirtualRegD  _  -> True
259         RealReg i       -> isFastTrue (freeReg i)
260
261
262
263 -- | Apply a given mapping to tall the register references in this instruction.
264 sparc_patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
265 sparc_patchRegsOfInstr instr env = case instr of
266     LD    sz addr reg           -> LD sz (fixAddr addr) (env reg)
267     ST    sz reg addr           -> ST sz (env reg) (fixAddr addr)
268
269     ADD   x cc r1 ar r2         -> ADD   x cc  (env r1) (fixRI ar) (env r2)
270     SUB   x cc r1 ar r2         -> SUB   x cc  (env r1) (fixRI ar) (env r2)
271     UMUL    cc r1 ar r2         -> UMUL    cc  (env r1) (fixRI ar) (env r2)
272     SMUL    cc r1 ar r2         -> SMUL    cc  (env r1) (fixRI ar) (env r2)
273     UDIV    cc r1 ar r2         -> UDIV    cc  (env r1) (fixRI ar) (env r2)
274     SDIV    cc r1 ar r2         -> SDIV    cc  (env r1) (fixRI ar) (env r2)
275     RDY   rd                    -> RDY         (env rd)
276     WRY   r1 r2                 -> WRY         (env r1) (env r2)
277     AND   b r1 ar r2            -> AND   b     (env r1) (fixRI ar) (env r2)
278     ANDN  b r1 ar r2            -> ANDN  b     (env r1) (fixRI ar) (env r2)
279     OR    b r1 ar r2            -> OR    b     (env r1) (fixRI ar) (env r2)
280     ORN   b r1 ar r2            -> ORN   b     (env r1) (fixRI ar) (env r2)
281     XOR   b r1 ar r2            -> XOR   b     (env r1) (fixRI ar) (env r2)
282     XNOR  b r1 ar r2            -> XNOR  b     (env r1) (fixRI ar) (env r2)
283     SLL   r1 ar r2              -> SLL         (env r1) (fixRI ar) (env r2)
284     SRL   r1 ar r2              -> SRL         (env r1) (fixRI ar) (env r2)
285     SRA   r1 ar r2              -> SRA         (env r1) (fixRI ar) (env r2)
286
287     SETHI imm reg               -> SETHI imm (env reg)
288
289     FABS  s r1 r2               -> FABS    s   (env r1) (env r2)
290     FADD  s r1 r2 r3            -> FADD    s   (env r1) (env r2) (env r3)
291     FCMP  e s r1 r2             -> FCMP e  s   (env r1) (env r2)
292     FDIV  s r1 r2 r3            -> FDIV    s   (env r1) (env r2) (env r3)
293     FMOV  s r1 r2               -> FMOV    s   (env r1) (env r2)
294     FMUL  s r1 r2 r3            -> FMUL    s   (env r1) (env r2) (env r3)
295     FNEG  s r1 r2               -> FNEG    s   (env r1) (env r2)
296     FSQRT s r1 r2               -> FSQRT   s   (env r1) (env r2)
297     FSUB  s r1 r2 r3            -> FSUB    s   (env r1) (env r2) (env r3)
298     FxTOy s1 s2 r1 r2           -> FxTOy s1 s2 (env r1) (env r2)
299
300     JMP     addr                -> JMP     (fixAddr addr)
301     JMP_TBL addr ids            -> JMP_TBL (fixAddr addr) ids
302
303     CALL  (Left i) n t          -> CALL (Left i) n t
304     CALL  (Right r) n t         -> CALL (Right (env r)) n t
305     _                           -> instr
306
307   where
308     fixAddr (AddrRegReg r1 r2)  = AddrRegReg   (env r1) (env r2)
309     fixAddr (AddrRegImm r1 i)   = AddrRegImm   (env r1) i
310
311     fixRI (RIReg r)             = RIReg (env r)
312     fixRI other                 = other
313
314
315 --------------------------------------------------------------------------------
316 sparc_isJumpishInstr :: Instr -> Bool
317 sparc_isJumpishInstr instr
318  = case instr of
319         BI{}            -> True
320         BF{}            -> True
321         JMP{}           -> True
322         JMP_TBL{}       -> True
323         CALL{}          -> True
324         _               -> False
325
326 sparc_jumpDestsOfInstr :: Instr -> [BlockId]
327 sparc_jumpDestsOfInstr insn
328   = case insn of
329         BI   _ _ id     -> [id]
330         BF   _ _ id     -> [id]
331         JMP_TBL _ ids   -> ids
332         _               -> []
333
334
335 sparc_patchJumpInstr :: Instr -> (BlockId -> BlockId) -> Instr
336 sparc_patchJumpInstr insn patchF
337   = case insn of
338         BI cc annul id  -> BI cc annul (patchF id)
339         BF cc annul id  -> BF cc annul (patchF id)
340         _               -> insn
341
342
343 --------------------------------------------------------------------------------
344 -- | Make a spill instruction.
345 --      On SPARC we spill below frame pointer leaving 2 words/spill
346 sparc_mkSpillInstr
347         :: Reg          -- ^ register to spill
348         -> Int          -- ^ current stack delta
349         -> Int          -- ^ spill slot to use
350         -> Instr
351
352 sparc_mkSpillInstr reg _ slot
353  = let  off     = spillSlotToOffset slot
354         off_w   = 1 + (off `div` 4)
355         sz      = case regClass reg of
356                         RcInteger -> II32
357                         RcFloat   -> FF32
358                         RcDouble  -> FF64
359                 
360     in ST sz reg (fpRel (negate off_w))
361
362
363 -- | Make a spill reload instruction.
364 sparc_mkLoadInstr
365         :: Reg          -- ^ register to load
366         -> Int          -- ^ current stack delta
367         -> Int          -- ^ spill slot to use
368         -> Instr
369
370 sparc_mkLoadInstr reg _ slot
371   = let off     = spillSlotToOffset slot
372         off_w   = 1 + (off `div` 4)
373         sz      = case regClass reg of
374                         RcInteger -> II32
375                         RcFloat   -> FF32
376                         RcDouble  -> FF64
377
378         in LD sz (fpRel (- off_w)) reg
379
380
381 --------------------------------------------------------------------------------
382 -- | See if this instruction is telling us the current C stack delta
383 sparc_takeDeltaInstr
384         :: Instr
385         -> Maybe Int
386         
387 sparc_takeDeltaInstr instr
388  = case instr of
389         DELTA i         -> Just i
390         _               -> Nothing
391
392
393 sparc_isMetaInstr
394         :: Instr
395         -> Bool
396         
397 sparc_isMetaInstr instr
398  = case instr of
399         COMMENT{}       -> True
400         LDATA{}         -> True
401         NEWBLOCK{}      -> True
402         DELTA{}         -> True
403         _               -> False
404         
405
406 -- | Make a reg-reg move instruction.
407 --      On SPARC v8 there are no instructions to move directly between
408 --      floating point and integer regs. If we need to do that then we
409 --      have to go via memory.
410 --
411 sparc_mkRegRegMoveInstr
412         :: Reg
413         -> Reg
414         -> Instr
415
416 sparc_mkRegRegMoveInstr src dst
417  = case regClass src of
418         RcInteger -> ADD  False False src (RIReg g0) dst
419         RcDouble  -> FMOV FF64 src dst
420         RcFloat   -> FMOV FF32 src dst
421
422
423 -- | Check whether an instruction represents a reg-reg move.
424 --      The register allocator attempts to eliminate reg->reg moves whenever it can,
425 --      by assigning the src and dest temporaries to the same real register.
426 --
427 sparc_takeRegRegMoveInstr :: Instr -> Maybe (Reg,Reg)
428 sparc_takeRegRegMoveInstr instr
429  = case instr of
430         ADD False False src (RIReg src2) dst
431          | g0 == src2           -> Just (src, dst)
432
433         FMOV FF64 src dst       -> Just (src, dst)
434         FMOV FF32  src dst      -> Just (src, dst)
435         _                       -> Nothing
436
437
438 -- | Make an unconditional branch instruction.
439 sparc_mkJumpInstr
440         :: BlockId
441         -> [Instr]
442
443 sparc_mkJumpInstr id 
444  =       [BI ALWAYS False id
445         , NOP]                  -- fill the branch delay slot.
446