32 EABase(..), EAIndex(..), addrModeRegs,
35 -- part of address mode. shared for both arches.
36 eax, ebx, ecx, edx, esi, edi, ebp, esp,
37 fake0, fake1, fake2, fake3, fake4, fake5,
39 #if x86_64_TARGET_ARCH
40 -- part of address mode. shared for both arches.
44 rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
45 eax, ebx, ecx, edx, esi, edi, ebp, esp,
46 r8, r9, r10, r11, r12, r13, r14, r15,
47 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
48 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
59 #include "nativeGen/NCG.h"
60 #include "HsVersions.h"
63 # define STOLEN_X86_REGS 4
64 -- HACK: go for the max
67 #include "../includes/MachRegs.h"
73 import CLabel ( CLabel )
75 import Outputable ( Outputable(..), pprPanic, panic )
76 import qualified Outputable
80 -- -----------------------------------------------------------------------------
81 -- Sizes on this architecture
83 -- A Size is usually a combination of width and class
85 -- It looks very like the old MachRep, but it's now of purely local
86 -- significance, here in the native code generator. You can change it
87 -- without global consequences.
89 -- A major use is as an opcode qualifier; thus the opcode
93 -- where the Size field encodes the ".l" part.
95 -- ToDo: it's not clear to me that we need separate signed-vs-unsigned sizes
96 -- here. I've removed them from the x86 version, we'll see what happens --SDM
98 -- ToDo: quite a few occurrences of Size could usefully be replaced by Width
101 = II8 | II16 | II32 | II64 | FF32 | FF64 | FF80
104 intSize, floatSize :: Width -> Size
109 intSize other = pprPanic "MachInstrs.intSize" (ppr other)
114 floatSize other = pprPanic "MachInstrs.intSize" (ppr other)
117 isFloatSize :: Size -> Bool
118 isFloatSize FF32 = True
119 isFloatSize FF64 = True
120 isFloatSize FF80 = True
121 isFloatSize _ = False
125 wordSize = intSize wordWidth
128 cmmTypeSize :: CmmType -> Size
129 cmmTypeSize ty | isFloatType ty = floatSize (typeWidth ty)
130 | otherwise = intSize (typeWidth ty)
133 sizeToWidth :: Size -> Width
135 sizeToWidth II16 = W16
136 sizeToWidth II32 = W32
137 sizeToWidth II64 = W64
138 sizeToWidth FF32 = W32
139 sizeToWidth FF64 = W64
140 sizeToWidth _ = panic "MachInstrs.sizeToWidth"
143 mkVReg :: Unique -> Size -> Reg
145 | not (isFloatSize size) = VirtualRegI u
148 FF32 -> VirtualRegD u
149 FF64 -> VirtualRegD u
153 -- -----------------------------------------------------------------------------
158 | ImmInteger Integer -- Sigh.
159 | ImmCLbl CLabel -- AbstractC Label (with baggage)
160 | ImmLit Doc -- Simple string
161 | ImmIndex CLabel Int
164 | ImmConstantSum Imm Imm
165 | ImmConstantDiff Imm Imm
168 strImmLit :: String -> Imm
169 strImmLit s = ImmLit (text s)
172 litToImm :: CmmLit -> Imm
173 litToImm (CmmInt i w) = ImmInteger (narrowS w i)
174 -- narrow to the width: a CmmInt might be out of
175 -- range, but we assume that ImmInteger only contains
176 -- in-range values. A signed value should be fine here.
177 litToImm (CmmFloat f W32) = ImmFloat f
178 litToImm (CmmFloat f W64) = ImmDouble f
179 litToImm (CmmLabel l) = ImmCLbl l
180 litToImm (CmmLabelOff l off) = ImmIndex l off
181 litToImm (CmmLabelDiffOff l1 l2 off)
183 (ImmConstantDiff (ImmCLbl l1) (ImmCLbl l2))
185 litToImm (CmmBlock id) = ImmCLbl (infoTblLbl id)
186 litToImm _ = panic "X86.Regs.litToImm: no match"
188 -- addressing modes ------------------------------------------------------------
191 = AddrBaseIndex EABase EAIndex Displacement
194 data EABase = EABaseNone | EABaseReg Reg | EABaseRip
195 data EAIndex = EAIndexNone | EAIndex Reg Int
196 type Displacement = Imm
199 addrOffset :: AddrMode -> Int -> Maybe AddrMode
202 ImmAddr i off0 -> Just (ImmAddr i (off0 + off))
204 AddrBaseIndex r i (ImmInt n) -> Just (AddrBaseIndex r i (ImmInt (n + off)))
205 AddrBaseIndex r i (ImmInteger n)
206 -> Just (AddrBaseIndex r i (ImmInt (fromInteger (n + toInteger off))))
208 AddrBaseIndex r i (ImmCLbl lbl)
209 -> Just (AddrBaseIndex r i (ImmIndex lbl off))
211 AddrBaseIndex r i (ImmIndex lbl ix)
212 -> Just (AddrBaseIndex r i (ImmIndex lbl (ix+off)))
214 _ -> Nothing -- in theory, shouldn't happen
217 addrModeRegs :: AddrMode -> [Reg]
218 addrModeRegs (AddrBaseIndex b i _) = b_regs ++ i_regs
220 b_regs = case b of { EABaseReg r -> [r]; _ -> [] }
221 i_regs = case i of { EAIndex r _ -> [r]; _ -> [] }
225 -- registers -------------------------------------------------------------------
227 -- @spRel@ gives us a stack relative addressing mode for volatile
228 -- temporaries and for excess call arguments. @fpRel@, where
229 -- applicable, is the same but for the frame pointer.
232 spRel :: Int -- ^ desired stack offset in words, positive or negative
236 spRel n = AddrBaseIndex (EABaseReg esp) EAIndexNone (ImmInt (n * wORD_SIZE))
238 #elif x86_64_TARGET_ARCH
239 spRel n = AddrBaseIndex (EABaseReg rsp) EAIndexNone (ImmInt (n * wORD_SIZE))
242 spRel _ = panic "X86.Regs.spRel: not defined for this architecture"
247 -- argRegs is the set of regs which are read for an n-argument call to C.
248 -- For archs which pass all args on the stack (x86), is empty.
249 -- Sparc passes up to the first 6 args in regs.
250 -- Dunno about Alpha.
251 argRegs :: RegNo -> [Reg]
252 argRegs _ = panic "MachRegs.argRegs(x86): should not be used!"
260 allArgRegs = panic "X86.Regs.allArgRegs: should not be used!"
262 #elif x86_64_TARGET_ARCH
263 allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9]
266 allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture"
270 -- | these are the regs which we cannot assume stay alive over a C call.
271 callClobberedRegs :: [Reg]
274 -- caller-saves registers
276 = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5]
278 #elif x86_64_TARGET_ARCH
279 -- all xmm regs are caller-saves
280 -- caller-saves registers
282 = map RealReg ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31])
286 = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
290 -- | The complete set of machine registers.
291 allMachRegNos :: [RegNo]
294 allMachRegNos = [0..13]
296 #elif x86_64_TARGET_ARCH
297 allMachRegNos = [0..31]
300 allMachRegNos = panic "X86.Regs.callClobberedRegs: not defined for this architecture"
305 -- | Take the class of a register.
306 {-# INLINE regClass #-}
307 regClass :: Reg -> RegClass
310 -- On x86, we might want to have an 8-bit RegClass, which would
311 -- contain just regs 1-4 (the others don't have 8-bit versions).
312 -- However, we can get away without this at the moment because the
313 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
314 regClass (RealReg i) = if i < 8 then RcInteger else RcDouble
315 regClass (VirtualRegI u) = RcInteger
316 regClass (VirtualRegHi u) = RcInteger
317 regClass (VirtualRegD u) = RcDouble
318 regClass (VirtualRegF u) = pprPanic "regClass(x86):VirtualRegF"
319 (ppr (VirtualRegF u))
321 #elif x86_64_TARGET_ARCH
322 -- On x86, we might want to have an 8-bit RegClass, which would
323 -- contain just regs 1-4 (the others don't have 8-bit versions).
324 -- However, we can get away without this at the moment because the
325 -- only allocatable integer regs are also 8-bit compatible (1, 3, 4).
326 regClass (RealReg i) = if i < 16 then RcInteger else RcDouble
327 regClass (VirtualRegI u) = RcInteger
328 regClass (VirtualRegHi u) = RcInteger
329 regClass (VirtualRegD u) = RcDouble
330 regClass (VirtualRegF u) = pprPanic "regClass(x86_64):VirtualRegF"
331 (ppr (VirtualRegF u))
334 regClass _ = panic "X86.Regs.regClass: not defined for this architecture"
339 -- | Get the name of the register with this number.
340 showReg :: RegNo -> String
344 = if n >= 0 && n < 14
346 else "%unknown_x86_real_reg_" ++ show n
349 = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp",
350 "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"]
352 #elif x86_64_TARGET_ARCH
354 | n >= 16 = "%xmm" ++ show (n-16)
355 | n >= 8 = "%r" ++ show n
356 | otherwise = regNames !! n
359 = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ]
362 showReg _ = panic "X86.Regs.showReg: not defined for this architecture"
369 -- machine specific ------------------------------------------------------------
373 Intel x86 architecture:
374 - All registers except 7 (esp) are available for use.
375 - Only ebx, esi, edi and esp are available across a C call (they are callee-saves).
376 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
377 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
378 - Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable
379 fp registers, and 3-operand insns for them, and we translate this into
380 real stack-based x86 fp code after register allocation.
382 The fp registers are all Double registers; we don't have any RcFloat class
383 regs. @regClass@ barfs if you give it a VirtualRegF, and mkVReg above should
388 fake0, fake1, fake2, fake3, fake4, fake5,
389 eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
409 AMD x86_64 architecture:
410 - Registers 0-16 have 32-bit counterparts (eax, ebx etc.)
411 - Registers 0-7 have 16-bit counterparts (ax, bx etc.)
412 - Registers 0-3 have 8 bit counterparts (ah, bh etc.)
416 #if x86_64_TARGET_ARCH
417 allFPArgRegs :: [Reg]
418 allFPArgRegs = map RealReg [xmm0 .. xmm7]
420 ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm
423 rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
424 r8, r9, r10, r11, r12, r13, r14, r15,
425 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
426 xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
461 -- so we can re-use some x86 code:
471 xmm n = RealReg (16+n)
477 -- horror show -----------------------------------------------------------------
478 freeReg :: RegNo -> FastBool
479 globalRegMaybe :: GlobalReg -> Maybe Reg
481 #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
500 #if x86_64_TARGET_ARCH
538 freeReg esp = fastBool False -- %esp is the C stack pointer
541 #if x86_64_TARGET_ARCH
542 freeReg rsp = fastBool False -- %rsp is the C stack pointer
546 freeReg REG_Base = fastBool False
549 freeReg REG_R1 = fastBool False
552 freeReg REG_R2 = fastBool False
555 freeReg REG_R3 = fastBool False
558 freeReg REG_R4 = fastBool False
561 freeReg REG_R5 = fastBool False
564 freeReg REG_R6 = fastBool False
567 freeReg REG_R7 = fastBool False
570 freeReg REG_R8 = fastBool False
573 freeReg REG_F1 = fastBool False
576 freeReg REG_F2 = fastBool False
579 freeReg REG_F3 = fastBool False
582 freeReg REG_F4 = fastBool False
585 freeReg REG_D1 = fastBool False
588 freeReg REG_D2 = fastBool False
591 freeReg REG_Sp = fastBool False
594 freeReg REG_Su = fastBool False
597 freeReg REG_SpLim = fastBool False
600 freeReg REG_Hp = fastBool False
603 freeReg REG_HpLim = fastBool False
605 freeReg n = fastBool True
608 -- | Returns 'Nothing' if this global register is not stored
609 -- in a real machine register, otherwise returns @'Just' reg@, where
610 -- reg is the machine register it is stored in.
613 globalRegMaybe BaseReg = Just (RealReg REG_Base)
616 globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1)
619 globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2)
622 globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3)
625 globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4)
628 globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5)
631 globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6)
634 globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7)
637 globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8)
640 globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9)
643 globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10)
646 globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1)
649 globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2)
652 globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3)
655 globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4)
658 globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1)
661 globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2)
664 globalRegMaybe Sp = Just (RealReg REG_Sp)
667 globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1)
670 globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2)
673 globalRegMaybe SpLim = Just (RealReg REG_SpLim)
676 globalRegMaybe Hp = Just (RealReg REG_Hp)
679 globalRegMaybe HpLim = Just (RealReg REG_HpLim)
681 #ifdef REG_CurrentTSO
682 globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO)
684 #ifdef REG_CurrentNursery
685 globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery)
687 globalRegMaybe _ = Nothing
689 #else /* i386_TARGET_ARCH || x86_64_TARGET_ARCH */
692 globalRegMaybe _ = panic "X86.Regs.globalRegMaybe: not defined"