X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FnativeGen%2FX86%2FRegs.hs;h=28d148c12c57b6607d5cf32bbec856efb0fefad8;hb=b2bd63f99d643f6b3eb30bb72bb9ae26d4183252;hp=bed9dc5c6e3f77f0470f1892d27448b970d0e2a0;hpb=335b9f366ac440259318777c4c07e4fa42fbbec6;p=ghc-hetmet.git diff --git a/compiler/nativeGen/X86/Regs.hs b/compiler/nativeGen/X86/Regs.hs index bed9dc5..28d148c 100644 --- a/compiler/nativeGen/X86/Regs.hs +++ b/compiler/nativeGen/X86/Regs.hs @@ -25,7 +25,7 @@ module X86.Regs ( EABase(..), EAIndex(..), addrModeRegs, eax, ebx, ecx, edx, esi, edi, ebp, esp, - fake0, fake1, fake2, fake3, fake4, fake5, + fake0, fake1, fake2, fake3, fake4, fake5, firstfake, rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13, r14, r15, @@ -40,7 +40,6 @@ module X86.Regs ( freeReg, globalRegMaybe, - get_GlobalReg_reg_or_addr, allocatableRegs ) @@ -54,9 +53,8 @@ where import Reg import RegClass -import CgUtils ( get_GlobalReg_addr ) import BlockId -import Cmm +import OldCmm import CLabel ( CLabel ) import Pretty import Outputable ( panic ) @@ -105,7 +103,7 @@ realRegSqueeze cls rr RcInteger -> case rr of RealRegSingle regNo - | regNo < 16 -> _ILIT(1) -- first xmm reg is 16 + | regNo < firstfake -> _ILIT(1) | otherwise -> _ILIT(0) RealRegPair{} -> _ILIT(0) @@ -113,14 +111,14 @@ realRegSqueeze cls rr RcDouble -> case rr of RealRegSingle regNo - | regNo >= 16 && regNo < 24 -> _ILIT(1) + | regNo >= firstfake && regNo <= lastfake -> _ILIT(1) | otherwise -> _ILIT(0) RealRegPair{} -> _ILIT(0) RcDoubleSSE -> case rr of - RealRegSingle regNo | regNo >= 24 -> _ILIT(1) + RealRegSingle regNo | regNo >= firstxmm -> _ILIT(1) _otherwise -> _ILIT(0) _other -> _ILIT(0) @@ -218,22 +216,45 @@ spRel _ = panic "X86.Regs.spRel: not defined for this architecture" #endif +-- The register numbers must fit into 32 bits on x86, so that we can +-- use a Word32 to represent the set of free registers in the register +-- allocator. + +firstfake, lastfake :: RegNo +firstfake = 16 +lastfake = 21 + +firstxmm, lastxmm :: RegNo +firstxmm = 24 +#if i386_TARGET_ARCH +lastxmm = 31 +#else +lastxmm = 39 +#endif + +lastint :: RegNo +#if i386_TARGET_ARCH +lastint = 7 -- not %r8..%r15 +#else +lastint = 15 +#endif + +intregnos, fakeregnos, xmmregnos, floatregnos :: [RegNo] +intregnos = [0..lastint] +fakeregnos = [firstfake .. lastfake] +xmmregnos = [firstxmm .. lastxmm] +floatregnos = fakeregnos ++ xmmregnos; + -- argRegs is the set of regs which are read for an n-argument call to C. -- For archs which pass all args on the stack (x86), is empty. -- Sparc passes up to the first 6 args in regs. --- Dunno about Alpha. 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..7] ++ floatregs -- not %r8..%r15 -#else -allMachRegNos = [0..15] ++ floatregs -#endif - where floatregs = fakes ++ xmms; fakes = [16..21]; xmms = [24..39] +allMachRegNos = intregnos ++ floatregnos -- | Take the class of a register. {-# INLINE classOfRealReg #-} @@ -245,19 +266,19 @@ classOfRealReg :: RealReg -> RegClass classOfRealReg reg = case reg of RealRegSingle i - | i < 16 -> RcInteger - | i < 24 -> RcDouble - | otherwise -> RcDoubleSSE + | i <= lastint -> RcInteger + | i <= lastfake -> RcDouble + | otherwise -> RcDoubleSSE RealRegPair{} -> panic "X86.Regs.classOfRealReg: RegPairs on this arch" -- | Get the name of the register with this number. showReg :: RegNo -> String showReg n - | n >= 24 = "%xmm" ++ show (n-24) - | n >= 16 = "%fake" ++ show (n-16) - | n >= 8 = "%r" ++ show n - | otherwise = regNames !! n + | n >= firstxmm = "%xmm" ++ show (n-firstxmm) + | n >= firstfake = "%fake" ++ show (n-firstfake) + | n >= 8 = "%r" ++ show n + | otherwise = regNames !! n regNames :: [String] regNames @@ -265,9 +286,12 @@ regNames = ["%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp", "%esp"] #elif x86_64_TARGET_ARCH = ["%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", "%rbp", "%rsp" ] +#else + = [] #endif + -- machine specific ------------------------------------------------------------ @@ -277,7 +301,7 @@ Intel x86 architecture: - Only ebx, esi, edi and esp are available across a C call (they are callee-saves). - Registers 0-7 have 16-bit counterparts (ax, bx etc.) - Registers 0-3 have 8 bit counterparts (ah, bh etc.) -- Registers 8-13 are fakes; we pretend x86 has 6 conventionally-addressable +- Registers fake0..fake5 are fakes; we pretend x86 has 6 conventionally-addressable fp registers, and 3-operand insns for them, and we translate this into real stack-based x86 fp code after register allocation. @@ -308,10 +332,24 @@ fake5 = regSingle 21 {- AMD x86_64 architecture: -- Registers 0-16 have 32-bit counterparts (eax, ebx etc.) -- Registers 0-7 have 16-bit counterparts (ax, bx etc.) -- Registers 0-3 have 8 bit counterparts (ah, bh etc.) - +- All 16 integer registers are addressable as 8, 16, 32 and 64-bit values: + + 8 16 32 64 + --------------------- + al ax eax rax + bl bx ebx rbx + cl cx ecx rcx + dl dx edx rdx + sil si esi rsi + dil si edi rdi + bpl bp ebp rbp + spl sp esp rsp + r10b r10w r10d r10 + r11b r11w r11d r11 + r12b r12w r12d r12 + r13b r13w r13d r13 + r14b r14w r14d r14 + r15b r15w r15d r15 -} rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, @@ -353,7 +391,7 @@ xmm14 = regSingle 38 xmm15 = regSingle 39 allFPArgRegs :: [Reg] -allFPArgRegs = map regSingle [24 .. 31] +allFPArgRegs = map regSingle [firstxmm .. firstxmm+7] ripRel :: Displacement -> AddrMode ripRel imm = AddrBaseIndex EABaseRip EAIndexNone imm @@ -372,7 +410,7 @@ esp = rsp -} xmm :: RegNo -> Reg -xmm n = regSingle (24+n) +xmm n = regSingle (firstxmm+n) @@ -439,7 +477,6 @@ callClobberedRegs :: [Reg] #define xmm14 38 #define xmm15 39 - #if i386_TARGET_ARCH freeReg esp = fastBool False -- %esp is the C stack pointer #endif @@ -610,13 +647,13 @@ allArgRegs = panic "X86.Regs.allArgRegs: not defined for this architecture" #if i386_TARGET_ARCH -- caller-saves registers callClobberedRegs - = map regSingle ([eax,ecx,edx] ++ [16..39]) + = map regSingle ([eax,ecx,edx] ++ floatregnos) #elif x86_64_TARGET_ARCH -- all xmm regs are caller-saves -- caller-saves registers callClobberedRegs - = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ [16..39]) + = map regSingle ([rax,rcx,rdx,rsi,rdi,r8,r9,r10,r11] ++ floatregnos) #else callClobberedRegs @@ -636,20 +673,6 @@ callClobberedRegs = panic "X86.Regs.globalRegMaybe: not defined" #endif --- We map STG registers onto appropriate CmmExprs. Either they map --- to real machine registers or stored as offsets from BaseReg. Given --- a GlobalReg, get_GlobalReg_reg_or_addr produces either the real --- register it is in, on this platform, or a CmmExpr denoting the --- address in the register table holding it. --- (See also get_GlobalReg_addr in CgUtils.) - -get_GlobalReg_reg_or_addr :: GlobalReg -> Either RealReg CmmExpr -get_GlobalReg_reg_or_addr mid - = case globalRegMaybe mid of - Just rr -> Left rr - Nothing -> Right (get_GlobalReg_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.