aboutsummaryrefslogtreecommitdiff
path: root/X64Optimiser.hs
blob: 746d88f4b05911affd3987b7dc554c27b3a6ba0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module X64Optimiser(x64Optimise) where

import Defs
import X64


x64Optimise :: Asm -> Error Asm
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 (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]