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 a
mB BBin
Op.AndB = a -> reg -> reg -> reg -> AArch64 reg freg a
forall reg freg a. a -> reg -> reg -> reg -> AArch64 reg freg a
AndRR
mB BBin
Op.OrB = a -> reg -> reg -> reg -> AArch64 reg freg a
forall reg freg a. a -> reg -> reg -> reg -> AArch64 reg freg a
OrRR
mB BBin
Op.XorB = a -> reg -> reg -> reg -> AArch64 reg freg a
forall reg freg a. a -> reg -> reg -> reg -> AArch64 reg freg a
Eor
mIop :: IBin -> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
mIop IBin
Op.IPlus = (a -> reg -> reg -> reg -> AArch64 reg freg a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg a
forall reg freg a. a -> reg -> reg -> reg -> AArch64 reg freg a
AddRR
mIop IBin
Op.IMinus = (a -> reg -> reg -> reg -> AArch64 reg freg a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg a
forall reg freg a. a -> reg -> reg -> reg -> AArch64 reg freg a
SubRR
mIop IBin
Op.ITimes = (a -> reg -> reg -> reg -> AArch64 reg freg a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg a
forall reg freg a. a -> reg -> reg -> reg -> AArch64 reg freg a
MulRR
mIop IBin
Op.IDiv = (a -> reg -> reg -> reg -> AArch64 reg freg a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> reg -> reg -> reg -> AArch64 reg freg a
forall reg freg a. a -> reg -> reg -> reg -> AArch64 reg freg a
Sdiv
mIop (Op.BI BBin
b) = (a -> reg -> reg -> reg -> AArch64 reg freg a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just((a -> reg -> reg -> reg -> AArch64 reg freg a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a))
-> (a -> reg -> reg -> reg -> AArch64 reg freg a)
-> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
forall a b. (a -> b) -> a -> b
$BBin -> a -> reg -> reg -> reg -> AArch64 reg freg a
forall {a} {reg} {freg}.
BBin -> a -> reg -> reg -> reg -> AArch64 reg freg a
mB BBin
b
mIop IBin
_ = Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
forall a. Maybe a
Nothing
mFop :: FBin -> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
mFop FBin
Op.FPlus = (a -> freg -> freg -> freg -> AArch64 reg freg a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg a
forall reg freg a. a -> freg -> freg -> freg -> AArch64 reg freg a
Fadd
mFop FBin
Op.FMinus = (a -> freg -> freg -> freg -> AArch64 reg freg a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg a
forall reg freg a. a -> freg -> freg -> freg -> AArch64 reg freg a
Fsub
mFop FBin
Op.FTimes = (a -> freg -> freg -> freg -> AArch64 reg freg a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg a
forall reg freg a. a -> freg -> freg -> freg -> AArch64 reg freg a
Fmul
mFop FBin
Op.FDiv = (a -> freg -> freg -> freg -> AArch64 reg freg a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg a
forall reg freg a. a -> freg -> freg -> freg -> AArch64 reg freg a
Fdiv
mFop FBin
Op.FMax = (a -> freg -> freg -> freg -> AArch64 reg freg a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg a
forall reg freg a. a -> freg -> freg -> freg -> AArch64 reg freg a
Fmax
mFop FBin
Op.FMin = (a -> freg -> freg -> freg -> AArch64 reg freg a)
-> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> AArch64 reg freg a
forall reg freg a. a -> freg -> freg -> freg -> AArch64 reg freg a
Fmin
mFop FBin
_ = Maybe (a -> freg -> freg -> freg -> AArch64 reg freg 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
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 ()])
irToAarch64 :: WSt -> [Stmt] -> (Int, [AArch64 AbsReg FAbsReg ()])
irToAarch64 WSt
st = ([AArch64 AbsReg FAbsReg ()], Int)
-> (Int, [AArch64 AbsReg FAbsReg ()])
forall a b. (a, b) -> (b, a)
swap (([AArch64 AbsReg FAbsReg ()], Int)
-> (Int, [AArch64 AbsReg FAbsReg ()]))
-> ([Stmt] -> ([AArch64 AbsReg FAbsReg ()], Int))
-> [Stmt]
-> (Int, [AArch64 AbsReg FAbsReg ()])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WSt -> Int)
-> ([AArch64 AbsReg FAbsReg ()], WSt)
-> ([AArch64 AbsReg FAbsReg ()], 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 ()], WSt)
-> ([AArch64 AbsReg FAbsReg ()], Int))
-> ([Stmt] -> ([AArch64 AbsReg FAbsReg ()], WSt))
-> [Stmt]
-> ([AArch64 AbsReg FAbsReg ()], Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State WSt [AArch64 AbsReg FAbsReg ()]
-> WSt -> ([AArch64 AbsReg FAbsReg ()], WSt))
-> WSt
-> State WSt [AArch64 AbsReg FAbsReg ()]
-> ([AArch64 AbsReg FAbsReg ()], WSt)
forall a b c. (a -> b -> c) -> b -> a -> c
flip State WSt [AArch64 AbsReg FAbsReg ()]
-> WSt -> ([AArch64 AbsReg FAbsReg ()], WSt)
forall s a. State s a -> s -> (a, s)
runState WSt
st (State WSt [AArch64 AbsReg FAbsReg ()]
-> ([AArch64 AbsReg FAbsReg ()], WSt))
-> ([Stmt] -> State WSt [AArch64 AbsReg FAbsReg ()])
-> [Stmt]
-> ([AArch64 AbsReg FAbsReg ()], WSt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Stmt -> State WSt [AArch64 AbsReg FAbsReg ()])
-> [Stmt] -> State WSt [AArch64 AbsReg FAbsReg ()]
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 ()]
ir
aR :: AbsReg -> WM [AArch64 AbsReg FAbsReg ()]
aR :: AbsReg -> State WSt [AArch64 AbsReg FAbsReg ()]
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 ()] -> [AArch64 AbsReg FAbsReg ()], FAbsReg)
plF :: FExp
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
FAbsReg)
plF (IR.FReg FTemp
t) = ([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
FAbsReg)
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
FAbsReg)
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()]
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 ()] -> [AArch64 AbsReg FAbsReg ()], AbsReg)
plI :: Exp
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
AbsReg)
plI (IR.Reg Temp
t) = ([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
AbsReg)
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
AbsReg)
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()]
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 ()]
ir :: Stmt -> State WSt [AArch64 AbsReg FAbsReg ()]
ir (IR.R Label
l) = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> Label -> AArch64 reg freg a
RetL () Label
l]
ir (IR.L Label
l) = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> Label -> AArch64 reg freg a
Label () Label
l]
ir (IR.J Label
l) = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> Label -> AArch64 reg freg a
B () Label
l]
ir (IR.C Label
l) = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> Label -> AArch64 reg freg a
C () Label
l]
ir (IR.MX FTemp
t FExp
e) = FExp -> FTemp -> State WSt [AArch64 AbsReg FAbsReg ()]
feval FExp
e FTemp
t
ir (IR.MT Temp
t Exp
e) = Exp -> Temp -> State WSt [AArch64 AbsReg FAbsReg ()]
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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> reg -> Word16 -> AArch64 reg freg a
SubRC () AbsReg
ASP AbsReg
ASP Word16
u, () -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> reg -> AArch64 reg freg 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 ()]
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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> reg -> Word16 -> AArch64 reg freg 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 ()]
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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
r <- StateT WSt Identity Int
nextI; rI <- nextI
plE <- eval e (IR.ITemp r); plEI <- eval eI (IR.ITemp rI)
pure $ plE ++ plEI ++ [Str () (IReg r) (BI (absReg t) (IReg 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
r <- StateT WSt Identity Int
nextI; rI <- nextI
plE <- eval e (IR.ITemp r); plEI <- eval (eI+IR.ConstI ix) (IR.ITemp rI)
pure $ plE ++ plEI ++ [Str () (IReg r) (BI (absReg t) (IReg rI) Three)]
ir (IR.Wr (IR.AP Temp
t (Just Exp
eI) Maybe AL
_) Exp
e) = do
r <- StateT WSt Identity Int
nextI; rI <- nextI
plE <- eval e (IR.ITemp r); plEI <- eval eI (IR.ITemp rI)
pure $ plE ++ plEI ++ [Str () (IReg r) (BI (absReg t) (IReg rI) Zero)]
ir (IR.WrB (IR.AP Temp
t (Just Exp
eI) Maybe AL
_) (IR.Is Temp
i)) = do
rI <- StateT WSt Identity Int
nextI
plEI <- eval eI (IR.ITemp rI)
pure $ plEI ++ [StrB () (absReg i) (BI (absReg t) (IReg 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
iI <- StateT WSt Identity Int
nextI
plEI <- eval eI (IR.ITemp iI)
(plE,i) <- plF e
pure $ plE $ plEI ++ [StrD () i (BI (absReg tB) (IReg 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
(plEI,iI) <- Exp
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
AbsReg)
plI Exp
eI
(plE,i) <- plF e
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
AbsReg)
plI Exp
e
pure $ plE [Cbnz () r l]
ir (IR.MJ (IR.Is Temp
r) Label
l) =
[AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Label -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> Label -> AArch64 reg freg 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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
FAbsReg)
plF FExp
e0; (plE1,r1) <- plF e1
pure $ plE0 $ plE1 [Fcmp () r0 r1, Bc () c 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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 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, 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 ()]
forall a. HasCallStack => [Char] -> a
error (Stmt -> [Char]
forall a. Show a => a -> [Char]
show Stmt
s)
puL, poL :: [AArch64 AbsReg freg ()]
puL :: forall freg. [AArch64 AbsReg freg ()]
puL = [() -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg freg ()
forall reg freg a. a -> reg -> reg -> Word16 -> AArch64 reg freg a
SubRC () AbsReg
ASP AbsReg
ASP Word16
16, () -> AbsReg -> AbsReg -> Addr AbsReg -> AArch64 AbsReg freg ()
forall reg freg a.
a -> reg -> reg -> Addr reg -> AArch64 reg freg a
Stp () AbsReg
FP AbsReg
LR (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R AbsReg
ASP)]
poL :: forall freg. [AArch64 AbsReg freg ()]
poL = [() -> AbsReg -> AbsReg -> Addr AbsReg -> AArch64 AbsReg freg ()
forall reg freg a.
a -> reg -> reg -> Addr reg -> AArch64 reg freg a
Ldp () AbsReg
FP AbsReg
LR (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R AbsReg
ASP), () -> AbsReg -> AbsReg -> Word16 -> AArch64 AbsReg freg ()
forall reg freg a. a -> reg -> reg -> Word16 -> AArch64 reg freg 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
24
mw64 :: Word64 -> AbsReg -> [AArch64 AbsReg freg ()]
mw64 :: forall freg. Word64 -> AbsReg -> [AArch64 AbsReg freg ()]
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 ()
forall reg freg a. a -> reg -> Word16 -> AArch64 reg freg a
MovRC () AbsReg
r (Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w0)AArch64 AbsReg freg ()
-> [AArch64 AbsReg freg ()] -> [AArch64 AbsReg freg ()]
forall a. a -> [a] -> [a]
:[() -> AbsReg -> Word16 -> Int -> AArch64 AbsReg freg ()
forall reg freg a. a -> reg -> Word16 -> Int -> AArch64 reg freg 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 ()]
ssin :: FTemp -> State WSt [AArch64 AbsReg FAbsReg ()]
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 ()]
cosϵ :: FTemp -> State WSt [AArch64 AbsReg FAbsReg ()]
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 ()]
feval :: FExp -> FTemp -> State WSt [AArch64 AbsReg FAbsReg ()]
feval (IR.FReg FTemp
tS) FTemp
tD = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> freg -> freg -> AArch64 reg freg 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 ()]
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 ()]
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()
isn <- FBin
-> Maybe
(() -> FAbsReg -> FAbsReg -> FAbsReg -> AArch64 AbsReg FAbsReg ())
forall {a} {freg} {reg}.
FBin -> Maybe (a -> freg -> freg -> freg -> AArch64 reg freg a)
mFop FBin
fop = do
(plE0,r0) <- FExp
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> freg -> Addr reg -> AArch64 reg freg 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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> freg -> Addr reg -> AArch64 reg freg 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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
FAbsReg)
plF FExp
e
pure $ plE [Fsqrt () (fabsReg t) r]
feval FExp
e FTemp
_ = [Char] -> State WSt [AArch64 AbsReg FAbsReg ()]
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 ()]
eval :: Exp -> Temp -> State WSt [AArch64 AbsReg FAbsReg ()]
eval (IR.Reg Temp
tS) Temp
tD = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> reg -> AArch64 reg freg a
MovRR () (Temp -> AbsReg
absReg Temp
tD) (Temp -> AbsReg
absReg Temp
tS)]
eval (IR.ConstI Int64
0) Temp
tD = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> AArch64 reg freg 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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Word16 -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> Word16 -> AArch64 reg freg a
MovRC () (Temp -> AbsReg
absReg Temp
tD) Word16
u]
eval (IR.ConstI Int64
i) Temp
tD = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()])
-> [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a b. (a -> b) -> a -> b
$ Word64 -> AbsReg -> [AArch64 AbsReg FAbsReg ()]
forall freg. Word64 -> AbsReg -> [AArch64 AbsReg freg ()]
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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> reg -> AArch64 reg freg 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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()
isn <- IBin
-> Maybe
(() -> AbsReg -> AbsReg -> AbsReg -> AArch64 AbsReg FAbsReg ())
forall {a} {reg} {freg}.
IBin -> Maybe (a -> reg -> reg -> reg -> AArch64 reg freg a)
mIop IBin
op = do
(plE0,r0) <- Exp
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
AbsReg)
plI Exp
e0; (plE1,r1) <- plI e1
pure $ plE0 $ plE1 [isn () (absReg t) r0 r1]
eval (IR.IRFloor FExp
e) Temp
t = do
(plE,r) <- FExp
-> WM
([AArch64 AbsReg FAbsReg ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> Addr reg -> AArch64 reg freg 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
p <- Int64 -> Maybe Word16
forall a. Integral a => a -> Maybe Word16
mp Int64
i = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> Addr reg -> AArch64 reg freg a
LdrB () (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.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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> Addr reg -> AArch64 reg freg 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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
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 ()] -> [AArch64 AbsReg FAbsReg ()],
AbsReg)
plI Exp
e
pure $ plE [Asr () (absReg t) r s]
eval (IR.LA Int
n) Temp
t = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> Int -> AArch64 reg freg a
LdrRL () (Temp -> AbsReg
absReg Temp
t) Int
n]
eval (IR.BU BUn
Op.BNeg (IR.Is Temp
r)) Temp
t = [AArch64 AbsReg FAbsReg ()]
-> State WSt [AArch64 AbsReg FAbsReg ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> BM -> AArch64 AbsReg FAbsReg ()
forall reg freg a. a -> reg -> reg -> BM -> AArch64 reg freg 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 ()]
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