rounded-hw 0.2.0 → 0.3.0
raw patch · 6 files changed
+96/−61 lines, 6 filesdep +tasty-benchdep −gauge
Dependencies added: tasty-bench
Dependencies removed: gauge
Files
- ChangeLog.md +5/−0
- cbits/interval-prim-x86_64-avx512.S +1/−1
- cbits/rounded.c +37/−5
- rounded-hw.cabal +46/−51
- src/Numeric/Rounded/Hardware/Internal/Class.hs +1/−1
- src/Numeric/Rounded/Hardware/Internal/Rounding.hs +6/−3
ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for rounded-hw +## 0.3.0 (2022-01-08)++* Support Clang on AArch64.+* Show the rounding attribute in `instance Show (Rounded r a)`.+ ## 0.2.0 (2020-12-27) * Some functionality was moved to fp-ieee.
cbits/interval-prim-x86_64-avx512.S view
@@ -24,7 +24,7 @@ .globl SYMBOL(rounded_hw_interval_add) SYMBOL(rounded_hw_interval_add): vaddsd {rd-sae}, %xmm3, %xmm1, %xmm1 # xmm1 = xmm1[0] + xmm3[0], xmm1[1] (downward)- vaddsd {ru-sae}, %xmm4, %xmm2, %xmm2 # xmm2 = xmm2[0] + xmm4[0], xmm2[1] (downward)+ vaddsd {ru-sae}, %xmm4, %xmm2, %xmm2 # xmm2 = xmm2[0] + xmm4[0], xmm2[1] (upward) jmp *(%rbp) #
cbits/rounded.c view
@@ -102,8 +102,8 @@ #elif defined(USE_AARCH64_FPCR) -typedef unsigned int fp_reg;-typedef unsigned int native_rounding_mode;+typedef uint64_t fp_reg;+typedef uint64_t native_rounding_mode; static const native_rounding_mode ROUND_TONEAREST = 0 << 22; static const native_rounding_mode ROUND_DOWNWARD = 2 << 22; static const native_rounding_mode ROUND_UPWARD = 1 << 22;@@ -121,21 +121,53 @@ } } +#if defined(__has_builtin)+#define HAS_BUILTIN(f) __has_builtin(f)+#else+#define HAS_BUILTIN(f) 0+#endif+/*+ * __has_builtin: Clang / GCC 10 or later+ * __builtin_aarch64_{get,set}_fpcr64: GCC 11 or later+ * __builtin_aarch64_{get,set}_fpcr: GCC 5 or later+ */ static inline ALWAYS_INLINE fp_reg get_fp_reg(void) {- return __builtin_aarch64_get_fpcr();+#if HAS_BUILTIN(__builtin_aarch64_get_fpcr64)+ return __builtin_aarch64_get_fpcr64();+#elif HAS_BUILTIN(__builtin_aarch64_get_fpcr) || __GNUC__ >= 5+ return (uint64_t)__builtin_aarch64_get_fpcr();+#else+ uint64_t fpcr;+ asm volatile("mrs %0, fpcr" : "=r"(fpcr));+ return fpcr;+#endif } static inline ALWAYS_INLINE void set_rounding(fp_reg reg, native_rounding_mode mode) {- __builtin_aarch64_set_fpcr((reg & ~(3u << 22)) | mode);+ uint64_t newreg = (reg & ~(3u << 22)) | mode;+#if HAS_BUILTIN(__builtin_aarch64_set_fpcr64)+ __builtin_aarch64_set_fpcr64(newreg);+#elif HAS_BUILTIN(__builtin_aarch64_set_fpcr) || __GNUC__ >= 5+ __builtin_aarch64_set_fpcr((unsigned int)newreg);+#else+ asm volatile("msr fpcr, %0" : : "r"(newreg));+#endif } static inline ALWAYS_INLINE void restore_fp_reg(fp_reg reg) {- __builtin_aarch64_set_fpcr(reg);+#if HAS_BUILTIN(__builtin_aarch64_set_fpcr64)+ __builtin_aarch64_set_fpcr64(reg);+#elif HAS_BUILTIN(__builtin_aarch64_set_fpcr) || __GNUC__ >= 5+ __builtin_aarch64_set_fpcr((unsigned int)reg);+#else+ asm volatile("msr fpcr, %0" : : "r"(reg));+#endif }+#undef HAS_BUILTIN static const char backend_name[] = "AArch64 FPCR";
rounded-hw.cabal view
@@ -1,13 +1,7 @@-cabal-version: 1.24---- This file has been generated from package.yaml by hpack version 0.33.0.------ see: https://github.com/sol/hpack------ hash: c52684ece684d2a3e1a2bde6e2919d961a59bd69724c32a8e7ab1ac0b9230685+cabal-version: 2.2 name: rounded-hw-version: 0.2.0+version: 0.3.0 synopsis: Directed rounding for built-in floating types description: Please see the README on GitHub at <https://github.com/minoki/haskell-floating-point/tree/master/rounded-hw#readme> category: Numeric, Math@@ -16,10 +10,11 @@ author: ARATA Mizuki maintainer: minorinoki@gmail.com copyright: 2020 ARATA Mizuki-license: BSD3+license: BSD-3-Clause license-file: LICENSE-tested-with: GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.2 build-type: Custom+tested-with:+ GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC == 9.2.1 extra-source-files: README.md ChangeLog.md@@ -30,14 +25,16 @@ source-repository head type: git location: https://github.com/minoki/haskell-floating-point+ subdir: rounded-hw +-- Custom setup is required to allow assembly sources to #include "ghcconfig.h" custom-setup setup-depends: Cabal >=1.24 , base >=4.7 -flag avx512- description: Use AVX512 EVEX encoding+flag pure-hs+ description: Disable FFI manual: True default: False @@ -46,8 +43,8 @@ manual: True default: False -flag float128- description: Support Float128+flag avx512+ description: Use AVX512 EVEX encoding manual: True default: False @@ -56,17 +53,30 @@ manual: True default: True -flag pure-hs- description: Disable FFI- manual: True- default: False- flag x87-long-double description: Support x87 "long double" manual: True default: True +flag float128+ description: Support Float128+ manual: True+ default: False++common deps+ build-depends:+ array+ , base >=4.12 && <5+ , deepseq+ , fp-ieee ==0.1.*+ , primitive+ , vector++common options+ ghc-options: -Wcompat+ library+ import: deps, options exposed-modules: Numeric.Rounded.Hardware Numeric.Rounded.Hardware.Backend@@ -91,13 +101,9 @@ hs-source-dirs: src build-depends:- array- , base >=4.12 && <5- , deepseq- , fp-ieee ==0.1.*- , primitive- , tagged- , vector+ tagged+ ghc-options: -Wall+ -- Use FFI when flag(pure-hs) is off if !flag(pure-hs) exposed-modules: Numeric.Rounded.Hardware.Backend.C@@ -107,10 +113,13 @@ cpp-options: -DUSE_FFI c-sources: cbits/rounded.c+ -- flag(c99): Disable platform-dependent techniques and only use C99 fesetround if flag(c99) cc-options: -DUSE_C99+ -- flag(avx512): Use AVX512 EVEX encoding if flag(avx512) cc-options: -DUSE_AVX512 -mavx512f+ -- flag(ghc-prim): We support "foreign import prim" on GHC/x86_64 if !flag(pure-hs) && !flag(c99) && flag(ghc-prim) && impl(ghc) && arch(x86_64) exposed-modules: Numeric.Rounded.Hardware.Backend.FastFFI@@ -121,6 +130,7 @@ else c-sources: cbits/interval-prim-x86_64.S+ -- flag(x87-long-double): Support LongDouble on x86 if flag(x87-long-double) && (arch(i386) || arch(x86_64)) other-modules: Numeric.Rounded.Hardware.Backend.X87LongDouble@@ -129,6 +139,7 @@ cbits/rounded-x87longdouble.c build-depends: long-double+ -- flag(float128): Support Float128 if flag(float128) other-modules: Numeric.Rounded.Hardware.Backend.Float128@@ -140,21 +151,15 @@ default-language: Haskell2010 test-suite rounded-hw-doctests+ import: deps, options type: exitcode-stdio-1.0 main-is: doctests.hs- other-modules:- Paths_rounded_hw build-depends:- array- , base >=4.12 && <5- , deepseq- , doctest >=0.8- , fp-ieee ==0.1.*- , primitive- , vector+ doctest >=0.8 default-language: Haskell2010 test-suite rounded-hw-test+ import: deps, options type: exitcode-stdio-1.0 main-is: Spec.hs other-modules:@@ -166,22 +171,16 @@ ShowFloatSpec Util VectorSpec- Paths_rounded_hw hs-source-dirs: test ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: QuickCheck- , array- , base >=4.12 && <5- , deepseq- , fp-ieee ==0.1.* , hspec- , primitive , random , rounded-hw- , vector if flag(x87-long-double) && (arch(i386) || (arch(x86_64) && !os(windows)))+ -- Support for 80-bit long double is not good on Win64, so don't test other-modules: X87LongDoubleSpec cpp-options: -DTEST_X87_LONG_DOUBLE@@ -196,21 +195,17 @@ default-language: Haskell2010 benchmark rounded-hw-benchmark+ import: deps, options type: exitcode-stdio-1.0 main-is: Benchmark.hs other-modules: Conversion IGA- Paths_rounded_hw hs-source-dirs: benchmark build-depends:- array- , base >=4.12 && <5- , deepseq- , fp-ieee ==0.1.*- , gauge- , primitive- , rounded-hw- , vector+ rounded-hw+ , tasty-bench+ mixins:+ tasty-bench (Test.Tasty.Bench as Gauge, Test.Tasty.Bench as Gauge.Main, Test.Tasty.Bench as Gauge.Benchmark) default-language: Haskell2010
src/Numeric/Rounded/Hardware/Internal/Class.hs view
@@ -8,7 +8,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-}-{-# OPTIONS_GHC -Wno-orphans #-}+{-# OPTIONS_GHC -Wno-orphans -Wno-name-shadowing #-} module Numeric.Rounded.Hardware.Internal.Class ( module Numeric.Rounded.Hardware.Internal.Class , module Numeric.Rounded.Hardware.Internal.Rounding
src/Numeric/Rounded/Hardware/Internal/Rounding.hs view
@@ -88,9 +88,12 @@ newtype Rounded (r :: RoundingMode) a = Rounded { getRounded :: a } deriving (Eq, Ord, Generic, Functor, Storable) -instance Show a => Show (Rounded r a) where- -- TODO: Take the rounding direction into account- showsPrec prec (Rounded x) = showParen (prec > 10) $ showString "Rounded " . showsPrec 11 x+instance (Rounding r, Show a) => Show (Rounded r a) where+ showsPrec prec rx@(Rounded x) = showParen (prec > 10) $ showString "Rounded @" . rs . showChar ' ' . showsPrec 11 x+ where+ toProxy :: Rounded r a -> Proxy r+ toProxy _ = Proxy+ rs = shows (rounding (toProxy rx)) instance NFData a => NFData (Rounded r a)