diff options
author | tomsmeding <tom.smeding@gmail.com> | 2017-01-27 10:53:28 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2017-01-27 10:53:28 +0100 |
commit | 97650a26c3d940a98313c37fe122c146ab7c7ff4 (patch) | |
tree | 5369aadafb3bf265346eae810c6a77b71c63c949 | |
parent | 2d68c697c480986089af1050b859b953d0f7fa82 (diff) |
Can compile test.nl (with a simple change)
-rw-r--r-- | codegen.hs | 93 | ||||
-rw-r--r-- | test.nl | 3 |
2 files changed, 89 insertions, 7 deletions
@@ -8,6 +8,7 @@ import qualified Data.Map.Strict as Map import qualified LLVM.General.AST.Type as A import qualified LLVM.General.AST.Global as A.G import qualified LLVM.General.AST.Constant as A.C +import qualified LLVM.General.AST.Float as A.F -- import qualified LLVM.General.AST.Operand as A -- import qualified LLVM.General.AST.Name as A -- import qualified LLVM.General.AST.Instruction as A @@ -106,7 +107,14 @@ setGlobalVar name label t = do state $ \s -> ((), s {globalVariables = Map.insert name (t, label) $ globalVariables s}) lookupVar :: Name -> CGMonad (Type, LLName) -lookupVar name = liftM (fromJust . Map.lookup name . variables) get +lookupVar name | trace ("Looking up var " ++ name) False = undefined +lookupVar name = do + obj <- get + let locfound = Map.lookup name $ variables obj + glofound = Map.lookup name $ globalVariables obj + if isJust locfound + then return $ fromJust locfound + else return $ fromJust glofound lookupGlobalVar :: Name -> CGMonad (Type, LLName) lookupGlobalVar name = liftM (fromJust . Map.lookup name . globalVariables) get @@ -301,16 +309,49 @@ genExpression (ExBinOp bo e1 e2 (Just t)) = do (TypePtr _) -> addInstr $ A.Sub False False e1op' e2op' [] (TypeName _) -> undefined return $ A.LocalReference (toLLVMType t) (A.Name label) + Divide -> do + e1op' <- castOperand e1op t + e2op' <- castOperand e2op t + label <- case t of + (TypeInt _) -> addInstr $ A.SDiv False e1op' e2op' [] + (TypeUInt _) -> addInstr $ A.UDiv False e1op' e2op' [] + TypeFloat -> addInstr $ A.FDiv A.NoFastMathFlags e1op' e2op' [] + TypeDouble -> addInstr $ A.FDiv A.NoFastMathFlags e1op' e2op' [] + (TypePtr _) -> throwError $ "Modulo '%' operator not defined on pointers" + (TypeName _) -> undefined + return $ A.LocalReference (toLLVMType t) (A.Name label) + Modulo -> do + e1op' <- castOperand e1op t + e2op' <- castOperand e2op t + label <- case t of + (TypeInt _) -> addInstr $ A.SRem e1op' e2op' [] + (TypeUInt _) -> addInstr $ A.URem e1op' e2op' [] + TypeFloat -> addInstr $ A.FRem A.NoFastMathFlags e1op' e2op' [] + TypeDouble -> addInstr $ A.FRem A.NoFastMathFlags e1op' e2op' [] + (TypePtr _) -> throwError $ "Modulo '%' operator not defined on pointers" + (TypeName _) -> undefined + return $ A.LocalReference (toLLVMType t) (A.Name label) Equal -> do - sharedType <- commonType (fromJust (exTypeOf e1)) (fromJust (exTypeOf e2)) + sharedType <- commonTypeM (fromJust (exTypeOf e1)) (fromJust (exTypeOf e2)) + trace ("Shared type for Equal of " ++ pshow e1 ++ " and " ++ pshow e2 ++ " is: " ++ pshow sharedType) + $ return () e1op' <- castOperand e1op sharedType e2op' <- castOperand e2op sharedType label <- case sharedType of (TypeInt _) -> addInstr $ A.ICmp A.EQ e1op' e2op' [] _ -> undefined return $ A.LocalReference (A.IntegerType 1) (A.Name label) + Greater -> do + sharedType <- commonTypeM (fromJust (exTypeOf e1)) (fromJust (exTypeOf e2)) + e1op' <- castOperand e1op sharedType + e2op' <- castOperand e2op sharedType + label <- case sharedType of + (TypeInt _) -> addInstr $ A.ICmp A.SGT e1op' e2op' [] + (TypeUInt _) -> addInstr $ A.ICmp A.UGT e1op' e2op' [] + _ -> undefined + return $ A.LocalReference (A.IntegerType 1) (A.Name label) Less -> do - sharedType <- commonType (fromJust (exTypeOf e1)) (fromJust (exTypeOf e2)) + sharedType <- commonTypeM (fromJust (exTypeOf e1)) (fromJust (exTypeOf e2)) e1op' <- castOperand e1op sharedType e2op' <- castOperand e2op sharedType label <- case sharedType of @@ -318,7 +359,25 @@ genExpression (ExBinOp bo e1 e2 (Just t)) = do (TypeUInt _) -> addInstr $ A.ICmp A.ULT e1op' e2op' [] _ -> undefined return $ A.LocalReference (A.IntegerType 1) (A.Name label) + BoolOr -> do + e1op' <- castToBool e1op + e2op' <- castToBool e2op + label <- addInstr $ A.Or e1op' e2op' [] + return $ A.LocalReference (A.IntegerType 1) (A.Name label) _ -> throwError $ "Binary operator " ++ pshow bo ++ " not implemented" +genExpression (ExUnOp uo e1 (Just t)) = do + e1op <- genExprArgument e1 + case uo of + Negate -> do + label <- case t of + (TypeInt s) -> addInstr $ A.Sub False False (A.ConstantOperand (A.C.Int (fromIntegral s) 0)) e1op [] + (TypeUInt s) -> addInstr $ A.Sub False False (A.ConstantOperand (A.C.Int (fromIntegral s) 0)) e1op [] + TypeFloat -> addInstr $ A.FSub A.NoFastMathFlags (A.ConstantOperand (A.C.Float (A.F.Single 0))) e1op [] + TypeDouble -> addInstr $ A.FSub A.NoFastMathFlags (A.ConstantOperand (A.C.Float (A.F.Double 0))) e1op [] + (TypePtr _) -> throwError $ "Negate '-' operator not defined on a pointer" + (TypeName _) -> undefined + return $ A.LocalReference (toLLVMType t) (A.Name label) + _ -> throwError $ "Unary operator " ++ pshow uo ++ " not implemented" genExpression ex = throwError $ "Expression '" ++ pshow ex ++ "' not implemented" genExprArgument :: Expression -> CGMonad A.Operand @@ -335,6 +394,9 @@ literalToOperand (LitVar n) t = do literalToOperand lit _ = throwError $ "Literal '" ++ pshow lit ++ "' not implemented" castOperand :: A.Operand -> Type -> CGMonad A.Operand +castOperand orig@(A.LocalReference (A.IntegerType 1) _) t2@(TypeInt _) = do + label <- addInstr $ A.ZExt orig (toLLVMType t2) [] + return $ A.LocalReference (toLLVMType t2) (A.Name label) castOperand orig@(A.LocalReference (A.IntegerType s1) _) t2@(TypeInt s2) | fromIntegral s1 == s2 = return orig | fromIntegral s1 < s2 = do @@ -365,9 +427,28 @@ castToBool (A.ConstantOperand (A.C.Int _ val)) = return $ A.ConstantOperand (A.C.Int 1 (if val == 0 then 1 else 0)) castToBool _ = undefined -commonType :: Type -> Type -> CGMonad Type -commonType (TypeInt s1) (TypeInt s2) = return $ TypeInt (max s1 s2) -commonType _ _ = undefined + +commonType :: Type -> Type -> Maybe Type +commonType (TypePtr t1) (TypePtr t2) | t1 == t2 = Just $ TypePtr t1 +commonType (TypePtr _) _ = Nothing +commonType _ (TypePtr _) = Nothing + +commonType (TypeInt s1) (TypeInt s2) = Just $ TypeInt (max s1 s2) + +commonType (TypeUInt s1) (TypeUInt s2) = Just $ TypeUInt (max s1 s2) + +commonType TypeFloat (TypeInt _) = Just TypeFloat +commonType (TypeInt _) TypeFloat = Just TypeFloat +commonType TypeDouble (TypeInt _) = Just TypeDouble +commonType (TypeInt _) TypeDouble = Just TypeDouble +commonType TypeFloat TypeDouble = Just TypeDouble +commonType TypeDouble TypeFloat = Just TypeDouble + +commonType _ _ = Nothing + +commonTypeM :: Type -> Type -> CGMonad Type +commonTypeM t1 t2 = maybe err return $ commonType t1 t2 + where err = throwError $ "Cannot implicitly find common type of '" ++ pshow t1 ++ "' and '" ++ pshow t2 ++ "'" cleanupTrampolines :: CGMonad () @@ -1,9 +1,10 @@ type int = i32; type char = i8; -int glob = 10; +int glob; int main(int argc, ptr(char) argv) { + glob = 10; int kaas = glob + 2; glob = 2 > 1 || 1 == 1 % 10; while (glob < 20) { |