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