{-# LANGUAGE GADTs               #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE RebindableSyntax    #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TupleSections       #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE ViewPatterns        #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module      : Data.Array.Accelerate.LLVM.CodeGen.Arithmetic
-- 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.Arithmetic
  where

import Data.Array.Accelerate.AST                                    ( PrimMaybe )
import Data.Array.Accelerate.Analysis.Match
import Data.Array.Accelerate.Representation.Tag
import Data.Array.Accelerate.Representation.Type

import LLVM.AST.Type.Constant
import LLVM.AST.Type.Function
import LLVM.AST.Type.Instruction
import LLVM.AST.Type.Instruction.Compare
import LLVM.AST.Type.Name
import LLVM.AST.Type.Operand
import LLVM.AST.Type.Representation

import Data.Array.Accelerate.LLVM.CodeGen.Base
import Data.Array.Accelerate.LLVM.CodeGen.Constant
import Data.Array.Accelerate.LLVM.CodeGen.IR
import Data.Array.Accelerate.LLVM.CodeGen.Monad
import Data.Array.Accelerate.LLVM.CodeGen.Type

import Control.Applicative
import Control.Monad
import Data.Bits                                                    ( finiteBitSize )
import Data.Bool                                                    ( Bool(..), otherwise )
import Data.ByteString.Short                                        ( ShortByteString )
import Data.Constraint                                              ( Dict(..) )
import Data.Monoid
import Data.String
import Foreign.Storable                                             ( sizeOf )
import Prelude                                                      ( Eq, Num, Maybe(..), ($), (==), (/), undefined, flip, fromInteger )
import Text.Printf
import qualified Data.Ord                                           as Ord
import qualified Prelude                                            as P


-- Operations from Num
-- -------------------

add :: NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add :: NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add = (NumType a -> Operand a -> Operand a -> Instruction a)
-> NumType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop NumType a -> Operand a -> Operand a -> Instruction a
forall a. NumType a -> Operand a -> Operand a -> Instruction a
Add

sub :: NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub :: NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub = (NumType a -> Operand a -> Operand a -> Instruction a)
-> NumType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop NumType a -> Operand a -> Operand a -> Instruction a
forall a. NumType a -> Operand a -> Operand a -> Instruction a
Sub

mul :: NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
mul :: NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
mul = (NumType a -> Operand a -> Operand a -> Instruction a)
-> NumType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop NumType a -> Operand a -> Operand a -> Instruction a
forall a. NumType a -> Operand a -> Operand a -> Instruction a
Mul

negate :: NumType a -> Operands a -> CodeGen arch (Operands a)
negate :: NumType a -> Operands a -> CodeGen arch (Operands a)
negate NumType a
t Operands a
x =
  case NumType a
t of
    IntegralNumType IntegralType a
i | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i -> NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
mul NumType a
t Operands a
x (NumType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir NumType a
t (NumType a -> a -> Operand a
forall a. NumType a -> a -> Operand a
num NumType a
t (a -> a
forall a. Num a => a -> a
P.negate a
1)))
    FloatingNumType FloatingType a
f | FloatingDict a
FloatingDict <- FloatingType a -> FloatingDict a
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType a
f -> NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
mul NumType a
t Operands a
x (NumType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir NumType a
t (NumType a -> a -> Operand a
forall a. NumType a -> a -> Operand a
num NumType a
t (a -> a
forall a. Num a => a -> a
P.negate a
1)))

abs :: forall arch a. NumType a -> Operands a -> CodeGen arch (Operands a)
abs :: NumType a -> Operands a -> CodeGen arch (Operands a)
abs NumType a
n Operands a
x =
  case NumType a
n of
    FloatingNumType FloatingType a
f                  -> ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"fabs" FloatingType a
f Operands a
x
    IntegralNumType IntegralType a
i
      | IntegralType a -> Bool
forall (dict :: * -> *) a. IsSigned dict => dict a -> Bool
unsigned IntegralType a
i                     -> Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
x
      | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i ->
          let p :: PrimType a
p = ScalarType a -> PrimType a
forall a. ScalarType a -> PrimType a
ScalarPrimType (SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
n))
              t :: Type a
t = PrimType a -> Type a
forall a. PrimType a -> Type a
PrimType PrimType a
p
          in
          case a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. HasCallStack => a
undefined :: a) of
            Int
64 -> GlobalFunction '[a] a
-> [FunctionAttribute] -> CodeGen arch (Operands a)
forall (args :: [*]) t arch.
GlobalFunction args t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
call (PrimType a
-> Operand a -> Function Label '[] a -> GlobalFunction '[a] a
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType a
p (NumType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op NumType a
n Operands a
x) (Type a -> Maybe TailCall -> Label -> Function Label '[] a
forall r kind.
Type r -> Maybe TailCall -> kind -> Function kind '[] r
Body Type a
t Maybe TailCall
forall a. Maybe a
Nothing Label
"llabs")) [FunctionAttribute
NoUnwind, FunctionAttribute
ReadNone]
            Int
_  -> GlobalFunction '[a] a
-> [FunctionAttribute] -> CodeGen arch (Operands a)
forall (args :: [*]) t arch.
GlobalFunction args t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
call (PrimType a
-> Operand a -> Function Label '[] a -> GlobalFunction '[a] a
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType a
p (NumType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op NumType a
n Operands a
x) (Type a -> Maybe TailCall -> Label -> Function Label '[] a
forall r kind.
Type r -> Maybe TailCall -> kind -> Function kind '[] r
Body Type a
t Maybe TailCall
forall a. Maybe a
Nothing Label
"abs"))   [FunctionAttribute
NoUnwind, FunctionAttribute
ReadNone]

signum :: forall arch a. NumType a -> Operands a -> CodeGen arch (Operands a)
signum :: NumType a -> Operands a -> CodeGen arch (Operands a)
signum NumType a
t Operands a
x =
  case NumType a
t of
    IntegralNumType IntegralType a
i
      | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
      , IntegralType a -> Bool
forall (dict :: * -> *) a. IsSigned dict => dict a -> Bool
unsigned IntegralType a
i
      -> do Operands Bool
z <- SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
neq (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
t) Operands a
x (NumType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir NumType a
t (NumType a -> a -> Operand a
forall a. NumType a -> a -> Operand a
num NumType a
t a
0))
            Operands a
s <- Instruction a -> CodeGen arch (Operands a)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType a -> Operand Bool -> Instruction a
forall a. IntegralType a -> Operand Bool -> Instruction a
BoolToInt IntegralType a
i (Operands Bool -> Operand Bool
unbool Operands Bool
z))
            Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
s
      --
      -- http://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign
      | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
      -> do let wsib :: Int
wsib = a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. HasCallStack => a
undefined::a)
            Operands Bool
z <- SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
neq (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
t) Operands a
x (NumType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir NumType a
t (NumType a -> a -> Operand a
forall a. NumType a -> a -> Operand a
num NumType a
t a
0))
            Operands a
l <- Instruction a -> CodeGen arch (Operands a)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType a -> Operand Bool -> Instruction a
forall a. IntegralType a -> Operand Bool -> Instruction a
BoolToInt IntegralType a
i (Operands Bool -> Operand Bool
unbool Operands Bool
z))
            Operands a
r <- IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRA IntegralType a
i Operands a
x (IntegralType Int -> Operand Int -> Operands Int
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType (IntegralType Int -> Int -> Operand Int
forall a. IntegralType a -> a -> Operand a
integral IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType (Int
wsib Int -> Int -> Int
forall a. Num a => a -> a -> a
P.- Int
1)))
            Operands a
s <- IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
bor IntegralType a
i Operands a
l Operands a
r
            Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
s
    --
    -- http://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign
    FloatingNumType FloatingType a
f
      | FloatingDict a
FloatingDict <- FloatingType a -> FloatingDict a
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType a
f
      -> do
            Operands Bool
l <- SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
t) Operands a
x (FloatingType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir FloatingType a
f (FloatingType a -> a -> Operand a
forall a. FloatingType a -> a -> Operand a
floating FloatingType a
f a
0))
            Operands Bool
r <- SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
t) Operands a
x (FloatingType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir FloatingType a
f (FloatingType a -> a -> Operand a
forall a. FloatingType a -> a -> Operand a
floating FloatingType a
f a
0))
            Operands a
u <- Instruction a -> CodeGen arch (Operands a)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (FloatingType a -> Operand Bool -> Instruction a
forall a. FloatingType a -> Operand Bool -> Instruction a
BoolToFP FloatingType a
f (Operands Bool -> Operand Bool
unbool Operands Bool
l))
            Operands a
