X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FnativeGen%2FX86%2FRegs.hs;h=bed9dc5c6e3f77f0470f1892d27448b970d0e2a0;hb=335b9f366ac440259318777c4c07e4fa42fbbec6;hp=5db3ab1fa6b069c550f3993ab4be13c370ef1e70;hpb=20c0e6ccf28b0961d2c5f6516b57e52fa2c13b33;p=ghc-hetmet.git diff --git a/compiler/nativeGen/X86/Regs.hs b/compiler/nativeGen/X86/Regs.hs index 5db3ab1..bed9dc5 100644 --- a/compiler/nativeGen/X86/Regs.hs +++ b/compiler/nativeGen/X86/Regs.hs @@ -1,4 +1,8 @@ module X86.Regs ( + -- squeese functions for the graph allocator + virtualRegSqueeze, + realRegSqueeze, + -- immediates Imm(..), strImmLit, @@ -14,7 +18,7 @@ module X86.Regs ( allArgRegs, callClobberedRegs, allMachRegNos, - regClass, + classOfRealReg, showReg, -- machine specific @@ -45,12 +49,7 @@ where #include "nativeGen/NCG.h" #include "HsVersions.h" -#if i386_TARGET_ARCH -# define STOLEN_X86_REGS 4 --- HACK: go for the max -#endif - -#include "../includes/MachRegs.h" +#include "../includes/stg/MachRegs.h" import Reg import RegClass @@ -61,15 +60,71 @@ import Cmm import CLabel ( CLabel ) import Pretty import Outputable ( panic ) -import qualified Outputable +import FastTypes import FastBool + #if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH) import Constants -import Outputable (ppr, pprPanic) #endif +-- | regSqueeze_class reg +-- Calculuate the maximum number of register colors that could be +-- denied to a node of this class due to having this reg +-- as a neighbour. +-- +{-# INLINE virtualRegSqueeze #-} +virtualRegSqueeze :: RegClass -> VirtualReg -> FastInt + +virtualRegSqueeze cls vr + = case cls of + RcInteger + -> case vr of + VirtualRegI{} -> _ILIT(1) + VirtualRegHi{} -> _ILIT(1) + _other -> _ILIT(0) + + RcDouble + -> case vr of + VirtualRegD{} -> _ILIT(1) + VirtualRegF{} -> _ILIT(0) + _other -> _ILIT(0) + + RcDoubleSSE + -> case vr of + VirtualRegSSE{} -> _ILIT(1) + _other -> _ILIT(0) + + _other -> _ILIT(0) + +{-# INLINE realRegSqueeze #-} +realRegSqueeze :: RegClass -> RealReg -> FastInt +realRegSqueeze cls rr + = case cls of + RcInteger + -> case rr of + RealRegSingle regNo + | regNo < 16 -> _ILIT(1) -- first xmm reg is 16 + | otherwise -> _ILIT(0) + + RealRegPair{} -> _ILIT(0) + + RcDouble + -> case rr of + RealRegSingle regNo + | regNo >= 16 && regNo < 24 -> _ILIT(1) + | otherwise -> _ILIT(0) + + RealRegPair{} -> _ILIT(0) + + RcDoubleSSE + -> case rr of + RealRegSingle regNo | regNo >= 24 -> _ILIT(1) + _otherwise -> _ILIT(0) + + _other -> _ILIT(0) + -- ----------------------------------------------------------------------------- -- Immediates @@ -171,89 +226,48 @@ spRel _ = panic "X86.Regs.spRel: not defined for this architecture" argRegs :: RegNo -> [Reg] argRegs _ = panic "MachRegs.argRegs(x86): should not be used!" - - - - -- | The complete set of machine registers. allMachRegNos :: [RegNo] - -#if i386_TARGET_ARCH -allMachRegNos = [0..13] - -#elif x86_64_TARGET_ARCH -allMachRegNos = [0..31] - +#if i386_TARGET_ARCH +allMachRegNos = [0..7] ++ floatregs -- not %r8..%r15 #else -allMachRegNos = panic "X86.Regs.callClobberedRegs: not defined for this architecture" - +allMachRegNos = [0..15] ++ floatregs #endif - + where floatregs = fakes ++ xmms; fakes = [16..21]; xmms = [24..39] -- | Take the class of a register. -{-# INLINE regClass #-} -regClass :: Reg -> RegClass - -#if i386_TARGET_ARCH +{-# INLINE classOfRealReg #-} +classOfRealReg :: RealReg -> RegClass -- On x86, we might want to have an 8-bit RegClass, which would -- contain just regs 1-4 (the others don't have 8-bit versions). -- However, we can get away without this at the moment because the -- only allocatable integer regs are also 8-bit compatible (1, 3, 4). -regClass (RealReg i) = if i < 8 then RcInteger else RcDouble -regClass (VirtualRegI _) = RcInteger -regClass (VirtualRegHi _) = RcInteger -regClass (VirtualRegD _) = RcDouble -regClass (VirtualRegF u) = pprPanic ("regClass(x86):VirtualRegF") (ppr u) - -#elif x86_64_TARGET_ARCH --- On x86, we might want to have an 8-bit RegClass, which would --- contain just regs 1-4 (the others don't have 8-bit versions). --- However, we can get away without this at the moment because the --- only allocatable integer regs are also 8-bit compatible (1, 3, 4). -regClass (RealReg i) = if i < 16 then RcInteger else RcDouble -regClass (VirtualRegI _) = RcInteger -regClass (VirtualRegHi _) = RcInteger -regClass (VirtualRegD _) = RcDouble -regClass (VirtualRegF u) = pprPanic "regClass(x86_64):VirtualRegF" (ppr u) - -#else -regClass _ = panic "X86.Regs.regClass: not defined for this architecture" - -#endif +classOfRealReg reg + = case reg of + RealRegSingle i + | i < 16 -> RcInteger + | i < 24 -> RcDouble + | otherwise -> RcDoubleSSE + RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch" -- | Get the name of the register with this number. showReg :: RegNo -> String - -#if i386_TARGET_ARCH -showReg n - = if n >= 0 && n < 14 - then regNames !! n - else "%unknown_x86_real_reg_" ++ show n - -regNames :: [String] -regNames - = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp", - "%fake0", "%fake1", "%fake2", "%fake3", "%fake4", "%fake5", "%fake6"] - -#elif x86_64_TARGET_ARCH showReg n - | n >= 16 = "%xmm" ++ show (n-16) + | n >= 24 = "%xmm" ++ show (n-24) + | n >= 16 = "%fake" ++ show (n-16) | n >= 8 = "%r" ++ show n | otherwise = regNames !! n regNames :: [String] regNames - = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ] - -#else -showReg _ = panic "X86.Regs.showReg: not defined for this architecture" - +#if i386_TARGET_ARCH + = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"] +#elif x86_64_TARGET_ARCH + = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ] #endif - - -- machine specific ------------------------------------------------------------ @@ -275,20 +289,20 @@ never generate them. fake0, fake1, fake2, fake3, fake4, fake5, eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg -eax = RealReg 0 -ebx = RealReg 1 -ecx = RealReg 2 -edx = RealReg 3 -esi = RealReg 4 -edi = RealReg 5 -ebp = RealReg 6 -esp = RealReg 7 -fake0 = RealReg 8 -fake1 = RealReg 9 -fake2 = RealReg 10 -fake3 = RealReg 11 -fake4 = RealReg 12 -fake5 = RealReg 13 +eax = regSingle 0 +ebx = regSingle 1 +ecx = regSingle 2 +edx = regSingle 3 +esi = regSingle 4 +edi = regSingle 5 +ebp = regSingle 6 +esp = regSingle 7 +fake0 = regSingle 16 +fake1 = regSingle 17 +fake2 = regSingle 18 +fake3 = regSingle 19 +fake4 = regSingle 20 +fake5 = regSingle 21 @@ -305,41 +319,41 @@ rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg -rax = RealReg 0 -rbx = RealReg 1 -rcx = RealReg 2 -rdx = RealReg 3 -rsi = RealReg 4 -rdi = RealReg 5 -rbp = RealReg 6 -rsp = RealReg 7 -r8 = RealReg 8 -r9 = RealReg 9 -r10 = RealReg 10 -r11 = RealReg 11 -r12 = RealReg 12 -r13 = RealReg 13 -r14 = RealReg 14 -r15 = RealReg 15 -xmm0 = RealReg 16 -xmm1 = RealReg 17 -xmm2 = RealReg 18 -xmm3 = RealReg 19 -xmm4 = RealReg 20 -xmm5 = RealReg 21 -xmm6 = RealReg 22 -xmm7 = RealReg 23 -xmm8 = RealReg 24 -xmm9 = RealReg 25 -xmm10 = RealReg 26 -xmm11 = RealReg 27 -xmm12 = RealReg 28 -xmm13 = RealReg 29 -xmm14 = RealReg 30 -xmm15 = RealReg 31 +rax = regSingle 0 +rbx = regSingle 1 +rcx = regSingle 2 +rdx = regSingle 3 +rsi = regSingle 4 +rdi = regSingle 5 +rbp = regSingle 6 +rsp = regSingle 7 +r8 = regSingle 8 +r9 = regSingle 9 +r10 = regSingle 10 +r11 = regSingle 11 +r12 = regSingle 12 +r13 = regSingle 13 +r14 = regSingle 14 +r15 = regSingle 15 +xmm0 = regSingle 24 +xmm1 = regSingle 25 +xmm2 = regSingle 26 +xmm3 = regSingle 27 +xmm4 = regSingle 28 +xmm5 = regSingle 29 +xmm6 = regSingle 30 +xmm7 = regSingle 31 +xmm8 = regSingle 32 +xmm9 = regSingle 33 +xmm10 = regSingle 34 +xmm11 = regSingle 35 +xmm12 = regSingle 36 +xmm13 = regSingle 37 +xmm14 = regSingle 38 +xmm15 = regSingle 39 allFPArgRegs :: [Reg] -allFPArgRegs = map RealReg [16 .. 23] +allFPArgRegs = map regSingle [24 .. 31] ripRel :: Displacement -> AddrMode ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm @@ -358,14 +372,14 @@ esp = rsp -} xmm :: RegNo -> Reg -xmm n = RealReg (16+n) +xmm n = regSingle (24+n) -- horror show ----------------------------------------------------------------- freeReg :: RegNo -> FastBool -globalRegMaybe :: GlobalReg -> Maybe Reg +globalRegMaybe :: GlobalReg -> Maybe RealReg allArgRegs :: [Reg] callClobberedRegs :: [Reg] @@ -380,12 +394,6 @@ callClobberedRegs :: [Reg] #define edi 5 #define ebp 6 #define esp 7 -#define fake0 8 -#define fake1 9 -#define fake2 10 -#define fake3 11 -#define fake4 12 -#define fake5 13 #endif #if x86_64_TARGET_ARCH @@ -405,24 +413,31 @@ callClobberedRegs :: [Reg] #define r13 13 #define r14 14 #define r15 15 -#define xmm0 16 -#define xmm1 17 -#define xmm2 18 -#define xmm3 19 -#define xmm4 20 -#define xmm5 21 -#define xmm6 22 -#define xmm7 23 -#define xmm8 24 -#define xmm9 25 -#define xmm10 26 -#define xmm11 27 -#define xmm12 28 -#define xmm13 29 -#define xmm14 30 -#define xmm15 31 #endif +#define fake0 16 +#define fake1 17 +#define fake2 18 +#define fake3 19 +#define fake4 20 +#define fake5 21 + +#define xmm0 24 +#define xmm1 25 +#define xmm2 26 +#define xmm3 27 +#define xmm4 28 +#define xmm5 29 +#define xmm6 30 +#define xmm7 31 +#define xmm8 32 +#define xmm9 33 +#define xmm10 34 +#define xmm11 35 +#define xmm12 36 +#define xmm13 37 +#define xmm14 38 +#define xmm15 39 #if i386_TARGET_ARCH @@ -501,79 +516,79 @@ freeReg _ = fastBool True -- reg is the machine register it is stored in. #ifdef REG_Base -globalRegMaybe BaseReg = Just (RealReg REG_Base) +globalRegMaybe BaseReg = Just (RealRegSingle REG_Base) #endif #ifdef REG_R1 -globalRegMaybe (VanillaReg 1 _) = Just (RealReg REG_R1) +globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1) #endif #ifdef REG_R2 -globalRegMaybe (VanillaReg 2 _) = Just (RealReg REG_R2) +globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2) #endif #ifdef REG_R3 -globalRegMaybe (VanillaReg 3 _) = Just (RealReg REG_R3) +globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3) #endif #ifdef REG_R4 -globalRegMaybe (VanillaReg 4 _) = Just (RealReg REG_R4) +globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4) #endif #ifdef REG_R5 -globalRegMaybe (VanillaReg 5 _) = Just (RealReg REG_R5) +globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5) #endif #ifdef REG_R6 -globalRegMaybe (VanillaReg 6 _) = Just (RealReg REG_R6) +globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6) #endif #ifdef REG_R7 -globalRegMaybe (VanillaReg 7 _) = Just (RealReg REG_R7) +globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7) #endif #ifdef REG_R8 -globalRegMaybe (VanillaReg 8 _) = Just (RealReg REG_R8) +globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8) #endif #ifdef REG_R9 -globalRegMaybe (VanillaReg 9 _) = Just (RealReg REG_R9) +globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9) #endif #ifdef REG_R10 -globalRegMaybe (VanillaReg 10 _) = Just (RealReg REG_R10) +globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10) #endif #ifdef REG_F1 -globalRegMaybe (FloatReg 1) = Just (RealReg REG_F1) +globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1) #endif #ifdef REG_F2 -globalRegMaybe (FloatReg 2) = Just (RealReg REG_F2) +globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2) #endif #ifdef REG_F3 -globalRegMaybe (FloatReg 3) = Just (RealReg REG_F3) +globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3) #endif #ifdef REG_F4 -globalRegMaybe (FloatReg 4) = Just (RealReg REG_F4) +globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4) #endif #ifdef REG_D1 -globalRegMaybe (DoubleReg 1) = Just (RealReg REG_D1) +globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1) #endif #ifdef REG_D2 -globalRegMaybe (DoubleReg 2) = Just (RealReg REG_D2) +globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2) #endif #ifdef REG_Sp -globalRegMaybe Sp = Just (RealReg REG_Sp) +globalRegMaybe Sp = Just (RealRegSingle REG_Sp) #endif #ifdef REG_Lng1 -globalRegMaybe (LongReg 1) = Just (RealReg REG_Lng1) +globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1) #endif #ifdef REG_Lng2 -globalRegMaybe (LongReg 2) = Just (RealReg REG_Lng2) +globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2) #endif #ifdef REG_SpLim -globalRegMaybe SpLim = Just (RealReg REG_SpLim) +globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim) #endif #ifdef REG_Hp -globalRegMaybe Hp = Just (RealReg REG_Hp) +globalRegMaybe Hp = Just (RealRegSingle REG_Hp) #endif #ifdef REG_HpLim -globalRegMaybe HpLim = Just (RealReg REG_HpLim) +globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim) #endif #ifdef REG_CurrentTSO -globalRegMaybe CurrentTSO = Just (RealReg REG_CurrentTSO) +globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO) #endif #ifdef REG_CurrentNursery -globalRegMaybe CurrentNursery = Just (RealReg REG_CurrentNursery) +globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery) #endif globalRegMaybe _ = Nothing @@ -583,7 +598,7 @@ globalRegMaybe _ = Nothing allArgRegs = panic "X86.Regs.allArgRegs: should not be used!" #elif x86_64_TARGET_ARCH -allArgRegs = map RealReg [rdi,rsi,rdx,rcx,r8,r9] +allArgRegs = map regSingle [rdi,rsi,rdx,rcx,r8,r9] #else allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture" @@ -595,13 +610,13 @@ allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture" #if i386_TARGET_ARCH -- caller-saves registers callClobberedRegs - = map RealReg [eax,ecx,edx,fake0,fake1,fake2,fake3,fake4,fake5] + = map regSingle ([eax,ecx,edx] ++ [16..39]) #elif x86_64_TARGET_ARCH -- all xmm regs are caller-saves -- caller-saves registers callClobberedRegs - = map RealReg ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..31]) + = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..39]) #else callClobberedRegs @@ -628,7 +643,7 @@ callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined" -- address in the register table holding it. -- (See also get_GlobalReg_addr in CgUtils.) -get_GlobalReg_reg_or_addr :: GlobalReg -> Either Reg CmmExpr +get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr get_GlobalReg_reg_or_addr mid = case globalRegMaybe mid of Just rr -> Left rr @@ -638,9 +653,9 @@ get_GlobalReg_reg_or_addr mid -- allocatableRegs is allMachRegNos with the fixed-use regs removed. -- i.e., these are the regs for which we are prepared to allow the -- register allocator to attempt to map VRegs to. -allocatableRegs :: [RegNo] +allocatableRegs :: [RealReg] allocatableRegs = let isFree i = isFastTrue (freeReg i) - in filter isFree allMachRegNos + in map RealRegSingle $ filter isFree allMachRegNos