module GHC.CmmToAsm.X86.Regs (
virtualRegSqueeze,
realRegSqueeze,
Imm(..),
strImmLit,
litToImm,
AddrMode(..),
addrOffset,
spRel,
argRegs,
allArgRegs,
allIntArgRegs,
callClobberedRegs,
instrClobberedRegs,
allMachRegNos,
classOfRealReg,
EABase(..), EAIndex(..), addrModeRegs,
eax, ebx, ecx, edx, esi, edi, ebp, esp,
rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
r8, r9, r10, r11, r12, r13, r14, r15,
lastint,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
xmm,
firstxmm, lastxmm,
intregnos, xmmregnos,
ripRel,
allFPArgRegs,
allocatableRegs
)
where
import GHC.Prelude
import GHC.Data.FastString
import GHC.Platform.Regs
import GHC.Platform.Reg
import GHC.Platform.Reg.Class.Unified
import GHC.Cmm
import GHC.Cmm.CLabel ( CLabel )
import GHC.Utils.Panic
import GHC.Platform
{-# INLINE virtualRegSqueeze #-}
virtualRegSqueeze :: RegClass -> VirtualReg -> Int
virtualRegSqueeze :: RegClass -> VirtualReg -> RegNo
virtualRegSqueeze RegClass
cls VirtualReg
vr
= case RegClass
cls of
RegClass
RcInteger
-> case VirtualReg
vr of
VirtualRegI{} -> RegNo
1
VirtualRegHi{} -> RegNo
1
VirtualReg
_other -> RegNo
0
RegClass
RcFloatOrVector
-> case VirtualReg
vr of
VirtualRegD{} -> RegNo
1
VirtualRegV128{} -> RegNo
1
VirtualReg
_other -> RegNo
0
{-# INLINE realRegSqueeze #-}
realRegSqueeze :: RegClass -> RealReg -> Int
realRegSqueeze :: RegClass -> RealReg -> RegNo
realRegSqueeze RegClass
cls RealReg
rr
= case RegClass
cls of
RegClass
RcInteger
-> case RealReg
rr of
RealRegSingle RegNo
regNo
| RegNo
regNo RegNo -> RegNo -> Bool
forall a. Ord a => a -> a -> Bool
< RegNo
firstxmm -> RegNo
1
| Bool
otherwise -> RegNo
0
RegClass
RcFloatOrVector
-> case RealReg
rr of
RealRegSingle RegNo
regNo
| RegNo
regNo RegNo -> RegNo -> Bool
forall a. Ord a => a -> a -> Bool
>= RegNo
firstxmm -> RegNo
1
| Bool
otherwise -> RegNo
0
data Imm
= ImmInt Int
| ImmInteger Integer
| ImmCLbl CLabel
| ImmLit FastString
| ImmIndex CLabel Int
| ImmFloat Rational
| ImmDouble Rational
| ImmConstantSum Imm Imm
| ImmConstantDiff Imm Imm
strImmLit :: FastString -> Imm
strImmLit :: FastString -> Imm
strImmLit FastString
s = FastString -> Imm
ImmLit FastString
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 RegNo
off) = CLabel -> RegNo -> Imm
ImmIndex CLabel
l RegNo
off
litToImm (CmmLabelDiffOff CLabel
l1 CLabel
l2 RegNo
off Width
_)
= Imm -> Imm -> Imm
ImmConstantSum
(Imm -> Imm -> Imm
ImmConstantDiff (CLabel -> Imm
ImmCLbl CLabel
l1) (CLabel -> Imm
ImmCLbl CLabel
l2))
(RegNo -> Imm
ImmInt RegNo
off)
litToImm CmmLit
_ = String -> Imm
forall a. HasCallStack => String -> a
panic String
"X86.Regs.litToImm: no match"
data AddrMode
= AddrBaseIndex EABase EAIndex Displacement
| ImmAddr Imm Int
data EABase = EABaseNone | EABaseReg Reg | EABaseRip
data EAIndex = EAIndexNone | EAIndex Reg Int
type Displacement = Imm
addrOffset :: AddrMode -> Int -> Maybe AddrMode
addrOffset :: AddrMode -> RegNo -> Maybe AddrMode
addrOffset AddrMode
addr RegNo
off
= case AddrMode
addr of
ImmAddr Imm
i RegNo
off0 -> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (Imm -> RegNo -> AddrMode
ImmAddr Imm
i (RegNo
off0 RegNo -> RegNo -> RegNo
forall a. Num a => a -> a -> a
+ RegNo
off))
AddrBaseIndex EABase
r EAIndex
i (ImmInt RegNo
n) -> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
r EAIndex
i (RegNo -> Imm
ImmInt (RegNo
n RegNo -> RegNo -> RegNo
forall a. Num a => a -> a -> a
+ RegNo
off)))
AddrBaseIndex EABase
r EAIndex
i (ImmInteger Integer
n)
-> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
r EAIndex
i (RegNo -> Imm
ImmInt (Integer -> RegNo
forall a. Num a => Integer -> a
fromInteger (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ RegNo -> Integer
forall a. Integral a => a -> Integer
toInteger RegNo
off))))
AddrBaseIndex EABase
r EAIndex
i (ImmCLbl CLabel
lbl)
-> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
r EAIndex
i (CLabel -> RegNo -> Imm
ImmIndex CLabel
lbl RegNo
off))
AddrBaseIndex EABase
r EAIndex
i (ImmIndex CLabel
lbl RegNo
ix)
-> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
r EAIndex
i (CLabel -> RegNo -> Imm
ImmIndex CLabel
lbl (RegNo
ixRegNo -> RegNo -> RegNo
forall a. Num a => a -> a -> a
+RegNo
off)))
AddrMode
_ -> Maybe AddrMode
forall a. Maybe a
Nothing
addrModeRegs :: AddrMode -> [Reg]
addrModeRegs :: AddrMode -> [Reg]
addrModeRegs (AddrBaseIndex EABase
b EAIndex
i Imm
_) = [Reg]
b_regs [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ [Reg]
i_regs
where
b_regs :: [Reg]
b_regs = case EABase
b of { EABaseReg Reg
r -> [Reg
r]; EABase
_ -> [] }
i_regs :: [Reg]
i_regs = case EAIndex
i of { EAIndex Reg
r RegNo
_ -> [Reg
r]; EAIndex
_ -> [] }
addrModeRegs AddrMode
_ = []
spRel :: Platform
-> Int
-> AddrMode
spRel :: Platform -> RegNo -> AddrMode
spRel Platform
platform RegNo
n
| Platform -> Bool
target32Bit Platform
platform
= EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex (Reg -> EABase
EABaseReg Reg
esp) EAIndex
EAIndexNone (RegNo -> Imm
ImmInt RegNo
n)
| Bool
otherwise
= EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex (Reg -> EABase
EABaseReg Reg
rsp) EAIndex
EAIndexNone (RegNo -> Imm
ImmInt RegNo
n)
firstxmm :: RegNo
firstxmm :: RegNo
firstxmm = RegNo
16
lastxmm :: Platform -> RegNo
lastxmm :: Platform -> RegNo
lastxmm Platform
platform
| Platform -> Bool
target32Bit Platform
platform = RegNo
firstxmm RegNo -> RegNo -> RegNo
forall a. Num a => a -> a -> a
+ RegNo
7
| Bool
otherwise = RegNo
firstxmm RegNo -> RegNo -> RegNo
forall a. Num a => a -> a -> a
+ RegNo
15
lastint :: Platform -> RegNo
lastint :: Platform -> RegNo
lastint Platform
platform
| Platform -> Bool
target32Bit Platform
platform = RegNo
7
| Bool
otherwise = RegNo
15
intregnos :: Platform -> [RegNo]
intregnos :: Platform -> [RegNo]
intregnos Platform
platform = [RegNo
0 .. Platform -> RegNo
lastint Platform
platform]
xmmregnos :: Platform -> [RegNo]
xmmregnos :: Platform -> [RegNo]
xmmregnos Platform
platform = [RegNo
firstxmm .. Platform -> RegNo
lastxmm Platform
platform]
floatregnos :: Platform -> [RegNo]
floatregnos :: Platform -> [RegNo]
floatregnos Platform
platform = Platform -> [RegNo]
xmmregnos Platform
platform
argRegs :: RegNo -> [Reg]
argRegs :: RegNo -> [Reg]
argRegs RegNo
_ = String -> [Reg]
forall a. HasCallStack => String -> a
panic String
"MachRegs.argRegs(x86): should not be used!"
allMachRegNos :: Platform -> [RegNo]
allMachRegNos :: Platform -> [RegNo]
allMachRegNos Platform
platform = Platform -> [RegNo]
intregnos Platform
platform [RegNo] -> [RegNo] -> [RegNo]
forall a. [a] -> [a] -> [a]
++ Platform -> [RegNo]
floatregnos Platform
platform
{-# INLINE classOfRealReg #-}
classOfRealReg :: Platform -> RealReg -> RegClass
classOfRealReg :: Platform -> RealReg -> RegClass
classOfRealReg Platform
platform RealReg
reg
= case RealReg
reg of
RealRegSingle RegNo
i
| RegNo
i RegNo -> RegNo -> Bool
forall a. Ord a => a -> a -> Bool
<= Platform -> RegNo
lastint Platform
platform -> RegClass
RcInteger
| RegNo
i RegNo -> RegNo -> Bool
forall a. Ord a => a -> a -> Bool
<= Platform -> RegNo
lastxmm Platform
platform -> RegClass
RcFloatOrVector
| Bool
otherwise -> String -> RegClass
forall a. HasCallStack => String -> a
panic String
"X86.Reg.classOfRealReg registerSingle too high"
eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
eax :: Reg
eax = RegNo -> Reg
regSingle RegNo
0
ebx :: Reg
ebx = RegNo -> Reg
regSingle RegNo
1
ecx :: Reg
ecx = RegNo -> Reg
regSingle RegNo
2
edx :: Reg
edx = RegNo -> Reg
regSingle RegNo
3
esi :: Reg
esi = RegNo -> Reg
regSingle RegNo
4
edi :: Reg
edi = RegNo -> Reg
regSingle RegNo
5
ebp :: Reg
ebp = RegNo -> Reg
regSingle RegNo
6
esp :: Reg
esp = RegNo -> Reg
regSingle RegNo
7
rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 :: Reg
rax :: Reg
rax = RegNo -> Reg
regSingle RegNo
0
rbx :: Reg
rbx = RegNo -> Reg
regSingle RegNo
1
rcx :: Reg
rcx = RegNo -> Reg
regSingle RegNo
2
rdx :: Reg
rdx = RegNo -> Reg
regSingle RegNo
3
rsi :: Reg
rsi = RegNo -> Reg
regSingle RegNo
4
rdi :: Reg
rdi = RegNo -> Reg
regSingle RegNo
5
rbp :: Reg
rbp = RegNo -> Reg
regSingle RegNo
6
rsp :: Reg
rsp = RegNo -> Reg
regSingle RegNo
7
r8 :: Reg
r8 = RegNo -> Reg
regSingle RegNo
8
r9 :: Reg
r9 = RegNo -> Reg
regSingle RegNo
9
r10 :: Reg
r10 = RegNo -> Reg
regSingle RegNo
10
r11 :: Reg
r11 = RegNo -> Reg
regSingle RegNo
11
r12 :: Reg
r12 = RegNo -> Reg
regSingle RegNo
12
r13 :: Reg
r13 = RegNo -> Reg
regSingle RegNo
13
r14 :: Reg
r14 = RegNo -> Reg
regSingle RegNo
14
r15 :: Reg
r15 = RegNo -> Reg
regSingle RegNo
15
xmm0 :: Reg
xmm0 = RegNo -> Reg
regSingle RegNo
16
xmm1 :: Reg
xmm1 = RegNo -> Reg
regSingle RegNo
17
xmm2 :: Reg
xmm2 = RegNo -> Reg
regSingle RegNo
18
xmm3 :: Reg
xmm3 = RegNo -> Reg
regSingle RegNo
19
xmm4 :: Reg
xmm4 = RegNo -> Reg
regSingle RegNo
20
xmm5 :: Reg
xmm5 = RegNo -> Reg
regSingle RegNo
21
xmm6 :: Reg
xmm6 = RegNo -> Reg
regSingle RegNo
22
xmm7 :: Reg
xmm7 = RegNo -> Reg
regSingle RegNo
23
xmm8 :: Reg
xmm8 = RegNo -> Reg
regSingle RegNo
24
xmm9 :: Reg
xmm9 = RegNo -> Reg
regSingle RegNo
25
xmm10 :: Reg
xmm10 = RegNo -> Reg
regSingle RegNo
26
xmm11 :: Reg
xmm11 = RegNo -> Reg
regSingle RegNo
27
xmm12 :: Reg
xmm12 = RegNo -> Reg
regSingle RegNo
28
xmm13 :: Reg
xmm13 = RegNo -> Reg
regSingle RegNo
29
xmm14 :: Reg
xmm14 = RegNo -> Reg
regSingle RegNo
30
xmm15 :: Reg
xmm15 = RegNo -> Reg
regSingle RegNo
31
ripRel :: Displacement -> AddrMode
ripRel :: Imm -> AddrMode
ripRel Imm
imm = EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
EABaseRip EAIndex
EAIndexNone Imm
imm
xmm :: RegNo -> Reg
xmm :: RegNo -> Reg
xmm RegNo
n = RegNo -> Reg
regSingle (RegNo
firstxmmRegNo -> RegNo -> RegNo
forall a. Num a => a -> a -> a
+RegNo
n)
callClobberedRegs :: Platform -> [Reg]
callClobberedRegs :: Platform -> [Reg]
callClobberedRegs Platform
platform
| Platform -> Bool
target32Bit Platform
platform = [Reg
eax,Reg
ecx,Reg
edx] [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ (RegNo -> Reg) -> [RegNo] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map RegNo -> Reg
regSingle (Platform -> [RegNo]
floatregnos Platform
platform)
| Platform -> OS
platformOS Platform
platform OS -> OS -> Bool
forall a. Eq a => a -> a -> Bool
== OS
OSMinGW32
= [Reg
rax,Reg
rcx,Reg
rdx,Reg
r8,Reg
r9,Reg
r10,Reg
r11]
[Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ (RegNo -> Reg) -> [RegNo] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map RegNo -> Reg
xmm [RegNo
0 .. RegNo
5]
| Bool
otherwise
= [Reg
rax,Reg
rcx,Reg
rdx,Reg
rsi,Reg
rdi,Reg
r8,Reg
r9,Reg
r10,Reg
r11]
[Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ (RegNo -> Reg) -> [RegNo] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map RegNo -> Reg
regSingle (Platform -> [RegNo]
floatregnos Platform
platform)
allArgRegs :: Platform -> [(Reg, Reg)]
allArgRegs :: Platform -> [(Reg, Reg)]
allArgRegs Platform
platform
| Platform -> OS
platformOS Platform
platform OS -> OS -> Bool
forall a. Eq a => a -> a -> Bool
== OS
OSMinGW32 = [Reg] -> [Reg] -> [(Reg, Reg)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Reg
rcx,Reg
rdx,Reg
r8,Reg
r9]
((RegNo -> Reg) -> [RegNo] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map RegNo -> Reg
regSingle [RegNo
firstxmm ..])
| Bool
otherwise = String -> [(Reg, Reg)]
forall a. HasCallStack => String -> a
panic String
"X86.Regs.allArgRegs: not defined for this arch"
allIntArgRegs :: Platform -> [Reg]
allIntArgRegs :: Platform -> [Reg]
allIntArgRegs Platform
platform
| (Platform -> OS
platformOS Platform
platform OS -> OS -> Bool
forall a. Eq a => a -> a -> Bool
== OS
OSMinGW32) Bool -> Bool -> Bool
|| Platform -> Bool
target32Bit Platform
platform
= String -> [Reg]
forall a. HasCallStack => String -> a
panic String
"X86.Regs.allIntArgRegs: not defined for this platform"
| Bool
otherwise = [Reg
rdi,Reg
rsi,Reg
rdx,Reg
rcx,Reg
r8,Reg
r9]
allFPArgRegs :: Platform -> [Reg]
allFPArgRegs :: Platform -> [Reg]
allFPArgRegs Platform
platform
| Platform -> OS
platformOS Platform
platform OS -> OS -> Bool
forall a. Eq a => a -> a -> Bool
== OS
OSMinGW32
= String -> [Reg]
forall a. HasCallStack => String -> a
panic String
"X86.Regs.allFPArgRegs: not defined for this platform"
| Bool
otherwise = (RegNo -> Reg) -> [RegNo] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map RegNo -> Reg
regSingle [RegNo
firstxmm .. RegNo
firstxmm RegNo -> RegNo -> RegNo
forall a. Num a => a -> a -> a
+ RegNo
7 ]
instrClobberedRegs :: Platform -> [Reg]
instrClobberedRegs :: Platform -> [Reg]
instrClobberedRegs Platform
platform
| Platform -> Bool
target32Bit Platform
platform = [ Reg
eax, Reg
ecx, Reg
edx ]
| Bool
otherwise = [ Reg
rax, Reg
rcx, Reg
rdx ]
allocatableRegs :: Platform -> [RealReg]
allocatableRegs :: Platform -> [RealReg]
allocatableRegs Platform
platform
= let isFree :: RegNo -> Bool
isFree RegNo
i = Platform -> RegNo -> Bool
freeReg Platform
platform RegNo
i
in (RegNo -> RealReg) -> [RegNo] -> [RealReg]
forall a b. (a -> b) -> [a] -> [b]
map RegNo -> RealReg
RealRegSingle ([RegNo] -> [RealReg]) -> [RegNo] -> [RealReg]
forall a b. (a -> b) -> a -> b
$ (RegNo -> Bool) -> [RegNo] -> [RegNo]
forall a. (a -> Bool) -> [a] -> [a]
filter RegNo -> Bool
isFree (Platform -> [RegNo]
allMachRegNos Platform
platform)