fix haddock submodule pointer
[ghc-hetmet.git] / compiler / nativeGen / SPARC / CodeGen / Sanity.hs
1
2 -- | One ounce of sanity checking is worth 10000000000000000 ounces 
3 --      of staring blindly at assembly code trying to find the problem..
4 --
5 module SPARC.CodeGen.Sanity (
6         checkBlock
7 )
8
9 where
10
11 import SPARC.Instr
12 import SPARC.Ppr        ()
13 import Instruction
14
15 import OldCmm
16
17 import Outputable
18
19
20 -- | Enforce intra-block invariants.
21 --
22 checkBlock
23         :: CmmBasicBlock 
24         -> NatBasicBlock Instr -> NatBasicBlock Instr
25
26 checkBlock cmm block@(BasicBlock _ instrs)
27         | checkBlockInstrs instrs
28         = block
29         
30         | otherwise
31         = pprPanic 
32                 ("SPARC.CodeGen: bad block\n")
33                 ( vcat  [ text " -- cmm -----------------\n"
34                         , ppr cmm
35                         , text " -- native code ---------\n"
36                         , ppr block ])
37
38
39 checkBlockInstrs :: [Instr] -> Bool
40 checkBlockInstrs ii
41
42         -- An unconditional jumps end the block.
43         --      There must be an unconditional jump in the block, otherwise
44         --      the register liveness determinator will get the liveness
45         --      information wrong. 
46         --
47         --      If the block ends with a cmm call that never returns
48         --      then there can be unreachable instructions after the jump,
49         --      but we don't mind here.
50         --
51         | instr : NOP : _       <- ii 
52         , isUnconditionalJump instr
53         = True
54         
55         -- All jumps must have a NOP in their branch delay slot.
56         --      The liveness determinator and register allocators aren't smart
57         --      enough to handle branch delay slots.
58         --
59         | instr : NOP : is      <- ii
60         , isJumpishInstr instr
61         = checkBlockInstrs is
62
63         -- keep checking
64         | _:i2:is               <- ii
65         = checkBlockInstrs (i2:is)
66
67         -- this block is no good        
68         | otherwise
69         = False
70
71