{-# LANGUAGE OverloadedStrings #-}

-- | Linear scan register allocator
--
-- See: https://web.stanford.edu/class/archive/cs/cs143/cs143.1128/lectures/17/Slides17.pdf
module Kempe.Asm.X86.Linear ( X86Reg (..)
                            , allocRegs
                            ) where

import           Control.Monad.State.Strict (State, evalState, gets)
import           Data.Foldable              (traverse_)
import qualified Data.Map                   as M
import           Data.Maybe                 (fromMaybe)
import qualified Data.Set                   as S
import           Kempe.Asm.X86.Type
import           Lens.Micro                 (Lens')
import           Lens.Micro.Mtl             (modifying, (.=))

-- brief problem:
--
--     mov HL16, 1 {datapointer,rdx ; datapointer,HL16,rdx}
--     jmp kmp_16 {datapointer,HL16,rdx ; datapointer,HL16,rdx}
-- kmp_15: {datapointer,rdx ; datapointer,rdx}
--     mov HL16, 0 {datapointer,rdx ; datapointer,HL16,rdx}
-- kmp_16: {datapointer,HL16,rdx ; datapointer,HL16,rdx}
--     mov [datapointer], HL16 {datapointer,HL16,rdx ; datapointer,rdx}
--
-- so it feels free to allocate HL16 after kmp_15, though they must match!

-- set of free registers we iterate over
data AllocSt = AllocSt { AllocSt -> Map AbsReg X86Reg
allocs :: M.Map AbsReg X86Reg -- ^ Already allocated registers
                       , AllocSt -> Set X86Reg
free64 :: S.Set X86Reg -- TODO: IntSet here?
                       , AllocSt -> Set X86Reg
free8  :: S.Set X86Reg
                       }

allocsLens :: Lens' AllocSt (M.Map AbsReg X86Reg)
allocsLens :: (Map AbsReg X86Reg -> f (Map AbsReg X86Reg))
-> AllocSt -> f AllocSt
allocsLens Map AbsReg X86Reg -> f (Map AbsReg X86Reg)
f AllocSt
s = (Map AbsReg X86Reg -> AllocSt)
-> f (Map AbsReg X86Reg) -> f AllocSt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Map AbsReg X86Reg
x -> AllocSt
s { allocs :: Map AbsReg X86Reg
allocs = Map AbsReg X86Reg
x }) (Map AbsReg X86Reg -> f (Map AbsReg X86Reg)
f (AllocSt -> Map AbsReg X86Reg
allocs AllocSt
s))

free64Lens :: Lens' AllocSt (S.Set X86Reg)
free64Lens :: (Set X86Reg -> f (Set X86Reg)) -> AllocSt -> f AllocSt
free64Lens Set X86Reg -> f (Set X86Reg)
f AllocSt
s = (Set X86Reg -> AllocSt) -> f (Set X86Reg) -> f AllocSt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Set X86Reg
x -> AllocSt
s { free64 :: Set X86Reg
free64 = Set X86Reg
x }) (Set X86Reg -> f (Set X86Reg)
f (AllocSt -> Set X86Reg
free64 AllocSt
s))

free8Lens :: Lens' AllocSt (S.Set X86Reg)
free8Lens :: (Set X86Reg -> f (Set X86Reg)) -> AllocSt -> f AllocSt
free8Lens Set X86Reg -> f (Set X86Reg)
f AllocSt
s = (Set X86Reg -> AllocSt) -> f (Set X86Reg) -> f AllocSt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Set X86Reg
x -> AllocSt
s { free8 :: Set X86Reg
free8 = Set X86Reg
x }) (Set X86Reg -> f (Set X86Reg)
f (AllocSt -> Set X86Reg
free8 AllocSt
s))

-- | Mark all registers as free (at the beginning).
allFree :: AllocSt
allFree :: AllocSt
allFree = Map AbsReg X86Reg -> Set X86Reg -> Set X86Reg -> AllocSt
AllocSt Map AbsReg X86Reg
forall a. Monoid a => a
mempty Set X86Reg
allReg64 ([X86Reg] -> Set X86Reg
forall a. Ord a => [a] -> Set a
S.fromList [X86Reg
R8b .. X86Reg
R15b])

