{-|
Module      : Htcc.Asm.Generate.Core
Description : The modules of intrinsic (x86_64) assembly
Copyright   : (c) roki, 2019
License     : MIT
Maintainer  : falgon53@yahoo.co.jp
Stability   : experimental
Portability : POSIX

The modules of intrinsic (x86_64) assembly
-}
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
module Htcc.Asm.Generate.Core (
    dataSection,
    textSection,
) where

import           Control.Monad                             (forM_, unless, when, zipWithM_)
import           Control.Monad.Finally                     (MonadFinally (..))
import           Prelude                                   hiding (truncate)
import           Data.Int                                  (Int32)
import           Data.IORef                                (readIORef)
import           Data.List                                 (find)
import qualified Data.Map                                  as M
import           Data.Maybe                                (fromJust, isJust)
import qualified Data.Text                                 as T
import qualified Data.Text.IO                              as T

import           Htcc.Parser                               (ATKind (..),
                                                            ATree (..),
                                                            fromATKindFor,
                                                            isATForCond,
                                                            isATForIncr,
                                                            isATForInit,
                                                            isATForStmt,
                                                            isComplexAssign,
                                                            stackSize)
import           Htcc.Parser.ConstructionData.Scope.Var    as PV
import           Htcc.Asm.Intrinsic.Operand
import           Htcc.Asm.Intrinsic.Register
import qualified Htcc.Asm.Intrinsic.Structure              as SI
import qualified Htcc.Asm.Intrinsic.Structure.Section.Data as ID
import qualified Htcc.Asm.Intrinsic.Structure.Section.Text as IT
import           Htcc.Utils                                (err, maybe', splitAtLen, tshow)
import qualified Htcc.CRules.Types                         as CR

{-# INLINE prologue #-}
prologue :: Integral i => i -> SI.Asm IT.TextLabelCtx e ()
prologue :: i -> Asm TextLabelCtx e ()
prologue ss :: i
ss = Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rbp Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rbp Register
rsp Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Integer -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rsp (i -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral i
ss :: Integer)

{-# INLINE epilogue #-}
epilogue :: SI.Asm IT.TextLabelCtx e ()
epilogue :: Asm TextLabelCtx e ()
epilogue = Asm TextLabelCtx e ()
forall ctx e. Asm ctx e ()
retLabel Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
IT.leave Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
IT.ret
    where
        retLabel :: Asm ctx e ()
retLabel = (AsmInfo e -> IO ()) -> Asm ctx e ()
forall ctx e a. (AsmInfo e -> IO a) -> Asm ctx e a
SI.Asm ((AsmInfo e -> IO ()) -> Asm ctx e ())
-> (AsmInfo e -> IO ()) -> Asm ctx e ()
forall a b. (a -> b) -> a -> b
$ \x :: AsmInfo e
x -> do
            Maybe Text
cf <- IORef (Maybe Text) -> IO (Maybe Text)
forall a. IORef a -> IO a
readIORef (AsmInfo e -> IORef (Maybe Text)
forall e. AsmInfo e -> IORef (Maybe Text)
SI.curFn AsmInfo e
x)
            Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust Maybe Text
cf) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Text -> IO ()
err "stray epilogue"
            Text -> IO ()
T.putStrLn (Text -> IO ()) -> Text -> IO ()
forall a b. (a -> b) -> a -> b
$ ".L.return." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Maybe Text -> Text
forall a. HasCallStack => Maybe a -> a
fromJust Maybe Text
cf Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ":"

truncate :: Ord i => CR.StorageClass i -> SI.Asm IT.TextLabelCtx e ()
truncate :: StorageClass i -> Asm TextLabelCtx e ()
truncate ty :: StorageClass i
ty = do
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StorageClass i -> TypeKind i
forall (a :: * -> *) i. TypeKindBase a => a i -> TypeKind i
CR.toTypeKind StorageClass i
ty TypeKind i -> TypeKind i -> Bool
forall a. Eq a => a -> a -> Bool
== TypeKind i
forall i. TypeKind i
CR.CTBool) (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.setne Register
al
    StorageClass i -> Asm TextLabelCtx e ()
forall a e. CType a => a -> Asm TextLabelCtx e ()
truncate' StorageClass i
ty
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
    where
        truncate' :: a -> Asm TextLabelCtx e ()
truncate' t :: a
t
            | a -> Natural
forall a. CType a => a -> Natural
CR.sizeof a
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 1 = Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movsx Register
rax Register
al
            | a -> Natural
forall a. CType a => a -> Natural
CR.sizeof a
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 2 = Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movsx Register
rax Register
ax
            | a -> Natural
forall a. CType a => a -> Natural
CR.sizeof a
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 4 = Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movsxd Register
rax Register
eax
            | Bool
otherwise = () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

genAddr :: (Integral e, Show e, IsOperand i, Integral i, Ord i, IT.UnaryInstruction i, IT.BinaryInstruction i) => ATree i -> SI.Asm IT.TextLabelCtx e ()
genAddr :: ATree i -> Asm TextLabelCtx e ()
genAddr (ATNode (ATLVar _ v :: i
v) _ _ _) = Register -> Ref Operand -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.lea Register
rax (Operand -> Ref Operand
forall a. a -> Ref a
Ref (Operand -> Ref Operand) -> Operand -> Ref Operand
forall a b. (a -> b) -> a -> b
$ Register
rbp Register -> i -> Operand
forall a b. (IsOperand a, IsOperand b) => a -> b -> Operand
`osub` i
v) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
genAddr (ATNode (ATGVar _ n :: Text
n) _ _ _) = Offset -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (Text -> Offset
IT.Offset Text
n)
genAddr (ATNode ATDeref _ lhs :: ATree i
lhs _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
genAddr (ATNode (ATMemberAcc m :: StructMember i
m) _ lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genAddr ATree i
lhs
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Natural -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rax (StructMember i -> Natural
forall i. StructMember i -> Natural
CR.smOffset StructMember i
m)
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
genAddr _ = Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "lvalue required as left operand of assignment"

genLVal :: (Integral e, Show e, IsOperand i, Integral i, Ord i, IT.UnaryInstruction i, IT.BinaryInstruction i) => ATree i -> SI.Asm IT.TextLabelCtx e ()
genLVal :: ATree i -> Asm TextLabelCtx e ()
genLVal xs :: ATree i
xs@(ATNode _ t :: StorageClass i
t _ _)
    | StorageClass i -> Bool
forall (a :: * -> *) i. TypeKindBase a => a i -> Bool
CR.isCTArray StorageClass i
t = Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "lvalue required as left operand of assignment"
    | Bool
otherwise = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genAddr ATree i
xs
genLVal _ = Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "internal compiler error: genLVal catch ATEmpty"

load :: Ord i => CR.StorageClass i -> SI.Asm IT.TextLabelCtx e ()
load :: StorageClass i -> Asm TextLabelCtx e ()
load t :: StorageClass i
t
    | StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 1 = Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Ptr Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movsx Register
rax ((SizeUnit -> Ref Register -> Ptr Register)
-> Ref Register -> Ptr Register
forall a.
IsOperand a =>
(SizeUnit -> Ref a -> Ptr a) -> Ref a -> Ptr a
IT.byte SizeUnit -> Ref Register -> Ptr Register
forall a. SizeUnit -> Ref a -> Ptr a
IT.Ptr (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rax)) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
    | StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 2 = Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Ptr Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movsx Register
rax ((SizeUnit -> Ref Register -> Ptr Register)
-> Ref Register -> Ptr Register
forall a.
IsOperand a =>
(SizeUnit -> Ref a -> Ptr a) -> Ref a -> Ptr a
IT.word SizeUnit -> Ref Register -> Ptr Register
forall a. SizeUnit -> Ref a -> Ptr a
IT.Ptr (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rax)) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
    | StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 4 = Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Ptr Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movsxd Register
rax ((SizeUnit -> Ref Register -> Ptr Register)
-> Ref Register -> Ptr Register
forall a.
IsOperand a =>
(SizeUnit -> Ref a -> Ptr a) -> Ref a -> Ptr a
IT.dword SizeUnit -> Ref Register -> Ptr Register
forall a. SizeUnit -> Ref a -> Ptr a
IT.Ptr (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rax)) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
    | Bool
otherwise = Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Ref Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rax) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax

store :: Ord i => CR.StorageClass i -> SI.Asm IT.TextLabelCtx e ()
store :: StorageClass i -> Asm TextLabelCtx e ()
store t :: StorageClass i
t = do
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rdi
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StorageClass i -> TypeKind i
forall (a :: * -> *) i. TypeKindBase a => a i -> TypeKind i
CR.toTypeKind StorageClass i
t TypeKind i -> TypeKind i -> Bool
forall a. Eq a => a -> a -> Bool
== TypeKind i
forall i. TypeKind i
CR.CTBool) (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rdi (0 :: Int) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.setne Register
dil Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rdi Register
dil
    Ref Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rax) Register
storeReg
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rdi
    where
        storeReg :: Register
storeReg
            | StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 1 = Register
dil
            | StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 2 = Register
di
            | StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== 4 = Register
edi
            | Bool
otherwise = Register
rdi

increment :: Ord i => CR.StorageClass i -> SI.Asm IT.TextLabelCtx e ()
increment :: StorageClass i -> Asm TextLabelCtx e ()
increment t :: StorageClass i
t = Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Natural -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rax (Natural
-> (StorageClass i -> Natural) -> Maybe (StorageClass i) -> Natural
forall b a. b -> (a -> b) -> Maybe a -> b
maybe 1 StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof (Maybe (StorageClass i) -> Natural)
-> Maybe (StorageClass i) -> Natural
forall a b. (a -> b) -> a -> b
$ StorageClass i -> Maybe (StorageClass i)
forall a. CType a => a -> Maybe a
CR.deref StorageClass i
t) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax

decrement :: Ord i => CR.StorageClass i -> SI.Asm IT.TextLabelCtx e ()
decrement :: StorageClass i -> Asm TextLabelCtx e ()
decrement t :: StorageClass i
t = Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Natural -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rax (Natural
-> (StorageClass i -> Natural) -> Maybe (StorageClass i) -> Natural
forall b a. b -> (a -> b) -> Maybe a -> b
maybe 1 StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof (Maybe (StorageClass i) -> Natural)
-> Maybe (StorageClass i) -> Natural
forall a b. (a -> b) -> a -> b
$ StorageClass i -> Maybe (StorageClass i)
forall a. CType a => a -> Maybe a
CR.deref StorageClass i
t) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax

genStmt :: (Show e, Integral e, Show i, Integral i, Ord i, IsOperand i, IT.UnaryInstruction i, IT.BinaryInstruction i) => ATree i -> SI.Asm IT.TextLabelCtx e ()
genStmt :: ATree i -> Asm TextLabelCtx e ()
genStmt (ATNode (ATCallFunc x :: Text
x Nothing) _ _ _) = Text -> Asm TextLabelCtx e ()
forall e. Text -> Asm TextLabelCtx e ()
IT.call Text
x Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
genStmt (ATNode (ATCallFunc x :: Text
x (Just args :: [ATree i]
args)) t :: StorageClass i
t _ _) = let (n' :: Int
n', toReg :: [ATree i]
toReg, _) = Int -> [ATree i] -> (Int, [ATree i], [ATree i])
forall a. Int -> [a] -> (Int, [a], [a])
splitAtLen 6 [ATree i]
args in do
    (ATree i -> Asm TextLabelCtx e ())
-> [ATree i] -> Asm TextLabelCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt [ATree i]
toReg
    (Register -> Asm TextLabelCtx e ())
-> [Register] -> Asm TextLabelCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop ([Register] -> Asm TextLabelCtx e ())
-> [Register] -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ Int -> [Register]
popRegs Int
n'
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax Register
rsp
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.and Register
rax (0x0f :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jnz (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ Text -> e -> Asm TargetLabelCtx e ()
forall e i.
(Show e, Show i) =>
Text -> i -> Asm TargetLabelCtx e ()
IT.ref "call" e
n
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax (0 :: Int)
    Text -> Asm TextLabelCtx e ()
forall e. Text -> Asm TextLabelCtx e ()
IT.call Text
x
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refEnd e
n
    Text -> e -> Asm TextLabelCtx e ()
forall i e. (Show i, Show e) => Text -> i -> Asm TextLabelCtx e ()
IT.label "call" e
n
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rsp (8 :: Int)
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax (0 :: Int)
    Text -> Asm TextLabelCtx e ()
forall e. Text -> Asm TextLabelCtx e ()
IT.call Text
x
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rsp (8 :: Int)
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.end e
n
    Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (StorageClass i -> TypeKind i
forall (a :: * -> *) i. TypeKindBase a => a i -> TypeKind i
CR.toTypeKind StorageClass i
t TypeKind i -> TypeKind i -> Bool
forall a. Eq a => a -> a -> Bool
== TypeKind i
forall i. TypeKind i
CR.CTBool) (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
genStmt (ATNode (ATBlock stmt :: [ATree i]
stmt) _ _ _) = (ATree i -> Asm TextLabelCtx e ())
-> [ATree i] -> Asm TextLabelCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt [ATree i]
stmt
genStmt (ATNode (ATStmtExpr stmt :: [ATree i]
stmt) _ _ _) = (ATree i -> Asm TextLabelCtx e ())
-> [ATree i] -> Asm TextLabelCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt [ATree i]
stmt
genStmt (ATNode ATBreak _ _ _) = Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp Asm TargetLabelCtx e ()
forall e. Show e => Asm TargetLabelCtx e ()
IT.refHBreak
genStmt (ATNode ATContinue _ _ _) = Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp Asm TargetLabelCtx e ()
forall e. Show e => Asm TargetLabelCtx e ()
IT.refHContinue
genStmt (ATNode (ATGoto ident :: Text
ident) _ _ _) = Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ Text -> Asm TargetLabelCtx e ()
forall e. Text -> Asm TargetLabelCtx e ()
IT.refGoto Text
ident
genStmt (ATNode (ATLabel ident :: Text
ident) _ _ _) = Text -> Asm TextLabelCtx e ()
forall e. Text -> Asm TextLabelCtx e ()
IT.gotoLabel Text
ident
genStmt (ATNode (ATFor exps :: [ATKindFor i]
exps) _ _ _) = Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
IT.bracketBrkCnt (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ do
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    Asm TextLabelCtx e ()
forall ctx e. Asm ctx e ()
IT.applyCnt Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Asm TextLabelCtx e ()
forall ctx e. Asm ctx e ()
IT.applyBrk
    Asm TextLabelCtx e ()
-> (ATKindFor i -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i)
-> Asm TextLabelCtx e ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Asm TextLabelCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt (ATree i -> Asm TextLabelCtx e ())
-> (ATKindFor i -> ATree i) -> ATKindFor i -> Asm TextLabelCtx e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ATKindFor i -> ATree i
forall a. ATKindFor a -> ATree a
fromATKindFor) (Maybe (ATKindFor i) -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i) -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ (ATKindFor i -> Bool) -> [ATKindFor i] -> Maybe (ATKindFor i)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ATKindFor i -> Bool
forall a. ATKindFor a -> Bool
isATForInit [ATKindFor i]
exps
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.begin e
n
    Asm TextLabelCtx e ()
-> (ATKindFor i -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i)
-> Asm TextLabelCtx e ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Asm TextLabelCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt (ATree i -> Asm TextLabelCtx e ())
-> (ATKindFor i -> ATree i) -> ATKindFor i -> Asm TextLabelCtx e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ATKindFor i -> ATree i
forall a. ATKindFor a -> ATree a
fromATKindFor) (Maybe (ATKindFor i) -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i) -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ (ATKindFor i -> Bool) -> [ATKindFor i] -> Maybe (ATKindFor i)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ATKindFor i -> Bool
forall a. ATKindFor a -> Bool
isATForCond [ATKindFor i]
exps
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refBreak e
n
    Asm TextLabelCtx e ()
-> (ATKindFor i -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i)
-> Asm TextLabelCtx e ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Asm TextLabelCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt (ATree i -> Asm TextLabelCtx e ())
-> (ATKindFor i -> ATree i) -> ATKindFor i -> Asm TextLabelCtx e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ATKindFor i -> ATree i
forall a. ATKindFor a -> ATree a
fromATKindFor) (Maybe (ATKindFor i) -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i) -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ (ATKindFor i -> Bool) -> [ATKindFor i] -> Maybe (ATKindFor i)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ATKindFor i -> Bool
forall a. ATKindFor a -> Bool
isATForStmt [ATKindFor i]
exps
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.continue e
n
    Asm TextLabelCtx e ()
-> (ATKindFor i -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i)
-> Asm TextLabelCtx e ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Asm TextLabelCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) (ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt (ATree i -> Asm TextLabelCtx e ())
-> (ATKindFor i -> ATree i) -> ATKindFor i -> Asm TextLabelCtx e ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ATKindFor i -> ATree i
forall a. ATKindFor a -> ATree a
fromATKindFor) (Maybe (ATKindFor i) -> Asm TextLabelCtx e ())
-> Maybe (ATKindFor i) -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ (ATKindFor i -> Bool) -> [ATKindFor i] -> Maybe (ATKindFor i)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ATKindFor i -> Bool
forall a. ATKindFor a -> Bool
isATForIncr [ATKindFor i]
exps
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refBegin e
n
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.break e
n
genStmt (ATNode ATWhile _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
IT.bracketBrkCnt (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ do
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    Asm TextLabelCtx e ()
forall ctx e. Asm ctx e ()
IT.applyCnt Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Asm TextLabelCtx e ()
forall ctx e. Asm ctx e ()
IT.applyBrk
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.continue e
n
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refBreak e
n
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refContinue e
n
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.break e
n
genStmt (ATNode ATIf _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refEnd e
n
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.end e
n
genStmt (ATNode ATElse _ (ATNode ATIf _ llhs :: ATree i
llhs rrhs :: ATree i
rrhs) rhs :: ATree i
rhs) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
llhs
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refElse e
n
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rrhs
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refEnd e
n
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.eLse e
n
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.end e
n
genStmt (ATNode ATElse _ _ _) = Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "internal compiler error: asm code generator should not reach here. Maybe abstract tree is broken it cause (bug)."
genStmt (ATNode (ATSwitch cond :: ATree i
cond cases :: [ATree i]
cases) _ _ _) = Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
IT.bracketBrkCnt (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ do
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    Asm TextLabelCtx e ()
forall ctx e. Asm ctx e ()
IT.applyBrk
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
cond
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    [ATree i]
ntr <- [ATree i] -> Asm TextLabelCtx e [ATree i]
forall e i.
(Show e, Enum e, Integral e, Show i, Num i) =>
[ATree i] -> Asm TextLabelCtx e [ATree i]
IT.makeCases [ATree i]
cases
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refBreak e
n
    (ATree i -> Asm TextLabelCtx e ())
-> [ATree i] -> Asm TextLabelCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt [ATree i]
ntr
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.break e
n
genStmt (ATNode (ATCase n :: i
n _) _ lhs :: ATree i
lhs _) = i -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.cAse i
n Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
genStmt (ATNode (ATDefault n :: i
n) _ lhs :: ATree i
lhs _) = i -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.cAse i
n Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
genStmt (ATNode ATReturn t :: StorageClass i
t ATEmpty r :: ATree i
r) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt (ATree i -> Asm TextLabelCtx e ())
-> ATree i -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ ATKind i -> StorageClass i -> ATree i -> ATree i -> ATree i
forall a.
ATKind a -> StorageClass a -> ATree a -> ATree a -> ATree a
ATNode ATKind i
forall a. ATKind a
ATReturn StorageClass i
t (ATKind i -> StorageClass i -> ATree i -> ATree i -> ATree i
forall a.
ATKind a -> StorageClass a -> ATree a -> ATree a -> ATree a
ATNode (i -> ATKind i
forall a. a -> ATKind a
ATNum 0) (TypeKind i -> StorageClass i
forall i. TypeKind i -> StorageClass i
CR.SCAuto TypeKind i
forall i. TypeKind i
CR.CTInt) ATree i
forall a. ATree a
ATEmpty ATree i
forall a. ATree a
ATEmpty) ATree i
r
genStmt (ATNode ATReturn _ lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp Asm TargetLabelCtx e ()
forall e. Show e => Asm TargetLabelCtx e ()
IT.refReturn
genStmt (ATNode ATCast t :: StorageClass i
t lhs :: ATree i
lhs _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
truncate StorageClass i
t
genStmt (ATNode ATExprStmt _ lhs :: ATree i
lhs _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rsp (8 :: Int)
genStmt (ATNode ATBitNot _ lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.not Register
rax
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
genStmt (ATNode ATLAnd _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = do
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Text -> e -> Asm TargetLabelCtx e ()
forall e i.
(Show e, Show i) =>
Text -> i -> Asm TargetLabelCtx e ()
IT.ref "false" e
n)
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Text -> e -> Asm TargetLabelCtx e ()
forall e i.
(Show e, Show i) =>
Text -> i -> Asm TargetLabelCtx e ()
IT.ref "false" e
n)
    Int -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (1 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refEnd e
n
    Text -> e -> Asm TextLabelCtx e ()
forall i e. (Show i, Show e) => Text -> i -> Asm TextLabelCtx e ()
IT.label "false" e
n
    Int -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (0 :: Int)
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.end e
n
genStmt (ATNode ATLOr _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = do
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jne (Text -> e -> Asm TargetLabelCtx e ()
forall e i.
(Show e, Show i) =>
Text -> i -> Asm TargetLabelCtx e ()
IT.ref "true" e
n)
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int) Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jne (Text -> e -> Asm TargetLabelCtx e ()
forall e i.
(Show e, Show i) =>
Text -> i -> Asm TargetLabelCtx e ()
IT.ref "true" e
n)
    Int -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (0 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refEnd e
n
    Text -> e -> Asm TextLabelCtx e ()
forall i e. (Show i, Show e) => Text -> i -> Asm TextLabelCtx e ()
IT.label "true" e
n
    Int -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (1 :: Int)
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.end e
n
genStmt (ATNode (ATConditional cn :: ATree i
cn ATEmpty el :: ATree i
el) _ _ _) = do
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
cn
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rdi Register
rax
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rdi
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refElse e
n
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refEnd e
n
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.eLse e
n
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
el
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.end e
n
genStmt (ATNode (ATConditional cn :: ATree i
cn th :: ATree i
th el :: ATree i
el) _ _ _) = do
    e
n <- Asm TextLabelCtx e e
forall e. Enum e => Asm TextLabelCtx e e
IT.incrLbl
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
cn
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int)
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.je (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refElse e
n
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
th
    Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall e. Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
IT.jmp (Asm TargetLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TargetLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ e -> Asm TargetLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TargetLabelCtx e ()
IT.refEnd e
n
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.eLse e
n
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
el
    e -> Asm TextLabelCtx e ()
forall e i. (Show e, Show i) => i -> Asm TextLabelCtx e ()
IT.end e
n
genStmt (ATNode ATPreInc t :: StorageClass i
t lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genLVal ATree i
lhs
    Ref Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rsp)
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
increment StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
store StorageClass i
t
genStmt (ATNode ATPreDec t :: StorageClass i
t lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genLVal ATree i
lhs
    Ref Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rsp)
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
decrement StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
store StorageClass i
t
genStmt (ATNode ATPostInc t :: StorageClass i
t lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genLVal ATree i
lhs
    Ref Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rsp)
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
increment StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
store StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
decrement StorageClass i
t
genStmt (ATNode ATPostDec t :: StorageClass i
t lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genLVal ATree i
lhs
    Ref Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rsp)
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
decrement StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
store StorageClass i
t
    StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
increment StorageClass i
t
genStmt (ATNode ATComma _ lhs :: ATree i
lhs rhs :: ATree i
rhs) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs
genStmt (ATNode ATAddr _ lhs :: ATree i
lhs _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genAddr ATree i
lhs
genStmt (ATNode ATDeref t :: StorageClass i
t lhs :: ATree i
lhs _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (StorageClass i -> Bool
forall (a :: * -> *) i. TypeKindBase a => a i -> Bool
CR.isCTArray StorageClass i
t) (StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t)
genStmt (ATNode ATNot _ lhs :: ATree i
lhs _) = do
    ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax
    Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax (0 :: Int)
    Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.sete Register
al
    Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
    Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
genStmt (ATNode (ATNum x :: i
x) _ _ _)
    | i
x i -> i -> Bool
forall a. Ord a => a -> a -> Bool
<= Int32 -> i
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int32
forall a. Bounded a => a
maxBound :: Int32) = i -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push i
x
    | Bool
otherwise = Register -> i -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movabs Register
rax i
x Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax
genStmt n :: ATree i
n@(ATNode (ATLVar _ _) t :: StorageClass i
t _ _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genAddr ATree i
n Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (StorageClass i -> Bool
forall (a :: * -> *) i. TypeKindBase a => a i -> Bool
CR.isCTArray StorageClass i
t) (StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t)
genStmt n :: ATree i
n@(ATNode (ATGVar _ _) t :: StorageClass i
t _ _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genAddr ATree i
n Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (StorageClass i -> Bool
forall (a :: * -> *) i. TypeKindBase a => a i -> Bool
CR.isCTArray StorageClass i
t) (StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t)
genStmt n :: ATree i
n@(ATNode (ATMemberAcc _) t :: StorageClass i
t _ _) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genAddr ATree i
n Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (StorageClass i -> Bool
forall (a :: * -> *) i. TypeKindBase a => a i -> Bool
CR.isCTArray StorageClass i
t) (StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
t)
genStmt (ATNode ATAssign t :: StorageClass i
t lhs :: ATree i
lhs rhs :: ATree i
rhs) = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genLVal ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
store StorageClass i
t
genStmt (ATNode (ATNull _) _ _ _) = () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
genStmt (ATNode kd :: ATKind i
kd ty :: StorageClass i
ty lhs :: ATree i
lhs rhs :: ATree i
rhs)
    | ATKind i -> Bool
forall a. ATKind a -> Bool
isComplexAssign ATKind i
kd = do
        ATree i -> Asm TextLabelCtx e ()
forall e i.
(Integral e, Show e, IsOperand i, Integral i, Ord i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genLVal ATree i
lhs
        Ref Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push (Register -> Ref Register
forall a. a -> Ref a
Ref Register
rsp)
        StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
load StorageClass i
ty
        ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs
        Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
binOp
        StorageClass i -> Asm TextLabelCtx e ()
forall i e. Ord i => StorageClass i -> Asm TextLabelCtx e ()
store StorageClass i
ty
    | Bool
otherwise = ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
lhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
rhs Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
binOp
    where
        binOp :: Asm TextLabelCtx e ()
binOp = (Asm TextLabelCtx e ()
 -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
-> Asm TextLabelCtx e ()
-> Asm TextLabelCtx e ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (μ :: * -> *) α β. MonadFinally μ => μ α -> μ β -> μ α
finally (Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax) (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> case ATKind i
kd of
            ATAdd -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rax Register
rdi
            ATAddAssign -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rax Register
rdi
            ATSub -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rax Register
rdi
            ATSubAssign -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rax Register
rdi
            ATAddPtr -> Asm TextLabelCtx e ()
-> Maybe (StorageClass i)
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall b a. b -> Maybe a -> (a -> b) -> b
maybe' (Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "the type is not pointer") (StorageClass i -> Maybe (StorageClass i)
forall a. CType a => a -> Maybe a
CR.deref StorageClass i
ty) ((StorageClass i -> Asm TextLabelCtx e ())
 -> Asm TextLabelCtx e ())
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ \dt :: StorageClass i
dt -> do
                Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.imul Register
rdi (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
dt) :: Int)
                Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rax Register
rdi
            ATAddPtrAssign -> Asm TextLabelCtx e ()
-> Maybe (StorageClass i)
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall b a. b -> Maybe a -> (a -> b) -> b
maybe' (Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "the type is not pointer") (StorageClass i -> Maybe (StorageClass i)
forall a. CType a => a -> Maybe a
CR.deref StorageClass i
ty) ((StorageClass i -> Asm TextLabelCtx e ())
 -> Asm TextLabelCtx e ())
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ \dt :: StorageClass i
dt -> do
                Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.imul Register
rdi (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
dt) :: Int)
                Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.add Register
rax Register
rdi
            ATSubPtr -> Asm TextLabelCtx e ()
-> Maybe (StorageClass i)
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall b a. b -> Maybe a -> (a -> b) -> b
maybe' (Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "the type is not pointer") (StorageClass i -> Maybe (StorageClass i)
forall a. CType a => a -> Maybe a
CR.deref StorageClass i
ty) ((StorageClass i -> Asm TextLabelCtx e ())
 -> Asm TextLabelCtx e ())
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ \dt :: StorageClass i
dt -> do
                Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.imul Register
rdi (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
dt) :: Int)
                Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rax Register
rdi
            ATSubPtrAssign -> Asm TextLabelCtx e ()
-> Maybe (StorageClass i)
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall b a. b -> Maybe a -> (a -> b) -> b
maybe' (Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "the type is not pointer") (StorageClass i -> Maybe (StorageClass i)
forall a. CType a => a -> Maybe a
CR.deref StorageClass i
ty) ((StorageClass i -> Asm TextLabelCtx e ())
 -> Asm TextLabelCtx e ())
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ \dt :: StorageClass i
dt -> do
                Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.imul Register
rdi (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
dt) :: Int)
                Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rax Register
rdi
            ATPtrDis -> Asm TextLabelCtx e ()
-> Maybe (StorageClass i)
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall b a. b -> Maybe a -> (a -> b) -> b
maybe' (Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "the type is not pointer") (StorageClass i -> Maybe (StorageClass i)
forall a. CType a => a -> Maybe a
CR.deref (StorageClass i -> Maybe (StorageClass i))
-> StorageClass i -> Maybe (StorageClass i)
forall a b. (a -> b) -> a -> b
$ ATree i -> StorageClass i
forall a. ATree a -> StorageClass a
atype ATree i
lhs) ((StorageClass i -> Asm TextLabelCtx e ())
 -> Asm TextLabelCtx e ())
-> (StorageClass i -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ \dt :: StorageClass i
dt -> do
                Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sub Register
rax Register
rdi
                Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
IT.cqo
                Register -> Int -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rdi (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
dt) :: Int)
                Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.idiv Register
rdi
            ATMul -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.imul Register
rax Register
rdi
            ATMulAssign -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.imul Register
rax Register
rdi
            ATDiv -> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
IT.cqo Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.idiv Register
rdi
            ATDivAssign -> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
IT.cqo Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.idiv Register
rdi
            ATMod -> Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
IT.cqo Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.idiv Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax Register
rdx
            ATAnd -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.and Register
rax Register
rdi
            ATAndAssign -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.and Register
rax Register
rdi
            ATOr -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.or Register
rax Register
rdi
            ATOrAssign -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.or Register
rax Register
rdi
            ATXor -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.xor Register
rax Register
rdi
            ATXorAssign -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.xor Register
rax Register
rdi
            ATShl -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
edx Register
eax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
ecx Register
edx Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.shl Register
rax Register
cl
            ATShlAssign -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
edx Register
eax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
ecx Register
edx Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.shl Register
rax Register
cl
            ATShr -> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
edx Register
eax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
ecx Register
edx Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sar Register
rax Register
cl
            ATShrAssign ->  Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.push Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
edx Register
eax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall a e. UnaryInstruction a => a -> Asm TextLabelCtx e ()
IT.pop Register
rax Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov Register
ecx Register
edx Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.sar Register
rax Register
cl
            ATEQ -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.sete Register
al Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
            ATNEQ -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.setne Register
al Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
            ATLT -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.setl Register
al Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
            ATLEQ -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.setle Register
al Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
            ATGT -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.setg Register
al Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
            ATGEQ -> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.cmp Register
rax Register
rdi Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Asm TextLabelCtx e ()
forall e. Register -> Asm TextLabelCtx e ()
IT.setge Register
al Asm TextLabelCtx e ()
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Register -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.movzb Register
rax Register
al
            _ -> Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "internal compiler error: asm code generator should not reach here (binOp). Maybe abstract tree is broken it cause (bug)."
genStmt _ = () -> Asm TextLabelCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

textSection' :: (Integral e, Show e, Integral i, IsOperand i, IT.UnaryInstruction i, IT.BinaryInstruction i) => ATree i -> SI.Asm IT.TextSectionCtx e ()
textSection' :: ATree i -> Asm TextSectionCtx e ()
textSection' lc :: ATree i
lc@(ATNode (ATDefFunc fn :: Text
fn margs :: Maybe [ATree i]
margs) ty :: StorageClass i
ty st :: ATree i
st _) = do
    Bool -> Asm TextSectionCtx e () -> Asm TextSectionCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (StorageClass i -> Bool
forall (a :: * -> *) i. StorageClassBase a => a i -> Bool
CR.isSCStatic StorageClass i
ty) (Asm TextSectionCtx e () -> Asm TextSectionCtx e ())
-> Asm TextSectionCtx e () -> Asm TextSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ Text -> Asm TextSectionCtx e ()
forall e. Text -> Asm TextSectionCtx e ()
IT.global Text
fn
    Text -> Asm TextLabelCtx e () -> Asm TextSectionCtx e ()
forall e a. Text -> Asm TextLabelCtx e a -> Asm TextSectionCtx e a
IT.fn Text
fn (Asm TextLabelCtx e () -> Asm TextSectionCtx e ())
-> Asm TextLabelCtx e () -> Asm TextSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ do
        Natural -> Asm TextLabelCtx e ()
forall i e. Integral i => i -> Asm TextLabelCtx e ()
prologue (ATree i -> Natural
forall i. (Show i, Integral i) => ATree i -> Natural
stackSize ATree i
lc)
        Bool -> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Maybe [ATree i] -> Bool
forall a. Maybe a -> Bool
isJust Maybe [ATree i]
margs) (Asm TextLabelCtx e () -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e () -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ ((ATree i -> [Register] -> Asm TextLabelCtx e ())
 -> [[Register]] -> Asm TextLabelCtx e ())
-> [[Register]]
-> (ATree i -> [Register] -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((ATree i -> [Register] -> Asm TextLabelCtx e ())
-> [ATree i] -> [[Register]] -> Asm TextLabelCtx e ()
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m ()
`zipWithM_` Maybe [ATree i] -> [ATree i]
forall a. HasCallStack => Maybe a -> a
fromJust Maybe [ATree i]
margs) [[Register]]
argRegs ((ATree i -> [Register] -> Asm TextLabelCtx e ())
 -> Asm TextLabelCtx e ())
-> (ATree i -> [Register] -> Asm TextLabelCtx e ())
-> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ \(ATNode (ATLVar t :: StorageClass i
t o :: i
o) _ _ _) reg :: [Register]
reg ->
            Asm TextLabelCtx e ()
-> (Register -> Asm TextLabelCtx e ())
-> Maybe Register
-> Asm TextLabelCtx e ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text -> Asm TextLabelCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "internal compiler error: there is no register that fits the specified size")
                (Ref Operand -> Register -> Asm TextLabelCtx e ()
forall a b e.
(BinaryInstruction a, BinaryInstruction b) =>
a -> b -> Asm TextLabelCtx e ()
IT.mov (Operand -> Ref Operand
forall a. a -> Ref a
Ref (Operand -> Ref Operand) -> Operand -> Ref Operand
forall a b. (a -> b) -> a -> b
$ Register
rbp Register -> i -> Operand
forall a b. (IsOperand a, IsOperand b) => a -> b -> Operand
`osub` i
o)) (Maybe Register -> Asm TextLabelCtx e ())
-> Maybe Register -> Asm TextLabelCtx e ()
forall a b. (a -> b) -> a -> b
$ (Register -> Bool) -> [Register] -> Maybe Register
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t) (Natural -> Bool) -> (Register -> Natural) -> Register -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Register -> Natural
forall a. IsRegister a => a -> Natural
byteWidth) [Register]
reg
        ATree i -> Asm TextLabelCtx e ()
forall e i.
(Show e, Integral e, Show i, Integral i, Ord i, IsOperand i,
 UnaryInstruction i, BinaryInstruction i) =>
ATree i -> Asm TextLabelCtx e ()
genStmt ATree i
st
        Asm TextLabelCtx e ()
forall e. Asm TextLabelCtx e ()
epilogue
textSection' ATEmpty = () -> Asm TextSectionCtx e ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
textSection' _ = Text -> Asm TextSectionCtx e ()
forall ctx e. Text -> Asm ctx e ()
SI.errCtx "internal compiler error: all abstract tree should start from some functions"

-- | data section of assembly code
dataSection :: (Show i, Ord i, Num i) => M.Map T.Text (GVar i) -> [Literal i] -> SI.Asm SI.AsmCodeCtx e ()
dataSection :: Map Text (GVar i) -> [Literal i] -> Asm AsmCodeCtx e ()
dataSection gvars :: Map Text (GVar i)
gvars lits :: [Literal i]
lits = Asm DataSectionCtx e () -> Asm AsmCodeCtx e ()
forall e a. Asm DataSectionCtx e a -> Asm AsmCodeCtx e a
ID.dAta (Asm DataSectionCtx e () -> Asm AsmCodeCtx e ())
-> Asm DataSectionCtx e () -> Asm AsmCodeCtx e ()
forall a b. (a -> b) -> a -> b
$ do
    [Literal i]
-> (Literal i -> Asm DataSectionCtx e ())
-> Asm DataSectionCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Literal i]
lits ((Literal i -> Asm DataSectionCtx e ()) -> Asm DataSectionCtx e ())
-> (Literal i -> Asm DataSectionCtx e ())
-> Asm DataSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ \(Literal _ n :: Natural
n cnt :: ByteString
cnt) -> Text -> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall e a. Text -> Asm DataLabelCtx e a -> Asm DataSectionCtx e a
ID.label (".L.data." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Natural -> Text
forall a. Show a => a -> Text
tshow Natural
n) (Asm DataLabelCtx e () -> Asm DataSectionCtx e ())
-> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ ByteString -> Asm DataLabelCtx e ()
forall e. ByteString -> Asm DataLabelCtx e ()
ID.byte ByteString
cnt
    [(Text, GVar i)]
-> ((Text, GVar i) -> Asm DataSectionCtx e ())
-> Asm DataSectionCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Map Text (GVar i) -> [(Text, GVar i)]
forall k a. Map k a -> [(k, a)]
M.toList Map Text (GVar i)
gvars) (((Text, GVar i) -> Asm DataSectionCtx e ())
 -> Asm DataSectionCtx e ())
-> ((Text, GVar i) -> Asm DataSectionCtx e ())
-> Asm DataSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ \(var :: Text
var, GVar t :: StorageClass i
t ginit :: GVarInitWith i
ginit) -> case GVarInitWith i
ginit of
        PV.GVarInitWithZero    -> Text -> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall e a. Text -> Asm DataLabelCtx e a -> Asm DataSectionCtx e a
ID.label Text
var (Asm DataLabelCtx e () -> Asm DataSectionCtx e ())
-> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ Natural -> Asm DataLabelCtx e ()
forall e. Natural -> Asm DataLabelCtx e ()
ID.zero (StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t)
        PV.GVarInitWithOG ref :: Text
ref  -> Text -> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall e a. Text -> Asm DataLabelCtx e a -> Asm DataSectionCtx e a
ID.label Text
var (Asm DataLabelCtx e () -> Asm DataSectionCtx e ())
-> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ Text -> Asm DataLabelCtx e ()
forall e. Text -> Asm DataLabelCtx e ()
ID.quad Text
ref
        PV.GVarInitWithVal val :: i
val -> Text -> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall e a. Text -> Asm DataLabelCtx e a -> Asm DataSectionCtx e a
ID.label Text
var (Asm DataLabelCtx e () -> Asm DataSectionCtx e ())
-> Asm DataLabelCtx e () -> Asm DataSectionCtx e ()
forall a b. (a -> b) -> a -> b
$ Natural -> i -> Asm DataLabelCtx e ()
forall i e.
(Num i, Show i) =>
Natural -> i -> Asm DataLabelCtx e ()
ID.sbyte (StorageClass i -> Natural
forall a. CType a => a -> Natural
CR.sizeof StorageClass i
t) i
val

-- | text section of assembly code
textSection :: (Integral e, Show e, IsOperand i, Integral i, Show i, IT.UnaryInstruction i, IT.BinaryInstruction i) => [ATree i] -> SI.Asm SI.AsmCodeCtx e ()
textSection :: [ATree i] -> Asm AsmCodeCtx e ()
textSection atl :: [ATree i]
atl = Asm TextSectionCtx e () -> Asm AsmCodeCtx e ()
forall e a. Asm TextSectionCtx e a -> Asm AsmCodeCtx e a
IT.text (Asm TextSectionCtx e () -> Asm AsmCodeCtx e ())
-> Asm TextSectionCtx e () -> Asm AsmCodeCtx e ()
forall a b. (a -> b) -> a -> b
$ [ATree i]
-> (ATree i -> Asm TextSectionCtx e ()) -> Asm TextSectionCtx e ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [ATree i]
atl ATree i -> Asm TextSectionCtx e ()
forall e i.
(Integral e, Show e, Integral i, IsOperand i, UnaryInstruction i,
 BinaryInstruction i) =>
ATree i -> Asm TextSectionCtx e ()
textSection'