{-# LANGUAGE HexFloatLiterals #-} {-# LANGUAGE NumericUnderscores #-} {-# OPTIONS_GHC -Wno-orphans #-} module Numeric.Rounded.Hardware.Backend.Float128 ( ) where import Data.Tagged import Foreign.C.String (CString, peekCString) import Foreign.Marshal (alloca, with) import Foreign.Ptr (Ptr) import Foreign.Storable (peek) import Numeric.Float128 (Float128) import Numeric.Rounded.Hardware.Internal.Class import Numeric.Rounded.Hardware.Internal.Constants import Numeric.Rounded.Hardware.Internal.Conversion import System.IO.Unsafe foreign import ccall unsafe "rounded_hw_add_float128" c_rounded_add_float128 :: Int -> Ptr Float128 -> Ptr Float128 -> Ptr Float128 -> IO () foreign import ccall unsafe "rounded_hw_sub_float128" c_rounded_sub_float128 :: Int -> Ptr Float128 -> Ptr Float128 -> Ptr Float128 -> IO () foreign import ccall unsafe "rounded_hw_mul_float128" c_rounded_mul_float128 :: Int -> Ptr Float128 -> Ptr Float128 -> Ptr Float128 -> IO () foreign import ccall unsafe "rounded_hw_div_float128" c_rounded_div_float128 :: Int -> Ptr Float128 -> Ptr Float128 -> Ptr Float128 -> IO () foreign import ccall unsafe "rounded_hw_sqrt_float128" c_rounded_sqrt_float128 :: Int -> Ptr Float128 -> Ptr Float128 -> IO () foreign import ccall unsafe "rounded_hw_fma_float128" c_rounded_fma_float128 :: Int -> Ptr Float128 -> Ptr Float128 -> Ptr Float128 -> Ptr Float128 -> IO () roundedAdd_f128 :: RoundingMode -> Float128 -> Float128 -> Float128 roundedAdd_f128 mode x y = unsafePerformIO $ with x $ \xPtr -> with y $ \yPtr -> alloca $ \resultPtr -> do c_rounded_add_float128 (fromEnum mode) resultPtr xPtr yPtr peek resultPtr roundedSub_f128 :: RoundingMode -> Float128 -> Float128 -> Float128 roundedSub_f128 mode x y = unsafePerformIO $ with x $ \xPtr -> with y $ \yPtr -> alloca $ \resultPtr -> do c_rounded_sub_float128 (fromEnum mode) resultPtr xPtr yPtr peek resultPtr roundedMul_f128 :: RoundingMode -> Float128 -> Float128 -> Float128 roundedMul_f128 mode x y = unsafePerformIO $ with x $ \xPtr -> with y $ \yPtr -> alloca $ \resultPtr -> do c_rounded_mul_float128 (fromEnum mode) resultPtr xPtr yPtr peek resultPtr roundedDiv_f128 :: RoundingMode -> Float128 -> Float128 -> Float128 roundedDiv_f128 mode x y = unsafePerformIO $ with x $ \xPtr -> with y $ \yPtr -> alloca $ \resultPtr -> do c_rounded_div_float128 (fromEnum mode) resultPtr xPtr yPtr peek resultPtr roundedSqrt_f128 :: RoundingMode -> Float128 -> Float128 roundedSqrt_f128 mode x = unsafePerformIO $ with x $ \xPtr -> alloca $ \resultPtr -> do c_rounded_sqrt_float128 (fromEnum mode) resultPtr xPtr peek resultPtr roundedFMA_f128 :: RoundingMode -> Float128 -> Float128 -> Float128 -> Float128 roundedFMA_f128 mode x y z = unsafePerformIO $ with x $ \xPtr -> with y $ \yPtr -> with z $ \zPtr -> alloca $ \resultPtr -> do c_rounded_fma_float128 (fromEnum mode) resultPtr xPtr yPtr zPtr peek resultPtr instance RealFloatConstants Float128 where positiveInfinity = 1/0 negativeInfinity = -1/0 -- 113 bits = (1 + 4 * 28) bits = (1 + 4 * 4 * 7) bits maxFinite = 0x1.ffff_ffff_ffff_ffff_ffff_ffff_ffffp+16383 minPositive = encodeFloat 1 (-16494) -- The literal 0x1p-16494 may yield 0 on float128-0.1 -- minPositiveNormal = encodeFloat 1 (-16382) -- emin = 1 - emax = 1 - 16383 pi_down = Rounded 0x1.921fb54442d18469898cc51701b8p+1 pi_up = Rounded 0x1.921fb54442d18469898cc51701b9p+1 -- 3*pi three_pi_down = Rounded 0x1.2d97c7f3321d234f272993d1414ap+3 three_pi_up = Rounded 0x1.2d97c7f3321d234f272993d1414bp+3 -- 5*pi five_pi_down = Rounded 0x1.f6a7a2955385e583ebeff65cc226p+3 five_pi_up = Rounded 0x1.f6a7a2955385e583ebeff65cc227p+3 -- log(2) log2_down = Rounded 0x1.62e42fefa39ef35793c7673007e5p-1 log2_up = Rounded 0x1.62e42fefa39ef35793c7673007e6p-1 -- exp(1) exp1_down = Rounded 0x1.5bf0a8b1457695355fb8ac404e7ap+1 exp1_up = Rounded 0x1.5bf0a8b1457695355fb8ac404e7bp+1 -- exp(1/2) exp1_2_down = Rounded 0x1.a61298e1e069bc972dfefab6df33p+0 exp1_2_up = Rounded 0x1.a61298e1e069bc972dfefab6df34p+0 -- exp(-1/2) expm1_2_down = Rounded 0x1.368b2fc6f9609fe7aceb46aa619bp-1 expm1_2_up = Rounded 0x1.368b2fc6f9609fe7aceb46aa619cp-1 -- sqrt(2) sqrt2_down = Rounded 0x1.6a09e667f3bcc908b2fb1366ea95p+0 sqrt2_up = Rounded 0x1.6a09e667f3bcc908b2fb1366ea96p+0 -- sqrt(1/2) sqrt1_2_down = Rounded 0x1.6a09e667f3bcc908b2fb1366ea95p-1 sqrt1_2_up = Rounded 0x1.6a09e667f3bcc908b2fb1366ea96p-1 -- sqrt(2)-1 sqrt2m1_down = Rounded 0x1.a827999fcef32422cbec4d9baa55p-2 sqrt2m1_up = Rounded 0x1.a827999fcef32422cbec4d9baa56p-2 -- 3 - 2 * sqrt(2) three_minus_2sqrt2_down = Rounded 0x1.5f619980c4336f74d04ec99156a8p-3 three_minus_2sqrt2_up = Rounded 0x1.5f619980c4336f74d04ec99156a9p-3 -- 2 - sqrt(2) two_minus_sqrt2_down = Rounded 0x1.2bec333018866dee9a09d9322ad5p-1 two_minus_sqrt2_up = Rounded 0x1.2bec333018866dee9a09d9322ad6p-1 instance RoundedRing Float128 where roundedAdd = roundedAdd_f128 roundedSub = roundedSub_f128 roundedMul = roundedMul_f128 roundedFusedMultiplyAdd = roundedFMA_f128 roundedFromInteger = roundedFromInteger_default intervalFromInteger = intervalFromInteger_default backendNameT = Tagged cBackendName {-# INLINE roundedAdd #-} {-# INLINE roundedSub #-} {-# INLINE roundedMul #-} {-# INLINE roundedFusedMultiplyAdd #-} {-# INLINE roundedFromInteger #-} {-# INLINE intervalFromInteger #-} instance RoundedFractional Float128 where roundedDiv = roundedDiv_f128 roundedFromRational = roundedFromRational_default intervalFromRational = intervalFromRational_default {-# INLINE roundedDiv #-} {-# INLINE roundedFromRational #-} {-# INLINE intervalFromRational #-} instance RoundedSqrt Float128 where roundedSqrt = roundedSqrt_f128 {-# INLINE roundedSqrt #-} -- -- Backend name -- foreign import ccall unsafe "rounded_hw_backend_name_float128" c_backend_name :: CString cBackendName :: String cBackendName = unsafePerformIO (peekCString c_backend_name)