{-# LANGUAGE GADTs #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module      : Data.Array.Accelerate.LLVM.CodeGen.Constant
-- 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.Constant (

  primConst,
  constant, scalar, single, vector, num, integral, floating, boolean,
  undef,

) where


import Data.Array.Accelerate.AST                                ( PrimConst(..) )
import Data.Array.Accelerate.LLVM.CodeGen.IR
import Data.Array.Accelerate.Representation.Type
import Data.Array.Accelerate.Type

import LLVM.AST.Type.Constant
import LLVM.AST.Type.Operand
import LLVM.AST.Type.Representation

import Data.Primitive.Vec


-- | Primitive constant values
--
primConst :: PrimConst t -> t
primConst :: PrimConst t -> t
primConst (PrimMinBound BoundedType t
t) = BoundedType t -> t
forall a. BoundedType a -> a
primMinBound BoundedType t
t
primConst (PrimMaxBound BoundedType t
t) = BoundedType t -> t
forall a. BoundedType a -> a
primMaxBound BoundedType t
t
primConst (PrimPi FloatingType t
t)       = FloatingType t -> t
forall a. FloatingType a -> a
primPi FloatingType t
t

primMinBound :: BoundedType a -> a
primMinBound :: BoundedType a -> a
primMinBound (IntegralBoundedType IntegralType a
t) | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
t = a
forall a. Bounded a => a
minBound

primMaxBound :: BoundedType a -> a
primMaxBound :: BoundedType a -> a
primMaxBound (IntegralBoundedType IntegralType a
t) | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
t = a
forall a. Bounded a => a
maxBound

primPi :: FloatingType a -> a
primPi :: FloatingType a -> a
primPi FloatingType a
t | FloatingDict a
FloatingDict <- FloatingType a -> FloatingDict a
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType a
t = a
forall a. Floating a => a
pi


-- | A constant value
--
constant :: TypeR a -> a -> Operands a
constant :: TypeR a -> a -> Operands a
constant TypeR a
TupRunit         ()    = Operands a
Operands ()
OP_Unit
constant (TupRpair TupR ScalarType a1
ta TupR ScalarType b
tb) (a,b) = Operands a1 -> Operands b -> Operands (a1, b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (TupR ScalarType a1 -> a1 -> Operands a1
forall a. TypeR a -> a -> Operands a
constant TupR ScalarType a1
ta a1
a) (TupR ScalarType b -> b -> Operands b
forall a. TypeR a -> a -> Operands a
constant TupR ScalarType b
tb b
b)
constant (TupRsingle ScalarType a
t)   a
a     = ScalarType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir ScalarType a
t (ScalarType a -> a -> Operand a
forall a. ScalarType a -> a -> Operand a
scalar ScalarType a
t a
a)

scalar :: ScalarType a -> a -> Operand a
scalar :: ScalarType a -> a -> Operand a
scalar ScalarType a
t = Constant a -> Operand a
forall a. Constant a -> Operand a
ConstantOperand (Constant a -> Operand a) -> (a -> Constant a) -> a -> Operand a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ScalarType a -> a -> Constant a
forall a. ScalarType a -> a -> Constant a
ScalarConstant ScalarType a
t

single :: SingleType a -> a -> Operand a
single :: SingleType a -> a -> Operand a
single SingleType a
t = ScalarType a -> a -> Operand a
forall a. ScalarType a -> a -> Operand a
scalar (SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType SingleType a
t)

vector :: VectorType (Vec n a) -> (Vec n a) -> Operand (Vec n a)
vector :: VectorType (Vec n a) -> Vec n a -> Operand (Vec n a)
vector VectorType (Vec n a)
t = ScalarType (Vec n a) -> Vec n a -> Operand (Vec n a)
forall a. ScalarType a -> a -> Operand a
scalar (VectorType (Vec n a) -> ScalarType (Vec n a)
forall (n :: Nat) a1.
VectorType (Vec n a1) -> ScalarType (Vec n a1)
VectorScalarType VectorType (Vec n a)
t)

num :: NumType a -> a -> Operand a
num :: NumType a -> a -> Operand a
num NumType a
t = SingleType a -> a -> Operand a
forall a. SingleType a -> a -> Operand a
single (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
t)

integral :: IntegralType a -> a -> Operand a
integral :: IntegralType a -> a -> Operand a
integral IntegralType a
t = NumType a -> a -> Operand a
forall a. NumType a -> a -> Operand a
num (IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
t)

floating :: FloatingType a -> a -> Operand a
floating :: FloatingType a -> a -> Operand a
floating FloatingType a
t = NumType a -> a -> Operand a
forall a. NumType a -> a -> Operand a
num (FloatingType a -> NumType a
forall a. FloatingType a -> NumType a
FloatingNumType FloatingType a
t)

boolean :: Bool -> Operand Bool
boolean :: Bool -> Operand Bool
boolean = Constant Bool -> Operand Bool
forall a. Constant a -> Operand a
ConstantOperand (Constant Bool -> Operand Bool)
-> (Bool -> Constant Bool) -> Bool -> Operand Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Constant Bool
BooleanConstant


-- | The string 'undef' can be used anywhere a constant is expected, and
-- indicates that the program is well defined no matter what value is used.
--
-- <http://llvm.org/docs/LangRef.html#undefined-values>
--
undef :: ScalarType a -> Operand a
undef :: ScalarType a -> Operand a
undef ScalarType a
t = Constant a -> Operand a
forall a. Constant a -> Operand a
ConstantOperand (Type a -> Constant a
forall a. Type a -> Constant a
UndefConstant (PrimType a -> Type a
forall a. PrimType a -> Type a
PrimType (ScalarType a -> PrimType a
forall a. ScalarType a -> PrimType a
ScalarPrimType ScalarType a
t)))