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
75 -- -----------------------------------------------------------------------------
76 -- Sizes on this architecture
78 -- A Size is usually a combination of width and class
80 -- It looks very like the old MachRep, but it's now of purely local
81 -- significance, here in the native code generator. You can change it
82 -- without global consequences.
84 -- A major use is as an opcode qualifier; thus the opcode
88 -- where the Size field encodes the ".l" part.
90 -- ToDo: it's not clear to me that we need separate signed-vs-unsigned sizes
91 -- here. I've removed them from the x86 version, we'll see what happens --SDM
93 -- ToDo: quite a few occurrences of Size could usefully be replaced by Width
96 = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80
99 intSize, floatSize :: Width -> Size
104 intSize other = pprPanic "MachInstrs.intSize" (ppr other)
109 floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
112 isFloatSize :: Size -> Bool
113 isFloatSize FF32 = True
114 isFloatSize FF64 = True
115 isFloatSize FF80 = True
116 isFloatSize _ = False
120 wordSize = intSize wordWidth
123 cmmTypeSize :: CmmType -> Size
124 cmmTypeSize ty | isFloatType ty = floatSize (typeWidth ty)
125 | otherwise = intSize (typeWidth ty)
128 sizeToWidth :: Size -> Width
130 sizeToWidth II16 = W16
131 sizeToWidth II32 = W32
132 sizeToWidth II64 = W64
133 sizeToWidth FF32 = W32
134 sizeToWidth FF64 = W64
135 sizeToWidth _ = panic "MachInstrs.sizeToWidth"
138 mkVReg :: Unique -> Size -> Reg
140 | not (isFloatSize size) = VirtualRegI u
143 FF32 -> VirtualRegD u
144 FF64 -> VirtualRegD u
148 -- -----------------------------------------------------------------------------
153 | ImmInteger Integer -- Sigh.
154 | ImmCLbl CLabel -- AbstractC Label (with baggage)
155 | ImmLit Doc -- Simple string
156 | ImmIndex CLabel Int
159 | ImmConstantSum Imm Imm
160 | ImmConstantDiff Imm Imm
163 strImmLit :: String -> Imm
164 strImmLit s = ImmLit (text s)
167 litToImm :: CmmLit -> Imm
168 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
169 -- narrow to the width: a CmmInt might be out of
170 -- range, but we assume that ImmInteger only contains
171 -- in-range values. A signed value should be fine here.
172 litToImm (CmmFloat f W32) = ImmFloat f
173 litToImm (CmmFloat f W64) = ImmDouble f
174 litToImm (CmmLabel l) = ImmCLbl l
175 litToImm (CmmLabelOff l off) = ImmIndex l off
176 litToImm (CmmLabelDiffOff l1 l2 off)
178 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
180 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
181 litToImm _ = panic "X86.Regs.litToImm: no match"
183 -- addressing modes ------------------------------------------------------------
186 = AddrBaseIndex EABase EAIndex Displacement
189 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
190 data EAIndex = EAIndexNone | EAIndex Reg Int
191 type Displacement = Imm
194 addrOffset :: AddrMode -> Int -> Maybe AddrMode
197 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
199 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
200 AddrBaseIndex r i (ImmInteger n)
201 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
203 AddrBaseIndex r i (ImmCLbl lbl)
204 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
206 AddrBaseIndex r i (ImmIndex lbl ix)
207 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
209 _ -> Nothing -- in theory, shouldn't happen
212 addrModeRegs :: AddrMode -> [Reg]
213 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
215 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
216 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
220 -- registers -------------------------------------------------------------------
222 -- @spRel@ gives us a stack relative addressing mode for volatile
223 -- temporaries and for excess call arguments. @fpRel@, where
224 -- applicable, is the same but for the frame pointer.
227 spRel :: Int -- ^ desired stack offset in words, positive or negative
231 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
233 #elif x86_64_TARGET_ARCH
234 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
237 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
242 -- argRegs is the set of regs which are read for an n-argument call to C.
243 -- For archs which pass all args on the stack (x86), is empty.
244 -- Sparc passes up to the first 6 args in regs.
245 -- Dunno about Alpha.
246 argRegs :: RegNo -> [Reg]
247 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
253 -- | The complete set of machine registers.
254 allMachRegNos :: [RegNo]
257 allMachRegNos = [0..13]
259 #elif x86_64_TARGET_ARCH
260 allMachRegNos = [0..31]
263 allMachRegNos = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
268 -- | Take the class of a register.
269 {-# INLINE regClass #-}
270 regClass :: Reg -> RegClass
273 -- On x86, we might want to have an 8-bit RegClass, which would
274 -- contain just regs 1-4 (the others don't have 8-bit versions).
275 -- However, we can get away without this at the moment because the
276 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
277 regClass (RealReg i) = if i < 8 then RcInteger else RcDouble
278 regClass (VirtualRegI _) = RcInteger
279 regClass (VirtualRegHi _) = RcInteger
280 regClass (VirtualRegD _) = RcDouble
281 regClass (VirtualRegF u) = pprPanic ("regClass(x86):VirtualRegF") (ppr u)
283 #elif x86_64_TARGET_ARCH
284 -- On x86, we might want to have an 8-bit RegClass, which would
285 -- contain just regs 1-4 (the others don't have 8-bit versions).
286 -- However, we can get away without this at the moment because the
287 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
288 regClass (RealReg i) = if i < 16 then RcInteger else RcDouble
289 regClass (VirtualRegI _) = RcInteger
290 regClass (VirtualRegHi _) = RcInteger
291 regClass (VirtualRegD _) = RcDouble
292 regClass (VirtualRegF u) = pprPanic "regClass(x86_64):VirtualRegF" (ppr u)
295 regClass _ = panic "X86.Regs.regClass: not defined for this architecture"
300 -- | Get the name of the register with this number.
301 showReg :: RegNo -> String
305 = if n >= 0 && n < 14
307 else "%unknown_x86_real_reg_" ++ show n
311 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
312 "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
314 #elif x86_64_TARGET_ARCH
316 | n >= 16 = "%xmm" ++ show (n-16)
317 | n >= 8 = "%r" ++ show n
318 | otherwise = regNames !! n
322 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
325 showReg _ = panic "X86.Regs.showReg: not defined for this architecture"
332 -- machine specific ------------------------------------------------------------
336 Intel x86 architecture:
337 - All registers except 7 (esp) are available for use.
338 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
339 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
340 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
341 - Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable
342 fp registers, and 3-operand insns for them, and we translate this into
343 real stack-based x86 fp code after register allocation.
345 The fp registers are all Double registers; we don't have any RcFloat class
346 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
350 fake0, fake1, fake2, fake3, fake4, fake5,
351 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
371 AMD x86_64 architecture:
372 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
373 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
374 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
378 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
379 r8, r9, r10, r11, r12, r13, r14, r15,
380 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
381 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
416 allFPArgRegs :: [Reg]
417 allFPArgRegs = map RealReg [16 .. 23]
419 ripRel :: Displacement -> AddrMode
420 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
423 -- so we can re-use some x86 code:
436 xmm n = RealReg (16+n)
441 -- horror show -----------------------------------------------------------------
442 freeReg :: RegNo -> FastBool
443 globalRegMaybe :: GlobalReg -> Maybe Reg
445 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
464 #if x86_64_TARGET_ARCH
502 freeReg esp = fastBool False -- %esp is the C stack pointer
505 #if x86_64_TARGET_ARCH
506 freeReg rsp = fastBool False -- %rsp is the C stack pointer
510 freeReg REG_Base = fastBool False
513 freeReg REG_R1 = fastBool False
516 freeReg REG_R2 = fastBool False
519 freeReg REG_R3 = fastBool False
522 freeReg REG_R4 = fastBool False
525 freeReg REG_R5 = fastBool False
528 freeReg REG_R6 = fastBool False
531 freeReg REG_R7 = fastBool False
534 freeReg REG_R8 = fastBool False
537 freeReg REG_F1 = fastBool False
540 freeReg REG_F2 = fastBool False
543 freeReg REG_F3 = fastBool False
546 freeReg REG_F4 = fastBool False
549 freeReg REG_D1 = fastBool False
552 freeReg REG_D2 = fastBool False
555 freeReg REG_Sp = fastBool False
558 freeReg REG_Su = fastBool False
561 freeReg REG_SpLim = fastBool False
564 freeReg REG_Hp = fastBool False
567 freeReg REG_HpLim = fastBool False
569 freeReg _ = fastBool True
572 -- | Returns 'Nothing' if this global register is not stored
573 -- in a real machine register, otherwise returns @'Just' reg@, where
574 -- reg is the machine register it is stored in.
577 globalRegMaybe BaseReg = Just (RealReg REG_Base)
580 globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
583 globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
586 globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
589 globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
592 globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
595 globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
598 globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
601 globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
604 globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
607 globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
610 globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
613 globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
616 globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
619 globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
622 globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
625 globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
628 globalRegMaybe Sp = Just (RealReg REG_Sp)
631 globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
634 globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
637 globalRegMaybe SpLim = Just (RealReg REG_SpLim)
640 globalRegMaybe Hp = Just (RealReg REG_Hp)
643 globalRegMaybe HpLim = Just (RealReg REG_HpLim)
645 #ifdef REG_CurrentTSO
646 globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
648 #ifdef REG_CurrentNursery
649 globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
651 globalRegMaybe _ = Nothing
657 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
659 #elif x86_64_TARGET_ARCH
660 allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9]
663 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
667 -- | these are the regs which we cannot assume stay alive over a C call.
668 callClobberedRegs :: [Reg]
671 -- caller-saves registers
673 = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
675 #elif x86_64_TARGET_ARCH
676 -- all xmm regs are caller-saves
677 -- caller-saves registers
679 = map RealReg ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31])
683 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
686 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
691 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"
693 allArgRegs = panic "X86.Regs.globalRegMaybe: not defined"
694 callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined"