32 EABase(..), EAIndex(..), addrModeRegs,
34 eax, ebx, ecx, edx, esi, edi, ebp, esp,
35 fake0, fake1, fake2, fake3, fake4, fake5,
37 rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
38 r8, r9, r10, r11, r12, r13, r14, r15,
39 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
40 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
53 #include "nativeGen/NCG.h"
54 #include "HsVersions.h"
57 # define STOLEN_X86_REGS 4
58 -- HACK: go for the max
61 #include "../includes/MachRegs.h"
67 import CLabel ( CLabel )
69 import Outputable ( Outputable(..), pprPanic, panic )
70 import qualified Outputable
74 -- -----------------------------------------------------------------------------
75 -- Sizes on this architecture
77 -- A Size is usually a combination of width and class
79 -- It looks very like the old MachRep, but it's now of purely local
80 -- significance, here in the native code generator. You can change it
81 -- without global consequences.
83 -- A major use is as an opcode qualifier; thus the opcode
87 -- where the Size field encodes the ".l" part.
89 -- ToDo: it's not clear to me that we need separate signed-vs-unsigned sizes
90 -- here. I've removed them from the x86 version, we'll see what happens --SDM
92 -- ToDo: quite a few occurrences of Size could usefully be replaced by Width
95 = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80
98 intSize, floatSize :: Width -> Size
103 intSize other = pprPanic "MachInstrs.intSize" (ppr other)
108 floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
111 isFloatSize :: Size -> Bool
112 isFloatSize FF32 = True
113 isFloatSize FF64 = True
114 isFloatSize FF80 = True
115 isFloatSize _ = False
119 wordSize = intSize wordWidth
122 cmmTypeSize :: CmmType -> Size
123 cmmTypeSize ty | isFloatType ty = floatSize (typeWidth ty)
124 | otherwise = intSize (typeWidth ty)
127 sizeToWidth :: Size -> Width
129 sizeToWidth II16 = W16
130 sizeToWidth II32 = W32
131 sizeToWidth II64 = W64
132 sizeToWidth FF32 = W32
133 sizeToWidth FF64 = W64
134 sizeToWidth _ = panic "MachInstrs.sizeToWidth"
137 mkVReg :: Unique -> Size -> Reg
139 | not (isFloatSize size) = VirtualRegI u
142 FF32 -> VirtualRegD u
143 FF64 -> VirtualRegD u
147 -- -----------------------------------------------------------------------------
152 | ImmInteger Integer -- Sigh.
153 | ImmCLbl CLabel -- AbstractC Label (with baggage)
154 | ImmLit Doc -- Simple string
155 | ImmIndex CLabel Int
158 | ImmConstantSum Imm Imm
159 | ImmConstantDiff Imm Imm
162 strImmLit :: String -> Imm
163 strImmLit s = ImmLit (text s)
166 litToImm :: CmmLit -> Imm
167 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
168 -- narrow to the width: a CmmInt might be out of
169 -- range, but we assume that ImmInteger only contains
170 -- in-range values. A signed value should be fine here.
171 litToImm (CmmFloat f W32) = ImmFloat f
172 litToImm (CmmFloat f W64) = ImmDouble f
173 litToImm (CmmLabel l) = ImmCLbl l
174 litToImm (CmmLabelOff l off) = ImmIndex l off
175 litToImm (CmmLabelDiffOff l1 l2 off)
177 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
179 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
180 litToImm _ = panic "X86.Regs.litToImm: no match"
182 -- addressing modes ------------------------------------------------------------
185 = AddrBaseIndex EABase EAIndex Displacement
188 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
189 data EAIndex = EAIndexNone | EAIndex Reg Int
190 type Displacement = Imm
193 addrOffset :: AddrMode -> Int -> Maybe AddrMode
196 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
198 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
199 AddrBaseIndex r i (ImmInteger n)
200 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
202 AddrBaseIndex r i (ImmCLbl lbl)
203 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
205 AddrBaseIndex r i (ImmIndex lbl ix)
206 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
208 _ -> Nothing -- in theory, shouldn't happen
211 addrModeRegs :: AddrMode -> [Reg]
212 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
214 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
215 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
219 -- registers -------------------------------------------------------------------
221 -- @spRel@ gives us a stack relative addressing mode for volatile
222 -- temporaries and for excess call arguments. @fpRel@, where
223 -- applicable, is the same but for the frame pointer.
226 spRel :: Int -- ^ desired stack offset in words, positive or negative
230 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
232 #elif x86_64_TARGET_ARCH
233 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
236 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
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 -- Dunno about Alpha.
245 argRegs :: RegNo -> [Reg]
246 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
254 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
256 #elif x86_64_TARGET_ARCH
257 allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9]
260 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
264 -- | these are the regs which we cannot assume stay alive over a C call.
265 callClobberedRegs :: [Reg]
268 -- caller-saves registers
270 = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
272 #elif x86_64_TARGET_ARCH
273 -- all xmm regs are caller-saves
274 -- caller-saves registers
276 = map RealReg ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31])
280 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
284 -- | The complete set of machine registers.
285 allMachRegNos :: [RegNo]
288 allMachRegNos = [0..13]
290 #elif x86_64_TARGET_ARCH
291 allMachRegNos = [0..31]
294 allMachRegNos = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
299 -- | Take the class of a register.
300 {-# INLINE regClass #-}
301 regClass :: Reg -> RegClass
304 -- On x86, we might want to have an 8-bit RegClass, which would
305 -- contain just regs 1-4 (the others don't have 8-bit versions).
306 -- However, we can get away without this at the moment because the
307 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
308 regClass (RealReg i) = if i < 8 then RcInteger else RcDouble
309 regClass (VirtualRegI u) = RcInteger
310 regClass (VirtualRegHi u) = RcInteger
311 regClass (VirtualRegD u) = RcDouble
312 regClass (VirtualRegF u) = pprPanic "regClass(x86):VirtualRegF"
313 (ppr (VirtualRegF u))
315 #elif x86_64_TARGET_ARCH
316 -- On x86, we might want to have an 8-bit RegClass, which would
317 -- contain just regs 1-4 (the others don't have 8-bit versions).
318 -- However, we can get away without this at the moment because the
319 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
320 regClass (RealReg i) = if i < 16 then RcInteger else RcDouble
321 regClass (VirtualRegI u) = RcInteger
322 regClass (VirtualRegHi u) = RcInteger
323 regClass (VirtualRegD u) = RcDouble
324 regClass (VirtualRegF u) = pprPanic "regClass(x86_64):VirtualRegF"
325 (ppr (VirtualRegF u))
328 regClass _ = panic "X86.Regs.regClass: not defined for this architecture"
333 -- | Get the name of the register with this number.
334 showReg :: RegNo -> String
338 = if n >= 0 && n < 14
340 else "%unknown_x86_real_reg_" ++ show n
343 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
344 "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
346 #elif x86_64_TARGET_ARCH
348 | n >= 16 = "%xmm" ++ show (n-16)
349 | n >= 8 = "%r" ++ show n
350 | otherwise = regNames !! n
353 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
356 showReg _ = panic "X86.Regs.showReg: not defined for this architecture"
363 -- machine specific ------------------------------------------------------------
367 Intel x86 architecture:
368 - All registers except 7 (esp) are available for use.
369 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
370 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
371 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
372 - Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable
373 fp registers, and 3-operand insns for them, and we translate this into
374 real stack-based x86 fp code after register allocation.
376 The fp registers are all Double registers; we don't have any RcFloat class
377 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
381 fake0, fake1, fake2, fake3, fake4, fake5,
382 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
402 AMD x86_64 architecture:
403 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
404 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
405 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
409 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
410 r8, r9, r10, r11, r12, r13, r14, r15,
411 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
412 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
447 allFPArgRegs :: [Reg]
448 allFPArgRegs = map RealReg [16 .. 23]
450 ripRel :: Displacement -> AddrMode
451 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
454 -- so we can re-use some x86 code:
467 xmm n = RealReg (16+n)
472 -- horror show -----------------------------------------------------------------
473 freeReg :: RegNo -> FastBool
474 globalRegMaybe :: GlobalReg -> Maybe Reg
476 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
495 #if x86_64_TARGET_ARCH
533 freeReg esp = fastBool False -- %esp is the C stack pointer
536 #if x86_64_TARGET_ARCH
537 freeReg rsp = fastBool False -- %rsp is the C stack pointer
541 freeReg REG_Base = fastBool False
544 freeReg REG_R1 = fastBool False
547 freeReg REG_R2 = fastBool False
550 freeReg REG_R3 = fastBool False
553 freeReg REG_R4 = fastBool False
556 freeReg REG_R5 = fastBool False
559 freeReg REG_R6 = fastBool False
562 freeReg REG_R7 = fastBool False
565 freeReg REG_R8 = fastBool False
568 freeReg REG_F1 = fastBool False
571 freeReg REG_F2 = fastBool False
574 freeReg REG_F3 = fastBool False
577 freeReg REG_F4 = fastBool False
580 freeReg REG_D1 = fastBool False
583 freeReg REG_D2 = fastBool False
586 freeReg REG_Sp = fastBool False
589 freeReg REG_Su = fastBool False
592 freeReg REG_SpLim = fastBool False
595 freeReg REG_Hp = fastBool False
598 freeReg REG_HpLim = fastBool False
600 freeReg n = fastBool True
603 -- | Returns 'Nothing' if this global register is not stored
604 -- in a real machine register, otherwise returns @'Just' reg@, where
605 -- reg is the machine register it is stored in.
608 globalRegMaybe BaseReg = Just (RealReg REG_Base)
611 globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
614 globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
617 globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
620 globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
623 globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
626 globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
629 globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
632 globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
635 globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
638 globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
641 globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
644 globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
647 globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
650 globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
653 globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
656 globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
659 globalRegMaybe Sp = Just (RealReg REG_Sp)
662 globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
665 globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
668 globalRegMaybe SpLim = Just (RealReg REG_SpLim)
671 globalRegMaybe Hp = Just (RealReg REG_Hp)
674 globalRegMaybe HpLim = Just (RealReg REG_HpLim)
676 #ifdef REG_CurrentTSO
677 globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
679 #ifdef REG_CurrentNursery
680 globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
682 globalRegMaybe _ = Nothing
684 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
687 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"