{-# LANGUAGE DeriveGeneric #-}
module X86.Register
( Register(..)
, reg8
, reg16
, reg32
, reg64
, reg80
, reg128
, reg256
, real
, overlapping) where
import GHC.Generics (Generic)
import qualified Data.Serialize as Cereal
import Generic.HasSize (HasSize(..))
import Base (allp)
import Control.DeepSeq
data Register =
InvalidRegister
| RIP
| EIP
| RAX
| EAX
| AX
| AH
| AL
| RBX
| EBX
| BX
| BH
| BL
| RCX
| ECX
| CX
| CH
| CL
| RDX
| EDX
| DX
| DH
| DL
| RDI
| EDI
| DI
| DIL
| RSI
| ESI
| SI
| SIL
| RSP
| ESP
| SP
| SPL
| RBP
| EBP
| BP
| BPL
| R15
| R15D
| R15W
| R15B
| R14
| R14D
| R14W
| R14B
| R13
| R13D
| R13W
| R13B
| R12
| R12D
| R12W
| R12B
| R11
| R11D
| R11W
| R11B
| R10
| R10D
| R10W
| R10B
| R9
| R9D
| R9W
| R9B
| R8
| R8D
| R8W
| R8B
| CS
| DS
| ES
| FS
| GS
| SS
| EIZ
| RIZ
| ST0
| ST1
| ST2
| ST3
| ST4
| ST5
| ST6
| ST7
| YMM0
| YMM1
| YMM2
| YMM3
| YMM4
| YMM5
| YMM6
| YMM7
| YMM8
| YMM9
| YMM10
| YMM11
| YMM12
| YMM13
| YMM14
| YMM15
| XMM0
| XMM1
| XMM2
| XMM3
| XMM4
| XMM5
| XMM6
| XMM7
| XMM8
| XMM9
| XMM10
| XMM11
| XMM12
| XMM13
| XMM14
| XMM15
| TEMP
deriving (Int -> Register -> ShowS
[Register] -> ShowS
Register -> String
(Int -> Register -> ShowS)
-> (Register -> String) -> ([Register] -> ShowS) -> Show Register
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Register] -> ShowS
$cshowList :: [Register] -> ShowS
show :: Register -> String
$cshow :: Register -> String
showsPrec :: Int -> Register -> ShowS
$cshowsPrec :: Int -> Register -> ShowS
Show, Register -> Register -> Bool
(Register -> Register -> Bool)
-> (Register -> Register -> Bool) -> Eq Register
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Register -> Register -> Bool
$c/= :: Register -> Register -> Bool
== :: Register -> Register -> Bool
$c== :: Register -> Register -> Bool
Eq, ReadPrec [Register]
ReadPrec Register
Int -> ReadS Register
ReadS [Register]
(Int -> ReadS Register)
-> ReadS [Register]
-> ReadPrec Register
-> ReadPrec [Register]
-> Read Register
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Register]
$creadListPrec :: ReadPrec [Register]
readPrec :: ReadPrec Register
$creadPrec :: ReadPrec Register
readList :: ReadS [Register]
$creadList :: ReadS [Register]
readsPrec :: Int -> ReadS Register
$creadsPrec :: Int -> ReadS Register
Read, Eq Register
Eq Register
-> (Register -> Register -> Ordering)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Bool)
-> (Register -> Register -> Register)
-> (Register -> Register -> Register)
-> Ord Register
Register -> Register -> Bool
Register -> Register -> Ordering
Register -> Register -> Register
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Register -> Register -> Register
$cmin :: Register -> Register -> Register
max :: Register -> Register -> Register
$cmax :: Register -> Register -> Register
>= :: Register -> Register -> Bool
$c>= :: Register -> Register -> Bool
> :: Register -> Register -> Bool
$c> :: Register -> Register -> Bool
<= :: Register -> Register -> Bool
$c<= :: Register -> Register -> Bool
< :: Register -> Register -> Bool
$c< :: Register -> Register -> Bool
compare :: Register -> Register -> Ordering
$ccompare :: Register -> Register -> Ordering
$cp1Ord :: Eq Register
Ord, (forall x. Register -> Rep Register x)
-> (forall x. Rep Register x -> Register) -> Generic Register
forall x. Rep Register x -> Register
forall x. Register -> Rep Register x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Register x -> Register
$cfrom :: forall x. Register -> Rep Register x
Generic, Int -> Register
Register -> Int
Register -> [Register]
Register -> Register
Register -> Register -> [Register]
Register -> Register -> Register -> [Register]
(Register -> Register)
-> (Register -> Register)
-> (Int -> Register)
-> (Register -> Int)
-> (Register -> [Register])
-> (Register -> Register -> [Register])
-> (Register -> Register -> [Register])
-> (Register -> Register -> Register -> [Register])
-> Enum Register
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Register -> Register -> Register -> [Register]
$cenumFromThenTo :: Register -> Register -> Register -> [Register]
enumFromTo :: Register -> Register -> [Register]
$cenumFromTo :: Register -> Register -> [Register]
enumFromThen :: Register -> Register -> [Register]
$cenumFromThen :: Register -> Register -> [Register]
enumFrom :: Register -> [Register]
$cenumFrom :: Register -> [Register]
fromEnum :: Register -> Int
$cfromEnum :: Register -> Int
toEnum :: Int -> Register
$ctoEnum :: Int -> Register
pred :: Register -> Register
$cpred :: Register -> Register
succ :: Register -> Register
$csucc :: Register -> Register
Enum, Register
Register -> Register -> Bounded Register
forall a. a -> a -> Bounded a
maxBound :: Register
$cmaxBound :: Register
minBound :: Register
$cminBound :: Register
Bounded)
instance Cereal.Serialize Register
instance NFData Register
reg256 :: [Register]
reg256 :: [Register]
reg256 =
[ Register
YMM0
, Register
YMM1
, Register
YMM2
, Register
YMM3
, Register
YMM4
, Register
YMM5
, Register
YMM6
, Register
YMM7
, Register
YMM8
, Register
YMM9
, Register
YMM10
, Register
YMM11
, Register
YMM12
, Register
YMM13
, Register
YMM14
, Register
YMM15]
reg128 :: [Register]
reg128 :: [Register]
reg128 =
[ Register
XMM0
, Register
XMM1
, Register
XMM2
, Register
XMM3
, Register
XMM4
, Register
XMM5
, Register
XMM6
, Register
XMM7
, Register
XMM8
, Register
XMM9
, Register
XMM10
, Register
XMM11
, Register
XMM12
, Register
XMM13
, Register
XMM14
, Register
XMM15]
reg80 :: [Register]
reg80 :: [Register]
reg80 = [Register
ST0, Register
ST1, Register
ST2, Register
ST3, Register
ST4, Register
ST5, Register
ST6, Register
ST7]
reg64 :: [Register]
reg64 :: [Register]
reg64 =
[ Register
RAX
, Register
RBX
, Register
RCX
, Register
RDX
, Register
RSI
, Register
RDI
, Register
RSP
, Register
RBP
, Register
R8
, Register
R9
, Register
R10
, Register
R11
, Register
R12
, Register
R13
, Register
R14
, Register
R15
, Register
RIP
, Register
CS
, Register
DS
, Register
ES
, Register
FS
, Register
GS
, Register
SS]
reg32 :: [Register]
reg32 :: [Register]
reg32 = [ Register
EAX
, Register
EBX
, Register
ECX
, Register
EDX
, Register
ESI
, Register
EDI
, Register
ESP
, Register
EBP
, Register
R8D
, Register
R9D
, Register
R10D
, Register
R11D
, Register
R12D
, Register
R13D
, Register
R14D
, Register
R15D]
reg16 :: [Register]
reg16 :: [Register]
reg16 = [ Register
AX
, Register
BX
, Register
CX
, Register
DX
, Register
SI
, Register
DI
, Register
SP
, Register
BP
, Register
R8W
, Register
R9W
, Register
R10W
, Register
R11W
, Register
R12W
, Register
R13W
, Register
R14W
, Register
R15W]
reg8 :: [Register]
reg8 :: [Register]
reg8 = [ Register
AL
, Register
BL
, Register
CL
, Register
DL
, Register
SIL
, Register
DIL
, Register
SPL
, Register
BPL
, Register
R8B
, Register
R9B
, Register
R10B
, Register
R11B
, Register
R12B
, Register
R13B
, Register
R14B
, Register
R15B]
real :: Register -> Register
real :: Register -> Register
real Register
EAX = Register
RAX
real Register
EBX = Register
RBX
real Register
ECX = Register
RCX
real Register
EDX = Register
RDX
real Register
ESI = Register
RSI
real Register
EDI = Register
RDI
real Register
ESP = Register
RSP
real Register
EBP = Register
RBP
real Register
R8D = Register
R8
real Register
R9D = Register
R9
real Register
R10D = Register
R10
real Register
R11D = Register
R11
real Register
R12D = Register
R12
real Register
R13D = Register
R13
real Register
R14D = Register
R14
real Register
R15D = Register
R15
real Register
AX = Register
RAX
real Register
BX = Register
RBX
real Register
CX = Register
RCX
real Register
DX = Register
RDX
real Register
SI = Register
RSI
real Register
DI = Register
RDI
real Register
SP = Register
RSP
real Register
BP = Register
RBP
real Register
R8W = Register
R8
real Register
R9W = Register
R9
real Register
R10W = Register
R10
real Register
R11W = Register
R11
real Register
R12W = Register
R12
real Register
R13W = Register
R13
real Register
R14W = Register
R14
real Register
R15W = Register
R15
real Register
AL = Register
RAX
real Register
BL = Register
RBX
real Register
CL = Register
RCX
real Register
DL = Register
RDX
real Register
SIL = Register
RSI
real Register
DIL = Register
RDI
real Register
SPL = Register
RSP
real Register
BPL = Register
RBP
real Register
R8B = Register
R8
real Register
R9B = Register
R9
real Register
R10B = Register
R10
real Register
R11B = Register
R11
real Register
R12B = Register
R12
real Register
R13B = Register
R13
real Register
R14B = Register
R14
real Register
R15B = Register
R15
real Register
XMM0 = Register
YMM0
real Register
XMM1 = Register
YMM1
real Register
XMM2 = Register
YMM2
real Register
XMM3 = Register
YMM3
real Register
XMM4 = Register
YMM4
real Register
XMM5 = Register
YMM5
real Register
XMM6 = Register
YMM6
real Register
XMM7 = Register
YMM7
real Register
XMM8 = Register
YMM8
real Register
XMM9 = Register
YMM9
real Register
XMM10 = Register
YMM10
real Register
XMM11 = Register
YMM11
real Register
XMM12 = Register
YMM12
real Register
XMM13 = Register
YMM13
real Register
XMM14 = Register
YMM14
real Register
XMM15 = Register
YMM15
real Register
ST0 = Register
ST0
real Register
ST1 = Register
ST1
real Register
ST2 = Register
ST2
real Register
ST3 = Register
ST3
real Register
ST4 = Register
ST4
real Register
ST5 = Register
ST5
real Register
ST6 = Register
ST6
real Register
ST7 = Register
ST7
real Register
AH = Register
RAX
real Register
BH = Register
RBX
real Register
CH = Register
RCX
real Register
DH = Register
RDX
real Register
TEMP = Register
TEMP
real Register
r = if Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Register]
reg64 [Register] -> [Register] -> [Register]
forall a. [a] -> [a] -> [a]
++ [Register]
reg256)
then Register
r
else String -> Register
forall a. HasCallStack => String -> a
error (String -> Register) -> String -> Register
forall a b. (a -> b) -> a -> b
$ String
"Cannot match register " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Register -> String
forall a. Show a => a -> String
show Register
r String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" to real register"
instance HasSize Register where
sizeof :: Register -> Int
sizeof Register
r
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register]
reg256 = Int
32
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register]
reg128 = Int
16
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register]
reg80 = Int
10
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register]
reg64 = Int
8
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register]
reg32 = Int
4
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register]
reg16 = Int
2
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register]
reg8 [Register] -> [Register] -> [Register]
forall a. [a] -> [a] -> [a]
++ [Register
AH, Register
BH, Register
CH, Register
DH] = Int
1
| Register
r Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Register
TEMP] = Int
8
| Bool
otherwise = String -> Int
forall a. HasCallStack => String -> a
error (String -> Int) -> String -> Int
forall a b. (a -> b) -> a -> b
$ String
"Size of " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Register -> String
forall a. Show a => a -> String
show Register
r String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" unknown"
overlapping :: Register -> [Register]
overlapping :: Register -> [Register]
overlapping Register
r =
(Register -> Bool) -> [Register] -> [Register]
forall a. (a -> Bool) -> [a] -> [a]
filter ([Register -> Bool] -> Register -> Bool
forall a. [a -> Bool] -> a -> Bool
allp [Register -> Register -> Bool
forall a. Eq a => a -> a -> Bool
(/=) Register
r, Register -> Register -> Bool
haveSameRealReg Register
r, Register -> Register -> Bool
areNotSeparate Register
r]) [Register]
allRegisters
allRegisters :: [Register]
allRegisters :: [Register]
allRegisters = [Register
forall a. Bounded a => a
minBound .. Register
forall a. Bounded a => a
maxBound]
hasRealReg :: Register -> Bool
hasRealReg :: Register -> Bool
hasRealReg = (Register -> [Register] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Register
InvalidRegister, Register
RIP, Register
EIP, Register
RIZ, Register
EIZ, Register
TEMP])
haveSameRealReg :: Register -> Register -> Bool
haveSameRealReg :: Register -> Register -> Bool
haveSameRealReg Register
r1 Register
r2 = Register -> Bool
hasRealReg Register
r2 Bool -> Bool -> Bool
&& (Register -> Register
real Register
r1 Register -> Register -> Bool
forall a. Eq a => a -> a -> Bool
== Register -> Register
real Register
r2)
areNotSeparate :: Register -> Register -> Bool
areNotSeparate :: Register -> Register -> Bool
areNotSeparate Register
AH Register
AL = Bool
False
areNotSeparate Register
AL Register
AH = Bool
False
areNotSeparate Register
BH Register
BL = Bool
False
areNotSeparate Register
BL Register
BH = Bool
False
areNotSeparate Register
CH Register
CL = Bool
False
areNotSeparate Register
CL Register
CH = Bool
False
areNotSeparate Register
DH Register
DL = Bool
False
areNotSeparate Register
DL Register
DH = Bool
False
areNotSeparate Register
_ Register
_ = Bool
True