-- | A cache-oblivious sequential transposition for CPU execution.
-- Generates a recursive function.
module Futhark.CodeGen.ImpGen.Transpose
  ( mapTransposeFunction,
    transposeArgs,
  )
where

import Futhark.CodeGen.ImpCode
import Futhark.IR.Prop.Types
import Futhark.Util.IntegralExp
import Prelude hiding (quot)

-- | Take well-typed arguments to the transpose function and produce
-- the actual argument list.
transposeArgs ::
  PrimType ->
  VName ->
  Count Bytes (TExp Int64) ->
  VName ->
  Count Bytes (TExp Int64) ->
  TExp Int64 ->
  TExp Int64 ->
  TExp Int64 ->
  [Arg]
transposeArgs :: PrimType
-> VName
-> Count Bytes (TExp Int64)
-> VName
-> Count Bytes (TExp Int64)
-> TExp Int64
-> TExp Int64
-> TExp Int64
-> [Arg]
transposeArgs PrimType
pt VName
destmem Count Bytes (TExp Int64)
destoffset VName
srcmem Count Bytes (TExp Int64)
srcoffset TExp Int64
num_arrays TExp Int64
m TExp Int64
n =
  [ VName -> Arg
MemArg VName
destmem,
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ Count Bytes (TExp Int64) -> TExp Int64
forall u e. Count u e -> e
unCount Count Bytes (TExp Int64)
destoffset TExp Int64 -> TExp Int64 -> TExp Int64
forall e. IntegralExp e => e -> e -> e
`quot` PrimType -> TExp Int64
forall a. Num a => PrimType -> a
primByteSize PrimType
pt,
    VName -> Arg
MemArg VName
srcmem,
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ Count Bytes (TExp Int64) -> TExp Int64
forall u e. Count u e -> e
unCount Count Bytes (TExp Int64)
srcoffset TExp Int64 -> TExp Int64 -> TExp Int64
forall e. IntegralExp e => e -> e -> e
`quot` PrimType -> TExp Int64
forall a. Num a => PrimType -> a
primByteSize PrimType
pt,
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TExp Int64
num_arrays,
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TExp Int64
m,
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TExp Int64
n,
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64
0 :: TExp Int64),
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TExp Int64
m,
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64
0 :: TExp Int64),
    Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TExp Int64
n
  ]

-- | We need to know the name of the function we are generating, as
-- this function is recursive.
mapTransposeFunction :: Name -> PrimType -> Function op
mapTransposeFunction :: Name -> PrimType -> Function op
mapTransposeFunction Name
fname PrimType
pt =
  Maybe Name
-> [Param]
-> [Param]
-> Code op
-> [ExternalValue]
-> [ExternalValue]
-> Function op
forall a.
Maybe Name
-> [Param]
-> [Param]
-> Code a
-> [ExternalValue]
-> [ExternalValue]
-> FunctionT a
Function
    Maybe Name
forall a. Maybe a
Nothing
    []
    [Param]
params
    ( [Code op] -> Code op
forall a. Monoid a => [a] -> a
mconcat
        [ VName -> TExp Int64 -> Code op
forall t a. VName -> TPrimExp t ExpLeaf -> Code a
dec VName
r (TExp Int64 -> Code op) -> TExp Int64 -> Code op
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
re TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
- VName -> TExp Int64
vi64 VName
rb,
          VName -> TExp Int64 -> Code op
forall t a. VName -> TPrimExp t ExpLeaf -> Code a
dec VName
c (TExp Int64 -> Code op) -> TExp Int64 -> Code op
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
ce TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
- VName -> TExp Int64
vi64 VName
cb,
          TExp Bool -> Code op -> Code op -> Code op
forall a. TExp Bool -> Code a -> Code a -> Code a
If (VName -> TExp Int64
vi64 VName
num_arrays TExp Int64 -> TExp Int64 -> TExp Bool
forall t v. TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
.==. TExp Int64
1) Code op
forall a. Code a
doTranspose Code op
forall a. Code a
doMapTranspose
        ]
    )
    []
    []
  where
    params :: [Param]
