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