v <- Instruction a -> CodeGen arch (Operands a)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (FloatingType a -> Operand Bool -> Instruction a
forall a. FloatingType a -> Operand Bool -> Instruction a
BoolToFP FloatingType a
f (Operands Bool -> Operand Bool
unbool Operands Bool
r))
            Operands a
s <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
t Operands a
u Operands a
v
            Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
s

-- Operations from Integral and Bits
-- ---------------------------------

quot :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
quot :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
quot = (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
Quot

rem :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
rem :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
rem = (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
Rem

quotRem :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands (a,a))
quotRem :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands (a, a))
quotRem IntegralType a
t Operands a
x Operands a
y = do
  Operands a
q <- IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
quot IntegralType a
t Operands a
x Operands a
y
  Operands a
r <- IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
rem  IntegralType a
t Operands a
x Operands a
y
  -- TLM: On x86 we can compute quotRem with a single [i]divq instruction. This
  -- is not evident from the generated LLVM IR, which will still list both
  -- div/rem operations. Note that this may not be true for other instruction
  -- sets, for example the NVPTX assembly contains both operations. It might be
  -- worthwhile to allow backends to specialise Exp code generation in the same
  -- way the other phases of compilation are handled.
  --
  -- The following can be used to compute the remainder, and _may_ be better for
  -- architectures without a combined quotRem instruction.
  --
  -- z <- mul (IntegralNumType t) y q
  -- r <- sub (IntegralNumType t) x z
  Operands (a, a) -> CodeGen arch (Operands (a, a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands (a, a) -> CodeGen arch (Operands (a, a)))
-> Operands (a, a) -> CodeGen arch (Operands (a, a))
forall a b. (a -> b) -> a -> b
$ Operands a -> Operands a -> Operands (a, a)
forall a b. Operands a -> Operands b -> Operands (a, b)
pair Operands a
q Operands a
r

idiv :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
idiv :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
idiv IntegralType a
i Operands a
x Operands a
y
  | IntegralType a -> Bool
forall (dict :: * -> *) a. IsSigned dict => dict a -> Bool
unsigned IntegralType a
i
  = IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
quot IntegralType a
i Operands a
x Operands a
y
  --
  | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
  , Dict (Elt a)
Dict         <- IntegralType a -> Dict (Elt a)
forall a. IntegralType a -> Dict (Elt a)
integralElt IntegralType a
i
  , Operands a
zero         <- IntegralType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType a
i (IntegralType a -> a -> Operand a
forall a. IntegralType a -> a -> Operand a
integral IntegralType a
i a
0)
  , Operands a
one          <- IntegralType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType a
i (IntegralType a -> a -> Operand a
forall a. IntegralType a -> a -> Operand a
integral IntegralType a
i a
1)
  , NumType a
n            <- IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i
  , SingleType a
s            <- NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
n
  = if (TupR ScalarType a
tp, SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt SingleType a
s Operands a
x Operands a
zero CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`land'` SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt SingleType a
s Operands a
y Operands a
zero)
       then do
         Operands a
a <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
n Operands a
x Operands a
one
         Operands a
b <- IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
quot IntegralType a
i Operands a
a Operands a
y
         Operands a
c <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
n Operands a
b Operands a
one
         Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
c
       else
    if (TupR ScalarType a
tp, SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt SingleType a
s Operands a
x Operands a
zero CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`land'` SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt SingleType a
s Operands a
y Operands a
zero)
       then do
         Operands a
a <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add NumType a
n Operands a
x Operands a
one
         Operands a
b <- IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
quot IntegralType a
i Operands a
a Operands a
y
         Operands a
c <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
n Operands a
b Operands a
one
         Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
c
    else
         IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
quot IntegralType a
i Operands a
x Operands a
y
  where
    tp :: TupR ScalarType a
tp = ScalarType a -> TupR ScalarType a
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ScalarType a -> TupR ScalarType a)
-> ScalarType a -> TupR ScalarType a
forall a b. (a -> b) -> a -> b
$ SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType (SingleType a -> ScalarType a) -> SingleType a -> ScalarType a
forall a b. (a -> b) -> a -> b
$ NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType (NumType a -> SingleType a) -> NumType a -> SingleType a
forall a b. (a -> b) -> a -> b
$ IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i

mod :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
mod :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
mod IntegralType a
i Operands a
x Operands a
y
  | IntegralType a -> Bool
forall (dict :: * -> *) a. IsSigned dict => dict a -> Bool
unsigned IntegralType a
i
  = IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
rem IntegralType a
i Operands a
x Operands a
y
  --
  | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
  , Dict (Elt a)
Dict         <- IntegralType a -> Dict (Elt a)
forall a. IntegralType a -> Dict (Elt a)
integralElt IntegralType a
i
  , Operands a
zero         <- IntegralType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType a
i (IntegralType a -> a -> Operand a
forall a. IntegralType a -> a -> Operand a
integral IntegralType a
i a
0)
  , NumType a
n            <- IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i
  , SingleType a
s            <- NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
n
  = do Operands a
r <- IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
rem IntegralType a
i Operands a
x Operands a
y
       if (TupR ScalarType a
tp, (SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt SingleType a
s Operands a
x Operands a
zero CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`land'` SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt SingleType a
s Operands a
y Operands a
zero) CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`lor'` (SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt SingleType a
s Operands a
x Operands a
zero CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`land'` SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt SingleType a
s Operands a
y Operands a
zero))
          then if (TupR ScalarType a
tp, SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
neq SingleType a
s Operands a
r Operands a
zero)
                  then NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add NumType a
n Operands a
r Operands a
y
                  else Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
zero
          else Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
r
  where
    tp :: TupR ScalarType a
tp = ScalarType a -> TupR ScalarType a
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ScalarType a -> TupR ScalarType a)
-> ScalarType a -> TupR ScalarType a
forall a b. (a -> b) -> a -> b
$ SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType (SingleType a -> ScalarType a) -> SingleType a -> ScalarType a
forall a b. (a -> b) -> a -> b
$ NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType (NumType a -> SingleType a) -> NumType a -> SingleType a
forall a b. (a -> b) -> a -> b
$ IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i

divMod :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands (a,a))
divMod :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands (a, a))
divMod IntegralType a
i Operands a
x Operands a
y
  | IntegralType a -> Bool
forall (dict :: * -> *) a. IsSigned dict => dict a -> Bool
unsigned IntegralType a
i
  = 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))
quotRem IntegralType a
i Operands a
x Operands a
y
  --
  | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
  , Dict (Elt a)
Dict         <- IntegralType a -> Dict (Elt a)
forall a. IntegralType a -> Dict (Elt a)
integralElt IntegralType a
i
  , Operands a
zero         <- IntegralType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType a
i (IntegralType a -> a -> Operand a
forall a. IntegralType a -> a -> Operand a
integral IntegralType a
i a
0)
  , Operands a
one          <- IntegralType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType a
i (IntegralType a -> a -> Operand a
forall a. IntegralType a -> a -> Operand a
integral IntegralType a
i a
1)
  , NumType a
n            <- IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i
  , SingleType a
s            <- NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
n
  = if (TupR ScalarType a -> TupR ScalarType a -> TupR ScalarType (a, a)
forall (s :: * -> *) a1 b. TupR s a1 -> TupR s b -> TupR s (a1, b)
TupRpair TupR ScalarType a
tp TupR ScalarType a
tp, SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt SingleType a
s Operands a
x Operands a
zero CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`land'` SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt SingleType a
s Operands a
y Operands a
zero)
       then do
         Operands a
a <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
n Operands a
x Operands a
one
         Operands (a, a)
b <- 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))
quotRem IntegralType a
i Operands a
a Operands a
y
         Operands a
c <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
n (Operands (a, a) -> Operands a
forall a b. Operands (a, b) -> Operands a
fst Operands (a, a)
b) Operands a
one
         Operands a
d <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add NumType a
n (Operands (a, a) -> Operands a
forall a b. Operands (a, b) -> Operands b
snd Operands (a, a)
b) Operands a
y
         Operands a
e <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add NumType a
n Operands a
d Operands a
one
         Operands (a, a) -> CodeGen arch (Operands (a, a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands (a, a) -> CodeGen arch (Operands (a, a)))
-> Operands (a, a) -> CodeGen arch (Operands (a, a))
forall a b. (a -> b) -> a -> b
$ Operands a -> Operands a -> Operands (a, a)
forall a b. Operands a -> Operands b -> Operands (a, b)
pair Operands a
c Operands a
e
       else
    if (TupR ScalarType a -> TupR ScalarType a -> TupR ScalarType (a, a)
forall (s :: * -> *) a1 b. TupR s a1 -> TupR s b -> TupR s (a1, b)
TupRpair TupR ScalarType a
tp TupR ScalarType a
tp, SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt SingleType a
s Operands a
x Operands a
zero CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
forall arch.
CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
`land'` SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt SingleType a
s Operands a
y Operands a
zero)
       then do
         Operands a
a <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add NumType a
n Operands a
x Operands a
one
         Operands (a, a)
b <- 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))
quotRem IntegralType a
i Operands a
a Operands a
y
         Operands a
