Fix todo in compiler/nativeGen: Rename Size to Format
[ghc.git] / compiler / nativeGen / X86 / Regs.hs
1 {-# LANGUAGE CPP #-}
2
3 module X86.Regs (
4 -- squeese functions for the graph allocator
5 virtualRegSqueeze,
6 realRegSqueeze,
7
8 -- immediates
9 Imm(..),
10 strImmLit,
11 litToImm,
12
13 -- addressing modes
14 AddrMode(..),
15 addrOffset,
16
17 -- registers
18 spRel,
19 argRegs,
20 allArgRegs,
21 allIntArgRegs,
22 callClobberedRegs,
23 instrClobberedRegs,
24 allMachRegNos,
25 classOfRealReg,
26 showReg,
27
28 -- machine specific
29 EABase(..), EAIndex(..), addrModeRegs,
30
31 eax, ebx, ecx, edx, esi, edi, ebp, esp,
32 fake0, fake1, fake2, fake3, fake4, fake5, firstfake,
33
34 rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
35 r8, r9, r10, r11, r12, r13, r14, r15,
36 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
37 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
38 xmm,
39
40 ripRel,
41 allFPArgRegs,
42
43 allocatableRegs
44 )
45
46 where
47
48 #include "nativeGen/NCG.h"
49 #include "HsVersions.h"
50
51 import CodeGen.Platform
52 import Reg
53 import RegClass
54
55 import Cmm
56 import CLabel ( CLabel )
57 import DynFlags
58 import Outputable
59 import Platform
60 import FastTypes
61 import FastBool
62
63
64 -- | regSqueeze_class reg
65 -- Calculuate the maximum number of register colors that could be
66 -- denied to a node of this class due to having this reg
67 -- as a neighbour.
68 --
69 {-# INLINE virtualRegSqueeze #-}
70 virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt
71
72 virtualRegSqueeze cls vr
73 = case cls of
74 RcInteger
75 -> case vr of
76 VirtualRegI{} -> _ILIT(1)
77 VirtualRegHi{} -> _ILIT(1)
78 _other -> _ILIT(0)
79
80 RcDouble
81 -> case vr of
82 VirtualRegD{} -> _ILIT(1)
83 VirtualRegF{} -> _ILIT(0)
84 _other -> _ILIT(0)
85
86 RcDoubleSSE
87 -> case vr of
88 VirtualRegSSE{} -> _ILIT(1)
89 _other -> _ILIT(0)
90
91 _other -> _ILIT(0)
92
93 {-# INLINE realRegSqueeze #-}
94 realRegSqueeze :: RegClass -> RealReg -> FastInt
95 realRegSqueeze cls rr
96 = case cls of
97 RcInteger
98 -> case rr of
99 RealRegSingle regNo
100 | regNo < firstfake -> _ILIT(1)
101 | otherwise -> _ILIT(0)
102
103 RealRegPair{} -> _ILIT(0)
104
105 RcDouble
106 -> case rr of
107 RealRegSingle regNo
108 | regNo >= firstfake && regNo <= lastfake -> _ILIT(1)
109 | otherwise -> _ILIT(0)
110
111 RealRegPair{} -> _ILIT(0)
112
113 RcDoubleSSE
114 -> case rr of
115 RealRegSingle regNo | regNo >= firstxmm -> _ILIT(1)
116 _otherwise -> _ILIT(0)
117
118 _other -> _ILIT(0)
119
120 -- -----------------------------------------------------------------------------
121 -- Immediates
122
123 data Imm
124 = ImmInt Int
125 | ImmInteger Integer -- Sigh.
126 | ImmCLbl CLabel -- AbstractC Label (with baggage)
127 | ImmLit SDoc -- Simple string
128 | ImmIndex CLabel Int
129 | ImmFloat Rational
130 | ImmDouble Rational
131 | ImmConstantSum Imm Imm
132 | ImmConstantDiff Imm Imm
133
134
135 strImmLit :: String -> Imm
136 strImmLit s = ImmLit (text s)
137
138
139 litToImm :: CmmLit -> Imm
140 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
141 -- narrow to the width: a CmmInt might be out of
142 -- range, but we assume that ImmInteger only contains
143 -- in-range values. A signed value should be fine here.
144 litToImm (CmmFloat f W32) = ImmFloat f
145 litToImm (CmmFloat f W64) = ImmDouble f
146 litToImm (CmmLabel l) = ImmCLbl l
147 litToImm (CmmLabelOff l off) = ImmIndex l off
148 litToImm (CmmLabelDiffOff l1 l2 off)
149 = ImmConstantSum
150 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
151 (ImmInt off)
152 litToImm _ = panic "X86.Regs.litToImm: no match"
153
154 -- addressing modes ------------------------------------------------------------
155
156 data AddrMode
157 = AddrBaseIndex EABase EAIndex Displacement
158 | ImmAddr Imm Int
159
160 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
161 data EAIndex = EAIndexNone | EAIndex Reg Int
162 type Displacement = Imm
163
164
165 addrOffset :: AddrMode -> Int -> Maybe AddrMode
166 addrOffset addr off
167 = case addr of
168 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
169
170 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
171 AddrBaseIndex r i (ImmInteger n)
172 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
173
174 AddrBaseIndex r i (ImmCLbl lbl)
175 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
176
177 AddrBaseIndex r i (ImmIndex lbl ix)
178 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
179
180 _ -> Nothing -- in theory, shouldn't happen
181
182
183 addrModeRegs :: AddrMode -> [Reg]
184 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
185 where
186 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
187 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
188 addrModeRegs _ = []
189
190
191 -- registers -------------------------------------------------------------------
192
193 -- @spRel@ gives us a stack relative addressing mode for volatile
194 -- temporaries and for excess call arguments. @fpRel@, where
195 -- applicable, is the same but for the frame pointer.
196
197
198 spRel :: DynFlags
199 -> Int -- ^ desired stack offset in bytes, positive or negative
200 -> AddrMode
201 spRel dflags n
202 | target32Bit (targetPlatform dflags)
203 = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt n)
204 | otherwise
205 = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt n)
206
207 -- The register numbers must fit into 32 bits on x86, so that we can
208 -- use a Word32 to represent the set of free registers in the register
209 -- allocator.
210
211 firstfake, lastfake :: RegNo
212 firstfake = 16
213 lastfake = 21
214
215 firstxmm :: RegNo
216 firstxmm = 24
217
218 lastxmm :: Platform -> RegNo
219 lastxmm platform
220 | target32Bit platform = 31
221 | otherwise = 39
222
223 lastint :: Platform -> RegNo
224 lastint platform
225 | target32Bit platform = 7 -- not %r8..%r15
226 | otherwise = 15
227
228 intregnos :: Platform -> [RegNo]
229 intregnos platform = [0 .. lastint platform]
230
231 fakeregnos :: [RegNo]
232 fakeregnos = [firstfake .. lastfake]
233
234 xmmregnos :: Platform -> [RegNo]
235 xmmregnos platform = [firstxmm .. lastxmm platform]
236
237 floatregnos :: Platform -> [RegNo]
238 floatregnos platform = fakeregnos ++ xmmregnos platform
239
240
241 -- argRegs is the set of regs which are read for an n-argument call to C.
242 -- For archs which pass all args on the stack (x86), is empty.
243 -- Sparc passes up to the first 6 args in regs.
244 argRegs :: RegNo -> [Reg]
245 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
246
247 -- | The complete set of machine registers.
248 allMachRegNos :: Platform -> [RegNo]
249 allMachRegNos platform = intregnos platform ++ floatregnos platform
250
251 -- | Take the class of a register.
252 {-# INLINE classOfRealReg #-}
253 classOfRealReg :: Platform -> RealReg -> RegClass
254 -- On x86, we might want to have an 8-bit RegClass, which would
255 -- contain just regs 1-4 (the others don't have 8-bit versions).
256 -- However, we can get away without this at the moment because the
257 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
258 classOfRealReg platform reg
259 = case reg of
260 RealRegSingle i
261 | i <= lastint platform -> RcInteger
262 | i <= lastfake -> RcDouble
263 | otherwise -> RcDoubleSSE
264
265 RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch"
266
267 -- | Get the name of the register with this number.
268 showReg :: Platform -> RegNo -> String
269 showReg platform n
270 | n >= firstxmm = "%xmm" ++ show (n-firstxmm)
271 | n >= firstfake = "%fake" ++ show (n-firstfake)
272 | n >= 8 = "%r" ++ show n
273 | otherwise = regNames platform !! n
274
275 regNames :: Platform -> [String]
276 regNames platform
277 = if target32Bit platform
278 then ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"]
279 else ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp"]
280
281
282
283 -- machine specific ------------------------------------------------------------
284
285
286 {-
287 Intel x86 architecture:
288 - All registers except 7 (esp) are available for use.
289 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
290 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
291 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
292 - Registers fake0..fake5 are fakes; we pretend x86 has 6 conventionally-addressable
293 fp registers, and 3-operand insns for them, and we translate this into
294 real stack-based x86 fp code after register allocation.
295
296 The fp registers are all Double registers; we don't have any RcFloat class
297 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
298 never generate them.
299 -}
300
301 fake0, fake1, fake2, fake3, fake4, fake5,
302 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
303
304 eax = regSingle 0
305 ebx = regSingle 1
306 ecx = regSingle 2
307 edx = regSingle 3
308 esi = regSingle 4
309 edi = regSingle 5
310 ebp = regSingle 6
311 esp = regSingle 7
312 fake0 = regSingle 16
313 fake1 = regSingle 17
314 fake2 = regSingle 18
315 fake3 = regSingle 19
316 fake4 = regSingle 20
317 fake5 = regSingle 21
318
319
320
321 {-
322 AMD x86_64 architecture:
323 - All 16 integer registers are addressable as 8, 16, 32 and 64-bit values:
324
325 8 16 32 64
326 ---------------------
327 al ax eax rax
328 bl bx ebx rbx
329 cl cx ecx rcx
330 dl dx edx rdx
331 sil si esi rsi
332 dil si edi rdi
333 bpl bp ebp rbp
334 spl sp esp rsp
335 r10b r10w r10d r10
336 r11b r11w r11d r11
337 r12b r12w r12d r12
338 r13b r13w r13d r13
339 r14b r14w r14d r14
340 r15b r15w r15d r15
341 -}
342
343 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
344 r8, r9, r10, r11, r12, r13, r14, r15,
345 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
346 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
347
348 rax = regSingle 0
349 rbx = regSingle 1
350 rcx = regSingle 2
351 rdx = regSingle 3
352 rsi = regSingle 4
353 rdi = regSingle 5
354 rbp = regSingle 6
355 rsp = regSingle 7
356 r8 = regSingle 8
357 r9 = regSingle 9
358 r10 = regSingle 10
359 r11 = regSingle 11
360 r12 = regSingle 12
361 r13 = regSingle 13
362 r14 = regSingle 14
363 r15 = regSingle 15
364 xmm0 = regSingle 24
365 xmm1 = regSingle 25
366 xmm2 = regSingle 26
367 xmm3 = regSingle 27
368 xmm4 = regSingle 28
369 xmm5 = regSingle 29
370 xmm6 = regSingle 30
371 xmm7 = regSingle 31
372 xmm8 = regSingle 32
373 xmm9 = regSingle 33
374 xmm10 = regSingle 34
375 xmm11 = regSingle 35
376 xmm12 = regSingle 36
377 xmm13 = regSingle 37
378 xmm14 = regSingle 38
379 xmm15 = regSingle 39
380
381 ripRel :: Displacement -> AddrMode
382 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
383
384
385 -- so we can re-use some x86 code:
386 {-
387 eax = rax
388 ebx = rbx
389 ecx = rcx
390 edx = rdx
391 esi = rsi
392 edi = rdi
393 ebp = rbp
394 esp = rsp
395 -}
396
397 xmm :: RegNo -> Reg
398 xmm n = regSingle (firstxmm+n)
399
400
401
402
403 -- | these are the regs which we cannot assume stay alive over a C call.
404 callClobberedRegs :: Platform -> [Reg]
405 -- caller-saves registers
406 callClobberedRegs platform
407 | target32Bit platform = [eax,ecx,edx] ++ map regSingle (floatregnos platform)
408 | platformOS platform == OSMinGW32
409 = [rax,rcx,rdx,r8,r9,r10,r11]
410 ++ map regSingle (floatregnos platform)
411 | otherwise
412 -- all xmm regs are caller-saves
413 -- caller-saves registers
414 = [rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11]
415 ++ map regSingle (floatregnos platform)
416
417 allArgRegs :: Platform -> [(Reg, Reg)]
418 allArgRegs platform
419 | platformOS platform == OSMinGW32 = zip [rcx,rdx,r8,r9]
420 (map regSingle [firstxmm ..])
421 | otherwise = panic "X86.Regs.allArgRegs: not defined for this arch"
422
423 allIntArgRegs :: Platform -> [Reg]
424 allIntArgRegs platform
425 | (platformOS platform == OSMinGW32) || target32Bit platform
426 = panic "X86.Regs.allIntArgRegs: not defined for this platform"
427 | otherwise = [rdi,rsi,rdx,rcx,r8,r9]
428
429 allFPArgRegs :: Platform -> [Reg]
430 allFPArgRegs platform
431 | platformOS platform == OSMinGW32
432 = panic "X86.Regs.allFPArgRegs: not defined for this platform"
433 | otherwise = map regSingle [firstxmm .. firstxmm+7]
434
435 -- Machine registers which might be clobbered by instructions that
436 -- generate results into fixed registers, or need arguments in a fixed
437 -- register.
438 instrClobberedRegs :: Platform -> [Reg]
439 instrClobberedRegs platform
440 | target32Bit platform = [ eax, ecx, edx ]
441 | otherwise = [ rax, rcx, rdx ]
442
443 --
444
445 -- allocatableRegs is allMachRegNos with the fixed-use regs removed.
446 -- i.e., these are the regs for which we are prepared to allow the
447 -- register allocator to attempt to map VRegs to.
448 allocatableRegs :: Platform -> [RealReg]
449 allocatableRegs platform
450 = let isFree i = isFastTrue (freeReg platform i)
451 in map RealRegSingle $ filter isFree (allMachRegNos platform)
452