@@ -5,7 +5,6 @@ import IRTS.CodegenCommon
5import IRTS.Lang
5import IRTS.Lang
6import IRTS.Simplified
6import IRTS.Simplified
7import qualified Core.TT as TT
7import qualified Core.TT as TT
8−import Core.TT (ArithTy(..), IntTy(..), NativeTy(..), nativeTyWidth)
10import Util.System
9import Util.System
11import Paths_idris
10import Paths_idris
@@ -14,6 +13,9 @@ import LLVM.General.Context
14import LLVM.General.Diagnostic
13import LLVM.General.Diagnostic
15import LLVM.General.AST
14import LLVM.General.AST
16import LLVM.General.AST.AddrSpace
15import LLVM.General.AST.AddrSpace
16+import LLVM.General.Target
17+import LLVM.General.AST.DataLayout
18+import LLVM.General.PassManager
17import qualified LLVM.General.Module as M
19import qualified LLVM.General.Module as M
18import qualified LLVM.General.AST.IntegerPredicate as IPred
20import qualified LLVM.General.AST.IntegerPredicate as IPred
19import qualified LLVM.General.AST.Linkage as L
21import qualified LLVM.General.AST.Linkage as L
@@ -23,17 +25,21 @@ import qualified LLVM.General.AST.Attribute as A
23import qualified LLVM.General.AST.Global as G
25import qualified LLVM.General.AST.Global as G
24import qualified LLVM.General.AST.Constant as C
26import qualified LLVM.General.AST.Constant as C
25import qualified LLVM.General.AST.Float as F
27import qualified LLVM.General.AST.Float as F
28+import qualified LLVM.General.Relocation as R
29+import qualified LLVM.General.CodeModel as CM
30+import qualified LLVM.General.CodeGenOpt as CGO
27import Data.List
32import Data.List
28import Data.Maybe
33import Data.Maybe
29import Data.Word
34import Data.Word
30import Data.Set (Set)
35import Data.Set (Set)
31import qualified Data.Set as S
36import qualified Data.Set as S
32−import qualified Data.Vector.Unboxed as V
37+import qualified Data.Map as M
33import Control.Applicative
38import Control.Applicative
34import Control.Monad.RWS
39import Control.Monad.RWS
35import Control.Monad.Writer
40import Control.Monad.Writer
36import Control.Monad.State
41import Control.Monad.State
42+import Control.Monad.Error
38import qualified System.Info as SI (arch, os)
44import qualified System.Info as SI (arch, os)
39import System.IO
45import System.IO
@@ -43,28 +49,46 @@ import System.Process (rawSystem)
43import System.Exit (ExitCode(..))
49import System.Exit (ExitCode(..))
44import Debug.Trace
50import Debug.Trace
46−data Target = Target { arch :: String, os :: String }
52+data Target = Target { triple :: String, dataLayout :: DataLayout }
48codegenLLVM :: [(TT.Name, SDecl)] ->
54codegenLLVM :: [(TT.Name, SDecl)] ->
55+ String -> -- target triple
56+ String -> -- target CPU
57+ Int -> -- Optimization degree
49 FilePath -> -- output file name
58 FilePath -> -- output file name
50 OutputType ->
59 OutputType ->
52−codegenLLVM defs file outty = withContext $ \context -> do
61+codegenLLVM defs triple cpu optimize file outty = withContext $ \context -> do
53− let target = Target { arch = SI.arch, os = SI.os }
62+ initializeAllTargets
63+ (target, _) <- failInIO $ lookupTarget Nothing triple
64+ withTargetOptions $ \options ->
65+ withTargetMachine target triple cpu S.empty options R.Default CM.Default CGO.Default $ \tm ->
66+ do layout <- getTargetMachineDataLayout tm
54− let ast = codegen target (map snd defs)
67+ let ast = codegen (Target triple layout) (map snd defs)
55− result <- M.withModuleFromAST context ast (outputModule file outty)
68+ result <- runErrorT . M.withModuleFromAST context ast $ \m ->
69+ do let opts = defaultCuratedPassSetSpec
70+ { optLevel = Just optimize
71+ , simplifyLibCalls = Just True
72+ , useInlinerWithThreshold = Just 225
74+ when (optimize /= 0) $ withPassManager opts $ void . flip runPassManager m
75+ outputModule tm file outty m
56− case result of
76+ case result of
57− Right _ -> return ()
77+ Right _ -> return ()
58− Left msg -> ierror msg
78+ Left msg -> ierror msg
80+failInIO :: ErrorT String IO a -> IO a
81+failInIO = either fail return <=< runErrorT
83+itWidth :: IntTy -> Word32
85+itWidth x = fromIntegral $ intTyWidth x
60−outputModule :: FilePath -> OutputType -> M.Module -> IO ()
87+outputModule :: TargetMachine -> FilePath -> OutputType -> M.Module -> IO ()
61−outputModule file Raw m = M.writeBitcodeToFile file m
88+outputModule _ file Raw m = failInIO $ M.writeBitcodeToFile file m
62−outputModule file Object m = withTmpFile $ \bc -> do
89+outputModule tm file Object m = failInIO $ M.writeObjectToFile tm file m
63− outputModule bc Raw m
64− exit <- rawSystem "llc" ["-filetype=obj", "--disable-fp-elim", "-o", file, bc]
65− when (exit /= ExitSuccess) $ ierror "FAILURE: Object generation"
66−outputModule file Executable m = withTmpFile $ \obj -> do
90+outputModule tm file Executable m = withTmpFile $ \obj -> do
67− outputModule obj Object m
91+ outputModule tm obj Object m
68 cc <- getCC
92 cc <- getCC
69 defs <- (</> "llvm" </> "libidris_rts.a") <$> getDataDir
93 defs <- (</> "llvm" </> "libidris_rts.a") <$> getDataDir
70 exit <- rawSystem cc [obj, defs, "-lm", "-lgmp", "-lgc", "-o", file]
94 exit <- rawSystem cc [obj, defs, "-lm", "-lgmp", "-lgc", "-o", file]
@@ -125,10 +149,10 @@ initDefs tgt =
126 , rtsFun "intStr" ptrI8 [IntegerType 64]
150 , rtsFun "intStr" ptrI8 [IntegerType 64]
127 [ BasicBlock (UnName 0)
151 [ BasicBlock (UnName 0)
128− [ UnName 1 := simpleCall "GC_malloc_atomic" [ConstantOperand (C.Int (fromInteger $ tgtWordSize tgt) 21)]
152+ [ UnName 1 := simpleCall "GC_malloc_atomic" [ConstantOperand (C.Int (tgtWordSize tgt) 21)]
129 , UnName 2 := simpleCall "snprintf"
153 , UnName 2 := simpleCall "snprintf"
130 [ LocalReference (UnName 1)
154 [ LocalReference (UnName 1)
131− , ConstantOperand (C.Int (fromInteger $ tgtWordSize tgt) 21)
155+ , ConstantOperand (C.Int (tgtWordSize tgt) 21)
132 , ConstantOperand $ C.GetElementPtr True (C.GlobalReference . Name $ "__idris_intFmtStr") [C.Int 32 0, C.Int 32 0]
156 , ConstantOperand $ C.GetElementPtr True (C.GlobalReference . Name $ "__idris_intFmtStr") [C.Int 32 0, C.Int 32 0]
133 , LocalReference (UnName 0)
157 , LocalReference (UnName 0)
@@ -136,10 +160,12 @@ initDefs tgt =
136 (Do $ Ret (Just (LocalReference (UnName 1))) [])
160 (Do $ Ret (Just (LocalReference (UnName 1))) [])
138 , exfun "llvm.trap" VoidType [] False
162 , exfun "llvm.trap" VoidType [] False
163+ -- , exfun "llvm.llvm.memcpy.p0i8.p0i8.i32" VoidType [ptrI8, ptrI8, IntegerType 32, IntegerType 32, IntegerType 1] False
164+ -- , exfun "llvm.llvm.memcpy.p0i8.p0i8.i64" VoidType [ptrI8, ptrI8, IntegerType 64, IntegerType 32, IntegerType 1] False
165+ , exfun "memcpy" ptrI8 [ptrI8, ptrI8, intPtr] False
139 , exfun "snprintf" (IntegerType 32) [ptrI8, intPtr, ptrI8] True
166 , exfun "snprintf" (IntegerType 32) [ptrI8, intPtr, ptrI8] True
140 , exfun "strcmp" (IntegerType 32) [ptrI8, ptrI8] False
167 , exfun "strcmp" (IntegerType 32) [ptrI8, ptrI8] False
141 , exfun "strlen" intPtr [ptrI8] False
168 , exfun "strlen" intPtr [ptrI8] False
142− , exfun "memcpy" ptrI8 [ptrI8, ptrI8, intPtr] False
143 , exfun "GC_init" VoidType [] False
169 , exfun "GC_init" VoidType [] False
144 , exfun "GC_malloc" ptrI8 [intPtr] False
170 , exfun "GC_malloc" ptrI8 [intPtr] False
145 , exfun "GC_malloc_atomic" ptrI8 [intPtr] False
171 , exfun "GC_malloc_atomic" ptrI8 [intPtr] False
@@ -167,7 +193,7 @@ initDefs tgt =
167 , GlobalDefinition mainDef
193 , GlobalDefinition mainDef
168 ] ++ map mpzBinFun ["add", "sub", "mul", "fdiv_q", "fdiv_r", "and", "ior", "xor"]
194 ] ++ map mpzBinFun ["add", "sub", "mul", "fdiv_q", "fdiv_r", "and", "ior", "xor"]
170− intPtr = IntegerType (fromInteger $ tgtWordSize tgt)
196+ intPtr = IntegerType (tgtWordSize tgt)
171 ptrI8 = PointerType (IntegerType 8) (AddrSpace 0)
197 ptrI8 = PointerType (IntegerType 8) (AddrSpace 0)
172 pmpz = PointerType mpzTy (AddrSpace 0)
198 pmpz = PointerType mpzTy (AddrSpace 0)
@@ -193,18 +219,24 @@ initDefs tgt =
193 exVar :: String -> Type -> Definition
219 exVar :: String -> Type -> Definition
194 exVar name ty = GlobalDefinition $ globalVariableDefaults { G.name = Name name, G.type' = ty }
220 exVar name ty = GlobalDefinition $ globalVariableDefaults { G.name = Name name, G.type' = ty }
196− stdinName :: Target -> String
222+isApple :: Target -> Bool
197− stdinName (Target { os = "darwin" }) = "__stdinp"
223+isApple (Target { triple = t }) = isJust . stripPrefix "-apple" $ dropWhile (/= '-') t
225+stdinName, stdoutName, stderrName :: Target -> String
226+stdinName t | isApple t = "__stdinp"
198− stdinName _ = "stdin"
227+stdinName _ = "stdin"
199− stdoutName :: Target -> String
228+stdoutName t | isApple t = "__stdoutp"
200− stdoutName (Target { os = "darwin" }) = "__stdoutp"
201− stdoutName _ = "stdout"
229+stdoutName _ = "stdout"
202− stderrName :: Target -> String
230+stderrName t | isApple t = "__stderrp"
203− stderrName (Target { os = "darwin" }) = "__stderrp"
204− stderrName _ = "stderr"
231+stderrName _ = "stderr"
233+getStdIn, getStdOut, getStdErr :: Codegen Operand
234+getStdIn = ConstantOperand . C.GlobalReference . Name . stdinName <$> asks target
235+getStdOut = ConstantOperand . C.GlobalReference . Name . stdoutName <$> asks target
236+getStdErr = ConstantOperand . C.GlobalReference . Name . stderrName <$> asks target
206codegen :: Target -> [SDecl] -> Module
238codegen :: Target -> [SDecl] -> Module
207−codegen tgt defs = Module "idris" Nothing Nothing (initDefs tgt ++ globals ++ gendefs)
239+codegen tgt defs = Module "idris" (Just . dataLayout $ tgt) (Just . triple $ tgt) (initDefs tgt ++ globals ++ gendefs)
209 (gendefs, _, globals) = runRWS (mapM cgDef defs) tgt 0
241 (gendefs, _, globals) = runRWS (mapM cgDef defs) tgt 0
@@ -363,13 +395,13 @@ alloc ty = do
363sizeOf :: Type -> Codegen Operand
395sizeOf :: Type -> Codegen Operand
364sizeOf ty = ConstantOperand . C.PtrToInt
396sizeOf ty = ConstantOperand . C.PtrToInt
365 (C.GetElementPtr True (C.Null (PointerType ty (AddrSpace 0))) [C.Int 32 1])
397 (C.GetElementPtr True (C.Null (PointerType ty (AddrSpace 0))) [C.Int 32 1])
366− . IntegerType . fromIntegral <$> getWordSize
398+ . IntegerType <$> getWordSize
368−tgtWordSize :: Target -> Integer
400+tgtWordSize :: Target -> Word32
369−tgtWordSize (Target { arch = "i386" }) = 32
401+tgtWordSize (Target { dataLayout = DataLayout { pointerLayouts = l } }) =
370−tgtWordSize (Target { arch = "x86_64" }) = 64
402+ fst . fromJust $ M.lookup (AddrSpace 0) l
372−getWordSize :: Codegen Integer
404+getWordSize :: Codegen Word32
373getWordSize = tgtWordSize <$> asks target
405getWordSize = tgtWordSize <$> asks target
375cgExpr :: SExp -> Codegen (Maybe Operand)
407cgExpr :: SExp -> Codegen (Maybe Operand)
@@ -554,7 +586,7 @@ cgChainCase :: Operand -> Maybe SExp -> [SAlt] -> Codegen (Maybe Operand)
554cgChainCase caseValPtr defExp alts = do
586cgChainCase caseValPtr defExp alts = do
555 let (caseTy, comparator) =
587 let (caseTy, comparator) =
556 case head alts of
588 case head alts of
557− SConstCase (TT.BI _) _ -> (FArith (ATInt ITBig), "__gmpz_cmp")
589+ SConstCase (TT.BI _) _ -> (FInt ITBig, "__gmpz_cmp")
558 SConstCase (TT.Str _) _ -> (FString, "strcmp")
590 SConstCase (TT.Str _) _ -> (FString, "strcmp")
559 caseVal <- unbox caseTy caseValPtr
591 caseVal <- unbox caseTy caseValPtr
560 defBlockName <- getName "default"
592 defBlockName <- getName "default"
@@ -680,11 +712,6 @@ cgConst' (TT.B8 i) = C.Int 8 (fromIntegral i)
680cgConst' (TT.B16 i) = C.Int 16 (fromIntegral i)
712cgConst' (TT.B16 i) = C.Int 16 (fromIntegral i)
681cgConst' (TT.B32 i) = C.Int 32 (fromIntegral i)
713cgConst' (TT.B32 i) = C.Int 32 (fromIntegral i)
682cgConst' (TT.B64 i) = C.Int 64 (fromIntegral i)
714cgConst' (TT.B64 i) = C.Int 64 (fromIntegral i)
683−cgConst' (TT.B8V v) = C.Vector (map ((C.Int 8) . fromIntegral) . V.toList $ v)
684−cgConst' (TT.B16V v) = C.Vector (map ((C.Int 16) . fromIntegral) . V.toList $ v)
685−cgConst' (TT.B32V v) = C.Vector (map ((C.Int 32) . fromIntegral) . V.toList $ v)
686−cgConst' (TT.B64V v) = C.Vector (map ((C.Int 64) . fromIntegral) . V.toList $ v)
688cgConst' (TT.BI i) = C.Array (IntegerType 8) (map (C.Int 8 . fromIntegral . fromEnum) (show i) ++ [C.Int 8 0])
715cgConst' (TT.BI i) = C.Array (IntegerType 8) (map (C.Int 8 . fromIntegral . fromEnum) (show i) ++ [C.Int 8 0])
689cgConst' (TT.Fl f) = C.Float (F.Double f)
716cgConst' (TT.Fl f) = C.Float (F.Double f)
690cgConst' (TT.Ch c) = C.Int 32 . fromIntegral . fromEnum $ c
717cgConst' (TT.Ch c) = C.Int 32 . fromIntegral . fromEnum $ c
@@ -692,16 +719,12 @@ cgConst' (TT.Str s) = C.Array (IntegerType 8) (map (C.Int 8 . fromIntegral . fro
692cgConst' x = ierror $ "Unsupported constant: " ++ show x
719cgConst' x = ierror $ "Unsupported constant: " ++ show x
694cgConst :: TT.Const -> Codegen Operand
721cgConst :: TT.Const -> Codegen Operand
695−cgConst c@(TT.I _) = box (FArith (ATInt ITNative)) (ConstantOperand $ cgConst' c)
722+cgConst c@(TT.I _) = box (FInt ITNative) (ConstantOperand $ cgConst' c)
696−cgConst c@(TT.B8 _) = box (FArith (ATInt (ITFixed IT8))) (ConstantOperand $ cgConst' c)
723+cgConst c@(TT.B8 _) = box (FInt IT8) (ConstantOperand $ cgConst' c)
697−cgConst c@(TT.B16 _) = box (FArith (ATInt (ITFixed IT16))) (ConstantOperand $ cgConst' c)
724+cgConst c@(TT.B16 _) = box (FInt IT16) (ConstantOperand $ cgConst' c)
698−cgConst c@(TT.B32 _) = box (FArith (ATInt (ITFixed IT32))) (ConstantOperand $ cgConst' c)
725+cgConst c@(TT.B32 _) = box (FInt IT32) (ConstantOperand $ cgConst' c)
699−cgConst c@(TT.B64 _) = box (FArith (ATInt (ITFixed IT64))) (ConstantOperand $ cgConst' c)
700−cgConst c@(TT.B8V v) = box (FArith (ATInt (ITVec IT8 (V.length v)))) (ConstantOperand $ cgConst' c)
701−cgConst c@(TT.B16V v) = box (FArith (ATInt (ITVec IT16 (V.length v)))) (ConstantOperand $ cgConst' c)
702−cgConst c@(TT.B32V v) = box (FArith (ATInt (ITVec IT32 (V.length v)))) (ConstantOperand $ cgConst' c)
703−cgConst c@(TT.B64V v) = box (FArith (ATInt (ITVec IT64 (V.length v)))) (ConstantOperand $ cgConst' c)
726+cgConst c@(TT.B64 _) = box (FInt IT64) (ConstantOperand $ cgConst' c)
704−cgConst c@(TT.Fl _) = box (FArith ATFloat) (ConstantOperand $ cgConst' c)
727+cgConst c@(TT.Fl _) = box FDouble (ConstantOperand $ cgConst' c)
705cgConst c@(TT.Ch _) = box FChar (ConstantOperand $ cgConst' c)
728cgConst c@(TT.Ch _) = box FChar (ConstantOperand $ cgConst' c)
706cgConst c@(TT.Str s) = do
729cgConst c@(TT.Str s) = do
707 str <- addGlobal' (ArrayType (1 + fromIntegral (length s)) (IntegerType 8)) (cgConst' c)
730 str <- addGlobal' (ArrayType (1 + fromIntegral (length s)) (IntegerType 8)) (cgConst' c)
@@ -713,7 +736,7 @@ cgConst c@(TT.BI i) = do
713 , ConstantOperand $ C.GetElementPtr True str [ C.Int 32 0, C.Int 32 0]
736 , ConstantOperand $ C.GetElementPtr True str [ C.Int 32 0, C.Int 32 0]
714 , ConstantOperand $ C.Int 32 10
737 , ConstantOperand $ C.Int 32 10
716− box (FArith (ATInt ITBig)) mpz
739+ box (FInt ITBig) mpz
717cgConst x = return $ ConstantOperand nullValue
740cgConst x = return $ ConstantOperand nullValue
719numDigits :: Integer -> Integer -> Integer
742numDigits :: Integer -> Integer -> Integer
@@ -759,82 +782,72 @@ ffunDecl name rty argtys =
761ftyToTy :: FType -> Type
784ftyToTy :: FType -> Type
762−ftyToTy (FArith (ATInt ITNative)) = IntegerType 32
785+ftyToTy (FInt ITNative) = IntegerType 32
763−ftyToTy (FArith (ATInt ITBig)) = PointerType mpzTy (AddrSpace 0)
786+ftyToTy (FInt ITBig) = PointerType mpzTy (AddrSpace 0)
764−ftyToTy (FArith (ATInt (ITFixed ty))) = IntegerType (fromIntegral $ nativeTyWidth ty)
787+ftyToTy (FInt ty) = IntegerType (itWidth ty)
765−ftyToTy (FArith (ATInt (ITVec e c)))
766− = VectorType (fromIntegral c) (IntegerType (fromIntegral $ nativeTyWidth e))
767ftyToTy FChar = IntegerType 32
788ftyToTy FChar = IntegerType 32
768ftyToTy FString = PointerType (IntegerType 8) (AddrSpace 0)
789ftyToTy FString = PointerType (IntegerType 8) (AddrSpace 0)
769ftyToTy FUnit = VoidType
790ftyToTy FUnit = VoidType
770ftyToTy FPtr = PointerType (IntegerType 8) (AddrSpace 0)
791ftyToTy FPtr = PointerType (IntegerType 8) (AddrSpace 0)
771−ftyToTy (FArith ATFloat) = FloatingPointType 64 IEEE
792+ftyToTy FDouble = FloatingPointType 64 IEEE
772ftyToTy FAny = valueType
793ftyToTy FAny = valueType
774−-- Only use when known not to be ITBig
775−itWidth :: IntTy -> Word32
776−itWidth ITNative = 32
777−itWidth (ITFixed x) = fromIntegral $ nativeTyWidth x
779cgOp :: PrimFn -> [Operand] -> Codegen Operand
795cgOp :: PrimFn -> [Operand] -> Codegen Operand
780cgOp (LTrunc ITBig ity) [x] = do
796cgOp (LTrunc ITBig ity) [x] = do
781− nx <- unbox (FArith (ATInt ITBig)) x
797+ nx <- unbox (FInt ITBig) x
782 val <- inst $ simpleCall "mpz_get_ull" [nx]
798 val <- inst $ simpleCall "mpz_get_ull" [nx]
783 v <- case ity of
799 v <- case ity of
784− (ITFixed IT64) -> return val
800+ IT64 -> return val
785− _ -> inst $ Trunc val (ftyToTy (FArith (ATInt ity))) []
801+ _ -> inst $ Trunc val (IntegerType $ itWidth ity) []
786− box (FArith (ATInt ity)) v
802+ box (FInt ity) v
787cgOp (LZExt from ITBig) [x] = do
803cgOp (LZExt from ITBig) [x] = do
788− nx <- unbox (FArith (ATInt from)) x
804+ nx <- unbox (FInt from) x
789 nx' <- case from of
805 nx' <- case from of
790− (ITFixed IT64) -> return nx
806+ IT64 -> return nx
791 _ -> inst $ ZExt nx (IntegerType 64) []
807 _ -> inst $ ZExt nx (IntegerType 64) []
792 mpz <- alloc mpzTy
808 mpz <- alloc mpzTy
793 inst' $ simpleCall "mpz_init_set_ull" [mpz, nx']
809 inst' $ simpleCall "mpz_init_set_ull" [mpz, nx']
794− box (FArith (ATInt ITBig)) mpz
810+ box (FInt ITBig) mpz
795cgOp (LSExt from ITBig) [x] = do
811cgOp (LSExt from ITBig) [x] = do
796− nx <- unbox (FArith (ATInt from)) x
812+ nx <- unbox (FInt from) x
797 nx' <- case from of
813 nx' <- case from of
798− (ITFixed IT64) -> return nx
814+ IT64 -> return nx
799 _ -> inst $ SExt nx (IntegerType 64) []
815 _ -> inst $ SExt nx (IntegerType 64) []
800 mpz <- alloc mpzTy
816 mpz <- alloc mpzTy
801 inst' $ simpleCall "mpz_init_set_sll" [mpz, nx']
817 inst' $ simpleCall "mpz_init_set_sll" [mpz, nx']
802− box (FArith (ATInt ITBig)) mpz
818+ box (FInt ITBig) mpz
804−cgOp (LLt (ATInt ITBig)) [x,y] = mpzCmp IPred.SLT x y
820+cgOp (LLt ITBig) [x,y] = mpzCmp IPred.SLT x y
805−cgOp (LLe (ATInt ITBig)) [x,y] = mpzCmp IPred.SLE x y
821+cgOp (LLe ITBig) [x,y] = mpzCmp IPred.SLE x y
806−cgOp (LEq (ATInt ITBig)) [x,y] = mpzCmp IPred.EQ x y
822+cgOp (LEq ITBig) [x,y] = mpzCmp IPred.EQ x y
807−cgOp (LGe (ATInt ITBig)) [x,y] = mpzCmp IPred.SGE x y
823+cgOp (LGe ITBig) [x,y] = mpzCmp IPred.SGE x y
808−cgOp (LGt (ATInt ITBig)) [x,y] = mpzCmp IPred.SGT x y
824+cgOp (LGt ITBig) [x,y] = mpzCmp IPred.SGT x y
809−cgOp (LPlus (ATInt ITBig)) [x,y] = mpzBin "add" x y
825+cgOp (LPlus ITBig) [x,y] = mpzBin "add" x y
810−cgOp (LMinus (ATInt ITBig)) [x,y] = mpzBin "sub" x y
826+cgOp (LMinus ITBig) [x,y] = mpzBin "sub" x y
811−cgOp (LTimes (ATInt ITBig)) [x,y] = mpzBin "mul" x y
827+cgOp (LTimes ITBig) [x,y] = mpzBin "mul" x y
812−cgOp (LSDiv (ATInt ITBig)) [x,y] = mpzBin "fdiv_q" x y
828+cgOp (LSDiv ITBig) [x,y] = mpzBin "fdiv_q" x y
813−cgOp (LSRem (ATInt ITBig)) [x,y] = mpzBin "fdiv_r" x y
829+cgOp (LSRem ITBig) [x,y] = mpzBin "fdiv_r" x y
814cgOp (LAnd ITBig) [x,y] = mpzBin "and" x y
830cgOp (LAnd ITBig) [x,y] = mpzBin "and" x y
815cgOp (LOr ITBig) [x,y] = mpzBin "ior" x y
831cgOp (LOr ITBig) [x,y] = mpzBin "ior" x y
816cgOp (LXOr ITBig) [x,y] = mpzBin "xor" x y
832cgOp (LXOr ITBig) [x,y] = mpzBin "xor" x y
817cgOp (LCompl ITBig) [x] = mpzUn "com" x
833cgOp (LCompl ITBig) [x] = mpzUn "com" x
819−cgOp (LTrunc (ITFixed from) (ITFixed to)) [x]
820− | nativeTyWidth from > nativeTyWidth to = iCoerce Trunc from to x
835+cgOp (LTrunc from to) [x] | itWidth from > itWidth to = iCoerce Trunc from to x
821−cgOp (LZExt (ITFixed from) (ITFixed to)) [x]
822− | nativeTyWidth from < nativeTyWidth to = iCoerce ZExt from to x
836+cgOp (LZExt from to) [x] | itWidth from < itWidth to = iCoerce ZExt from to x
823−cgOp (LSExt (ITFixed from) (ITFixed to)) [x]
824− | nativeTyWidth from < nativeTyWidth to = iCoerce SExt from to x
837+cgOp (LSExt from to) [x] | itWidth from < itWidth to = iCoerce SExt from to x
826−cgOp (LLt (ATInt ity)) [x,y] = iCmp ity IPred.SLT x y
839+cgOp (LLt ity) [x,y] = iCmp ity IPred.SLT x y
827−cgOp (LLe (ATInt ity)) [x,y] = iCmp ity IPred.SLE x y
840+cgOp (LLe ity) [x,y] = iCmp ity IPred.SLE x y
828−cgOp (LEq (ATInt ity)) [x,y] = iCmp ity IPred.EQ x y
841+cgOp (LEq ity) [x,y] = iCmp ity IPred.EQ x y
829−cgOp (LGe (ATInt ity)) [x,y] = iCmp ity IPred.SGE x y
842+cgOp (LGe ity) [x,y] = iCmp ity IPred.SGE x y
830−cgOp (LGt (ATInt ity)) [x,y] = iCmp ity IPred.SGT x y
843+cgOp (LGt ity) [x,y] = iCmp ity IPred.SGT x y
831−cgOp (LPlus (ATInt ity)) [x,y] = ibin ity x y (Add False False)
844+cgOp (LPlus ity) [x,y] = ibin ity x y (Add False False)
832−cgOp (LMinus (ATInt ity)) [x,y] = ibin ity x y (Sub False False)
845+cgOp (LMinus ity) [x,y] = ibin ity x y (Sub False False)
833−cgOp (LTimes (ATInt ity)) [x,y] = ibin ity x y (Mul False False)
846+cgOp (LTimes ity) [x,y] = ibin ity x y (Mul False False)
834−cgOp (LSDiv (ATInt ity)) [x,y] = ibin ity x y (SDiv False)
835−cgOp (LSRem (ATInt ity)) [x,y] = ibin ity x y SRem
836cgOp (LUDiv ity) [x,y] = ibin ity x y (UDiv False)
847cgOp (LUDiv ity) [x,y] = ibin ity x y (UDiv False)
837cgOp (LURem ity) [x,y] = ibin ity x y URem
848cgOp (LURem ity) [x,y] = ibin ity x y URem
849+cgOp (LSDiv ity) [x,y] = ibin ity x y (SDiv False)
850+cgOp (LSRem ity) [x,y] = ibin ity x y SRem
838cgOp (LAnd ity) [x,y] = ibin ity x y And
851cgOp (LAnd ity) [x,y] = ibin ity x y And
839cgOp (LOr ity) [x,y] = ibin ity x y Or
852cgOp (LOr ity) [x,y] = ibin ity x y Or
840cgOp (LXOr ity) [x,y] = ibin ity x y Xor
853cgOp (LXOr ity) [x,y] = ibin ity x y Xor
@@ -843,26 +856,7 @@ cgOp (LSHL ity) [x,y] = ibin ity x y (Shl False False)
843cgOp (LLSHR ity) [x,y] = ibin ity x y (LShr False)
856cgOp (LLSHR ity) [x,y] = ibin ity x y (LShr False)
844cgOp (LASHR ity) [x,y] = ibin ity x y (AShr False)
857cgOp (LASHR ity) [x,y] = ibin ity x y (AShr False)
846−cgOp (LMkVec ety c) xs | c == length xs = do
859+cgOp LNoOp xs = return $ last xs
847− nxs <- mapM (unbox (FArith (ATInt (ITFixed ety)))) xs
848− vec <- foldM (\v (e, i) -> inst $ InsertElement v e (ConstantOperand (C.Int 32 i)) [])
849− (ConstantOperand $ C.Vector (replicate c (C.Undef (IntegerType . fromIntegral $ nativeTyWidth ety))))
851− box (FArith (ATInt (ITVec ety c))) vec
853−cgOp (LIdxVec ety c) [v,i] = do
854− nv <- unbox (FArith (ATInt (ITVec ety c))) v
855− ni <- unbox (FArith (ATInt (ITFixed IT32))) i
856− elt <- inst $ ExtractElement nv ni []
857− box (FArith (ATInt (ITFixed ety))) elt
859−cgOp (LUpdateVec ety c) [v,i,e] = do
860− let fty = FArith (ATInt (ITVec ety c))
862− ni <- unbox (FArith (ATInt (ITFixed IT32))) i
863− ne <- unbox (FArith (ATInt (ITFixed ety))) e
864− nv' <- inst $ InsertElement nv ne ni []
867cgOp LStrEq [x,y] = do
861cgOp LStrEq [x,y] = do
868 x' <- unbox FString x
862 x' <- unbox FString x
@@ -870,7 +864,7 @@ cgOp LStrEq [x,y] = do
870 cmp <- inst $ simpleCall "strcmp" [x', y']
864 cmp <- inst $ simpleCall "strcmp" [x', y']
871 flag <- inst $ ICmp IPred.EQ cmp (ConstantOperand (C.Int 32 0)) []
865 flag <- inst $ ICmp IPred.EQ cmp (ConstantOperand (C.Int 32 0)) []
872 val <- inst $ ZExt flag (IntegerType 32) []
866 val <- inst $ ZExt flag (IntegerType 32) []
873− box (FArith (ATInt (ITFixed IT32))) val
867+ box (FInt IT32) val
875cgOp LStrLt [x,y] = do
869cgOp LStrLt [x,y] = do
876 nx <- unbox FString x
870 nx <- unbox FString x
@@ -878,10 +872,10 @@ cgOp LStrLt [x,y] = do
878 cmp <- inst $ simpleCall "strcmp" [nx, ny]
872 cmp <- inst $ simpleCall "strcmp" [nx, ny]
879 flag <- inst $ ICmp IPred.ULT cmp (ConstantOperand (C.Int 32 0)) []
873 flag <- inst $ ICmp IPred.ULT cmp (ConstantOperand (C.Int 32 0)) []
880 val <- inst $ ZExt flag (IntegerType 32) []
874 val <- inst $ ZExt flag (IntegerType 32) []
881− box (FArith (ATInt (ITFixed IT32))) val
875+ box (FInt IT32) val
883cgOp (LIntStr ITBig) [x] = do
877cgOp (LIntStr ITBig) [x] = do
884− x' <- unbox (FArith (ATInt ITBig)) x
878+ x' <- unbox (FInt ITBig) x
885 ustr <- inst $ simpleCall "__gmpz_get_str"
879 ustr <- inst $ simpleCall "__gmpz_get_str"
886 [ ConstantOperand (C.Null (PointerType (IntegerType 8) (AddrSpace 0)))
880 [ ConstantOperand (C.Null (PointerType (IntegerType 8) (AddrSpace 0)))
887 , ConstantOperand (C.Int 32 10)
881 , ConstantOperand (C.Int 32 10)
@@ -889,7 +883,7 @@ cgOp (LIntStr ITBig) [x] = do
890 box FString ustr
884 box FString ustr
891cgOp (LIntStr ity) [x] = do
885cgOp (LIntStr ity) [x] = do
892− x' <- unbox (FArith (ATInt ity)) x
886+ x' <- unbox (FInt ity) x
893 x'' <- if itWidth ity < 64
887 x'' <- if itWidth ity < 64
894 then inst $ SExt x' (IntegerType 64) []
888 then inst $ SExt x' (IntegerType 64) []
895 else return x'
889 else return x'
@@ -898,7 +892,7 @@ cgOp (LStrInt ITBig) [s] = do
898 ns <- unbox FString s
892 ns <- unbox FString s
899 mpz <- alloc mpzTy
893 mpz <- alloc mpzTy
900 inst $ simpleCall "__gmpz_init_set_str" [mpz, ns, ConstantOperand $ C.Int 32 10]
894 inst $ simpleCall "__gmpz_init_set_str" [mpz, ns, ConstantOperand $ C.Int 32 10]
901− box (FArith (ATInt ITBig)) mpz
895+ box (FInt ITBig) mpz
902cgOp (LStrInt ity) [s] = do
896cgOp (LStrInt ity) [s] = do
903 ns <- unbox FString s
897 ns <- unbox FString s
904 nx <- inst $ simpleCall "strtoll"
898 nx <- inst $ simpleCall "strtoll"
@@ -907,9 +901,9 @@ cgOp (LStrInt ity) [s] = do
907 , ConstantOperand $ C.Int 32 10
901 , ConstantOperand $ C.Int 32 10
909 nx' <- case ity of
903 nx' <- case ity of
910− (ITFixed IT64) -> return nx
904+ IT64 -> return nx
911 _ -> inst $ Trunc nx (IntegerType (itWidth ity)) []
905 _ -> inst $ Trunc nx (IntegerType (itWidth ity)) []
912− box (FArith (ATInt ity)) nx'
906+ box (FInt ity) nx'
914cgOp LStrConcat [x,y] = cgStrCat x y
908cgOp LStrConcat [x,y] = cgStrCat x y
@@ -928,7 +922,7 @@ cgOp LStrHead [c] = do
929cgOp LStrIndex [s, i] = do
923cgOp LStrIndex [s, i] = do
930 ns <- unbox FString s
924 ns <- unbox FString s
931− ni <- unbox (FArith (ATInt (ITFixed IT32))) i
925+ ni <- unbox (FInt IT32) i
932 p <- inst $ GetElementPtr True ns [ni] []
926 p <- inst $ GetElementPtr True ns [ni] []
933 c <- inst $ Load False p Nothing 0 []
927 c <- inst $ Load False p Nothing 0 []
934 c' <- inst $ ZExt c (IntegerType 32) []
928 c' <- inst $ ZExt c (IntegerType 32) []
@@ -945,9 +939,9 @@ cgOp LStrLen [s] = do
945 ws <- getWordSize
939 ws <- getWordSize
946 len' <- case ws of
940 len' <- case ws of
947 32 -> return len
941 32 -> return len
948− x | x > 32 -> inst $ Trunc len (IntegerType $ fromInteger x) []
942+ x | x > 32 -> inst $ Trunc len (IntegerType 32) []
949− | x < 32 -> inst $ ZExt len (IntegerType $ fromInteger x) []
943+ | x < 32 -> inst $ ZExt len (IntegerType 32) []
950− box (FArith (ATInt (ITFixed IT32))) len'
944+ box (FInt IT32) len'
952cgOp LReadStr [p] = do
946cgOp LReadStr [p] = do
953 np <- unbox FPtr p
947 np <- unbox FPtr p
@@ -955,24 +949,26 @@ cgOp LReadStr [p] = do
955 box FString s
949 box FString s
957cgOp LStdIn [] = do
951cgOp LStdIn [] = do
958− ptr <- inst $ Load False (ConstantOperand . C.GlobalReference . Name $ "stdin") Nothing 0 []
953+ ptr <- inst $ Load False stdin Nothing 0 []
959 box FPtr ptr
954 box FPtr ptr
960cgOp LStdOut [] = do
955cgOp LStdOut [] = do
961− ptr <- inst $ Load False (ConstantOperand . C.GlobalReference . Name $ "stdout") Nothing 0 []
957+ ptr <- inst $ Load False stdout Nothing 0 []
962 box FPtr ptr
958 box FPtr ptr
963cgOp LStdErr [] = do
959cgOp LStdErr [] = do
964− ptr <- inst $ Load False (ConstantOperand . C.GlobalReference . Name $ "stderr") Nothing 0 []
961+ ptr <- inst $ Load False stdErr Nothing 0 []
965 box FPtr ptr
962 box FPtr ptr
968cgOp prim args = ierror $ "Unimplemented primitive: [" ++ show prim ++ "]("
964cgOp prim args = ierror $ "Unimplemented primitive: [" ++ show prim ++ "]("
969 ++ intersperse ',' (take (length args) ['a'..]) ++ ")"
965 ++ intersperse ',' (take (length args) ['a'..]) ++ ")"
971−iCoerce :: (Operand -> Type -> InstructionMetadata -> Instruction) -> NativeTy -> NativeTy -> Operand -> Codegen Operand
967+iCoerce :: (Operand -> Type -> InstructionMetadata -> Instruction) -> IntTy -> IntTy -> Operand -> Codegen Operand
972iCoerce operator from to x = do
968iCoerce operator from to x = do
973− x' <- unbox (FArith (ATInt (ITFixed from))) x
969+ x' <- unbox (FInt from) x
974− x'' <- inst $ operator x' (ftyToTy (FArith (ATInt (ITFixed from)))) []
970+ x'' <- inst $ operator x' (IntegerType $ itWidth to) []
975− box (FArith (ATInt (ITFixed to))) x''
971+ box (FInt to) x''
977cgStrCat :: Operand -> Operand -> Codegen Operand
973cgStrCat :: Operand -> Operand -> Codegen Operand
978cgStrCat x y = do
974cgStrCat x y = do
@@ -981,7 +977,7 @@ cgStrCat x y = do
981 xlen <- inst $ simpleCall "strlen" [x']
977 xlen <- inst $ simpleCall "strlen" [x']
982 ylen <- inst $ simpleCall "strlen" [y']
978 ylen <- inst $ simpleCall "strlen" [y']
983 zlen <- inst $ Add False True xlen ylen []
979 zlen <- inst $ Add False True xlen ylen []
984− ws <- fromIntegral <$> getWordSize
980+ ws <- getWordSize
985 total <- inst $ Add False True zlen (ConstantOperand (C.Int ws 1)) []
981 total <- inst $ Add False True zlen (ConstantOperand (C.Int ws 1)) []
986 mem <- allocAtomic total
982 mem <- allocAtomic total
987 inst $ simpleCall "memcpy" [mem, x', xlen]
983 inst $ simpleCall "memcpy" [mem, x', xlen]
@@ -998,54 +994,50 @@ cgStrCat x y = do
998ibin :: IntTy -> Operand -> Operand
994ibin :: IntTy -> Operand -> Operand
999 -> (Operand -> Operand -> InstructionMetadata -> Instruction) -> Codegen Operand
995 -> (Operand -> Operand -> InstructionMetadata -> Instruction) -> Codegen Operand
1000ibin ity x y instCon = do
996ibin ity x y instCon = do
1001− nx <- unbox (FArith (ATInt ity)) x
997+ nx <- unbox (FInt ity) x
1002− ny <- unbox (FArith (ATInt ity)) y
998+ ny <- unbox (FInt ity) y
1003 nr <- inst $ instCon nx ny []
999 nr <- inst $ instCon nx ny []
1004− box (FArith (ATInt ity)) nr
1000+ box (FInt ity) nr
1006iun :: IntTy -> Operand -> (Operand -> InstructionMetadata -> Instruction) -> Codegen Operand
1002iun :: IntTy -> Operand -> (Operand -> InstructionMetadata -> Instruction) -> Codegen Operand
1007iun ity x instCon = do
1003iun ity x instCon = do
1008− nx <- unbox (FArith (ATInt ity)) x
1004+ nx <- unbox (FInt ity) x
1009 nr <- inst $ instCon nx []
1005 nr <- inst $ instCon nx []
1010− box (FArith (ATInt ity)) nr
1006+ box (FInt ity) nr
1012iCmp :: IntTy -> IPred.IntegerPredicate -> Operand -> Operand -> Codegen Operand
1008iCmp :: IntTy -> IPred.IntegerPredicate -> Operand -> Operand -> Codegen Operand
1013iCmp ity pred x y = do
1009iCmp ity pred x y = do
1014− nx <- unbox (FArith (ATInt ity)) x
1010+ nx <- unbox (FInt ity) x
1015− ny <- unbox (FArith (ATInt ity)) y
1011+ ny <- unbox (FInt ity) y
1016 nr <- inst $ ICmp pred nx ny []
1012 nr <- inst $ ICmp pred nx ny []
1017− nr' <- inst $ SExt nr (ftyToTy $ cmpResultTy ity) []
1013+ nr' <- inst $ ZExt nr (IntegerType 32) []
1018− box (cmpResultTy ity) nr'
1014+ box (FInt IT32) nr'
1020−cmpResultTy :: IntTy -> FType
1021−cmpResultTy v@(ITVec _ _) = FArith (ATInt v)
1022−cmpResultTy _ = FArith (ATInt (ITFixed IT32))
1024mpzBin :: String -> Operand -> Operand -> Codegen Operand
1016mpzBin :: String -> Operand -> Operand -> Codegen Operand
1025mpzBin name x y = do
1017mpzBin name x y = do
1026− nx <- unbox (FArith (ATInt ITBig)) x
1018+ nx <- unbox (FInt ITBig) x
1027− ny <- unbox (FArith (ATInt ITBig)) y
1019+ ny <- unbox (FInt ITBig) y
1028 nz <- alloc mpzTy
1020 nz <- alloc mpzTy
1029 inst' $ simpleCall "__gmpz_init" [nz]
1021 inst' $ simpleCall "__gmpz_init" [nz]
1030 inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx, ny]
1022 inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx, ny]
1031− box (FArith (ATInt ITBig)) nz
1023+ box (FInt ITBig) nz
1033mpzUn :: String -> Operand -> Codegen Operand
1025mpzUn :: String -> Operand -> Codegen Operand
1034mpzUn name x = do
1026mpzUn name x = do
1035− nx <- unbox (FArith (ATInt ITBig)) x
1027+ nx <- unbox (FInt ITBig) x
1036 nz <- alloc mpzTy
1028 nz <- alloc mpzTy
1037 inst' $ simpleCall "__gmpz_init" [nz]
1029 inst' $ simpleCall "__gmpz_init" [nz]
1038 inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx]
1030 inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx]
1039− box (FArith (ATInt ITBig)) nz
1031+ box (FInt ITBig) nz
1041mpzCmp :: IPred.IntegerPredicate -> Operand -> Operand -> Codegen Operand
1033mpzCmp :: IPred.IntegerPredicate -> Operand -> Operand -> Codegen Operand
1042mpzCmp pred x y = do
1034mpzCmp pred x y = do
1043− nx <- unbox (FArith (ATInt ITBig)) x
1035+ nx <- unbox (FInt ITBig) x
1044− ny <- unbox (FArith (ATInt ITBig)) y
1036+ ny <- unbox (FInt ITBig) y
1045 cmp <- inst $ simpleCall "__gmpz_cmp" [nx, ny]
1037 cmp <- inst $ simpleCall "__gmpz_cmp" [nx, ny]
1046 result <- inst $ ICmp pred cmp (ConstantOperand (C.Int 32 0)) []
1038 result <- inst $ ICmp pred cmp (ConstantOperand (C.Int 32 0)) []
1047 i <- inst $ ZExt result (IntegerType 32) []
1039 i <- inst $ ZExt result (IntegerType 32) []
1048− box (FArith (ATInt (ITFixed IT32))) i
1040+ box (FInt IT32) i
1050simpleCall :: String -> [Operand] -> Instruction
1042simpleCall :: String -> [Operand] -> Instruction
1051simpleCall name args =
1043simpleCall name args =