c <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
n (Operands (a, a) -> Operands a
forall a b. Operands (a, b) -> Operands a
fst Operands (a, a)
b) Operands a
one
         Operands a
d <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
add NumType a
n (Operands (a, a) -> Operands a
forall a b. Operands (a, b) -> Operands b
snd Operands (a, a)
b) Operands a
y
         Operands a
e <- NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType a
n Operands a
d Operands a
one
         Operands (a, a) -> CodeGen arch (Operands (a, a))
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands (a, a) -> CodeGen arch (Operands (a, a)))
-> Operands (a, a) -> CodeGen arch (Operands (a, a))
forall a b. (a -> b) -> a -> b
$ Operands a -> Operands a -> Operands (a, a)
forall a b. Operands a -> Operands b -> Operands (a, b)
pair Operands a
c Operands a
e
    else
         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))
quotRem IntegralType a
i Operands a
x Operands a
y
  where
    tp :: TupR ScalarType a
tp = ScalarType a -> TupR ScalarType a
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle (ScalarType a -> TupR ScalarType a)
-> ScalarType a -> TupR ScalarType a
forall a b. (a -> b) -> a -> b
$ SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType (SingleType a -> ScalarType a) -> SingleType a -> ScalarType a
forall a b. (a -> b) -> a -> b
$ NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType (NumType a -> SingleType a) -> NumType a -> SingleType a
forall a b. (a -> b) -> a -> b
$ IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i


band :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
band :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
band = (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
BAnd

bor :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
bor :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
bor = (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
BOr

xor :: IntegralType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
xor :: IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
xor = (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
BXor

complement :: IntegralType a -> Operands a -> CodeGen arch (Operands a)
complement :: IntegralType a -> Operands a -> CodeGen arch (Operands a)
complement IntegralType a
t Operands a
x | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
t = IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
xor IntegralType a
t Operands a
x (IntegralType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType a
t (IntegralType a -> a -> Operand a
forall a. IntegralType a -> a -> Operand a
integral IntegralType a
t (a -> a
forall a. Num a => a -> a
P.negate a
1)))

shiftL :: IntegralType a -> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftL :: IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftL IntegralType a
t Operands a
x Operands Int
i = do
  Operands a
i' <- IntegralType Int
-> NumType a -> Operands Int -> CodeGen arch (Operands a)
forall arch a b.
IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType (IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
t) Operands Int
i
  (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
ShiftL IntegralType a
t Operands a
x Operands a
i'

shiftR :: IntegralType a -> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftR :: IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftR IntegralType a
t
  | IntegralType a -> Bool
forall (dict :: * -> *) a. IsSigned dict => dict a -> Bool
signed IntegralType a
t  = IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRA IntegralType a
t
  | Bool
otherwise = IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRL IntegralType a
t

shiftRL :: IntegralType a -> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRL :: IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRL IntegralType a
t Operands a
x Operands Int
i = do
  Operands a
i' <- IntegralType Int
-> NumType a -> Operands Int -> CodeGen arch (Operands a)
forall arch a b.
IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType (IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
t) Operands Int
i
  Operands a
r  <- (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
ShiftRL IntegralType a
t Operands a
x Operands a
i'
  Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
r

shiftRA :: IntegralType a -> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRA :: IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRA IntegralType a
t Operands a
x Operands Int
i = do
  Operands a
i' <- IntegralType Int
-> NumType a -> Operands Int -> CodeGen arch (Operands a)
forall arch a b.
IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType (IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
t) Operands Int
i
  Operands a
r  <- (IntegralType a -> Operand a -> Operand a -> Instruction a)
-> IntegralType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop IntegralType a -> Operand a -> Operand a -> Instruction a
forall a. IntegralType a -> Operand a -> Operand a -> Instruction a
ShiftRA IntegralType a
t Operands a
x Operands a
i'
  Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
r

rotateL :: forall arch a. IntegralType a -> Operands a -> Operands Int -> CodeGen arch (Operands a)
rotateL :: IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
rotateL IntegralType a
t Operands a
x Operands Int
i
  | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
t
  = do let wsib :: Int
wsib = a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. HasCallStack => a
undefined::a)
       Operands Int
i1 <- IntegralType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
band IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType Operands Int
i (IntegralType Int -> Operand Int -> Operands Int
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType (IntegralType Int -> Int -> Operand Int
forall a. IntegralType a -> a -> Operand a
integral IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType (Int
wsib Int -> Int -> Int
forall a. Num a => a -> a -> a
P.- Int
1)))
       Operands Int
i2 <- NumType Int
-> Operands Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch.
NumType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
sub NumType Int
forall a. IsNum a => NumType a
numType (NumType Int -> Operand Int -> Operands Int
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir NumType Int
forall a. IsNum a => NumType a
numType (IntegralType Int -> Int -> Operand Int
forall a. IntegralType a -> a -> Operand a
integral IntegralType Int
forall a. IsIntegral a => IntegralType a
integralType Int
wsib)) Operands Int
i1
       --
       Operands a
a  <- IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftL IntegralType a
t Operands a
x Operands Int
i1
       Operands a
b  <- IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
shiftRL IntegralType a
t Operands a
x Operands Int
i2
       Operands a
c  <- IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
IntegralType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
bor IntegralType a
t Operands a
a Operands a
b
       Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
c

rotateR :: IntegralType a -> Operands a -> Operands Int -> CodeGen arch (Operands a)
rotateR :: IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
rotateR IntegralType a
t Operands a
x Operands Int
i = do
  Operands Int
i' <- NumType Int -> Operands Int -> CodeGen arch (Operands Int)
forall a arch. NumType a -> Operands a -> CodeGen arch (Operands a)
negate NumType Int
forall a. IsNum a => NumType a
numType Operands Int
i
  Operands a
r  <- IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
forall arch a.
IntegralType a
-> Operands a -> Operands Int -> CodeGen arch (Operands a)
rotateL IntegralType a
t Operands a
x Operands Int
i'
  Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
r

popCount :: forall arch a. IntegralType a -> Operands a -> CodeGen arch (Operands Int)
popCount :: IntegralType a -> Operands a -> CodeGen arch (Operands Int)
popCount IntegralType a
i Operands a
x
  | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
  = do let ctpop :: Label
ctpop = String -> Label
forall a. IsString a => String -> a
fromString (String -> Label) -> String -> Label
forall a b. (a -> b) -> a -> b
$ String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"llvm.ctpop.i%d" (a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. HasCallStack => a
undefined::a))
           p :: PrimType a
p     = ScalarType a -> PrimType a
forall a. ScalarType a -> PrimType a
ScalarPrimType (SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType (IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i)))
           t :: Type a
t     = PrimType a -> Type a
forall a. PrimType a -> Type a
PrimType PrimType a
p
       --
       Operands a
c <- GlobalFunction '[a] a
-> [FunctionAttribute] -> CodeGen arch (Operands a)
forall (args :: [*]) t arch.
GlobalFunction args t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
call (PrimType a
-> Operand a -> Function Label '[] a -> GlobalFunction '[a] a
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType a
p (IntegralType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType a
i Operands a
x) (Type a -> Maybe TailCall -> Label -> Function Label '[] a
forall r kind.
Type r -> Maybe TailCall -> kind -> Function kind '[] r
Body Type a
t Maybe TailCall
forall a. Maybe a
Nothing Label
ctpop)) [FunctionAttribute
NoUnwind, FunctionAttribute
ReadNone]
       Operands Int
r <- IntegralType a
-> NumType Int -> Operands a -> CodeGen arch (Operands Int)
forall arch a b.
IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral IntegralType a
i NumType Int
forall a. IsNum a => NumType a
numType Operands a
c
       Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
r

countLeadingZeros :: forall arch a. IntegralType a -> Operands a -> CodeGen arch (Operands Int)
countLeadingZeros :: IntegralType a -> Operands a -> CodeGen arch (Operands Int)
countLeadingZeros IntegralType a
i Operands a
x
  | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
  = do let clz :: Label
clz = String -> Label
forall a. IsString a => String -> a
fromString (String -> Label) -> String -> Label
forall a b. (a -> b) -> a -> b
$ String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"llvm.ctlz.i%d" (a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. HasCallStack => a
undefined::a))
           p :: PrimType a
p   = ScalarType a -> PrimType a
forall a. ScalarType a -> PrimType a
ScalarPrimType (SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType (IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i)))
           t :: Type a
