diff options
Diffstat (limited to 'X64Optimiser.hs')
-rw-r--r-- | X64Optimiser.hs | 24 |
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] |