apple-0.1.0.0: src/Asm/X86/Frame.hs
module Asm.X86.Frame ( frameC ) where
import Asm.X86
import CF
import Data.Copointed
import Data.Functor (void)
import qualified Data.IntSet as IS
import Data.Maybe (mapMaybe)
frameC :: [X86 X86Reg FX86Reg Live] -> [X86 X86Reg FX86Reg ()]
frameC = concat . go IS.empty IS.empty
where go _ _ [] = []
go s fs (isn:isns) =
let i = copoint isn
s' = s `IS.union` new i `IS.difference` done i
fs' = fs `IS.union` fnew i `IS.difference` fdone i
in case isn of
Call _ cf ->
let
cs = handleRax cf $ mapMaybe fromInt $ IS.toList s
xms = mx cf $ mapMaybe fInt $ IS.toList fs
scratch = odd(length cs+length xms)
save = (if scratch then (++[ISubRI () Rsp 8]) else id)$fmap (Push ()) cs
restore = (if scratch then (IAddRI () Rsp 8:) else id)$fmap (Pop ()) (reverse cs)
savex = concatMap puxmm xms
restorex = concatMap poxmm (reverse xms)
in (save ++ savex ++ void isn : restorex ++ restore) : go s' fs' isns
_ -> [void isn] : go s' fs' isns
handleRax Malloc = filter (/=Rax)
handleRax Free = id
handleRax DR = id
puxmm xr = [ISubRI () Rsp 8, MovqAX () (R Rsp) xr]
poxmm xr = [MovqXA () xr (R Rsp), IAddRI () Rsp 8]
mx Free = const []
mx Malloc = id
mx DR = filter (/=XMM0)
fromInt :: Int -> Maybe X86Reg
fromInt 1 = Just Rsi
fromInt 2 = Just Rdx
fromInt 3 = Just Rcx
fromInt 4 = Just R8
fromInt 5 = Just R9
fromInt 6 = Just Rax
fromInt (-1) = Just R10
fromInt (-2) = Just R11
fromInt _ = Nothing
fInt :: Int -> Maybe FX86Reg
fInt 8 = Just XMM0
fInt 9 = Just XMM1
fInt 10 = Just XMM2
fInt 11 = Just XMM3
fInt 12 = Just XMM4
fInt 13 = Just XMM5
fInt 14 = Just XMM6
fInt 15 = Just XMM7
fInt (-5) = Just XMM8
fInt (-6) = Just XMM9
fInt (-7) = Just XMM10
fInt (-8) = Just XMM11
fInt (-9) = Just XMM12
fInt (-10) = Just XMM13
fInt (-11) = Just XMM14
fInt (-12) = Just XMM15
fInt _ = Nothing