allReg64 :: S.Set X86Reg
allReg64 :: Set X86Reg
allReg64 = [X86Reg] -> Set X86Reg
forall a. Ord a => [a] -> Set a
S.fromList [X86Reg
R8 .. X86Reg
R15]

type AllocM = State AllocSt

runAllocM :: AllocM a -> a
runAllocM :: AllocM a -> a
runAllocM = (AllocM a -> AllocSt -> a) -> AllocSt -> AllocM a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip AllocM a -> AllocSt -> a
forall s a. State s a -> s -> a
evalState AllocSt
allFree

-- | On X86, certain registers interfere/are dependent. Thus, if we are using
-- some 'X86Reg', we need to remove several from the set of free registers up to
-- that point.
assoc :: X86Reg -> S.Set X86Reg
assoc :: X86Reg -> Set X86Reg
assoc X86Reg
Rax  = [X86Reg] -> Set X86Reg
forall a. Ord a => [a] -> Set a
S.fromList [X86Reg
AH, X86Reg
AL]
assoc X86Reg
Rdx  = [X86Reg] -> Set X86Reg
forall a. Ord a => [a] -> Set a
S.fromList [X86Reg
DH, X86Reg
DL]
assoc X86Reg
R8   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R8b
assoc X86Reg
R9   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R9b
assoc X86Reg
R10  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R10b
assoc X86Reg
R11  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R11b
assoc X86Reg
R12  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R12b
assoc X86Reg
R13  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R13b
assoc X86Reg
R14  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R14b
assoc X86Reg
R15  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R15b
assoc X86Reg
AH   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rax
assoc X86Reg
AL   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rax
assoc X86Reg
DH   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rdx
assoc X86Reg
DL   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rdx
assoc X86Reg
R8b  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R8
assoc X86Reg
R9b  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R9
assoc X86Reg
R10b = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R10
assoc X86Reg
R11b = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R11
assoc X86Reg
R12b = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R12
assoc X86Reg
R13b = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R13
assoc X86Reg
R14b = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R14
assoc X86Reg
R15b = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
R15
assoc X86Reg
Rcx  = [X86Reg] -> Set X86Reg
forall a. Ord a => [a] -> Set a
S.fromList [X86Reg
CH, X86Reg
CL]
assoc X86Reg
CH   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rcx
assoc X86Reg
CL   = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rcx

