58d063bd88e71361b3aa4585a5b6bcd140c43c16
[ghc-hetmet.git] / compiler / nativeGen / X86 / RegInfo.hs
1
2 module X86.RegInfo (
3         mkVReg,
4
5         JumpDest, 
6         canShortcut, 
7         shortcutJump, 
8
9         spillSlotSize,
10         maxSpillSlots,
11         spillSlotToOffset,
12         
13         shortcutStatic,
14         regDotColor
15 )
16
17 where
18
19 #include "nativeGen/NCG.h"
20 #include "HsVersions.h"
21
22 import X86.Instr
23 import X86.Cond
24 import X86.Regs
25 import Size
26 import Reg
27
28 import Cmm
29 import CLabel
30 import BlockId
31 import Outputable
32 import Constants        ( rESERVED_C_STACK_BYTES )
33 import Unique
34
35 mkVReg :: Unique -> Size -> Reg
36 mkVReg u size
37    | not (isFloatSize size) = VirtualRegI u
38    | otherwise
39    = case size of
40         FF32    -> VirtualRegD u
41         FF64    -> VirtualRegD u
42         _       -> panic "mkVReg"
43
44
45 data JumpDest = DestBlockId BlockId | DestImm Imm
46
47
48 canShortcut :: Instr -> Maybe JumpDest
49 canShortcut (JXX ALWAYS id)     = Just (DestBlockId id)
50 canShortcut (JMP (OpImm imm))   = Just (DestImm imm)
51 canShortcut _                   = Nothing
52
53
54 shortcutJump :: (BlockId -> Maybe JumpDest) -> Instr -> Instr
55 shortcutJump fn insn@(JXX cc id) = 
56   case fn id of
57     Nothing                -> insn
58     Just (DestBlockId id') -> shortcutJump fn (JXX cc id')
59     Just (DestImm imm)     -> shortcutJump fn (JXX_GBL cc imm)
60
61 shortcutJump _ other = other
62
63
64
65 spillSlotSize :: Int
66 spillSlotSize = IF_ARCH_i386(12, 8)
67
68 maxSpillSlots :: Int
69 maxSpillSlots = ((rESERVED_C_STACK_BYTES - 64) `div` spillSlotSize) - 1
70
71 -- convert a spill slot number to a *byte* offset, with no sign:
72 -- decide on a per arch basis whether you are spilling above or below
73 -- the C stack pointer.
74 spillSlotToOffset :: Int -> Int
75 spillSlotToOffset slot
76    | slot >= 0 && slot < maxSpillSlots
77    = 64 + spillSlotSize * slot
78    | otherwise
79    = pprPanic "spillSlotToOffset:" 
80               (   text "invalid spill location: " <> int slot
81               $$  text "maxSpillSlots:          " <> int maxSpillSlots)
82
83
84 -- Here because it knows about JumpDest
85 shortcutStatic :: (BlockId -> Maybe JumpDest) -> CmmStatic -> CmmStatic
86 shortcutStatic fn (CmmStaticLit (CmmLabel lab))
87   | Just uq <- maybeAsmTemp lab 
88   = CmmStaticLit (CmmLabel (shortBlockId fn (BlockId uq)))
89 shortcutStatic fn (CmmStaticLit (CmmLabelDiffOff lbl1 lbl2 off))
90   | Just uq <- maybeAsmTemp lbl1
91   = CmmStaticLit (CmmLabelDiffOff (shortBlockId fn (BlockId uq)) lbl2 off)
92         -- slightly dodgy, we're ignoring the second label, but this
93         -- works with the way we use CmmLabelDiffOff for jump tables now.
94
95 shortcutStatic _ other_static
96         = other_static
97
98 shortBlockId 
99         :: (BlockId -> Maybe JumpDest)
100         -> BlockId
101         -> CLabel
102
103 shortBlockId fn blockid@(BlockId uq) =
104    case fn blockid of
105       Nothing -> mkAsmTempLabel uq
106       Just (DestBlockId blockid')  -> shortBlockId fn blockid'
107       Just (DestImm (ImmCLbl lbl)) -> lbl
108       _other -> panic "shortBlockId"
109
110
111
112 -- reg colors for x86
113 #if i386_TARGET_ARCH
114 regDotColor :: Reg -> SDoc
115 regDotColor reg
116  = let  Just    str     = lookupUFM regColors reg
117    in   text str
118
119 regColors
120  = listToUFM
121  $      [ (eax, "#00ff00")
122         , (ebx, "#0000ff")
123         , (ecx, "#00ffff")
124         , (edx, "#0080ff")
125
126         , (fake0, "#ff00ff")
127         , (fake1, "#ff00aa")
128         , (fake2, "#aa00ff")
129         , (fake3, "#aa00aa")
130         , (fake4, "#ff0055")
131         , (fake5, "#5500ff") ]
132
133
134 -- reg colors for x86_64
135 #elif x86_64_TARGET_ARCH
136 regDotColor :: Reg -> SDoc
137 regDotColor reg
138  = let  Just    str     = lookupUFM regColors reg
139    in   text str
140
141 regColors
142  = listToUFM
143  $      [ (rax, "#00ff00"), (eax, "#00ff00")
144         , (rbx, "#0000ff"), (ebx, "#0000ff")
145         , (rcx, "#00ffff"), (ecx, "#00ffff")
146         , (rdx, "#0080ff"), (edx, "#00ffff")
147         , (r8,  "#00ff80")
148         , (r9,  "#008080")
149         , (r10, "#0040ff")
150         , (r11, "#00ff40")
151         , (r12, "#008040")
152         , (r13, "#004080")
153         , (r14, "#004040")
154         , (r15, "#002080") ]
155
156         ++ zip (map RealReg [16..31]) (repeat "red")
157 #else
158 regDotColor :: Reg -> SDoc
159 regDotColor     = panic "not defined"
160 #endif