{-# LANGUAGE CPP #-}
module X86.Regs (
virtualRegSqueeze,
realRegSqueeze,
Imm(..),
strImmLit,
litToImm,
AddrMode(..),
addrOffset,
spRel,
argRegs,
allArgRegs,
allIntArgRegs,
callClobberedRegs,
instrClobberedRegs,
allMachRegNos,
classOfRealReg,
showReg,
EABase(..), EAIndex(..), addrModeRegs,
eax, ebx, ecx, edx, esi, edi, ebp, esp,
fake0, fake1, fake2, fake3, fake4, fake5, firstfake,
rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
xmm,
ripRel,
allFPArgRegs,
allocatableRegs
)
where
#include "nativeGen/NCG.h"
#include "GhclibHsVersions.h"
import GhcPrelude
import CodeGen.Platform
import Reg
import RegClass
import Cmm
import CLabel ( CLabel )
import DynFlags
import Outputable
import Platform
import qualified Data.Array as A
{-# 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
RcDoubleSSE
-> case VirtualReg
vr of
VirtualRegSSE{} -> Int
1
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
firstfake -> 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
firstfake Bool -> Bool -> Bool
&& Int
regNo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
lastfake -> Int
1
| Bool
otherwise -> Int
0
RealRegPair{} -> Int
0
RegClass
RcDoubleSSE
-> case RealReg
rr of
RealRegSingle Int
regNo | Int
regNo Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
firstxmm -> Int
1
RealReg
_otherwise -> Int
0
RegClass
_other -> Int
0
data Imm
= ImmInt Int
| ImmInteger Integer
| ImmCLbl CLabel
| ImmLit SDoc
| ImmIndex CLabel Int
| ImmFloat Rational
| ImmDouble Rational
| ImmConstantSum Imm Imm
| ImmConstantDiff Imm 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
"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 -> Int -> Maybe AddrMode
addrOffset AddrMode
addr Int
off
= case AddrMode
addr of
ImmAddr Imm
i Int
off0 -> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (Imm -> Int -> AddrMode
ImmAddr Imm
i (Int
off0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
off))
AddrBaseIndex EABase
r EAIndex
i (ImmInt Int
n) -> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
r EAIndex
i (Int -> Imm
ImmInt (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
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 (Int -> Imm
ImmInt (Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer
n Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
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 -> Int -> Imm
ImmIndex CLabel
lbl Int
off))
AddrBaseIndex EABase
r EAIndex
i (ImmIndex CLabel
lbl Int
ix)
-> AddrMode -> Maybe AddrMode
forall a. a -> Maybe a
Just (EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
r EAIndex
i (CLabel -> Int -> Imm
ImmIndex CLabel
lbl (Int
ixInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
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 Int
_ -> [Reg
r]; EAIndex
_ -> [] }
addrModeRegs AddrMode
_ = []
spRel :: DynFlags
-> Int
-> AddrMode
spRel :: DynFlags -> Int -> AddrMode
spRel DynFlags
dflags Int
n
| Platform -> Bool
target32Bit (DynFlags -> Platform
targetPlatform DynFlags
dflags)
= EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex (Reg -> EABase
EABaseReg Reg
esp) EAIndex
EAIndexNone (Int -> Imm
ImmInt Int
n)
| Bool
otherwise
= EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex (Reg -> EABase
EABaseReg Reg
rsp) EAIndex
EAIndexNone (Int -> Imm
ImmInt Int
n)
firstfake, lastfake :: RegNo
firstfake :: Int
firstfake = Int
16
lastfake :: Int
lastfake = Int
21
firstxmm :: RegNo
firstxmm :: Int
firstxmm = Int
24
lastxmm :: Platform -> RegNo
lastxmm :: Platform -> Int
lastxmm Platform
platform
| Platform -> Bool
target32Bit Platform
platform = Int
31
| Bool
otherwise = Int
39
lastint :: Platform -> RegNo
lastint :: Platform -> Int
lastint Platform
platform
| Platform -> Bool
target32Bit Platform
platform = Int
7
| Bool
otherwise = Int
15
intregnos :: Platform -> [RegNo]
intregnos :: Platform -> [Int]
intregnos Platform
platform = [Int
0 .. Platform -> Int
lastint Platform
platform]
fakeregnos :: [RegNo]
fakeregnos :: [Int]
fakeregnos = [Int
firstfake .. Int
lastfake]
xmmregnos :: Platform -> [RegNo]
xmmregnos :: Platform -> [Int]
xmmregnos Platform
platform = [Int
firstxmm .. Platform -> Int
lastxmm Platform
platform]
floatregnos :: Platform -> [RegNo]
floatregnos :: Platform -> [Int]
floatregnos Platform
platform = [Int]
fakeregnos [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Platform -> [Int]
xmmregnos Platform
platform
argRegs :: RegNo -> [Reg]
argRegs :: Int -> [Reg]
argRegs Int
_ = String -> [Reg]
forall a. String -> a
panic String
"MachRegs.argRegs(x86): should not be used!"
allMachRegNos :: Platform -> [RegNo]
allMachRegNos :: Platform -> [Int]
allMachRegNos Platform
platform = Platform -> [Int]
intregnos Platform
platform [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ Platform -> [Int]
floatregnos Platform
platform
{-# INLINE classOfRealReg #-}
classOfRealReg :: Platform -> RealReg -> RegClass
classOfRealReg :: Platform -> RealReg -> RegClass
classOfRealReg Platform
platform RealReg
reg
= case RealReg
reg of
RealRegSingle Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Platform -> Int
lastint Platform
platform -> RegClass
RcInteger
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
lastfake -> RegClass
RcDouble
| Bool
otherwise -> RegClass
RcDoubleSSE
RealRegPair{} -> String -> RegClass
forall a. String -> a
panic String
"X86.Regs.classOfRealReg: RegPairs on this arch"
showReg :: Platform -> RegNo -> String
showReg :: Platform -> Int -> String
showReg Platform
platform Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
firstxmm = String
"%xmm" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
firstxmm)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
firstfake = String
"%fake" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
firstfake)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
8 = String
"%r" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
| Bool
otherwise = Platform -> Array Int String
regNames Platform
platform Array Int String -> Int -> String
forall i e. Ix i => Array i e -> i -> e
A.! Int
n
regNames :: Platform -> A.Array Int String
regNames :: Platform -> Array Int String
regNames Platform
platform
= if Platform -> Bool
target32Bit Platform
platform
then (Int, Int) -> [String] -> Array Int String
forall i e. Ix i => (i, i) -> [e] -> Array i e
A.listArray (Int
0,Int
8) [String
"%eax", String
"%ebx", String
"%ecx", String
"%edx", String
"%esi", String
"%edi", String
"%ebp", String
"%esp"]
else (Int, Int) -> [String] -> Array Int String
forall i e. Ix i => (i, i) -> [e] -> Array i e
A.listArray (Int
0,Int
8) [String
"%rax", String
"%rbx", String
"%rcx", String
"%rdx", String
"%rsi", String
"%rdi", String
"%rbp", String
"%rsp"]
fake0, fake1, fake2, fake3, fake4, fake5,
eax, ebx, ecx, edx, esp, ebp, esi, edi :: Reg
eax :: Reg
eax = Int -> Reg
regSingle Int
0
ebx :: Reg
ebx = Int -> Reg
regSingle Int
1
ecx :: Reg
ecx = Int -> Reg
regSingle Int
2
edx :: Reg
edx = Int -> Reg
regSingle Int
3
esi :: Reg
esi = Int -> Reg
regSingle Int
4
edi :: Reg
edi = Int -> Reg
regSingle Int
5
ebp :: Reg
ebp = Int -> Reg
regSingle Int
6
esp :: Reg
esp = Int -> Reg
regSingle Int
7
fake0 :: Reg
fake0 = Int -> Reg
regSingle Int
16
fake1 :: Reg
fake1 = Int -> Reg
regSingle Int
17
fake2 :: Reg
fake2 = Int -> Reg
regSingle Int
18
fake3 :: Reg
fake3 = Int -> Reg
regSingle Int
19
fake4 :: Reg
fake4 = Int -> Reg
regSingle Int
20
fake5 :: Reg
fake5 = Int -> Reg
regSingle Int
21
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 = Int -> Reg
regSingle Int
0
rbx :: Reg
rbx = Int -> Reg
regSingle Int
1
rcx :: Reg
rcx = Int -> Reg
regSingle Int
2
rdx :: Reg
rdx = Int -> Reg
regSingle Int
3
rsi :: Reg
rsi = Int -> Reg
regSingle Int
4
rdi :: Reg
rdi = Int -> Reg
regSingle Int
5
rbp :: Reg
rbp = Int -> Reg
regSingle Int
6
rsp :: Reg
rsp = Int -> Reg
regSingle Int
7
r8 :: Reg
r8 = Int -> Reg
regSingle Int
8
r9 :: Reg
r9 = Int -> Reg
regSingle Int
9
r10 :: Reg
r10 = Int -> Reg
regSingle Int
10
r11 :: Reg
r11 = Int -> Reg
regSingle Int
11
r12 :: Reg
r12 = Int -> Reg
regSingle Int
12
r13 :: Reg
r13 = Int -> Reg
regSingle Int
13
r14 :: Reg
r14 = Int -> Reg
regSingle Int
14
r15 :: Reg
r15 = Int -> Reg
regSingle Int
15
xmm0 :: Reg
xmm0 = Int -> Reg
regSingle Int
24
xmm1 :: Reg
xmm1 = Int -> Reg
regSingle Int
25
xmm2 :: Reg
xmm2 = Int -> Reg
regSingle Int
26
xmm3 :: Reg
xmm3 = Int -> Reg
regSingle Int
27
xmm4 :: Reg
xmm4 = Int -> Reg
regSingle Int
28
xmm5 :: Reg
xmm5 = Int -> Reg
regSingle Int
29
xmm6 :: Reg
xmm6 = Int -> Reg
regSingle Int
30
xmm7 :: Reg
xmm7 = Int -> Reg
regSingle Int
31
xmm8 :: Reg
xmm8 = Int -> Reg
regSingle Int
32
xmm9 :: Reg
xmm9 = Int -> Reg
regSingle Int
33
xmm10 :: Reg
xmm10 = Int -> Reg
regSingle Int
34
xmm11 :: Reg
xmm11 = Int -> Reg
regSingle Int
35
xmm12 :: Reg
xmm12 = Int -> Reg
regSingle Int
36
xmm13 :: Reg
xmm13 = Int -> Reg
regSingle Int
37
xmm14 :: Reg
xmm14 = Int -> Reg
regSingle Int
38
xmm15 :: Reg
xmm15 = Int -> Reg
regSingle Int
39
ripRel :: Displacement -> AddrMode
ripRel :: Imm -> AddrMode
ripRel Imm
imm = EABase -> EAIndex -> Imm -> AddrMode
AddrBaseIndex EABase
EABaseRip EAIndex
EAIndexNone Imm
imm
xmm :: RegNo -> Reg
xmm :: Int -> Reg
xmm Int
n = Int -> Reg
regSingle (Int
firstxmmInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
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]
++ (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle (Platform -> [Int]
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]
++ (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int]
fakeregnos [Reg] -> [Reg] -> [Reg]
forall a. [a] -> [a] -> [a]
++ (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
xmm [Int
0 .. Int
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]
++ (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle (Platform -> [Int]
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]
((Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
firstxmm ..])
| Bool
otherwise = String -> [(Reg, Reg)]
forall a. 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. 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. String -> a
panic String
"X86.Regs.allFPArgRegs: not defined for this platform"
| Bool
otherwise = (Int -> Reg) -> [Int] -> [Reg]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Reg
regSingle [Int
firstxmm .. Int
firstxmmInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
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 :: 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 (Platform -> [Int]
allMachRegNos Platform
platform)