module Asm.Aarch64.T ( irToAarch64 ) where
import Asm.Aarch64
import Asm.M
import Control.Monad.State.Strict (runState)
import Data.Bifunctor (second)
import Data.Bits (rotateR, (.&.))
import Data.Tuple (swap)
import Data.Word (Word16, Word64, Word8)
import GHC.Float (castDoubleToWord64)
import qualified IR
import qualified Op
absReg :: IR.Temp -> AbsReg
absReg :: Temp -> AbsReg
absReg (IR.ITemp Int
i) = Int -> AbsReg
IReg Int
i; absReg (IR.ATemp Int
i) = Int -> AbsReg
IReg Int
i
absReg Temp
IR.C0 = AbsReg
CArg0; absReg Temp
IR.C1 = AbsReg
CArg1; absReg Temp
IR.C2 = AbsReg
CArg2
absReg Temp
IR.C3 = AbsReg
CArg3; absReg Temp
IR.C4 = AbsReg
CArg4; absReg Temp
IR.C5 = AbsReg
CArg5
absReg Temp
IR.CRet = AbsReg
CArg0
fabsReg :: IR.FTemp -> FAbsReg
fabsReg :: FTemp -> FAbsReg
fabsReg (IR.FTemp Int
i) = Int -> FAbsReg
FReg Int
i
fabsReg FTemp
IR.F0 = FAbsReg
FArg0; fabsReg FTemp
IR.F1 = FAbsReg
FArg1; fabsReg FTemp
IR.F2 = FAbsReg
FArg2
fabsReg FTemp
IR.F3 = FAbsReg
FArg3; fabsReg FTemp
IR.F4 = FAbsReg
FArg4; fabsReg FTemp
IR.F5 = FAbsReg
FArg5
fabsReg FTemp
IR.FRet = FAbsReg
FArg0; fabsReg FTemp
IR.FRet1 = FAbsReg
FArg1
mB :: BBin -> a -> reg -> reg -> reg -> AArch64 reg freg f2 a
mB BBin
Op.AndB = a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> reg -> reg -> reg -> AArch64 reg freg f2 a
AndRR
mB BBin
Op.OrB = a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> reg -> reg -> reg -> AArch64 reg freg f2 a
OrRR
mB BBin
Op.XorB = a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> reg -> reg -> reg -> AArch64 reg freg f2 a
Eor
mIop :: IBin -> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
mIop IBin
Op.IPlus = (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> reg -> reg -> reg -> AArch64 reg freg f2 a
AddRR
mIop IBin
Op.IMinus = (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> reg -> reg -> reg -> AArch64 reg freg f2 a
SubRR
mIop IBin
Op.ITimes = (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> reg -> reg -> reg -> AArch64 reg freg f2 a
MulRR
mIop IBin
Op.IDiv = (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> reg -> reg -> reg -> AArch64 reg freg f2 a
Sdiv
mIop (Op.BI BBin
b) = (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just((a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a))
-> (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
forall a b. (a -> b) -> a -> b
$BBin -> a -> reg -> reg -> reg -> AArch64 reg freg f2 a
forall {a} {reg} {freg} {f2}.
BBin -> a -> reg -> reg -> reg -> AArch64 reg freg f2 a
mB BBin
b
mIop IBin
_ = Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
forall a. Maybe a
Nothing
mFop :: FBin -> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
mFop FBin
Op.FPlus = (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> AArch64 reg freg f2 a
Fadd
mFop FBin
Op.FMinus = (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> AArch64 reg freg f2 a
Fsub
mFop FBin
Op.FTimes = (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> AArch64 reg freg f2 a
Fmul
mFop FBin
Op.FDiv = (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> AArch64 reg freg f2 a
Fdiv
mFop FBin
Op.FMax = (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> AArch64 reg freg f2 a
Fmax
mFop FBin
Op.FMin = (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> AArch64 reg freg f2 a
Fmin
mFop FBin
_ = Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
forall a. Maybe a
Nothing
frel :: Op.FRel -> Cond
frel :: FRel -> Cond
frel FRel
Op.FGeq = Cond
Geq
frel FRel
Op.FLeq = Cond
Leq
frel FRel
Op.FGt = Cond
Gt
frel FRel
Op.FLt = Cond
Lt
frel FRel
Op.FEq = Cond
Eq
frel FRel
Op.FNeq = Cond
Neq
iop :: Op.IRel -> Cond
iop :: IRel -> Cond
iop IRel
Op.IEq = Cond
Eq
iop IRel
Op.INeq = Cond
Neq
iop IRel
Op.IGeq = Cond
Geq
iop IRel
Op.ILeq = Cond
Leq
iop IRel
Op.IGt = Cond
Gt
iop IRel
Op.ILt = Cond
Lt
nextR :: WM AbsReg
nextR :: WM AbsReg
nextR = Int -> AbsReg
IReg (Int -> AbsReg) -> StateT WSt Identity Int -> WM AbsReg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT WSt Identity Int
nextI
nextV :: WM F2Abs
nextV :: WM F2Abs
nextV = Int -> F2Abs
F2Reg (Int -> F2Abs) -> StateT WSt Identity Int -> WM F2Abs
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT WSt Identity Int
nextI
nextF :: WM FAbsReg
nextF :: WM FAbsReg
nextF = Int -> FAbsReg
FReg (Int -> FAbsReg) -> StateT WSt Identity Int -> WM FAbsReg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT WSt Identity Int
nextI
irToAarch64 :: IR.WSt -> [IR.Stmt] -> (Int, [AArch64 AbsReg FAbsReg F2Abs ()])
irToAarch64 :: WSt -> [Stmt] -> (Int, [AArch64 AbsReg FAbsReg F2Abs ()])
irToAarch64 WSt
st = ([AArch64 AbsReg FAbsReg F2Abs ()], Int)
-> (Int, [AArch64 AbsReg FAbsReg F2Abs ()])
forall a b. (a, b) -> (b, a)
swap (([AArch64 AbsReg FAbsReg F2Abs ()], Int)
-> (Int, [AArch64 AbsReg FAbsReg F2Abs ()]))
-> ([Stmt] -> ([AArch64 AbsReg FAbsReg F2Abs ()], Int))
-> [Stmt]
-> (Int, [AArch64 AbsReg FAbsReg F2Abs ()])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WSt -> Int)
-> ([AArch64 AbsReg FAbsReg F2Abs ()], WSt)
-> ([AArch64 AbsReg FAbsReg F2Abs ()], Int)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second WSt -> Int
IR.wtemps (([AArch64 AbsReg FAbsReg F2Abs ()], WSt)
-> ([AArch64 AbsReg FAbsReg F2Abs ()], Int))
-> ([Stmt] -> ([AArch64 AbsReg FAbsReg F2Abs ()], WSt))
-> [Stmt]
-> ([AArch64 AbsReg FAbsReg F2Abs ()], Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
-> WSt -> ([AArch64 AbsReg FAbsReg F2Abs ()], WSt))
-> WSt
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
-> ([AArch64 AbsReg FAbsReg F2Abs ()], WSt)
forall a b c. (a -> b -> c) -> b -> a -> c
flip State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
-> WSt -> ([AArch64 AbsReg FAbsReg F2Abs ()], WSt)
forall s a. State s a -> s -> (a, s)
runState WSt
st (State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
-> ([AArch64 AbsReg FAbsReg F2Abs ()], WSt))
-> ([Stmt] -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()])
-> [Stmt]
-> ([AArch64 AbsReg FAbsReg F2Abs ()], WSt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Stmt -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()])
-> [Stmt] -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall (f :: * -> *) (t :: * -> *) m a.
(Applicative f, Traversable t, Monoid m) =>
(a -> f m) -> t a -> f m
foldMapA Stmt -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
ir
aR :: AbsReg -> WM [AArch64 AbsReg FAbsReg F2Abs ()]
aR :: AbsReg -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
aR AbsReg
t = do
l <- WM Label
nextL
pure [TstI () t (BM 1 3), Bc () Eq l, AddRC () t t 8, Label () l]
plF :: IR.FExp -> WM ([AArch64 AbsReg FAbsReg F2Abs ()] -> [AArch64 AbsReg FAbsReg F2Abs ()], FAbsReg)
plF :: FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF (IR.FReg FTemp
t) = ([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> a
id, FTemp -> FAbsReg
fabsReg FTemp
t)
plF FExp
e = do {i <- StateT WSt Identity Int
nextI; pl <- feval e (IR.FTemp i); pure ((pl++), FReg i)}
plI :: IR.Exp -> WM ([AArch64 AbsReg FAbsReg F2Abs ()] -> [AArch64 AbsReg FAbsReg F2Abs ()], AbsReg)
plI :: Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI (IR.Reg Temp
t) = ([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> a
id, Temp -> AbsReg
absReg Temp
t)
plI Exp
e = do {i <- StateT WSt Identity Int
nextI; pl <- eval e (IR.ITemp i); pure ((pl++), IReg i)}
ir :: IR.Stmt -> WM [AArch64 AbsReg FAbsReg F2Abs ()]
ir :: Stmt -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
ir (IR.R Label
l) = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> Label -> AArch64 reg freg f2 a
RetL () Label
l]
ir (IR.L Label
l) = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> Label -> AArch64 reg freg f2 a
Label () Label
l]
ir (IR.J Label
l) = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> Label -> AArch64 reg freg f2 a
B () Label
l]
ir (IR.C Label
l) = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> Label -> AArch64 reg freg f2 a
C () Label
l]
ir (IR.MX FTemp
t FExp
e) = FExp -> FTemp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
feval FExp
e FTemp
t
ir (IR.MT Temp
t Exp
e) = Exp -> Temp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
eval Exp
e Temp
t
ir (IR.Ma AL
_ Temp
t Exp
e) = do {r <- WM AbsReg
nextR; plE <- eval e IR.C0; pure $ plE ++ puL ++ [AddRC () FP ASP 16, MovRCf () r Malloc, Blr () r, MovRR () (absReg t) CArg0] ++ poL}
ir (IR.Free Temp
t) = do {r <- WM AbsReg
nextR; pure $ puL ++ [MovRR () CArg0 (absReg t), AddRC () FP ASP 16, MovRCf () r Free, Blr () r] ++ poL}
ir (IR.Sa Temp
t (IR.ConstI Int64
i)) | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 (Int64 -> Int64
forall {a}. Integral a => a -> a
sai Int64
i) = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a.
a -> reg -> reg -> Word16 -> AArch64 reg freg f2 a
SubRC () AbsReg
ASP AbsReg
ASP Word16
u, () -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> reg -> AArch64 reg freg f2 a
MovRR () (Temp -> AbsReg
absReg Temp
t) AbsReg
ASP]
ir (IR.Sa Temp
t (IR.Reg Temp
r)) = let r' :: AbsReg
r'=Temp -> AbsReg
absReg Temp
r in do {plR <- AbsReg -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
aR AbsReg
r'; pure $ plR++[SubRR () ASP ASP (absReg r), MovRR () (absReg t) ASP]}
ir (IR.Sa Temp
t Exp
e) = do
r <- StateT WSt Identity Int
nextI; plE <- eval e (IR.ITemp r)
let r'=Int -> AbsReg
IReg Int
r
plR <- aR r'
pure $ plE ++ plR ++ [SubRR () ASP ASP r', MovRR () (absReg t) ASP]
ir (IR.Pop (IR.ConstI Int64
i)) | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 (Int64 -> Int64
forall {a}. Integral a => a -> a
sai Int64
i) = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a.
a -> reg -> reg -> Word16 -> AArch64 reg freg f2 a
AddRC () AbsReg
ASP AbsReg
ASP Word16
u]
ir (IR.Pop (IR.Reg Temp
r)) = let r' :: AbsReg
r'=Temp -> AbsReg
absReg Temp
r in do {plR <- AbsReg -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
aR AbsReg
r'; pure $ plR ++ [AddRR () ASP ASP r']}
ir (IR.Pop Exp
e) = do
r <- StateT WSt Identity Int
nextI; plE <- eval e (IR.ITemp r)
let r'=Int -> AbsReg
IReg Int
r
plR <- aR r'
pure $ plE ++ plR ++ [AddRR () ASP ASP r']
ir (IR.Wr (IR.AP Temp
t Maybe Exp
Nothing Maybe AL
_) Exp
e) = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Str () r (R $ absReg t)]
ir (IR.Wr (IR.AP Temp
t (Just (IR.ConstI Int64
i)) Maybe AL
_) Exp
e) | Just Word16
p <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mp Int64
i = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Str () r (RP (absReg t) p)]
ir (IR.Wr (IR.AP Temp
t (Just (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3))) Maybe AL
_) Exp
e) = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e; (plEI,rI) <- plI eI
pure $ plE $ plEI [Str () r (BI (absReg t) rI Three)]
ir (IR.Wr (IR.AP Temp
t (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3)) (IR.ConstI Int64
i))) Maybe AL
_) Exp
e) | (Int64
ix, Int64
0) <- Int64
i Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
8 = do
rI <- StateT WSt Identity Int
nextI
plEI <- eval (eI+IR.ConstI ix) (IR.ITemp rI)
(plE,r) <- plI e
pure $ plE $ plEI ++ [Str () r (BI (absReg t) (IReg rI) Three)]
ir (IR.Wr (IR.AP Temp
t (Just Exp
eI) Maybe AL
_) Exp
e) = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e; (plEI,rI) <- plI eI
pure $ plE $ plEI [Str () r (BI (absReg t) rI Zero)]
ir (IR.WrB (IR.AP Temp
t (Just (IR.ConstI Int64
i)) Maybe AL
_) (IR.ConstI Int64
n)) | Just Word16
iu <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
i, Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
n = do
r <- WM AbsReg
nextR
pure [MovRC () r u, StrB () r (RP (absReg t) iu)]
ir (IR.WrB (IR.AP Temp
t (Just Exp
eI) Maybe AL
_) (IR.ConstI Int64
n)) | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
n = do
i <- WM AbsReg
nextR
(plEI,rI) <- plI eI
pure $ plEI [MovRC () i u, StrB () i (BI (absReg t) rI Zero)]
ir (IR.WrB (IR.AP Temp
t (Just (IR.ConstI Int64
ix)) Maybe AL
_) (IR.Is Temp
i)) | Just Word16
iu <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
ix = do
[AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> AArch64 reg freg f2 a
StrB () (Temp -> AbsReg
absReg Temp
i) (AbsReg -> Word16 -> Addr AbsReg
forall reg. reg -> Word16 -> Addr reg
RP (Temp -> AbsReg
absReg Temp
t) Word16
iu)]
ir (IR.WrB (IR.AP Temp
t (Just Exp
eI) Maybe AL
_) (IR.Is Temp
i)) = do
(plEI,rI) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
eI
pure $ plEI [StrB () (absReg i) (BI (absReg t) rI Zero)]
ir (IR.WrF (IR.AP Temp
tB (Just (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3))) Maybe AL
_) FExp
e) = do
(plEI,iI) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
eI
(plE,i) <- plF e
pure $ plE $ plEI [StrD () i (BI (absReg tB) iI Three)]
ir (IR.WrF (IR.AP Temp
tB (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3)) (IR.ConstI Int64
ix8))) Maybe AL
_) FExp
e) | (Int64
ix, Int64
0) <- Int64
ix8 Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
8 = do
iI <- StateT WSt Identity Int
nextI
plEI <- eval (eI+IR.ConstI ix) (IR.ITemp iI)
(plE,i) <- plF e
pure $ plE $ plEI ++ [StrD () i (BI (absReg tB) (IReg iI) Three)]
ir (IR.WrF (IR.AP Temp
t (Just Exp
eI) Maybe AL
_) FExp
e) = do
(plE,i) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e; (plEI,iI) <- plI eI
pure $ plE $ plEI [StrD () i (BI (absReg t) iI Zero)]
ir (IR.WrF (IR.AP Temp
t Maybe Exp
Nothing Maybe AL
_) FExp
e) = do
(plE,i) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [StrD () i (R (absReg t))]
ir (IR.MJ (IR.IRel IRel
Op.INeq Exp
e (IR.ConstI Int64
0)) Label
l) = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Cbnz () r l]
ir (IR.MJ (IR.Is Temp
r) Label
l) =
[AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Label -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Label -> AArch64 reg freg f2 a
Cbnz () (Temp -> AbsReg
absReg Temp
r) Label
l]
ir (IR.MJ (IR.IU IUn
Op.IEven Exp
e) Label
l) = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Tbz () r 0 l]
ir (IR.MJ (IR.IRel IRel
op Exp
e (IR.ConstI Int64
i)) Label
l) | Cond
c <- IRel -> Cond
iop IRel
op, Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
m12 Int64
i = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [CmpRC () r u, Bc () c l]
ir (IR.MJ (IR.IRel IRel
op Exp
e0 Exp
e1) Label
l) | Cond
c <- IRel -> Cond
iop IRel
op = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [CmpRR () r0 r1, Bc () c l]
ir (IR.MJ (IR.FRel FRel
op FExp
e (IR.ConstF Double
0)) Label
l) | Cond
c <- FRel -> Cond
frel FRel
op = do
(plE,i) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [FcmpZ () i, Bc () c l]
ir (IR.MJ (IR.FRel FRel
op FExp
e0 FExp
e1) Label
l) | Cond
c <- FRel -> Cond
frel FRel
op = do
(plE0,r0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,r1) <- plF e1
pure $ plE0 $ plE1 [Fcmp () r0 r1, Bc () c l]
ir (IR.MJ (IR.BU BUn
Op.BNeg Exp
p) Label
l) = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
p
pure $ plE [Cbz () r l]
ir (IR.MJ Exp
p Label
l) = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
p
pure $ plE [Cbnz () r l]
ir (IR.Cmov (IR.IRel IRel
op Exp
e0 Exp
e1) Temp
t Exp
e) | Cond
c <- IRel -> Cond
iop IRel
op = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
(plE,r) <- plI e
pure $ plE $ plE0 $ plE1 [CmpRR () r0 r1, Csel () (absReg t) r (absReg t) c]
ir (IR.Cset Temp
t (IR.IRel IRel
op Exp
e0 (IR.ConstI Int64
i))) | Cond
c <- IRel -> Cond
iop IRel
op, Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
m12 Int64
i = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0
pure $ plE0 [CmpRC () r0 u, Cset () (absReg t) c]
ir (IR.Cset Temp
t (IR.IRel IRel
op Exp
e0 Exp
e1)) | Cond
c <- IRel -> Cond
iop IRel
op = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [CmpRR () r0 r1, Cset () (absReg t) c]
ir (IR.Cset Temp
t (IR.FRel FRel
op FExp
e0 FExp
e1)) | Cond
c <- FRel -> Cond
frel FRel
op = do
(plE0,r0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,r1) <- plF e1
pure $ plE0 $ plE1 [Fcmp () r0 r1, Cset () (absReg t) c]
ir (IR.Cset Temp
t (IR.IU IUn
Op.IOdd Exp
e0)) = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0
pure $ plE0 [TstI () r0 (BM 1 0), Cset () (absReg t) Neq]
ir (IR.Cset Temp
t (IR.IU IUn
Op.IEven Exp
e0)) = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0
pure $ plE0 [TstI () r0 (BM 1 0), Cset () (absReg t) Eq]
ir (IR.Fcmov (IR.IRel IRel
op Exp
e0 (IR.ConstI Int64
i64)) FTemp
t FExp
e) | Cond
c <- IRel -> Cond
iop IRel
op, Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
m12 Int64
i64 = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE,i) <- plF e
pure $ plE $ plE0 [CmpRC () r0 u, Fcsel () (fabsReg t) i (fabsReg t) c]
ir (IR.Fcmov (IR.IRel IRel
op Exp
e0 Exp
e1) FTemp
t FExp
e) | Cond
c <- IRel -> Cond
iop IRel
op = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
(plE,i) <- plF e
pure $ plE $ plE0 $ plE1 [CmpRR () r0 r1, Fcsel () (fabsReg t) i (fabsReg t) c]
ir (IR.Fcmov (IR.FRel FRel
op FExp
e0 FExp
e1) FTemp
t FExp
e) | Cond
c <- FRel -> Cond
frel FRel
op = do
(plE0,r0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,r1) <- plF e1
(plE,i) <- plF e
pure $ plE $ plE0 $ plE1 [Fcmp () r0 r1, Fcsel () (fabsReg t) i (fabsReg t) c]
ir (IR.Fcmov (IR.IU IUn
Op.IOdd Exp
e0) FTemp
t FExp
e) = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE,i) <- plF e
pure $ plE $ plE0 [TstI () r0 (BM 1 0), Fcsel () (fabsReg t) i (fabsReg t) Neq]
ir (IR.Fcmov (IR.IU IUn
Op.IEven Exp
e0) FTemp
t FExp
e) = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE,i) <- plF e
pure $ plE $ plE0 [TstI () r0 (BM 1 0), Fcsel () (fabsReg t) i (fabsReg t) Eq]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
Nothing Maybe AL
_) (IR.AP Temp
tS Maybe Exp
Nothing Maybe AL
_) (IR.ConstI Int64
n)) | (Int64
n', Int64
0) <- Int64
n Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
2, Int64
n' Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
t0 <- WM AbsReg
nextR; t1 <- nextR
pure $ concat [ [Ldp () t0 t1 (RP (absReg tS) (i*16)), Stp () t0 t1 (RP (absReg tD) (i*16))] | i <- fromIntegral<$>[0..(n'-1)] ]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
Nothing Maybe AL
_) (IR.AP Temp
tS Maybe Exp
Nothing Maybe AL
_) (IR.ConstI Int64
n)) | Int64
n Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
t <- WM AbsReg
nextR
pure $ concat [ [Ldr () t (RP (absReg tS) (i*8)), Str () t (RP (absReg tD) (i*8))] | i <- fromIntegral<$>[0..(n-1)] ]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
Nothing Maybe AL
_) (IR.AP Temp
tS (Just Exp
eS) Maybe AL
_) (IR.ConstI Int64
n)) | (Int64
n', Int64
0) <- Int64
n Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
2, Int64
n' Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI
t0 <- nextR; t1 <- nextR
plED <- eval (IR.Reg tD) (IR.ITemp rD)
plES <- eval (IR.Reg tS+eS) (IR.ITemp rS)
pure $ plED ++ plES ++ concat [ [Ldp () t0 t1 (RP (IReg rS) (i*16)), Stp () t0 t1 (RP (IReg rD) (i*16))] | i <- fromIntegral<$>[0..(n'-1)] ]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
eD) Maybe AL
_) (IR.AP Temp
tS Maybe Exp
Nothing Maybe AL
_) (IR.ConstI Int64
n)) | (Int64
n', Int64
0) <- Int64
n Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
2, Int64
n' Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI
t0 <- nextR; t1 <- nextR
plED <- eval (IR.Reg tD+eD) (IR.ITemp rD)
plES <- eval (IR.Reg tS) (IR.ITemp rS)
pure $ plED ++ plES ++ concat [ [Ldp () t0 t1 (RP (IReg rS) (i*16)), Stp () t0 t1 (RP (IReg rD) (i*16))] | i <- fromIntegral<$>[0..(n'-1)] ]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
eD) Maybe AL
_) (IR.AP Temp
tS (Just Exp
eS) Maybe AL
_) (IR.ConstI Int64
n)) | (Int64
n', Int64
0) <- Int64
n Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
2, Int64
n' Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI
t0 <- nextR; t1 <- nextR
plED <- eval (IR.Reg tD+eD) (IR.ITemp rD)
plES <- eval (IR.Reg tS+eS) (IR.ITemp rS)
pure $ plED ++ plES ++ concat [ [Ldp () t0 t1 (RP (IReg rS) (i*16)), Stp () t0 t1 (RP (IReg rD) (i*16))] | i <- fromIntegral<$>[0..(n'-1)] ]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
eD) Maybe AL
_) (IR.AP Temp
tS (Just Exp
eS) Maybe AL
_) (IR.ConstI Int64
n)) | (Int64
n', Int64
1) <- Int64
n Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
2, Int64
n' Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI
t0 <- nextR; t1 <- nextR
plED <- eval (IR.Reg tD+eD) (IR.ITemp rD)
plES <- eval (IR.Reg tS+eS) (IR.ITemp rS)
let li=Int64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral(Int64 -> Word16) -> Int64 -> Word16
forall a b. (a -> b) -> a -> b
$(Int64
nInt64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
-Int64
1)Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
*Int64
8
pure $ plED ++ plES ++ concat [ [Ldp () t0 t1 (RP (IReg rS) (i*16)), Stp () t0 t1 (RP (IReg rD) (i*16))] | i <- fromIntegral<$>[0..(n'-1)] ] ++ [Ldr () t0 (RP (IReg rS) li), Str () t0 (RP (IReg rD) li)]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.ConstI Int64
oD)) Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
oS)) Maybe AL
_) Exp
eN) | Just Word16
uS <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
oS, Just Word16
uD <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
oD = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI; i <- nextR
t0 <- nextR; t1 <- nextR
plED <- eval (IR.Reg tD) (IR.ITemp rD)
plES <- eval (IR.Reg tS) (IR.ITemp rS)
(plEN, rN) <- plI eN
let rDA=Int -> AbsReg
IReg Int
rD; rSA=Int -> AbsReg
IReg Int
rS
l <- nextL; eL <- nextL
pure $ plED ++ plES ++ plEN [ZeroR () i, CmpRR () i rN, Bc () Geq eL, Tbz () rN 0 l, Ldr () t0 (RP rSA uS), Str () t0 (RP rDA uD), MovRC () i 1, Bc () Geq eL, AddRC () rSA rSA 8, AddRC () rDA rDA 8, Label () l, Ldp () t0 t1 (RP rSA uS), Stp () t0 t1 (RP rDA uD), AddRC () rSA rSA 16, AddRC () rDA rDA 16, AddRC () i i 2, CmpRR () i rN, Bc () Lt l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.ConstI Int64
oD)) Maybe AL
_) (IR.AP Temp
tS Maybe Exp
eS Maybe AL
_) Exp
eN) | Just Word16
uD <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
oD = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI; i <- nextR
t0 <- nextR; t1 <- nextR
plED <- eval (IR.Reg tD) (IR.ITemp rD)
plES <- eval (maybe id (+) eS$IR.Reg tS) (IR.ITemp rS)
(plEN, rN) <- plI eN
let rDA=Int -> AbsReg
IReg Int
rD; rSA=Int -> AbsReg
IReg Int
rS
l <- nextL; eL <- nextL
pure $ plED ++ plES ++ plEN [ZeroR () i, CmpRR () i rN, Bc () Geq eL, Tbz () rN 0 l, Ldr () t0 (R rSA), Str () t0 (RP rDA uD), MovRC () i 1, Bc () Geq eL, AddRC () rSA rSA 8, AddRC () rDA rDA 8, Label () l, Ldp () t0 t1 (R rSA), Stp () t0 t1 (RP rDA uD), AddRC () rSA rSA 16, AddRC () rDA rDA 16, AddRC () i i 2, CmpRR () i rN, Bc () Lt l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
eD Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
oS)) Maybe AL
_) Exp
eN) | Just Word16
uS <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
oS = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI; i <- nextR
t0 <- nextR; t1 <- nextR
plED <- eval (maybe id (+) eD$IR.Reg tD) (IR.ITemp rD)
plES <- eval (IR.Reg tS) (IR.ITemp rS)
(plEN, rN) <- plI eN
let rDA=Int -> AbsReg
IReg Int
rD; rSA=Int -> AbsReg
IReg Int
rS
l <- nextL; eL <- nextL
pure $ plED ++ plES ++ plEN [ZeroR () i, CmpRR () i rN, Bc () Geq eL, Tbz () rN 0 l, Ldr () t0 (RP rSA uS), Str () t0 (R rDA), MovRC () i 1, Bc () Geq eL, AddRC () rSA rSA 8, AddRC () rDA rDA 8, Label () l, Ldp () t0 t1 (RP rSA uS), Stp () t0 t1 (R rDA), AddRC () rSA rSA 16, AddRC () rDA rDA 16, AddRC () i i 2, CmpRR () i rN, Bc () Lt l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
eD Maybe AL
_) (IR.AP Temp
tS (Just (IR.IB IBin
Op.IPlus Exp
eS (IR.ConstI Int64
oS))) Maybe AL
_) Exp
eN) | Just Word16
uS <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
oS = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI; i <- nextR
t0 <- nextR; t1 <- nextR
plED <- eval (maybe id (+) eD$IR.Reg tD) (IR.ITemp rD)
plES <- eval (eS+IR.Reg tS) (IR.ITemp rS)
(plEN, rN) <- plI eN
let rDA=Int -> AbsReg
IReg Int
rD; rSA=Int -> AbsReg
IReg Int
rS
l <- nextL; eL <- nextL
pure $ plED ++ plES ++ plEN [ZeroR () i, CmpRR () i rN, Bc () Geq eL, Tbz () rN 0 l, Ldr () t0 (RP rSA uS), Str () t0 (R rDA), MovRC () i 1, Bc () Geq eL, AddRC () rSA rSA 8, AddRC () rDA rDA 8, Label () l, Ldp () t0 t1 (RP rSA uS), Stp () t0 t1 (R rDA), AddRC () rSA rSA 16, AddRC () rDA rDA 16, AddRC () i i 2, CmpRR () i rN, Bc () Lt l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
eD Maybe AL
_) (IR.AP Temp
tS Maybe Exp
eS Maybe AL
_) Exp
eN) = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI; i <- nextR
t0 <- nextR; t1 <- nextR
plED <- eval (maybe id (+) eD$IR.Reg tD) (IR.ITemp rD)
plES <- eval (maybe id (+) eS$IR.Reg tS) (IR.ITemp rS)
(plEN, rN) <- plI eN
let rDA=Int -> AbsReg
IReg Int
rD; rSA=Int -> AbsReg
IReg Int
rS
l <- nextL; eL <- nextL
pure $ plED ++ plES ++ plEN [ZeroR () i, CmpRR () i rN, Bc () Geq eL, Tbz () rN 0 l, Ldr () t0 (R rSA), Str () t0 (R rDA), MovRC () i 1, Bc () Geq eL, AddRC () rSA rSA 8, AddRC () rDA rDA 8, Label () l, Ldp () t0 t1 (R rSA), Stp () t0 t1 (R rDA), AddRC () rSA rSA 16, AddRC () rDA rDA 16, AddRC () i i 2, CmpRR () i rN, Bc () Lt l, Label () eL]
ir (IR.Cpy1 (IR.AP Temp
tD (Just (IR.ConstI Int64
di)) Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
si)) Maybe AL
_) Exp
eN) | Just Word16
du <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
di, Just Word16
su <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
si = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI; i <- nextR; t <- nextR
(plEN, rN) <- plI eN
l <- nextL; eL <- nextL
let rDA=Int -> AbsReg
IReg Int
rD; rSA=Int -> AbsReg
IReg Int
rS
pure $ plEN [MovRR () rDA (absReg tD), MovRR () rSA (absReg tS), ZeroR () i, CmpRR () i rN, Bc () Geq eL, Label () l, LdrB () t (RP rSA du), StrB () t (RP rDA su), AddRC () rSA rSA 1, AddRC () rDA rDA 1, AddRC () i i 1, CmpRR () i rN, Bc () Lt l, Label () eL]
ir (IR.Cpy1 (IR.AP Temp
tD Maybe Exp
eD Maybe AL
_) (IR.AP Temp
tS Maybe Exp
eS Maybe AL
_) Exp
eN) = do
rD <- StateT WSt Identity Int
nextI; rS <- nextI; i <- nextR; t <- nextR
plED <- eval (maybe id (+) eD$IR.Reg tD) (IR.ITemp rD)
plES <- eval (maybe id (+) eS$IR.Reg tS) (IR.ITemp rS)
(plEN, rN) <- plI eN
l <- nextL; eL <- nextL
let rDA=Int -> AbsReg
IReg Int
rD; rSA=Int -> AbsReg
IReg Int
rS
pure $ plED ++ plES ++ plEN [ZeroR () i, CmpRR () i rN, Bc () Geq eL, Label () l, LdrB () t (BI rSA i Zero), StrB () t (BI rDA i Zero), AddRC () i i 1, CmpRR () i rN, Bc () Lt l, Label () eL]
ir (IR.IRnd Temp
t) = do
r <- WM AbsReg
nextR
pure $ puL ++ [AddRC () FP ASP 16, MovRCf () r JR, Blr () r, MovRR () (absReg t) CArg0] ++ poL
ir (IR.FRnd FTemp
t) = do
r <- WM AbsReg
nextR
pure $ puL ++ [AddRC () FP ASP 16, MovRCf () r DR, Blr () r, FMovXX () (fabsReg t) FArg0] ++ poL
ir Stmt
s = [Char] -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. HasCallStack => [Char] -> a
error (Stmt -> [Char]
forall a. Show a => a -> [Char]
show Stmt
s)
puL, poL :: [AArch64 AbsReg freg f2reg ()]
puL :: forall freg f2reg. [AArch64 AbsReg freg f2reg ()]
puL = [() -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg freg f2reg ()
forall reg freg f2 a.
a -> reg -> reg -> Word16 -> AArch64 reg freg f2 a
SubRC () AbsReg
ASP AbsReg
ASP Word16
16, ()
-> AbsReg -> AbsReg -> Addr AbsReg -> AArch64 AbsReg freg f2reg ()
forall reg freg f2 a.
a -> reg -> reg -> Addr reg -> AArch64 reg freg f2 a
Stp () AbsReg
FP AbsReg
LR (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R AbsReg
ASP)]
poL :: forall freg f2reg. [AArch64 AbsReg freg f2reg ()]
poL = [()
-> AbsReg -> AbsReg -> Addr AbsReg -> AArch64 AbsReg freg f2reg ()
forall reg freg f2 a.
a -> reg -> reg -> Addr reg -> AArch64 reg freg f2 a
Ldp () AbsReg
FP AbsReg
LR (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R AbsReg
ASP), () -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg freg f2reg ()
forall reg freg f2 a.
a -> reg -> reg -> Word16 -> AArch64 reg freg f2 a
AddRC () AbsReg
ASP AbsReg
ASP Word16
16]
sai :: a -> a
sai a
i | a
i a -> a -> a
forall a. Integral a => a -> a -> a
`rem` a
16 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = a
ia -> a -> a
forall a. Num a => a -> a -> a
+a
16 | Bool
otherwise = a
ia -> a -> a
forall a. Num a => a -> a -> a
+a
16a -> a -> a
forall a. Num a => a -> a -> a
+(a
16a -> a -> a
forall a. Num a => a -> a -> a
-a
r) where r :: a
r = a
i a -> a -> a
forall a. Integral a => a -> a -> a
`rem` a
16
mw64 :: Word64 -> AbsReg -> [AArch64 AbsReg freg f2reg ()]
mw64 :: forall freg f2reg.
Word64 -> AbsReg -> [AArch64 AbsReg freg f2reg ()]
mw64 Word64
w AbsReg
r =
let w0 :: Word64
w0=Word64
w Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0xffff; w1 :: Word64
w1=(Word64
w Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0xffff0000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`rotateR` Int
16; w2 :: Word64
w2=(Word64
w Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0xFFFF00000000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`rotateR` Int
32; w3 :: Word64
w3=(Word64
w Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.&. Word64
0xFFFF000000000000) Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`rotateR` Int
48
in () -> AbsReg -> Word16 -> AArch64 AbsReg freg f2reg ()
forall reg freg f2 a. a -> reg -> Word16 -> AArch64 reg freg f2 a
MovRC () AbsReg
r (Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w0)AArch64 AbsReg freg f2reg ()
-> [AArch64 AbsReg freg f2reg ()] -> [AArch64 AbsReg freg f2reg ()]
forall a. a -> [a] -> [a]
:[() -> AbsReg -> Word16 -> Int -> AArch64 AbsReg freg f2reg ()
forall reg freg f2 a.
a -> reg -> Word16 -> Int -> AArch64 reg freg f2 a
MovK () AbsReg
r (Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
wi) Int
s | (Word64
wi, Int
s) <- [(Word64
w1, Int
16), (Word64
w2, Int
32), (Word64
w3, Int
48)], Word64
wi Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word64
0 ]
ssin :: IR.FTemp -> WM [AArch64 AbsReg FAbsReg F2Abs ()]
ssin :: FTemp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
ssin FTemp
t = do
d1 <- WM FAbsReg
nextF; d2 <- nextF; d3 <- nextF
tsI <- nextI
let tsIR=Int -> FTemp
IR.FTemp Int
tsI; tsC=Int -> FAbsReg
FReg Int
tsI
pl3 <- feval (IR.ConstF$ -(1/6)) tsIR; pl5 <- feval (IR.ConstF$1/120) tsIR; pl7 <- feval (IR.ConstF$ -(1/5040)) tsIR
pure $ [Fmul () d1 d0 d0, Fmul () d2 d1 d0, Fmul () d3 d2 d1, Fmul () d1 d1 d3] ++ pl3 ++ Fmadd () d0 d2 tsC d0 : pl5 ++ Fmadd () d0 d3 tsC d0 : pl7 ++ [Fmadd () d0 d1 tsC d0]
where
d0 :: FAbsReg
d0 = FTemp -> FAbsReg
fabsReg FTemp
t
cosϵ :: IR.FTemp -> WM [AArch64 AbsReg FAbsReg F2Abs ()]
cosϵ :: FTemp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
cosϵ FTemp
t = do
d1 <- WM FAbsReg
nextF; d2 <- nextF; d3 <- nextF
tsI <- nextI
let tsIR=Int -> FTemp
IR.FTemp Int
tsI; tsC=Int -> FAbsReg
FReg Int
tsI
pl0 <- feval 1 tsIR; pl2 <- feval (IR.ConstF$ -(1/2)) tsIR; pl4 <- feval (IR.ConstF$1/24) tsIR; pl6 <- feval (IR.ConstF$ -(1/720)) tsIR
pure $ [Fmul () d1 d0 d0, Fmul () d2 d1 d1, Fmul () d3 d2 d1] ++ pl0 ++ FMovXX () d0 tsC : pl2 ++ Fmadd () d0 d1 tsC d0 : pl4 ++ Fmadd () d0 d2 tsC d0 : pl6 ++ [Fmadd () d0 d3 tsC d0]
where
d0 :: FAbsReg
d0 = FTemp -> FAbsReg
fabsReg FTemp
t
feval :: IR.FExp -> IR.FTemp -> WM [AArch64 AbsReg FAbsReg F2Abs ()]
feval :: FExp -> FTemp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
feval (IR.FReg FTemp
tS) FTemp
tD = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> freg -> freg -> AArch64 reg freg f2 a
FMovXX () (FTemp -> FAbsReg
fabsReg FTemp
tD) (FTemp -> FAbsReg
fabsReg FTemp
tS)]
feval (IR.ConstF Double
d) FTemp
t = do
i <- StateT WSt Identity Int
nextI
let r=Int -> AbsReg
IReg Int
i
w=Double -> Word64
castDoubleToWord64 Double
d
pure $ mw64 w r ++ [FMovDR () (fabsReg t) r]
feval (IR.FU FUn
Op.FSin FExp
e) FTemp
t = do
plE <- FExp -> FTemp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
feval FExp
e FTemp
t
let d0=FTemp -> FAbsReg
fabsReg FTemp
t
s <- ssin t; c <- cosϵ t
lc <- nextL; endL <- nextL
i <- nextR; d2 <- nextF; i7 <- nextI
π4i<-nextI; plπ4 <- feval (IR.ConstF$pi/4) (IR.FTemp π4i); pl7 <- eval (IR.ConstI 7) (IR.ITemp i7)
let π4=Int -> FAbsReg
FReg Int
π4i
dRot <- nextF; nres <- nextF
pure $
plE
++plπ4
++[Fdiv () d2 d0 π4, Frintm () d2 d2, Fmsub () d0 π4 d2 d0, Fcvtas () i d2]
++pl7
++[AndRR () i i (IReg i7), TstI () i (BM 1 0), Fsub () dRot π4 d0, Fcsel () d0 dRot d0 Neq]
++[ CmpRC () i 1, Bc () Eq lc, CmpRC () i 2, Bc () Eq lc
, CmpRC () i 5, Bc () Eq lc, CmpRC () i 6, Bc () Eq lc
]
++s++B () endL
:Label () lc:c
++[Label () endL]
++[Fneg () nres d0, TstI () i (BM 1 2), Fcsel () d0 nres d0 Neq]
feval (IR.FU FUn
Op.FCos FExp
e) FTemp
t = FExp -> FTemp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
feval (FUn -> FExp -> FExp
IR.FU FUn
Op.FSin (Double -> FExp
IR.ConstF(Double
forall a. Floating a => a
piDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)FExp -> FExp -> FExp
forall a. Num a => a -> a -> a
-FExp
e)) FTemp
t
feval (IR.FB FBin
Op.FExp (IR.ConstF Double
2.718281828459045) FExp
e) FTemp
t = do
r <- WM AbsReg
nextR
plE <- feval e IR.F0
pure $ plE ++ puL ++ [AddRC () FP ASP 16, MovRCf () r Exp, Blr () r, FMovXX () (fabsReg t) FArg0] ++ poL
feval (IR.FB FBin
Op.FExp FExp
e0 FExp
e1) FTemp
t = do
r <- WM AbsReg
nextR
plE0 <- feval e0 IR.F0; plE1 <- feval e1 IR.F1
pure $ plE0 ++ plE1 ++ puL ++ [AddRC () FP ASP 16, MovRCf () r Pow, Blr () r, FMovXX () (fabsReg t) FArg0] ++ poL
feval (IR.FU FUn
Op.FLog FExp
e) FTemp
t = do
r <- WM AbsReg
nextR
plE <- feval e IR.F0
pure $ plE ++ puL ++ [AddRC () FP ASP 16, MovRCf () r Log, Blr () r, FMovXX () (fabsReg t) FArg0] ++ poL
feval (IR.FB FBin
Op.FPlus FExp
e0 (IR.FB FBin
Op.FTimes FExp
e1 FExp
e2)) FTemp
t = do
(plE0,i0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,i1) <- plF e1; (plE2,i2) <- plF e2
pure $ plE0 $ plE1 $ plE2 [Fmadd () (fabsReg t) i1 i2 i0]
feval (IR.FB FBin
Op.FPlus (IR.FB FBin
Op.FTimes FExp
e0 FExp
e1) FExp
e2) FTemp
t = do
(plE0,i0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,i1) <- plF e1; (plE2,i2) <- plF e2
pure $ plE0 $ plE1 $ plE2 [Fmadd () (fabsReg t) i0 i1 i2]
feval (IR.FB FBin
Op.FMinus FExp
e0 (IR.FB FBin
Op.FTimes FExp
e1 FExp
e2)) FTemp
t = do
(plE0,i0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,i1) <- plF e1; (plE2,i2) <- plF e2
pure $ plE0 $ plE1 $ plE2 [Fmsub () (fabsReg t) i1 i2 i0]
feval (IR.FB FBin
Op.FMinus (IR.ConstF Double
0) FExp
e) FTemp
t = do
(plE,i) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [Fneg () (fabsReg t) i]
feval (IR.FB FBin
Op.FTimes (IR.ConstF (-1)) FExp
e) FTemp
t = do
(plE,i) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [Fneg () (fabsReg t) i]
feval (IR.FB FBin
Op.FTimes FExp
e (IR.ConstF (-1))) FTemp
t = do
(plE,i) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [Fneg () (fabsReg t) i]
feval (IR.FB FBin
fop FExp
e0 FExp
e1) FTemp
t | Just ()
-> FAbsReg -> FAbsReg -> FAbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
isn <- FBin
-> Maybe
(()
-> FAbsReg
-> FAbsReg
-> FAbsReg
-> AArch64 AbsReg FAbsReg F2Abs ())
forall {a} {freg} {reg} {f2}.
FBin -> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg f2 a)
mFop FBin
fop = do
(plE0,r0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,r1) <- plF e1
pure $ plE0 $ plE1 [isn () (fabsReg t) r0 r1]
feval (IR.FU FUn
Op.FAbs FExp
e) FTemp
t = do
(plE,i) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [Fabs () (fabsReg t) i]
feval (IR.FAt (IR.AP Temp
tS (Just (IR.ConstI Int64
i)) Maybe AL
_)) FTemp
tD | Just Word16
i8 <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mp Int64
i = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a.
a -> freg -> Addr reg -> AArch64 reg freg f2 a
LdrD () (FTemp -> FAbsReg
fabsReg FTemp
tD) (AbsReg -> Word16 -> Addr AbsReg
forall reg. reg -> Word16 -> Addr reg
RP (Temp -> AbsReg
absReg Temp
tS) Word16
i8)]
feval (IR.FAt (IR.AP Temp
tB (Just (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3))) Maybe AL
_)) FTemp
tD = do
(plE,i) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
eI
pure $ plE [LdrD () (fabsReg tD) (BI (absReg tB) i Three)]
feval (IR.FAt (IR.AP Temp
tB (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3)) (IR.ConstI Int64
ix8))) Maybe AL
_)) FTemp
tD | (Int64
ix, Int64
0) <- Int64
ix8 Int64 -> Int64 -> (Int64, Int64)
forall a. Integral a => a -> a -> (a, a)
`quotRem` Int64
8 = do
i <- StateT WSt Identity Int
nextI; plE <- eval (eI+IR.ConstI ix) (IR.ITemp i)
pure $ plE ++ [LdrD () (fabsReg tD) (BI (absReg tB) (IReg i) Three)]
feval (IR.FAt (IR.AP Temp
tB (Just Exp
e) Maybe AL
_)) FTemp
tD = do
i <- StateT WSt Identity Int
nextI; plE <- eval e (IR.ITemp i)
pure $ plE ++ [LdrD () (fabsReg tD) (BI (absReg tB) (IReg i) Zero)]
feval (IR.FAt (IR.AP Temp
tB Maybe Exp
Nothing Maybe AL
_)) FTemp
tD =
[AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a.
a -> freg -> Addr reg -> AArch64 reg freg f2 a
LdrD () (FTemp -> FAbsReg
fabsReg FTemp
tD) (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R (Temp -> AbsReg
absReg Temp
tB))]
feval (IR.FConv Exp
e) FTemp
tD = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Scvtf () (fabsReg tD) r]
feval (IR.FU FUn
Op.FSqrt FExp
e) FTemp
t = do
(plE,r) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [Fsqrt () (fabsReg t) r]
feval FExp
e FTemp
_ = [Char] -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. HasCallStack => [Char] -> a
error (FExp -> [Char]
forall a. Show a => a -> [Char]
show FExp
e)
eval :: IR.Exp -> IR.Temp -> WM [AArch64 AbsReg FAbsReg F2Abs ()]
eval :: Exp -> Temp -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
eval (IR.Reg Temp
tS) Temp
tD = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> reg -> AArch64 reg freg f2 a
MovRR () (Temp -> AbsReg
absReg Temp
tD) (Temp -> AbsReg
absReg Temp
tS)]
eval (IR.ConstI Int64
0) Temp
tD = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> AArch64 reg freg f2 a
ZeroR () (Temp -> AbsReg
absReg Temp
tD)]
eval (IR.ConstI Int64
i) Temp
tD | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
i = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Word16 -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Word16 -> AArch64 reg freg f2 a
MovRC () (Temp -> AbsReg
absReg Temp
tD) Word16
u]
eval (IR.ConstI Int64
i) Temp
tD | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 (-Int64
i) = let t :: AbsReg
t=Temp -> AbsReg
absReg Temp
tD in [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Word16 -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Word16 -> AArch64 reg freg f2 a
MovRC () AbsReg
t Word16
u, () -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> reg -> AArch64 reg freg f2 a
Neg () AbsReg
t AbsReg
t]
eval (IR.ConstI Int64
i) Temp
tD = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()])
-> [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a b. (a -> b) -> a -> b
$ Word64 -> AbsReg -> [AArch64 AbsReg FAbsReg F2Abs ()]
forall freg f2reg.
Word64 -> AbsReg -> [AArch64 AbsReg freg f2reg ()]
mw64 (Int64 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i) (Temp -> AbsReg
absReg Temp
tD)
eval (IR.Is Temp
p) Temp
tD = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> reg -> AArch64 reg freg f2 a
MovRR () (Temp -> AbsReg
absReg Temp
tD) (Temp -> AbsReg
absReg Temp
p)]
eval (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
e0 (IR.ConstI Int64
i)) Exp
e1) Temp
t | Just Word8
u <- Int64 -> Maybe Word8
forall a. Integral a => a -> Maybe Word8
ms Int64
i = do
r0 <- StateT WSt Identity Int
nextI; r1 <- nextI
plE0 <- eval e0 (IR.ITemp r0); plE1 <- eval e1 (IR.ITemp r1)
pure $ plE0 ++ plE1 ++ [AddRRS () (absReg t) (IReg r1) (IReg r0) u]
eval (IR.IB IBin
Op.IPlus Exp
e (IR.ConstI Int64
i)) Temp
t | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
m12 Int64
i = do
r <- StateT WSt Identity Int
nextI; plE <- eval e (IR.ITemp r)
pure $ plE ++ [AddRC () (absReg t) (IReg r) u]
eval (IR.IB IBin
Op.IMinus Exp
e (IR.ConstI Int64
i)) Temp
t | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
m12 Int64
i = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [SubRC () (absReg t) r u]
eval (IR.IB IBin
Op.IAsl Exp
e (IR.ConstI Int64
i)) Temp
t = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Lsl () (absReg t) r (fromIntegral (i `mod` 64))]
eval (IR.IB IBin
Op.IMinus (IR.ConstI Int64
0) Exp
e) Temp
t = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Neg () (absReg t) r]
eval (IR.IB IBin
Op.ITimes (IR.ConstI (-1)) Exp
e) Temp
t = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Neg () (absReg t) r]
eval (IR.IB IBin
Op.ITimes Exp
e (IR.ConstI (-1))) Temp
t = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Neg () (absReg t) r]
eval (IR.IB IBin
Op.IRem Exp
e0 Exp
e1) Temp
t = do
r2 <- WM AbsReg
nextR
(plE0,r0) <- plI e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [Sdiv () r2 r0 r1, Msub () (absReg t) r2 r1 r0]
eval (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.ITimes Exp
e0 Exp
e1) Exp
e2) Temp
t = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1; (plE2,r2) <- plI e2
pure $ plE0 $ plE1 $ plE2 [Madd () (absReg t) r0 r1 r2]
eval (IR.IB IBin
Op.IMin Exp
e0 Exp
e1) Temp
t = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [CmpRR () r0 r1, Csel () (absReg t) r0 r1 Leq]
eval (IR.IB IBin
Op.IMax Exp
e0 Exp
e1) Temp
t = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [CmpRR () r0 r1, Csel () (absReg t) r0 r1 Geq]
eval (IR.IB IBin
op Exp
e0 Exp
e1) Temp
t | Just () -> AbsReg -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
isn <- IBin
-> Maybe
(()
-> AbsReg -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg F2Abs ())
forall {a} {reg} {freg} {f2}.
IBin -> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg f2 a)
mIop IBin
op = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [isn () (absReg t) r0 r1]
eval (IR.IRel IRel
rel Exp
e0 Exp
e1) Temp
t | Cond
c <- IRel -> Cond
iop IRel
rel = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [CmpRR () r0 r1, Cset () (absReg t) c]
eval (IR.IRFloor FExp
e) Temp
t = do
(plE,r) <- FExp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
FAbsReg)
plF FExp
e
pure $ plE [Fcvtms () (absReg t) r]
eval (IR.EAt (IR.AP Temp
tB (Just (IR.ConstI Int64
i)) Maybe AL
_)) Temp
tD | Just Word16
p <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mp Int64
i = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> AArch64 reg freg f2 a
Ldr () (Temp -> AbsReg
absReg Temp
tD) (AbsReg -> Word16 -> Addr AbsReg
forall reg. reg -> Word16 -> Addr reg
RP (Temp -> AbsReg
absReg Temp
tB) Word16
p)]
eval (IR.BAt (IR.AP Temp
tB (Just (IR.ConstI Int64
i)) Maybe AL
_)) Temp
tD | Just Word16
u <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mu16 Int64
i = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> AArch64 reg freg f2 a
LdrB () (Temp -> AbsReg
absReg Temp
tD) (AbsReg -> Word16 -> Addr AbsReg
forall reg. reg -> Word16 -> Addr reg
RP (Temp -> AbsReg
absReg Temp
tB) Word16
u)]
eval (IR.EAt (IR.AP Temp
rB (Just (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3))) Maybe AL
_)) Temp
t = do
(plE,i) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
eI
pure $ plE [Ldr () (absReg t) (BI (absReg rB) i Three)]
eval (IR.EAt (IR.AP Temp
rB Maybe Exp
Nothing Maybe AL
_)) Temp
t = do
[AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> AArch64 reg freg f2 a
Ldr () (Temp -> AbsReg
absReg Temp
t) (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R (Temp -> AbsReg
absReg Temp
rB))]
eval (IR.EAt (IR.AP Temp
rB (Just Exp
e) Maybe AL
_)) Temp
t = do
(plE,i) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Ldr () (absReg t) (BI (absReg rB) i Zero)]
eval (IR.BAt (IR.AP Temp
rB (Just Exp
e) Maybe AL
_)) Temp
t = do
(plE,i) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [LdrB () (absReg t) (BI (absReg rB) i Zero)]
eval (IR.IB IBin
Op.IAsr Exp
e (IR.ConstI Int64
i)) Temp
t | Just Word8
s <- Int64 -> Maybe Word8
forall a. Integral a => a -> Maybe Word8
ms Int64
i = do
(plE,r) <- Exp
-> WM
([AArch64 AbsReg FAbsReg F2Abs ()]
-> [AArch64 AbsReg FAbsReg F2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [Asr () (absReg t) r s]
eval (IR.LA Int
n) Temp
t = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a. a -> reg -> Int -> AArch64 reg freg f2 a
LdrRL () (Temp -> AbsReg
absReg Temp
t) Int
n]
eval (IR.BU BUn
Op.BNeg (IR.Is Temp
r)) Temp
t = [AArch64 AbsReg FAbsReg F2Abs ()]
-> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> BM -> AArch64 AbsReg FAbsReg F2Abs ()
forall reg freg f2 a.
a -> reg -> reg -> BM -> AArch64 reg freg f2 a
EorI () (Temp -> AbsReg
absReg Temp
t) (Temp -> AbsReg
absReg Temp
r) (Word8 -> Word8 -> BM
BM Word8
1 Word8
0)]
eval Exp
e Temp
_ = [Char] -> State WSt [AArch64 AbsReg FAbsReg F2Abs ()]
forall a. HasCallStack => [Char] -> a
error (Exp -> [Char]
forall a. Show a => a -> [Char]
show Exp
e)
ms :: Integral a => a -> Maybe Word8
ms :: forall a. Integral a => a -> Maybe Word8
ms a
i | a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>=a
0 Bool -> Bool -> Bool
&& a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
63 = Word8 -> Maybe Word8
forall a. a -> Maybe a
Just (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i) | Bool
otherwise = Maybe Word8
forall a. Maybe a
Nothing
m12, mu16 :: Integral a => a -> Maybe Word16
m12 :: forall a. Integral a => a -> Maybe Word16
m12 a
i | a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0 Bool -> Bool -> Bool
&& a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
4096 = Word16 -> Maybe Word16
forall a. a -> Maybe a
Just (a -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i) | Bool
otherwise = Maybe Word16
forall a. Maybe a
Nothing
mu16 :: forall a. Integral a => a -> Maybe Word16
mu16 a
i | a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Word16 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16
forall a. Bounded a => a
maxBound :: Word16) Bool -> Bool -> Bool
|| a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< Word16 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word16
forall a. Bounded a => a
minBound :: Word16) = Maybe Word16
forall a. Maybe a
Nothing
| Bool
otherwise = Word16 -> Maybe Word16
forall a. a -> Maybe a
Just (a -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i)
mp :: Integral a => a -> Maybe Word16
mp :: forall a. Integral a => a -> Maybe Word16
mp a
i | a
i a -> a -> a
forall a. Integral a => a -> a -> a
`rem` a
8 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0 Bool -> Bool -> Bool
&& a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
32760 = Word16 -> Maybe Word16
forall a. a -> Maybe a
Just (a -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i) | Bool
otherwise = Maybe Word16
forall a. Maybe a
Nothing