{-# LANGUAGE DeriveGeneric #-}

module X86.Opcode (Opcode(..), isJump, isCondJump, isCall, isRet, isHalt) where

import           GHC.Generics (Generic)
import qualified Data.Serialize as Cereal
import           Control.DeepSeq


-- | Opcodes / mnemonics
data Opcode =
    InvalidOpcode
  | AAA
  | AAD
  | AAM
  | AAS
  | ADC
  | ADD
  | ADDPD
  | ADDPS
  | ADDSD
  | ADDSS
  | ADDSUBPD
  | ADDUBPS
  | AND
  | ANDNPD
  | ANDNPS
  | ANDPD
  | ANDPS
  | ARPL
  | BLENDVPD
  | BLENDVPS
  | BOUND
  | BSF
  | BSR
  | BT
  | BTC
  | BTR
  | BTS
  | CALL
  | CALLF
  | CBW
  | CDQ
  | CDQE
  | CLC
  | CLD
  | CLFLUSH
  | CLI
  | CLTS
  | CMC
  | CMOVA
  | CMOVAE
  | CMOVB
  | CMOVBE
  | CMOVC
  | CMOVE
  | CMOVG
  | CMOVGE
  | CMOVL
  | CMOVLE
  | CMOVNA
  | CMOVNAE
  | CMOVNB
  | CMOVNBE
  | CMOVNC
  | CMOVNE
  | CMOVNG
  | CMOVNGE
  | CMOVNL
  | CMOVNLE
  | CMOVNO
  | CMOVNP
  | CMOVNS
  | CMOVNZ
  | CMOVO
  | CMOVP
  | CMOVPE
  | CMOVPO
  | CMOVS
  | CMOVZ
  | CMP
  | CMPEQSD
  | CMPNEQSD
  | CMPNLESD
  | CMPLTSD
  | CMPS
  | CMPSB
  | CMPSD
  | CMPSW
  | CMPXCHG
  | CMPXCHG16B
  | CMPXCHG8B
  | COMISD
  | COMISS
  | CPUID
  | CQO
  | CVTDQ2PD
  | CVTSD2SS
  | CVTSI2SD
  | CVTSI2SS
  | CVTSS2SD
  | CVTTSD2SI
  | CVTTSS2SI
  | CVTTPD2DQ
  | CWD
  | CWDE
  | DAA
  | DAS
  | DEC
  | DIV
  | DIV_LO
  | DIV_HI
  | DIVPD
  | DIVPS
  | DIVSD
  | DIVSS
  | EMMS
  | ENDBR64
  | ENTER
  | EXTRACTPS
  | FABS
  | FADD
  | FADDP
  | FBLD
  | FBSTP
  | FCHS
  | FCLEX
  | FCMOVB
  | FCMOVBE
  | FCMOVE
  | FCMOVNB
  | FCMOVNBE
  | FCMOVNE
  | FCMOVNU
  | FCMOVU
  | FCOM
  | FCOMI
  | FCOMIP
  | FCOMP
  | FCOMPI
  | FCOMPP
  | FCOS
  | FDIV
  | FDIVP
  | FDIVR
  | FDIVRP
  | FFREE
  | FRNDINT
  | FIADD
  | FICOM
  | FICOMP
  | FIDIV
  | FIDIVR
  | FILD
  | FIMUL
  | FINIT
  | FIST
  | FISTP
  | FISTPP
  | FISTTP
  | FISUB
  | FISUBR
  | FLD
  | FLD1
  | FLDCW
  | FLDENV
  | FLDL2E
  | FLDL2T
  | FLDLG2
  | FLDLN2
  | FLDPI
  | FLDZ
  | FMUL
  | FMULP
  | FNOP
  | FNINIT
  | FNSTCW
  | FPREM1
  | FRSTOR
  | FSAVE
  | FSIN
  | FSINCOS
  | FSCALE
  | FSQRT
  | FST
  | FSTCW
  | FSTENV
  | FSTP
  | FSTSW
  | FSUB
  | FSUBP
  | FSUBR
  | FSUBRP
  | FTST
  | FUCOM
  | FUCOMI
  | FUCOMIP
  | FUCOMP
  | FUCOMPI
  | FUCOMPP
  | FXAM
  | FXCH
  | FXRSTOR
  | FXSAVE
  | FXTRACT
  | HADDPD
  | HADDPS
  | HLT
  | HSUBPD
  | HSUBPS
  | IDIV
  | IDIV_LO
  | IDIV_HI
  | IMUL
  | IMUL_LO
  | IMUL_HI
  | BSWAP
  | IN
  | INC
  | INS
  | INSD
  | INT
  | INT3
  | INTO
  | INVD
  | INVLPG
  | INVPCID
  | IRET
  | IRETD
  | IRETQ
  | JA
  | JAE
  | JB
  | JBE
  | JC
  | JCXZ
  | JE
  | JECXZ
  | JG
  | JGE
  | JL
  | JLE
  | JMP
  | JMPF
  | JMPN
  | JNAE
  | JNA
  | JNB
  | JNBE
  | JNC
  | JNG
  | JNE
  | JNGE
  | JNLE
  | JNL
  | JNO
  | JNP
  | JNS
  | JNZ
  | JO
  | JP
  | JPE
  | JPO
  | JRCXZ
  | JS
  | JZ
  | LAHF
  | LAR
  | LDDQU
  | LDMXCSR
  | LDS
  | LEA
  | LEAVE
  | LES
  | LFENCE
  | LFS
  | LGDT
  | LGS
  | LIDT
  | LLDT
  | LMSW
  | LODS
  | LODSB
  | LODSD
  | LODSW
  | LOOP
  | LOOPE
  | LOOPNE
  | LSL
  | LSS
  | LTR
  | MASKMOVQ
  | MAXPD
  | MAXPS
  | MAXSD
  | MAXSS
  | MFENCE
  | MINPD
  | MINPS
  | MINSD
  | MINSS
  | MONITOR
  | MOV
  | MOVABS
  | MOVAPD
  | MOVAPS
  | MOVD
  | MOVDDUP
  | MOVDQA
  | MOVDQU
  | MOVHLPS
  | MOVHPD
  | MOVHPS
  | MOVLHPS
  | MOVLPD
  | MOVLPS
  | MOVLSDUP
  | MOVMSKPD
  | MOVMSKPS
  | MOVNTDQ
  | MOVNTPD
  | MOVNTPS
  | MOVNTQ
  | MOVQ
  | MOVS
  | MOVSB
  | MOVSD
  | MOVSLDUP
  | MOVSS
  | MOVSW
  | MOVSQ
  | MOVSX
  | MOVSXB
  | MOVSXD
  | MOVSXW
  | MOVUPD
  | MOVUPS
  | MOVZX
  | MOVZXB
  | MOVZXW
  | MUL
  | MUL_LO
  | MUL_HI
  | MULPD
  | MULPS
  | MULSD
  | MULSS
  | MWAIT
  | NEG
  | NOP
  | NOT
  | OR
  | ORPD
  | ORPS
  | OUT
  | OUTS
  | PALIGNR
  | PACKSSDW
  | PACKSSWB
  | PADDB
  | PADDD
  | PADDQ
  | PADDSB
  | PADDSW
  | PADDUSB
  | PADDUSW
  | PADDW
  | PAND
  | PANDN
  | PAUSE
  | PAVGB
  | PAVGW
  | PBLENDW
  | PCLMULQDQ
  | PCMPEQB
  | PCMPEQD
  | PCMPGTB
  | PCMPGTD
  | PEXTRB
  | PEXTRD
  | PEXTRQ
  | PHADDD
  | PINSRB
  | PINSRD
  | PINSRQ
  | PMADDWD
  | PMAXSD
  | PMAXSW
  | PMAXUB
  | PMAXUD
  | PMAXUQ
  | PMINSD
  | PMINSW
  | PMINUB
  | PMINUD
  | PMOVMSKB
  | PMOVSXDQ
  | PMOVZXDQ
  | PMOVSXBD
  | PMOVZXBD
  | PMULLD
  | PMULLQ
  | PMULHUW
  | PMULHW
  | PMULLW
  | PMULUDQ
  | POP
  | POPA
  | POPAD
  | POPF
  | POPFD
  | POPFQ
  | POR
  | PREFETCHNTA
  | PREFETCHT0
  | PREFETCHT1
  | PREFETCHT2
  | PSADBW
  | PSHUFB
  | PSHUFD
  | PSHUFLW
  | PSLLD
  | PSLLDQ
  | PSLLQ
  | PSLLW
  | PSRAD
  | PSRAW
  | PSRLD
  | PSRLDQ
  | PSRLQ
  | PSRLW
  | PSUBB
  | PSUBD
  | PSUBQ
  | PSUBSB
  | PSUBSQ
  | PSUBUSB
  | PSUBUSW
  | PSUBW
  | PTEST
  | PUNPCKLBW
  | PUNPCKLWD
  | PUNPCKLDQ
  | PUNPCKLQDQ
  | PUSH
  | PUSHA
  | PUSHAD
  | PUSHF
  | PUSHFD
  | PUSHFQ
  | PXOR
  | RCL
  | RCPPS
  | RCPSS
  | RCR
  | RDMSR
  | RDPMC
  | RDTSC
  | RET
  | RETF
  | RETN
  | ROL
  | ROR
  | ROUNDSD
  | ROUNDSS
  | RSM
  | RSQRTPS
  | RSQRTSS
  | SAHF
  | SAL
  | SAR
  | SBB
  | SCAS
  | SCASB
  | SCASD
  | SETA
  | SETAE
  | SETB
  | SETBE
  | SETC
  | SETE
  | SETG
  | SETGE
  | SETL
  | SETLE
  | SETNA
  | SETNAE
  | SETNB
  | SETNBE
  | SETNC
  | SETNE
  | SETNG
  | SETNGE
  | SETNL
  | SETNLE
  | SETNO
  | SETNP
  | SETNS
  | SETNZ
  | SETO
  | SETP
  | SETPE
  | SETPO
  | SETS
  | SETZ
  | SFENCE
  | SGDT
  | SHL
  | SHLD
  | SHR
  | SHRD
  | SHUFPS
  | SIDT
  | SLDT
  | SMSW
  | SQRTPD
  | SQRTPS
  | SQRTSD
  | SQRTSS
  | STC
  | STD
  | STI
  | STMXCSR
  | STOS
  | STOSB
  | STOSD
  | STOSQ
  | STR
  | SUB
  | SUBPD
  | SUBPS
  | SUBSD
  | SUBSS
  | SWAPGS
  | SYSCALL
  | SYSENTER
  | SYSEXIT
  | SYSRET
  | TEST
  | UCOMISD
  | UCOMISS
  | UD2
  | UNPCKHPD
  | UNPCKHPS
  | UNPCKLPD
  | UNPCKLPS
  | VANDPD
  | VANDPS
  | VADDPD
  | VADDPS
  | VBLENDPS
  | VERR
  | VERW
  | VEXTRACTI128
  | VEXTRACTF128
  | VINSERTF128
  | VMCALL
  | VMCLEAR
  | VMLAUNCH
  | VMOVAPD
  | VMOVAPS
  | VMOVHPS
  | VMOVD
  | VMOVDQA
  | VMOVDQU
  | VMOVLHPS
  | VMPTRLD
  | VMPTRST
  | VMREAD
  | VMRESUME
  | VMWRITE
  | VMULPD
  | VMULPS
  | VMXOFF
  | VMXON
  | VPALIGNR
  | VPAND
  | VPANDN
  | VPCMPEQB
  | VPCMPEQW
  | VPERM2F128
  | VPERM2I128
  | VPERMILPS
  | VPOR
  | VPSHUFB
  | VPSHUFD
  | VPSLLW
  | VSHUFPS
  | VSHUFPD
  | VPXOR
  | VPUNPCKLWD
  | VPUNPCKHWD
  | VSUBPD
  | VSUBPS
  | VUNPCKHPS
  | VUNPCKLPS
  | VXORPD
  | VXORPS
  | VZEROUPPER
  | WAIT
  | WBINVD
  | WRFSBASE
  | WRGSBASE
  | WRMSR
  | XADD
  | XCHG
  | XGETBV
  | XLAT
  | XLATB
  | XSETBV
  | XSAVEOPT
  | XRSTOR
  | XOR
  | XORPD
  | XORPS
  deriving (Int -> Opcode -> ShowS
[Opcode] -> ShowS
Opcode -> String
(Int -> Opcode -> ShowS)
-> (Opcode -> String) -> ([Opcode] -> ShowS) -> Show Opcode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Opcode] -> ShowS
$cshowList :: [Opcode] -> ShowS
show :: Opcode -> String
$cshow :: Opcode -> String
showsPrec :: Int -> Opcode -> ShowS
$cshowsPrec :: Int -> Opcode -> ShowS
Show, Opcode -> Opcode -> Bool
(Opcode -> Opcode -> Bool)
-> (Opcode -> Opcode -> Bool) -> Eq Opcode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Opcode -> Opcode -> Bool
$c/= :: Opcode -> Opcode -> Bool
== :: Opcode -> Opcode -> Bool
$c== :: Opcode -> Opcode -> Bool
Eq, Eq Opcode
Eq Opcode
-> (Opcode -> Opcode -> Ordering)
-> (Opcode -> Opcode -> Bool)
-> (Opcode -> Opcode -> Bool)
-> (Opcode -> Opcode -> Bool)
-> (Opcode -> Opcode -> Bool)
-> (Opcode -> Opcode -> Opcode)
-> (Opcode -> Opcode -> Opcode)
-> Ord Opcode
Opcode -> Opcode -> Bool
Opcode -> Opcode -> Ordering
Opcode -> Opcode -> Opcode
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 :: Opcode -> Opcode -> Opcode
$cmin :: Opcode -> Opcode -> Opcode
max :: Opcode -> Opcode -> Opcode
$cmax :: Opcode -> Opcode -> Opcode
>= :: Opcode -> Opcode -> Bool
$c>= :: Opcode -> Opcode -> Bool
> :: Opcode -> Opcode -> Bool
$c> :: Opcode -> Opcode -> Bool
<= :: Opcode -> Opcode -> Bool
$c<= :: Opcode -> Opcode -> Bool
< :: Opcode -> Opcode -> Bool
$c< :: Opcode -> Opcode -> Bool
compare :: Opcode -> Opcode -> Ordering
$ccompare :: Opcode -> Opcode -> Ordering
$cp1Ord :: Eq Opcode
Ord, (forall x. Opcode -> Rep Opcode x)
-> (forall x. Rep Opcode x -> Opcode) -> Generic Opcode
forall x. Rep Opcode x -> Opcode
forall x. Opcode -> Rep Opcode x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Opcode x -> Opcode
$cfrom :: forall x. Opcode -> Rep Opcode x
Generic)

