aboutsummaryrefslogtreecommitdiff
path: root/X64.hs
diff options
context:
space:
mode:
Diffstat (limited to 'X64.hs')
-rw-r--r--X64.hs44
1 files changed, 36 insertions, 8 deletions
diff --git a/X64.hs b/X64.hs
index 42a8857..222d1cd 100644
--- a/X64.hs
+++ b/X64.hs
@@ -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