aboutsummaryrefslogtreecommitdiff
path: root/X64Optimiser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'X64Optimiser.hs')
-rw-r--r--X64Optimiser.hs24
1 files changed, 22 insertions, 2 deletions
diff --git a/X64Optimiser.hs b/X64Optimiser.hs
index 9cae96d..746d88f 100644
--- a/X64Optimiser.hs
+++ b/X64Optimiser.hs
@@ -5,11 +5,31 @@ import X64
x64Optimise :: Asm -> Error Asm
-x64Optimise (Asm funcs) = return $ Asm [(name, concat $ map goI inss) | (name, inss) <- funcs]
+x64Optimise asm =
+ return $
+ optUnnecessaryJumps $
+ funcopt optSimpleInstructions $
+ asm
+
+funcopt :: (Func -> Func) -> Asm -> Asm
+funcopt f (Asm funcs) = Asm (map f funcs)
+
+optUnnecessaryJumps :: Asm -> Asm
+optUnnecessaryJumps (Asm funcs) = Asm $ map goF (zip funcs (tail funcs)) ++ [last funcs]
+ where
+ goF :: (Func, Func) -> Func
+ goF (f1@(_, f1i), (f2n, _)) = case last f1i of
+ JMP n | n == f2n -> fmap init f1
+ _ -> f1
+
+optSimpleInstructions :: Func -> Func
+optSimpleInstructions (name, inss) = (name, concat $ map goI inss)
where
goI :: Ins -> [Ins]
goI (MOV (RegMem a) (RegMem b)) | a == b = []
- goI (MOVi (RegMem a) (Imm (XImm 0))) | isXReg a = [XOR (RegMem a) (RegMemImm a)]
+ goI (MOVi (RegMem (XReg 8 r)) (Imm (XImm 0))) = [XOR (RegMem (XReg 4 r)) (RegMemImm (XReg 4 r))]
+ goI (MOVi (RegMem a@(XReg _ _)) (Imm (XImm 0))) = [XOR (RegMem a) (RegMemImm a)]
+ goI (MOVi64 (Reg (XReg 8 r)) (Imm (XImm 0))) = [XOR (RegMem (XReg 4 r)) (RegMemImm (XReg 4 r))]
goI (MOVi64 (Reg a) (Imm (XImm 0))) = [XOR (RegMem a) (RegMemImm a)]
goI (MOVSX (Reg a) (RegMem b)) | a == b = []
goI ins = [ins]