@@ -5,7 +5,6 @@ import IRTS.CodegenCommon
55import IRTS.Lang
66import IRTS.Simplified
77import qualified Core.TT as TT
8−import Core.TT (ArithTy(..), IntTy(..), NativeTy(..), nativeTyWidth)
98
109import Util.System
1110import Paths_idris
@@ -14,6 +13,9 @@ import LLVM.General.Context
1413import LLVM.General.Diagnostic
1514import LLVM.General.AST
1615import LLVM.General.AST.AddrSpace
16+import LLVM.General.Target
17+import LLVM.General.AST.DataLayout
18+import LLVM.General.PassManager
1719import qualified LLVM.General.Module as M
1820import qualified LLVM.General.AST.IntegerPredicate as IPred
1921import qualified LLVM.General.AST.Linkage as L
@@ -23,17 +25,21 @@ import qualified LLVM.General.AST.Attribute as A
2325import qualified LLVM.General.AST.Global as G
2426import qualified LLVM.General.AST.Constant as C
2527import 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
2631
2732import Data.List
2833import Data.Maybe
2934import Data.Word
3035import Data.Set (Set)
3136import qualified Data.Set as S
32−import qualified Data.Vector.Unboxed as V
37+import qualified Data.Map as M
3338import Control.Applicative
3439import Control.Monad.RWS
3540import Control.Monad.Writer
3641import Control.Monad.State
42+import Control.Monad.Error
3743
3844import qualified System.Info as SI (arch, os)
3945import System.IO
@@ -43,28 +49,46 @@ import System.Process (rawSystem)
4349import System.Exit (ExitCode(..))
4450import Debug.Trace
4551
46−data Target = Target { arch :: String, os :: String }
52+data Target = Target { triple :: String, dataLayout :: DataLayout }
4753
4854codegenLLVM :: [(TT.Name, SDecl)] ->
55+ String -> -- target triple
56+ String -> -- target CPU
57+ Int -> -- Optimization degree
4958 FilePath -> -- output file name
5059 OutputType ->
5160 IO ()
52−codegenLLVM defs file outty = withContext $ \context -> do
53− let target = Target { arch = SI.arch, os = SI.os }
54− let ast = codegen target (map snd defs)
55− result <- M.withModuleFromAST context ast (outputModule file outty)
56− case result of
57− Right _ -> return ()
58− Left msg -> ierror msg
59−
60−outputModule :: FilePath -> OutputType -> M.Module -> IO ()
61−outputModule file Raw m = M.writeBitcodeToFile file m
62−outputModule file Object m = withTmpFile $ \bc -> do
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
67− outputModule obj Object m
61+codegenLLVM defs triple cpu optimize file outty = withContext $ \context -> do
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
67+ let ast = codegen (Target triple layout) (map snd defs)
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
73+ }
74+ when (optimize /= 0) $ withPassManager opts $ void . flip runPassManager m
75+ outputModule tm file outty m
76+ case result of
77+ Right _ -> return ()
78+ Left msg -> ierror msg
79+
80+failInIO :: ErrorT String IO a -> IO a
81+failInIO = either fail return <=< runErrorT
82+
83+itWidth :: IntTy -> Word32
84+itWidth ITNative = 32
85+itWidth x = fromIntegral $ intTyWidth x
86+
87+outputModule :: TargetMachine -> FilePath -> OutputType -> M.Module -> IO ()
88+outputModule _ file Raw m = failInIO $ M.writeBitcodeToFile file m
89+outputModule tm file Object m = failInIO $ M.writeObjectToFile tm file m
90+outputModule tm file Executable m = withTmpFile $ \obj -> do
91+ outputModule tm obj Object m
6892 cc <- getCC
6993 defs <- (</> "llvm" </> "libidris_rts.a") <$> getDataDir
7094 exit <- rawSystem cc [obj, defs, "-lm", "-lgmp", "-lgc", "-o", file]
@@ -125,10 +149,10 @@ initDefs tgt =
125149 }
126150 , rtsFun "intStr" ptrI8 [IntegerType 64]
127151 [ 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)]
129153 , UnName 2 := simpleCall "snprintf"
130154 [ LocalReference (UnName 1)
131− , ConstantOperand (C.Int (fromInteger $ tgtWordSize tgt) 21)
155+ , ConstantOperand (C.Int (tgtWordSize tgt) 21)
132156 , ConstantOperand $ C.GetElementPtr True (C.GlobalReference . Name $ "__idris_intFmtStr") [C.Int 32 0, C.Int 32 0]
133157 , LocalReference (UnName 0)
134158 ]
@@ -136,10 +160,12 @@ initDefs tgt =
136160 (Do $ Ret (Just (LocalReference (UnName 1))) [])
137161 ]
138162 , 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
139166 , exfun "snprintf" (IntegerType 32) [ptrI8, intPtr, ptrI8] True
140167 , exfun "strcmp" (IntegerType 32) [ptrI8, ptrI8] False
141168 , exfun "strlen" intPtr [ptrI8] False
142− , exfun "memcpy" ptrI8 [ptrI8, ptrI8, intPtr] False
143169 , exfun "GC_init" VoidType [] False
144170 , exfun "GC_malloc" ptrI8 [intPtr] False
145171 , exfun "GC_malloc_atomic" ptrI8 [intPtr] False
@@ -167,7 +193,7 @@ initDefs tgt =
167193 , GlobalDefinition mainDef
168194 ] ++ map mpzBinFun ["add", "sub", "mul", "fdiv_q", "fdiv_r", "and", "ior", "xor"]
169195 where
170− intPtr = IntegerType (fromInteger $ tgtWordSize tgt)
196+ intPtr = IntegerType (tgtWordSize tgt)
171197 ptrI8 = PointerType (IntegerType 8) (AddrSpace 0)
172198 pmpz = PointerType mpzTy (AddrSpace 0)
173199
@@ -193,18 +219,24 @@ initDefs tgt =
193219 exVar :: String -> Type -> Definition
194220 exVar name ty = GlobalDefinition $ globalVariableDefaults { G.name = Name name, G.type' = ty }
195221
196− stdinName :: Target -> String
197− stdinName (Target { os = "darwin" }) = "__stdinp"
198− stdinName _ = "stdin"
199− stdoutName :: Target -> String
200− stdoutName (Target { os = "darwin" }) = "__stdoutp"
201− stdoutName _ = "stdout"
202− stderrName :: Target -> String
203− stderrName (Target { os = "darwin" }) = "__stderrp"
204− stderrName _ = "stderr"
222+isApple :: Target -> Bool
223+isApple (Target { triple = t }) = isJust . stripPrefix "-apple" $ dropWhile (/= '-') t
224+
225+stdinName, stdoutName, stderrName :: Target -> String
226+stdinName t | isApple t = "__stdinp"
227+stdinName _ = "stdin"
228+stdoutName t | isApple t = "__stdoutp"
229+stdoutName _ = "stdout"
230+stderrName t | isApple t = "__stderrp"
231+stderrName _ = "stderr"
232+
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
205237
206238codegen :: 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)
208240 where
209241 (gendefs, _, globals) = runRWS (mapM cgDef defs) tgt 0
210242
@@ -363,13 +395,13 @@ alloc ty = do
363395sizeOf :: Type -> Codegen Operand
364396sizeOf ty = ConstantOperand . C.PtrToInt
365397 (C.GetElementPtr True (C.Null (PointerType ty (AddrSpace 0))) [C.Int 32 1])
366− . IntegerType . fromIntegral <$> getWordSize
398+ . IntegerType <$> getWordSize
367399
368−tgtWordSize :: Target -> Integer
369−tgtWordSize (Target { arch = "i386" }) = 32
370−tgtWordSize (Target { arch = "x86_64" }) = 64
400+tgtWordSize :: Target -> Word32
401+tgtWordSize (Target { dataLayout = DataLayout { pointerLayouts = l } }) =
402+ fst . fromJust $ M.lookup (AddrSpace 0) l
371403
372−getWordSize :: Codegen Integer
404+getWordSize :: Codegen Word32
373405getWordSize = tgtWordSize <$> asks target
374406
375407cgExpr :: SExp -> Codegen (Maybe Operand)
@@ -554,7 +586,7 @@ cgChainCase :: Operand -> Maybe SExp -> [SAlt] -> Codegen (Maybe Operand)
554586cgChainCase caseValPtr defExp alts = do
555587 let (caseTy, comparator) =
556588 case head alts of
557− SConstCase (TT.BI _) _ -> (FArith (ATInt ITBig), "__gmpz_cmp")
589+ SConstCase (TT.BI _) _ -> (FInt ITBig, "__gmpz_cmp")
558590 SConstCase (TT.Str _) _ -> (FString, "strcmp")
559591 caseVal <- unbox caseTy caseValPtr
560592 defBlockName <- getName "default"
@@ -680,11 +712,6 @@ cgConst' (TT.B8 i) = C.Int 8 (fromIntegral i)
680712cgConst' (TT.B16 i) = C.Int 16 (fromIntegral i)
681713cgConst' (TT.B32 i) = C.Int 32 (fromIntegral i)
682714cgConst' (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)
687−
688715cgConst' (TT.BI i) = C.Array (IntegerType 8) (map (C.Int 8 . fromIntegral . fromEnum) (show i) ++ [C.Int 8 0])
689716cgConst' (TT.Fl f) = C.Float (F.Double f)
690717cgConst' (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
692719cgConst' x = ierror $ "Unsupported constant: " ++ show x
693720
694721cgConst :: TT.Const -> Codegen Operand
695−cgConst c@(TT.I _) = box (FArith (ATInt ITNative)) (ConstantOperand $ cgConst' c)
696−cgConst c@(TT.B8 _) = box (FArith (ATInt (ITFixed IT8))) (ConstantOperand $ cgConst' c)
697−cgConst c@(TT.B16 _) = box (FArith (ATInt (ITFixed IT16))) (ConstantOperand $ cgConst' c)
698−cgConst c@(TT.B32 _) = box (FArith (ATInt (ITFixed 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)
704−cgConst c@(TT.Fl _) = box (FArith ATFloat) (ConstantOperand $ cgConst' c)
722+cgConst c@(TT.I _) = box (FInt ITNative) (ConstantOperand $ cgConst' c)
723+cgConst c@(TT.B8 _) = box (FInt IT8) (ConstantOperand $ cgConst' c)
724+cgConst c@(TT.B16 _) = box (FInt IT16) (ConstantOperand $ cgConst' c)
725+cgConst c@(TT.B32 _) = box (FInt IT32) (ConstantOperand $ cgConst' c)
726+cgConst c@(TT.B64 _) = box (FInt IT64) (ConstantOperand $ cgConst' c)
727+cgConst c@(TT.Fl _) = box FDouble (ConstantOperand $ cgConst' c)
705728cgConst c@(TT.Ch _) = box FChar (ConstantOperand $ cgConst' c)
706729cgConst c@(TT.Str s) = do
707730 str <- addGlobal' (ArrayType (1 + fromIntegral (length s)) (IntegerType 8)) (cgConst' c)
@@ -713,7 +736,7 @@ cgConst c@(TT.BI i) = do
713736 , ConstantOperand $ C.GetElementPtr True str [ C.Int 32 0, C.Int 32 0]
714737 , ConstantOperand $ C.Int 32 10
715738 ]
716− box (FArith (ATInt ITBig)) mpz
739+ box (FInt ITBig) mpz
717740cgConst x = return $ ConstantOperand nullValue
718741
719742numDigits :: Integer -> Integer -> Integer
@@ -759,82 +782,72 @@ ffunDecl name rty argtys =
759782 }
760783
761784ftyToTy :: FType -> Type
762−ftyToTy (FArith (ATInt ITNative)) = IntegerType 32
763−ftyToTy (FArith (ATInt ITBig)) = PointerType mpzTy (AddrSpace 0)
764−ftyToTy (FArith (ATInt (ITFixed ty))) = IntegerType (fromIntegral $ nativeTyWidth ty)
765−ftyToTy (FArith (ATInt (ITVec e c)))
766− = VectorType (fromIntegral c) (IntegerType (fromIntegral $ nativeTyWidth e))
785+ftyToTy (FInt ITNative) = IntegerType 32
786+ftyToTy (FInt ITBig) = PointerType mpzTy (AddrSpace 0)
787+ftyToTy (FInt ty) = IntegerType (itWidth ty)
767788ftyToTy FChar = IntegerType 32
768789ftyToTy FString = PointerType (IntegerType 8) (AddrSpace 0)
769790ftyToTy FUnit = VoidType
770791ftyToTy FPtr = PointerType (IntegerType 8) (AddrSpace 0)
771−ftyToTy (FArith ATFloat) = FloatingPointType 64 IEEE
792+ftyToTy FDouble = FloatingPointType 64 IEEE
772793ftyToTy FAny = valueType
773794
774−-- Only use when known not to be ITBig
775−itWidth :: IntTy -> Word32
776−itWidth ITNative = 32
777−itWidth (ITFixed x) = fromIntegral $ nativeTyWidth x
778−
779795cgOp :: PrimFn -> [Operand] -> Codegen Operand
780796cgOp (LTrunc ITBig ity) [x] = do
781− nx <- unbox (FArith (ATInt ITBig)) x
797+ nx <- unbox (FInt ITBig) x
782798 val <- inst $ simpleCall "mpz_get_ull" [nx]
783799 v <- case ity of
784− (ITFixed IT64) -> return val
785− _ -> inst $ Trunc val (ftyToTy (FArith (ATInt ity))) []
786− box (FArith (ATInt ity)) v
800+ IT64 -> return val
801+ _ -> inst $ Trunc val (IntegerType $ itWidth ity) []
802+ box (FInt ity) v
787803cgOp (LZExt from ITBig) [x] = do
788− nx <- unbox (FArith (ATInt from)) x
804+ nx <- unbox (FInt from) x
789805 nx' <- case from of
790− (ITFixed IT64) -> return nx
806+ IT64 -> return nx
791807 _ -> inst $ ZExt nx (IntegerType 64) []
792808 mpz <- alloc mpzTy
793809 inst' $ simpleCall "mpz_init_set_ull" [mpz, nx']
794− box (FArith (ATInt ITBig)) mpz
810+ box (FInt ITBig) mpz
795811cgOp (LSExt from ITBig) [x] = do
796− nx <- unbox (FArith (ATInt from)) x
812+ nx <- unbox (FInt from) x
797813 nx' <- case from of
798− (ITFixed IT64) -> return nx
814+ IT64 -> return nx
799815 _ -> inst $ SExt nx (IntegerType 64) []
800816 mpz <- alloc mpzTy
801817 inst' $ simpleCall "mpz_init_set_sll" [mpz, nx']
802− box (FArith (ATInt ITBig)) mpz
803−
804−cgOp (LLt (ATInt ITBig)) [x,y] = mpzCmp IPred.SLT x y
805−cgOp (LLe (ATInt ITBig)) [x,y] = mpzCmp IPred.SLE x y
806−cgOp (LEq (ATInt ITBig)) [x,y] = mpzCmp IPred.EQ x y
807−cgOp (LGe (ATInt ITBig)) [x,y] = mpzCmp IPred.SGE x y
808−cgOp (LGt (ATInt ITBig)) [x,y] = mpzCmp IPred.SGT x y
809−cgOp (LPlus (ATInt ITBig)) [x,y] = mpzBin "add" x y
810−cgOp (LMinus (ATInt ITBig)) [x,y] = mpzBin "sub" x y
811−cgOp (LTimes (ATInt ITBig)) [x,y] = mpzBin "mul" x y
812−cgOp (LSDiv (ATInt ITBig)) [x,y] = mpzBin "fdiv_q" x y
813−cgOp (LSRem (ATInt ITBig)) [x,y] = mpzBin "fdiv_r" x y
818+ box (FInt ITBig) mpz
819+
820+cgOp (LLt ITBig) [x,y] = mpzCmp IPred.SLT x y
821+cgOp (LLe ITBig) [x,y] = mpzCmp IPred.SLE x y
822+cgOp (LEq ITBig) [x,y] = mpzCmp IPred.EQ x y
823+cgOp (LGe ITBig) [x,y] = mpzCmp IPred.SGE x y
824+cgOp (LGt ITBig) [x,y] = mpzCmp IPred.SGT x y
825+cgOp (LPlus ITBig) [x,y] = mpzBin "add" x y
826+cgOp (LMinus ITBig) [x,y] = mpzBin "sub" x y
827+cgOp (LTimes ITBig) [x,y] = mpzBin "mul" x y
828+cgOp (LSDiv ITBig) [x,y] = mpzBin "fdiv_q" x y
829+cgOp (LSRem ITBig) [x,y] = mpzBin "fdiv_r" x y
814830cgOp (LAnd ITBig) [x,y] = mpzBin "and" x y
815831cgOp (LOr ITBig) [x,y] = mpzBin "ior" x y
816832cgOp (LXOr ITBig) [x,y] = mpzBin "xor" x y
817833cgOp (LCompl ITBig) [x] = mpzUn "com" x
818834
819−cgOp (LTrunc (ITFixed from) (ITFixed to)) [x]
820− | nativeTyWidth from > nativeTyWidth to = iCoerce Trunc from to x
821−cgOp (LZExt (ITFixed from) (ITFixed to)) [x]
822− | nativeTyWidth from < nativeTyWidth to = iCoerce ZExt from to x
823−cgOp (LSExt (ITFixed from) (ITFixed to)) [x]
824− | nativeTyWidth from < nativeTyWidth to = iCoerce SExt from to x
825−
826−cgOp (LLt (ATInt ity)) [x,y] = iCmp ity IPred.SLT x y
827−cgOp (LLe (ATInt ity)) [x,y] = iCmp ity IPred.SLE x y
828−cgOp (LEq (ATInt ity)) [x,y] = iCmp ity IPred.EQ x y
829−cgOp (LGe (ATInt ity)) [x,y] = iCmp ity IPred.SGE x y
830−cgOp (LGt (ATInt ity)) [x,y] = iCmp ity IPred.SGT x y
831−cgOp (LPlus (ATInt ity)) [x,y] = ibin ity x y (Add False False)
832−cgOp (LMinus (ATInt ity)) [x,y] = ibin ity x y (Sub False False)
833−cgOp (LTimes (ATInt 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
835+cgOp (LTrunc from to) [x] | itWidth from > itWidth to = iCoerce Trunc from to x
836+cgOp (LZExt from to) [x] | itWidth from < itWidth to = iCoerce ZExt from to x
837+cgOp (LSExt from to) [x] | itWidth from < itWidth to = iCoerce SExt from to x
838+
839+cgOp (LLt ity) [x,y] = iCmp ity IPred.SLT x y
840+cgOp (LLe ity) [x,y] = iCmp ity IPred.SLE x y
841+cgOp (LEq ity) [x,y] = iCmp ity IPred.EQ x y
842+cgOp (LGe ity) [x,y] = iCmp ity IPred.SGE x y
843+cgOp (LGt ity) [x,y] = iCmp ity IPred.SGT x y
844+cgOp (LPlus ity) [x,y] = ibin ity x y (Add False False)
845+cgOp (LMinus ity) [x,y] = ibin ity x y (Sub False False)
846+cgOp (LTimes ity) [x,y] = ibin ity x y (Mul False False)
836847cgOp (LUDiv ity) [x,y] = ibin ity x y (UDiv False)
837848cgOp (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
838851cgOp (LAnd ity) [x,y] = ibin ity x y And
839852cgOp (LOr ity) [x,y] = ibin ity x y Or
840853cgOp (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)
843856cgOp (LLSHR ity) [x,y] = ibin ity x y (LShr False)
844857cgOp (LASHR ity) [x,y] = ibin ity x y (AShr False)
845858
846−cgOp (LMkVec ety c) xs | c == length xs = do
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))))
850− (zip nxs [0..])
851− box (FArith (ATInt (ITVec ety c))) vec
852−
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
858−
859−cgOp (LUpdateVec ety c) [v,i,e] = do
860− let fty = FArith (ATInt (ITVec ety c))
861− nv <- unbox fty v
862− ni <- unbox (FArith (ATInt (ITFixed IT32))) i
863− ne <- unbox (FArith (ATInt (ITFixed ety))) e
864− nv' <- inst $ InsertElement nv ne ni []
865− box fty nv'
859+cgOp LNoOp xs = return $ last xs
866860
867861cgOp LStrEq [x,y] = do
868862 x' <- unbox FString x
@@ -870,7 +864,7 @@ cgOp LStrEq [x,y] = do
870864 cmp <- inst $ simpleCall "strcmp" [x', y']
871865 flag <- inst $ ICmp IPred.EQ cmp (ConstantOperand (C.Int 32 0)) []
872866 val <- inst $ ZExt flag (IntegerType 32) []
873− box (FArith (ATInt (ITFixed IT32))) val
867+ box (FInt IT32) val
874868
875869cgOp LStrLt [x,y] = do
876870 nx <- unbox FString x
@@ -878,10 +872,10 @@ cgOp LStrLt [x,y] = do
878872 cmp <- inst $ simpleCall "strcmp" [nx, ny]
879873 flag <- inst $ ICmp IPred.ULT cmp (ConstantOperand (C.Int 32 0)) []
880874 val <- inst $ ZExt flag (IntegerType 32) []
881− box (FArith (ATInt (ITFixed IT32))) val
875+ box (FInt IT32) val
882876
883877cgOp (LIntStr ITBig) [x] = do
884− x' <- unbox (FArith (ATInt ITBig)) x
878+ x' <- unbox (FInt ITBig) x
885879 ustr <- inst $ simpleCall "__gmpz_get_str"
886880 [ ConstantOperand (C.Null (PointerType (IntegerType 8) (AddrSpace 0)))
887881 , ConstantOperand (C.Int 32 10)
@@ -889,7 +883,7 @@ cgOp (LIntStr ITBig) [x] = do
889883 ]
890884 box FString ustr
891885cgOp (LIntStr ity) [x] = do
892− x' <- unbox (FArith (ATInt ity)) x
886+ x' <- unbox (FInt ity) x
893887 x'' <- if itWidth ity < 64
894888 then inst $ SExt x' (IntegerType 64) []
895889 else return x'
@@ -898,7 +892,7 @@ cgOp (LStrInt ITBig) [s] = do
898892 ns <- unbox FString s
899893 mpz <- alloc mpzTy
900894 inst $ simpleCall "__gmpz_init_set_str" [mpz, ns, ConstantOperand $ C.Int 32 10]
901− box (FArith (ATInt ITBig)) mpz
895+ box (FInt ITBig) mpz
902896cgOp (LStrInt ity) [s] = do
903897 ns <- unbox FString s
904898 nx <- inst $ simpleCall "strtoll"
@@ -907,9 +901,9 @@ cgOp (LStrInt ity) [s] = do
907901 , ConstantOperand $ C.Int 32 10
908902 ]
909903 nx' <- case ity of
910− (ITFixed IT64) -> return nx
904+ IT64 -> return nx
911905 _ -> inst $ Trunc nx (IntegerType (itWidth ity)) []
912− box (FArith (ATInt ity)) nx'
906+ box (FInt ity) nx'
913907
914908cgOp LStrConcat [x,y] = cgStrCat x y
915909
@@ -928,7 +922,7 @@ cgOp LStrHead [c] = do
928922
929923cgOp LStrIndex [s, i] = do
930924 ns <- unbox FString s
931− ni <- unbox (FArith (ATInt (ITFixed IT32))) i
925+ ni <- unbox (FInt IT32) i
932926 p <- inst $ GetElementPtr True ns [ni] []
933927 c <- inst $ Load False p Nothing 0 []
934928 c' <- inst $ ZExt c (IntegerType 32) []
@@ -945,9 +939,9 @@ cgOp LStrLen [s] = do
945939 ws <- getWordSize
946940 len' <- case ws of
947941 32 -> return len
948− x | x > 32 -> inst $ Trunc len (IntegerType $ fromInteger x) []
949− | x < 32 -> inst $ ZExt len (IntegerType $ fromInteger x) []
950− box (FArith (ATInt (ITFixed IT32))) len'
942+ x | x > 32 -> inst $ Trunc len (IntegerType 32) []
943+ | x < 32 -> inst $ ZExt len (IntegerType 32) []
944+ box (FInt IT32) len'
951945
952946cgOp LReadStr [p] = do
953947 np <- unbox FPtr p
@@ -955,24 +949,26 @@ cgOp LReadStr [p] = do
955949 box FString s
956950
957951cgOp LStdIn [] = do
958− ptr <- inst $ Load False (ConstantOperand . C.GlobalReference . Name $ "stdin") Nothing 0 []
952+ stdin <- getStdIn
953+ ptr <- inst $ Load False stdin Nothing 0 []
959954 box FPtr ptr
960955cgOp LStdOut [] = do
961− ptr <- inst $ Load False (ConstantOperand . C.GlobalReference . Name $ "stdout") Nothing 0 []
956+ stdout <- getStdOut
957+ ptr <- inst $ Load False stdout Nothing 0 []
962958 box FPtr ptr
963959cgOp LStdErr [] = do
964− ptr <- inst $ Load False (ConstantOperand . C.GlobalReference . Name $ "stderr") Nothing 0 []
960+ stdErr <- getStdErr
961+ ptr <- inst $ Load False stdErr Nothing 0 []
965962 box FPtr ptr
966963
967−
968964cgOp prim args = ierror $ "Unimplemented primitive: [" ++ show prim ++ "]("
969965 ++ intersperse ',' (take (length args) ['a'..]) ++ ")"
970966
971−iCoerce :: (Operand -> Type -> InstructionMetadata -> Instruction) -> NativeTy -> NativeTy -> Operand -> Codegen Operand
967+iCoerce :: (Operand -> Type -> InstructionMetadata -> Instruction) -> IntTy -> IntTy -> Operand -> Codegen Operand
972968iCoerce operator from to x = do
973− x' <- unbox (FArith (ATInt (ITFixed from))) x
974− x'' <- inst $ operator x' (ftyToTy (FArith (ATInt (ITFixed from)))) []
975− box (FArith (ATInt (ITFixed to))) x''
969+ x' <- unbox (FInt from) x
970+ x'' <- inst $ operator x' (IntegerType $ itWidth to) []
971+ box (FInt to) x''
976972
977973cgStrCat :: Operand -> Operand -> Codegen Operand
978974cgStrCat x y = do
@@ -981,7 +977,7 @@ cgStrCat x y = do
981977 xlen <- inst $ simpleCall "strlen" [x']
982978 ylen <- inst $ simpleCall "strlen" [y']
983979 zlen <- inst $ Add False True xlen ylen []
984− ws <- fromIntegral <$> getWordSize
980+ ws <- getWordSize
985981 total <- inst $ Add False True zlen (ConstantOperand (C.Int ws 1)) []
986982 mem <- allocAtomic total
987983 inst $ simpleCall "memcpy" [mem, x', xlen]
@@ -998,54 +994,50 @@ cgStrCat x y = do
998994ibin :: IntTy -> Operand -> Operand
999995 -> (Operand -> Operand -> InstructionMetadata -> Instruction) -> Codegen Operand
1000996ibin ity x y instCon = do
1001− nx <- unbox (FArith (ATInt ity)) x
1002− ny <- unbox (FArith (ATInt ity)) y
997+ nx <- unbox (FInt ity) x
998+ ny <- unbox (FInt ity) y
1003999 nr <- inst $ instCon nx ny []
1004− box (FArith (ATInt ity)) nr
1000+ box (FInt ity) nr
10051001
10061002iun :: IntTy -> Operand -> (Operand -> InstructionMetadata -> Instruction) -> Codegen Operand
10071003iun ity x instCon = do
1008− nx <- unbox (FArith (ATInt ity)) x
1004+ nx <- unbox (FInt ity) x
10091005 nr <- inst $ instCon nx []
1010− box (FArith (ATInt ity)) nr
1006+ box (FInt ity) nr
10111007
10121008iCmp :: IntTy -> IPred.IntegerPredicate -> Operand -> Operand -> Codegen Operand
10131009iCmp ity pred x y = do
1014− nx <- unbox (FArith (ATInt ity)) x
1015− ny <- unbox (FArith (ATInt ity)) y
1010+ nx <- unbox (FInt ity) x
1011+ ny <- unbox (FInt ity) y
10161012 nr <- inst $ ICmp pred nx ny []
1017− nr' <- inst $ SExt nr (ftyToTy $ cmpResultTy ity) []
1018− box (cmpResultTy ity) nr'
1019−
1020−cmpResultTy :: IntTy -> FType
1021−cmpResultTy v@(ITVec _ _) = FArith (ATInt v)
1022−cmpResultTy _ = FArith (ATInt (ITFixed IT32))
1013+ nr' <- inst $ ZExt nr (IntegerType 32) []
1014+ box (FInt IT32) nr'
10231015
10241016mpzBin :: String -> Operand -> Operand -> Codegen Operand
10251017mpzBin name x y = do
1026− nx <- unbox (FArith (ATInt ITBig)) x
1027− ny <- unbox (FArith (ATInt ITBig)) y
1018+ nx <- unbox (FInt ITBig) x
1019+ ny <- unbox (FInt ITBig) y
10281020 nz <- alloc mpzTy
10291021 inst' $ simpleCall "__gmpz_init" [nz]
10301022 inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx, ny]
1031− box (FArith (ATInt ITBig)) nz
1023+ box (FInt ITBig) nz
10321024
10331025mpzUn :: String -> Operand -> Codegen Operand
10341026mpzUn name x = do
1035− nx <- unbox (FArith (ATInt ITBig)) x
1027+ nx <- unbox (FInt ITBig) x
10361028 nz <- alloc mpzTy
10371029 inst' $ simpleCall "__gmpz_init" [nz]
10381030 inst' $ simpleCall ("__gmpz_" ++ name) [nz, nx]
1039− box (FArith (ATInt ITBig)) nz
1031+ box (FInt ITBig) nz
10401032
10411033mpzCmp :: IPred.IntegerPredicate -> Operand -> Operand -> Codegen Operand
10421034mpzCmp pred x y = do
1043− nx <- unbox (FArith (ATInt ITBig)) x
1044− ny <- unbox (FArith (ATInt ITBig)) y
1035+ nx <- unbox (FInt ITBig) x
1036+ ny <- unbox (FInt ITBig) y
10451037 cmp <- inst $ simpleCall "__gmpz_cmp" [nx, ny]
10461038 result <- inst $ ICmp pred cmp (ConstantOperand (C.Int 32 0)) []
10471039 i <- inst $ ZExt result (IntegerType 32) []
1048− box (FArith (ATInt (ITFixed IT32))) i
1040+ box (FInt IT32) i
10491041
10501042simpleCall :: String -> [Operand] -> Instruction
10511043simpleCall name args =