module Bindings.Bfd.Disasm.I386.Mnemonic where
import Bindings.Bfd.Disasm.I386.CondCode
import Bindings.Bfd.Disasm.I386.Order
import Bindings.Bfd.Disasm.I386.Precision
import Bindings.Bfd.Disasm.I386.XmmType
data Mnemonic = Add {
width1 :: Int
}
| AddCarry {
width1 :: Int
}
| AddScalar {
precision :: Precision
}
| BitwiseAnd {
width1 :: Int
}
| BitwiseExclOr {
xmmType :: XmmType
}
| BitwiseNot {
width1 :: Int
}
| BitwiseOr {
width1 :: Int
}
| Branch {
condCode :: CondCode
}
| Call {
width1 :: Int
}
| Compare {
width1 :: Int
}
| CompareExchange {
width1 :: Int
}
| CompareString {
width1 :: Int
}
| CompareUnordered {
precision :: Precision
}
| Convert {
width1 :: Int
, width2 :: Int
, isSplit :: Bool
}
| ConvertXmm {
numElems :: Int
, sourceXmmType :: XmmType
, targetXmmType :: XmmType
, isTruncate :: Bool
}
| Cpuid
| Decrement {
width1 :: Int
}
| Direction {
isSet :: Bool
}
| Divide {
width1 :: Int
}
| DivideInt {
width1 :: Int
}
| DivideScalar {
precision :: Precision
}
| Exchange {
width1 :: Int
}
| ExchangeAdd {
width1 :: Int
}
| Increment {
width1 :: Int
}
| Jump {
mbWidth :: Maybe Int
}
| Leave {
width1 :: Int
}
| LoadEffAddr {
width1 :: Int
}
| Loop
| Move {
width1 :: Int
, mbWidthSignExtend :: Maybe (Int, Bool)
}
| MoveAligned {
precision :: Precision
}
| MoveCond {
width1 :: Int
, condCode :: CondCode
}
| MoveNonTemp {
xmmType2 :: Either Int XmmType
}
| MovePacked {
precision :: Precision
, isHigh1 :: Bool
, isHigh2 :: Bool
}
| MoveScalar {
precision :: Precision
}
| MoveString {
width1 :: Int
}
| MoveUnaligned {
precision :: Precision
}
| Multiply {
width1 :: Int
}
| MultiplyInt {
width1 :: Int
}
| MultiplyScalar {
xmmType :: XmmType
}
| Negate {
width1 :: Int
}
| NoOp
| Pop {
width1 :: Int
}
| Push {
width1 :: Int
}
| Return {
width1 :: Int
}
| Rotate {
width1 :: Int
, isRight :: Bool
}
| Set {
condCode :: CondCode
}
| Shift {
width1 :: Int
, isRight :: Bool
, isArith :: Bool
}
| StoreString {
width1 :: Int
}
| Subtract {
width1 :: Int
}
| SubtractBorrow {
width1 :: Int
}
| SubtractScalar {
precision :: Precision
}
| Test {
width1 :: Int
}
| Unpack {
order :: Order
, precision :: Precision
}
deriving (Show)
toMnemonic
:: String
-> Mnemonic
toMnemonic s
| s == "adcl" = AddCarry 4
| s == "addb" = Add 1
| s == "addl" = Add 4
| s == "addq" = Add 8
| s == "addsd" = AddScalar Double
| s == "addss" = AddScalar Single
| s == "addw" = Add 2
| s == "andb" = BitwiseAnd 1
| s == "andl" = BitwiseAnd 4
| s == "andq" = BitwiseAnd 8
| s == "andw" = BitwiseAnd 2
| s == "callq" = Call 8
| s == "cld" = Direction False
| s == "cltd" = Convert 4 8 True
| s == "cltq" = Convert 4 8 False
| s == "cmovael" = MoveCond 4 AboveOrEqual
| s == "cmovaeq" = MoveCond 8 AboveOrEqual
| s == "cmoval" = MoveCond 4 Above
| s == "cmovaq" = MoveCond 8 Above
| s == "cmovbel" = MoveCond 4 BelowOrEqual
| s == "cmovbeq" = MoveCond 8 BelowOrEqual
| s == "cmovbl" = MoveCond 4 Below
| s == "cmovbq" = MoveCond 8 Below
| s == "cmovel" = MoveCond 4 Equal
| s == "cmoveq" = MoveCond 8 Equal
| s == "cmovgel" = MoveCond 4 GreaterOrEqual
| s == "cmovgl" = MoveCond 4 Greater
| s == "cmovlel" = MoveCond 4 LessOrEqual
| s == "cmovll" = MoveCond 4 Less
| s == "cmovnel" = MoveCond 4 NotEqual
| s == "cmovneq" = MoveCond 8 NotEqual
| s == "cmpb" = Compare 1
| s == "cmpl" = Compare 4
| s == "cmpsb" = CompareString 1
| s == "cmpq" = Compare 8
| s == "cmpw" = Compare 2
| s == "cmpxchgl" = CompareExchange 4
| s == "cmpxchgq" = CompareExchange 8
| s == "cpuid" = Cpuid
| s == "cvtpd2ps" = ConvertXmm 2 (FloatingPt Double) (FloatingPt Single) False
| s == "cvtps2pd" = ConvertXmm 2 (FloatingPt Single) (FloatingPt Double) False
| s == "cvtsd2ss" = ConvertXmm 1 (FloatingPt Double) (Int 0) False
| s == "cvtsi2sdl" = ConvertXmm 1 (Int 4) (FloatingPt Double) False
| s == "cvtsi2sdq" = ConvertXmm 1 (Int 8) (FloatingPt Double) False
| s == "cvtsi2ssl" = ConvertXmm 1 (Int 4) (FloatingPt Single) False
| s == "cvtsi2ssq" = ConvertXmm 1 (Int 8) (FloatingPt Single) False
| s == "cvtss2sd" = ConvertXmm 1 (FloatingPt Single) (FloatingPt Double) False
| s == "cvttsd2si" = ConvertXmm 1 (FloatingPt Double) (Int 0) True
| s == "cvttss2siq" = ConvertXmm 1 (FloatingPt Single) (Int 8) True
| s == "cwtl" = Convert 2 4 False
| s == "decb" = Decrement 1
| s == "decl" = Decrement 4
| s == "decq" = Decrement 8
| s == "divl" = Divide 4
| s == "divq" = Divide 8
| s == "divsd" = DivideScalar Double
| s == "divss" = DivideScalar Single
| s == "idivl" = DivideInt 4
| s == "imull" = MultiplyInt 4
| s == "imulq" = MultiplyInt 8
| s == "incl" = Increment 4
| s == "incq" = Increment 8
| s == "ja" = Branch Above
| s == "jae" = Branch AboveOrEqual
| s == "jb" = Branch Below
| s == "jbe" = Branch BelowOrEqual
| s == "je" = Branch Equal
| s == "jg" = Branch Greater
| s == "jge" = Branch GreaterOrEqual
| s == "jl" = Branch Less
| s == "jle" = Branch LessOrEqual
| s == "jne" = Branch NotEqual
| s == "jns" = Branch NotSigned
| s == "jmp" = Jump Nothing
| s == "jmpq" = Jump $ Just 8
| s == "jp" = Branch Parity
| s == "js" = Branch Signed
| s == "leal" = LoadEffAddr 4
| s == "leaq" = LoadEffAddr 8
| s == "leaveq" = Leave 8
| s == "movabsq" = Move 8 Nothing
| s == "movaps" = MoveAligned Single
| s == "movb" = Move 1 Nothing
| s == "movl" = Move 4 Nothing
| s == "movlpd" = MovePacked Double False False
| s == "movntps" = MoveNonTemp $ Right $ FloatingPt Single
| s == "movq" = Move 8 Nothing
| s == "movsbl" = Move 1 $ Just (4, True)
| s == "movsbq" = Move 1 $ Just (8, True)
| s == "movsd" = MoveString 4
| s == "movslq" = Move 4 $ Just (8, True)
| s == "movsq" = MoveString 8
| s == "movss" = MoveScalar Single
| s == "movswl" = Move 2 $ Just (4, True)
| s == "movswq" = Move 2 $ Just (8, True)
| s == "movups" = MoveUnaligned Single
| s == "movw" = Move 2 Nothing
| s == "movzbl" = Move 1 $ Just (4, False)
| s == "movzwl" = Move 2 $ Just (4, False)
| s == "mull" = Multiply 4
| s == "mulq" = Multiply 8
| s == "mulss" = MultiplyScalar $ FloatingPt Single
| s == "negl" = Negate 4
| s == "negq" = Negate 8
| s == "nop" = NoOp
| s == "nopl" = NoOp
| s == "nopw" = NoOp
| s == "notl" = BitwiseNot 4
| s == "notq" = BitwiseNot 8
| s == "orb" = BitwiseOr 1
| s == "orl" = BitwiseOr 4
| s == "orq" = BitwiseOr 8
| s == "orw" = BitwiseOr 2
| s == "popq" = Pop 8
| s == "pushq" = Push 8
| s == "roll" = Rotate 4 False
| s == "retq" = Return 8
| s == "sarl" = Shift 4 True True
| s == "sarq" = Shift 8 True True
| s == "sbbl" = SubtractBorrow 4
| s == "sbbq" = SubtractBorrow 8
| s == "seta" = Set Above
| s == "setb" = Set Below
| s == "setbe" = Set BelowOrEqual
| s == "sete" = Set Equal
| s == "setg" = Set Greater
| s == "setl" = Set Less
| s == "setle" = Set LessOrEqual
| s == "setne" = Set NotEqual
| s == "shll" = Shift 4 False False
| s == "shlq" = Shift 8 False False
| s == "shrb" = Shift 1 True False
| s == "shrl" = Shift 4 True False
| s == "shrq" = Shift 8 True False
| s == "shrw" = Shift 2 True False
| s == "stosq" = StoreString 8
| s == "subb" = Subtract 1
| s == "subl" = Subtract 4
| s == "subq" = Subtract 8
| s == "subss" = SubtractScalar Single
| s == "testb" = Test 1
| s == "testl" = Test 4
| s == "testq" = Test 8
| s == "testw" = Test 2
| s == "ucomiss" = CompareUnordered Single
| s == "unpcklpd" = Unpack Low Double
| s == "unpcklps" = Unpack Low Single
| s == "xaddl" = ExchangeAdd 4
| s == "xchgl" = Exchange 4
| s == "xchgq" = Exchange 8
| s == "xchgw" = Exchange 2
| s == "xorb" = BitwiseExclOr $ Int 1
| s == "xorl" = BitwiseExclOr $ Int 4
| s == "xorpd" = BitwiseExclOr $ FloatingPt Double
| s == "xorps" = BitwiseExclOr $ FloatingPt Single
| s == "xorq" = BitwiseExclOr $ Int 8
| s == "xorw" = BitwiseExclOr $ Int 2
| otherwise = error $ "toMnemonic: " ++ show s
isCall
:: Mnemonic
-> Bool
isCall (Call _) = True
isCall _ = False
isJump
:: Mnemonic
-> Bool
isJump (Jump _) = True
isJump _ = False
isBranch
:: Mnemonic
-> Bool
isBranch (Branch _) = True
isBranch (Loop ) = True
isBranch _ = False
isReturn
:: Mnemonic
-> Bool
isReturn (Return _) = True
isReturn _ = False