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

  Intrinsic(..)

) where

-- accelerate-llvm
import LLVM.AST.Type.Name

-- libraries
import Data.Monoid
import Data.ByteString.Short                                    ( ShortByteString )
import Data.HashMap.Strict                                      ( HashMap )
import qualified Data.HashMap.Strict                            as HashMap
import Prelude                                                  as P


-- | During code generation we need to know the name of functions implementing
-- certain intrinsic maths operations. Depending on the backend, these functions
-- may not be implemented using the standard C math library.
--
-- This class allows a backend to provide a mapping from the C math library
-- function name to the name of the function which should be called instead. The
-- default implementation maps to the llvm intrinsic. For example:
--
--   sqrtf      -> llvm.sqrt.f32
--   sqrt       -> llvm.sqrt.f64
--
class Intrinsic arch where
  intrinsicForTarget :: HashMap ShortByteString Label
  intrinsicForTarget = HashMap ShortByteString Label
llvmIntrinsic


llvmIntrinsic :: HashMap ShortByteString Label
llvmIntrinsic :: HashMap ShortByteString Label
llvmIntrinsic =
  let floating :: ShortByteString
-> [(ShortByteString, Label)] -> [(ShortByteString, Label)]
floating ShortByteString
base [(ShortByteString, Label)]
rest
          = (ShortByteString
base,        ShortByteString -> Label
Label (ShortByteString
"llvm." ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
base ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
".f64"))
          (ShortByteString, Label)
-> [(ShortByteString, Label)] -> [(ShortByteString, Label)]
forall a. a -> [a] -> [a]
: (ShortByteString
base ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
"f", ShortByteString -> Label
Label (ShortByteString
"llvm." ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
base ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
".f32"))
          (ShortByteString, Label)
-> [(ShortByteString, Label)] -> [(ShortByteString, Label)]
forall a. a -> [a] -> [a]
: (ShortByteString
base ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
"l", ShortByteString -> Label
Label (ShortByteString
"llvm." ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
base ShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<> ShortByteString
".f128"))
          (ShortByteString, Label)
-> [(ShortByteString, Label)] -> [(ShortByteString, Label)]
forall a. a -> [a] -> [a]
: [(ShortByteString, Label)]
rest
  in
  [(ShortByteString, Label)] -> HashMap ShortByteString Label
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList ([(ShortByteString, Label)] -> HashMap ShortByteString Label)
-> [(ShortByteString, Label)] -> HashMap ShortByteString Label
forall a b. (a -> b) -> a -> b
$ (ShortByteString
 -> [(ShortByteString, Label)] -> [(ShortByteString, Label)])
-> [(ShortByteString, Label)]
-> [ShortByteString]
-> [(ShortByteString, Label)]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ShortByteString
-> [(ShortByteString, Label)] -> [(ShortByteString, Label)]
floating []
    [ ShortByteString
"sqrt"
    , ShortByteString
"powi"
    , ShortByteString
"sin"
    , ShortByteString
"cos"
    , ShortByteString
"pow"
    , ShortByteString
"exp"
    , ShortByteString
"exp2"
    , ShortByteString
"log"
    , ShortByteString
"log10"
    , ShortByteString
"log2"
    , ShortByteString
"fma"
    , ShortByteString
"fabs"
    , ShortByteString
"copysign"
    , ShortByteString
"floor"
    , ShortByteString
"ceil"
    , ShortByteString
"trunc"
    , ShortByteString
"rint"
    , ShortByteString
"nearbyint"
    , ShortByteString
"round"
    ]