t   = PrimType a -> Type a
forall a. PrimType a -> Type a
PrimType PrimType a
p
       --
       Operands a
c <- GlobalFunction '[a, Bool] a
-> [FunctionAttribute] -> CodeGen arch (Operands a)
forall (args :: [*]) t arch.
GlobalFunction args t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
call (PrimType a
-> Operand a
-> Function Label '[Bool] a
-> GlobalFunction '[a, Bool] a
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType a
p (IntegralType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType a
i Operands a
x) (PrimType Bool
-> Operand Bool -> Function Label '[] a -> Function Label '[Bool] a
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType Bool
forall a. IsPrim a => PrimType a
primType (Bool -> Operand Bool
boolean Bool
False) (Type a -> Maybe TailCall -> Label -> Function Label '[] a
forall r kind.
Type r -> Maybe TailCall -> kind -> Function kind '[] r
Body Type a
t Maybe TailCall
forall a. Maybe a
Nothing Label
clz))) [FunctionAttribute
NoUnwind, FunctionAttribute
ReadNone]
       Operands Int
r <- IntegralType a
-> NumType Int -> Operands a -> CodeGen arch (Operands Int)
forall arch a b.
IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral IntegralType a
i NumType Int
forall a. IsNum a => NumType a
numType Operands a
c
       Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
r

countTrailingZeros :: forall arch a. IntegralType a -> Operands a -> CodeGen arch (Operands Int)
countTrailingZeros :: IntegralType a -> Operands a -> CodeGen arch (Operands Int)
countTrailingZeros IntegralType a
i Operands a
x
  | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i
  = do let clz :: Label
clz = String -> Label
forall a. IsString a => String -> a
fromString (String -> Label) -> String -> Label
forall a b. (a -> b) -> a -> b
$ String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"llvm.cttz.i%d" (a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. HasCallStack => a
undefined::a))
           p :: PrimType a
p   = ScalarType a -> PrimType a
forall a. ScalarType a -> PrimType a
ScalarPrimType (SingleType a -> ScalarType a
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType (IntegralType a -> NumType a
forall a. IntegralType a -> NumType a
IntegralNumType IntegralType a
i)))
           t :: Type a
t   = PrimType a -> Type a
forall a. PrimType a -> Type a
PrimType PrimType a
p
       --
       Operands a
c <- GlobalFunction '[a, Bool] a
-> [FunctionAttribute] -> CodeGen arch (Operands a)
forall (args :: [*]) t arch.
GlobalFunction args t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
call (PrimType a
-> Operand a
-> Function Label '[Bool] a
-> GlobalFunction '[a, Bool] a
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType a
p (IntegralType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType a
i Operands a
x) (PrimType Bool
-> Operand Bool -> Function Label '[] a -> Function Label '[Bool] a
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType Bool
forall a. IsPrim a => PrimType a
primType (Bool -> Operand Bool
boolean Bool
False) (Type a -> Maybe TailCall -> Label -> Function Label '[] a
forall r kind.
Type r -> Maybe TailCall -> kind -> Function kind '[] r
Body Type a
t Maybe TailCall
forall a. Maybe a
Nothing Label
clz))) [FunctionAttribute
NoUnwind, FunctionAttribute
ReadNone]
       Operands Int
r <- IntegralType a
-> NumType Int -> Operands a -> CodeGen arch (Operands Int)
forall arch a b.
IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral IntegralType a
i NumType Int
forall a. IsNum a => NumType a
numType Operands a
c
       Operands Int -> CodeGen arch (Operands Int)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands Int
r


-- Operators from Fractional and Floating
-- --------------------------------------

fdiv :: FloatingType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
fdiv :: FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
fdiv = (FloatingType a -> Operand a -> Operand a -> Instruction a)
-> FloatingType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop FloatingType a -> Operand a -> Operand a -> Instruction a
forall a. FloatingType a -> Operand a -> Operand a -> Instruction a
Div

recip :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
recip :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
recip FloatingType a
t Operands a
x | FloatingDict a
FloatingDict <- FloatingType a -> FloatingDict a
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType a
t = FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
fdiv FloatingType a
t (FloatingType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir FloatingType a
t (FloatingType a -> a -> Operand a
forall a. FloatingType a -> a -> Operand a
floating FloatingType a
t a
1)) Operands a
x

sin :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
sin :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
sin = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"sin"

cos :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
cos :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
cos = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"cos"

tan :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
tan :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
tan = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"tan"

sinh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
sinh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
sinh = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"sinh"

cosh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
cosh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
cosh = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"cosh"

tanh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
tanh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
tanh = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"tanh"

asin :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
asin :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
asin = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"asin"

acos :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
acos :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
acos = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"acos"

atan :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
atan :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
atan = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"atan"

asinh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
asinh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
asinh = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"asinh"

acosh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
acosh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
acosh = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"acosh"

atanh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
atanh :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
atanh = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"atanh"

atan2 :: FloatingType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
atan2 :: FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
atan2 = ShortByteString
-> FloatingType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t
-> Operands t
-> Operands t
-> CodeGen arch (Operands t)
mathf2 ShortByteString
"atan2"

exp :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
exp :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
exp = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"exp"

fpow :: FloatingType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
fpow :: FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
fpow = ShortByteString
-> FloatingType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t
-> Operands t
-> Operands t
-> CodeGen arch (Operands t)
mathf2 ShortByteString
"pow"

sqrt :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
sqrt :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
sqrt = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"sqrt"

log :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
log :: FloatingType a -> Operands a -> CodeGen arch (Operands a)
log = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"log"

logBase :: forall arch a. FloatingType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
logBase :: FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
logBase FloatingType a
t x :: Operands a
x@(FloatingType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op FloatingType a
t -> Operand a
base) Operands a
y | FloatingDict a
FloatingDict <- FloatingType a -> FloatingDict a
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType a
t = CodeGen arch (Operands a)
(Num a, Eq a) => CodeGen arch (Operands a)
logBase'
  where
    match :: Eq t => Operand t -> Operand t -> Bool
    match :: Operand t -> Operand t -> Bool
match (ConstantOperand (ScalarConstant ScalarType t
_ t
u))
          (ConstantOperand (ScalarConstant ScalarType t
_ t
v)) = t
u t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
v
    match Operand t
_ Operand t
_                                    = Bool
False

    logBase' :: (Num a, Eq a) => CodeGen arch (Operands a)
    logBase' :: CodeGen arch (Operands a)
logBase' | Operand a -> Operand a -> Bool
forall t. Eq t => Operand t -> Operand t -> Bool
match Operand a
base (FloatingType a -> a -> Operand a
forall a. FloatingType a -> a -> Operand a
floating FloatingType a
t a
2)  = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"log2"  FloatingType a
t Operands a
y
             | Operand a -> Operand a -> Bool
forall t. Eq t => Operand t -> Operand t -> Bool
match Operand a
base (FloatingType a -> a -> Operand a
forall a. FloatingType a -> a -> Operand a
floating FloatingType a
t a
10) = ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"log10" FloatingType a
t Operands a
y
             | Bool
otherwise
             = do Operands a
x' <- FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
log FloatingType a
t Operands a
x
                  Operands a
y' <- FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a -> Operands a -> CodeGen arch (Operands a)
log FloatingType a
t Operands a
y
                  FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
forall a arch.
FloatingType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
fdiv FloatingType a
t Operands a
y' Operands a
x'


-- Operators from RealFloat
-- ------------------------

isNaN :: FloatingType a -> Operands a -> CodeGen arch (Operands Bool)
isNaN :: FloatingType a -> Operands a -> CodeGen arch (Operands Bool)
isNaN FloatingType a
f (FloatingType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op FloatingType a
f -> Operand a
x) = Instruction Bool -> CodeGen arch (Operands Bool)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (FloatingType a -> Operand a -> Instruction Bool
forall a. FloatingType a -> Operand a -> Instruction Bool
IsNaN FloatingType a
f Operand a
x)

isInfinite :: forall arch a. FloatingType a -> Operands a -> CodeGen arch (Operands Bool)
isInfinite :: FloatingType a -> Operands a -> CodeGen arch (Operands Bool)
isInfinite FloatingType a
f Operands a
x = do
  Operands a
x' <- NumType a -> Operands a -> CodeGen arch (Operands a)
forall arch a. NumType a -> Operands a -> CodeGen arch (Operands a)
abs NumType a
n Operands a
x
  SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
eq (NumType a -> SingleType a
forall a. NumType a -> SingleType a
NumSingleType NumType a
n) Operands a
infinity Operands a
x'
  where
    n :: NumType a
    n :: NumType a
