-- | A description of the register set of the X86. -- This isn't used directly in GHC proper. -- -- See RegArchBase.hs for the reference. -- See MachRegs.hs for the actual trivColorable function used in GHC. -- {-# OPTIONS_GHC -w #-} -- The above warning supression flag is a temporary kludge. -- While working on this module you are encouraged to remove it and fix -- any warnings in the module. See -- http://hackage.haskell.org/trac/ghc/wiki/WorkingConventions#Warnings -- for details module RegArchX86 ( classOfReg, regsOfClass, regName, regAlias, worst, squeese, ) where import RegArchBase (Reg(..), RegSub(..), RegClass(..)) import UniqSet -- | Determine the class of a register classOfReg :: Reg -> RegClass classOfReg reg = case reg of Reg c i -> c RegSub SubL16 r -> ClassG16 RegSub SubL8 r -> ClassG8 RegSub SubL8H r -> ClassG8 -- | Determine all the regs that make up a certain class. -- regsOfClass :: RegClass -> UniqSet Reg regsOfClass c = case c of ClassG32 -> mkUniqSet [ Reg ClassG32 i | i <- [0..7] ] ClassG16 -> mkUniqSet [ RegSub SubL16 (Reg ClassG32 i) | i <- [0..7] ] ClassG8 -> unionUniqSets (mkUniqSet [ RegSub SubL8 (Reg ClassG32 i) | i <- [0..3] ]) (mkUniqSet [ RegSub SubL8H (Reg ClassG32 i) | i <- [0..3] ]) ClassF64 -> mkUniqSet [ Reg ClassF64 i | i <- [0..5] ] -- | Determine the common name of a reg -- returns Nothing if this reg is not part of the machine. regName :: Reg -> Maybe String regName reg = case reg of Reg ClassG32 i | i <= 7 -> Just ([ "eax", "ebx", "ecx", "edx", "ebp", "esi", "edi", "esp" ] !! i) RegSub SubL16 (Reg ClassG32 i) | i <= 7 -> Just ([ "ax", "bx", "cx", "dx", "bp", "si", "di", "sp"] !! i) RegSub SubL8 (Reg ClassG32 i) | i <= 3 -> Just ([ "al", "bl", "cl", "dl"] !! i) RegSub SubL8H (Reg ClassG32 i) | i <= 3 -> Just ([ "ah", "bh", "ch", "dh"] !! i) _ -> Nothing -- | Which regs alias what other regs regAlias :: Reg -> UniqSet Reg regAlias reg = case reg of -- 32 bit regs alias all of the subregs Reg ClassG32 i -- for eax, ebx, ecx, eds | i <= 3 -> mkUniqSet $ [ Reg ClassG32 i, RegSub SubL16 reg, RegSub SubL8 reg, RegSub SubL8H reg ] -- for esi, edi, esp, ebp | 4 <= i && i <= 7 -> mkUniqSet $ [ Reg ClassG32 i, RegSub SubL16 reg ] -- 16 bit subregs alias the whole reg RegSub SubL16 r@(Reg ClassG32 i) -> regAlias r -- 8 bit subregs alias the 32 and 16, but not the other 8 bit subreg RegSub SubL8 r@(Reg ClassG32 i) -> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8 r ] RegSub SubL8H r@(Reg ClassG32 i) -> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8H r ] -- fp Reg ClassF64 i -> unitUniqSet reg _ -> error "regAlias: invalid register" -- | Optimised versions of RegColorBase.{worst, squeese} specific to x86 worst :: Int -> RegClass -> RegClass -> Int worst n classN classC = case classN of ClassG32 -> case classC of ClassG32 -> min n 8 ClassG16 -> min n 8 ClassG8 -> min n 4 ClassF64 -> 0 ClassG16 -> case classC of ClassG32 -> min n 8 ClassG16 -> min n 8 ClassG8 -> min n 4 ClassF64 -> 0 ClassG8 -> case classC of ClassG32 -> min (n*2) 8 ClassG16 -> min (n*2) 8 ClassG8 -> min n 8 ClassF64 -> 0 ClassF64 -> case classC of ClassF64 -> min n 6 _ -> 0 squeese :: RegClass -> [(Int, RegClass)] -> Int squeese classN countCs = sum (map (\(i, classC) -> worst i classN classC) countCs)