{-# LANGUAGE FlexibleContexts  #-}
{-# 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.IntMap                as IM
import qualified Data.IntSet                as IS
import           Data.Maybe                 (fromMaybe)
import           Data.Semigroup             ((<>))
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 -> IntMap X86Reg
allocs :: IM.IntMap X86Reg -- ^ Already allocated registers
                       , AllocSt -> Set X86Reg
free64 :: S.Set X86Reg -- TODO: IntSet here?
                       , AllocSt -> Set X86Reg
free8  :: S.Set X86Reg
                       }

allocsLens :: Lens' AllocSt (IM.IntMap X86Reg)
allocsLens :: (IntMap X86Reg -> f (IntMap X86Reg)) -> AllocSt -> f AllocSt
allocsLens IntMap X86Reg -> f (IntMap X86Reg)
f AllocSt
s = (IntMap X86Reg -> AllocSt) -> f (IntMap X86Reg) -> f AllocSt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\IntMap X86Reg
x -> AllocSt
s { allocs :: IntMap X86Reg
allocs = IntMap X86Reg
x }) (IntMap X86Reg -> f (IntMap X86Reg)
f (AllocSt -> IntMap 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 = IntMap X86Reg -> Set X86Reg -> Set X86Reg -> AllocSt
AllocSt IntMap 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
Rsi]

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
assoc X86Reg
Rsi  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Sil
assoc X86Reg
Rdi  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Dil
assoc X86Reg
Sil  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rsi
assoc X86Reg
Dil  = X86Reg -> Set X86Reg
forall a. a -> Set a
S.singleton X86Reg
Rdi

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 -> IS.IntSet
new :: Liveness -> IntSet
new (Liveness IntSet
i IntSet
o) = IntSet
o IntSet -> IntSet -> IntSet
IS.\\ IntSet
i

done :: Liveness -> IS.IntSet
done :: Liveness -> IntSet
done (Liveness IntSet
i IntSet
o) = IntSet
i IntSet -> IntSet -> IntSet
IS.\\ IntSet
o

freeDone :: Liveness -> AllocM ()
freeDone :: Liveness -> AllocM ()
freeDone Liveness
l = (Int -> AllocM ()) -> [Int] -> AllocM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Int -> AllocM ()
freeReg (IntSet -> [Int]
IS.toList IntSet
absRs)
    where absRs :: IntSet
absRs = Liveness -> IntSet
done Liveness
l

freeReg :: Int -> AllocM ()
freeReg :: Int -> AllocM ()
freeReg Int
i = do
    X86Reg
xR <- Int -> AllocM X86Reg
findReg Int
i
    ASetter AllocSt AllocSt (IntMap X86Reg) (IntMap X86Reg)
-> (IntMap X86Reg -> IntMap X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (IntMap X86Reg) (IntMap X86Reg)
Lens' AllocSt (IntMap X86Reg)
allocsLens (Int -> IntMap X86Reg -> IntMap X86Reg
forall a. Int -> IntMap a -> IntMap a
IM.delete Int
i)
    case X86Reg
xR of
        X86Reg
R8   -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R9   -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R10  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R11  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R12  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R13  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R14  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R15  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free64Bit X86Reg
xR
        X86Reg
R8b  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR
        X86Reg
R9b  -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR
        X86Reg
R10b -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR
        X86Reg
R11b -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR
        X86Reg
R12b -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR
        X86Reg
R13b -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR
        X86Reg
R14b -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR
        X86Reg
R15b -> X86Reg -> AllocM ()
forall (m :: * -> *). MonadState AllocSt m => X86Reg -> m ()
free8Bit X86Reg
xR

    where free64Bit :: X86Reg -> m ()
free64Bit X86Reg
xR = do
            ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> m ()
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) -> m ()
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)
          free8Bit :: X86Reg -> m ()
free8Bit X86Reg
xR = do
            ASetter AllocSt AllocSt (Set X86Reg) (Set X86Reg)
-> (Set X86Reg -> Set X86Reg) -> m ()
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) -> m ()
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)

assignReg :: Int -> X86Reg -> AllocM ()
assignReg :: Int -> X86Reg -> AllocM ()
assignReg Int
i X86Reg
xr =
    ASetter AllocSt AllocSt (IntMap X86Reg) (IntMap X86Reg)
-> (IntMap X86Reg -> IntMap X86Reg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (IntMap X86Reg) (IntMap X86Reg)
Lens' AllocSt (IntMap X86Reg)
allocsLens (Int -> X86Reg -> IntMap X86Reg -> IntMap X86Reg
forall a. Int -> a -> IntMap a -> IntMap a
IM.insert 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 :: Int -> AllocM X86Reg
findReg :: Int -> AllocM X86Reg
findReg Int
i = (AllocSt -> X86Reg) -> AllocM X86Reg
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets
    (X86Reg -> Int -> IntMap X86Reg -> X86Reg
forall a. a -> Int -> IntMap a -> a
IM.findWithDefault ([Char] -> X86Reg
forall a. HasCallStack => [Char] -> a
error [Char]
"Internal error in register allocator: unfound register") Int
i (IntMap X86Reg -> X86Reg)
-> (AllocSt -> IntMap X86Reg) -> AllocSt -> X86Reg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AllocSt -> IntMap X86Reg
allocs)

useReg64 :: Liveness -> Int -> AllocM X86Reg
useReg64 :: Liveness -> Int -> AllocM X86Reg
useReg64 Liveness
l Int
i =
    if Int
i Int -> IntSet -> Bool
`IS.member` Liveness -> IntSet
new Liveness
l
        then do { X86Reg
res <- AllocM X86Reg
newReg64 ; Int -> X86Reg -> AllocM ()
assignReg Int
i X86Reg
res ; X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
res }
        else Int -> AllocM X86Reg
findReg Int
i

useReg8 :: Liveness -> Int -> AllocM X86Reg
useReg8 :: Liveness -> Int -> AllocM X86Reg
useReg8 Liveness
l Int
i =
    if Int
i Int -> IntSet -> Bool
`IS.member` Liveness -> IntSet
new Liveness
l
        then do { X86Reg
res <- AllocM X86Reg
newReg8 ; Int -> X86Reg -> AllocM ()
assignReg Int
i X86Reg
res ; X86Reg -> AllocM X86Reg
forall (f :: * -> *) a. Applicative f => a -> f a
pure X86Reg
res }
        else Int -> AllocM X86Reg
findReg 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
-- 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
allocReg (NasmMacro0 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
NasmMacro0 () ByteString
b
allocReg (CallBS 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
CallBS () ByteString
b