n = FloatingType a -> NumType a
forall a. FloatingType a -> NumType a
FloatingNumType FloatingType a
f

    infinity :: Operands a
    infinity :: Operands a
infinity | FloatingDict a
FloatingDict <- FloatingType a -> FloatingDict a
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType a
f = FloatingType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir FloatingType a
f (FloatingType a -> a -> Operand a
forall a. FloatingType a -> a -> Operand a
floating FloatingType a
f (a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
0))


-- Operators from RealFrac
-- -----------------------

truncate :: FloatingType a -> IntegralType b -> Operands a -> CodeGen arch (Operands b)
truncate :: FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
truncate FloatingType a
tf IntegralType b
ti (FloatingType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op FloatingType a
tf -> Operand a
x) = Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (FloatingType a -> IntegralType b -> Operand a -> Instruction b
forall a b.
FloatingType a -> IntegralType b -> Operand a -> Instruction b
FPToInt FloatingType a
tf IntegralType b
ti Operand a
x)

round :: FloatingType a -> IntegralType b -> Operands a -> CodeGen arch (Operands b)
round :: FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
round FloatingType a
tf IntegralType b
ti Operands a
x = do
  Operands a
i <- ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"round" FloatingType a
tf Operands a
x
  FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
forall a b arch.
FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
truncate FloatingType a
tf IntegralType b
ti Operands a
i

floor :: FloatingType a -> IntegralType b -> Operands a -> CodeGen arch (Operands b)
floor :: FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
floor FloatingType a
tf IntegralType b
ti Operands a
x = do
  Operands a
i <- ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"floor" FloatingType a
tf Operands a
x
  FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
forall a b arch.
FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
truncate FloatingType a
tf IntegralType b
ti Operands a
i

ceiling :: FloatingType a -> IntegralType b -> Operands a -> CodeGen arch (Operands b)
ceiling :: FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
ceiling FloatingType a
tf IntegralType b
ti Operands a
x = do
  Operands a
i <- ShortByteString
-> FloatingType a -> Operands a -> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
"ceil" FloatingType a
tf Operands a
x
  FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
forall a b arch.
FloatingType a
-> IntegralType b -> Operands a -> CodeGen arch (Operands b)
truncate FloatingType a
tf IntegralType b
ti Operands a
i


-- Relational and Equality operators
-- ---------------------------------

cmp :: Ordering -> SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands Bool)
cmp :: Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
cmp Ordering
p SingleType a
dict (SingleType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op SingleType a
dict -> Operand a
x) (SingleType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op SingleType a
dict -> Operand a
y) = Instruction Bool -> CodeGen arch (Operands Bool)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (SingleType a
-> Ordering -> Operand a -> Operand a -> Instruction Bool
forall a.
SingleType a
-> Ordering -> Operand a -> Operand a -> Instruction Bool
Cmp SingleType a
dict Ordering
p Operand a
x Operand a
y)

lt :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lt = Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
forall a arch.
Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
cmp Ordering
LT

gt :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gt = Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
forall a arch.
Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
cmp Ordering
GT

lte :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lte :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lte = Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
forall a arch.
Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
cmp Ordering
LE

gte :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gte :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gte = Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
forall a arch.
Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
cmp Ordering
GE

eq :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands Bool)
eq :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
eq = Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
forall a arch.
Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
cmp Ordering
EQ

neq :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands Bool)
neq :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
neq = Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
forall a arch.
Ordering
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands Bool)
cmp Ordering
NE

max :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
max :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
max SingleType a
ty Operands a
x Operands a
y
  | NumSingleType (FloatingNumType FloatingType a
f) <- SingleType a
ty = ShortByteString
-> FloatingType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t
-> Operands t
-> Operands t
-> CodeGen arch (Operands t)
mathf2 ShortByteString
"fmax" FloatingType a
f Operands a
x Operands a
y
  | Bool
otherwise                               = do Operand Bool
c <- Operands Bool -> Operand Bool
unbool (Operands Bool -> Operand Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operand Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
gte SingleType a
ty Operands a
x Operands a
y
                                                 (SingleType a -> Operand a -> Operand a -> Instruction a)
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop ((SingleType a
 -> Operand Bool -> Operand a -> Operand a -> Instruction a)
-> Operand Bool
-> SingleType a
-> Operand a
-> Operand a
-> Instruction a
forall a b c. (a -> b -> c) -> b -> a -> c
flip SingleType a
-> Operand Bool -> Operand a -> Operand a -> Instruction a
forall a.
SingleType a
-> Operand Bool -> Operand a -> Operand a -> Instruction a
Select Operand Bool
c) SingleType a
ty Operands a
x Operands a
y

min :: SingleType a -> Operands a -> Operands a -> CodeGen arch (Operands a)
min :: SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands a)
min SingleType a
ty Operands a
x Operands a
y
  | NumSingleType (FloatingNumType FloatingType a
f) <- SingleType a
ty = ShortByteString
-> FloatingType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall t arch.
ShortByteString
-> FloatingType t
-> Operands t
-> Operands t
-> CodeGen arch (Operands t)
mathf2 ShortByteString
"fmin" FloatingType a
f Operands a
x Operands a
y
  | Bool
otherwise                               = do Operand Bool
c <- Operands Bool -> Operand Bool
unbool (Operands Bool -> Operand Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operand Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
forall a arch.
SingleType a
-> Operands a -> Operands a -> CodeGen arch (Operands Bool)
lte SingleType a
ty Operands a
x Operands a
y
                                                 (SingleType a -> Operand a -> Operand a -> Instruction a)
-> SingleType a
-> Operands a
-> Operands a
-> CodeGen arch (Operands a)
forall (dict :: * -> *) a arch.
IROP dict =>
(dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop ((SingleType a
 -> Operand Bool -> Operand a -> Operand a -> Instruction a)
-> Operand Bool
-> SingleType a
-> Operand a
-> Operand a
-> Instruction a
forall a b c. (a -> b -> c) -> b -> a -> c
flip SingleType a
-> Operand Bool -> Operand a -> Operand a -> Instruction a
forall a.
SingleType a
-> Operand Bool -> Operand a -> Operand a -> Instruction a
Select Operand Bool
c) SingleType a
ty Operands a
x Operands a
y


-- Logical operators
-- -----------------
--
-- Note that these implementations are strict in both arguments. The short
-- circuiting (&&) and (||) operators in the language are not evaluated
-- using these functions, but defined in terms of if-then-else.
--
land :: Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
land :: Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
land (OP_Bool x) (OP_Bool y) = Instruction Bool -> CodeGen arch (Operands Bool)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (Operand Bool -> Operand Bool -> Instruction Bool
LAnd Operand Bool
x Operand Bool
y)

lor :: Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
lor :: Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
lor (OP_Bool x) (OP_Bool y) = Instruction Bool -> CodeGen arch (Operands Bool)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (Operand Bool -> Operand Bool -> Instruction Bool
LOr Operand Bool
x Operand Bool
y)

lnot :: Operands Bool -> CodeGen arch (Operands Bool)
lnot :: Operands Bool -> CodeGen arch (Operands Bool)
lnot (OP_Bool x) = Instruction Bool -> CodeGen arch (Operands Bool)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (Operand Bool -> Instruction Bool
LNot Operand Bool
x)

-- Utilities for implementing bounds checks
land' :: CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
land' :: CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
land' CodeGen arch (Operands Bool)
x CodeGen arch (Operands Bool)
y = do
  Operands Bool
a <- CodeGen arch (Operands Bool)
x
  Operands Bool
b <- CodeGen arch (Operands Bool)
y
  Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
forall arch.
Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
land Operands Bool
a Operands Bool
b

lor' :: CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
lor' :: CodeGen arch (Operands Bool)
-> CodeGen arch (Operands Bool) -> CodeGen arch (Operands Bool)
lor' CodeGen arch (Operands Bool)
x CodeGen arch (Operands Bool)
y = do
  Operands Bool
a <- CodeGen arch (Operands Bool)
x
  Operands Bool
b <- CodeGen arch (Operands Bool)
y
  Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
forall arch.
Operands Bool -> Operands Bool -> CodeGen arch (Operands Bool)
lor Operands Bool
a Operands Bool
b

-- Type conversions
-- ----------------

fromIntegral :: forall arch a b. IntegralType a -> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral :: IntegralType a
-> NumType b -> Operands a -> CodeGen arch (Operands b)
fromIntegral IntegralType a
i1 NumType b
n (IntegralType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op IntegralType a
i1 -> Operand a
x) =
  case NumType b
n of
    FloatingNumType FloatingType b
f
      -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType a -> FloatingType b -> Operand a -> Instruction b
forall a b.
IntegralType a -> FloatingType b -> Operand a -> Instruction b
IntToFP IntegralType a
i1 FloatingType b
f Operand a
x)

    IntegralNumType (IntegralType b
i2 :: IntegralType b)
      | IntegralDict a
IntegralDict <- IntegralType a -> IntegralDict a
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType a
i1
      , IntegralDict b
IntegralDict <- IntegralType b -> IntegralDict b
forall a. IntegralType a -> IntegralDict a
integralDict IntegralType b
i2
      -> let
             bits_a :: Int
bits_a = a -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (a
forall a. HasCallStack => a
undefined::a)
             bits_b :: Int
bits_b = b -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (b
forall a. HasCallStack => a
undefined::b)
         in
         case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
Ord.compare Int
bits_a Int
bits_b of
           Ordering
Ord.EQ -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (ScalarType b -> Operand a -> Instruction b
forall b a. ScalarType b -> Operand a -> Instruction b
BitCast (SingleType b -> ScalarType b
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType b -> SingleType b
forall a. NumType a -> SingleType a
NumSingleType NumType b
n)) Operand a
x)
           Ordering
