{-# LANGUAGE CPP #-}
module GHC.CmmToAsm.PPC.Regs (
virtualRegSqueeze,
realRegSqueeze,
mkVirtualReg,
regDotColor,
Imm(..),
strImmLit,
litToImm,
AddrMode(..),
addrOffset,
spRel,
argRegs,
allArgRegs,
callClobberedRegs,
allMachRegNos,
classOfRealReg,
showReg,
toRegNo,
allFPArgRegs,
fits16Bits,
makeImmediate,
fReg,
r0, sp, toc, r3, r4, r11, r12, r30,
tmpReg,
f1,
allocatableRegs
)
where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Platform.Reg
import GHC.Platform.Reg.Class
import GHC.CmmToAsm.Format
import GHC.Cmm
import GHC.Cmm.CLabel ( CLabel )
import GHC.Types.Unique
import GHC.Platform.Regs
import GHC.Utils.Outputable
import GHC.Platform
import Data.Word ( Word8, Word16, Word32, Word64 )
import Data.Int ( Int8, Int16, Int32, Int64 )
{-# INLINE virtualRegSqueeze #-}
virtualRegSqueeze :: RegClass -> VirtualReg -> Int
virtualRegSqueeze :: RegClass -> VirtualReg -> Int
virtualRegSqueeze RegClass
cls VirtualReg
vr
= case RegClass
cls of
RegClass
RcInteger
-> case VirtualReg
vr of
VirtualRegI{} -> Int
1
VirtualRegHi{} -> Int
1
VirtualReg
_other -> Int
0
RegClass
RcDouble
-> case VirtualReg
vr of
VirtualRegD{} -> Int
1
VirtualRegF{} -> Int
0
VirtualReg
_other -> Int
0
RegClass
_other -> Int
0
{-# INLINE realRegSqueeze #-}
realRegSqueeze :: RegClass -> RealReg -> Int
realRegSqueeze :: RegClass -> RealReg -> Int
realRegSqueeze RegClass
cls RealReg
rr
= case RegClass
cls of
RegClass
RcInteger
-> case RealReg
rr of
RealRegSingle Int
regNo
| Int
regNo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
32 -> Int
1
| Bool
otherwise -> Int
0
RealRegPair{} -> Int
0
RegClass
RcDouble
-> case RealReg
rr of
RealRegSingle Int
regNo
| Int
regNo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
32 -> Int
0
| Bool
otherwise -> Int
1
RealRegPair{} -> Int
0
RegClass
_other -> Int
0
mkVirtualReg :: Unique -> Format -> VirtualReg
mkVirtualReg :: Unique -> Format -> VirtualReg
mkVirtualReg Unique
u Format
format
| Bool -> Bool
not (Format -> Bool
isFloatFormat Format
format) = Unique -> VirtualReg
VirtualRegI Unique
u
| Bool
otherwise
= case Format
format of
Format
FF32 -> Unique -> VirtualReg
VirtualRegD Unique
u
Format
FF64 -> Unique -> VirtualReg
VirtualRegD Unique
u
Format
_ -> String -> VirtualReg
forall a. String -> a
panic String
"mkVirtualReg"
regDotColor :: RealReg -> SDoc
regDotColor :: RealReg -> SDoc
regDotColor RealReg
reg
= case RealReg -> RegClass
classOfRealReg RealReg
reg of
RegClass
RcInteger -> String -> SDoc
text String
"blue"
RegClass
RcFloat -> String -> SDoc
text String
"red"
RegClass
RcDouble -> String -> SDoc
text String
"green"
data Imm
= ImmInt Int
| ImmInteger Integer
| ImmCLbl CLabel
| ImmLit SDoc
| ImmIndex CLabel Int
| ImmFloat Rational
| ImmDouble Rational
| ImmConstantSum Imm Imm
| ImmConstantDiff Imm Imm
| LO Imm
| HI Imm
| HA Imm
| HIGHERA Imm
| HIGHESTA Imm
strImmLit :: String -> Imm
strImmLit :: String -> Imm
strImmLit String
s = SDoc -> Imm
ImmLit (String -> SDoc
text String
s)
litToImm :: CmmLit -> Imm
litToImm :: CmmLit -> Imm
litToImm (CmmInt Integer
i Width
w) = Integer -> Imm
ImmInteger (Width -> Integer -> Integer
narrowS Width
w Integer
i)
litToImm (CmmFloat Rational
f Width
W32) = Rational -> Imm
ImmFloat Rational
f
litToImm (CmmFloat Rational
f Width
W64) = Rational -> Imm
ImmDouble Rational
f
litToImm (CmmLabel CLabel
l) = CLabel -> Imm
ImmCLbl CLabel
l
litToImm (CmmLabelOff CLabel
l Int
off) = CLabel -> Int -> Imm
ImmIndex CLabel
l Int
off
litToImm (CmmLabelDiffOff CLabel
l1 CLabel
l2 Int
off Width
_)
= Imm -> Imm -> Imm
ImmConstantSum
(Imm -> Imm -> Imm
ImmConstantDiff (CLabel -> Imm
ImmCLbl CLabel
l1) (CLabel -> Imm
ImmCLbl CLabel
l2))
(Int -> Imm
ImmInt Int
off)
litToImm CmmLit
_ = String -> Imm
forall a. String -> a
panic String
"PPC.Regs.litToImm: no match"
data AddrMode
= AddrRegReg Reg Reg
| AddrRegImm Reg Imm
addrOffset :: AddrMode -> Int -> Maybe AddrMode
addrOffset :: AddrMode -> Int -> Maybe AddrMode
addrOffset AddrMode
addr Int
off
= case AddrMode
addr of
AddrRegImm Reg
r (ImmInt Int
n)
| Int -> Bool
forall a. Integral a => a -> Bool
fits16Bits Int
n2 -> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (Reg -> Imm -> AddrMode
AddrRegImm Reg
r (Int -> Imm
ImmInt Int
n2))
| Bool
otherwise -> Maybe AddrMode
forall a. Maybe a
Nothing
where n2 :: Int
n2 = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off
AddrRegImm Reg
r (ImmInteger Integer
n)
| Integer -> Bool
forall a. Integral a => a -> Bool
fits16Bits Integer
n2 -> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (Reg -> Imm -> AddrMode
AddrRegImm Reg
r (Int -> Imm
ImmInt (Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
n2)))
| Bool
otherwise -> Maybe AddrMode
forall a. Maybe a
Nothing
where n2 :: Integer
n2 = Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
off
AddrMode
_ -> Maybe AddrMode
forall a. Maybe a
Nothing
spRel :: Platform
-> Int
-> AddrMode
spRel :: Platform -> Int -> AddrMode
spRel Platform
platform Int
n = Reg -> Imm -> AddrMode
AddrRegImm Reg
sp (Int -> Imm
ImmInt (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Platform -> Int
platformWordSizeInBytes Platform
platform))
argRegs :: RegNo -> [Reg]
argRegs :: Int -> [Reg]
argRegs Int
0 = []
argRegs Int
1 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3]
argRegs Int
2 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3,Int
4]
argRegs Int
3 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3..Int
5]
argRegs Int
4 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3..Int
6]
argRegs Int
5 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3..Int
7]
argRegs Int
6 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3..Int
8]
argRegs Int
7 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3..Int
9]
argRegs Int
8 = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3..Int
10]
argRegs Int
_ = String -> [Reg]
forall a. String -> a
panic String
"MachRegs.argRegs(powerpc): don't know about >8 arguments!"
allArgRegs :: [Reg]
allArgRegs :: [Reg]
allArgRegs = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
3..Int
10]
callClobberedRegs :: Platform -> [Reg]
callClobberedRegs :: Platform -> [Reg]
callClobberedRegs Platform
_platform
= (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle (Int
0Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int
2..Int
12] [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ (Int -> Int) -> [Int] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Int
fReg [Int
0..Int
13])
allMachRegNos :: [RegNo]
allMachRegNos :: [Int]
allMachRegNos = [Int
0..Int
63]
{-# INLINE classOfRealReg #-}
classOfRealReg :: RealReg -> RegClass
classOfRealReg :: RealReg -> RegClass
classOfRealReg (RealRegSingle Int
i)
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
32 = RegClass
RcInteger
| Bool
otherwise = RegClass
RcDouble
classOfRealReg (RealRegPair{})
= String -> RegClass
forall a. String -> a
panic String
"regClass(ppr): no reg pairs on this architecture"
showReg :: RegNo -> String
showReg :: Int -> String
showReg Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
31 = String
"%r" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
32 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
63 = String
"%f" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
32)
| Bool
otherwise = String
"%unknown_powerpc_real_reg_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
toRegNo :: Reg -> RegNo
toRegNo :: Reg -> Int
toRegNo (RegReal (RealRegSingle Int
n)) = Int
n
toRegNo Reg
_ = String -> Int
forall a. String -> a
panic String
"PPC.toRegNo: unsupported register"
allFPArgRegs :: Platform -> [Reg]
allFPArgRegs :: Platform -> [Reg]
allFPArgRegs Platform
platform
= case Platform -> OS
platformOS Platform
platform of
OS
OSAIX -> (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Reg
regSingle (Int -> Reg) -> (Int -> Int) -> Int -> Reg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
fReg) [Int
1..Int
13]
OS
_ -> case Platform -> Arch
platformArch Platform
platform of
Arch
ArchPPC -> (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Reg
regSingle (Int -> Reg) -> (Int -> Int) -> Int -> Reg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
fReg) [Int
1..Int
8]
ArchPPC_64 PPC_64ABI
_ -> (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Reg
regSingle (Int -> Reg) -> (Int -> Int) -> Int -> Reg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int
fReg) [Int
1..Int
13]
Arch
_ -> String -> [Reg]
forall a. String -> a
panic String
"PPC.Regs.allFPArgRegs: unknown PPC Linux"
fits16Bits :: Integral a => a -> Bool
fits16Bits :: forall a. Integral a => a -> Bool
fits16Bits a
x = a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= -a
32768 Bool -> Bool -> Bool
&& a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
32768
makeImmediate :: Integral a => Width -> Bool -> a -> Maybe Imm
makeImmediate :: forall a. Integral a => Width -> Bool -> a -> Maybe Imm
makeImmediate Width
rep Bool
signed a
x = (Int -> Imm) -> Maybe Int -> Maybe Imm
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Imm
ImmInt (Width -> Bool -> Maybe Int
toI16 Width
rep Bool
signed)
where
narrow :: Width -> Bool -> b
narrow Width
W64 Bool
False = Word64 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Word64)
narrow Width
W32 Bool
False = Word32 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Word32)
narrow Width
W16 Bool
False = Word16 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Word16)
narrow Width
W8 Bool
False = Word8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Word8)
narrow Width
W64 Bool
True = Int64 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Int64)
narrow Width
W32 Bool
True = Int32 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Int32)
narrow Width
W16 Bool
True = Int16 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int16
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Int16)
narrow Width
W8 Bool
True = Int8 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
x :: Int8)
narrow Width
_ Bool
_ = String -> b
forall a. String -> a
panic String
"PPC.Regs.narrow: no match"
narrowed :: Int
narrowed = Width -> Bool -> Int
forall {b}. Num b => Width -> Bool -> b
narrow Width
rep Bool
signed
toI16 :: Width -> Bool -> Maybe Int
toI16 Width
W32 Bool
True
| Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= -Int
32768 Bool -> Bool -> Bool
&& Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
32768 = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
narrowed
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
toI16 Width
W32 Bool
False
| Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
65536 = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
narrowed
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
toI16 Width
W64 Bool
True
| Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= -Int
32768 Bool -> Bool -> Bool
&& Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
32768 = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
narrowed
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
toI16 Width
W64 Bool
False
| Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
narrowed Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
65536 = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
narrowed
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
toI16 Width
_ Bool
_ = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
narrowed
fReg :: Int -> RegNo
fReg :: Int -> Int
fReg Int
x = (Int
32 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x)
r0, sp, toc, r3, r4, r11, r12, r30, f1 :: Reg
r0 :: Reg
r0 = Int -> Reg
regSingle Int
0
sp :: Reg
sp = Int -> Reg
regSingle Int
1
toc :: Reg
toc = Int -> Reg
regSingle Int
2
r3 :: Reg
r3 = Int -> Reg
regSingle Int
3
r4 :: Reg
r4 = Int -> Reg
regSingle Int
4
r11 :: Reg
r11 = Int -> Reg
regSingle Int
11
r12 :: Reg
r12 = Int -> Reg
regSingle Int
12
r30 :: Reg
r30 = Int -> Reg
regSingle Int
30
f1 :: Reg
f1 = Int -> Reg
regSingle (Int -> Reg) -> Int -> Reg
forall a b. (a -> b) -> a -> b
$ Int -> Int
fReg Int
1
allocatableRegs :: Platform -> [RealReg]
allocatableRegs :: Platform -> [RealReg]
allocatableRegs Platform
platform
= let isFree :: Int -> Bool
isFree Int
i = Platform -> Int -> Bool
freeReg Platform
platform Int
i
in (Int -> RealReg) -> [Int] -> [RealReg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> RealReg
RealRegSingle ([Int] -> [RealReg]) -> [Int] -> [RealReg]
forall a b. (a -> b) -> a -> b
$ (Int -> Bool) -> [Int] -> [Int]
forall a. (a -> Bool) -> [a] -> [a]
filter Int -> Bool
isFree [Int]
allMachRegNos
tmpReg :: Platform -> Reg
tmpReg :: Platform -> Reg
tmpReg Platform
platform =
case Platform -> Arch
platformArch Platform
platform of
Arch
ArchPPC -> Int -> Reg
regSingle Int
13
ArchPPC_64 PPC_64ABI
_ -> Int -> Reg
regSingle Int
30
Arch
_ -> String -> Reg
forall a. String -> a
panic String
"PPC.Regs.tmpReg: unknown arch"