diff options
Diffstat (limited to 'X64Optimiser.hs')
-rw-r--r-- | X64Optimiser.hs | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/X64Optimiser.hs b/X64Optimiser.hs index 195389f..206529f 100644 --- a/X64Optimiser.hs +++ b/X64Optimiser.hs @@ -3,7 +3,7 @@ module X64Optimiser(x64Optimise) where import Data.List import Data.Maybe -import Defs +import Defs hiding (Offset) import X64 @@ -88,17 +88,21 @@ optDoubleAdd (name, inss) = (name, go inss) where go :: [Ins] -> [Ins] go [] = [] - go (add@(ADD (RegMem xreg@(XReg _ xregReg)) (RegMemImm (XImm _))) : rest) = + go (add@(ADD (RegMem xreg@(XReg _ xregReg)) (RegMemImm (XImm _))) : rest) = start xreg xregReg add rest + go (sub@(SUB (RegMem xreg@(XReg _ xregReg)) (RegMemImm (XImm _))) : rest) = start xreg xregReg sub rest + go (ins : rest) = ins : go rest + + start :: XRef -> Register -> Ins -> [Ins] -> [Ins] + start xreg xregReg addsub rest = let midx = flip findIndex rest $ \ins -> case ins of ADD (RegMem xreg2@(XReg _ _)) (RegMemImm (XImm _)) | xreg == xreg2 -> True SUB (RegMem xreg2@(XReg _ _)) (RegMemImm (XImm _)) | xreg == xreg2 -> True _ -> False in case midx of - Nothing -> add : go rest + Nothing -> addsub : go rest Just idx -> if all (canSkip xregReg) (take idx rest) - then go $ merge add (rest !! idx) : take idx rest ++ drop (idx + 1) rest - else add : go rest - go (ins : rest) = ins : go rest + then go $ merge addsub (rest !! idx) : take idx rest ++ drop (idx + 1) rest + else addsub : go rest canSkip :: Register -> Ins -> Bool canSkip _ (CALL _) = False @@ -121,7 +125,7 @@ optDoubleAdd (name, inss) = (name, go inss) dst1 = destOf ins1 dst2 = destOf ins2 in if dst1 == dst2 - then ADD (RegMem dst1) (RegMemImm $ XImm $ e1 + e2) + then (if e1 + e2 < 0 then SUB else ADD) (RegMem dst1) (RegMemImm $ XImm $ abs $ e1 + e2) else undefined effectOf :: Ins -> Offset |