{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE OverloadedStrings #-}

-- | Linear scan register allocator
module Kempe.Asm.Arm.Linear ( 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.Arm.Type
import           Kempe.Asm.Type
import           Lens.Micro                 (Lens')
import           Lens.Micro.Mtl             (modifying, (.=))

data AllocSt = AllocSt { AllocSt -> IntMap ArmReg
allocs :: IM.IntMap ArmReg -- ^ Already allocated registers
                       , AllocSt -> Set ArmReg
free   :: S.Set ArmReg -- TODO: IntSet here?
                       }

allocsLens :: Lens' AllocSt (IM.IntMap ArmReg)
allocsLens :: (IntMap ArmReg -> f (IntMap ArmReg)) -> AllocSt -> f AllocSt
allocsLens IntMap ArmReg -> f (IntMap ArmReg)
f AllocSt
s = (IntMap ArmReg -> AllocSt) -> f (IntMap ArmReg) -> f AllocSt
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\IntMap ArmReg
x -> AllocSt
s { allocs :: IntMap ArmReg
allocs = IntMap ArmReg
x }) (IntMap ArmReg -> f (IntMap ArmReg)
f (AllocSt -> IntMap ArmReg
allocs AllocSt
s))

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

-- | Mark all registers as free (at the beginning).
allFree :: AllocSt
allFree :: AllocSt
allFree = IntMap ArmReg -> Set ArmReg -> AllocSt
AllocSt IntMap ArmReg
forall a. Monoid a => a
mempty Set ArmReg
allReg

allReg :: S.Set ArmReg
allReg :: Set ArmReg
allReg = [ArmReg] -> Set ArmReg
forall a. Ord a => [a] -> Set a
S.fromList [ArmReg
X0 .. ArmReg
X29] Set ArmReg -> Set ArmReg -> Set ArmReg
forall a. Ord a => Set a -> Set a -> Set a
S.\\ ArmReg -> Set ArmReg
forall a. a -> Set a
S.singleton ArmReg
X19 -- don't allocate to x19 (data pointer)

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

allocRegs :: [Arm AbsReg Liveness] -> [Arm ArmReg ()]
allocRegs :: [Arm AbsReg Liveness] -> [Arm ArmReg ()]
allocRegs = AllocM [Arm ArmReg ()] -> [Arm ArmReg ()]
forall a. AllocM a -> a
runAllocM (AllocM [Arm ArmReg ()] -> [Arm ArmReg ()])
-> ([Arm AbsReg Liveness] -> AllocM [Arm ArmReg ()])
-> [Arm AbsReg Liveness]
-> [Arm ArmReg ()]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Arm AbsReg Liveness -> StateT AllocSt Identity (Arm ArmReg ()))
-> [Arm AbsReg Liveness] -> AllocM [Arm ArmReg ()]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Arm AbsReg Liveness -> StateT AllocSt Identity (Arm ArmReg ())
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
    ArmReg
xR <- Int -> AllocM ArmReg
findReg Int
i
    ASetter AllocSt AllocSt (IntMap ArmReg) (IntMap ArmReg)
-> (IntMap ArmReg -> IntMap ArmReg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (IntMap ArmReg) (IntMap ArmReg)
Lens' AllocSt (IntMap ArmReg)
allocsLens (Int -> IntMap ArmReg -> IntMap ArmReg
forall a. Int -> IntMap a -> IntMap a
IM.delete Int
i)
    ASetter AllocSt AllocSt (Set ArmReg) (Set ArmReg)
-> (Set ArmReg -> Set ArmReg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (Set ArmReg) (Set ArmReg)
Lens' AllocSt (Set ArmReg)
freeLens (ArmReg -> Set ArmReg -> Set ArmReg
forall a. Ord a => a -> Set a -> Set a
S.insert ArmReg
xR)

assignReg :: Int -> ArmReg -> AllocM ()
assignReg :: Int -> ArmReg -> AllocM ()
assignReg Int
i ArmReg
xr =
    ASetter AllocSt AllocSt (IntMap ArmReg) (IntMap ArmReg)
-> (IntMap ArmReg -> IntMap ArmReg) -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
modifying ASetter AllocSt AllocSt (IntMap ArmReg) (IntMap ArmReg)
Lens' AllocSt (IntMap ArmReg)
allocsLens (Int -> ArmReg -> IntMap ArmReg -> IntMap ArmReg
forall a. Int -> a -> IntMap a -> IntMap a
IM.insert Int
i ArmReg
xr)

newReg :: AllocM ArmReg
newReg :: AllocM ArmReg
newReg = do
    Set ArmReg
rSt <- (AllocSt -> Set ArmReg) -> StateT AllocSt Identity (Set ArmReg)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets AllocSt -> Set ArmReg
free
    let (ArmReg
res', Set ArmReg
newSt) = (ArmReg, Set ArmReg)
-> Maybe (ArmReg, Set ArmReg) -> (ArmReg, Set ArmReg)
forall a. a -> Maybe a -> a
fromMaybe (ArmReg, Set ArmReg)
forall a. a
err (Maybe (ArmReg, Set ArmReg) -> (ArmReg, Set ArmReg))
-> Maybe (ArmReg, Set ArmReg) -> (ArmReg, Set ArmReg)
forall a b. (a -> b) -> a -> b
$ Set ArmReg -> Maybe (ArmReg, Set ArmReg)
forall a. Set a -> Maybe (a, Set a)
S.minView Set ArmReg
rSt
    -- register is no longer free
    ASetter AllocSt AllocSt (Set ArmReg) (Set ArmReg)
Lens' AllocSt (Set ArmReg)
freeLens ASetter AllocSt AllocSt (Set ArmReg) (Set ArmReg)
-> Set ArmReg -> AllocM ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= Set ArmReg
newSt
    ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
res'

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

findReg :: Int -> AllocM ArmReg
findReg :: Int -> AllocM ArmReg
findReg Int
i = (AllocSt -> ArmReg) -> AllocM ArmReg
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets
    (ArmReg -> Int -> IntMap ArmReg -> ArmReg
forall a. a -> Int -> IntMap a -> a
IM.findWithDefault ([Char] -> ArmReg
forall a. HasCallStack => [Char] -> a
error ([Char] -> ArmReg) -> [Char] -> ArmReg
forall a b. (a -> b) -> a -> b
$ [Char]
"Internal error in register allocator: unfound register" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i) Int
i (IntMap ArmReg -> ArmReg)
-> (AllocSt -> IntMap ArmReg) -> AllocSt -> ArmReg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AllocSt -> IntMap ArmReg
allocs)

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

useAddr :: Liveness -> Addr AbsReg -> AllocM (Addr ArmReg)
useAddr :: Liveness -> Addr AbsReg -> AllocM (Addr ArmReg)
useAddr Liveness
l (Reg AbsReg
r)           = ArmReg -> Addr ArmReg
forall reg. reg -> Addr reg
Reg (ArmReg -> Addr ArmReg) -> AllocM ArmReg -> AllocM (Addr ArmReg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r
useAddr Liveness
l (AddRCPlus AbsReg
r Int64
c)   = ArmReg -> Int64 -> Addr ArmReg
forall reg. reg -> Int64 -> Addr reg
AddRCPlus (ArmReg -> Int64 -> Addr ArmReg)
-> AllocM ArmReg -> StateT AllocSt Identity (Int64 -> Addr ArmReg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int64 -> Addr ArmReg)
-> StateT AllocSt Identity Int64 -> AllocM (Addr ArmReg)
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 (AddRRPlus AbsReg
r0 AbsReg
r1) = ArmReg -> ArmReg -> Addr ArmReg
forall reg. reg -> reg -> Addr reg
AddRRPlus (ArmReg -> ArmReg -> Addr ArmReg)
-> AllocM ArmReg -> StateT AllocSt Identity (ArmReg -> Addr ArmReg)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> Addr ArmReg)
-> AllocM ArmReg -> AllocM (Addr ArmReg)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1

useReg :: Liveness -> AbsReg -> AllocM ArmReg
useReg :: Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l (AllocReg Int
i) = Liveness -> Int -> AllocM ArmReg
useRegInt Liveness
l Int
i
useReg Liveness
_ AbsReg
DataPointer  = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X19
useReg Liveness
_ AbsReg
LinkReg      = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X30
useReg Liveness
_ AbsReg
CArg0        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X0
useReg Liveness
_ AbsReg
CArg1        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X1 -- shouldn't clobber anything because it's just used in function wrapper to push onto the kempe stack
useReg Liveness
_ AbsReg
CArg2        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X2
useReg Liveness
_ AbsReg
CArg3        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X3
useReg Liveness
_ AbsReg
CArg4        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X4
useReg Liveness
_ AbsReg
CArg5        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X5
useReg Liveness
_ AbsReg
CArg6        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X6
useReg Liveness
_ AbsReg
CArg7        = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
X7
useReg Liveness
_ AbsReg
StackPtr     = ArmReg -> AllocM ArmReg
forall (f :: * -> *) a. Applicative f => a -> f a
pure ArmReg
SP

allocReg :: Arm AbsReg Liveness -> AllocM (Arm ArmReg ())
allocReg :: Arm AbsReg Liveness -> StateT AllocSt Identity (Arm ArmReg ())
allocReg Ret{}                      = Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ()))
-> Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall a b. (a -> b) -> a -> b
$ () -> Arm ArmReg ()
forall reg a. a -> Arm reg a
Ret ()
allocReg (Branch Liveness
_ Label
l)               = Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ()))
-> Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> Arm ArmReg ()
forall reg a. a -> Label -> Arm reg a
Branch () Label
l
allocReg (BranchLink Liveness
_ Label
l)           = Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ()))
-> Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> Arm ArmReg ()
forall reg a. a -> Label -> Arm reg a
BranchLink () Label
l
allocReg (BranchCond Liveness
_ Label
l Cond
c)         = Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ()))
-> Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> Cond -> Arm ArmReg ()
forall reg a. a -> Label -> Cond -> Arm reg a
BranchCond () Label
l Cond
c
allocReg (Label Liveness
_ Label
l)                = Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ()))
-> Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall a b. (a -> b) -> a -> b
$ () -> Label -> Arm ArmReg ()
forall reg a. a -> Label -> Arm reg a
Label () Label
l
allocReg (BSLabel Liveness
_ ByteString
l)              = Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ()))
-> Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall a b. (a -> b) -> a -> b
$ () -> ByteString -> Arm ArmReg ()
forall reg a. a -> ByteString -> Arm reg a
BSLabel () ByteString
l
allocReg (GnuMacro Liveness
_ ByteString
m)             = Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ()))
-> Arm ArmReg () -> StateT AllocSt Identity (Arm ArmReg ())
forall a b. (a -> b) -> a -> b
$ () -> ByteString -> Arm ArmReg ()
forall reg a. a -> ByteString -> Arm reg a
GnuMacro () ByteString
m
allocReg (BranchZero Liveness
l AbsReg
r Label
lbl)       = (() -> ArmReg -> Label -> Arm ArmReg ()
forall reg a. a -> reg -> Label -> Arm reg a
BranchZero () (ArmReg -> Label -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Label -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Label -> Arm ArmReg ())
-> StateT AllocSt Identity Label
-> StateT AllocSt Identity (Arm ArmReg ())
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
lbl) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
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 AbsReg
r2)         = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
AddRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
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 AbsReg
r2)         = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
SubRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MulRR Liveness
l AbsReg
r0 AbsReg
r1 AbsReg
r2)         = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
MulRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (SignedDivRR Liveness
l AbsReg
r0 AbsReg
r1 AbsReg
r2)   = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
SignedDivRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (UnsignedDivRR Liveness
l AbsReg
r0 AbsReg
r1 AbsReg
r2) = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
UnsignedDivRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (LShiftLRR Liveness
l AbsReg
r0 AbsReg
r1 AbsReg
r2)     = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
LShiftLRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (LShiftRRR Liveness
l AbsReg
r0 AbsReg
r1 AbsReg
r2)     = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
LShiftRRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
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 AbsReg
r2)         = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
AndRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (AddRC Liveness
l AbsReg
r0 AbsReg
r1 Int64
c)          = (() -> ArmReg -> ArmReg -> Int64 -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> Int64 -> Arm reg a
AddRC () (ArmReg -> ArmReg -> Int64 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Int64 -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> Int64 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Int64 -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (Int64 -> Arm ArmReg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (Arm ArmReg ())
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 (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (SubRC Liveness
l AbsReg
r0 AbsReg
r1 Int64
c)          = (() -> ArmReg -> ArmReg -> Int64 -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> Int64 -> Arm reg a
SubRC () (ArmReg -> ArmReg -> Int64 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Int64 -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> Int64 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Int64 -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (Int64 -> Arm ArmReg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (Arm ArmReg ())
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 (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRC Liveness
l AbsReg
r0 Int64
c)             = (() -> ArmReg -> Int64 -> Arm ArmReg ()
forall reg a. a -> reg -> Int64 -> Arm reg a
MovRC () (ArmReg -> Int64 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Int64 -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (Int64 -> Arm ArmReg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (Arm ArmReg ())
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 (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRWord Liveness
l AbsReg
r0 Word16
w)          = (() -> ArmReg -> Word16 -> Arm ArmReg ()
forall reg a. a -> reg -> Word16 -> Arm reg a
MovRWord () (ArmReg -> Word16 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Word16 -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (Word16 -> Arm ArmReg ())
-> StateT AllocSt Identity Word16
-> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word16 -> StateT AllocSt Identity Word16
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word16
w) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (Load Liveness
l AbsReg
r Addr AbsReg
a)               = (() -> ArmReg -> Addr ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> Addr reg -> Arm reg a
Load () (ArmReg -> Addr ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
-> AllocM (Addr ArmReg) -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> Addr AbsReg -> AllocM (Addr ArmReg)
useAddr Liveness
l Addr AbsReg
a) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (LoadLabel Liveness
l AbsReg
r ByteString
lbl)        = (() -> ArmReg -> ByteString -> Arm ArmReg ()
forall reg a. a -> reg -> ByteString -> Arm reg a
LoadLabel () (ArmReg -> ByteString -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ByteString -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (ByteString -> Arm ArmReg ())
-> StateT AllocSt Identity ByteString
-> StateT AllocSt Identity (Arm ArmReg ())
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
lbl) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRR Liveness
l AbsReg
r0 AbsReg
r1)            = (() -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> Arm reg a
MovRR () (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (CSet Liveness
l AbsReg
r Cond
c)               = (() -> ArmReg -> Cond -> Arm ArmReg ()
forall reg a. a -> reg -> Cond -> Arm reg a
CSet () (ArmReg -> Cond -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Cond -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Cond -> Arm ArmReg ())
-> StateT AllocSt Identity Cond
-> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Cond -> StateT AllocSt Identity Cond
forall (f :: * -> *) a. Applicative f => a -> f a
pure Cond
c) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (Store Liveness
l AbsReg
r Addr AbsReg
a)              = (() -> ArmReg -> Addr ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> Addr reg -> Arm reg a
Store () (ArmReg -> Addr ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
-> AllocM (Addr ArmReg) -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> Addr AbsReg -> AllocM (Addr ArmReg)
useAddr Liveness
l Addr AbsReg
a) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (StoreByte Liveness
l AbsReg
r Addr AbsReg
a)          = (() -> ArmReg -> Addr ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> Addr reg -> Arm reg a
StoreByte () (ArmReg -> Addr ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
-> AllocM (Addr ArmReg) -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> Addr AbsReg -> AllocM (Addr ArmReg)
useAddr Liveness
l Addr AbsReg
a) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (CmpRR Liveness
l AbsReg
r0 AbsReg
r1)            = (() -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> Arm reg a
CmpRR () (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (Neg Liveness
l AbsReg
r0 AbsReg
r1)              = (() -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> Arm reg a
Neg () (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MulSubRRR Liveness
l AbsReg
r0 AbsReg
r1 AbsReg
r2 AbsReg
r3)  = (() -> ArmReg -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> reg -> Arm reg a
MulSubRRR () (ArmReg -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT
     AllocSt Identity (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT
  AllocSt Identity (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r3) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (LoadByte Liveness
l AbsReg
r Addr AbsReg
a)           = (() -> ArmReg -> Addr ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> Addr reg -> Arm reg a
LoadByte () (ArmReg -> Addr ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Addr ArmReg -> Arm ArmReg ())
-> AllocM (Addr ArmReg) -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> Addr AbsReg -> AllocM (Addr ArmReg)
useAddr Liveness
l Addr AbsReg
a) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
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 AbsReg
r2)         = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
XorRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
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 AbsReg
r2)          = (() -> ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ()
forall reg a. a -> reg -> reg -> reg -> Arm reg a
OrRR () (ArmReg -> ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (ArmReg -> ArmReg -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r1 StateT AllocSt Identity (ArmReg -> Arm ArmReg ())
-> AllocM ArmReg -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r2) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (BranchNonzero Liveness
l AbsReg
r Label
lbl)    = (() -> ArmReg -> Label -> Arm ArmReg ()
forall reg a. a -> reg -> Label -> Arm reg a
BranchNonzero () (ArmReg -> Label -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Label -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Label -> Arm ArmReg ())
-> StateT AllocSt Identity Label
-> StateT AllocSt Identity (Arm ArmReg ())
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
lbl) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (CmpRC Liveness
l AbsReg
r Int64
c)              = (() -> ArmReg -> Int64 -> Arm ArmReg ()
forall reg a. a -> reg -> Int64 -> Arm reg a
CmpRC () (ArmReg -> Int64 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Int64 -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r StateT AllocSt Identity (Int64 -> Arm ArmReg ())
-> StateT AllocSt Identity Int64
-> StateT AllocSt Identity (Arm ArmReg ())
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 (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l
allocReg (MovRK Liveness
l AbsReg
r0 Word16
c Int8
s)           = (() -> ArmReg -> Word16 -> Int8 -> Arm ArmReg ()
forall reg a. a -> reg -> Word16 -> Int8 -> Arm reg a
MovRK () (ArmReg -> Word16 -> Int8 -> Arm ArmReg ())
-> AllocM ArmReg
-> StateT AllocSt Identity (Word16 -> Int8 -> Arm ArmReg ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Liveness -> AbsReg -> AllocM ArmReg
useReg Liveness
l AbsReg
r0 StateT AllocSt Identity (Word16 -> Int8 -> Arm ArmReg ())
-> StateT AllocSt Identity Word16
-> StateT AllocSt Identity (Int8 -> Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Word16 -> StateT AllocSt Identity Word16
forall (f :: * -> *) a. Applicative f => a -> f a
pure Word16
c StateT AllocSt Identity (Int8 -> Arm ArmReg ())
-> StateT AllocSt Identity Int8
-> StateT AllocSt Identity (Arm ArmReg ())
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
s) StateT AllocSt Identity (Arm ArmReg ())
-> AllocM () -> StateT AllocSt Identity (Arm ArmReg ())
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Liveness -> AllocM ()
freeDone Liveness
l