allocRegs :: [X86 AbsReg Liveness] -> [X86 X86Reg ()]
allocRegs :: [X86 AbsReg Liveness] -> [X86 X86Reg ()]
allocRegs = AllocM [X86 X86Reg ()] -> [X86 X86Reg ()]
forall a. AllocM a -> a
runAllocM (AllocM [X86 X86Reg ()] -> [X86 X86Reg ()])
-> ([X86 AbsReg Liveness] -> AllocM [X86 X86Reg ()])
-> [X86 AbsReg Liveness]
-> [X86 X86Reg ()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (X86 AbsReg Liveness -> StateT AllocSt Identity (X86 X86Reg ()))
-> [X86 AbsReg Liveness] -> AllocM [X86 X86Reg ()]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse X86 AbsReg Liveness -> StateT AllocSt Identity (X86 X86Reg ())
allocReg

new :: Liveness -> S.Set AbsReg
new :: Liveness -> Set AbsReg
new (Liveness Set AbsReg
i Set AbsReg
o) = Set AbsReg
o Set AbsReg -> Set AbsReg -> Set AbsReg
forall a. Ord a => Set a -> Set a -> Set a
S.\\ Set AbsReg
i

done :: Liveness -> S.Set AbsReg
done :: Liveness -> Set AbsReg
done (Liveness Set AbsReg
i Set AbsReg
o) = Set AbsReg
i Set AbsReg -> Set AbsReg -> Set AbsReg
forall a. Ord a => Set a -> Set a -> Set a
S.\\ Set AbsReg
o

freeDone :: Liveness -> AllocM ()
freeDone :: Liveness -> AllocM ()
freeDone Liveness
l = (AbsReg -> AllocM ()) -> Set AbsReg -> AllocM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ AbsReg -> AllocM ()
freeAbsReg Set AbsReg
absRs
    where absRs :: Set AbsReg
absRs = Liveness -> Set AbsReg
done Liveness
l

freeAbsReg :: AbsReg -> AllocM ()
freeAbsReg :: AbsReg -> AllocM ()
freeAbsReg (AllocReg64 Int
i) = Int -> AllocM ()
freeAbsReg64 Int
i
freeAbsReg (AllocReg8 Int
i)  = Int -> AllocM ()
freeAbsReg8 Int
i
freeAbsReg AbsReg
_              = () -> AllocM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure () -- maybe sketchy?

freeAbsReg8 :: Int -> AllocM ()
freeAbsReg8 :: Int -> AllocM ()
freeAbsReg8 Int
i = do
    X86Reg
xR <- AbsReg -> AllocM X86Reg
findReg AbsReg
absR
    ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
-> (Map AbsReg X86Reg -> Map AbsReg X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
Lens' AllocSt (Map AbsReg X86Reg)
allocsLens (AbsReg -> Map AbsReg X86Reg -> Map AbsReg X86Reg
forall k a. Ord k => k -> Map k a -> Map k a
M.delete AbsReg
absR)
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free8Lens (X86Reg -> Set X86Reg -> Set X86Reg
forall a. Ord a => a -> Set a -> Set a
S.insert X86Reg
xR)
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free64Lens (Set X86Reg -> Set X86Reg -> Set X86Reg
forall a. Semigroup a => a -> a -> a
<> X86Reg -> Set X86Reg
assoc X86Reg
xR)

    where absR :: AbsReg
absR = Int -> AbsReg
AllocReg8 Int
i

freeAbsReg64 :: Int -> AllocM ()
freeAbsReg64 :: Int -> AllocM ()
freeAbsReg64 Int
i = do
    X86Reg
xR <- AbsReg -> AllocM X86Reg
findReg AbsReg
absR
    ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
-> (Map AbsReg X86Reg -> Map AbsReg X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
Lens' AllocSt (Map AbsReg X86Reg)
allocsLens (AbsReg -> Map AbsReg X86Reg -> Map AbsReg X86Reg
forall k a. Ord k => k -> Map k a -> Map k a
M.delete AbsReg
absR)
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free64Lens (X86Reg -> Set X86Reg -> Set X86Reg
forall a. Ord a => a -> Set a -> Set a
S.insert X86Reg
xR)
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free8Lens (Set X86Reg -> Set X86Reg -> Set X86Reg
forall a. Semigroup a => a -> a -> a
<> X86Reg -> Set X86Reg
assoc X86Reg
xR)

    where absR :: AbsReg
absR = Int -> AbsReg
AllocReg64 Int
i

assignReg64 :: Int -> X86Reg -> AllocM ()
assignReg64 :: Int -> X86Reg -> AllocM ()
assignReg64 Int
i X86Reg
xr =
    ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
-> (Map AbsReg X86Reg -> Map AbsReg X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
Lens' AllocSt (Map AbsReg X86Reg)
allocsLens (AbsReg -> X86Reg -> Map AbsReg X86Reg -> Map AbsReg X86Reg
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (Int -> AbsReg
AllocReg64 Int
i) X86Reg
xr)

assignReg8 :: Int -> X86Reg -> AllocM ()
assignReg8 :: Int -> X86Reg -> AllocM ()
assignReg8 Int
i X86Reg
xr =
    ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
-> (Map AbsReg X86Reg -> Map AbsReg X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Map AbsReg X86Reg) (Map AbsReg X86Reg)
Lens' AllocSt (Map AbsReg X86Reg)
allocsLens (AbsReg -> X86Reg -> Map AbsReg X86Reg -> Map AbsReg X86Reg
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (Int -> AbsReg
AllocReg8 Int
i) X86Reg
xr)

newReg64 :: AllocM X86Reg
newReg64 :: AllocM X86Reg
newReg64 = do
    Set X86Reg
r64St <- (AllocSt -> Set X86Reg) -> StateT AllocSt Identity (Set X86Reg)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets AllocSt -> Set X86Reg
free64
    let (X86Reg
res, Set X86Reg
newSt) = (X86Reg, Set X86Reg)
-> Maybe (X86Reg, Set X86Reg) -> (X86Reg, Set X86Reg)
forall a. a -> Maybe a -> a
fromMaybe (X86Reg, Set X86Reg)
forall a. a
err (Maybe (X86Reg, Set X86Reg) -> (X86Reg, Set X86Reg))
-> Maybe (X86Reg, Set X86Reg) -> (X86Reg, Set X86Reg)
forall a b. (a -> b) -> a -> b
$ Set X86Reg -> Maybe (X86Reg, Set X86Reg)
forall a. Set a -> Maybe (a, Set a)
S.minView Set X86Reg
r64St
        assocRes :: Set X86Reg
assocRes = X86Reg -> Set X86Reg
assoc X86Reg
res
    -- register is no longer free
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free64Lens ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> Set X86Reg -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Set X86Reg
newSt
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free8Lens (Set X86Reg -> Set X86Reg -> Set X86Reg
forall a. Ord a => Set a -> Set a -> Set a
S.\\ Set X86Reg
assocRes)
    X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
res

    where err :: a
err = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"(internal error) No register available."

newReg8 :: AllocM X86Reg
newReg8 :: AllocM X86Reg
newReg8 = do
    Set X86Reg
r8St <- (AllocSt -> Set X86Reg) -> StateT AllocSt Identity (Set X86Reg)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets AllocSt -> Set X86Reg
free8
    let (X86Reg
res, Set X86Reg
newSt) = (X86Reg, Set X86Reg)
-> Maybe (X86Reg, Set X86Reg) -> (X86Reg, Set X86Reg)
forall a. a -> Maybe a -> a
fromMaybe (X86Reg, Set X86Reg)
forall a. a
err (Maybe (X86Reg, Set X86Reg) -> (X86Reg, Set X86Reg))
-> Maybe (X86Reg, Set X86Reg) -> (X86Reg, Set X86Reg)
forall a b. (a -> b) -> a -> b
$ Set X86Reg -> Maybe (X86Reg, Set X86Reg)
forall a. Set a -> Maybe (a, Set a)
S.minView Set X86Reg
r8St
        assocRes :: Set X86Reg
assocRes = X86Reg -> Set X86Reg
assoc X86Reg
res
    -- register is no longer free
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free8Lens ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> Set X86Reg -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Set X86Reg
newSt
    ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
Lens' AllocSt (Set X86Reg)
free64Lens (Set X86Reg -> Set X86Reg -> Set X86Reg
forall a. Ord a => Set a -> Set a -> Set a
S.\\ Set X86Reg
assocRes)
    X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
res

    where err :: a
err = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"(internal error) No register available."

findReg :: AbsReg -> AllocM X86Reg
findReg :: AbsReg -> AllocM X86Reg
findReg AbsReg
absR = (AllocSt -> X86Reg) -> AllocM X86Reg
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets
    (X86Reg -> AbsReg -> Map AbsReg X86Reg -> X86Reg
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault ([Char] -> X86Reg
forall a. HasCallStack => [Char] -> a
error [Char]
"Internal error in register allocator: unfound register") AbsReg
absR (Map AbsReg X86Reg -> X86Reg)
-> (AllocSt -> Map AbsReg X86Reg) -> AllocSt -> X86Reg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AllocSt -> Map AbsReg X86Reg
allocs)

useReg64 :: Liveness -> Int -> AllocM X86Reg
useReg64 :: Liveness -> Int -> AllocM X86Reg
useReg64 Liveness
l Int
i =
    if AbsReg
absR AbsReg -> Set AbsReg -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Liveness -> Set AbsReg
new Liveness
l
        then do { X86Reg
res <- AllocM X86Reg
newReg64 ; Int -> X86Reg -> AllocM ()
assignReg64 Int
i X86Reg
res ; X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
res }
        else AbsReg -> AllocM X86Reg
findReg AbsReg
absR
    where absR :: AbsReg
absR = Int -> AbsReg
AllocReg64 Int
i

useReg8 :: Liveness -> Int -> AllocM X86Reg
useReg8 :: Liveness -> Int -> AllocM X86Reg
useReg8 Liveness
l Int
i =
    if AbsReg
absR AbsReg -> Set AbsReg -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Liveness -> Set AbsReg
new Liveness
l
        then do { X86Reg
res <- AllocM X86Reg
newReg8 ; Int -> X86Reg -> AllocM ()
assignReg8 Int
i X86Reg
res ; X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
res }
        else AbsReg -> AllocM X86Reg
findReg AbsReg
absR
    where absR :: AbsReg
absR = Int -> AbsReg
AllocReg8 Int
i

useAddr :: Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr :: Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l (Reg AbsReg
r)               = X86Reg -> Addr X86Reg
forall reg. reg -> Addr reg
Reg (X86Reg -> Addr X86Reg) -> AllocM X86Reg -> AllocM (Addr X86Reg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r
useAddr Liveness
l (AddrRCPlus AbsReg
r Int64
c)      = X86Reg -> Int64 -> Addr X86Reg
forall reg. reg -> Int64 -> Addr reg
AddrRCPlus (X86Reg -> Int64 -> Addr X86Reg)
-> AllocM X86Reg -> StateT AllocSt Identity (Int64 -> Addr X86Reg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int64 -> Addr X86Reg)
-> StateT AllocSt Identity Int64 -> AllocM (Addr X86Reg)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c
useAddr Liveness
l (AddrRCMinus AbsReg
r Int64
c)     = X86Reg -> Int64 -> Addr X86Reg
forall reg. reg -> Int64 -> Addr reg
AddrRCMinus (X86Reg -> Int64 -> Addr X86Reg)
-> AllocM X86Reg -> StateT AllocSt Identity (Int64 -> Addr X86Reg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int64 -> Addr X86Reg)
-> StateT AllocSt Identity Int64 -> AllocM (Addr X86Reg)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c
useAddr Liveness
l (AddrRRPlus AbsReg
r0 AbsReg
r1)    = X86Reg -> X86Reg -> Addr X86Reg
forall reg. reg -> reg -> Addr reg
AddrRRPlus (X86Reg -> X86Reg -> Addr X86Reg)
-> AllocM X86Reg -> StateT AllocSt Identity (X86Reg -> Addr X86Reg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> Addr X86Reg)
-> AllocM X86Reg -> AllocM (Addr X86Reg)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1
useAddr Liveness
l (AddrRRScale AbsReg
r0 AbsReg
r1 Int64
c) = X86Reg -> X86Reg -> Int64 -> Addr X86Reg
forall reg. reg -> reg -> Int64 -> Addr reg
AddrRRScale (X86Reg -> X86Reg -> Int64 -> Addr X86Reg)
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> Int64 -> Addr X86Reg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> Int64 -> Addr X86Reg)
-> AllocM X86Reg -> StateT AllocSt Identity (Int64 -> Addr X86Reg)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (Int64 -> Addr X86Reg)
-> StateT AllocSt Identity Int64 -> AllocM (Addr X86Reg)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c

useReg :: Liveness -> AbsReg -> AllocM X86Reg
useReg :: Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l (AllocReg64 Int
i) = Liveness -> Int -> AllocM X86Reg
useReg64 Liveness
l Int
i
useReg Liveness
l (AllocReg8 Int
i)  = Liveness -> Int -> AllocM X86Reg
useReg8 Liveness
l Int
i
useReg Liveness
_ AbsReg
DataPointer    = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rbx
useReg Liveness
_ AbsReg
CArg1          = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rdi -- shouldn't clobber anything because it's just used in function wrapper to push onto the kempe stack
useReg Liveness
_ AbsReg
CArg2          = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rsi
useReg Liveness
_ AbsReg
CArg3          = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rdx
useReg Liveness
_ AbsReg
CArg4          = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rcx
useReg Liveness
_ AbsReg
CArg5          = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
R8
useReg Liveness
_ AbsReg
CArg6          = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
R9
useReg Liveness
_ AbsReg
ShiftExponent  = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
CL
useReg Liveness
_ AbsReg
CRet           = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rax -- shouldn't clobber anything because this is used at end of function calls/wrappers anyway
useReg Liveness
_ AbsReg
QuotRes        = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rax
useReg Liveness
_ AbsReg
RemRes         = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rdx
useReg Liveness
_ AbsReg
CalleeSave1    = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rbx
useReg Liveness
_ AbsReg
CalleeSave2    = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
Rbp
useReg Liveness
_ AbsReg
CalleeSave3    = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
R12
useReg Liveness
_ AbsReg
CalleeSave4    = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
R13
useReg Liveness
_ AbsReg
CalleeSave5    = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
R14
useReg Liveness
_ AbsReg
CalleeSave6    = X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
R15
-- TODO: ig we should have a sanity check here?

-- There's no spill code buuut that's probably not necessary since the whole
-- kempe model is basically to start with everything pre-spilled
allocReg :: X86 AbsReg Liveness -> AllocM (X86 X86Reg ())
allocReg :: X86 AbsReg Liveness -> StateT AllocSt Identity (X86 X86Reg ())
allocReg (PushReg Liveness
l AbsReg
r)                         = () -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> X86 reg a
PushReg () (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg Ret{}                                 = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> X86 X86Reg ()
forall reg a. a -> X86 reg a
Ret ()
allocReg (Call Liveness
_ Label
l)                            = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Call () Label
l
allocReg (PushConst Liveness
_ Int64
i)                       = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Int64 -> X86 X86Reg ()
forall reg a. a -> Int64 -> X86 reg a
PushConst () Int64
i
allocReg (Je Liveness
_ Label
l)                              = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Je () Label
l
allocReg (Jump Liveness
_ Label
l)                            = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Jump () Label
l
allocReg (Label Liveness
_ Label
l)                           = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Label () Label
l
allocReg (MovRCBool Liveness
l AbsReg
r Word8
b)                     = (() -> X86Reg -> Word8 -> X86 X86Reg ()
forall reg a. a -> reg -> Word8 -> X86 reg a
MovRCBool () (X86Reg -> Word8 -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Word8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Word8 -> X86 X86Reg ())
-> StateT AllocSt Identity Word8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word8 -> StateT AllocSt Identity Word8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word8
b) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (CmpAddrReg Liveness
l Addr AbsReg
a AbsReg
r)                    = (() -> Addr X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> Addr reg -> reg -> X86 reg a
CmpAddrReg () (Addr X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (CmpAddrBool Liveness
l Addr AbsReg
a Word8
b)                   = (() -> Addr X86Reg -> Word8 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Word8 -> X86 reg a
CmpAddrBool () (Addr X86Reg -> Word8 -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (Word8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (Word8 -> X86 X86Reg ())
-> StateT AllocSt Identity Word8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word8 -> StateT AllocSt Identity Word8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word8
b) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (AddRC Liveness
_ AbsReg
DataPointer Int64
c)               = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> reg -> Int64 -> X86 reg a
AddRC () X86Reg
Rbx Int64
c
allocReg (SubRC Liveness
_ AbsReg
DataPointer Int64
c)               = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> reg -> Int64 -> X86 reg a
SubRC () X86Reg
Rbx Int64
c
allocReg (MovRA Liveness
l AbsReg
r0 (Reg AbsReg
r1))                 = (() -> X86Reg -> Addr X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> Addr reg -> X86 reg a
MovRA () (X86Reg -> Addr X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Addr X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (Addr X86Reg -> X86 X86Reg ())
-> AllocM (Addr X86Reg) -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (X86Reg -> Addr X86Reg) -> AllocM X86Reg -> AllocM (Addr X86Reg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap X86Reg -> Addr X86Reg
forall reg. reg -> Addr reg
Reg (Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1)) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (SubRR Liveness
l AbsReg
r0 AbsReg
r1)                       = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
SubRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovAR Liveness
l Addr AbsReg
a AbsReg
r)                         = (() -> Addr X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> Addr reg -> reg -> X86 reg a
MovAR () (Addr X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovAC Liveness
_ (Reg AbsReg
DataPointer) Int64
i)         = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Addr X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Int64 -> X86 reg a
MovAC () (X86Reg -> Addr X86Reg
forall reg. reg -> Addr reg
Reg X86Reg
Rbx) Int64
i
allocReg (MovRR Liveness
l AbsReg
r0 AbsReg
r1)                       = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
MovRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRA Liveness
l AbsReg
r Addr AbsReg
a)                         = (() -> X86Reg -> Addr X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> Addr reg -> X86 reg a
MovRA () (X86Reg -> Addr X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Addr X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Addr X86Reg -> X86 X86Reg ())
-> AllocM (Addr X86Reg) -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (CmpRegReg Liveness
l AbsReg
r0 AbsReg
r1)                   = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
CmpRegReg () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (CmpRegBool Liveness
l AbsReg
r Word8
b)                    = (() -> X86Reg -> Word8 -> X86 X86Reg ()
forall reg a. a -> reg -> Word8 -> X86 reg a
CmpRegBool () (X86Reg -> Word8 -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Word8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Word8 -> X86 X86Reg ())
-> StateT AllocSt Identity Word8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word8 -> StateT AllocSt Identity Word8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word8
b) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovABool Liveness
_ (Reg AbsReg
DataPointer) Word8
b)      = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Addr X86Reg -> Word8 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Word8 -> X86 reg a
MovABool () (X86Reg -> Addr X86Reg
forall reg. reg -> Addr reg
Reg X86Reg
Rbx) Word8
b
allocReg (BSLabel Liveness
_ ByteString
b)                         = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> ByteString -> X86 X86Reg ()
forall reg a. a -> ByteString -> X86 reg a
BSLabel () ByteString
b
allocReg (MovRC Liveness
l AbsReg
r Int64
c)                         = (() -> X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> reg -> Int64 -> X86 reg a
MovRC () (X86Reg -> Int64 -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Int64 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int64 -> X86 X86Reg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (PopMem Liveness
_ (AddrRCPlus AbsReg
DataPointer Int64
c)) = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Addr X86Reg -> X86 X86Reg ()
forall reg a. a -> Addr reg -> X86 reg a
PopMem () (X86Reg -> Int64 -> Addr X86Reg
forall reg. reg -> Int64 -> Addr reg
AddrRCPlus X86Reg
Rbx Int64
c)
allocReg (AddAC Liveness
_ (Reg AbsReg
DataPointer) Int64
c)         = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Addr X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Int64 -> X86 reg a
AddAC () (X86Reg -> Addr X86Reg
forall reg. reg -> Addr reg
Reg X86Reg
Rbx) Int64
c
allocReg (AddRC Liveness
l AbsReg
r Int64
c)                         = (() -> X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> reg -> Int64 -> X86 reg a
AddRC () (X86Reg -> Int64 -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Int64 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int64 -> X86 X86Reg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (SubRC Liveness
l AbsReg
r Int64
c)                         = (() -> X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> reg -> Int64 -> X86 reg a
SubRC () (X86Reg -> Int64 -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Int64 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int64 -> X86 X86Reg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovAC Liveness
l Addr AbsReg
a Int64
c)                         = (() -> Addr X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Int64 -> X86 reg a
MovAC () (Addr X86Reg -> Int64 -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (Int64 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (Int64 -> X86 X86Reg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovACi8 Liveness
l Addr AbsReg
a Int8
c)                       = (() -> Addr X86Reg -> Int8 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Int8 -> X86 reg a
MovACi8 () (Addr X86Reg -> Int8 -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (Int8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (Int8 -> X86 X86Reg ())
-> StateT AllocSt Identity Int8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int8 -> StateT AllocSt Identity Int8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int8
c) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovABool Liveness
l Addr AbsReg
a Word8
b)                      = (() -> Addr X86Reg -> Word8 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Word8 -> X86 reg a
MovABool () (Addr X86Reg -> Word8 -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (Word8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (Word8 -> X86 X86Reg ())
-> StateT AllocSt Identity Word8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word8 -> StateT AllocSt Identity Word8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word8
b) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (PopMem Liveness
l Addr AbsReg
a)                          = () -> Addr X86Reg -> X86 X86Reg ()
forall reg a. a -> Addr reg -> X86 reg a
PopMem () (Addr X86Reg -> X86 X86Reg ())
-> AllocM (Addr X86Reg) -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (AddAC Liveness
l Addr AbsReg
a Int64
c)                         = (() -> Addr X86Reg -> Int64 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Int64 -> X86 reg a
AddAC () (Addr X86Reg -> Int64 -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (Int64 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (Int64 -> X86 X86Reg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int64 -> StateT AllocSt Identity Int64
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int64
c) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (PushMem Liveness
l Addr AbsReg
a)                         = () -> Addr X86Reg -> X86 X86Reg ()
forall reg a. a -> Addr reg -> X86 reg a
PushMem () (Addr X86Reg -> X86 X86Reg ())
-> AllocM (Addr X86Reg) -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (AddRR Liveness
l AbsReg
r0 AbsReg
r1)                       = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
AddRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRL Liveness
l AbsReg
r ByteString
bl)                        = (() -> X86Reg -> ByteString -> X86 X86Reg ()
forall reg a. a -> reg -> ByteString -> X86 reg a
MovRL () (X86Reg -> ByteString -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (ByteString -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (ByteString -> X86 X86Reg ())
-> StateT AllocSt Identity ByteString
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ByteString -> StateT AllocSt Identity ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure ByteString
bl) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (XorRR Liveness
l AbsReg
r0 AbsReg
r1)                       = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
XorRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (ShiftLRR Liveness
l AbsReg
r0 AbsReg
r1)                    = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
ShiftLRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (ShiftRRR Liveness
l AbsReg
r0 AbsReg
r1)                    = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
ShiftRRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (ImulRR Liveness
l AbsReg
r0 AbsReg
r1)                      = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
ImulRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRWord Liveness
l AbsReg
r Label
w)                      = (() -> X86Reg -> Label -> X86 X86Reg ()
forall reg a. a -> reg -> Label -> X86 reg a
MovRWord () (X86Reg -> Label -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Label -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Label -> X86 X86Reg ())
-> StateT AllocSt Identity Label
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Label -> StateT AllocSt Identity Label
forall (f :: * -> *) a. Applicative f => a -> f a
pure Label
w) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (IdivR Liveness
l AbsReg
r)                           = (() -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> X86 reg a
IdivR () (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg Cqo{}                                 = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> X86 X86Reg ()
forall reg a. a -> X86 reg a
Cqo ()
allocReg (PopReg Liveness
l AbsReg
r)                          = (() -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> X86 reg a
PopReg () (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRCi8 Liveness
l AbsReg
r Int8
c)                       = (() -> X86Reg -> Int8 -> X86 X86Reg ()
forall reg a. a -> reg -> Int8 -> X86 reg a
MovRCi8 () (X86Reg -> Int8 -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (Int8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int8 -> X86 X86Reg ())
-> StateT AllocSt Identity Int8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int8 -> StateT AllocSt Identity Int8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int8
c) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (Jl Liveness
_ Label
l)                              = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Jl () Label
l
allocReg (MovACTag Liveness
l Addr AbsReg
a Word8
t)                      = (() -> Addr X86Reg -> Word8 -> X86 X86Reg ()
forall reg a. a -> Addr reg -> Word8 -> X86 reg a
MovACTag () (Addr X86Reg -> Word8 -> X86 X86Reg ())
-> AllocM (Addr X86Reg)
-> StateT AllocSt Identity (Word8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> Addr AbsReg -> AllocM (Addr X86Reg)
useAddr Liveness
l Addr AbsReg
a StateT AllocSt Identity (Word8 -> X86 X86Reg ())
-> StateT AllocSt Identity Word8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word8 -> StateT AllocSt Identity Word8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word8
t) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (AndRR Liveness
l AbsReg
r0 AbsReg
r1)                       = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
AndRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (OrRR Liveness
l AbsReg
r0 AbsReg
r1)                        = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
OrRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (PopcountRR Liveness
l AbsReg
r0 AbsReg
r1)                  = (() -> X86Reg -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> reg -> X86 reg a
PopcountRR () (X86Reg -> X86Reg -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (NegR Liveness
l AbsReg
r)                            = () -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> X86 reg a
NegR () (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r -- shouldn't be anything to free
allocReg (Jle Liveness
_ Label
l)                             = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Jle () Label
l
allocReg (Jge Liveness
_ Label
l)                             = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Jge () Label
l
allocReg (Jg Liveness
_ Label
l)                              = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Jg () Label
l
allocReg (Jne Liveness
_ Label
l)                             = X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ()))
-> X86 X86Reg () -> StateT AllocSt Identity (X86 X86Reg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> X86 X86Reg ()
forall reg a. a -> Label -> X86 reg a
Jne () Label
l
allocReg (MovRCTag Liveness
l AbsReg
r Word8
b)                      = () -> X86Reg -> Word8 -> X86 X86Reg ()
forall reg a. a -> reg -> Word8 -> X86 reg a
MovRCTag () (X86Reg -> Word8 -> X86 X86Reg ())
-> AllocM X86Reg
-> StateT AllocSt Identity (Word8 -> X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Word8 -> X86 X86Reg ())
-> StateT AllocSt Identity Word8
-> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word8 -> StateT AllocSt Identity Word8
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word8
b -- don't need to free anything
allocReg (DivR Liveness
l AbsReg
r)                            = (() -> X86Reg -> X86 X86Reg ()
forall reg a. a -> reg -> X86 reg a
DivR () (X86Reg -> X86 X86Reg ())
-> AllocM X86Reg -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM X86Reg
useReg Liveness
l AbsReg
r) StateT AllocSt Identity (X86 X86Reg ())
-> AllocM () -> StateT AllocSt Identity (X86 X86Reg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l