Ord.GT -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (BoundedType a -> BoundedType b -> Operand a -> Instruction b
forall a b.
BoundedType a -> BoundedType b -> Operand a -> Instruction b
Trunc (IntegralType a -> BoundedType a
forall a. IntegralType a -> BoundedType a
IntegralBoundedType IntegralType a
i1) (IntegralType b -> BoundedType b
forall a. IntegralType a -> BoundedType a
IntegralBoundedType IntegralType b
i2) Operand a
x)
           Ordering
Ord.LT -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (BoundedType a -> BoundedType b -> Operand a -> Instruction b
forall a b.
BoundedType a -> BoundedType b -> Operand a -> Instruction b
Ext   (IntegralType a -> BoundedType a
forall a. IntegralType a -> BoundedType a
IntegralBoundedType IntegralType a
i1) (IntegralType b -> BoundedType b
forall a. IntegralType a -> BoundedType a
IntegralBoundedType IntegralType b
i2) Operand a
x)

toFloating :: forall arch a b. NumType a -> FloatingType b -> Operands a -> CodeGen arch (Operands b)
toFloating :: NumType a
-> FloatingType b -> Operands a -> CodeGen arch (Operands b)
toFloating NumType a
n1 FloatingType b
f2 (NumType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op NumType a
n1 -> Operand a
x) =
  case NumType a
n1 of
    IntegralNumType IntegralType a
i1
      -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (IntegralType a -> FloatingType b -> Operand a -> Instruction b
forall a b.
IntegralType a -> FloatingType b -> Operand a -> Instruction b
IntToFP IntegralType a
i1 FloatingType b
f2 Operand a
x)

    FloatingNumType (FloatingType a
f1 :: FloatingType a)
      | FloatingDict a
FloatingDict <- FloatingType a -> FloatingDict a
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType a
f1
      , FloatingDict b
FloatingDict <- FloatingType b -> FloatingDict b
forall a. FloatingType a -> FloatingDict a
floatingDict FloatingType b
f2
      -> let
             bytes_a :: Int
bytes_a = a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined::a)
             bytes_b :: Int
bytes_b = b -> Int
forall a. Storable a => a -> Int
sizeOf (b
forall a. HasCallStack => a
undefined::b)
         in
         case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
Ord.compare Int
bytes_a Int
bytes_b of
           Ordering
Ord.EQ -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (ScalarType b -> Operand a -> Instruction b
forall b a. ScalarType b -> Operand a -> Instruction b
BitCast (SingleType b -> ScalarType b
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType b -> SingleType b
forall a. NumType a -> SingleType a
NumSingleType (FloatingType b -> NumType b
forall a. FloatingType a -> NumType a
FloatingNumType FloatingType b
f2))) Operand a
x)
           Ordering
Ord.GT -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (FloatingType a -> FloatingType b -> Operand a -> Instruction b
forall a b.
FloatingType a -> FloatingType b -> Operand a -> Instruction b
FTrunc FloatingType a
f1 FloatingType b
f2 Operand a
x)
           Ordering
Ord.LT -> Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (FloatingType a -> FloatingType b -> Operand a -> Instruction b
forall a b.
FloatingType a -> FloatingType b -> Operand a -> Instruction b
FExt   FloatingType a
f1 FloatingType b
f2 Operand a
x)

bitcast :: ScalarType a -> ScalarType b -> Operands a -> CodeGen arch (Operands b)
bitcast :: ScalarType a
-> ScalarType b -> Operands a -> CodeGen arch (Operands b)
bitcast ScalarType a
ta ScalarType b
tb 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
ta ScalarType b
tb = Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
x
  | Bool
otherwise                          = Instruction b -> CodeGen arch (Operands b)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (ScalarType b -> Operand a -> Instruction b
forall b a. ScalarType b -> Operand a -> Instruction b
BitCast ScalarType b
tb (ScalarType a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op ScalarType a
ta Operands a
x))


-- Utility functions
-- -----------------

fst :: Operands (a, b) -> Operands a
fst :: Operands (a, b) -> Operands a
fst (OP_Pair x _) = Operands a
x

snd :: Operands (a, b) -> Operands b
snd :: Operands (a, b) -> Operands b
snd (OP_Pair _ y) = Operands b
y

