diff options
Diffstat (limited to 'X64.hs')
-rw-r--r-- | X64.hs | 44 |
1 files changed, 36 insertions, 8 deletions
@@ -1,6 +1,7 @@ module X64 where import Control.Monad +import Data.Functor.Identity import Data.Char import Data.Int import Data.List @@ -28,7 +29,7 @@ data CondCode = CCA | CCAE | CCB | CCBE | CCC | CCE | CCG | CCGE | CCL | CCLE | deriving (Show, Eq) data Ins - = MOV RegMem RegMem | MOVi RegMem Imm | MOVi64 Reg Imm + = MOV RegMem RegMemImm | MOVi Reg Imm | MOVSX Reg RegMem | ADD RegMem RegMemImm | SUB RegMem RegMemImm @@ -80,9 +81,8 @@ verify :: Asm -> Either String () verify (Asm funcs) = mapM_ (\(_, inss) -> mapM_ goI inss) funcs where goI :: Ins -> Either String () - goI (MOV (RegMem a) (RegMem b)) = ckRegMem a >> ckRegMem b >> ck2mem a b >> ckSizes a b - goI (MOVi (RegMem a) (Imm b)) = ckRegMem a >> ckImm b >> ckSizes a b - goI (MOVi64 (Reg a) (Imm b)) = ckReg a >> ckImm b >> ckSizes64 a b + goI (MOV (RegMem a) (RegMemImm b)) = ckRegMem a >> ckRegMemImm b >> ck2mem a b >> ckSizes a b + goI (MOVi (Reg a) (Imm b)) = ckReg a >> ckImm b >> ckSizes64 a b goI (MOVSX (Reg a) (RegMem b)) = ckReg a >> ckRegMem b >> ckMovsx a b goI (ADD (RegMem a) (RegMemImm b)) = ckRegMem a >> ckRegMemImm b >> ck2mem a b >> ckSizes a b goI (SUB (RegMem a) (RegMemImm b)) = ckRegMem a >> ckRegMemImm b >> ck2mem a b >> ckSizes a b @@ -178,7 +178,7 @@ instance Stringifiable XRef where stringify (XMem _ _ (mult, _) _ _) | not (mult `elem` [0,1,2,4,8]) = error $ "Register multiplier has invalid value " ++ show mult ++ " in XMem" stringify (XMem sz mr pair lab off) = - let res = intercalate "+" $ catMaybes [goR1 mr, goPair pair, goLab lab, goOff off] + let res = intercalate "+" (catMaybes [goR1 mr, goPair pair, goLab lab]) ++ goOff off in szword sz ++ " " ++ if null res then "[0]" else "[" ++ res ++ "]" where szword 1 = "byte" @@ -191,8 +191,9 @@ instance Stringifiable XRef where goPair (0, _) = Nothing goPair (mult, r) = Just $ show mult ++ "*" ++ stringify (XReg 8 r) goLab = id - goOff 0 = Nothing - goOff o = Just $ show o + goOff o | o > 0 = '+' : show o + | o < 0 = show o + | otherwise = "" stringify (XImm imm) = show imm @@ -227,7 +228,6 @@ instance Stringifiable CondCode where instance Stringifiable Ins where stringify (MOV a b) = "mov " ++ stringify a ++ ", " ++ stringify b stringify (MOVi a b) = "mov " ++ stringify a ++ ", " ++ stringify b - stringify (MOVi64 a b) = "mov " ++ stringify a ++ ", " ++ stringify b stringify (MOVSX a b@(RegMem bx)) = case compare (xrefGetSize bx) 4 of EQ -> "movsxd " ++ stringify a ++ ", " ++ stringify b LT -> "movsx " ++ stringify a ++ ", " ++ stringify b @@ -280,3 +280,31 @@ isXMem _ = False isXImm :: XRef -> Bool isXImm (XImm _) = True isXImm _ = False + +xrefMapM :: Monad m => (XRef -> m XRef) -> Ins -> m Ins +xrefMapM f (MOV (RegMem x) (RegMemImm y)) = MOV <$> (RegMem <$> f x) <*> (RegMemImm <$> f y) +xrefMapM f (MOVi (Reg x) (Imm y)) = MOVi <$> (Reg <$> f x) <*> (Imm <$> f y) +xrefMapM f (MOVSX (Reg x) (RegMem y)) = MOVSX <$> (Reg <$> f x) <*> (RegMem <$> f y) +xrefMapM f (ADD (RegMem x) (RegMemImm y)) = ADD <$> (RegMem <$> f x) <*> (RegMemImm <$> f y) +xrefMapM f (SUB (RegMem x) (RegMemImm y)) = SUB <$> (RegMem <$> f x) <*> (RegMemImm <$> f y) +xrefMapM f (AND (RegMem x) (RegMemImm y)) = AND <$> (RegMem <$> f x) <*> (RegMemImm <$> f y) +xrefMapM f (OR (RegMem x) (RegMemImm y)) = OR <$> (RegMem <$> f x) <*> (RegMemImm <$> f y) +xrefMapM f (XOR (RegMem x) (RegMemImm y)) = XOR <$> (RegMem <$> f x) <*> (RegMemImm <$> f y) +xrefMapM f (IMULDA (RegMem x)) = IMULDA <$> (RegMem <$> f x) +xrefMapM f (IMUL (Reg x) (RegMem y)) = IMUL <$> (Reg <$> f x) <*> (RegMem <$> f y) +xrefMapM f (IMUL3 (Reg x) (RegMem y) (Imm z)) = IMUL3<$>(Reg <$> f x)<*>(RegMem <$> f y)<*>(Imm <$> f z) +xrefMapM f (MULDA (RegMem x)) = MULDA <$> (RegMem <$> f x) +xrefMapM f (IDIVDA (RegMem x)) = IDIVDA <$> (RegMem <$> f x) +xrefMapM f (DIVDA (RegMem x)) = DIVDA <$> (RegMem <$> f x) +xrefMapM f (CMP (RegMem x) (RegMem y)) = CMP <$> (RegMem <$> f x) <*> (RegMem <$> f y) +xrefMapM f (CMPi (RegMem x) (Imm y)) = CMPi <$> (RegMem <$> f x) <*> (Imm <$> f y) +xrefMapM f (SETCC c (RegMem x)) = SETCC c <$> (RegMem <$> f x) +xrefMapM _ i@(CALL _) = return i +xrefMapM f (PUSH (RegMemImm x)) = PUSH <$> (RegMemImm <$> f x) +xrefMapM f (POP (RegMem x)) = POP <$> (RegMem <$> f x) +xrefMapM _ i@(JMP _) = return i +xrefMapM _ i@(JCC _ _) = return i +xrefMapM _ i@RET = return i + +xrefMap :: (XRef -> XRef) -> Ins -> Ins +xrefMap f i = runIdentity $ xrefMapM (return . f) i |