module Asm.X86.Trans ( irToX86 ) where
import Asm.M
import Asm.X86
import Control.Monad.State.Strict (runState)
import Data.Bifunctor (second)
import Data.ByteString.Internal (accursedUnutterablePerformIO)
import Data.Int (Int32, Int64, Int8)
import Data.Tuple (swap)
import Foreign.Marshal.Alloc (alloca)
import Foreign.Ptr (castPtr)
import Foreign.Storable (peek, poke)
import qualified IR
import qualified Op
plF :: IR.FExp -> WM ([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()], FAbsReg)
plF :: FExp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
plF (IR.FReg FTemp
t) = ([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> a
id, FTemp -> FAbsReg
fabsReg FTemp
t)
plF FExp
e = do {i <- WM Int
nextI; pl <- feval e (IR.FTemp i); pure ((pl++), FReg i)}
plI :: IR.Exp -> WM ([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()], AbsReg)
plI :: Exp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
plI (IR.Reg Temp
t) = ([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> a
id, Temp -> AbsReg
absReg Temp
t)
plI Exp
e = do {i <- WM Int
nextI; pl <- evalE e (IR.ITemp i); pure ((pl++), IReg i)}
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
CRet
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
FRet0
fabsReg FTemp
IR.FRet1 = FAbsReg
FRet1
irToX86 :: IR.WSt -> [IR.Stmt] -> (Int, [X86 AbsReg FAbsReg X2Abs ()])
irToX86 :: WSt -> [Stmt] -> (Int, [X86 AbsReg FAbsReg X2Abs ()])
irToX86 WSt
st = ([X86 AbsReg FAbsReg X2Abs ()], Int)
-> (Int, [X86 AbsReg FAbsReg X2Abs ()])
forall a b. (a, b) -> (b, a)
swap (([X86 AbsReg FAbsReg X2Abs ()], Int)
-> (Int, [X86 AbsReg FAbsReg X2Abs ()]))
-> ([Stmt] -> ([X86 AbsReg FAbsReg X2Abs ()], Int))
-> [Stmt]
-> (Int, [X86 AbsReg FAbsReg X2Abs ()])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WSt -> Int)
-> ([X86 AbsReg FAbsReg X2Abs ()], WSt)
-> ([X86 AbsReg FAbsReg X2Abs ()], 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 (([X86 AbsReg FAbsReg X2Abs ()], WSt)
-> ([X86 AbsReg FAbsReg X2Abs ()], Int))
-> ([Stmt] -> ([X86 AbsReg FAbsReg X2Abs ()], WSt))
-> [Stmt]
-> ([X86 AbsReg FAbsReg X2Abs ()], Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (WM [X86 AbsReg FAbsReg X2Abs ()]
-> WSt -> ([X86 AbsReg FAbsReg X2Abs ()], WSt))
-> WSt
-> WM [X86 AbsReg FAbsReg X2Abs ()]
-> ([X86 AbsReg FAbsReg X2Abs ()], WSt)
forall a b c. (a -> b -> c) -> b -> a -> c
flip WM [X86 AbsReg FAbsReg X2Abs ()]
-> WSt -> ([X86 AbsReg FAbsReg X2Abs ()], WSt)
forall s a. State s a -> s -> (a, s)
runState WSt
st (WM [X86 AbsReg FAbsReg X2Abs ()]
-> ([X86 AbsReg FAbsReg X2Abs ()], WSt))
-> ([Stmt] -> WM [X86 AbsReg FAbsReg X2Abs ()])
-> [Stmt]
-> ([X86 AbsReg FAbsReg X2Abs ()], WSt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Stmt -> WM [X86 AbsReg FAbsReg X2Abs ()])
-> [Stmt] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall (f :: * -> *) (t :: * -> *) m a.
(Applicative f, Traversable t, Monoid m) =>
(a -> f m) -> t a -> f m
foldMapA Stmt -> WM [X86 AbsReg FAbsReg X2Abs ()]
ir
nextR :: WM AbsReg
nextR :: WM AbsReg
nextR = Int -> AbsReg
IReg (Int -> AbsReg) -> WM Int -> WM AbsReg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WM Int
nextI; nextF :: StateT WSt Identity FAbsReg
nextF = Int -> FAbsReg
FReg (Int -> FAbsReg) -> WM Int -> StateT WSt Identity FAbsReg
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WM Int
nextI
mi8 :: Int64 -> Maybe Int8
mi8 :: Int64 -> Maybe Int8
mi8 Int64
i | Int64
i Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int8 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int8
forall a. Bounded a => a
maxBound :: Int8) Bool -> Bool -> Bool
&& Int64
i Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Int8 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int8
forall a. Bounded a => a
minBound :: Int8) = Int8 -> Maybe Int8
forall a. a -> Maybe a
Just (Int8 -> Maybe Int8) -> Int8 -> Maybe Int8
forall a b. (a -> b) -> a -> b
$ Int64 -> Int8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i
| Bool
otherwise = Maybe Int8
forall a. Maybe a
Nothing
mi32 :: Int64 -> Maybe Int32
mi32 :: Int64 -> Maybe Int32
mi32 Int64
i | Int64
i Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32
forall a. Bounded a => a
maxBound :: Int32) Bool -> Bool -> Bool
&& Int64
i Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
>= Int32 -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32
forall a. Bounded a => a
minBound :: Int32) = Int32 -> Maybe Int32
forall a. a -> Maybe a
Just (Int32 -> Maybe Int32) -> Int32 -> Maybe Int32
forall a b. (a -> b) -> a -> b
$ Int64 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
i
| Bool
otherwise = Maybe Int32
forall a. Maybe a
Nothing
fI64 :: Double -> Int64
fI64 :: Double -> Int64
fI64 Double
x = IO Int64 -> Int64
forall a. IO a -> a
accursedUnutterablePerformIO (IO Int64 -> Int64) -> IO Int64 -> Int64
forall a b. (a -> b) -> a -> b
$ (Ptr Int64 -> IO Int64) -> IO Int64
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr Int64 -> IO Int64) -> IO Int64)
-> (Ptr Int64 -> IO Int64) -> IO Int64
forall a b. (a -> b) -> a -> b
$ \Ptr Int64
bytes -> Ptr Double -> Double -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Int64 -> Ptr Double
forall a b. Ptr a -> Ptr b
castPtr Ptr Int64
bytes) Double
x IO () -> IO Int64 -> IO Int64
forall a b. IO a -> IO b -> IO b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Ptr Int64 -> IO Int64
forall a. Storable a => Ptr a -> IO a
peek Ptr Int64
bytes
opPred :: Op.FRel -> Pred
opPred :: FRel -> Pred
opPred FRel
Op.FGeq = Pred
Nltus
opPred FRel
Op.FGt = Pred
Nleus
opPred FRel
Op.FEq = Pred
Eqoq
opPred FRel
Op.FNeq = Pred
Nequq
opPred FRel
Op.FLeq = Pred
Leos
opPred FRel
Op.FLt = Pred
Ltos
nopPred :: Op.FRel -> Pred
nopPred :: FRel -> Pred
nopPred FRel
Op.FGeq = Pred
Ltos
nopPred FRel
Op.FGt = Pred
Leos
nopPred FRel
Op.FEq = Pred
Nequq
nopPred FRel
Op.FNeq = Pred
Eqoq
nopPred FRel
Op.FLt = Pred
Nltus
nopPred FRel
Op.FLeq = Pred
Nleus
ir :: IR.Stmt -> WM [X86 AbsReg FAbsReg X2Abs ()]
ir :: Stmt -> WM [X86 AbsReg FAbsReg X2Abs ()]
ir (IR.MT Temp
t (IR.EAt (IR.AP Temp
m (Just (IR.ConstI Int64
i)) Maybe AL
_))) | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () (Temp -> AbsReg
absReg Temp
t) (AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC (Temp -> AbsReg
absReg Temp
m) Int8
i8)]
ir (IR.MT Temp
t (IR.EAt (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_))) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () (Temp -> AbsReg
absReg Temp
t) (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R(AbsReg -> Addr AbsReg) -> AbsReg -> Addr AbsReg
forall a b. (a -> b) -> a -> b
$Temp -> AbsReg
absReg Temp
m)]
ir (IR.MX FTemp
t (IR.FAt (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_ ))) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () (FTemp -> FAbsReg
fabsReg FTemp
t) (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R (Temp -> AbsReg
absReg Temp
m))]
ir (IR.MX FTemp
t (IR.FAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IAsl (IR.Reg Temp
i) (IR.ConstI Int64
3))) Maybe AL
_))) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () (FTemp -> FAbsReg
fabsReg FTemp
t) (AbsReg -> Scale -> AbsReg -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Addr reg
RS (Temp -> AbsReg
absReg Temp
m) Scale
Eight (Temp -> AbsReg
absReg Temp
i))]
ir (IR.MX FTemp
t (IR.FAt (IR.AP Temp
m (Just (IR.ConstI Int64
i)) Maybe AL
_))) | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () (FTemp -> FAbsReg
fabsReg FTemp
t) (AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC (Temp -> AbsReg
absReg Temp
m) Int8
i8)]
ir (IR.L Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Label () Label
l]
ir (IR.MT Temp
t Exp
e) = Exp -> Temp -> WM [X86 AbsReg FAbsReg X2Abs ()]
evalE Exp
e Temp
t
ir (IR.MJ (IR.IRel IRel
Op.ILeq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
CmpRR () (Temp -> AbsReg
absReg Temp
r0) (Temp -> AbsReg
absReg Temp
r1), () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jle () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.ILeq (IR.Reg Temp
r0) (IR.ConstI Int64
i)) Label
l) | Just Int32
i32 <- Int64 -> Maybe Int32
mi32 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int32 -> X86 reg freg f2 a
CmpRI () (Temp -> AbsReg
absReg Temp
r0) Int32
i32, () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jle () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.INeq (IR.Reg Temp
r0) (IR.ConstI Int64
0)) Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int32 -> X86 reg freg f2 a
TestI () (Temp -> AbsReg
absReg Temp
r0) Int32
forall a. Bounded a => a
maxBound, () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jne () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.INeq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
Test () (Temp -> AbsReg
absReg Temp
r0) (Temp -> AbsReg
absReg Temp
r1), () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jne () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.IEq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
Test () (Temp -> AbsReg
absReg Temp
r0) (Temp -> AbsReg
absReg Temp
r1), () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Je () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.IEq (IR.Reg Temp
r0) (IR.ConstI Int64
i)) Label
l) | Just Int32
i32 <- Int64 -> Maybe Int32
mi32 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int32 -> X86 reg freg f2 a
CmpRI () (Temp -> AbsReg
absReg Temp
r0) Int32
i32, () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Je () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.IGeq (IR.Reg Temp
r0) (IR.ConstI Int64
i)) Label
l) | Just Int32
i32 <- Int64 -> Maybe Int32
mi32 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int32 -> X86 reg freg f2 a
CmpRI () (Temp -> AbsReg
absReg Temp
r0) Int32
i32, () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jge () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.IGt (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
CmpRR () (Temp -> AbsReg
absReg Temp
r0) (Temp -> AbsReg
absReg Temp
r1), () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jg () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.IGeq (IR.Reg Temp
r0) Exp
e1) Label
l) = do
i1 <- WM Int
nextI; plE1 <- evalE e1 (IR.ITemp i1)
pure $ plE1 ++ [CmpRR () (absReg r0) (IReg i1), Jge () l]
ir (IR.MJ (IR.IRel IRel
Op.IGt (IR.Reg Temp
r0) (IR.ConstI Int64
i)) Label
l) | Just Int32
i32 <- Int64 -> Maybe Int32
mi32 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int32 -> X86 reg freg f2 a
CmpRI () (Temp -> AbsReg
absReg Temp
r0) Int32
i32, () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jg () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.ILt (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
CmpRR () (Temp -> AbsReg
absReg Temp
r0) (Temp -> AbsReg
absReg Temp
r1), () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jl () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.ILt (IR.Reg Temp
r0) (IR.ConstI Int64
i)) Label
l) | Just Int32
i32 <- Int64 -> Maybe Int32
mi32 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int32 -> X86 reg freg f2 a
CmpRI () (Temp -> AbsReg
absReg Temp
r0) Int32
i32, () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jl () Label
l]
ir (IR.MJ (IR.IRel IRel
Op.ILt (IR.Reg Temp
r0) Exp
e1) Label
l) = do
i1 <- WM Int
nextI; plE1 <- evalE e1 (IR.ITemp i1)
pure $ plE1 ++ [CmpRR () (absReg r0) (IReg i1), Jl () l]
ir (IR.MJ (IR.FRel FRel
fop (IR.FReg FTemp
r0) FExp
e1) Label
l) = do
(plE1,i1) <- FExp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
plF FExp
e1
f <- nextF; r <- nextR
pure $ plE1 [Vcmppd () f (fabsReg r0) i1 (opPred fop), MovqRX () r f, TestI () r maxBound, Jne () l]
ir (IR.MJ (IR.Is Temp
p) Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int32 -> X86 reg freg f2 a
TestI () (Temp -> AbsReg
absReg Temp
p) Int32
1, () -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
Jne () Label
l]
ir (IR.MJ (IR.IU IUn
Op.IOdd Exp
e) Label
l) = do
i <- WM Int
nextI; plE <- evalE e (IR.ITemp i)
pure $ plE ++ [TestI () (IReg i) 1, Jne () l]
ir (IR.MJ (IR.IU IUn
Op.IEven Exp
e) Label
l) = do
i <- WM Int
nextI; plE <- evalE e (IR.ITemp i)
pure $ plE ++ [TestI () (IReg i) 1, Je () l]
ir (IR.J Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
J () Label
l]
ir (IR.MX FTemp
t FExp
e) = FExp -> FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval FExp
e FTemp
t
ir IR.RA{} = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure[]
ir (IR.Ma AL
_ Temp
t Exp
e) = do
plE <- Exp -> Temp -> WM [X86 AbsReg FAbsReg X2Abs ()]
evalE Exp
e Temp
IR.C0
pure $ plE ++ [Call () Malloc, MovRR () (absReg t) CRet]
ir (IR.Free Temp
t) =
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
MovRR () AbsReg
CArg0 (Temp -> AbsReg
absReg Temp
t), () -> CFunc -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> CFunc -> X86 reg freg f2 a
Call () CFunc
Free]
ir (IR.Wr (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_) (IR.ConstI Int64
i)) | Just Int32
i32 <- Int64 -> Maybe Int32
mi32 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> Int32 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> Int32 -> X86 reg freg f2 a
MovAI32 () (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R(AbsReg -> Addr AbsReg) -> AbsReg -> Addr AbsReg
forall a b. (a -> b) -> a -> b
$Temp -> AbsReg
absReg Temp
m) Int32
i32]
ir (IR.Wr (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_) (IR.Reg Temp
r)) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> reg -> X86 reg freg f2 a
MovAR () (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R(AbsReg -> Addr AbsReg) -> AbsReg -> Addr AbsReg
forall a b. (a -> b) -> a -> b
$Temp -> AbsReg
absReg Temp
m) (Temp -> AbsReg
absReg Temp
r)]
ir (IR.Wr (IR.AP Temp
m (Just (IR.ConstI Int64
i)) Maybe AL
_) (IR.Reg Temp
r)) | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> reg -> X86 reg freg f2 a
MovAR () (AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC (Temp -> AbsReg
absReg Temp
m) Int8
i8) (Temp -> AbsReg
absReg Temp
r)]
ir (IR.Wr (IR.AP Temp
m (Just (IR.ConstI Int64
i)) Maybe AL
_) Exp
e) | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
i = do
iT <- WM Int
nextI
plE <- evalE e (IR.ITemp iT)
pure $ plE ++ [MovAR () (RC (absReg m) i8) (IReg iT)]
ir (IR.Wr (IR.AP Temp
m (Just (IR.Reg Temp
ix)) Maybe AL
_) (IR.Reg Temp
r)) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> reg -> X86 reg freg f2 a
MovAR () (AbsReg -> Scale -> AbsReg -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Addr reg
RS (Temp -> AbsReg
absReg Temp
m) Scale
One (Temp -> AbsReg
absReg Temp
ix)) (Temp -> AbsReg
absReg Temp
r)]
ir (IR.Wr (IR.AP Temp
m (Just (IR.IB IBin
Op.IAsl (IR.Reg Temp
i) (IR.ConstI Int64
3))) Maybe AL
_) (IR.Reg Temp
r)) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> reg -> X86 reg freg f2 a
MovAR () (AbsReg -> Scale -> AbsReg -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Addr reg
RS (Temp -> AbsReg
absReg Temp
m) Scale
Eight (Temp -> AbsReg
absReg Temp
i)) (Temp -> AbsReg
absReg Temp
r)]
ir (IR.Wr (IR.AP Temp
m (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl (IR.Reg Temp
i) (IR.ConstI Int64
3)) (IR.ConstI Int64
j))) Maybe AL
_) (IR.Reg Temp
r)) | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
j = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> reg -> X86 reg freg f2 a
MovAR () (AbsReg -> Scale -> AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Int8 -> Addr reg
RSD (Temp -> AbsReg
absReg Temp
m) Scale
Eight (Temp -> AbsReg
absReg Temp
i) Int8
i8) (Temp -> AbsReg
absReg Temp
r)]
ir (IR.Wr (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_) Exp
e) = do
eR <- WM Int
nextI
plE <- evalE e (IR.ITemp eR)
pure $ plE ++ [MovAR () (R (absReg m)) (IReg eR)]
ir (IR.Wr (IR.AP Temp
m (Just Exp
ei) Maybe AL
_) Exp
e) = do
eR <- WM Int
nextI; eiR <- nextI
plE <- evalE e (IR.ITemp eR); plE' <- evalE ei (IR.ITemp eiR)
pure $ plE ++ plE' ++ [MovAR () (RS (absReg m) One (IReg eiR)) (IReg eR)]
ir (IR.WrF (IR.AP Temp
m (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
ei (IR.ConstI Int64
3)) (IR.ConstI Int64
d))) Maybe AL
_) (IR.FReg FTemp
fr)) | Just Int8
d8 <- Int64 -> Maybe Int8
mi8 Int64
d = do
i <- WM Int
nextI; plEI <- evalE ei (IR.ITemp i)
pure $ plEI ++ [MovqAX () (RSD (absReg m) Eight (IReg i) d8) (fabsReg fr)]
ir (IR.WrF (IR.AP Temp
m (Just (IR.ConstI Int64
i)) Maybe AL
_) (IR.FReg FTemp
r)) | Just Int8
d8 <- Int64 -> Maybe Int8
mi8 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> freg -> X86 reg freg f2 a
MovqAX () (AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC (Temp -> AbsReg
absReg Temp
m) Int8
d8) (FTemp -> FAbsReg
fabsReg FTemp
r)]
ir (IR.WrF (IR.AP Temp
m (Just Exp
ei) Maybe AL
_) (IR.FReg FTemp
r)) = do
let m' :: AbsReg
m' = Temp -> AbsReg
absReg Temp
m
eR <- WM Int
nextI
plE <- evalE ei (IR.ITemp eR)
pure $ plE ++ [IAddRR () (IReg eR) m', MovqAX () (R (IReg eR)) (fabsReg r)]
ir (IR.WrF (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_) (IR.FReg FTemp
r)) =
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> freg -> X86 reg freg f2 a
MovqAX () (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R (Temp -> AbsReg
absReg Temp
m)) (FTemp -> FAbsReg
fabsReg FTemp
r)]
ir (IR.WrF (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_) (IR.ConstF Double
x)) = do
iR <- WM AbsReg
nextR
pure [MovRI () iR (fI64 x), MovAR () (R (absReg m)) iR]
ir (IR.Cset Temp
t Exp
p) = (Stmt -> WM [X86 AbsReg FAbsReg X2Abs ()])
-> [Stmt] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall (f :: * -> *) (t :: * -> *) m a.
(Applicative f, Traversable t, Monoid m) =>
(a -> f m) -> t a -> f m
foldMapA Stmt -> WM [X86 AbsReg FAbsReg X2Abs ()]
ir [Temp -> Exp -> Stmt
IR.MT Temp
t Exp
0, Exp -> Temp -> Exp -> Stmt
IR.Cmov Exp
p Temp
t Exp
1]
ir (IR.Fcmov (IR.IU IUn
Op.IOdd (IR.Reg Temp
r0)) FTemp
t FExp
e) = do
plE <- FExp -> FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval FExp
e FTemp
t; l <- nextL
pure $ [TestI () (absReg r0) 1, Je () l] ++ plE ++ [Label () l]
ir (IR.Cmov (IR.IU IUn
Op.IEven (IR.Reg Temp
r)) Temp
rD Exp
e) = do
i <- WM Int
nextI; plE <- evalE e (IR.ITemp i)
pure $ plE ++ [TestI () (absReg r) 1, Cmove () (absReg rD) (IReg i)]
ir (IR.Cmov (IR.IU IUn
Op.IOdd (IR.Reg Temp
r)) Temp
rD Exp
e) = do
i <- WM Int
nextI; plE <- evalE e (IR.ITemp i)
pure $ plE ++ [TestI () (absReg r) 1, Cmovne () (absReg rD) (IReg i)]
ir (IR.Fcmov (IR.IRel IRel
Op.IEq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) FTemp
t FExp
e) = do
plE <- FExp -> FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval FExp
e FTemp
t; l <- nextL
pure $ [CmpRR () (absReg r0) (absReg r1), Jne () l] ++ plE ++ [Label () l]
ir (IR.Cmov (IR.IRel IRel
Op.IGt (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD Exp
eS) = do
iS <- WM Int
nextI; plES <- evalE eS (IR.ITemp iS)
pure $ plES ++ [CmpRR () (absReg r0) (absReg r1), Cmovnle () (absReg rD) (IReg iS)]
ir (IR.Cmov (IR.IRel IRel
Op.IGeq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD Exp
eS) = do
iS <- WM Int
nextI; plES <- evalE eS (IR.ITemp iS)
pure $ plES ++ [CmpRR () (absReg r0) (absReg r1), Cmovnl () (absReg rD) (IReg iS)]
ir (IR.Cmov (IR.IRel IRel
Op.INeq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD Exp
eS) = do
iS <- WM Int
nextI; plES <- evalE eS (IR.ITemp iS)
pure $ plES ++ [CmpRR () (absReg r0) (absReg r1), Cmovne () (absReg rD) (IReg iS)]
ir (IR.Cmov (IR.IRel IRel
Op.IEq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD Exp
eS) = do
iS <- WM Int
nextI; plES <- evalE eS (IR.ITemp iS)
pure $ plES ++ [CmpRR () (absReg r0) (absReg r1), Cmove () (absReg rD) (IReg iS)]
ir (IR.Cmov (IR.IRel IRel
Op.ILeq (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD Exp
eS) = do
iS <- WM Int
nextI; plES <- evalE eS (IR.ITemp iS)
pure $ plES ++ [CmpRR () (absReg r0) (absReg r1), Cmovle () (absReg rD) (IReg iS)]
ir (IR.Cmov (IR.IRel IRel
Op.ILt (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD Exp
eS) = do
iS <- WM Int
nextI; plES <- evalE eS (IR.ITemp iS)
pure $ plES ++ [CmpRR () (absReg r0) (absReg r1), Cmovl () (absReg rD) (IReg iS)]
ir (IR.Cmov (IR.FRel FRel
fop (IR.FReg FTemp
xr0) (IR.FReg FTemp
xr1)) Temp
rD Exp
e) = do
i1 <- WM Int
nextI; plE <- evalE e (IR.ITemp i1)
f <- nextF; r <- nextR
pure $ plE ++ [Vcmppd () f (fabsReg xr0) (fabsReg xr1) (opPred fop), MovqRX () r f, TestI () r maxBound, Cmovne () (absReg rD) (IReg i1)]
ir (IR.Fcmov (IR.FRel FRel
fop (IR.FReg FTemp
xr0) (IR.FReg FTemp
xr1)) FTemp
t FExp
e) = do
plE <- FExp -> FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval FExp
e FTemp
t; l <- nextL
f <- nextF; r <- nextR
pure $ [Vcmppd () f (fabsReg xr0) (fabsReg xr1) (nopPred fop), MovqRX () r f, TestI () r maxBound, Jne () l] ++ plE ++ [Label () l]
ir (IR.Fcmov (IR.IRel IRel
Op.IEq (IR.Reg Temp
r0) (IR.ConstI Int64
n)) FTemp
t FExp
e) | Just Int32
i32 <- Int64 -> Maybe Int32
mi32 Int64
n = do
plE <- FExp -> FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval FExp
e FTemp
t; l <- nextL
pure $ [CmpRI () (absReg r0) i32, Jne () l] ++ plE ++ [Label () l]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.ConstI Int64
sD)) Maybe AL
_) (IR.AP Temp
tS (Just Exp
eI) Maybe AL
_) (IR.ConstI Int64
n)) | Just Int32
n32 <- Int64 -> Maybe Int32
mi32 Int64
n, Just Int8
sd8 <- Int64 -> Maybe Int8
mi8 Int64
sD = do
iT <- WM Int
nextI
plE <- evalE (IR.IB Op.IPlus (IR.Reg tS) eI) (IR.ITemp iT)
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plE ++ [MovRI () i 0, CmpRI () i (n32-1), Jg () eL, Label () l, MovRA () t (RS (IReg iT) Eight i), MovAR () (RSD (absReg tD) Eight i sd8) t, IAddRI () i 1, CmpRI () i (n32-1), Jle () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.ConstI Int64
sD)) Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
sI)) Maybe AL
_) (IR.ConstI Int64
n)) | Just Int8
sd8 <- Int64 -> Maybe Int8
mi8 Int64
sD, Just Int8
si8 <- Int64 -> Maybe Int8
mi8 Int64
sI = do
i <- WM AbsReg
nextR; t <- nextR
l <- nextL; eL <- nextL
pure [MovRI () i (n-1), CmpRI () i 0, Jl () eL, Label () l, MovRA () t (RSD (absReg tS) Eight i si8), MovAR () (RSD (absReg tD) Eight i sd8) t, ISubRI () i 1, CmpRI () i 0, Jge () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.ConstI Int64
sD)) Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
sI)) Maybe AL
_) Exp
e) | Just Int8
sd8 <- Int64 -> Maybe Int8
mi8 Int64
sD, Just Int8
si8 <- Int64 -> Maybe Int8
mi8 Int64
sI = do
ii <- WM Int
nextI; t <- nextR
plE <- evalE e (IR.ITemp ii)
let i = Int -> AbsReg
IReg Int
ii
l <- nextL; endL <- nextL
pure $ plE ++ [ISubRI () i 1, Label () l, CmpRI () i 0, Jl () endL, MovRA () t (RSD (absReg tS) Eight i si8), MovAR () (RSD (absReg tD) Eight i sd8) t, ISubRI () i 1, J () l, Label () endL]
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 [ [ MovRA () t (RC (absReg tS) (i*8)), MovAR () (RC (absReg tD) (i*8)) t ] | i <- [0..(fromIntegral n-1)] ]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
e) 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
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
t <- nextR
pure $ plE ++ IAddRR () (IReg iR) (absReg tD):concat [ [MovRA () t (RC (absReg tS) (i*8)), MovAR () (RC (IReg iR) (i*8)) t ] | i <- [0..(fromIntegral n-1)] ]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
Nothing Maybe AL
_) (IR.AP Temp
tS (Just Exp
e) Maybe AL
_) (IR.ConstI Int64
n)) | Int64
n Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
t <- nextR
pure $ plE ++ IAddRR () (IReg iR) (absReg tS):concat [ [MovRA () t (RC (IReg iR) (i*8)), MovAR () (RC (absReg tD) (i*8)) t ] | i <- [0..(fromIntegral n-1)] ]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
eid (IR.ConstI Int64
3)) (IR.ConstI Int64
sS))) Maybe AL
_) (IR.AP Temp
tS (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
eis (IR.ConstI Int64
3)) (IR.ConstI Int64
dS))) Maybe AL
_) Exp
n) | Just Int8
ds8 <- Int64 -> Maybe Int8
mi8 Int64
dS, Just Int8
sS8 <- Int64 -> Maybe Int8
mi8 Int64
sS = do
(plD,diR) <- Exp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
plI Exp
eid; (plS,siR) <- plI eis
(plN,nR) <- plI n
t <- nextR; i <- nextR
l <- nextL; eL <- nextL
pure $ plN $ plD $ plS [IAddRR () diR (absReg tD), IAddRR () siR (absReg tS), MovRI () i 0, CmpRR () i nR, Jge () eL, Label () l, MovRA () t (RSD siR Eight i ds8), MovAR () (RSD diR Eight i sS8) t, IAddRI () i 1, CmpRR () i nR, Jl () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.IB IBin
Op.IAsl Exp
eid (IR.ConstI Int64
3))) Maybe AL
_) (IR.AP Temp
tS (Just (IR.IB IBin
Op.IAsl Exp
eis (IR.ConstI Int64
3))) Maybe AL
_) (IR.ConstI Int64
n)) | Int64
n Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
(plD,diR) <- Exp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
plI Exp
eid; (plS,siR) <- plI eis
t <- nextR
pure $ plD $ plS $ concat [ [ MovRA () t (RSD (absReg tS) Eight siR (i*8)), MovAR () (RSD (absReg tD) Eight diR (i*8)) t ] | i <- [0..(fromIntegral 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 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
4 = do
dR <- WM Int
nextI; sR <- nextI
plD <- evalE ed (IR.ITemp dR); plS <- evalE es (IR.ITemp sR)
t <- nextR
pure $ plD ++ plS ++ IAddRR () (IReg dR) (absReg tD):IAddRR () (IReg sR) (absReg tS):concat [ [MovRA () t (RC (IReg sR) (i*8)), MovAR () (RC (IReg dR) (i*8)) t ] | i <- [0..(fromIntegral n-1)] ]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.IB IBin
Op.IPlus Exp
ed (IR.ConstI Int64
sS))) Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
dS)) Maybe AL
_) Exp
k) | Just Int8
dS8 <- Int64 -> Maybe Int8
mi8 Int64
dS, Just Int8
sS8 <- Int64 -> Maybe Int8
mi8 Int64
sS = do
dR <- WM Int
nextI; kR <- nextI
plK <- evalE k (IR.ITemp kR); plD <- evalE ed (IR.ITemp dR)
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plD ++ plK ++ IAddRR () (IReg dR) (absReg tD):[MovRI () i 0, CmpRR () i (IReg kR), Jge () eL, Label () l, MovRA () t (RSD (absReg tS) Eight i dS8), MovAR () (RSD (IReg dR) Eight i sS8) t, IAddRI () i 1, CmpRR () i (IReg kR), Jl () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
ed) Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
dS)) Maybe AL
_) Exp
k) | Just Int8
dS8 <- Int64 -> Maybe Int8
mi8 Int64
dS = do
dR <- WM Int
nextI; kR <- nextI
plK <- evalE k (IR.ITemp kR); plD <- evalE ed (IR.ITemp dR)
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plD ++ plK ++ IAddRR () (IReg dR) (absReg tD):[MovRI () i 0, CmpRR () i (IReg kR), Jge () eL, Label () l, MovRA () t (RSD (absReg tS) Eight i dS8), MovAR () (RS (IReg dR) Eight i) t, IAddRI () i 1, CmpRR () i (IReg kR), Jl () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
e) Maybe AL
_) (IR.AP Temp
tS Maybe Exp
Nothing Maybe AL
_) (IR.ConstI Int64
n)) | Just Int32
n32 <- Int64 -> Maybe Int32
mi32 Int64
n = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plE ++ [IAddRR () (IReg iR) (absReg tD), MovRI () i 0, CmpRI () i (n32-1), Jg () eL, Label () l, MovRA () t (RS (absReg tS) Eight i), MovAR () (RS (IReg iR) Eight i) t, IAddRI () i 1, CmpRI () i (n32-1), Jle () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
Nothing Maybe AL
_) (IR.AP Temp
tS (Just Exp
e) Maybe AL
_) (IR.ConstI Int64
n)) | Just Int32
n32 <- Int64 -> Maybe Int32
mi32 Int64
n = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plE ++ [IAddRR () (IReg iR) (absReg tS), MovRI () i 0, CmpRI () i (n32-1), Jg () eL, Label () l, MovRA () t (RS (IReg iR) Eight i), MovAR () (RS (absReg tD) Eight i) t, IAddRI () i 1, CmpRI () i (n32-1), Jle () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
e) Maybe AL
_) (IR.AP Temp
tS (Just (IR.ConstI Int64
d)) Maybe AL
_) (IR.ConstI Int64
n)) | Just Int32
n32 <- Int64 -> Maybe Int32
mi32 Int64
n, Just Int8
d8 <- Int64 -> Maybe Int8
mi8 Int64
d = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plE ++ [IAddRR () (IReg iR) (absReg tD), MovRI () i 0, CmpRI () i (n32-1), Jg () eL, Label () l, MovRA () t (RSD (absReg tS) Eight i d8), MovAR () (RS (IReg iR) Eight i) t, IAddRI () i 1, CmpRI () i (n32-1), Jle () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
Nothing Maybe AL
_) (IR.AP Temp
tS (Just Exp
e) Maybe AL
_) Exp
ne) = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
(plN,nR) <- plI ne
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plE ++ plN [IAddRR () (IReg iR) (absReg tS), MovRI () i 0, CmpRR () i nR, Jge () eL, Label () l, MovRA () t (RS (IReg iR) Eight i), MovAR () (RS (absReg tD) Eight i) t, IAddRI () i 1, CmpRR () i nR, Jl () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just Exp
e) Maybe AL
_) (IR.AP Temp
tS Maybe Exp
Nothing Maybe AL
_) Exp
ne) = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
(plN,nR) <- plI ne
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plE ++ plN [IAddRR () (IReg iR) (absReg tD), MovRI () i 0, CmpRR () i nR, Jge () eL, Label () l, MovRA () t (RS (IReg iR) Eight i), MovAR () (RS (absReg tS) Eight i) t, IAddRI () i 1, CmpRR () i nR, Jl () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD Maybe Exp
Nothing Maybe AL
_) (IR.AP Temp
tS Maybe Exp
Nothing Maybe AL
_) Exp
ne) = do
(plN,nR) <- Exp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
plI Exp
ne
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plN [MovRI () i 0, CmpRR () i nR, Jge () eL, Label () l, MovRA () t (RS (absReg tS) Eight i), MovAR () (RS (absReg tD) Eight i) t, IAddRI () i 1, CmpRR () i nR, Jl () l, Label () eL]
ir (IR.Cpy (IR.AP Temp
tD (Just (IR.ConstI Int64
n)) Maybe AL
_) (IR.AP Temp
tS (Just Exp
e) Maybe AL
_) Exp
ne) | Just Int8
n8 <- Int64 -> Maybe Int8
mi8 Int64
n = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
(plN,nR) <- plI ne
i <- nextR; t <- nextR
l <- nextL; eL <- nextL
pure $ plE ++ plN [IAddRR () (IReg iR) (absReg tS), MovRI () i 0, CmpRR () i nR, Jge () eL, Label () l, MovRA () t (RS (IReg iR) Eight i), MovAR () (RSD (absReg tD) Eight i n8) t, IAddRI () i 1, CmpRR () i nR, Jl () l, Label () eL]
ir (IR.Sa Temp
t (IR.ConstI Int64
i)) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int64 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int64 -> X86 reg freg f2 a
ISubRI () AbsReg
SP (Int64 -> Int64
forall a b. (Integral a, Num b) => a -> b
saI(Int64 -> Int64) -> Int64 -> Int64
forall a b. (a -> b) -> a -> b
$Int64
iInt64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+Int64
8), () -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
MovRR () (Temp -> AbsReg
absReg Temp
t) AbsReg
SP]
ir (IR.Pop (IR.ConstI Int64
i)) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int64 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int64 -> X86 reg freg f2 a
IAddRI () AbsReg
SP (Int64 -> Int64
forall a b. (Integral a, Num b) => a -> b
saI(Int64 -> Int64) -> Int64 -> Int64
forall a b. (a -> b) -> a -> b
$Int64
iInt64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
+Int64
8)]
ir (IR.Sa Temp
t Exp
e) = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
l <- nextL
pure $ plE ++ [TestI () (IReg iR) 0x8, Je () l, IAddRI () (IReg iR) 8, Label () l, ISubRR () SP (IReg iR), MovRR () (absReg t) SP]
ir (IR.Pop Exp
e) = do
iR <- WM Int
nextI; plE <- evalE e (IR.ITemp iR)
l <- nextL
pure $ plE ++ [TestI () (IReg iR) 0x8, Je () l, IAddRI () (IReg iR) 8, Label () l, IAddRR () SP (IReg iR)]
ir (IR.FRnd FTemp
t) =
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> CFunc -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> CFunc -> X86 reg freg f2 a
Call () CFunc
DR, () -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Movapd () (FTemp -> FAbsReg
fabsReg FTemp
t) FAbsReg
FRet0]
ir (IR.IRnd Temp
t) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> X86 reg freg f2 a
Rdrand () (Temp -> AbsReg
absReg Temp
t)]
ir (IR.R Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
RetL () Label
l]
ir (IR.C Label
l) = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Label -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Label -> X86 reg freg f2 a
C () Label
l]
ir Stmt
s = [Char] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. HasCallStack => [Char] -> a
error (Stmt -> [Char]
forall a. Show a => a -> [Char]
show Stmt
s)
saI :: a -> b
saI a
i | a
ia -> 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 -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i | Bool
otherwise = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
ib -> b -> b
forall a. Num a => a -> a -> a
+b
8
mSse :: FBin -> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
mSse FBin
Op.FMinus = (a -> freg -> freg -> freg -> X86 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> X86 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vsubsd
mSse FBin
Op.FPlus = (a -> freg -> freg -> freg -> X86 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> X86 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vaddsd
mSse FBin
Op.FDiv = (a -> freg -> freg -> freg -> X86 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> X86 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vdivsd
mSse FBin
Op.FMax = (a -> freg -> freg -> freg -> X86 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> X86 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vmaxsd
mSse FBin
Op.FMin = (a -> freg -> freg -> freg -> X86 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> X86 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vminsd
mSse FBin
Op.FTimes = (a -> freg -> freg -> freg -> X86 reg freg f2 a)
-> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
forall a. a -> Maybe a
Just a -> freg -> freg -> freg -> X86 reg freg f2 a
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vmulsd
mSse FBin
Op.FExp = Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
forall a. Maybe a
Nothing
feval :: IR.FExp -> IR.FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval :: FExp -> FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval (IR.FB FBin
Op.FDiv (IR.FReg FTemp
r0) (IR.FReg FTemp
r1)) FTemp
t | FTemp
t FTemp -> FTemp -> Bool
forall a. Eq a => a -> a -> Bool
== FTemp
r0 = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Divsd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r1)]
feval (IR.FB FBin
Op.FTimes (IR.FReg FTemp
r0) (IR.FReg FTemp
r1)) FTemp
t | FTemp
t FTemp -> FTemp -> Bool
forall a. Eq a => a -> a -> Bool
== FTemp
r0 = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Mulsd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r1)]
feval (IR.FB FBin
Op.FMinus (IR.FReg FTemp
r0) (IR.FReg FTemp
r1)) FTemp
t | FTemp
t FTemp -> FTemp -> Bool
forall a. Eq a => a -> a -> Bool
== FTemp
r0 = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Subsd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r1)]
feval (IR.FB FBin
Op.FPlus (IR.FReg FTemp
r0) (IR.FReg FTemp
r1)) FTemp
t | FTemp
t FTemp -> FTemp -> Bool
forall a. Eq a => a -> a -> Bool
== FTemp
r0 = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Addsd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r1)]
feval (IR.FConv (IR.Reg Temp
r)) FTemp
t = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> reg -> X86 reg freg f2 a
Cvtsi2sd () (FTemp -> FAbsReg
fabsReg FTemp
t) (Temp -> AbsReg
absReg Temp
r)]
feval (IR.FReg FTemp
r) FTemp
t = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Movapd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r)]
feval (IR.FB FBin
Op.FPlus (IR.FReg FTemp
r0) (IR.FB FBin
Op.FTimes (IR.FReg FTemp
r1) (IR.FReg FTemp
r2))) FTemp
t =
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Movapd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r0), () -> FAbsReg -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vfmadd231sd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r1) (FTemp -> FAbsReg
fabsReg FTemp
r2)]
feval (IR.FB FBin
Op.FPlus (IR.FReg FTemp
r0) (IR.FB FBin
Op.FTimes FExp
e (IR.FAt (IR.AP Temp
b (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
eI (IR.ConstI Int64
3)) (IR.ConstI Int64
s))) Maybe AL
_)))) FTemp
t | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
s = do
(plE,i) <- FExp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
plF FExp
e; (plEI,iI) <- plI eI
pure $ plE $ plEI [Movapd () (fabsReg t) (fabsReg r0), Vfmadd231sdA () (fabsReg t) i (RSD (absReg b) Eight iI i8)]
feval (IR.FB FBin
Op.FPlus (IR.FReg FTemp
r0) (IR.FB FBin
Op.FTimes FExp
e0 FExp
e1)) FTemp
t = do
(plE0,i0) <- FExp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
plF FExp
e0; (plE1,i1) <- plF e1
pure $ plE0 $ plE1 [Movapd () (fabsReg t) (fabsReg r0), Vfmadd231sd () (fabsReg t) i0 i1]
feval (IR.FB FBin
Op.FMinus (IR.FReg FTemp
r0) (IR.FB FBin
Op.FTimes (IR.FReg FTemp
r1) (IR.FReg FTemp
r2))) FTemp
t =
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Movapd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r0), () -> FAbsReg -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a.
a -> freg -> freg -> freg -> X86 reg freg f2 a
Vfmnadd231sd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r1) (FTemp -> FAbsReg
fabsReg FTemp
r2)]
feval (IR.FB FBin
fop FExp
e0 FExp
e1) FTemp
t | Just () -> FAbsReg -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
isn <- FBin
-> Maybe
(()
-> FAbsReg -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ())
forall {a} {freg} {reg} {f2}.
FBin -> Maybe (a -> freg -> freg -> freg -> X86 reg freg f2 a)
mSse FBin
fop = do
(plR0,i0) <- FExp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
plF FExp
e0; (plR1,i1) <- plF e1
pure $ plR0 $ plR1 [isn () (fabsReg t) i0 i1]
feval (IR.ConstF Double
x) FTemp
t = do
iR <- WM AbsReg
nextR
pure [MovRI () iR (fI64 x), MovqXR () (fabsReg t) iR]
feval (IR.FU FUn
Op.FAbs FExp
e) FTemp
t = do
plE <- FExp -> FTemp -> WM [X86 AbsReg FAbsReg X2Abs ()]
feval FExp
e FTemp
t
l <- nextL
let nextIR=[Exp -> Label -> Stmt
IR.MJ (FRel -> FExp -> FExp -> Exp
IR.FRel FRel
Op.FGeq (FTemp -> FExp
IR.FReg FTemp
t) FExp
0) Label
l, FTemp -> FExp -> Stmt
IR.MX FTemp
t (FExp -> FExp
forall a. Num a => a -> a
negate (FTemp -> FExp
IR.FReg FTemp
t)), Label -> Stmt
IR.L Label
l]
nextX86 <- foldMapA ir nextIR
pure $ plE ++ nextX86
feval (IR.FU FUn
Op.FLog (IR.FReg FTemp
r0)) FTemp
t =
let sa :: Addr AbsReg
sa = AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC AbsReg
SP (-Int8
8) in
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> X86 reg freg f2 a
Fldln2 (), () -> Addr AbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> freg -> X86 reg freg f2 a
MovqAX () Addr AbsReg
sa (FTemp -> FAbsReg
fabsReg FTemp
r0), () -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> X86 reg freg f2 a
Fld () Addr AbsReg
sa, () -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> X86 reg freg f2 a
Fyl2x (), () -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> X86 reg freg f2 a
Fstp () Addr AbsReg
sa, () -> FAbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () (FTemp -> FAbsReg
fabsReg FTemp
t) Addr AbsReg
sa]
feval (IR.FU FUn
Op.FSin (IR.FReg FTemp
r)) FTemp
t =
let sa :: Addr AbsReg
sa = AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC AbsReg
SP (-Int8
8) in
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> freg -> X86 reg freg f2 a
MovqAX () Addr AbsReg
sa (FTemp -> FAbsReg
fabsReg FTemp
r), () -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> X86 reg freg f2 a
Fld () Addr AbsReg
sa, () -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> X86 reg freg f2 a
Fsin (), () -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> X86 reg freg f2 a
Fstp () Addr AbsReg
sa, () -> FAbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () (FTemp -> FAbsReg
fabsReg FTemp
t) Addr AbsReg
sa]
feval (IR.FU FUn
Op.FCos (IR.FReg FTemp
r)) FTemp
t =
let sa :: Addr AbsReg
sa = AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC AbsReg
SP (-Int8
8) in
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> Addr AbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> freg -> X86 reg freg f2 a
MovqAX () Addr AbsReg
sa (FTemp -> FAbsReg
fabsReg FTemp
r), () -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> X86 reg freg f2 a
Fld () Addr AbsReg
sa, () -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> X86 reg freg f2 a
Fcos (), () -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> Addr reg -> X86 reg freg f2 a
Fstp () Addr AbsReg
sa, () -> FAbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () (FTemp -> FAbsReg
fabsReg FTemp
t) Addr AbsReg
sa]
feval (IR.FB FBin
Op.FExp (IR.ConstF Double
2.718281828459045) FExp
e) FTemp
t = do
(plE,i) <- FExp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
plF FExp
e
let sa = AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC AbsReg
SP (-Int8
8)
pure $ plE [MovqAX () sa i, Fninit (), Fld () sa, Fldl2e (), Fmulp (), Fld1 (), FldS () (ST 1), Fprem (), F2xm1 (), Faddp (), Fscale (), Fstp () sa, MovqXA () (fabsReg t) sa]
feval (IR.FB FBin
Op.FExp FExp
e0 FExp
e1) FTemp
t = do
(plE0,i0) <- FExp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
FAbsReg)
plF FExp
e0
(plE1,i1) <- plF e1
let sa0 = AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC AbsReg
SP (-Int8
8)
sa1 = AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC AbsReg
SP (-Int8
16)
pure $ plE0 $ plE1 [MovqAX () sa0 i0, MovqAX () sa1 i1, Fld () sa1, Fld () sa0, Fyl2x (), Fld1 (), FldS () (ST 1), Fprem (), F2xm1 (), Faddp (), Fscale (), Fstp () sa0, MovqXA () (fabsReg t) sa0]
feval (IR.FU FUn
Op.FSqrt (IR.FReg FTemp
r)) FTemp
t =
[X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> freg -> X86 reg freg f2 a
Sqrtsd () (FTemp -> FAbsReg
fabsReg FTemp
t) (FTemp -> FAbsReg
fabsReg FTemp
r)]
feval (IR.FAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl (IR.Reg Temp
i) (IR.ConstI Int64
3)) (IR.ConstI Int64
d))) Maybe AL
_)) FTemp
rD | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
d = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> FAbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> freg -> Addr reg -> X86 reg freg f2 a
MovqXA () (FTemp -> FAbsReg
fabsReg FTemp
rD) (AbsReg -> Scale -> AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Int8 -> Addr reg
RSD (Temp -> AbsReg
absReg Temp
m) Scale
Eight (Temp -> AbsReg
absReg Temp
i) Int8
i8)]
feval (IR.FAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
e (IR.ConstI Int64
3)) (IR.ConstI Int64
d))) Maybe AL
_)) FTemp
rD | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
d = do
i <- WM Int
nextI; plE <- evalE e (IR.ITemp i)
pure $ plE ++ [MovqXA () (fabsReg rD) (RSD (absReg m) Eight (IReg i) i8)]
feval (IR.FAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IAsl Exp
e (IR.ConstI Int64
3))) Maybe AL
_)) FTemp
rD = do
i <- WM Int
nextI; plE <- evalE e (IR.ITemp i)
pure $ plE ++ [MovqXA () (fabsReg rD) (RS (absReg m) Eight (IReg i))]
feval FExp
e FTemp
_ = [Char] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. HasCallStack => [Char] -> a
error (FExp -> [Char]
forall a. Show a => a -> [Char]
show FExp
e)
evalE :: IR.Exp -> IR.Temp -> WM [X86 AbsReg FAbsReg X2Abs ()]
evalE :: Exp -> Temp -> WM [X86 AbsReg FAbsReg X2Abs ()]
evalE (IR.Reg Temp
r) Temp
rD = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
MovRR () (Temp -> AbsReg
absReg Temp
rD) (Temp -> AbsReg
absReg Temp
r)]
evalE (IR.ConstI Int64
0) Temp
rD = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
XorRR () (Temp -> AbsReg
absReg Temp
rD) (Temp -> AbsReg
absReg Temp
rD)]
evalE (IR.ConstI Int64
i) Temp
rD = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int64 -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int64 -> X86 reg freg f2 a
MovRI () (Temp -> AbsReg
absReg Temp
rD) Int64
i]
evalE (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.ITimes (IR.Reg Temp
r0) (IR.Reg Temp
r1)) (IR.Reg Temp
r2)) Temp
rD = let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD in [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
MovRR () AbsReg
rD' (Temp -> AbsReg
absReg Temp
r0), () -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
IMulRR () AbsReg
rD' (Temp -> AbsReg
absReg Temp
r1), () -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
IAddRR () AbsReg
rD' (Temp -> AbsReg
absReg Temp
r2)]
evalE (IR.IB IBin
Op.ITimes (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD | Temp
r1 Temp -> Temp -> Bool
forall a. Eq a => a -> a -> Bool
/= Temp
rD = let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD in [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
MovRR () AbsReg
rD' (Temp -> AbsReg
absReg Temp
r0), () -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
IMulRR () AbsReg
rD' (Temp -> AbsReg
absReg Temp
r1)]
| Bool
otherwise = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
IMulRR () (Temp -> AbsReg
absReg Temp
rD) (Temp -> AbsReg
absReg Temp
r0)]
evalE (IR.IB IBin
Op.IAsl Exp
e (IR.ConstI Int64
i)) Temp
rD | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
i = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
eR <- WM Int
nextI; plE <- evalE e (IR.ITemp eR)
pure $ plE ++ [MovRR () rD' (IReg eR), Sal () rD' i8]
evalE (IR.IB IBin
Op.IAsr Exp
e (IR.ConstI Int64
i)) Temp
rD | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
i = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
eR <- WM Int
nextI; plE <- evalE e (IR.ITemp eR)
pure $ plE ++ [MovRR () rD' (IReg eR), Sar () rD' i8]
evalE (IR.IB IBin
Op.IMinus (IR.ConstI Int64
0) Exp
e) Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
plE <- Exp -> Temp -> WM [X86 AbsReg FAbsReg X2Abs ()]
evalE Exp
e Temp
rD
pure $ plE ++ [Neg () rD']
evalE (IR.IB IBin
Op.IMinus Exp
e (IR.ConstI Int64
i)) Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
eR <- WM Int
nextI
plE <- evalE e (IR.ITemp eR)
pure $ plE ++ [MovRR () rD' (IReg eR), ISubRI () rD' i]
evalE (IR.IB IBin
Op.IMinus Exp
e Exp
e') Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
(plE,eR) <- Exp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
plI Exp
e; (plE',e'R) <- plI e'
pure $ plE $ plE' [MovRR () rD' eR, ISubRR () rD' e'R]
evalE (IR.IB IBin
Op.IPlus Exp
e (IR.ConstI Int64
i)) Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
(plE,eR) <- Exp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
plI Exp
e
pure $ plE [MovRR () rD' eR, IAddRI () rD' i]
evalE (IR.IB IBin
Op.IPlus Exp
e Exp
e') Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
(plE,eR) <- Exp
-> WM
([X86 AbsReg FAbsReg X2Abs ()] -> [X86 AbsReg FAbsReg X2Abs ()],
AbsReg)
plI Exp
e; (plE',e'R) <- plI e'
pure $ plE $ plE' [MovRR () rD' eR, IAddRR () rD' e'R]
evalE (IR.IB IBin
Op.ITimes Exp
e (IR.EAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl (IR.Reg Temp
i) (IR.ConstI Int64
3)) (IR.ConstI Int64
d))) Maybe AL
_))) Temp
rD | Just Int8
d8 <- Int64 -> Maybe Int8
mi8 Int64
d = do
let rD' :: AbsReg
rD'=Temp -> AbsReg
absReg Temp
rD
eR <- WM Int
nextI; plE <- evalE e (IR.ITemp eR)
pure $ plE ++ [MovRR () rD' (IReg eR), IMulRA () rD' (RSD (absReg m) Eight (absReg i) d8)]
evalE (IR.IB IBin
Op.ITimes Exp
e0 Exp
e1) Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
e0R <- WM Int
nextI; plE0 <- evalE e0 (IR.ITemp e0R)
e1R <- nextI; plE1 <- evalE e1 (IR.ITemp e1R)
pure $ plE0 ++ plE1 ++ [MovRR () rD' (IReg e0R), IMulRR () rD' (IReg e1R)]
evalE (IR.IB IBin
Op.IDiv Exp
e0 Exp
e1) Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
e0R <- WM Int
nextI; e1R <- nextI
plE0 <- evalE e0 (IR.ITemp e0R)
plE1 <- evalE e1 (IR.ITemp e1R)
pure $ plE0 ++ plE1 ++ [XorRR () Rem Rem, MovRR () Quot (IReg e0R), IDiv () (IReg e1R), MovRR () rD' Quot]
evalE (IR.IB IBin
Op.IRem Exp
e0 Exp
e1) Temp
rD = do
let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD
e0R <- WM Int
nextI; e1R <- nextI
plE0 <- evalE e0 (IR.ITemp e0R); plE1 <- evalE e1 (IR.ITemp e1R)
pure $ plE0 ++ plE1 ++ [XorRR () Rem Rem, MovRR () Quot (IReg e0R), IDiv () (IReg e1R), MovRR () rD' Rem]
evalE (IR.IRFloor (IR.FReg FTemp
r)) Temp
t = let r' :: FAbsReg
r' = FTemp -> FAbsReg
fabsReg FTemp
r in [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [()
-> FAbsReg -> FAbsReg -> RoundMode -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a.
a -> freg -> freg -> RoundMode -> X86 reg freg f2 a
Roundsd () FAbsReg
r' FAbsReg
r' RoundMode
RDown, () -> AbsReg -> FAbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> freg -> X86 reg freg f2 a
Cvttsd2si () (Temp -> AbsReg
absReg Temp
t) FAbsReg
r']
evalE (IR.EAt (IR.AP Temp
m (Just (IR.ConstI Int64
i)) Maybe AL
_)) Temp
rD | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
i = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () (Temp -> AbsReg
absReg Temp
rD) (AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Int8 -> Addr reg
RC (Temp -> AbsReg
absReg Temp
m) Int8
i8)]
evalE (IR.EAt (IR.AP Temp
m (Just (IR.Reg Temp
i)) Maybe AL
_)) Temp
rD = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () (Temp -> AbsReg
absReg Temp
rD) (AbsReg -> Scale -> AbsReg -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Addr reg
RS (Temp -> AbsReg
absReg Temp
m) Scale
One (Temp -> AbsReg
absReg Temp
i))]
evalE (IR.EAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IAsl (IR.Reg Temp
i) (IR.ConstI Int64
3))) Maybe AL
_)) Temp
rD = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () (Temp -> AbsReg
absReg Temp
rD) (AbsReg -> Scale -> AbsReg -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Addr reg
RS (Temp -> AbsReg
absReg Temp
m) Scale
Eight (Temp -> AbsReg
absReg Temp
i))]
evalE (IR.IB (Op.BI BBin
Op.AndB) (IR.Reg Temp
r0) (IR.Reg Temp
r1)) Temp
rD = let rD' :: AbsReg
rD' = Temp -> AbsReg
absReg Temp
rD in [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
MovRR () AbsReg
rD' (Temp -> AbsReg
absReg Temp
r0), () -> AbsReg -> AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> reg -> X86 reg freg f2 a
And () AbsReg
rD' (Temp -> AbsReg
absReg Temp
r1)]
evalE (IR.EAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl (IR.Reg Temp
i) (IR.ConstI Int64
3)) (IR.ConstI Int64
d))) Maybe AL
_)) Temp
rD | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
d = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () (Temp -> AbsReg
absReg Temp
rD) (AbsReg -> Scale -> AbsReg -> Int8 -> Addr AbsReg
forall reg. reg -> Scale -> reg -> Int8 -> Addr reg
RSD (Temp -> AbsReg
absReg Temp
m) Scale
Eight (Temp -> AbsReg
absReg Temp
i) Int8
i8)]
evalE (IR.EAt (IR.AP Temp
m (Just (IR.IB IBin
Op.IPlus (IR.IB IBin
Op.IAsl Exp
e (IR.ConstI Int64
3)) (IR.ConstI Int64
d))) Maybe AL
_)) Temp
rD | Just Int8
i8 <- Int64 -> Maybe Int8
mi8 Int64
d = do
i <- WM Int
nextI; plE <- evalE e (IR.ITemp i)
pure $ plE ++ [MovRA () (absReg rD) (RSD (absReg m) Eight (IReg i) i8)]
evalE (IR.EAt (IR.AP Temp
m Maybe Exp
Nothing Maybe AL
_)) Temp
rD =
let rD' :: AbsReg
rD'=Temp -> AbsReg
absReg Temp
rD in [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Addr AbsReg -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Addr reg -> X86 reg freg f2 a
MovRA () AbsReg
rD' (AbsReg -> Addr AbsReg
forall reg. reg -> Addr reg
R(AbsReg -> Addr AbsReg) -> AbsReg -> Addr AbsReg
forall a b. (a -> b) -> a -> b
$Temp -> AbsReg
absReg Temp
m)]
evalE (IR.EAt (IR.AP Temp
m (Just Exp
e) Maybe AL
_)) Temp
rD = do
let rD' :: AbsReg
rD'=Temp -> AbsReg
absReg Temp
rD;m' :: AbsReg
m'=Temp -> AbsReg
absReg Temp
m
r <- WM AbsReg
nextR; eR <- nextI; plE <- evalE e (IR.ITemp eR)
pure $ plE ++ [MovRR () r m', IAddRR () r (IReg eR), MovRA () rD' (R r)]
evalE (IR.LA Int
i) Temp
rD = [X86 AbsReg FAbsReg X2Abs ()] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. a -> StateT WSt Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [() -> AbsReg -> Int -> X86 AbsReg FAbsReg X2Abs ()
forall reg freg f2 a. a -> reg -> Int -> X86 reg freg f2 a
MovRL () (Temp -> AbsReg
absReg Temp
rD) Int
i]
evalE Exp
e Temp
_ = [Char] -> WM [X86 AbsReg FAbsReg X2Abs ()]
forall a. HasCallStack => [Char] -> a
error (Exp -> [Char]
forall a. Show a => a -> [Char]
show Exp
e)