params =
      [ VName -> Param
memparam VName
destmem,
        VName -> Param
intparam VName
destoffset,
        VName -> Param
memparam VName
srcmem,
        VName -> Param
intparam VName
srcoffset,
        VName -> Param
intparam VName
num_arrays,
        VName -> Param
intparam VName
m,
        VName -> Param
intparam VName
n,
        VName -> Param
intparam VName
cb,
        VName -> Param
intparam VName
ce,
        VName -> Param
intparam VName
rb,
        VName -> Param
intparam VName
re
      ]

    memparam :: VName -> Param
memparam VName
v = VName -> Space -> Param
MemParam VName
v Space
DefaultSpace
    intparam :: VName -> Param
intparam VName
v = VName -> PrimType -> Param
ScalarParam VName
v PrimType
int64

    [ VName
destmem,
      VName
destoffset,
      VName
srcmem,
      VName
srcoffset,
      VName
num_arrays,
      VName
n,
      VName
m,
      VName
rb,
      VName
re,
      VName
cb,
      VName
ce,
      VName
r,
      VName
c,
      VName
i,
      VName
j
      ] =
        (String -> Int -> VName) -> [String] -> [Int] -> [VName]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith
          (Name -> Int -> VName
VName (Name -> Int -> VName)
-> (String -> Name) -> String -> Int -> VName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Name
nameFromString)
          [ String
"destmem",
            String
"destoffset",
            String
"srcmem",
            String
"srcoffset",
            String
"num_arrays",
            String
"n",
            String
"m",
            String
"rb",
            String
"re",
            String
"cb",
            String
"ce",
            String
"r",
            String
"c",
            String
"i",
            String
"j" -- local
          ]
          [Int
0 ..]

    dec :: VName -> TPrimExp t ExpLeaf -> Code a
dec VName
v TPrimExp t ExpLeaf
e = VName -> Volatility -> PrimType -> Code a
forall a. VName -> Volatility -> PrimType -> Code a
DeclareScalar VName
v Volatility
Nonvolatile PrimType
int32 Code a -> Code a -> Code a
forall a. Semigroup a => a -> a -> a
<> VName -> Exp -> Code a
forall a. VName -> Exp -> Code a
SetScalar VName
v (TPrimExp t ExpLeaf -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TPrimExp t ExpLeaf
e)

    naiveTranspose :: Code a
naiveTranspose =
      VName -> Exp -> Code a -> Code a
forall a. VName -> Exp -> Code a -> Code a
For VName
j (TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
c) (Code a -> Code a) -> Code a -> Code a
forall a b. (a -> b) -> a -> b
$
        VName -> Exp -> Code a -> Code a
forall a. VName -> Exp -> Code a -> Code a
For VName
i (TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
r) (Code a -> Code a) -> Code a -> Code a
forall a b. (a -> b) -> a -> b
$
          let i' :: TExp Int64
i' = VName -> TExp Int64
vi64 VName
i TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ VName -> TExp Int64
vi64 VName
rb
              j' :: TExp Int64
j' = VName -> TExp Int64
vi64 VName
j TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ VName -> TExp Int64
vi64 VName
cb
           in VName
-> Count Elements (TExp Int64)
-> PrimType
-> Space
-> Volatility
-> Exp
-> Code a
forall a.
VName
-> Count Elements (TExp Int64)
-> PrimType
-> Space
-> Volatility
-> Exp
-> Code a
Write
                VName
