module GHC.CmmToAsm.SPARC.Regs (
showReg,
virtualRegSqueeze,
realRegSqueeze,
classOfRealReg,
allRealRegs,
gReg, iReg, lReg, oReg, fReg,
fp, sp, g0, g1, g2, o0, o1, f0, f1, f6, f8, f22, f26, f27,
allocatableRegs,
argRegs,
allArgRegs,
callClobberedRegs,
mkVirtualReg,
regDotColor
)
where
import GHC.Prelude
import GHC.Platform.SPARC
import GHC.Platform.Reg
import GHC.Platform.Reg.Class
import GHC.CmmToAsm.Format
import GHC.Types.Unique
import GHC.Utils.Outputable
import GHC.Utils.Panic
showReg :: RegNo -> String
showReg n
| n >= 0 && n < 8 = "%g" ++ show n
| n >= 8 && n < 16 = "%o" ++ show (n8)
| n >= 16 && n < 24 = "%l" ++ show (n16)
| n >= 24 && n < 32 = "%i" ++ show (n24)
| n >= 32 && n < 64 = "%f" ++ show (n32)
| otherwise = panic "SPARC.Regs.showReg: unknown sparc register"
classOfRealReg :: RealReg -> RegClass
classOfRealReg reg
= case reg of
RealRegSingle i
| i < 32 -> RcInteger
| otherwise -> RcFloat
RealRegPair{} -> RcDouble
virtualRegSqueeze :: RegClass -> VirtualReg -> Int
virtualRegSqueeze cls vr
= case cls of
RcInteger
-> case vr of
VirtualRegI{} -> 1
VirtualRegHi{} -> 1
_other -> 0
RcFloat
-> case vr of
VirtualRegF{} -> 1
VirtualRegD{} -> 2
_other -> 0
RcDouble
-> case vr of
VirtualRegF{} -> 1
VirtualRegD{} -> 1
_other -> 0
realRegSqueeze :: RegClass -> RealReg -> Int
realRegSqueeze cls rr
= case cls of
RcInteger
-> case rr of
RealRegSingle regNo
| regNo < 32 -> 1
| otherwise -> 0
RealRegPair{} -> 0
RcFloat
-> case rr of
RealRegSingle regNo
| regNo < 32 -> 0
| otherwise -> 1
RealRegPair{} -> 2
RcDouble
-> case rr of
RealRegSingle regNo
| regNo < 32 -> 0
| otherwise -> 1
RealRegPair{} -> 1
allRealRegs :: [RealReg]
allRealRegs
= [ (RealRegSingle i) | i <- [0..63] ]
++ [ (RealRegPair i (i+1)) | i <- [32, 34 .. 62 ] ]
gReg, lReg, iReg, oReg, fReg :: Int -> RegNo
gReg x = x
oReg x = (8 + x)
lReg x = (16 + x)
iReg x = (24 + x)
fReg x = (32 + x)
g0, g1, g2, fp, sp, o0, o1, f0, f1, f6, f8, f22, f26, f27 :: Reg
f6 = RegReal (RealRegSingle (fReg 6))
f8 = RegReal (RealRegSingle (fReg 8))
f22 = RegReal (RealRegSingle (fReg 22))
f26 = RegReal (RealRegSingle (fReg 26))
f27 = RegReal (RealRegSingle (fReg 27))
g0 = RegReal (RealRegSingle (gReg 0))
g1 = RegReal (RealRegSingle (gReg 1))
g2 = RegReal (RealRegSingle (gReg 2))
fp = RegReal (RealRegSingle (iReg 6))
sp = RegReal (RealRegSingle (oReg 6))
o0 = RegReal (RealRegSingle (oReg 0))
o1 = RegReal (RealRegSingle (oReg 1))
f0 = RegReal (RealRegSingle (fReg 0))
f1 = RegReal (RealRegSingle (fReg 1))
allocatableRegs :: [RealReg]
allocatableRegs
= let isFree rr
= case rr of
RealRegSingle r -> freeReg r
RealRegPair r1 r2 -> freeReg r1 && freeReg r2
in filter isFree allRealRegs
argRegs :: RegNo -> [Reg]
argRegs r
= case r of
0 -> []
1 -> map (RegReal . RealRegSingle . oReg) [0]
2 -> map (RegReal . RealRegSingle . oReg) [0,1]
3 -> map (RegReal . RealRegSingle . oReg) [0,1,2]
4 -> map (RegReal . RealRegSingle . oReg) [0,1,2,3]
5 -> map (RegReal . RealRegSingle . oReg) [0,1,2,3,4]
6 -> map (RegReal . RealRegSingle . oReg) [0,1,2,3,4,5]
_ -> panic "MachRegs.argRegs(sparc): don't know about >6 arguments!"
allArgRegs :: [Reg]
allArgRegs
= map (RegReal . RealRegSingle) [oReg i | i <- [0..5]]
callClobberedRegs :: [Reg]
callClobberedRegs
= map (RegReal . RealRegSingle)
( oReg 7 :
[oReg i | i <- [0..5]] ++
[gReg i | i <- [1..7]] ++
[fReg i | i <- [0..31]] )
mkVirtualReg :: Unique -> Format -> VirtualReg
mkVirtualReg u format
| not (isFloatFormat format)
= VirtualRegI u
| otherwise
= case format of
FF32 -> VirtualRegF u
FF64 -> VirtualRegD u
_ -> panic "mkVReg"
regDotColor :: RealReg -> SDoc
regDotColor reg
= case classOfRealReg reg of
RcInteger -> text "blue"
RcFloat -> text "red"
_other -> text "green"