5d2f481a15cf27b94cfa2114ef0658032c17311e
[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 Cmm
16
17 import Outputable
18
19
20 -- | Enforce intra-block invariants.
21 --
22 checkBlock
23         :: CmmBasicBlock -> NatBasicBlock Instr -> NatBasicBlock Instr
24
25 checkBlock cmm block@(BasicBlock _ instrs)
26         | checkBlockInstrs instrs
27         = block
28         
29         | otherwise
30         = pprPanic 
31                 ("SPARC.CodeGen: bad block\n")
32                 ( vcat  [ text " -- cmm -----------------\n"
33                         , ppr cmm
34                         , text " -- native code ---------\n"
35                         , ppr block ])
36
37
38 checkBlockInstrs :: [Instr] -> Bool
39 checkBlockInstrs ii
40
41         -- An unconditional jumps end the block.
42         --      There must be an unconditional jump in the block, otherwise
43         --      the register liveness determinator will get the liveness
44         --      information wrong. 
45         --
46         --      If the block ends with a cmm call that never returns
47         --      then there can be unreachable instructions after the jump,
48         --      but we don't mind here.
49         --
50         | instr : NOP : _       <- ii 
51         , isUnconditionalJump instr
52         = True
53         
54         -- All jumps must have a NOP in their branch delay slot.
55         --      The liveness determinator and register allocators aren't smart
56         --      enough to handle branch delay slots.
57         --
58         | instr : NOP : is      <- ii
59         , isJumpishInstr instr
60         = checkBlockInstrs is
61
62         -- keep checking
63         | _:i2:is               <- ii
64         = checkBlockInstrs (i2:is)
65
66         -- this block is no good        
67         | otherwise
68         = False
69
70