{-# OPTIONS_GHC -cpp #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE ScopedTypeVariables #-} module Llvm.Data.Conversion.IrAstConversion(irToAst) where #define FLC (I.FileLoc $(I.srcLoc)) import qualified Compiler.Hoopl as H import qualified Control.Monad as Md import qualified Data.Map as M import qualified Llvm.Data.Ast as A import qualified Llvm.Data.Ir as I import Llvm.Util.Monadic (maybeM, pairM) import Llvm.Data.Conversion.TypeConversion import Control.Monad.Reader class Conversion l1 l2 | l1 -> l2 where convert :: l1 -> l2 type Rm = Reader (M.Map H.Label A.LabelId) instance Conversion a (Rm b) => Conversion (Maybe a) (Rm (Maybe b)) where convert (Just x) = Md.liftM Just (convert x) convert Nothing = return Nothing instance (Conversion a (Rm c), Conversion b (Rm c)) => Conversion (Either a b) (Rm c) where convert (Left x) = (convert x) convert (Right x) = (convert x) {- Ir to Ast conversion -} instance Conversion H.Label (Rm A.LabelId) where convert l = do { r <- ask ; case M.lookup l r of Just l0 -> return l0 Nothing -> return $ A.LabelDqString $ "_hoopl_label_" ++ show l } convert_to_PercentLabel :: H.Label -> Rm A.PercentLabel convert_to_PercentLabel l = Md.liftM A.PercentLabel (convert l) convert_to_TargetLabel :: H.Label -> Rm A.TargetLabel convert_to_TargetLabel l = Md.liftM (A.TargetLabel . A.PercentLabel) (convert l) convert_to_BlockLabel :: H.Label -> Rm A.BlockLabel convert_to_BlockLabel l = Md.liftM A.ExplicitBlockLabel (convert l) cnowrap :: Maybe I.NoWrap -> [A.TrapFlag] cnowrap = maybe [] (\x -> case x of I.Nsw -> [A.Nsw] I.Nuw -> [A.Nuw] I.Nsuw -> [A.Nsw, A.Nuw] ) cexact :: Maybe a -> [A.TrapFlag] cexact = maybe [] (\_ -> [A.Exact]) instance Conversion v1 (Rm v2) => Conversion (I.Conversion I.ScalarB v1) (Rm (A.Conversion v2)) where convert x = let (op, t1, u, dt1) = case x of I.Trunc (I.T t0 u0) dt0 -> (A.Trunc, tconvert () t0, u0, tconvert () dt0) I.Zext (I.T t0 u0) dt0 -> (A.Zext, tconvert () t0, u0, tconvert () dt0) I.Sext (I.T t0 u0) dt0 -> (A.Sext, tconvert () t0, u0, tconvert () dt0) I.FpTrunc (I.T t0 u0) dt0 -> (A.FpTrunc, tconvert () t0, u0, tconvert () dt0) I.FpExt (I.T t0 u0) dt0 -> (A.FpExt, tconvert () t0, u0, tconvert () dt0) I.FpToUi (I.T t0 u0) dt0 -> (A.FpToUi, tconvert () t0, u0, tconvert () dt0) I.FpToSi (I.T t0 u0) dt0 -> (A.FpToSi, tconvert () t0, u0, tconvert () dt0) I.UiToFp (I.T t0 u0) dt0 -> (A.UiToFp, tconvert () t0, u0, tconvert () dt0) I.SiToFp (I.T t0 u0) dt0 -> (A.SiToFp, tconvert () t0, u0, tconvert () dt0) I.PtrToInt (I.T t0 u0) dt0 -> (A.PtrToInt, tconvert () t0, u0, tconvert () dt0) I.IntToPtr (I.T t0 u0) dt0 -> (A.IntToPtr, tconvert () t0, u0, tconvert () dt0) I.Bitcast (I.T t0 u0) dt0 -> (A.Bitcast, tconvert () t0, u0, tconvert () dt0) I.AddrSpaceCast (I.T t0 u0) dt0 -> (A.AddrSpaceCast, tconvert () t0, u0, tconvert () dt0) in do { u1 <- convert u ; return $ A.Conversion op (A.Typed t1 u1) dt1 } instance Conversion v1 (Rm v2) => Conversion (I.Conversion I.VectorB v1) (Rm (A.Conversion v2)) where convert x = let (op, t1, u, dt1) = case x of I.Trunc (I.T t0 u0) dt0 -> (A.Trunc, tconvert () t0, u0, tconvert () dt0) I.Zext (I.T t0 u0) dt0 -> (A.Zext, tconvert () t0, u0, tconvert () dt0) I.Sext (I.T t0 u0) dt0 -> (A.Sext, tconvert () t0, u0, tconvert () dt0) I.FpTrunc (I.T t0 u0) dt0 -> (A.FpTrunc, tconvert () t0, u0, tconvert () dt0) I.FpExt (I.T t0 u0) dt0 -> (A.FpExt, tconvert () t0, u0, tconvert () dt0) I.FpToUi (I.T t0 u0) dt0 -> (A.FpToUi, tconvert () t0, u0, tconvert () dt0) I.FpToSi (I.T t0 u0) dt0 -> (A.FpToSi, tconvert () t0, u0, tconvert () dt0) I.UiToFp (I.T t0 u0) dt0 -> (A.UiToFp, tconvert () t0, u0, tconvert () dt0) I.SiToFp (I.T t0 u0) dt0 -> (A.SiToFp, tconvert () t0, u0, tconvert () dt0) I.PtrToInt (I.T t0 u0) dt0 -> (A.PtrToInt, tconvert () t0, u0, tconvert () dt0) I.IntToPtr (I.T t0 u0) dt0 -> (A.IntToPtr, tconvert () t0, u0, tconvert () dt0) I.Bitcast (I.T t0 u0) dt0 -> (A.Bitcast, tconvert () t0, u0, tconvert () dt0) I.AddrSpaceCast (I.T t0 u0) dt0 -> (A.AddrSpaceCast, tconvert () t0, u0, tconvert () dt0) in do { u1 <- convert u ; return $ A.Conversion op (A.Typed t1 u1) dt1 } mkConversion :: (A.ConvertOp, A.Type, I.Const, A.Type) -> Rm A.Const mkConversion (op, t1, u, dt1) = do { u1 <- convert u ; return $ A.C_conv $ A.Conversion op (A.Typed t1 u1) dt1 } instance (Conversion v1 (Rm v2)) => Conversion (I.GetElementPtr I.ScalarB v1) (Rm (A.GetElementPtr v2)) where convert (I.GetElementPtr b u us) = do { ua <- convert u ; usa <- mapM convert us ; return $ A.GetElementPtr b (A.Pointer ua) usa } instance (Conversion v1 (Rm v2)) => Conversion (I.GetElementPtr I.VectorB v1) (Rm (A.GetElementPtr v2)) where convert (I.GetElementPtr b u us) = do { ua <- convert u ; usa <- mapM convert us ; return $ A.GetElementPtr b (A.Pointer ua) usa } instance Conversion v1 (Rm v2) => Conversion (I.T I.ScalarType v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T I.Dtype v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.ScalarB I.I) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.ScalarB I.F) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.ScalarB I.P) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.VectorB I.I) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.VectorB I.F) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.VectorB I.P) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.RecordB I.D) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.CodeFunB I.X) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.CodeLabelB I.X) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance Conversion v1 (Rm v2) => Conversion (I.T (I.Type I.FirstClassB I.D) v1) (Rm (A.Typed v2)) where convert (I.T t v) = Md.liftM (A.Typed $ tconvert () t) (convert v) instance (Conversion v1 (Rm v2)) => Conversion (I.Select I.ScalarB I.I v1) (Rm (A.Select v2)) where convert (I.Select u1 u2 u3) = Md.liftM3 A.Select (convert u1) (convert u2) (convert u3) instance (Conversion v1 (Rm v2)) => Conversion (I.Select I.ScalarB I.F v1) (Rm (A.Select v2)) where convert (I.Select u1 u2 u3) = Md.liftM3 A.Select (convert u1) (convert u2) (convert u3) instance (Conversion v1 (Rm v2)) => Conversion (I.Select I.ScalarB I.P v1) (Rm (A.Select v2)) where convert (I.Select u1 u2 u3) = Md.liftM3 A.Select (convert u1) (convert u2) (convert u3) instance (Conversion v1 (Rm v2)) => Conversion (I.Select I.VectorB I.I v1) (Rm (A.Select v2)) where convert (I.Select u1 u2 u3) = Md.liftM3 A.Select (convert u1) (convert u2) (convert u3) instance (Conversion v1 (Rm v2)) => Conversion (I.Select I.VectorB I.F v1) (Rm (A.Select v2)) where convert (I.Select u1 u2 u3) = Md.liftM3 A.Select (convert u1) (convert u2) (convert u3) instance (Conversion v1 (Rm v2)) => Conversion (I.Select I.VectorB I.P v1) (Rm (A.Select v2)) where convert (I.Select u1 u2 u3) = Md.liftM3 A.Select (convert u1) (convert u2) (convert u3) instance Conversion v1 (Rm v2) => Conversion (I.Icmp I.ScalarB v1) (Rm (A.Icmp v2)) where convert (I.Icmp op t u1 u2) = Md.liftM2 (A.Icmp op (tconvert () t)) (convert u1) (convert u2) instance Conversion v1 (Rm v2) => Conversion (I.Icmp I.VectorB v1) (Rm (A.Icmp v2)) where convert (I.Icmp op t u1 u2) = Md.liftM2 (A.Icmp op (tconvert () t)) (convert u1) (convert u2) instance Conversion v1 (Rm v2) => Conversion (I.Fcmp I.ScalarB v1) (Rm (A.Fcmp v2)) where convert (I.Fcmp op t u1 u2) = Md.liftM2 (A.Fcmp op (tconvert () t)) (convert u1) (convert u2) instance Conversion v1 (Rm v2) => Conversion (I.Fcmp I.VectorB v1) (Rm (A.Fcmp v2)) where convert (I.Fcmp op t u1 u2) = Md.liftM2 (A.Fcmp op (tconvert () t)) (convert u1) (convert u2) instance Conversion v1 (Rm v2) => Conversion (I.ShuffleVector I.I v1) (Rm (A.ShuffleVector v2)) where convert (I.ShuffleVector u1 u2 u3) = Md.liftM3 A.ShuffleVector (convert u1) (convert u2) (convert u3) instance Conversion v1 (Rm v2) => Conversion (I.ShuffleVector I.F v1) (Rm (A.ShuffleVector v2)) where convert (I.ShuffleVector u1 u2 u3) = Md.liftM3 A.ShuffleVector (convert u1) (convert u2) (convert u3) instance Conversion v1 (Rm v2) => Conversion (I.ShuffleVector I.P v1) (Rm (A.ShuffleVector v2)) where convert (I.ShuffleVector u1 u2 u3) = Md.liftM3 A.ShuffleVector (convert u1) (convert u2) (convert u3) instance Conversion v1 (Rm v2) => Conversion (I.ExtractValue v1) (Rm (A.ExtractValue v2)) where convert (I.ExtractValue u s) = convert u >>= \u' -> return $ A.ExtractValue u' s instance Conversion v1 (Rm v2) => Conversion (I.InsertValue v1) (Rm (A.InsertValue v2)) where convert (I.InsertValue u1 u2 s) = do { u1' <- convert u1 ; u2' <- convert u2 ; return $ A.InsertValue u1' u2' s } instance Conversion v1 (Rm v2) => Conversion (I.ExtractElement I.I v1) (Rm (A.ExtractElement v2)) where convert (I.ExtractElement u1 u2) = Md.liftM2 A.ExtractElement (convert u1) (convert u2) instance Conversion v1 (Rm v2) => Conversion (I.ExtractElement I.F v1) (Rm (A.ExtractElement v2)) where convert (I.ExtractElement u1 u2) = Md.liftM2 A.ExtractElement (convert u1) (convert u2) instance Conversion v1 (Rm v2) => Conversion (I.ExtractElement I.P v1) (Rm (A.ExtractElement v2)) where convert (I.ExtractElement u1 u2) = Md.liftM2 A.ExtractElement (convert u1) (convert u2) instance Conversion v1 (Rm v2) => Conversion (I.InsertElement I.I v1) (Rm (A.InsertElement v2)) where convert (I.InsertElement u1 u2 u3) = Md.liftM3 A.InsertElement (convert u1) (convert u2) (convert u3) instance Conversion v1 (Rm v2) => Conversion (I.InsertElement I.F v1) (Rm (A.InsertElement v2)) where convert (I.InsertElement u1 u2 u3) = Md.liftM3 A.InsertElement (convert u1) (convert u2) (convert u3) instance Conversion v1 (Rm v2) => Conversion (I.InsertElement I.P v1) (Rm (A.InsertElement v2)) where convert (I.InsertElement u1 u2 u3) = Md.liftM3 A.InsertElement (convert u1) (convert u2) (convert u3) instance Conversion I.Const (Rm A.Const) where convert x = case x of I.C_int s -> return $ A.C_simple $ A.CpInt s I.C_uhex_int s -> return $ A.C_simple $ A.CpUhexInt s I.C_shex_int s -> return $ A.C_simple $ A.CpShexInt s I.C_float s -> return $ A.C_simple $ A.CpFloat s I.C_null -> return $ A.C_simple $ A.CpNull I.C_undef -> return $ A.C_simple $ A.CpUndef I.C_true -> return $ A.C_simple $ A.CpTrue I.C_false -> return $ A.C_simple $ A.CpFalse I.C_zeroinitializer -> return $ A.C_simple $ A.CpZeroInitializer I.C_globalAddr s -> return $ A.C_simple $ A.CpGlobalAddr s I.C_str s -> return $ A.C_simple $ A.CpStr s I.C_u8 s -> return $ A.C_simple $ A.CpBconst $ A.BconstUint8 s I.C_u16 s -> return $ A.C_simple $ A.CpBconst $ A.BconstUint16 s I.C_u32 s -> return $ A.C_simple $ A.CpBconst $ A.BconstUint32 s I.C_u64 s -> return $ A.C_simple $ A.CpBconst $ A.BconstUint64 s I.C_u96 s -> return $ A.C_simple $ A.CpBconst $ A.BconstUint96 s I.C_u128 s -> return $ A.C_simple $ A.CpBconst $ A.BconstUint128 s I.C_s8 s -> return $ A.C_simple $ A.CpBconst $ A.BconstInt8 s I.C_s16 s -> return $ A.C_simple $ A.CpBconst $ A.BconstInt16 s I.C_s32 s -> return $ A.C_simple $ A.CpBconst $ A.BconstInt32 s I.C_s64 s -> return $ A.C_simple $ A.CpBconst $ A.BconstInt64 s I.C_s96 s -> return $ A.C_simple $ A.CpBconst $ A.BconstInt96 s I.C_s128 s -> return $ A.C_simple $ A.CpBconst $ A.BconstInt128 s (I.C_struct b fs) -> Md.liftM (A.C_complex . (A.Cstruct b)) (mapM convert fs) (I.C_vector fs) -> Md.liftM (A.C_complex . A.Cvector) (mapM convert fs) (I.C_array fs) -> Md.liftM (A.C_complex . A.Carray) (mapM convert fs) (I.C_vectorN n fs) -> do { v <- convert fs ; return (A.C_complex $ A.Cvector $ (fmap (\_ -> v) [1..n])) } (I.C_arrayN n fs) -> do { v <- convert fs ; return (A.C_complex $ A.Carray $ (fmap (\_ -> v) [1..n])) } I.C_localId a -> return $ A.C_localId a I.C_labelId a -> Md.liftM A.C_labelId (convert a) I.C_block g a -> do { a' <- convert_to_PercentLabel a ; return $ A.C_blockAddress g a' } I.C_add nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Add (cnowrap nw) (tconvert () t)) (convert u1) (convert u2)) I.C_sub nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Sub (cnowrap nw) (tconvert () t)) (convert u1) (convert u2)) I.C_mul nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Mul (cnowrap nw) (tconvert () t)) (convert u1) (convert u2)) I.C_udiv nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Udiv (cexact nw) (tconvert () t)) (convert u1) (convert u2)) I.C_sdiv nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Sdiv (cexact nw) (tconvert () t)) (convert u1) (convert u2)) I.C_urem t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Urem [] (tconvert () t)) (convert u1) (convert u2)) I.C_srem t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Srem [] (tconvert () t)) (convert u1) (convert u2)) I.C_shl nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Shl (cnowrap nw) (tconvert () t)) (convert u1) (convert u2)) I.C_lshr nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Lshr (cexact nw) (tconvert () t)) (convert u1) (convert u2)) I.C_ashr nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Ashr (cexact nw) (tconvert () t)) (convert u1) (convert u2)) I.C_and t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.And [] (tconvert () t)) (convert u1) (convert u2)) I.C_or t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Or [] (tconvert () t)) (convert u1) (convert u2)) I.C_xor t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Xor [] (tconvert () t)) (convert u1) (convert u2)) I.C_add_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Add (cnowrap nw) (tconvert () t)) (convert u1) (convert u2)) I.C_sub_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Sub (cnowrap nw) (tconvert () t)) (convert u1) (convert u2)) I.C_mul_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) (Md.liftM2 (A.IbinExpr A.Mul (cnowrap nw) (tconvert () t)) (convert u1) (convert u2)) I.C_udiv_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Udiv (cexact nw) (tconvert () t)) (convert u1) (convert u2) I.C_sdiv_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Sdiv (cexact nw) (tconvert () t)) (convert u1) (convert u2) I.C_urem_V t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Urem [] (tconvert () t)) (convert u1) (convert u2) I.C_srem_V t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Srem [] (tconvert () t)) (convert u1) (convert u2) I.C_shl_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Shl (cnowrap nw) (tconvert () t)) (convert u1) (convert u2) I.C_lshr_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Lshr (cexact nw) (tconvert () t)) (convert u1) (convert u2) I.C_ashr_V nw t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Ashr (cexact nw) (tconvert () t)) (convert u1) (convert u2) I.C_and_V t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.And [] (tconvert () t)) (convert u1) (convert u2) I.C_or_V t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Or [] (tconvert () t)) (convert u1) (convert u2) I.C_xor_V t u1 u2 -> Md.liftM (A.C_binexp . A.Ie) $ Md.liftM2 (A.IbinExpr A.Xor [] (tconvert () t)) (convert u1) (convert u2) I.C_fadd fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fadd fg (tconvert () t)) (convert u1) (convert u2) I.C_fsub fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fsub fg (tconvert () t)) (convert u1) (convert u2) I.C_fmul fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fmul fg (tconvert () t)) (convert u1) (convert u2) I.C_fdiv fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fdiv fg (tconvert () t)) (convert u1) (convert u2) I.C_frem fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Frem fg (tconvert () t)) (convert u1) (convert u2) I.C_fadd_V fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fadd fg (tconvert () t)) (convert u1) (convert u2) I.C_fsub_V fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fsub fg (tconvert () t)) (convert u1) (convert u2) I.C_fmul_V fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fmul fg (tconvert () t)) (convert u1) (convert u2) I.C_fdiv_V fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Fdiv fg (tconvert () t)) (convert u1) (convert u2) I.C_frem_V fg t u1 u2 -> Md.liftM (A.C_binexp . A.Fe) $ Md.liftM2 (A.FbinExpr A.Frem fg (tconvert () t)) (convert u1) (convert u2) I.C_trunc (I.T t0 u0) dt0 -> mkConversion (A.Trunc, tconvert () t0, u0, tconvert () dt0) I.C_zext (I.T t0 u0) dt0 -> mkConversion (A.Zext, tconvert () t0, u0, tconvert () dt0) I.C_sext (I.T t0 u0) dt0 -> mkConversion (A.Sext, tconvert () t0, u0, tconvert () dt0) I.C_fptrunc (I.T t0 u0) dt0 -> mkConversion (A.FpTrunc, tconvert () t0, u0, tconvert () dt0) I.C_fpext (I.T t0 u0) dt0 -> mkConversion (A.FpExt, tconvert () t0, u0, tconvert () dt0) I.C_fptoui (I.T t0 u0) dt0 -> mkConversion (A.FpToUi, tconvert () t0, u0, tconvert () dt0) I.C_fptosi (I.T t0 u0) dt0 -> mkConversion (A.FpToSi, tconvert () t0, u0, tconvert () dt0) I.C_uitofp (I.T t0 u0) dt0 -> mkConversion (A.UiToFp, tconvert () t0, u0, tconvert () dt0) I.C_sitofp (I.T t0 u0) dt0 -> mkConversion (A.SiToFp, tconvert () t0, u0, tconvert () dt0) I.C_ptrtoint (I.T t0 u0) dt0 -> mkConversion (A.PtrToInt, tconvert () t0, u0, tconvert () dt0) I.C_inttoptr (I.T t0 u0) dt0 -> mkConversion (A.IntToPtr, tconvert () t0, u0, tconvert () dt0) I.C_addrspacecast (I.T t0 u0) dt0 -> mkConversion (A.AddrSpaceCast, tconvert () t0, u0, tconvert () dt0) I.C_bitcast (I.T t0 u0) dt0 -> mkConversion (A.Bitcast, tconvert () t0, u0, tconvert () dt0) I.C_trunc_V (I.T t0 u0) dt0 -> mkConversion (A.Trunc, tconvert () t0, u0, tconvert () dt0) I.C_zext_V (I.T t0 u0) dt0 -> mkConversion (A.Zext, tconvert () t0, u0, tconvert () dt0) I.C_sext_V (I.T t0 u0) dt0 -> mkConversion (A.Sext, tconvert () t0, u0, tconvert () dt0) I.C_fptrunc_V (I.T t0 u0) dt0 -> mkConversion (A.FpTrunc, tconvert () t0, u0, tconvert () dt0) I.C_fpext_V (I.T t0 u0) dt0 -> mkConversion (A.FpExt, tconvert () t0, u0, tconvert () dt0) I.C_fptoui_V (I.T t0 u0) dt0 -> mkConversion (A.FpToUi, tconvert () t0, u0, tconvert () dt0) I.C_fptosi_V (I.T t0 u0) dt0 -> mkConversion (A.FpToSi, tconvert () t0, u0, tconvert () dt0) I.C_uitofp_V (I.T t0 u0) dt0 -> mkConversion (A.UiToFp, tconvert () t0, u0, tconvert () dt0) I.C_sitofp_V (I.T t0 u0) dt0 -> mkConversion (A.SiToFp, tconvert () t0, u0, tconvert () dt0) I.C_ptrtoint_V (I.T t0 u0) dt0 -> mkConversion (A.PtrToInt, tconvert () t0, u0, tconvert () dt0) I.C_inttoptr_V (I.T t0 u0) dt0 -> mkConversion (A.IntToPtr, tconvert () t0, u0, tconvert () dt0) I.C_addrspacecast_V (I.T t0 u0) dt0 -> mkConversion (A.AddrSpaceCast, tconvert () t0, u0, tconvert () dt0) I.C_getelementptr b u us -> do { ua <- convert u ; usa <- mapM convert us ; return $ A.C_gep $ A.GetElementPtr b (A.Pointer ua) usa } I.C_getelementptr_V b u us -> do { ua <- convert u ; usa <- mapM convert us ; return $ A.C_gep $ A.GetElementPtr b (A.Pointer ua) usa } I.C_select_I a -> Md.liftM A.C_select (convert a) I.C_select_F a -> Md.liftM A.C_select (convert a) I.C_select_P a -> Md.liftM A.C_select (convert a) I.C_select_First cnd t f -> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.C_select (A.Select cnda ta fa) } I.C_select_VI a -> Md.liftM A.C_select (convert a) I.C_select_VF a -> Md.liftM A.C_select (convert a) I.C_select_VP a -> Md.liftM A.C_select (convert a) I.C_icmp a -> Md.liftM A.C_icmp (convert a) I.C_icmp_V a -> Md.liftM A.C_icmp (convert a) I.C_fcmp a -> Md.liftM A.C_fcmp (convert a) I.C_fcmp_V a -> Md.liftM A.C_fcmp (convert a) I.C_shufflevector_I a -> Md.liftM A.C_shufflevector (convert a) I.C_shufflevector_F a -> Md.liftM A.C_shufflevector (convert a) I.C_shufflevector_P a -> Md.liftM A.C_shufflevector (convert a) I.C_extractvalue a -> Md.liftM A.C_extractvalue (convert a) I.C_insertvalue a -> Md.liftM A.C_insertvalue (convert a) I.C_extractelement_I a -> Md.liftM A.C_extractelement (convert a) I.C_extractelement_F a -> Md.liftM A.C_extractelement (convert a) I.C_extractelement_P a -> Md.liftM A.C_extractelement (convert a) I.C_insertelement_I a -> Md.liftM A.C_insertelement (convert a) I.C_insertelement_F a -> Md.liftM A.C_insertelement (convert a) I.C_insertelement_P a -> Md.liftM A.C_insertelement (convert a) instance Conversion I.MdVar (Rm A.MdVar) where convert (I.MdVar s) = return $ A.MdVar s instance Conversion I.MdNode (Rm A.MdNode) where convert (I.MdNode s) = return $ A.MdNode s instance Conversion I.MetaConst (Rm A.MetaConst) where convert (I.McStruct c) = mapM convert c >>= return . A.McStruct convert (I.McString s) = return $ A.McString s convert (I.McMn n) = convert n >>= return . A.McMn convert (I.McMv n) = convert n >>= return . A.McMv convert (I.McRef i) = return $ A.McRef i convert (I.McSimple sc) = Md.liftM A.McSimple (convert sc) instance Conversion I.MetaKindedConst (Rm A.MetaKindedConst) where convert x = case x of (I.MetaKindedConst mk mc) -> Md.liftM (A.MetaKindedConst (tconvert () mk)) (convert mc) I.UnmetaKindedNull -> return A.UnmetaKindedNull instance Conversion I.FunName (Rm A.FunName) where convert (I.FunNameGlobal g) = return $ A.FunNameGlobal g convert (I.FunNameString s) = return $ A.FunNameString s instance Conversion I.Value (Rm A.Value) where convert (I.Val_ssa a) = return $ A.Val_local a convert (I.Val_const a) = Md.liftM A.Val_const (convert a) instance Conversion I.CallSiteType (Rm A.Type) where convert t = case t of I.CallSiteRet x -> return $ tconvert () x I.CallSiteFun ft as -> return $ tconvert () (I.Tpointer (I.ucast ft) as) instance Conversion I.CallSite (Rm A.CallSite) where convert (I.CsFun cc pa t fn aps fa) = do { fna <- convert fn ; apsa <- mapM convert aps ; ta <- convert t ; return $ A.CsFun cc pa ta fna apsa fa } convert (I.CsAsm t dia b1 b2 qs1 qs2 as fa) = do { asa <- mapM convert as ; ta <- convert t ; return $ A.CsAsm ta dia b1 b2 qs1 qs2 asa fa } convert (I.CsConversion pa t cv as fa) = do { cva <- convert cv ; asa <- mapM convert as ; ta <- convert t ; return $ A.CsConversion pa ta cva asa fa } convert (I.CsConversionV pa t cv as fa) = do { cva <- convert cv ; asa <- mapM convert as ; ta <- convert t ; return $ A.CsConversion pa ta cva asa fa } instance Conversion I.Clause (Rm A.Clause) where convert (I.Catch tv) = convert tv >>= \tv' -> return $ A.Catch tv' convert (I.Filter tc) = convert tc >>= \tc' -> return $ A.Filter tc' convert (I.CcoS tc) = convert tc >>= return . A.Cco convert (I.CcoV tc) = convert tc >>= return . A.Cco instance Conversion I.GlobalOrLocalId (Rm A.GlobalOrLocalId) where convert g = return g instance Conversion I.PersFn (Rm A.PersFn) where convert (I.PersFnId s) = return $ A.PersFnId $ s convert (I.PersFnCastS c) = convert c >>= return . A.PersFnCast convert (I.PersFnCastV c) = convert c >>= return . A.PersFnCast convert (I.PersFnUndef) = return $ A.PersFnUndef convert (I.PersFnNull) = return $ A.PersFnNull convert (I.PersFnConst c) = Md.liftM A.PersFnConst (convert c) instance Conversion I.CInst (Rm A.ComputingInst) where convert cinst = case cinst of I.I_alloca mar t mtv ma lhs -> do { mtva <- maybeM convert mtv ; return $ A.ComputingInst (Just lhs) $ A.RmO $ A.Alloca mar (tconvert () t) mtva ma } I.I_load atom tv aa nonterm invr nonull lhs -> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) $ A.RmO $ A.Load atom (A.Pointer tva) aa nonterm invr nonull } I.I_loadatomic atom v tv aa lhs -> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) $ A.RmO $ A.LoadAtomic atom v (A.Pointer tva) aa } I.I_store atom tv1 tv2 aa nonterm -> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; return $ A.ComputingInst Nothing (A.RmO $ A.Store atom tv1a (A.Pointer tv2a) aa nonterm) } I.I_storeatomic atom v tv1 tv2 aa -> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; return $ A.ComputingInst Nothing (A.RmO $ A.StoreAtomic atom v tv1a (A.Pointer tv2a) aa) } I.I_cmpxchg_I wk b1 tv1 tv2 tv3 b2 sord ford lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; tv3a <- convert tv3 ; return $ A.ComputingInst (Just lhs) (A.RmO $ A.CmpXchg wk b1 (A.Pointer tv1a) tv2a tv3a b2 sord ford) } I.I_cmpxchg_F wk b1 tv1 tv2 tv3 b2 sord ford lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; tv3a <- convert tv3 ; return $ A.ComputingInst (Just lhs) (A.RmO $ A.CmpXchg wk b1 (A.Pointer tv1a) tv2a tv3a b2 sord ford) } I.I_cmpxchg_P wk b1 tv1 tv2 tv3 b2 sord ford lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; tv3a <- convert tv3 ; return $ A.ComputingInst (Just lhs) (A.RmO $ A.CmpXchg wk b1 (A.Pointer tv1a) tv2a tv3a b2 sord ford) } I.I_atomicrmw b1 op tv1 tv2 b2 mf lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; return $ A.ComputingInst (Just lhs) (A.RmO $ A.AtomicRmw b1 op (A.Pointer tv1a) tv2a b2 mf) } I.I_fence b fo -> return $ A.ComputingInst Nothing $ A.RmO $ A.Fence b fo I.I_va_arg tv t lhs-> do { tv1 <- convert tv ; return $ A.ComputingInst (Just lhs) $ A.RvA $ A.VaArg tv1 (tconvert () t) } I.I_va_start (I.T t v) -> do { let t1 = tconvert () t ; va <- convert v ; return $ A.ComputingInst Nothing $ A.Call A.TcNon $ A.CsFun Nothing [] A.Tvoid (A.FunNameGlobal $ A.GolG $ A.GlobalIdAlphaNum "llvm.va_start") [A.ActualParamData t1 [] Nothing va []] [] } I.I_va_end (I.T t v) -> do { let t1 = tconvert () t ; va <- convert v ; return $ A.ComputingInst Nothing $ A.Call A.TcNon $ A.CsFun Nothing [] A.Tvoid (A.FunNameGlobal $ A.GolG $ A.GlobalIdAlphaNum "llvm.va_end") [A.ActualParamData t1 [] Nothing va []] [] } I.I_landingpad t1 t2 pf b cs lhs-> do { pfa <- convert pf ; csa <- mapM convert cs ; return $ A.ComputingInst (Just lhs) (A.RlP $ A.LandingPad (tconvert () t1) (tconvert () t2) pfa b csa) } I.I_extractelement_I tv1 tv2 lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; return $ A.ComputingInst (Just lhs) (A.ReE $ A.ExtractElement tv1a tv2a) } I.I_extractelement_F tv1 tv2 lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; return $ A.ComputingInst (Just lhs) (A.ReE $ A.ExtractElement tv1a tv2a) } I.I_extractelement_P tv1 tv2 lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; return $ A.ComputingInst (Just lhs) (A.ReE $ A.ExtractElement tv1a tv2a) } I.I_extractvalue tv1 idx lhs-> do { tv1a <- convert tv1 ; return $ A.ComputingInst (Just lhs) (A.ReV $ A.ExtractValue tv1a idx) } I.I_getelementptr b ptr idx lhs-> do { ptra <- convert ptr ; idxa <- mapM convert idx ; return $ A.ComputingInst (Just lhs) (A.Re $ A.EgEp $ A.GetElementPtr b (A.Pointer ptra) idxa) } I.I_getelementptr_V b ptr idx lhs -> do { ptra <- convert ptr ; idxa <- mapM convert idx ; return $ A.ComputingInst (Just lhs) (A.Re $ A.EgEp $ A.GetElementPtr b (A.Pointer ptra) idxa) } I.I_icmp op t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.EiC $ A.Icmp op (tconvert () t) v1a v2a) } I.I_icmp_V op t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.EiC $ A.Icmp op (tconvert () t) v1a v2a) } I.I_fcmp op t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.EfC $ A.Fcmp op (tconvert () t) v1a v2a) } I.I_fcmp_V op t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.EfC $ A.Fcmp op (tconvert () t) v1a v2a) } I.I_add n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Add (cnowrap n) (tconvert () t) v1a v2a) } I.I_sub n t v1 v2 lhs -> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Sub (cnowrap n) (tconvert () t) v1a v2a) } I.I_mul n t v1 v2 lhs -> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Mul (cnowrap n) (tconvert () t) v1a v2a) } I.I_udiv n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Udiv (cexact n) (tconvert () t) v1a v2a) } I.I_sdiv n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Sdiv (cexact n) (tconvert () t) v1a v2a) } I.I_urem t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Urem [] (tconvert () t) v1a v2a) } I.I_srem t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Srem [] (tconvert () t) v1a v2a) } I.I_shl n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Shl (cnowrap n) (tconvert () t) v1a v2a) } I.I_lshr n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Lshr (cexact n) (tconvert () t) v1a v2a) } I.I_ashr n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Ashr (cexact n) (tconvert () t) v1a v2a) } I.I_and t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.And [] (tconvert () t) v1a v2a) } I.I_or t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Or [] (tconvert () t) v1a v2a) } I.I_xor t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Xor [] (tconvert () t) v1a v2a) } I.I_add_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Add (cnowrap n) (tconvert () t) v1a v2a) } I.I_sub_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Sub (cnowrap n) (tconvert () t) v1a v2a) } I.I_mul_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Mul (cnowrap n) (tconvert () t) v1a v2a) } I.I_udiv_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Udiv (cexact n) (tconvert () t) v1a v2a) } I.I_sdiv_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Sdiv (cexact n) (tconvert () t) v1a v2a) } I.I_urem_V t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Urem [] (tconvert () t) v1a v2a) } I.I_srem_V t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Srem [] (tconvert () t) v1a v2a) } I.I_shl_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Shl (cnowrap n) (tconvert () t) v1a v2a) } I.I_lshr_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Lshr (cexact n) (tconvert () t) v1a v2a) } I.I_ashr_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Ashr (cexact n) (tconvert () t) v1a v2a) } I.I_and_V t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.And [] (tconvert () t) v1a v2a) } I.I_or_V t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Or [] (tconvert () t) v1a v2a) } I.I_xor_V t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Ie $ A.IbinExpr A.Xor [] (tconvert () t) v1a v2a) } I.I_fadd n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_fsub n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_fmul n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_fdiv n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_frem n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_fadd_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_fsub_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_fmul_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_fdiv_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_frem_V n t v1 v2 lhs-> do { v1a <- convert v1 ; v2a <- convert v2 ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Eb $ A.Fe $ A.FbinExpr A.Fadd n (tconvert () t) v1a v2a) } I.I_trunc tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Trunc tva (tconvert () dt)) } I.I_zext tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Zext tva (tconvert () dt)) } I.I_sext tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Sext tva (tconvert () dt)) } I.I_fptrunc tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpTrunc tva (tconvert () dt)) } I.I_fpext tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpExt tva (tconvert () dt)) } I.I_fptoui tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpToUi tva (tconvert () dt)) } I.I_fptosi tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpToSi tva (tconvert () dt)) } I.I_uitofp tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.UiToFp tva (tconvert () dt)) } I.I_sitofp tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.SiToFp tva (tconvert () dt)) } I.I_ptrtoint tv dt lhs -> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.PtrToInt tva (tconvert () dt)) } I.I_inttoptr tv dt lhs -> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.IntToPtr tva (tconvert () dt)) } I.I_bitcast tv dt lhs -> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Bitcast tva (tconvert () dt)) } I.I_bitcast_D tv dt lhs -> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Bitcast tva (tconvert () dt)) } I.I_addrspacecast tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.AddrSpaceCast tva (tconvert () dt)) } I.I_trunc_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Trunc tva (tconvert () dt)) } I.I_zext_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Zext tva (tconvert () dt)) } I.I_sext_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.Sext tva (tconvert () dt)) } I.I_fptrunc_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpTrunc tva (tconvert () dt)) } I.I_fpext_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpExt tva (tconvert () dt)) } I.I_fptoui_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpToUi tva (tconvert () dt)) } I.I_fptosi_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.FpToSi tva (tconvert () dt)) } I.I_uitofp_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.UiToFp tva (tconvert () dt)) } I.I_sitofp_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.SiToFp tva (tconvert () dt)) } I.I_ptrtoint_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.PtrToInt tva (tconvert () dt)) } I.I_inttoptr_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.IntToPtr tva (tconvert () dt)) } I.I_addrspacecast_V tv dt lhs-> do { tva <- convert tv ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Ec $ A.Conversion A.AddrSpaceCast tva (tconvert () dt)) } I.I_select_I cnd t f lhs-> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Es $ A.Select cnda ta fa) } I.I_select_F cnd t f lhs-> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Es $ A.Select cnda ta fa) } I.I_select_P cnd t f lhs-> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Es $ A.Select cnda ta fa) } I.I_select_First cnd t f lhs-> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Es $ A.Select cnda ta fa) } I.I_select_VI cnd t f lhs-> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Es $ A.Select cnda ta fa) } I.I_select_VF cnd t f lhs-> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Es $ A.Select cnda ta fa) } I.I_select_VP cnd t f lhs-> do { cnda <- convert cnd ; ta <- convert t ; fa <- convert f ; return $ A.ComputingInst (Just lhs) (A.Re $ A.Es $ A.Select cnda ta fa) } I.I_insertelement_I vtv tv idx lhs-> do { vtva <- convert vtv ; tva <- convert tv ; idxa <- convert idx ; return $ A.ComputingInst (Just lhs) (A.RiE $ A.InsertElement vtva tva idxa) } I.I_insertelement_F vtv tv idx lhs-> do { vtva <- convert vtv ; tva <- convert tv ; idxa <- convert idx ; return $ A.ComputingInst (Just lhs) (A.RiE $ A.InsertElement vtva tva idxa) } I.I_insertelement_P vtv tv idx lhs-> do { vtva <- convert vtv ; tva <- convert tv ; idxa <- convert idx ; return $ A.ComputingInst (Just lhs) (A.RiE $ A.InsertElement vtva tva idxa) } I.I_shufflevector_I tv1 tv2 tv3 lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; tv3a <- convert tv3 ; return $ A.ComputingInst (Just lhs) (A.RsV $ A.ShuffleVector tv1a tv2a tv3a) } I.I_shufflevector_F tv1 tv2 tv3 lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; tv3a <- convert tv3 ; return $ A.ComputingInst (Just lhs) (A.RsV $ A.ShuffleVector tv1a tv2a tv3a) } I.I_shufflevector_P tv1 tv2 tv3 lhs-> do { tv1a <- convert tv1 ; tv2a <- convert tv2 ; tv3a <- convert tv3 ; return $ A.ComputingInst (Just lhs) (A.RsV $ A.ShuffleVector tv1a tv2a tv3a) } I.I_insertvalue vtv tv idx lhs-> do { vtva <- convert vtv ; tva <- convert tv ; return $ A.ComputingInst (Just lhs) $ A.RiV $ A.InsertValue vtva tva idx } I.I_call_fun tc cc pa cstype fn ap fna lhs-> do { csa <- convert (I.CsFun cc pa cstype fn ap fna) ; return $ A.ComputingInst lhs $ A.Call tc csa } I.I_call_other tc cs lhs-> do { csa <- convert cs ; return $ A.ComputingInst lhs $ A.Call tc csa } I.I_llvm_dbg_declare ap -> do { apa <- mapM convert ap ; return $ A.ComputingInst Nothing $ A.Call A.TcNon $ A.CsFun Nothing [] A.Tvoid (A.FunNameGlobal $ A.GolG $ A.GlobalIdAlphaNum "llvm.dbg.declare") apa [] } I.I_llvm_dbg_value ap -> do { apa <- mapM convert ap ; return $ A.ComputingInst Nothing $ A.Call A.TcNon $ A.CsFun Nothing [] A.Tvoid (A.FunNameGlobal $ A.GolG $ A.GlobalIdAlphaNum "llvm.dbg.value") apa [] } I.I_llvm_memcpy memLen tv1 tv2 tv3 tv4 tv5 -> do { (A.Typed t1 v1) <- convert tv1 ; (A.Typed t2 v2) <- convert tv2 ; (A.Typed t3 v3) <- convert tv3 ; (A.Typed t4 v4) <- convert tv4 ; (A.Typed t5 v5) <- convert tv5 ; let nm = case memLen of I.MemLenI32 -> "llvm.memcpy.p0i8.p0i8.i32" I.MemLenI64 -> "llvm.memcpy.p0i8.p0i8.i64" ; return $ A.ComputingInst Nothing $ A.Call A.TcNon $ A.CsFun Nothing [] A.Tvoid (A.FunNameGlobal $ A.GolG $ A.GlobalIdAlphaNum nm) [A.ActualParamData t1 [] Nothing v1 [] ,A.ActualParamData t2 [] Nothing v2 [] ,A.ActualParamData t3 [] Nothing v3 [] ,A.ActualParamData t4 [] Nothing v4 [] ,A.ActualParamData t5 [] Nothing v5 [] ] [] } instance Conversion I.ActualParam (Rm A.ActualParam) where convert x = case x of (I.ActualParamData t pa1 ma v pa2) -> do { va <- convert v ; return $ A.ActualParamData (tconvert () t) pa1 ma va pa2 } (I.ActualParamLabel t pa1 ma v pa2) -> do { va <- convert v ; return $ A.ActualParamData (tconvert () t) pa1 ma va pa2 } (I.ActualParamMeta mc) -> Md.liftM (A.ActualParamMeta) (convert mc) instance Conversion I.Aliasee (Rm A.Aliasee) where convert (I.AtV tv) = Md.liftM A.AtV (convert tv) convert (I.Ac a) = Md.liftM A.Ac (convert a) convert (I.AcV a) = Md.liftM A.Ac (convert a) convert (I.Agep a) = Md.liftM A.AgEp (convert a) convert (I.AgepV a) = Md.liftM A.AgEp (convert a) instance Conversion I.Prefix (Rm A.Prefix) where convert (I.Prefix n) = Md.liftM A.Prefix (convert n) instance Conversion I.Prologue (Rm A.Prologue) where convert (I.Prologue n) = Md.liftM A.Prologue (convert n) instance Conversion I.TypedConstOrNull (Rm A.TypedConstOrNull) where convert x = case x of I.TypedConst tv -> Md.liftM A.TypedConst (convert tv) I.UntypedNull -> return A.UntypedNull instance Conversion I.FunctionPrototype (Rm A.FunctionPrototype) where convert (I.FunctionPrototype f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f10a f11 f12 f13 f14) = do { f13' <- convert f13 ; f14' <- convert f14 ; return $ A.FunctionPrototype f0 f1 f2 f3 f4 (tconvert () f5) f6 (tconvert () f7) f8 f9 f10 f10a f11 f12 f13' f14' } instance Conversion I.PhiInst (Rm A.PhiInst) where convert (I.PhiInst mg t branches) = Md.liftM (A.PhiInst (Just mg) (tconvert () t)) (mapM (pairM convert convert_to_PercentLabel) branches) instance Conversion I.TerminatorInst (Rm A.TerminatorInst) where convert (I.RetVoid) = return A.RetVoid convert (I.Return tvs) = Md.liftM A.Return (mapM convert tvs) convert (I.Br t) = Md.liftM A.Br (convert_to_TargetLabel t) convert (I.Cbr cnd t f) = Md.liftM3 A.Cbr (convert cnd) (convert_to_TargetLabel t) (convert_to_TargetLabel f) convert (I.IndirectBr cnd bs) = Md.liftM2 A.IndirectBr (convert cnd) (mapM convert_to_TargetLabel bs) convert (I.Switch cnd d cases) = Md.liftM3 A.Switch (convert cnd) (convert_to_TargetLabel d) (mapM (pairM convert convert_to_TargetLabel) cases) convert (I.Invoke cs t f mg) = Md.liftM3 (A.Invoke mg) (convert cs) (convert_to_TargetLabel t) (convert_to_TargetLabel f) convert (I.InvokeCmd cs t f) = Md.liftM3 (A.Invoke Nothing) (convert cs) (convert_to_TargetLabel t) (convert_to_TargetLabel f) convert (I.Resume tv) = Md.liftM A.Resume (convert tv) convert I.Unreachable = return A.Unreachable convert I.Unwind = return A.Unwind instance Conversion I.Dbg (Rm A.Dbg) where convert (I.Dbg mv mc) = Md.liftM2 A.Dbg (convert mv) (convert mc) instance Conversion I.PhiInstWithDbg (Rm A.PhiInstWithDbg) where convert (I.PhiInstWithDbg ins dbgs) = Md.liftM2 A.PhiInstWithDbg (convert ins) (mapM convert dbgs) instance Conversion I.CInstWithDbg (Rm A.ComputingInstWithDbg) where convert (I.CInstWithDbg ins dbgs) = Md.liftM2 A.ComputingInstWithDbg (convert ins) (mapM convert dbgs) instance Conversion I.TerminatorInstWithDbg (Rm A.TerminatorInstWithDbg) where convert (I.TerminatorInstWithDbg term dbgs) = Md.liftM2 A.TerminatorInstWithDbg (convert term) (mapM convert dbgs) instance Conversion I.TlTriple (Rm A.TlTriple) where convert (I.TlTriple x) = return (A.TlTriple x) instance Conversion I.TlDataLayout (Rm A.TlDataLayout) where convert (I.TlDataLayout x) = return (A.TlDataLayout x) instance Conversion I.TlAlias (Rm A.TlAlias) where convert (I.TlAlias g v dll tlm na l a) = convert a >>= return . (A.TlAlias g v dll tlm na l) instance Conversion I.TlDbgInit (Rm A.TlDbgInit) where convert (I.TlDbgInit s i) = return (A.TlDbgInit s i) instance Conversion I.TlStandaloneMd (Rm A.TlStandaloneMd) where convert (I.TlStandaloneMd s tv) = convert tv >>= return . (A.TlStandaloneMd s) instance Conversion I.TlNamedMd (Rm A.TlNamedMd) where convert (I.TlNamedMd m ns) = do { m' <- convert m ; ns' <- mapM convert ns ; return $ A.TlNamedMd m' ns' } instance Conversion I.TlDeclare (Rm A.TlDeclare) where convert (I.TlDeclare f) = convert f >>= return . A.TlDeclare instance Conversion (I.TlDefine a) (Rm A.TlDefine) where convert (I.TlDefine f elbl g) = do { (bl, bm) <- graphToBlocks g ; f' <- convert f ; elbla <- convert elbl ; let entryblk = case M.lookup elbla bm of Just x -> x Nothing -> error $ "irrefutable: entry block " ++ show elbl ++ " does not exist." ; let bs'' = entryblk:(filter (\x -> x /= entryblk) bl) ; return $ A.TlDefine f' bs'' } -- TODO: this method will NOT emit the new nodes generated by hoopl passes, it should be fixed ASAP. instance Conversion I.TlGlobal (Rm A.TlGlobal) where convert x = case x of (I.TlGlobalDtype a1 a2 a3 a4 a5 a6 a7 a8 a8a a9 a10 a11 a12 a13) -> do { a10a <- maybeM convert a10 ; return $ A.TlGlobal a1 a2 a3 a4 a5 a6 (fmap (tconvert ()) a7) a8 a8a (tconvert () a9) a10a a11 a12 a13 } (I.TlGlobalOpaque a1 a2 a3 a4 a5 a6 a7 a8 a8a a9 a10 a11 a12 a13) -> do { a10a <- maybeM convert a10 ; return $ A.TlGlobal a1 a2 a3 a4 a5 a6 (fmap (tconvert ()) a7) a8 a8a (tconvert () a9) a10a a11 a12 a13 } instance Conversion I.TlTypeDef (Rm A.TlTypeDef) where convert x = case x of (I.TlFunTypeDef lid t) -> return (A.TlTypeDef lid (tconvert () t)) (I.TlDatTypeDef lid t) -> return (A.TlTypeDef lid (tconvert () t)) (I.TlOpqTypeDef lid t) -> return (A.TlTypeDef lid (tconvert () t)) instance Conversion I.TlDepLibs (Rm A.TlDepLibs) where convert (I.TlDepLibs s) = return (A.TlDepLibs s) instance Conversion I.TlUnamedType (Rm A.TlUnamedType) where convert (I.TlUnamedType i t) = return (A.TlUnamedType i (tconvert () t)) instance Conversion I.TlModuleAsm (Rm A.TlModuleAsm) where convert (I.TlModuleAsm s) = return (A.TlModuleAsm s) instance Conversion I.TlAttribute (Rm A.TlAttribute) where convert (I.TlAttribute n l) = return (A.TlAttribute n l) instance Conversion I.TlComdat (Rm A.TlComdat) where convert (I.TlComdat l s) = return (A.TlComdat l s) type Pblock = (A.BlockLabel, [A.PhiInstWithDbg], [A.ComputingInstWithDbg]) getLabelId :: A.BlockLabel -> A.LabelId getLabelId (A.ImplicitBlockLabel _) = error "ImplicitBlockLabel should be normalized" getLabelId (A.ExplicitBlockLabel l) = l convertNode :: I.Node a e x -> Rm ([A.Block], M.Map A.LabelId A.Block, Maybe Pblock) -> Rm ([A.Block], M.Map A.LabelId A.Block, Maybe Pblock) convertNode (I.Nlabel a) p = do { (bl, bs, Nothing) <- p ; a' <- convert_to_BlockLabel a ; return (bl, bs, Just (a', [], [])) } convertNode (I.Pinst a) p = do { (bl, bs, Just (pb, phis, [])) <- p ; a' <- convert a ; return (bl, bs, Just (pb, a':phis, [])) } convertNode (I.Cinst a) p = do { (bl, bs, Just (pb, phis, cs)) <- p ; a' <- convert a ; return (bl, bs, Just (pb, phis, a':cs)) } convertNode (I.Comment a) p = do { (bl, bs, Just (pb, phis, cs)) <- p ; return (bl, bs, Just (pb, phis, (A.ComputingInstWithComment a):cs)) } convertNode (I.Tinst a) p = do { (bl, bs, pb) <- p ; a' <- convert a ; case pb of Nothing -> error "irrefutable" Just (l, phis, cs) -> let blk = A.Block l (reverse phis) (reverse cs) a' in return (blk:bl, M.insert (getLabelId l) blk bs, Nothing) } convertNode (I.Additional _) _ = error "irrefutable:Additional node should be converted to LLVM node" graphToBlocks :: H.Graph (I.Node a) H.C H.C -> Rm ([A.Block], M.Map A.LabelId A.Block) graphToBlocks g = do { (bl, bs, Nothing) <- H.foldGraphNodes convertNode g (return ([], M.empty, Nothing)) ; return (reverse bl, bs) } toplevel2Ast :: I.Toplevel a -> Rm A.Toplevel toplevel2Ast (I.ToplevelTriple q) = Md.liftM A.ToplevelTriple (convert q) toplevel2Ast (I.ToplevelDataLayout q) = Md.liftM A.ToplevelDataLayout (convert q) toplevel2Ast (I.ToplevelAlias g) = Md.liftM A.ToplevelAlias (convert g) toplevel2Ast (I.ToplevelDbgInit s) = Md.liftM A.ToplevelDbgInit (convert s) toplevel2Ast (I.ToplevelStandaloneMd s) = Md.liftM (A.ToplevelStandaloneMd) (convert s) toplevel2Ast (I.ToplevelNamedMd m) = Md.liftM A.ToplevelNamedMd (convert m) toplevel2Ast (I.ToplevelDeclare f) = Md.liftM A.ToplevelDeclare (convert f) toplevel2Ast (I.ToplevelDefine f) = Md.liftM A.ToplevelDefine (convert f) toplevel2Ast (I.ToplevelGlobal s) = Md.liftM A.ToplevelGlobal (convert s) toplevel2Ast (I.ToplevelTypeDef t) = Md.liftM A.ToplevelTypeDef (convert t) toplevel2Ast (I.ToplevelDepLibs qs) = Md.liftM A.ToplevelDepLibs (convert qs) toplevel2Ast (I.ToplevelUnamedType i) = Md.liftM A.ToplevelUnamedType (convert i) toplevel2Ast (I.ToplevelModuleAsm q) = Md.liftM A.ToplevelModuleAsm (convert q) toplevel2Ast (I.ToplevelComdat l) = Md.liftM A.ToplevelComdat (convert l) toplevel2Ast (I.ToplevelAttribute n) = Md.liftM A.ToplevelAttribute (convert n) irToAst :: M.Map H.Label A.LabelId -> I.Module a -> A.Module irToAst iLm (I.Module ts) = runReader (Md.liftM A.Module (mapM toplevel2Ast ts)) iLm