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 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
78 -- -----------------------------------------------------------------------------
79 -- Sizes on this architecture
81 -- A Size is usually a combination of width and class
83 -- It looks very like the old MachRep, but it's now of purely local
84 -- significance, here in the native code generator. You can change it
85 -- without global consequences.
87 -- A major use is as an opcode qualifier; thus the opcode
91 -- where the Size field encodes the ".l" part.
93 -- ToDo: it's not clear to me that we need separate signed-vs-unsigned sizes
94 -- here. I've removed them from the x86 version, we'll see what happens --SDM
96 -- ToDo: quite a few occurrences of Size could usefully be replaced by Width
99 = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80
102 intSize, floatSize :: Width -> Size
107 intSize other = pprPanic "MachInstrs.intSize" (ppr other)
112 floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
115 isFloatSize :: Size -> Bool
116 isFloatSize FF32 = True
117 isFloatSize FF64 = True
118 isFloatSize FF80 = True
119 isFloatSize _ = False
123 wordSize = intSize wordWidth
126 cmmTypeSize :: CmmType -> Size
127 cmmTypeSize ty | isFloatType ty = floatSize (typeWidth ty)
128 | otherwise = intSize (typeWidth ty)
131 sizeToWidth :: Size -> Width
133 sizeToWidth II16 = W16
134 sizeToWidth II32 = W32
135 sizeToWidth II64 = W64
136 sizeToWidth FF32 = W32
137 sizeToWidth FF64 = W64
138 sizeToWidth _ = panic "MachInstrs.sizeToWidth"
141 mkVReg :: Unique -> Size -> Reg
143 | not (isFloatSize size) = VirtualRegI u
146 FF32 -> VirtualRegD u
147 FF64 -> VirtualRegD u
151 -- -----------------------------------------------------------------------------
156 | ImmInteger Integer -- Sigh.
157 | ImmCLbl CLabel -- AbstractC Label (with baggage)
158 | ImmLit Doc -- Simple string
159 | ImmIndex CLabel Int
162 | ImmConstantSum Imm Imm
163 | ImmConstantDiff Imm Imm
166 strImmLit :: String -> Imm
167 strImmLit s = ImmLit (text s)
170 litToImm :: CmmLit -> Imm
171 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
172 -- narrow to the width: a CmmInt might be out of
173 -- range, but we assume that ImmInteger only contains
174 -- in-range values. A signed value should be fine here.
175 litToImm (CmmFloat f W32) = ImmFloat f
176 litToImm (CmmFloat f W64) = ImmDouble f
177 litToImm (CmmLabel l) = ImmCLbl l
178 litToImm (CmmLabelOff l off) = ImmIndex l off
179 litToImm (CmmLabelDiffOff l1 l2 off)
181 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
183 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
184 litToImm _ = panic "X86.Regs.litToImm: no match"
186 -- addressing modes ------------------------------------------------------------
189 = AddrBaseIndex EABase EAIndex Displacement
192 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
193 data EAIndex = EAIndexNone | EAIndex Reg Int
194 type Displacement = Imm
197 addrOffset :: AddrMode -> Int -> Maybe AddrMode
200 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
202 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
203 AddrBaseIndex r i (ImmInteger n)
204 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
206 AddrBaseIndex r i (ImmCLbl lbl)
207 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
209 AddrBaseIndex r i (ImmIndex lbl ix)
210 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
212 _ -> Nothing -- in theory, shouldn't happen
215 addrModeRegs :: AddrMode -> [Reg]
216 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
218 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
219 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
223 -- registers -------------------------------------------------------------------
225 -- @spRel@ gives us a stack relative addressing mode for volatile
226 -- temporaries and for excess call arguments. @fpRel@, where
227 -- applicable, is the same but for the frame pointer.
230 spRel :: Int -- ^ desired stack offset in words, positive or negative
234 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
236 #elif x86_64_TARGET_ARCH
237 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
240 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
245 -- argRegs is the set of regs which are read for an n-argument call to C.
246 -- For archs which pass all args on the stack (x86), is empty.
247 -- Sparc passes up to the first 6 args in regs.
248 -- Dunno about Alpha.
249 argRegs :: RegNo -> [Reg]
250 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
256 -- | The complete set of machine registers.
257 allMachRegNos :: [RegNo]
260 allMachRegNos = [0..13]
262 #elif x86_64_TARGET_ARCH
263 allMachRegNos = [0..31]
266 allMachRegNos = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
271 -- | Take the class of a register.
272 {-# INLINE regClass #-}
273 regClass :: Reg -> RegClass
276 -- On x86, we might want to have an 8-bit RegClass, which would
277 -- contain just regs 1-4 (the others don't have 8-bit versions).
278 -- However, we can get away without this at the moment because the
279 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
280 regClass (RealReg i) = if i < 8 then RcInteger else RcDouble
281 regClass (VirtualRegI _) = RcInteger
282 regClass (VirtualRegHi _) = RcInteger
283 regClass (VirtualRegD _) = RcDouble
284 regClass (VirtualRegF u) = pprPanic ("regClass(x86):VirtualRegF") (ppr u)
286 #elif x86_64_TARGET_ARCH
287 -- On x86, we might want to have an 8-bit RegClass, which would
288 -- contain just regs 1-4 (the others don't have 8-bit versions).
289 -- However, we can get away without this at the moment because the
290 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
291 regClass (RealReg i) = if i < 16 then RcInteger else RcDouble
292 regClass (VirtualRegI _) = RcInteger
293 regClass (VirtualRegHi _) = RcInteger
294 regClass (VirtualRegD _) = RcDouble
295 regClass (VirtualRegF u) = pprPanic "regClass(x86_64):VirtualRegF" (ppr u)
298 regClass _ = panic "X86.Regs.regClass: not defined for this architecture"
303 -- | Get the name of the register with this number.
304 showReg :: RegNo -> String
308 = if n >= 0 && n < 14
310 else "%unknown_x86_real_reg_" ++ show n
314 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
315 "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
317 #elif x86_64_TARGET_ARCH
319 | n >= 16 = "%xmm" ++ show (n-16)
320 | n >= 8 = "%r" ++ show n
321 | otherwise = regNames !! n
325 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
328 showReg _ = panic "X86.Regs.showReg: not defined for this architecture"
335 -- machine specific ------------------------------------------------------------
339 Intel x86 architecture:
340 - All registers except 7 (esp) are available for use.
341 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
342 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
343 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
344 - Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable
345 fp registers, and 3-operand insns for them, and we translate this into
346 real stack-based x86 fp code after register allocation.
348 The fp registers are all Double registers; we don't have any RcFloat class
349 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
353 fake0, fake1, fake2, fake3, fake4, fake5,
354 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
374 AMD x86_64 architecture:
375 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
376 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
377 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
381 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
382 r8, r9, r10, r11, r12, r13, r14, r15,
383 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
384 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
419 allFPArgRegs :: [Reg]
420 allFPArgRegs = map RealReg [16 .. 23]
422 ripRel :: Displacement -> AddrMode
423 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
426 -- so we can re-use some x86 code:
439 xmm n = RealReg (16+n)
444 -- horror show -----------------------------------------------------------------
445 freeReg :: RegNo -> FastBool
446 globalRegMaybe :: GlobalReg -> Maybe Reg
448 callClobberedRegs :: [Reg]
450 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
469 #if x86_64_TARGET_ARCH
507 freeReg esp = fastBool False -- %esp is the C stack pointer
510 #if x86_64_TARGET_ARCH
511 freeReg rsp = fastBool False -- %rsp is the C stack pointer
515 freeReg REG_Base = fastBool False
518 freeReg REG_R1 = fastBool False
521 freeReg REG_R2 = fastBool False
524 freeReg REG_R3 = fastBool False
527 freeReg REG_R4 = fastBool False
530 freeReg REG_R5 = fastBool False
533 freeReg REG_R6 = fastBool False
536 freeReg REG_R7 = fastBool False
539 freeReg REG_R8 = fastBool False
542 freeReg REG_F1 = fastBool False
545 freeReg REG_F2 = fastBool False
548 freeReg REG_F3 = fastBool False
551 freeReg REG_F4 = fastBool False
554 freeReg REG_D1 = fastBool False
557 freeReg REG_D2 = fastBool False
560 freeReg REG_Sp = fastBool False
563 freeReg REG_Su = fastBool False
566 freeReg REG_SpLim = fastBool False
569 freeReg REG_Hp = fastBool False
572 freeReg REG_HpLim = fastBool False
574 freeReg _ = fastBool True
577 -- | Returns 'Nothing' if this global register is not stored
578 -- in a real machine register, otherwise returns @'Just' reg@, where
579 -- reg is the machine register it is stored in.
582 globalRegMaybe BaseReg = Just (RealReg REG_Base)
585 globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
588 globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
591 globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
594 globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
597 globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
600 globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
603 globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
606 globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
609 globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
612 globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
615 globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
618 globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
621 globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
624 globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
627 globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
630 globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
633 globalRegMaybe Sp = Just (RealReg REG_Sp)
636 globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
639 globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
642 globalRegMaybe SpLim = Just (RealReg REG_SpLim)
645 globalRegMaybe Hp = Just (RealReg REG_Hp)
648 globalRegMaybe HpLim = Just (RealReg REG_HpLim)
650 #ifdef REG_CurrentTSO
651 globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
653 #ifdef REG_CurrentNursery
654 globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
656 globalRegMaybe _ = Nothing
661 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
663 #elif x86_64_TARGET_ARCH
664 allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9]
667 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
671 -- | these are the regs which we cannot assume stay alive over a C call.
674 -- caller-saves registers
676 = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
678 #elif x86_64_TARGET_ARCH
679 -- all xmm regs are caller-saves
680 -- caller-saves registers
682 = map RealReg ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31])
686 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
689 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
694 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
696 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
697 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"