instance Cereal.Serialize Opcode
instance NFData Opcode

-- | Returns true iff m is the mnemonic of a conditional jump
isCondJump :: Opcode -> Bool
isCondJump :: Opcode -> Bool
isCondJump Opcode
m = Opcode
m
  Opcode -> [Opcode] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ Opcode
JO
         , Opcode
JNO
         , Opcode
JS
         , Opcode
JNS
         , Opcode
JE
         , Opcode
JZ
         , Opcode
JNE
         , Opcode
JNZ
         , Opcode
JB
         , Opcode
JNAE
         , Opcode
JC
         , Opcode
JNB
         , Opcode
JAE
         , Opcode
JNC
         , Opcode
JBE
         , Opcode
JNA
         , Opcode
JA
         , Opcode
JNBE
         , Opcode
JL
         , Opcode
JNGE
         , Opcode
JGE
         , Opcode
JNL
         , Opcode
JLE
         , Opcode
JNG
         , Opcode
JG
         , Opcode
JNLE
         , Opcode
JP
         , Opcode
JPE
         , Opcode
JNP
         , Opcode
JPO
         , Opcode
JCXZ
         , Opcode
JECXZ
         , Opcode
JRCXZ
         , Opcode
LOOP
         , Opcode
LOOPE
         , Opcode
LOOPNE ]

-- | Returns true iff m is the mnemonic of a halting instruction
isHalt :: Opcode -> Bool
isHalt :: Opcode -> Bool
isHalt Opcode
m = Opcode
m Opcode -> Opcode -> Bool
forall a. Eq a => a -> a -> Bool
== Opcode
HLT

-- | Returns true iff m is the mnemonic of a jump
isJump :: Opcode -> Bool
isJump :: Opcode -> Bool
isJump Opcode
m = Opcode
m Opcode -> [Opcode] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Opcode
JMP, Opcode
JMPF, Opcode
JMPN]

-- | Returns true iff m is the mnemonic of a call
isCall :: Opcode -> Bool
isCall :: Opcode -> Bool
isCall Opcode
m = Opcode
m Opcode -> [Opcode] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Opcode
CALL, Opcode
CALLF]

-- | Returns true iff m is the mnemonic of a return
isRet :: Opcode -> Bool
isRet :: Opcode -> Bool
isRet Opcode
m = Opcode
m Opcode -> [Opcode] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Opcode
RET, Opcode
RETF, Opcode
RET, Opcode
RETN, Opcode
IRET, Opcode
IRETD, Opcode
IRETQ]