destmem
                (TExp Int64 -> Count Elements (TExp Int64)
forall a. a -> Count Elements a
elements (TExp Int64 -> Count Elements (TExp Int64))
-> TExp Int64 -> Count Elements (TExp Int64)
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
destoffset TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ TExp Int64
j' TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
* VName -> TExp Int64
vi64 VName
n TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ TExp Int64
i')
                PrimType
pt
                Space
DefaultSpace
                Volatility
Nonvolatile
                (Exp -> Code a) -> Exp -> Code a
forall a b. (a -> b) -> a -> b
$ VName
-> Count Elements (TExp Int64)
-> PrimType
-> Space
-> Volatility
-> Exp
index
                  VName
srcmem
                  (TExp Int64 -> Count Elements (TExp Int64)
forall a. a -> Count Elements a
elements (TExp Int64 -> Count Elements (TExp Int64))
-> TExp Int64 -> Count Elements (TExp Int64)
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
srcoffset TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ TExp Int64
i' TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
* VName -> TExp Int64
vi64 VName
m TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ TExp Int64
j')
                  PrimType
pt
                  Space
DefaultSpace
                  Volatility
Nonvolatile

    recArgs :: (TPrimExp t ExpLeaf, TPrimExp t ExpLeaf, TPrimExp t ExpLeaf,
 TPrimExp t ExpLeaf)
-> [Arg]
recArgs (TPrimExp t ExpLeaf
cb', TPrimExp t ExpLeaf
ce', TPrimExp t ExpLeaf
rb', TPrimExp t ExpLeaf
re') =
      [ VName -> Arg
MemArg VName
destmem,
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
destoffset,
        VName -> Arg
MemArg VName
srcmem,
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
srcoffset,
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
num_arrays,
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
m,
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
n,
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TPrimExp t ExpLeaf -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TPrimExp t ExpLeaf
cb',
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TPrimExp t ExpLeaf -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TPrimExp t ExpLeaf
ce',
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TPrimExp t ExpLeaf -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TPrimExp t ExpLeaf
rb',
        Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TPrimExp t ExpLeaf -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped TPrimExp t ExpLeaf
re'
      ]

    cutoff :: TExp Int64
cutoff = TExp Int64
64 -- arbitrary
    doTranspose :: Code a
doTranspose =
      [Code a] -> Code a
forall a. Monoid a => [a] -> a
mconcat
        [ TExp Bool -> Code a -> Code a -> Code a
forall a. TExp Bool -> Code a -> Code a -> Code a
If
            (VName -> TExp Int64
vi64 VName
r TExp Int64 -> TExp Int64 -> TExp Bool
forall t v. TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
.<=. TExp Int64
cutoff TExp Bool -> TExp Bool -> TExp Bool
forall v. TPrimExp Bool v -> TPrimExp Bool v -> TPrimExp Bool v
.&&. VName -> TExp Int64
vi64 VName
c TExp Int64 -> TExp Int64 -> TExp Bool
forall t v. TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
.<=. TExp Int64
cutoff)
            Code a
forall a. Code a
naiveTranspose
            (Code a -> Code a) -> Code a -> Code a
forall a b. (a -> b) -> a -> b
$ TExp Bool -> Code a -> Code a -> Code a
forall a. TExp Bool -> Code a -> Code a -> Code a
If
              (VName -> TExp Int64
vi64 VName
r TExp Int64 -> TExp Int64 -> TExp Bool
forall t v. TPrimExp t v -> TPrimExp t v -> TPrimExp Bool v
.>=. VName -> TExp Int64
vi64 VName
c)
              ( [VName] -> Name -> [Arg] -> Code a
forall a. [VName] -> Name -> [Arg] -> Code a
Call
                  []
                  Name
fname
                  ( (TExp Int64, TExp Int64, TExp Int64, TExp Int64) -> [Arg]
forall t t t t.
(TPrimExp t ExpLeaf, TPrimExp t ExpLeaf, TPrimExp t ExpLeaf,
 TPrimExp t ExpLeaf)
-> [Arg]
recArgs
                      ( VName -> TExp Int64
vi64 VName
cb,
                        VName -> TExp Int64
vi64 VName
ce,
                        VName -> TExp Int64
vi64 VName
rb,
                        VName -> TExp Int64
vi64 VName
rb TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ (VName -> TExp Int64
vi64 VName
r TExp Int64 -> TExp Int64 -> TExp Int64
forall e. IntegralExp e => e -> e -> e
`quot` TExp Int64
2)
                      )
                  )
                  Code a -> Code a -> Code a
forall a. Semigroup a => a -> a -> a
<> [VName] -> Name -> [Arg] -> Code a
forall a. [VName] -> Name -> [Arg] -> Code a
Call
                    []
                    Name
fname
                    ( (TExp Int64, TExp Int64, TExp Int64, TExp Int64) -> [Arg]
forall t t t t.
(TPrimExp t ExpLeaf, TPrimExp t ExpLeaf, TPrimExp t ExpLeaf,
 TPrimExp t ExpLeaf)
-> [Arg]
recArgs
                        ( VName -> TExp Int64
vi64 VName
cb,
                          VName -> TExp Int64
vi64 VName
ce,
                          VName -> TExp Int64
vi64 VName
rb TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ VName -> TExp Int64
vi64 VName
r TExp Int64 -> TExp Int64 -> TExp Int64
forall e. IntegralExp e => e -> e -> e
`quot` TExp Int64
2,
                          VName -> TExp Int64
vi64 VName
re
                        )
                    )
              )
              ( [VName] -> Name -> [Arg] -> Code a
forall a. [VName] -> Name -> [Arg] -> Code a
Call
                  []
                  Name
fname
                  ( (TExp Int64, TExp Int64, TExp Int64, TExp Int64) -> [Arg]
forall t t t t.
(TPrimExp t ExpLeaf, TPrimExp t ExpLeaf, TPrimExp t ExpLeaf,
 TPrimExp t ExpLeaf)
-> [Arg]
recArgs
                      ( VName -> TExp Int64
vi64 VName
cb,
                        VName -> TExp Int64
vi64 VName
cb TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ (VName -> TExp Int64
vi64 VName
c TExp Int64 -> TExp Int64 -> TExp Int64
forall e. IntegralExp e => e -> e -> e
`quot` TExp Int64
2),
                        VName -> TExp Int64
vi64 VName
rb,
                        VName -> TExp Int64
vi64 VName
re
                      )
                  )
                  Code a -> Code a -> Code a
forall a. Semigroup a => a -> a -> a
<> [VName] -> Name -> [Arg] -> Code a
forall a. [VName] -> Name -> [Arg] -> Code a
Call
                    []
                    Name
fname
                    ( (TExp Int64, TExp Int64, TExp Int64, TExp Int64) -> [Arg]
forall t t t t.
(TPrimExp t ExpLeaf, TPrimExp t ExpLeaf, TPrimExp t ExpLeaf,
 TPrimExp t ExpLeaf)
-> [Arg]
recArgs
                        ( VName -> TExp Int64
vi64 VName
cb TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ VName -> TExp Int64
vi64 VName
c TExp Int64 -> TExp Int64 -> TExp Int64
forall e. IntegralExp e => e -> e -> e
`quot` TExp Int64
2,
                          VName -> TExp Int64
vi64 VName
ce,
                          VName -> TExp Int64
vi64 VName
rb,
                          VName -> TExp Int64
vi64 VName
re
                        )
                    )
              )
        ]

    doMapTranspose :: Code a
doMapTranspose =
      -- In the map-transpose case, we assume that cb==rb==0, ce==m,
      -- re==n.
      VName -> Exp -> Code a -> Code a
forall a. VName -> Exp -> Code a -> Code a
For VName
i (TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
num_arrays) (Code a -> Code a) -> Code a -> Code a
forall a b. (a -> b) -> a -> b
$
        [VName] -> Name -> [Arg] -> Code a
forall a. [VName] -> Name -> [Arg] -> Code a
Call
          []
          Name
fname
          [ VName -> Arg
MemArg VName
destmem,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
destoffset TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ VName -> TExp Int64
vi64 VName
i TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
* VName -> TExp Int64
vi64 VName
m TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
* VName -> TExp Int64
vi64 VName
n,
            VName -> Arg
MemArg VName
srcmem,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
srcoffset TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
+ VName -> TExp Int64
vi64 VName
i TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
* VName -> TExp Int64
vi64 VName
m TExp Int64 -> TExp Int64 -> TExp Int64
forall a. Num a => a -> a -> a
* VName -> TExp Int64
vi64 VName
n,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64
1 :: TExp Int64),
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
m,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
n,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
cb,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
ce,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
rb,
            Exp -> Arg
ExpArg (Exp -> Arg) -> Exp -> Arg
forall a b. (a -> b) -> a -> b
$ TExp Int64 -> Exp
forall t v. TPrimExp t v -> PrimExp v
untyped (TExp Int64 -> Exp) -> TExp Int64 -> Exp
forall a b. (a -> b) -> a -> b
$ VName -> TExp Int64
vi64 VName
re
          ]