aboutsummaryrefslogtreecommitdiff
path: root/X64Optimiser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'X64Optimiser.hs')
-rw-r--r--X64Optimiser.hs18
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