pair :: Operands a -> Operands b -> Operands (a, b)
pair :: Operands a -> Operands b -> Operands (a, b)
pair Operands a
x Operands b
y = Operands a -> Operands b -> Operands (a, b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands a
x Operands b
y

unpair :: Operands (a, b) -> (Operands a, Operands b)
unpair :: Operands (a, b) -> (Operands a, Operands b)
unpair (OP_Pair x y) = (Operands a
x, Operands b
y)

uncurry :: (Operands a -> Operands b -> c) -> Operands (a, b) -> c
uncurry :: (Operands a -> Operands b -> c) -> Operands (a, b) -> c
uncurry Operands a -> Operands b -> c
f (OP_Pair x y) = Operands a -> Operands b -> c
f Operands a
x Operands b
y

unbool :: Operands Bool -> Operand Bool
unbool :: Operands Bool -> Operand Bool
unbool (OP_Bool x) = Operand Bool
x

binop :: IROP dict => (dict a -> Operand a -> Operand a -> Instruction a) -> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop :: (dict a -> Operand a -> Operand a -> Instruction a)
-> dict a -> Operands a -> Operands a -> CodeGen arch (Operands a)
binop dict a -> Operand a -> Operand a -> Instruction a
f dict a
dict (dict a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op dict a
dict -> Operand a
x) (dict a -> Operands a -> Operand a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op dict a
dict -> Operand a
y) = Instruction a -> CodeGen arch (Operands a)
forall a arch.
HasCallStack =>
Instruction a -> CodeGen arch (Operands a)
instr (dict a -> Operand a -> Operand a -> Instruction a
f dict a
dict Operand a
x Operand a
y)


fst3 :: Operands (Tup3 a b c) -> Operands a
fst3 :: Operands (Tup3 a b c) -> Operands a
fst3 (OP_Pair (OP_Pair (OP_Pair OP_Unit x) _) _) = Operands a
x

snd3 :: Operands (Tup3 a b c) -> Operands b
snd3 :: Operands (Tup3 a b c) -> Operands b
snd3 (OP_Pair (OP_Pair _ y) _) = Operands b
y

thd3 :: Operands (Tup3 a b c) -> Operands c
thd3 :: Operands (Tup3 a b c) -> Operands c
thd3 (OP_Pair _ z) = Operands c
z

trip :: Operands a -> Operands b -> Operands c -> Operands (Tup3 a b c)
trip :: Operands a -> Operands b -> Operands c -> Operands (Tup3 a b c)
trip Operands a
x Operands b
y Operands c
z = Operands (((), a), b) -> Operands c -> Operands (Tup3 a b c)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands ((), a) -> Operands b -> Operands (((), a), b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (Operands () -> Operands a -> Operands ((), a)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair Operands ()
OP_Unit Operands a
x) Operands b
y) Operands c
z

untrip :: Operands (Tup3 a b c) -> (Operands a, Operands b, Operands c)
untrip :: Operands (Tup3 a b c) -> (Operands a, Operands b, Operands c)
untrip Operands (Tup3 a b c)
t = (Operands (Tup3 a b c) -> Operands a
forall a b c. Operands (Tup3 a b c) -> Operands a
fst3 Operands (Tup3 a b c)
t, Operands (Tup3 a b c) -> Operands b
forall a b c. Operands (Tup3 a b c) -> Operands b
snd3 Operands (Tup3 a b c)
t, Operands (Tup3 a b c) -> Operands c
forall a b c. Operands (Tup3 a b c) -> Operands c
thd3 Operands (Tup3 a b c)
t)


-- | Lift a constant value into an constant in the intermediate representation.
--
{-# INLINABLE lift #-}
lift :: TypeR a -> a -> Operands a
lift :: TypeR a -> a -> Operands a
lift TypeR a
tp a
v = TypeR a -> a -> Operands a
forall a. TypeR a -> a -> Operands a
constant TypeR a
tp a
v

{-# INLINE liftInt #-}
liftInt :: Int -> Operands Int
liftInt :: Int -> Operands Int
liftInt = TypeR Int -> Int -> Operands Int
forall a. TypeR a -> a -> Operands a
lift (TypeR Int -> Int -> Operands Int)
-> TypeR Int -> Int -> Operands Int
forall a b. (a -> b) -> a -> b
$ ScalarType Int -> TypeR Int
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Int
scalarTypeInt

{-# INLINE liftInt32 #-}
liftInt32 :: Int32 -> Operands Int32
liftInt32 :: Int32 -> Operands Int32
liftInt32 = TypeR Int32 -> Int32 -> Operands Int32
forall a. TypeR a -> a -> Operands a
lift (TypeR Int32 -> Int32 -> Operands Int32)
-> TypeR Int32 -> Int32 -> Operands Int32
forall a b. (a -> b) -> a -> b
$ ScalarType Int32 -> TypeR Int32
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Int32
scalarTypeInt32

{-# INLINE liftWord32 #-}
liftWord32 :: Word32 -> Operands Word32
liftWord32 :: Word32 -> Operands Word32
liftWord32 = TypeR Word32 -> Word32 -> Operands Word32
forall a. TypeR a -> a -> Operands a
lift (TypeR Word32 -> Word32 -> Operands Word32)
-> TypeR Word32 -> Word32 -> Operands Word32
forall a b. (a -> b) -> a -> b
$ ScalarType Word32 -> TypeR Word32
forall (s :: * -> *) a. s a -> TupR s a
TupRsingle ScalarType Word32
scalarTypeWord32

{-# INLINE liftBool #-}
liftBool :: Bool -> Operands Bool
liftBool :: Bool -> Operands Bool
liftBool Bool
x = Operand Bool -> Operands Bool
OP_Bool (Bool -> Operand Bool
boolean Bool
x)

-- | Standard if-then-else expression
--
ifThenElse
    :: (TypeR a, CodeGen arch (Operands Bool))
    -> CodeGen arch (Operands a)
    -> CodeGen arch (Operands a)
    -> CodeGen arch (Operands a)
ifThenElse :: (TypeR a, CodeGen arch (Operands Bool))
-> CodeGen arch (Operands a)
-> CodeGen arch (Operands a)
-> CodeGen arch (Operands a)
ifThenElse (TypeR a
tp, CodeGen arch (Operands Bool)
test) CodeGen arch (Operands a)
yes CodeGen arch (Operands a)
no = do
  Block
ifThen <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"if.then"
  Block
ifElse <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"if.else"
  Block
ifExit <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"if.exit"

  Block
_  <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
beginBlock String
"if.entry"
  Operands Bool
p  <- CodeGen arch (Operands Bool)
test
  Block
_  <- Operands Bool -> Block -> Block -> CodeGen arch Block
forall arch.
HasCallStack =>
Operands Bool -> Block -> Block -> CodeGen arch Block
cbr Operands Bool
p Block
ifThen Block
ifElse

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
ifThen
  Operands a
tv <- CodeGen arch (Operands a)
yes
  Block
tb <- Block -> CodeGen arch Block
forall arch. HasCallStack => Block -> CodeGen arch Block
br Block
ifExit

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
ifElse
  Operands a
fv <- CodeGen arch (Operands a)
no
  Block
fb <- Block -> CodeGen arch Block
forall arch. HasCallStack => Block -> CodeGen arch Block
br Block
ifExit

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
ifExit
  TypeR a -> [(Operands a, Block)] -> CodeGen arch (Operands a)
forall arch a.
HasCallStack =>
TypeR a -> [(Operands a, Block)] -> CodeGen arch (Operands a)
phi TypeR a
tp [(Operands a
tv, Block
tb), (Operands a
fv, Block
fb)]


caseof
    :: TypeR a
    -> CodeGen arch (Operands TAG)
    -> [(TAG, CodeGen arch (Operands a))]
    -> Maybe (CodeGen arch (Operands a))
    -> CodeGen arch (Operands a)
caseof :: TypeR a
-> CodeGen arch (Operands TAG)
-> [(TAG, CodeGen arch (Operands a))]
-> Maybe (CodeGen arch (Operands a))
-> CodeGen arch (Operands a)
caseof TypeR a
tR CodeGen arch (Operands TAG)
tag [(TAG, CodeGen arch (Operands a))]
xs Maybe (CodeGen arch (Operands a))
x = do
  Block
exit   <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"switch.exit"
  Block
def    <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"switch.default"
  [(TAG, CodeGen arch (Operands a), Block)]
cases  <- [(TAG, CodeGen arch (Operands a))]
-> ((TAG, CodeGen arch (Operands a))
    -> CodeGen arch (TAG, CodeGen arch (Operands a), Block))
-> CodeGen arch [(TAG, CodeGen arch (Operands a), Block)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(TAG, CodeGen arch (Operands a))]
xs (\(TAG
t,CodeGen arch (Operands a)
e) -> (TAG
t,CodeGen arch (Operands a)
e,) (Block -> (TAG, CodeGen arch (Operands a), Block))
-> CodeGen arch Block
-> CodeGen arch (TAG, CodeGen arch (Operands a), Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock (String -> TAG -> String
forall r. PrintfType r => String -> r
printf String
"switch.l%d" TAG
t))

  Block
_    <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
beginBlock String
"switch.entry"
  Operands TAG
p    <- CodeGen arch (Operands TAG)
tag
  Block
_    <- Operands TAG -> Block -> [(TAG, Block)] -> CodeGen arch Block
forall arch.
HasCallStack =>
Operands TAG -> Block -> [(TAG, Block)] -> CodeGen arch Block
switch Operands TAG
p Block
def [(TAG
t,Block
b) | (TAG
t,CodeGen arch (Operands a)
_,Block
b) <- [(TAG, CodeGen arch (Operands a), Block)]
cases]

  -- Generate basic blocks for each equation
  [(Operands a, Block)]
vs   <- [(TAG, CodeGen arch (Operands a), Block)]
-> ((TAG, CodeGen arch (Operands a), Block)
    -> CodeGen arch (Operands a, Block))
-> CodeGen arch [(Operands a, Block)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(TAG, CodeGen arch (Operands a), Block)]
cases (((TAG, CodeGen arch (Operands a), Block)
  -> CodeGen arch (Operands a, Block))
 -> CodeGen arch [(Operands a, Block)])
-> ((TAG, CodeGen arch (Operands a), Block)
    -> CodeGen arch (Operands a, Block))
-> CodeGen arch [(Operands a, Block)]
forall a b. (a -> b) -> a -> b
$ \(TAG
_,CodeGen arch (Operands a)
body,Block
label) -> do
    Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
label
    Operands a
r <- CodeGen arch (Operands a)
body
    Block
b <- Block -> CodeGen arch Block
forall arch. HasCallStack => Block -> CodeGen arch Block
br Block
exit
    (Operands a, Block) -> CodeGen arch (Operands a, Block)
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands a
r,Block
b)

  -- Basic block for the default case
  (Operands a, Block)
v    <- do
    Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
def
    Operands a
r <- case Maybe (CodeGen arch (Operands a))
x of
        Maybe (CodeGen arch (Operands a))
Nothing ->
          let go :: TypeR a -> Operands a
              go :: TypeR a -> Operands a
go TypeR a
TupRunit       = Operands a
Operands ()
OP_Unit
              go (TupRsingle ScalarType a
t) = ScalarType a -> Operand a -> Operands a
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operand a -> Operands a
ir ScalarType a
t (ScalarType a -> Operand a
forall a. ScalarType a -> Operand a
undef ScalarType a
t)
              go (TupRpair TupR ScalarType a1
a TupR ScalarType b
b) = Operands a1 -> Operands b -> Operands (a1, b)
forall a b. Operands a -> Operands b -> Operands (a, b)
OP_Pair (TupR ScalarType a1 -> Operands a1
forall a. TypeR a -> Operands a
go TupR ScalarType a1
a) (TupR ScalarType b -> Operands b
forall a. TypeR a -> Operands a
go TupR ScalarType b
b)
          in Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return (TypeR a -> Operands a
forall a. TypeR a -> Operands a
go TypeR a
tR)
        Just CodeGen arch (Operands a)
default_ -> CodeGen arch (Operands a)
default_
    Block
b <- Block -> CodeGen arch Block
forall arch. HasCallStack => Block -> CodeGen arch Block
br Block
exit
    (Operands a, Block) -> CodeGen arch (Operands a, Block)
forall (m :: * -> *) a. Monad m => a -> m a
return (Operands a
r,Block
b)

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
exit
  TypeR a -> [(Operands a, Block)] -> CodeGen arch (Operands a)
forall arch a.
HasCallStack =>
TypeR a -> [(Operands a, Block)] -> CodeGen arch (Operands a)
phi TypeR a
tR ((Operands a, Block)
v(Operands a, Block)
-> [(Operands a, Block)] -> [(Operands a, Block)]
forall a. a -> [a] -> [a]
:[(Operands a, Block)]
vs)


-- Execute the body only if the first argument evaluates to True
--
when :: CodeGen arch (Operands Bool) -> CodeGen arch () -> CodeGen arch ()
when :: CodeGen arch (Operands Bool) -> CodeGen arch () -> CodeGen arch ()
when CodeGen arch (Operands Bool)
test CodeGen arch ()
doit = do
  Block
body <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"when.body"
  Block
exit <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"when.exit"

  Operands Bool
p <- CodeGen arch (Operands Bool)
test
  Block
_ <- Operands Bool -> Block -> Block -> CodeGen arch Block
forall arch.
HasCallStack =>
Operands Bool -> Block -> Block -> CodeGen arch Block
cbr Operands Bool
p Block
body Block
exit

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
body
  CodeGen arch ()
doit
  Block
_ <- Block -> CodeGen arch Block
forall arch. HasCallStack => Block -> CodeGen arch Block
br Block
exit

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
exit


-- Execute the body only if the first argument evaluates to False
--
unless :: CodeGen arch (Operands Bool) -> CodeGen arch () -> CodeGen arch ()
unless :: CodeGen arch (Operands Bool) -> CodeGen arch () -> CodeGen arch ()
unless CodeGen arch (Operands Bool)
test CodeGen arch ()
doit = do
  Block
body <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"unless.body"
  Block
exit <- String -> CodeGen arch Block
forall arch. HasCallStack => String -> CodeGen arch Block
newBlock String
"unless.exit"

  Operands Bool
p <- CodeGen arch (Operands Bool)
test
  Block
_ <- Operands Bool -> Block -> Block -> CodeGen arch Block
forall arch.
HasCallStack =>
Operands Bool -> Block -> Block -> CodeGen arch Block
cbr Operands Bool
p Block
exit Block
body

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
body
  CodeGen arch ()
doit
  Block
_ <- Block -> CodeGen arch Block
forall arch. HasCallStack => Block -> CodeGen arch Block
br Block
exit

  Block -> CodeGen arch ()
forall arch. Block -> CodeGen arch ()
setBlock Block
exit


-- Call a function from the standard C math library. This is a wrapper around
-- the 'call' function from CodeGen.Base since:
--
--   (1) The parameter and return types are all the same; and
--   (2) We check if there is an intrinsic implementation of this function
--
-- TLM: We should really be able to construct functions of any arity.
--
mathf :: ShortByteString -> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf :: ShortByteString
-> FloatingType t -> Operands t -> CodeGen arch (Operands t)
mathf ShortByteString
n FloatingType t
f (FloatingType t -> Operands t -> Operand t
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op FloatingType t
f -> Operand t
x) = do
  let s :: PrimType t
s = ScalarType t -> PrimType t
forall a. ScalarType a -> PrimType a
ScalarPrimType (SingleType t -> ScalarType t
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType t -> SingleType t
forall a. NumType a -> SingleType a
NumSingleType (FloatingType t -> NumType t
forall a. FloatingType a -> NumType a
FloatingNumType FloatingType t
f)))
      t :: Type t
t = PrimType t -> Type t
forall a. PrimType a -> Type a
PrimType PrimType t
s
  --
  Label
name <- FloatingType t -> ShortByteString -> CodeGen arch Label
forall t arch.
FloatingType t -> ShortByteString -> CodeGen arch Label
lm FloatingType t
f ShortByteString
n
  Operands t
r    <- GlobalFunction '[t] t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
forall (args :: [*]) t arch.
GlobalFunction args t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
call (PrimType t
-> Operand t -> Function Label '[] t -> GlobalFunction '[t] t
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType t
s Operand t
x (Type t -> Maybe TailCall -> Label -> Function Label '[] t
forall r kind.
Type r -> Maybe TailCall -> kind -> Function kind '[] r
Body Type t
t Maybe TailCall
forall a. Maybe a
Nothing Label
name)) [FunctionAttribute
NoUnwind, FunctionAttribute
ReadOnly]
  Operands t -> CodeGen arch (Operands t)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands t
r


mathf2 :: ShortByteString -> FloatingType t -> Operands t -> Operands t -> CodeGen arch (Operands t)
mathf2 :: ShortByteString
-> FloatingType t
-> Operands t
-> Operands t
-> CodeGen arch (Operands t)
mathf2 ShortByteString
n FloatingType t
f (FloatingType t -> Operands t -> Operand t
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op FloatingType t
f -> Operand t
x) (FloatingType t -> Operands t -> Operand t
forall (dict :: * -> *) a.
(IROP dict, HasCallStack) =>
dict a -> Operands a -> Operand a
op FloatingType t
f -> Operand t
y) = do
  let s :: PrimType t
s = ScalarType t -> PrimType t
forall a. ScalarType a -> PrimType a
ScalarPrimType (SingleType t -> ScalarType t
forall a. SingleType a -> ScalarType a
SingleScalarType (NumType t -> SingleType t
forall a. NumType a -> SingleType a
NumSingleType (FloatingType t -> NumType t
forall a. FloatingType a -> NumType a
FloatingNumType FloatingType t
f)))
      t :: Type t
t = PrimType t -> Type t
forall a. PrimType a -> Type a
PrimType PrimType t
s
  --
  Label
name <- FloatingType t -> ShortByteString -> CodeGen arch Label
forall t arch.
FloatingType t -> ShortByteString -> CodeGen arch Label
lm FloatingType t
f ShortByteString
n
  Operands t
r    <- GlobalFunction '[t, t] t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
forall (args :: [*]) t arch.
GlobalFunction args t
-> [FunctionAttribute] -> CodeGen arch (Operands t)
call (PrimType t
-> Operand t -> Function Label '[t] t -> GlobalFunction '[t, t] t
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType t
s Operand t
x (PrimType t
-> Operand t -> Function Label '[] t -> Function Label '[t] t
forall a kind (args :: [*]) t.
PrimType a
-> Operand a -> Function kind args t -> Function kind (a : args) t
Lam PrimType t
s Operand t
y (Type t -> Maybe TailCall -> Label -> Function Label '[] t
forall r kind.
Type r -> Maybe TailCall -> kind -> Function kind '[] r
Body Type t
t Maybe TailCall
forall a. Maybe a
Nothing Label
name))) [FunctionAttribute
NoUnwind, FunctionAttribute
ReadOnly]
  Operands t -> CodeGen arch (Operands t)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands t
r

lm :: FloatingType t -> ShortByteString -> CodeGen arch Label
lm :: FloatingType t -> ShortByteString -> CodeGen arch Label
lm FloatingType t
t ShortByteString
n
  = ShortByteString -> CodeGen arch Label
forall arch. ShortByteString -> CodeGen arch Label
intrinsic
  (ShortByteString -> CodeGen arch Label)
-> ShortByteString -> CodeGen arch Label
forall a b. (a -> b) -> a -> b
$ case FloatingType t
t of
      TypeHalf{}    -> ShortByteString
nShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<>ShortByteString
"f"   -- XXX: check
      TypeFloat{}   -> ShortByteString
nShortByteString -> ShortByteString -> ShortByteString
forall a. Semigroup a => a -> a -> a
<>ShortByteString
"f"
      TypeDouble{}  -> ShortByteString
n

isJust :: Operands (PrimMaybe a) -> CodeGen arch (Operands Bool)
isJust :: Operands (PrimMaybe a) -> CodeGen arch (Operands Bool)
isJust (OP_Pair l _) = Instruction Bool -> CodeGen arch (Operands 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
l))

fromJust :: Operands (PrimMaybe a) -> CodeGen arch (Operands a)
fromJust :: Operands (PrimMaybe a) -> CodeGen arch (Operands a)
fromJust (OP_Pair _ (OP_Pair OP_Unit r)) = Operands a -> CodeGen arch (Operands a)
forall (m :: * -> *) a. Monad m => a -> m a
return Operands a
r