module GHC.CmmToAsm.Reg.Graph.X86 (
classOfReg,
regsOfClass,
regName,
regAlias,
worst,
squeese,
) where
import GHC.Prelude
import GHC.CmmToAsm.Reg.Graph.Base (Reg(..), RegSub(..), RegClass(..))
import GHC.Types.Unique.Set
import qualified Data.Array as A
classOfReg :: Reg -> RegClass
classOfReg reg
= case reg of
Reg c _ -> c
RegSub SubL16 _ -> ClassG16
RegSub SubL8 _ -> ClassG8
RegSub SubL8H _ -> ClassG8
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] ]
regName :: Reg -> Maybe String
regName reg
= case reg of
Reg ClassG32 i
| i <= 7 ->
let names = A.listArray (0,8)
[ "eax", "ebx", "ecx", "edx"
, "ebp", "esi", "edi", "esp" ]
in Just $ names A.! i
RegSub SubL16 (Reg ClassG32 i)
| i <= 7 ->
let names = A.listArray (0,8)
[ "ax", "bx", "cx", "dx"
, "bp", "si", "di", "sp"]
in Just $ names A.! i
RegSub SubL8 (Reg ClassG32 i)
| i <= 3 ->
let names = A.listArray (0,4) [ "al", "bl", "cl", "dl"]
in Just $ names A.! i
RegSub SubL8H (Reg ClassG32 i)
| i <= 3 ->
let names = A.listArray (0,4) [ "ah", "bh", "ch", "dh"]
in Just $ names A.! i
_ -> Nothing
regAlias :: Reg -> UniqSet Reg
regAlias reg
= case reg of
Reg ClassG32 i
| i <= 3
-> mkUniqSet
$ [ Reg ClassG32 i, RegSub SubL16 reg
, RegSub SubL8 reg, RegSub SubL8H reg ]
| 4 <= i && i <= 7
-> mkUniqSet
$ [ Reg ClassG32 i, RegSub SubL16 reg ]
RegSub SubL16 r@(Reg ClassG32 _)
-> regAlias r
RegSub SubL8 r@(Reg ClassG32 _)
-> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8 r ]
RegSub SubL8H r@(Reg ClassG32 _)
-> mkUniqSet $ [ r, RegSub SubL16 r, RegSub SubL8H r ]
Reg ClassF64 _
-> unitUniqSet reg
_ -> error "regAlias: invalid register"
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)