{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections       #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}
{-# LANGUAGE ViewPatterns        #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module      : Data.Array.Accelerate.LLVM.CodeGen.Exp
-- Copyright   : [2015..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--

module Data.Array.Accelerate.LLVM.CodeGen.Exp
  where

import Data.Array.Accelerate.AST
import Data.Array.Accelerate.AST.LeftHandSide
import Data.Array.Accelerate.AST.Var
import Data.Array.Accelerate.Analysis.Match
import Data.Array.Accelerate.Error
import Data.Array.Accelerate.Representation.Array                   ( Array, arrayRshape )
import Data.Array.Accelerate.Representation.Shape
import Data.Array.Accelerate.Representation.Slice
import Data.Array.Accelerate.Representation.Type
import Data.Array.Accelerate.Representation.Vec
import Data.Array.Accelerate.Type
import qualified Data.Array.Accelerate.Sugar.Foreign                as A

import Data.Array.Accelerate.LLVM.CodeGen.Array
import Data.Array.Accelerate.LLVM.CodeGen.Base
import Data.Array.Accelerate.LLVM.CodeGen.Constant
import Data.Array.Accelerate.LLVM.CodeGen.Environment
import Data.Array.Accelerate.LLVM.CodeGen.IR
import Data.Array.Accelerate.LLVM.CodeGen.Monad
import Data.Array.Accelerate.LLVM.CodeGen.Sugar
import Data.Array.Accelerate.LLVM.Foreign
import qualified Data.Array.Accelerate.LLVM.CodeGen.Arithmetic      as A
import qualified Data.Array.Accelerate.LLVM.CodeGen.Loop            as L

import Data.Primitive.Vec

import LLVM.AST.Type.Instruction
import LLVM.AST.Type.Operand                                        ( Operand )

import Control.Applicative                                          hiding ( Const )
import Control.Monad
import Prelude                                                      hiding ( exp, any )
import qualified Data.IntMap                                        as IM

import GHC.TypeNats


-- Scalar expressions
-- ==================

{-# INLINEABLE llvmOfFun1 #-}
llvmOfFun1
    :: (HasCallStack, Foreign arch)
    => Fun aenv (a -> b)
    -> Gamma aenv
    -> IRFun1 arch aenv (a -> b)
llvmOfFun1 :: Fun aenv (a -> b) -> Gamma aenv -> IRFun1 arch aenv (a -> b)
llvmOfFun1 (Lam ELeftHandSide a () env'
lhs (Body OpenExp env' aenv t1
body)) Gamma aenv
aenv = (Operands a -> IROpenExp arch ((), a) aenv t1)
-> IROpenFun1 arch () aenv (a -> t1)
forall a arch env aenv b.
(Operands a -> IROpenExp arch (env, a) aenv b)
-> IROpenFun1 arch env aenv (a -> b)
IRFun1 ((Operands a -> IROpenExp arch ((), a) aenv t1)
 -> IROpenFun1 arch () aenv (a -> t1))
-> (Operands a -> IROpenExp arch ((), a) aenv t1)
-> IROpenFun1 arch () aenv (a -> t1)
forall a b. (a -> b) -> a -> b
$ \Operands a
x -> OpenExp env' aenv t1
-> Val env' -> Gamma aenv -> IROpenExp arch ((), a) aenv t1
forall arch env aenv _t.
(HasCallStack, Foreign arch) =>
OpenExp env aenv _t
-> Val env -> Gamma aenv -> IROpenExp arch env aenv _t
llvmOfOpenExp OpenExp env' aenv t1
body (Val ()
Empty Val () -> (ELeftHandSide a () env', Operands a) -> Val env'
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
`pushE` (ELeftHandSide a () env'
lhs, Operands a
x)) Gamma aenv
aenv
llvmOfFun1  Fun aenv (a -> b)
_                    Gamma aenv
_    = String -> IRFun1 arch aenv (a -> b)
forall a. HasCallStack => String -> a
internalError String
"impossible evaluation"

{-# INLINEABLE llvmOfFun2 #-}
llvmOfFun2
    :: (HasCallStack, Foreign arch)
    => Fun aenv (a -> b -> c)
    -> Gamma aenv
    -> IRFun2 arch aenv (a -> b -> c)
llvmOfFun2 :: Fun aenv (a -> b -> c)
-> Gamma aenv -> IRFun2 arch aenv (a -> b -> c)
llvmOfFun2 (Lam ELeftHandSide a () env'
lhs1 (Lam ELeftHandSide a env' env'
lhs2 (Body OpenExp env' aenv t1
body))) Gamma aenv
aenv = (Operands a -> Operands a -> IROpenExp arch (((), a), a) aenv t1)
-> IROpenFun2 arch () aenv (a -> a -> t1)
forall a b arch env aenv c.
(Operands a -> Operands b -> IROpenExp arch ((env, a), b) aenv c)
-> IROpenFun2 arch env aenv (a -> b -> c)
IRFun2 ((Operands a -> Operands a -> IROpenExp arch (((), a), a) aenv t1)
 -> IROpenFun2 arch () aenv (a -> a -> t1))
-> (Operands a
    -> Operands a -> IROpenExp arch (((), a), a) aenv t1)
-> IROpenFun2 arch () aenv (a -> a -> t1)
forall a b. (a -> b) -> a -> b
$ \Operands a
x Operands a
y -> OpenExp env' aenv t1
-> Val env' -> Gamma aenv -> IROpenExp arch (((), a), a) aenv t1
forall arch env aenv _t.
(HasCallStack, Foreign arch) =>
OpenExp env aenv _t
-> Val env -> Gamma aenv -> IROpenExp arch env aenv _t
llvmOfOpenExp OpenExp env' aenv t1
body (Val ()
Empty Val () -> (ELeftHandSide a () env', Operands a) -> Val env'
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
`pushE` (ELeftHandSide a () env'
lhs1, Operands a
x) Val env' -> (ELeftHandSide a env' env', Operands a) -> Val env'
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
`pushE` (ELeftHandSide a env' env'
lhs2, Operands a
y)) Gamma aenv
aenv
llvmOfFun2 Fun aenv (a -> b -> c)
_                                 Gamma aenv
_    = String -> IRFun2 arch aenv (a -> b -> c)
forall a. HasCallStack => String -> a
internalError String
"impossible evaluation"


-- | Convert an open scalar expression into a sequence of LLVM Operands instructions.
-- Code is generated in depth first order, and uses a monad to collect the
-- sequence of instructions used to construct basic blocks.
--
{-# INLINEABLE llvmOfOpenExp #-}
llvmOfOpenExp
    :: forall arch env aenv _t. (HasCallStack, Foreign arch)
    => OpenExp env aenv _t
    -> Val env
    -> Gamma aenv
    -> IROpenExp arch env aenv _t
llvmOfOpenExp :: OpenExp env aenv _t
-> Val env -> Gamma aenv -> IROpenExp arch env aenv _t
llvmOfOpenExp OpenExp env aenv _t
top Val env
env Gamma aenv
aenv = OpenExp env aenv _t -> IROpenExp arch env aenv _t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv _t
top
  where

    cvtF1 :: OpenFun env aenv (a -> b) -> IROpenFun1 arch env aenv (a -> b)
    cvtF1 :: OpenFun env aenv (a -> b) -> IROpenFun1 arch env aenv (a -> b)
cvtF1 (Lam ELeftHandSide a env env'
lhs (Body OpenExp env' aenv t1
body)) = (Operands a -> IROpenExp arch (env, a) aenv t1)
-> IROpenFun1 arch env aenv (a -> t1)
forall a arch env aenv b.
(Operands a -> IROpenExp arch (env, a) aenv b)
-> IROpenFun1 arch env aenv (a -> b)
IRFun1 ((Operands a -> IROpenExp arch (env, a) aenv t1)
 -> IROpenFun1 arch env aenv (a -> t1))
-> (Operands a -> IROpenExp arch (env, a) aenv t1)
-> IROpenFun1 arch env aenv (a -> t1)
forall a b. (a -> b) -> a -> b
$ \Operands a
x -> OpenExp env' aenv t1
-> Val env' -> Gamma aenv -> IROpenExp arch (env, a) aenv t1
forall arch env aenv _t.
(HasCallStack, Foreign arch) =>
OpenExp env aenv _t
-> Val env -> Gamma aenv -> IROpenExp arch env aenv _t
llvmOfOpenExp OpenExp env' aenv t1
body (Val env
env Val env -> (ELeftHandSide a env env', Operands a) -> Val env'
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
`pushE` (ELeftHandSide a env env'
lhs, Operands a
x)) Gamma aenv
aenv
    cvtF1 OpenFun env aenv (a -> b)
_                     = String -> IROpenFun1 arch env aenv (a -> b)
forall a. HasCallStack => String -> a
internalError String
"impossible evaluation"

    cvtE :: forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
    cvtE :: OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t
exp =
      case OpenExp env aenv t
exp of
        Let ELeftHandSide bnd_t env env'
lhs OpenExp env aenv bnd_t
bnd OpenExp env' aenv t
body            -> do Operands bnd_t
x <- OpenExp env aenv bnd_t -> IROpenExp arch env aenv bnd_t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv bnd_t
bnd
                                          OpenExp env' aenv t
-> Val env' -> Gamma aenv -> IROpenExp arch env aenv t
forall arch env aenv _t.
(HasCallStack, Foreign arch) =>
OpenExp env aenv _t
-> Val env -> Gamma aenv -> IROpenExp arch env aenv _t
llvmOfOpenExp OpenExp env' aenv t
body (Val env
env Val env
-> (ELeftHandSide bnd_t env env', Operands bnd_t) -> Val env'
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
`pushE` (ELeftHandSide bnd_t env env'
lhs, Operands bnd_t
x)) Gamma aenv
aenv
        Evar (Var ScalarType t
_ Idx env t
ix)             -> Operands t -> IROpenExp arch env aenv t
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands t -> IROpenExp arch env aenv t)
-> Operands t -> IROpenExp arch env aenv t
forall a b. (a -> b) -> a -> b
$ Idx env t -> Val env -> Operands t
forall env t. Idx env t -> Val env -> Operands t
prj Idx env t
ix Val env
env
        Const ScalarType t
tp t
c                  -> Operands t -> IROpenExp arch env aenv t
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands t -> IROpenExp arch env aenv t)
-> Operands t -> IROpenExp arch env aenv t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> Operand t -> Operands t
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir ScalarType t
tp (Operand t -> Operands t) -> Operand t -> Operands t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> t -> Operand t
forall a. ScalarType a -> a -> Operand a
scalar ScalarType t
tp t
c
        PrimConst PrimConst t
c                 -> let tp :: ScalarType t
tp = (SingleType t -> ScalarType t
forall a. SingleType a -> ScalarType a
SingleScalarType (SingleType t -> ScalarType t) -> SingleType t -> ScalarType t
forall a b. (a -> b) -> a -> b
$ PrimConst t -> SingleType t
forall a. PrimConst a -> SingleType a
primConstType PrimConst t
c)
                                       in  Operands t -> IROpenExp arch env aenv t
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands t -> IROpenExp arch env aenv t)
-> Operands t -> IROpenExp arch env aenv t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> Operand t -> Operands t
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir ScalarType t
tp (Operand t -> Operands t) -> Operand t -> Operands t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> t -> Operand t
forall a. ScalarType a -> a -> Operand a
scalar ScalarType t
tp (t -> Operand t) -> t -> Operand t
forall a b. (a -> b) -> a -> b
$ PrimConst t -> t
forall t. PrimConst t -> t
primConst PrimConst t
c
        PrimApp PrimFun (a -> t)
f OpenExp env aenv a
x                 -> PrimFun (a -> t) -> OpenExp env aenv a -> IROpenExp arch env aenv t
forall a r.
PrimFun (a -> r) -> OpenExp env aenv a -> IROpenExp arch env aenv r
primFun PrimFun (a -> t)
f OpenExp env aenv a
x
        Undef ScalarType t
tp                    -> Operands t -> IROpenExp arch env aenv t
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands t -> IROpenExp arch env aenv t)
-> Operands t -> IROpenExp arch env aenv t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> Operand t -> Operands t
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir ScalarType t
tp (Operand t -> Operands t) -> Operand t -> Operands t
forall a b. (a -> b) -> a -> b
$ ScalarType t -> Operand t
forall a. ScalarType a -> Operand a
undef ScalarType t
tp
        OpenExp env aenv t
Nil                         -> Operands () -> CodeGen arch (Operands ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands () -> CodeGen arch (Operands ()))
-> Operands () -> CodeGen arch (Operands ())
forall a b. (a -> b) -> a -> b
$ Operands ()
OP_Unit
        Pair OpenExp env aenv t1
e1 OpenExp env aenv t2
e2                  -> CodeGen arch (CodeGen arch (Operands (t1, t2)))
-> CodeGen arch (Operands (t1, t2))
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (CodeGen arch (CodeGen arch (Operands (t1, t2)))
 -> CodeGen arch (Operands (t1, t2)))
-> CodeGen arch (CodeGen arch (Operands (t1, t2)))
-> CodeGen arch (Operands (t1, t2))
forall a b. (a -> b) -> a -> b
$ Operands t1 -> Operands t2 -> CodeGen arch (Operands (t1, t2))
forall t1 t2.
Operands t1 -> Operands t2 -> IROpenExp arch env aenv (t1, t2)
pair (Operands t1 -> Operands t2 -> CodeGen arch (Operands (t1, t2)))
-> CodeGen arch (Operands t1)
-> CodeGen arch (Operands t2 -> CodeGen arch (Operands (t1, t2)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OpenExp env aenv t1 -> CodeGen arch (Operands t1)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t1
e1 CodeGen arch (Operands t2 -> CodeGen arch (Operands (t1, t2)))
-> CodeGen arch (Operands t2)
-> CodeGen arch (CodeGen arch (Operands (t1, t2)))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> OpenExp env aenv t2 -> CodeGen arch (Operands t2)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t2
e2
        VecPack   VecR n s tup
vecr OpenExp env aenv tup
e            -> VecR n s tup -> Operands tup -> CodeGen arch (Operands (Vec n s))
forall (n :: Nat) single tuple.
(HasCallStack, KnownNat n) =>
VecR n single tuple
-> Operands tuple -> CodeGen arch (Operands (Vec n single))
vecPack   VecR n s tup
vecr (Operands tup -> CodeGen arch (Operands (Vec n s)))
-> CodeGen arch (Operands tup) -> CodeGen arch (Operands (Vec n s))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv tup -> CodeGen arch (Operands tup)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv tup
e
        VecUnpack VecR n s t
vecr OpenExp env aenv (Vec n s)
e            -> VecR n s t -> Operands (Vec n s) -> IROpenExp arch env aenv t
forall (n :: Nat) single tuple.
(HasCallStack, KnownNat n) =>
VecR n single tuple
-> Operands (Vec n single) -> CodeGen arch (Operands tuple)
vecUnpack VecR n s t
vecr (Operands (Vec n s) -> IROpenExp arch env aenv t)
-> CodeGen arch (Operands (Vec n s)) -> IROpenExp arch env aenv t
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv (Vec n s) -> CodeGen arch (Operands (Vec n s))
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv (Vec n s)
e
        Foreign TypeR t
tp asm (x -> t)
asm Fun () (x -> t)
f OpenExp env aenv x
x          -> TypeR t
-> asm (x -> t)
-> Fun () (x -> t)
-> Operands x
-> IROpenExp arch env aenv t
forall (asm :: * -> *) b a.
Foreign asm =>
TypeR b
-> asm (a -> b) -> Fun () (a -> b) -> Operands a -> IRExp arch () b
foreignE TypeR t
tp asm (x -> t)
asm Fun () (x -> t)
f (Operands x -> IROpenExp arch env aenv t)
-> CodeGen arch (Operands x) -> IROpenExp arch env aenv t
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv x -> CodeGen arch (Operands x)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv x
x
        Case OpenExp env aenv TAG
tag [(TAG, OpenExp env aenv t)]
xs Maybe (OpenExp env aenv t)
mx              -> TypeR t
-> CodeGen arch (Operands TAG)
-> [(TAG, IROpenExp arch env aenv t)]
-> Maybe (IROpenExp arch env aenv t)
-> IROpenExp arch env aenv t
forall a arch.
TypeR a
-> CodeGen arch (Operands TAG)
-> [(TAG, CodeGen arch (Operands a))]
-> Maybe (CodeGen arch (Operands a))
-> CodeGen arch (Operands a)
A.caseof (OpenExp env aenv t -> TypeR t
forall aenv env t. HasCallStack => OpenExp aenv env t -> TypeR t
expType ((TAG, OpenExp env aenv t) -> OpenExp env aenv t
forall a b. (a, b) -> b
snd ([(TAG, OpenExp env aenv t)] -> (TAG, OpenExp env aenv t)
forall a. [a] -> a
head [(TAG, OpenExp env aenv t)]
xs))) (OpenExp env aenv TAG -> CodeGen arch (Operands TAG)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv TAG
tag) [(TAG
t,OpenExp env aenv t -> IROpenExp arch env aenv t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t
e) | (TAG
t,OpenExp env aenv t
e) <- [(TAG, OpenExp env aenv t)]
xs] ((OpenExp env aenv t -> IROpenExp arch env aenv t)
-> Maybe (OpenExp env aenv t) -> Maybe (IROpenExp arch env aenv t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OpenExp env aenv t -> IROpenExp arch env aenv t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE Maybe (OpenExp env aenv t)
mx)
        Cond OpenExp env aenv TAG
c OpenExp env aenv t
t OpenExp env aenv t
e                  -> TypeR t
-> CodeGen arch (Operands TAG)
-> IROpenExp arch env aenv t
-> IROpenExp arch env aenv t
-> IROpenExp arch env aenv t
forall a.
TypeR a
-> CodeGen arch (Operands TAG)
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
cond (OpenExp env aenv t -> TypeR t
forall aenv env t. HasCallStack => OpenExp aenv env t -> TypeR t
expType OpenExp env aenv t
t) (OpenExp env aenv TAG -> CodeGen arch (Operands TAG)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv TAG
c) (OpenExp env aenv t -> IROpenExp arch env aenv t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t
t) (OpenExp env aenv t -> IROpenExp arch env aenv t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t
e)
        IndexSlice SliceIndex slix t co sh
slice OpenExp env aenv slix
slix OpenExp env aenv sh
sh    -> SliceIndex slix t co sh
-> Operands slix -> Operands sh -> Operands t
forall slix sl co sh.
SliceIndex slix sl co sh
-> Operands slix -> Operands sh -> Operands sl
indexSlice SliceIndex slix t co sh
slice (Operands slix -> Operands sh -> Operands t)
-> CodeGen arch (Operands slix)
-> CodeGen arch (Operands sh -> Operands t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OpenExp env aenv slix -> CodeGen arch (Operands slix)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv slix
slix CodeGen arch (Operands sh -> Operands t)
-> CodeGen arch (Operands sh) -> IROpenExp arch env aenv t
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> OpenExp env aenv sh -> CodeGen arch (Operands sh)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv sh
sh
        IndexFull SliceIndex slix sl co t
slice OpenExp env aenv slix
slix OpenExp env aenv sl
sh     -> SliceIndex slix sl co t
-> Operands slix -> Operands sl -> Operands t
forall slix sl co sh.
SliceIndex slix sl co sh
-> Operands slix -> Operands sl -> Operands sh
indexFull SliceIndex slix sl co t
slice  (Operands slix -> Operands sl -> Operands t)
-> CodeGen arch (Operands slix)
-> CodeGen arch (Operands sl -> Operands t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OpenExp env aenv slix -> CodeGen arch (Operands slix)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv slix
slix CodeGen arch (Operands sl -> Operands t)
-> CodeGen arch (Operands sl) -> IROpenExp arch env aenv t
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> OpenExp env aenv sl -> CodeGen arch (Operands sl)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv sl
sh
        ToIndex ShapeR sh
shr OpenExp env aenv sh
sh OpenExp env aenv sh
ix           -> CodeGen arch (CodeGen arch (Operands Int))
-> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (CodeGen arch (CodeGen arch (Operands Int))
 -> CodeGen arch (Operands Int))
-> CodeGen arch (CodeGen arch (Operands Int))
-> CodeGen arch (Operands Int)
forall a b. (a -> b) -> a -> b
$ ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Int)
forall sh arch.
ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Int)
intOfIndex ShapeR sh
shr (Operands sh -> Operands sh -> CodeGen arch (Operands Int))
-> CodeGen arch (Operands sh)
-> CodeGen arch (Operands sh -> CodeGen arch (Operands Int))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OpenExp env aenv sh -> CodeGen arch (Operands sh)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv sh
sh CodeGen arch (Operands sh -> CodeGen arch (Operands Int))
-> CodeGen arch (Operands sh)
-> CodeGen arch (CodeGen arch (Operands Int))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> OpenExp env aenv sh -> CodeGen arch (Operands sh)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv sh
ix
        FromIndex ShapeR t
shr OpenExp env aenv t
sh OpenExp env aenv Int
ix         -> CodeGen arch (IROpenExp arch env aenv t)
-> IROpenExp arch env aenv t
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (CodeGen arch (IROpenExp arch env aenv t)
 -> IROpenExp arch env aenv t)
-> CodeGen arch (IROpenExp arch env aenv t)
-> IROpenExp arch env aenv t
forall a b. (a -> b) -> a -> b
$ ShapeR t -> Operands t -> Operands Int -> IROpenExp arch env aenv t
forall sh arch.
ShapeR sh
-> Operands sh -> Operands Int -> CodeGen arch (Operands sh)
indexOfInt ShapeR t
shr (Operands t -> Operands Int -> IROpenExp arch env aenv t)
-> IROpenExp arch env aenv t
-> CodeGen arch (Operands Int -> IROpenExp arch env aenv t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OpenExp env aenv t -> IROpenExp arch env aenv t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t
sh CodeGen arch (Operands Int -> IROpenExp arch env aenv t)
-> CodeGen arch (Operands Int)
-> CodeGen arch (IROpenExp arch env aenv t)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> OpenExp env aenv Int -> CodeGen arch (Operands Int)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv Int
ix
        Index ArrayVar aenv (Array dim t)
acc OpenExp env aenv dim
ix                -> ArrayVar aenv (Array dim t)
-> Operands dim -> IROpenExp arch env aenv t
forall sh e.
ArrayVar aenv (Array sh e)
-> Operands sh -> IROpenExp arch env aenv e
index ArrayVar aenv (Array dim t)
acc (Operands dim -> IROpenExp arch env aenv t)
-> CodeGen arch (Operands dim) -> IROpenExp arch env aenv t
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv dim -> CodeGen arch (Operands dim)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv dim
ix
        LinearIndex ArrayVar aenv (Array dim t)
acc OpenExp env aenv Int
ix          -> ArrayVar aenv (Array dim t)
-> Operands Int -> IROpenExp arch env aenv t
forall sh e.
ArrayVar aenv (Array sh e)
-> Operands Int -> IROpenExp arch env aenv e
linearIndex ArrayVar aenv (Array dim t)
acc (Operands Int -> IROpenExp arch env aenv t)
-> CodeGen arch (Operands Int) -> IROpenExp arch env aenv t
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv Int -> CodeGen arch (Operands Int)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv Int
ix
        ShapeSize ShapeR dim
shr OpenExp env aenv dim
sh            -> ShapeR dim -> Operands dim -> CodeGen arch (Operands Int)
forall sh arch.
ShapeR sh -> Operands sh -> CodeGen arch (Operands Int)
shapeSize ShapeR dim
shr (Operands dim -> CodeGen arch (Operands Int))
-> CodeGen arch (Operands dim) -> CodeGen arch (Operands Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv dim -> CodeGen arch (Operands dim)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv dim
sh
        Shape ArrayVar aenv (Array t e)
acc                   -> Operands t -> IROpenExp arch env aenv t
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands t -> IROpenExp arch env aenv t)
-> Operands t -> IROpenExp arch env aenv t
forall a b. (a -> b) -> a -> b
$ ArrayVar aenv (Array t e) -> Operands t
forall sh e. ArrayVar aenv (Array sh e) -> Operands sh
shape ArrayVar aenv (Array t e)
acc
        While OpenFun env aenv (t -> TAG)
c OpenFun env aenv (t -> t)
f OpenExp env aenv t
x                 -> TypeR t
-> IROpenFun1 arch env aenv (t -> TAG)
-> IROpenFun1 arch env aenv (t -> t)
-> IROpenExp arch env aenv t
-> IROpenExp arch env aenv t
forall a.
TypeR a
-> IROpenFun1 arch env aenv (a -> TAG)
-> IROpenFun1 arch env aenv (a -> a)
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
while (OpenExp env aenv t -> TypeR t
forall aenv env t. HasCallStack => OpenExp aenv env t -> TypeR t
expType OpenExp env aenv t
x) (OpenFun env aenv (t -> TAG) -> IROpenFun1 arch env aenv (t -> TAG)
forall a b.
OpenFun env aenv (a -> b) -> IROpenFun1 arch env aenv (a -> b)
cvtF1 OpenFun env aenv (t -> TAG)
c) (OpenFun env aenv (t -> t) -> IROpenFun1 arch env aenv (t -> t)
forall a b.
OpenFun env aenv (a -> b) -> IROpenFun1 arch env aenv (a -> b)
cvtF1 OpenFun env aenv (t -> t)
f) (OpenExp env aenv t -> IROpenExp arch env aenv t
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv t
x)
        Coerce ScalarType a
t1 ScalarType t
t2 OpenExp env aenv a
x              -> ScalarType a
-> ScalarType t -> Operands a -> IROpenExp arch env aenv t
forall a b.
ScalarType a
-> ScalarType b -> Operands a -> IROpenExp arch env aenv b
coerce ScalarType a
t1 ScalarType t
t2 (Operands a -> IROpenExp arch env aenv t)
-> CodeGen arch (Operands a) -> IROpenExp arch env aenv t
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> CodeGen arch (Operands a)
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x

    indexSlice :: SliceIndex slix sl co sh -> Operands slix -> Operands sh -> Operands sl
    indexSlice :: SliceIndex slix sl co sh
-> Operands slix -> Operands sh -> Operands sl
indexSlice SliceIndex slix sl co sh
SliceNil              Operands slix
OP_Unit               Operands sh
OP_Unit          = Operands sl
Operands ()
OP_Unit
    indexSlice (SliceAll SliceIndex ix1 slice1 co dim
sliceIdx)   (OP_Pair slx OP_Unit) (OP_Pair sl sz)  =
      let sl' :: Operands slice1
sl' = SliceIndex ix1 slice1 co dim
-> Operands ix1 -> Operands dim -> Operands slice1
forall slix sl co sh.
SliceIndex slix sl co sh
-> Operands slix -> Operands sh -> Operands sl
indexSlice SliceIndex ix1 slice1 co dim
sliceIdx Operands ix1
slx Operands dim
sl
        in Operands slice1 -> Operands Int -> Operands (slice1, Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands slice1
sl' Operands Int
sz
    indexSlice (SliceFixed SliceIndex ix1 sl co dim
sliceIdx) (OP_Pair slx _i)      (OP_Pair sl _sz) =
      SliceIndex ix1 sl co dim
-> Operands ix1 -> Operands dim -> Operands sl
forall slix sl co sh.
SliceIndex slix sl co sh
-> Operands slix -> Operands sh -> Operands sl
indexSlice SliceIndex ix1 sl co dim
sliceIdx Operands ix1
slx Operands dim
sl

    indexFull :: SliceIndex slix sl co sh -> Operands slix -> Operands sl -> Operands sh
    indexFull :: SliceIndex slix sl co sh
-> Operands slix -> Operands sl -> Operands sh
indexFull SliceIndex slix sl co sh
SliceNil              Operands slix
OP_Unit               Operands sl
OP_Unit         = Operands sh
Operands ()
OP_Unit
    indexFull (SliceAll SliceIndex ix1 slice1 co dim
sliceIdx)   (OP_Pair slx OP_Unit) (OP_Pair sl sz) =
      let sh' :: Operands dim
sh' = SliceIndex ix1 slice1 co dim
-> Operands ix1 -> Operands slice1 -> Operands dim
forall slix sl co sh.
SliceIndex slix sl co sh
-> Operands slix -> Operands sl -> Operands sh
indexFull SliceIndex ix1 slice1 co dim
sliceIdx Operands ix1
slx Operands slice1
sl
        in Operands dim -> Operands Int -> Operands (dim, Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands dim
sh' Operands Int
sz
    indexFull (SliceFixed SliceIndex ix1 sl co dim
sliceIdx) (OP_Pair slx sz)      Operands sl
sl              =
      let sh' :: Operands dim
sh' = SliceIndex ix1 sl co dim
-> Operands ix1 -> Operands sl -> Operands dim
forall slix sl co sh.
SliceIndex slix sl co sh
-> Operands slix -> Operands sl -> Operands sh
indexFull SliceIndex ix1 sl co dim
sliceIdx Operands ix1
slx Operands sl
sl
        in Operands dim -> Operands Int -> Operands (dim, Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands dim
sh' Operands Int
sz

    vecPack :: forall n single tuple. (HasCallStack, KnownNat n) => VecR n single tuple -> Operands tuple -> CodeGen arch (Operands (Vec n single))
    vecPack :: VecR n single tuple
-> Operands tuple -> CodeGen arch (Operands (Vec n single))
vecPack VecR n single tuple
vecr Operands tuple
tuple = VectorType (Vec n single)
-> Operand (Vec n single) -> Operands (Vec n single)
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir VectorType (Vec n single)
tp (Operand (Vec n single) -> Operands (Vec n single))
-> CodeGen arch (Operand (Vec n single))
-> CodeGen arch (Operands (Vec n single))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> VecR n single tuple
-> Int -> Operands tuple -> CodeGen arch (Operand (Vec n single))
forall (n' :: Nat) tuple'.
VecR n' single tuple'
-> Int -> Operands tuple' -> CodeGen arch (Operand (Vec n single))
go VecR n single tuple
vecr Int
n Operands tuple
tuple
      where
        go :: VecR n' single tuple' -> Int -> Operands tuple' -> CodeGen arch (Operand (Vec n single))
        go :: VecR n' single tuple'
-> Int -> Operands tuple' -> CodeGen arch (Operand (Vec n single))
go (VecRnil SingleType single
_)      Int
0 Operands tuple'
OP_Unit        = Operand (Vec n single) -> CodeGen arch (Operand (Vec n single))
forall (m :: * -> *) a. Monad m => a -> m a
return (Operand (Vec n single) -> CodeGen arch (Operand (Vec n single)))
-> Operand (Vec n single) -> CodeGen arch (Operand (Vec n single))
forall a b. (a -> b) -> a -> b
$ ScalarType (Vec n single) -> Operand (Vec n single)
forall a. ScalarType a -> Operand a
undef (ScalarType (Vec n single) -> Operand (Vec n single))
-> ScalarType (Vec n single) -> Operand (Vec n single)
forall a b. (a -> b) -> a -> b
$ VectorType (Vec n single) -> ScalarType (Vec n single)
forall (n :: Nat) a1.
VectorType (Vec n a1) -> ScalarType (Vec n a1)
VectorScalarType VectorType (Vec n single)
tp
        go (VecRnil SingleType single
_)      Int
_ Operands tuple'
OP_Unit        = String -> CodeGen arch (Operand (Vec n single))
forall a. HasCallStack => String -> a
internalError String
"index mismatch"
        go (VecRsucc VecR n1 single t
vecr') Int
i (OP_Pair xs x) = do
          Operand (Vec n single)
vec <- VecR n1 single t
-> Int -> Operands t -> CodeGen arch (Operand (Vec n single))
forall (n' :: Nat) tuple'.
VecR n' single tuple'
-> Int -> Operands tuple' -> CodeGen arch (Operand (Vec n single))
go VecR n1 single t
vecr' (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Operands t
xs
          Instruction (Vec n single) -> CodeGen arch (Operand (Vec n single))
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operand a)
instr' (Instruction (Vec n single)
 -> CodeGen arch (Operand (Vec n single)))
-> Instruction (Vec n single)
-> CodeGen arch (Operand (Vec n single))
forall a b. (a -> b) -> a -> b
$ Int32
-> Operand (Vec n single)
-> Operand single
-> Instruction (Vec n single)
forall (n :: Nat) a.
Int32 -> Operand (Vec n a) -> Operand a -> Instruction (Vec n a)
InsertElement (Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
- Int32
1) Operand (Vec n single)
vec (SingleType single -> Operands single -> Operand single
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op SingleType single
singleTp Operands single
x)

        singleTp :: SingleType single -- GHC 8.4 cannot infer this type for some reason
        tp :: VectorType (Vec n single)
tp@(VectorType Int
n SingleType a1
singleTp) = VecR n single tuple -> VectorType (Vec n single)
forall (n :: Nat) s tuple.
KnownNat n =>
VecR n s tuple -> VectorType (Vec n s)
vecRvector VecR n single tuple
vecr

    vecUnpack :: forall n single tuple. (HasCallStack, KnownNat n) => VecR n single tuple -> Operands (Vec n single) -> CodeGen arch (Operands tuple)
    vecUnpack :: VecR n single tuple
-> Operands (Vec n single) -> CodeGen arch (Operands tuple)
vecUnpack VecR n single tuple
vecr (OP_Vec vec) = VecR n single tuple -> Int -> CodeGen arch (Operands tuple)
forall (n' :: Nat) tuple'.
VecR n' single tuple' -> Int -> CodeGen arch (Operands tuple')
go VecR n single tuple
vecr Int
n
      where
        go :: VecR n' single tuple' -> Int -> CodeGen arch (Operands tuple')
        go :: VecR n' single tuple' -> Int -> CodeGen arch (Operands tuple')
go (VecRnil SingleType single
_)      Int
0 = Operands () -> CodeGen arch (Operands ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands () -> CodeGen arch (Operands ()))
-> Operands () -> CodeGen arch (Operands ())
forall a b. (a -> b) -> a -> b
$ Operands ()
OP_Unit
        go (VecRnil SingleType single
_)      Int
_ = String -> CodeGen arch (Operands tuple')
forall a. HasCallStack => String -> a
internalError String
"index mismatch"
        go (VecRsucc VecR n1 single t
vecr') Int
i = do
          Operands t
xs <- VecR n1 single t -> Int -> CodeGen arch (Operands t)
forall (n' :: Nat) tuple'.
VecR n' single tuple' -> Int -> CodeGen arch (Operands tuple')
go VecR n1 single t
vecr' (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
          Operand single
x  <- Instruction single -> CodeGen arch (Operand single)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operand a)
instr' (Instruction single -> CodeGen arch (Operand single))
-> Instruction single -> CodeGen arch (Operand single)
forall a b. (a -> b) -> a -> b
$ Int32 -> Operand (Vec n single) -> Instruction single
forall (n :: Nat) a. Int32 -> Operand (Vec n a) -> Instruction a
ExtractElement (Int -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
- Int32
1) Operand (Vec n single)
vec
          Operands (t, single) -> CodeGen arch (Operands (t, single))
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands (t, single) -> CodeGen arch (Operands (t, single)))
-> Operands (t, single) -> CodeGen arch (Operands (t, single))
forall a b. (a -> b) -> a -> b
$ Operands t -> Operands single -> Operands (t, single)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands t
xs (SingleType single -> Operand single -> Operands single
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir SingleType single
singleTp Operand single
x)

        singleTp :: SingleType single -- GHC 8.4 cannot infer this type for some reason
        VectorType Int
n SingleType a1
singleTp = VecR n single tuple -> VectorType (Vec n single)
forall (n :: Nat) s tuple.
KnownNat n =>
VecR n s tuple -> VectorType (Vec n s)
vecRvector VecR n single tuple
vecr

    linearIndex :: ArrayVar aenv (Array sh e) -> Operands Int -> IROpenExp arch env aenv e
    linearIndex :: ArrayVar aenv (Array sh e)
-> Operands Int -> IROpenExp arch env aenv e
linearIndex (Var ArrayR (Array sh e)
repr Idx aenv (Array sh e)
v) = IRArray (Array sh e) -> Operands Int -> IROpenExp arch env aenv e
forall sh e arch env aenv.
IRArray (Array sh e) -> Operands Int -> IROpenExp arch env aenv e
linearIndexArray (ArrayR (Array sh e) -> Name (Array sh e) -> IRArray (Array sh e)
forall sh e.
ArrayR (Array sh e) -> Name (Array sh e) -> IRArray (Array sh e)
irArray ArrayR (Array sh e)
repr (Idx aenv (Array sh e) -> Gamma aenv -> Name (Array sh e)
forall aenv t. HasCallStack => Idx aenv t -> Gamma aenv -> Name t
aprj Idx aenv (Array sh e)
v Gamma aenv
aenv))

    index :: ArrayVar aenv (Array sh e) -> Operands sh -> IROpenExp arch env aenv e
    index :: ArrayVar aenv (Array sh e)
-> Operands sh -> IROpenExp arch env aenv e
index (Var ArrayR (Array sh e)
repr Idx aenv (Array sh e)
v) = IRArray (Array sh e) -> Operands sh -> IROpenExp arch env aenv e
forall sh e arch env aenv.
IRArray (Array sh e) -> Operands sh -> IROpenExp arch env aenv e
indexArray (ArrayR (Array sh e) -> Name (Array sh e) -> IRArray (Array sh e)
forall sh e.
ArrayR (Array sh e) -> Name (Array sh e) -> IRArray (Array sh e)
irArray ArrayR (Array sh e)
repr (Idx aenv (Array sh e) -> Gamma aenv -> Name (Array sh e)
forall aenv t. HasCallStack => Idx aenv t -> Gamma aenv -> Name t
aprj Idx aenv (Array sh e)
v Gamma aenv
aenv))

    shape :: ArrayVar aenv (Array sh e) -> Operands sh
    shape :: ArrayVar aenv (Array sh e) -> Operands sh
shape (Var ArrayR (Array sh e)
repr Idx aenv (Array sh e)
v) = IRArray (Array sh e) -> Operands sh
forall sh e. IRArray (Array sh e) -> Operands sh
irArrayShape (ArrayR (Array sh e) -> Name (Array sh e) -> IRArray (Array sh e)
forall sh e.
ArrayR (Array sh e) -> Name (Array sh e) -> IRArray (Array sh e)
irArray ArrayR (Array sh e)
repr (Idx aenv (Array sh e) -> Gamma aenv -> Name (Array sh e)
forall aenv t. HasCallStack => Idx aenv t -> Gamma aenv -> Name t
aprj Idx aenv (Array sh e)
v Gamma aenv
aenv))

    pair :: Operands t1 -> Operands t2 -> IROpenExp arch env aenv (t1, t2)
    pair :: Operands t1 -> Operands t2 -> IROpenExp arch env aenv (t1, t2)
pair Operands t1
a Operands t2
b = Operands (t1, t2) -> IROpenExp arch env aenv (t1, t2)
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands (t1, t2) -> IROpenExp arch env aenv (t1, t2))
-> Operands (t1, t2) -> IROpenExp arch env aenv (t1, t2)
forall a b. (a -> b) -> a -> b
$ Operands t1 -> Operands t2 -> Operands (t1, t2)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands t1
a Operands t2
b

    bool :: IROpenExp arch env aenv PrimBool
         -> IROpenExp arch env aenv Bool
    bool :: CodeGen arch (Operands TAG) -> IROpenExp arch env aenv Bool
bool CodeGen arch (Operands TAG)
p = Instruction Bool -> IROpenExp arch env aenv Bool
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (Instruction Bool -> IROpenExp arch env aenv Bool)
-> (Operands TAG -> Instruction Bool)
-> Operands TAG
-> IROpenExp arch env aenv Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntegralType TAG -> Operand TAG -> Instruction Bool
forall a. IntegralType a -> Operand a -> Instruction Bool
IntToBool IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType (Operand TAG -> Instruction Bool)
-> (Operands TAG -> Operand TAG)
-> Operands TAG
-> Instruction Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntegralType TAG -> Operands TAG -> Operand TAG
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType (Operands TAG -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands TAG) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CodeGen arch (Operands TAG)
p

    primbool :: IROpenExp arch env aenv Bool
             -> IROpenExp arch env aenv PrimBool
    primbool :: IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool IROpenExp arch env aenv Bool
b = Instruction TAG -> CodeGen arch (Operands TAG)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (Instruction TAG -> CodeGen arch (Operands TAG))
-> (Operands Bool -> Instruction TAG)
-> Operands Bool
-> CodeGen arch (Operands TAG)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntegralType TAG -> Operand Bool -> Instruction TAG
forall a. IntegralType a -> Operand Bool -> Instruction a
BoolToInt IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType (Operand Bool -> Instruction TAG)
-> (Operands Bool -> Operand Bool)
-> Operands Bool
-> Instruction TAG
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Operands Bool -> Operand Bool
A.unbool (Operands Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IROpenExp arch env aenv Bool
b

    cond :: TypeR a
         -> IROpenExp arch env aenv PrimBool
         -> IROpenExp arch env aenv a
         -> IROpenExp arch env aenv a
         -> IROpenExp arch env aenv a
    cond :: TypeR a
-> CodeGen arch (Operands TAG)
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
cond TypeR a
tp CodeGen arch (Operands TAG)
p IROpenExp arch env aenv a
t IROpenExp arch env aenv a
e =
      (TypeR a, IROpenExp arch env aenv Bool)
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
forall a arch.
(TypeR a, CodeGen arch (Operands Bool))
-> CodeGen arch (Operands a)
-> CodeGen arch (Operands a)
-> CodeGen arch (Operands a)
A.ifThenElse (TypeR a
tp, CodeGen arch (Operands TAG) -> IROpenExp arch env aenv Bool
bool CodeGen arch (Operands TAG)
p) IROpenExp arch env aenv a
t IROpenExp arch env aenv a
e

    while :: TypeR a
          -> IROpenFun1 arch env aenv (a -> PrimBool)
          -> IROpenFun1 arch env aenv (a -> a)
          -> IROpenExp  arch env aenv a
          -> IROpenExp  arch env aenv a
    while :: TypeR a
-> IROpenFun1 arch env aenv (a -> TAG)
-> IROpenFun1 arch env aenv (a -> a)
-> IROpenExp arch env aenv a
-> IROpenExp arch env aenv a
while TypeR a
tp IROpenFun1 arch env aenv (a -> TAG)
p IROpenFun1 arch env aenv (a -> a)
f IROpenExp arch env aenv a
x =
      TypeR a
-> (Operands a -> IROpenExp arch env aenv Bool)
-> (Operands a -> IROpenExp arch env aenv a)
-> Operands a
-> IROpenExp arch env aenv a
forall a arch.
TypeR a
-> (Operands a -> CodeGen arch (Operands Bool))
-> (Operands a -> CodeGen arch (Operands a))
-> Operands a
-> CodeGen arch (Operands a)
L.while TypeR a
tp (CodeGen arch (Operands TAG) -> IROpenExp arch env aenv Bool
bool (CodeGen arch (Operands TAG) -> IROpenExp arch env aenv Bool)
-> (Operands a -> CodeGen arch (Operands TAG))
-> Operands a
-> IROpenExp arch env aenv Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IROpenFun1 arch env aenv (a -> TAG)
-> Operands a -> CodeGen arch (Operands TAG)
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IROpenFun1 arch env aenv (a -> TAG)
p) (IROpenFun1 arch env aenv (a -> a)
-> Operands a -> IROpenExp arch env aenv a
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IROpenFun1 arch env aenv (a -> a)
f) (Operands a -> IROpenExp arch env aenv a)
-> IROpenExp arch env aenv a -> IROpenExp arch env aenv a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IROpenExp arch env aenv a
x

    land :: Operands PrimBool
         -> Operands PrimBool
         -> IROpenExp arch env aenv PrimBool
    land :: Operands TAG -> Operands TAG -> CodeGen arch (Operands TAG)
land Operands TAG
x Operands TAG
y = do
      Operands Bool
x' <- Instruction Bool -> IROpenExp arch env aenv Bool
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType TAG -> Operand TAG -> Instruction Bool
forall a. IntegralType a -> Operand a -> Instruction Bool
IntToBool IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType (IntegralType TAG -> Operands TAG -> Operand TAG
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType Operands TAG
x))
      Operands Bool
y' <- Instruction Bool -> IROpenExp arch env aenv Bool
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType TAG -> Operand TAG -> Instruction Bool
forall a. IntegralType a -> Operand a -> Instruction Bool
IntToBool IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType (IntegralType TAG -> Operands TAG -> Operand TAG
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType Operands TAG
y))
      IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (Operands Bool -> Operands Bool -> IROpenExp arch env aenv Bool
forall arch.
Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
A.land Operands Bool
x' Operands Bool
y')

    lor :: Operands PrimBool
        -> Operands PrimBool
        -> IROpenExp arch env aenv PrimBool
    lor :: Operands TAG -> Operands TAG -> CodeGen arch (Operands TAG)
lor Operands TAG
x Operands TAG
y = do
      Operands Bool
x' <- Instruction Bool -> IROpenExp arch env aenv Bool
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType TAG -> Operand TAG -> Instruction Bool
forall a. IntegralType a -> Operand a -> Instruction Bool
IntToBool IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType (IntegralType TAG -> Operands TAG -> Operand TAG
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType Operands TAG
x))
      Operands Bool
y' <- Instruction Bool -> IROpenExp arch env aenv Bool
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType TAG -> Operand TAG -> Instruction Bool
forall a. IntegralType a -> Operand a -> Instruction Bool
IntToBool IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType (IntegralType TAG -> Operands TAG -> Operand TAG
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType TAG
forall a. IsIntegral a => IntegralType a
integralType Operands TAG
y))
      IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (Operands Bool -> Operands Bool -> IROpenExp arch env aenv Bool
forall arch.
Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
A.lor Operands Bool
x' Operands Bool
y')

    foreignE :: A.Foreign asm
             => TypeR b
             -> asm           (a -> b)
             -> Fun () (a -> b)
             -> Operands a
             -> IRExp arch () b
    foreignE :: TypeR b
-> asm (a -> b) -> Fun () (a -> b) -> Operands a -> IRExp arch () b
foreignE TypeR b
_ asm (a -> b)
asm Fun () (a -> b)
no Operands a
x =
      case asm (a -> b) -> Maybe (IRFun1 arch () (a -> b))
forall arch (asm :: * -> *) x y.
(Foreign arch, Foreign asm) =>
asm (x -> y) -> Maybe (IRFun1 arch () (x -> y))
foreignExp asm (a -> b)
asm of
        Just IRFun1 arch () (a -> b)
f                           -> IRFun1 arch () (a -> b) -> Operands a -> IRExp arch () b
forall arch env aenv a b.
IROpenFun1 arch env aenv (a -> b)
-> Operands a -> IROpenExp arch (env, a) aenv b
app1 IRFun1 arch () (a -> b)
f Operands a
x
        Maybe (IRFun1 arch () (a -> b))
Nothing | Lam ELeftHandSide a () env'
lhs (Body OpenExp env' () t1
b) <- Fun () (a -> b)
no -> OpenExp env' () t1
-> Val env' -> Gamma () -> IROpenExp arch env' () t1
forall arch env aenv _t.
(HasCallStack, Foreign arch) =>
OpenExp env aenv _t
-> Val env -> Gamma aenv -> IROpenExp arch env aenv _t
llvmOfOpenExp OpenExp env' () t1
b (Val ()
Empty Val () -> (ELeftHandSide a () env', Operands a) -> Val env'
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
`pushE` (ELeftHandSide a () env'
lhs, Operands a
Operands a
x)) Gamma ()
forall a. IntMap a
IM.empty
        Maybe (IRFun1 arch () (a -> b))
_                                -> String -> IRExp arch () b
forall a. HasCallStack => String -> a
error String
"when a grid's misaligned with another behind / that's a moiré..."

    coerce :: ScalarType a -> ScalarType b -> Operands a -> IROpenExp arch env aenv b
    coerce :: ScalarType a
-> ScalarType b -> Operands a -> IROpenExp arch env aenv b
coerce ScalarType a
s ScalarType b
t Operands a
x
      | Just a :~: b
Refl <- ScalarType a -> ScalarType b -> Maybe (a :~: b)
forall s t. ScalarType s -> ScalarType t -> Maybe (s :~: t)
matchScalarType ScalarType a
s ScalarType b
t = Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands a -> CodeGen arch (Operands a))
-> Operands a -> CodeGen arch (Operands a)
forall a b. (a -> b) -> a -> b
$ Operands a
x
      | Bool
otherwise                        = ScalarType b -> Operand b -> Operands b
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir ScalarType b
t (Operand b -> Operands b)
-> CodeGen arch (Operand b) -> IROpenExp arch env aenv b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Instruction b -> CodeGen arch (Operand b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operand a)
instr' (ScalarType b -> Operand a -> Instruction b
forall b a. ScalarType b -> Operand a -> Instruction b
BitCast ScalarType b
t (ScalarType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op ScalarType a
s Operands a
x))

    primFun :: PrimFun (a -> r)
            -> OpenExp env aenv a
            -> IROpenExp arch env aenv r
    primFun :: PrimFun (a -> r) -> OpenExp env aenv a -> IROpenExp arch env aenv r
primFun PrimFun (a -> r)
f OpenExp env aenv a
x =
      case PrimFun (a -> r)
f of
        PrimAdd NumType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimSub NumType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.sub NumType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimMul NumType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.mul NumType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimNeg NumType a
t                 -> NumType a -> Operands a -> CodeGen arch (Operands a)
forall a arch. NumType a -> Operands a -> CodeGen arch (Operands a)
A.negate NumType a
t                     (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAbs NumType a
t                 -> NumType a -> Operands a -> CodeGen arch (Operands a)
forall arch a. NumType a -> Operands a -> CodeGen arch (Operands a)
A.abs NumType a
t                        (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimSig NumType a
t                 -> NumType a -> Operands a -> CodeGen arch (Operands a)
forall arch a. NumType a -> Operands a -> CodeGen arch (Operands a)
A.signum NumType a
t                     (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimQuot IntegralType a
t                -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.quot IntegralType a
t)           (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimRem IntegralType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.rem IntegralType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimQuotRem IntegralType a
t             -> (Operands a -> Operands a -> CodeGen arch (Operands (a, a)))
-> Operands (a, a) -> CodeGen arch (Operands (a, a))
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands (a, a))
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands (a, a))
A.quotRem IntegralType a
t)        (Operands (a, a) -> CodeGen arch (Operands (a, a)))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands (a, a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimIDiv IntegralType a
t                -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.idiv IntegralType a
t)           (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimMod IntegralType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.mod IntegralType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimDivMod IntegralType a
t              -> (Operands a -> Operands a -> CodeGen arch (Operands (a, a)))
-> Operands (a, a) -> CodeGen arch (Operands (a, a))
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands (a, a))
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands (a, a))
A.divMod IntegralType a
t)         (Operands (a, a) -> CodeGen arch (Operands (a, a)))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands (a, a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBAnd IntegralType a
t                -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.band IntegralType a
t)           (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBOr IntegralType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.bor IntegralType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBXor IntegralType a
t                -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.xor IntegralType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBNot IntegralType a
t                -> IntegralType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a -> Operands a -> CodeGen arch (Operands a)
A.complement IntegralType a
t                 (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBShiftL IntegralType a
t             -> (Operands a -> Operands Int -> CodeGen arch (Operands a))
-> Operands (a, Int) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
A.shiftL IntegralType a
t)         (Operands (a, Int) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, Int)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBShiftR IntegralType a
t             -> (Operands a -> Operands Int -> CodeGen arch (Operands a))
-> Operands (a, Int) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
A.shiftR IntegralType a
t)         (Operands (a, Int) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, Int)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBRotateL IntegralType a
t            -> (Operands a -> Operands Int -> CodeGen arch (Operands a))
-> Operands (a, Int) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall arch a.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
A.rotateL IntegralType a
t)        (Operands (a, Int) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, Int)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimBRotateR IntegralType a
t            -> (Operands a -> Operands Int -> CodeGen arch (Operands a))
-> Operands (a, Int) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
A.rotateR IntegralType a
t)        (Operands (a, Int) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, Int)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimPopCount IntegralType a
t            -> IntegralType a -> Operands a -> CodeGen arch (Operands Int)
forall arch a.
IntegralType a -> Operands a -> CodeGen arch (Operands Int)
A.popCount IntegralType a
t                   (Operands a -> CodeGen arch (Operands Int))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimCountLeadingZeros IntegralType a
t   -> IntegralType a -> Operands a -> CodeGen arch (Operands Int)
forall arch a.
IntegralType a -> Operands a -> CodeGen arch (Operands Int)
A.countLeadingZeros IntegralType a
t          (Operands a -> CodeGen arch (Operands Int))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimCountTrailingZeros IntegralType a
t  -> IntegralType a -> Operands a -> CodeGen arch (Operands Int)
forall arch a.
IntegralType a -> Operands a -> CodeGen arch (Operands Int)
A.countTrailingZeros IntegralType a
t         (Operands a -> CodeGen arch (Operands Int))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimFDiv FloatingType a
t                -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.fdiv FloatingType a
t)           (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimRecip FloatingType a
t               -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.recip FloatingType a
t                      (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimSin FloatingType a
t                 -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.sin FloatingType a
t                        (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimCos FloatingType a
t                 -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.cos FloatingType a
t                        (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimTan FloatingType a
t                 -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.tan FloatingType a
t                        (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimSinh FloatingType a
t                -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.sinh FloatingType a
t                       (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimCosh FloatingType a
t                -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.cosh FloatingType a
t                       (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimTanh FloatingType a
t                -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.tanh FloatingType a
t                       (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAsin FloatingType a
t                -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.asin FloatingType a
t                       (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAcos FloatingType a
t                -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.acos FloatingType a
t                       (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAtan FloatingType a
t                -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.atan FloatingType a
t                       (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAsinh FloatingType a
t               -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.asinh FloatingType a
t                      (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAcosh FloatingType a
t               -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.acosh FloatingType a
t                      (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAtanh FloatingType a
t               -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.atanh FloatingType a
t                      (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimAtan2 FloatingType a
t               -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.atan2 FloatingType a
t)          (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimExpFloating FloatingType a
t         -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.exp FloatingType a
t                        (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimFPow FloatingType a
t                -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.fpow FloatingType a
t)           (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimSqrt FloatingType a
t                -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.sqrt FloatingType a
t                       (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimLog FloatingType a
t                 -> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
A.log FloatingType a
t                        (Operands a -> CodeGen arch (Operands a))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimLogBase FloatingType a
t             -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall arch a.
FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.logBase FloatingType a
t)        (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimTruncate FloatingType a
ta IntegralType b
tb        -> FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
forall a b arch.
FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
A.truncate FloatingType a
ta IntegralType b
tb               (Operands a -> CodeGen arch (Operands b))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimRound FloatingType a
ta IntegralType b
tb           -> FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
forall a b arch.
FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
A.round FloatingType a
ta IntegralType b
tb                  (Operands a -> CodeGen arch (Operands b))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimFloor FloatingType a
ta IntegralType b
tb           -> FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
forall a b arch.
FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
A.floor FloatingType a
ta IntegralType b
tb                  (Operands a -> CodeGen arch (Operands b))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimCeiling FloatingType a
ta IntegralType b
tb         -> FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
forall a b arch.
FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
A.ceiling FloatingType a
ta IntegralType b
tb                (Operands a -> CodeGen arch (Operands b))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimMax SingleType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.max SingleType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimMin SingleType a
t                 -> (Operands a -> Operands a -> CodeGen arch (Operands a))
-> Operands (a, a) -> CodeGen arch (Operands a)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.min SingleType a
t)            (Operands (a, a) -> CodeGen arch (Operands a))
-> CodeGen arch (Operands (a, a)) -> CodeGen arch (Operands a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimFromIntegral IntegralType a
ta NumType b
tb    -> IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
forall arch a b.
IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
A.fromIntegral IntegralType a
ta NumType b
tb           (Operands a -> CodeGen arch (Operands b))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimToFloating NumType a
ta FloatingType b
tb      -> NumType a
-> FloatingType b -> Operands a -> CodeGen arch (Operands b)
forall arch a b.
NumType a
-> FloatingType b -> Operands a -> CodeGen arch (Operands b)
A.toFloating NumType a
ta FloatingType b
tb             (Operands a -> CodeGen arch (Operands b))
-> CodeGen arch (Operands a) -> CodeGen arch (Operands b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimFun (a -> r)
PrimLAnd                  -> (Operands TAG -> Operands TAG -> CodeGen arch (Operands TAG))
-> Operands (TAG, TAG) -> CodeGen arch (Operands TAG)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry Operands TAG -> Operands TAG -> CodeGen arch (Operands TAG)
land                 (Operands (TAG, TAG) -> CodeGen arch (Operands TAG))
-> CodeGen arch (Operands (TAG, TAG))
-> CodeGen arch (Operands TAG)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimFun (a -> r)
PrimLOr                   -> (Operands TAG -> Operands TAG -> CodeGen arch (Operands TAG))
-> Operands (TAG, TAG) -> CodeGen arch (Operands TAG)
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry Operands TAG -> Operands TAG -> CodeGen arch (Operands TAG)
lor                  (Operands (TAG, TAG) -> CodeGen arch (Operands TAG))
-> CodeGen arch (Operands (TAG, TAG))
-> CodeGen arch (Operands TAG)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimIsNaN FloatingType a
t               -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ FloatingType a -> Operands a -> IROpenExp arch env aenv Bool
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands Bool)
A.isNaN FloatingType a
t           (Operands a -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands a) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimIsInfinite FloatingType a
t          -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ FloatingType a -> Operands a -> IROpenExp arch env aenv Bool
forall arch a.
FloatingType a -> Operands a -> CodeGen arch (Operands Bool)
A.isInfinite FloatingType a
t      (Operands a -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands a) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimLt SingleType a
t                  -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ (Operands a -> Operands a -> IROpenExp arch env aenv Bool)
-> Operands (a, a) -> IROpenExp arch env aenv Bool
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> IROpenExp arch env aenv Bool
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.lt SingleType a
t)  (Operands (a, a) -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands (a, a)) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimGt SingleType a
t                  -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ (Operands a -> Operands a -> IROpenExp arch env aenv Bool)
-> Operands (a, a) -> IROpenExp arch env aenv Bool
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> IROpenExp arch env aenv Bool
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.gt SingleType a
t)  (Operands (a, a) -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands (a, a)) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimLtEq SingleType a
t                -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ (Operands a -> Operands a -> IROpenExp arch env aenv Bool)
-> Operands (a, a) -> IROpenExp arch env aenv Bool
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> IROpenExp arch env aenv Bool
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.lte SingleType a
t) (Operands (a, a) -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands (a, a)) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimGtEq SingleType a
t                -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ (Operands a -> Operands a -> IROpenExp arch env aenv Bool)
-> Operands (a, a) -> IROpenExp arch env aenv Bool
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> IROpenExp arch env aenv Bool
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.gte SingleType a
t) (Operands (a, a) -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands (a, a)) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimEq SingleType a
t                  -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ (Operands a -> Operands a -> IROpenExp arch env aenv Bool)
-> Operands (a, a) -> IROpenExp arch env aenv Bool
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> IROpenExp arch env aenv Bool
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.eq SingleType a
t)  (Operands (a, a) -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands (a, a)) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimNEq SingleType a
t                 -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ (Operands a -> Operands a -> IROpenExp arch env aenv Bool)
-> Operands (a, a) -> IROpenExp arch env aenv Bool
forall a b c.
(Operands a -> Operands b -> c) -> Operands (a, b) -> c
A.uncurry (SingleType a
-> Operands a -> Operands a -> IROpenExp arch env aenv Bool
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
A.neq SingleType a
t) (Operands (a, a) -> IROpenExp arch env aenv Bool)
-> CodeGen arch (Operands (a, a)) -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x
        PrimFun (a -> r)
PrimLNot                  -> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
primbool (IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG))
-> IROpenExp arch env aenv Bool -> CodeGen arch (Operands TAG)
forall a b. (a -> b) -> a -> b
$ Operands Bool -> IROpenExp arch env aenv Bool
forall arch. Operands Bool -> CodeGen arch (Operands Bool)
A.lnot              (Operands Bool -> IROpenExp arch env aenv Bool)
-> IROpenExp arch env aenv Bool -> IROpenExp arch env aenv Bool
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CodeGen arch (Operands TAG) -> IROpenExp arch env aenv Bool
bool (OpenExp env aenv a -> IROpenExp arch env aenv a
forall t. OpenExp env aenv t -> IROpenExp arch env aenv t
cvtE OpenExp env aenv a
x)
          -- no missing patterns, whoo!


-- | Extract the head of an index
--
indexHead :: Operands (sh, sz) -> Operands sz
indexHead :: Operands (sh, sz) -> Operands sz
indexHead (OP_Pair _ sz) = Operands sz
sz

-- | Extract the tail of an index
--
indexTail :: Operands (sh, sz) -> Operands sh
indexTail :: Operands (sh, sz) -> Operands sh
indexTail (OP_Pair sh _) = Operands sh
sh

-- | Construct an index from the head and tail
--
indexCons :: Operands sh -> Operands sz -> Operands (sh, sz)
indexCons :: Operands sh -> Operands sz -> Operands (sh, sz)
indexCons Operands sh
sh Operands sz
sz = Operands sh -> Operands sz -> Operands (sh, sz)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands sh
sh Operands sz
sz

-- | Number of elements contained within a shape
--
shapeSize :: ShapeR sh -> Operands sh -> CodeGen arch (Operands Int)
shapeSize :: ShapeR sh -> Operands sh -> CodeGen arch (Operands Int)
shapeSize ShapeR sh
ShapeRz Operands sh
OP_Unit
  = Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands Int -> CodeGen arch (Operands Int))
-> Operands Int -> CodeGen arch (Operands Int)
forall a b. (a -> b) -> a -> b
$ Int -> Operands Int
A.liftInt Int
1
shapeSize (ShapeRsnoc ShapeR sh1
shr) (OP_Pair sh sz)
  = case ShapeR sh1
shr of
      ShapeR sh1
ShapeRz -> Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
sz
      ShapeR sh1
_       -> do
        Operands Int
a <- ShapeR sh1 -> Operands sh1 -> CodeGen arch (Operands Int)
forall sh arch.
ShapeR sh -> Operands sh -> CodeGen arch (Operands Int)
shapeSize ShapeR sh1
shr Operands sh1
sh
        Operands Int
b <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.mul NumType Int
forall a. IsNum a => NumType a
numType Operands Int
a Operands Int
sz
        Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
b

-- | Convert a multidimensional array index into a linear index
--
intOfIndex :: ShapeR sh -> Operands sh -> Operands sh -> CodeGen arch (Operands Int)
intOfIndex :: ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Int)
intOfIndex ShapeR sh
ShapeRz Operands sh
OP_Unit Operands sh
OP_Unit
  = Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands Int -> CodeGen arch (Operands Int))
-> Operands Int -> CodeGen arch (Operands Int)
forall a b. (a -> b) -> a -> b
$ Int -> Operands Int
A.liftInt Int
0
intOfIndex (ShapeRsnoc ShapeR sh1
shr) (OP_Pair sh sz) (OP_Pair ix i)
  -- If we short-circuit the last dimension, we can avoid inserting
  -- a multiply by zero and add of the result.
  = case ShapeR sh1
shr of
      ShapeR sh1
ShapeRz -> Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
i
      ShapeR sh1
_       -> do
        Operands Int
a <- ShapeR sh1
-> Operands sh1 -> Operands sh1 -> CodeGen arch (Operands Int)
forall sh arch.
ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Int)
intOfIndex ShapeR sh1
shr Operands sh1
sh Operands sh1
ix
        Operands Int
b <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.mul NumType Int
forall a. IsNum a => NumType a
numType Operands Int
a Operands Int
sz
        Operands Int
c <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
A.add NumType Int
forall a. IsNum a => NumType a
numType Operands Int
b Operands Int
i
        Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
c


-- | Convert a linear index into into a multidimensional index
--
indexOfInt :: ShapeR sh -> Operands sh -> Operands Int -> CodeGen arch (Operands sh)
indexOfInt :: ShapeR sh
-> Operands sh -> Operands Int -> CodeGen arch (Operands sh)
indexOfInt ShapeR sh
ShapeRz Operands sh
OP_Unit Operands Int
_
  = Operands () -> CodeGen arch (Operands ())
forall (m :: * -> *) a. Monad m => a -> m a
return Operands ()
OP_Unit
indexOfInt (ShapeRsnoc ShapeR sh1
shr) (OP_Pair sh sz) Operands Int
i
  = do
        Operands Int
i'    <- IntegralType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.quot IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType Operands Int
i Operands Int
sz
        -- If we assume the index is in range, there is no point computing
        -- the remainder of the highest dimension since (i < sz) must hold
        Operands Int
r     <- case ShapeR sh1
shr of
                  ShapeR sh1
ShapeRz -> Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
i     -- TODO: in debug mode assert (i < sz)
                  ShapeR sh1
_       -> IntegralType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
A.rem  IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType Operands Int
i Operands Int
sz
        Operands sh1
sh'   <- ShapeR sh1
-> Operands sh1 -> Operands Int -> CodeGen arch (Operands sh1)
forall sh arch.
ShapeR sh
-> Operands sh -> Operands Int -> CodeGen arch (Operands sh)
indexOfInt ShapeR sh1
shr Operands sh1
sh Operands Int
i'
        Operands (sh1, Int) -> CodeGen arch (Operands (sh1, Int))
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands (sh1, Int) -> CodeGen arch (Operands (sh1, Int)))
-> Operands (sh1, Int) -> CodeGen arch (Operands (sh1, Int))
forall a b. (a -> b) -> a -> b
$ Operands sh1 -> Operands Int -> Operands (sh1, Int)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands sh1
sh' Operands Int
r

-- | Read an element at a multidimensional index
--
indexArray :: IRArray (Array sh e) -> Operands sh -> IROpenExp arch env aenv e
indexArray :: IRArray (Array sh e) -> Operands sh -> IROpenExp arch env aenv e
indexArray IRArray (Array sh e)
arr Operands sh
ix = IRArray (Array sh e) -> Operands Int -> IROpenExp arch env aenv e
forall sh e arch env aenv.
IRArray (Array sh e) -> Operands Int -> IROpenExp arch env aenv e
linearIndexArray IRArray (Array sh e)
arr (Operands Int -> IROpenExp arch env aenv e)
-> CodeGen arch (Operands Int) -> IROpenExp arch env aenv e
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Int)
forall sh arch.
ShapeR sh
-> Operands sh -> Operands sh -> CodeGen arch (Operands Int)
intOfIndex (ArrayR (Array sh e) -> ShapeR sh
forall sh e. ArrayR (Array sh e) -> ShapeR sh
arrayRshape (ArrayR (Array sh e) -> ShapeR sh)
-> ArrayR (Array sh e) -> ShapeR sh
forall a b. (a -> b) -> a -> b
$ IRArray (Array sh e) -> ArrayR (Array sh e)
forall sh e. IRArray (Array sh e) -> ArrayR (Array sh e)
irArrayRepr IRArray (Array sh e)
arr) (IRArray (Array sh e) -> Operands sh
forall sh e. IRArray (Array sh e) -> Operands sh
irArrayShape IRArray (Array sh e)
arr) Operands sh
ix

-- | Read an element at a linear index
--
linearIndexArray :: IRArray (Array sh e) -> Operands Int -> IROpenExp arch env aenv e
linearIndexArray :: IRArray (Array sh e) -> Operands Int -> IROpenExp arch env aenv e
linearIndexArray = IntegralType Int
-> IRArray (Array sh e)
-> Operands Int
-> IROpenExp arch env aenv e
forall int sh e arch.
IntegralType int
-> IRArray (Array sh e)
-> Operands int
-> CodeGen arch (Operands e)
readArray IntegralType Int
TypeInt

pushE :: Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
pushE :: Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
pushE Val env
env (LeftHandSideSingle ScalarType t
_  , Operands t
e)               = Val env
env Val env -> Operands t -> Val (env, t)
forall env t. Val env -> Operands t -> Val (env, t)
`Push` Operands t
e
pushE Val env
env (LeftHandSideWildcard TupR ScalarType t
_, Operands t
_)               = Val env
Val env'
env
pushE Val env
env (LeftHandSidePair LeftHandSide ScalarType v1 env env'1
l1 LeftHandSide ScalarType v2 env'1 env'
l2, (OP_Pair e1 e2)) = Val env
-> (LeftHandSide ScalarType v1 env env'1, Operands v1) -> Val env'1
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
pushE Val env
env (LeftHandSide ScalarType v1 env env'1
l1, Operands v1
e1) Val env'1
-> (LeftHandSide ScalarType v2 env'1 env', Operands v2) -> Val env'
forall env t env'.
Val env -> (ELeftHandSide t env env', Operands t) -> Val env'
`pushE` (LeftHandSide ScalarType v2 env'1 env'
l2, Operands v2
e2)