@@ -36,9 +36,11 @@ export checked_abs, checked_add, checked_cld, checked_div, checked_fld,
3636
3737using Base: decompose, BitInteger
3838
39- import BitIntegers # For 128-bit _widemul / _widen
39+ using BitIntegers: BitIntegers, UInt256, Int256
4040import Parsers
4141
42+ include (" fldmod-by-const.jl" )
43+
4244# floats that support fma and are roughly IEEE-like
4345const FMAFloat = Union{Float16, Float32, Float64, BigFloat}
4446
@@ -129,8 +131,10 @@ _widemul(x::Unsigned,y::Signed) = signed(_widen(x)) * _widen(y)
129131
130132# Custom widen implementation to avoid the cost of widening to BigInt.
131133# FD{Int128} operations should widen to 256 bits internally, rather than to a BigInt.
132- _widen (:: Type{Int128} ) = BitIntegers. Int256
133- _widen (:: Type{UInt128} ) = BitIntegers. UInt256
134+ _widen (:: Type{Int128} ) = Int256
135+ _widen (:: Type{UInt128} ) = UInt256
136+ _widen (:: Type{Int256} ) = BitIntegers. Int512
137+ _widen (:: Type{UInt256} ) = BitIntegers. UInt512
134138_widen (t:: Type ) = widen (t)
135139_widen (x:: T ) where {T} = (_widen (T))(x)
136140
@@ -196,18 +200,12 @@ function _round_to_nearest(quotient::T,
196200end
197201_round_to_nearest (q, r, d, m= RoundNearest) = _round_to_nearest (promote (q, r, d)... , m)
198202
199- # In many of our calls to fldmod, `y` is a constant (the coefficient, 10^f). However, since
200- # `fldmod` is sometimes not being inlined, that constant information is not available to the
201- # optimizer. We need an inlined version of fldmod so that the compiler can replace expensive
202- # divide-by-power-of-ten instructions with the cheaper multiply-by-inverse-coefficient.
203- @inline fldmodinline (x,y) = (fld (x,y), mod (x,y))
204-
205203# multiplication rounds to nearest even representation
206204# TODO : can we use floating point to speed this up? after we build a
207205# correctness test suite.
208206function Base.:* (x:: FD{T, f} , y:: FD{T, f} ) where {T, f}
209207 powt = coefficient (FD{T, f})
210- quotient, remainder = fldmodinline (_widemul (x. i, y. i), powt)
208+ quotient, remainder = fldmod_by_const (_widemul (x. i, y. i), Val ( powt) )
211209 reinterpret (FD{T, f}, _round_to_nearest (quotient, remainder, powt))
212210end
213211
@@ -234,12 +232,12 @@ function Base.round(x::FD{T, f},
234232 RoundingMode{:NearestTiesUp },
235233 RoundingMode{:NearestTiesAway }}= RoundNearest) where {T, f}
236234 powt = coefficient (FD{T, f})
237- quotient, remainder = fldmodinline (x. i, powt)
235+ quotient, remainder = fldmod_by_const (x. i, Val ( powt) )
238236 FD {T, f} (_round_to_nearest (quotient, remainder, powt, m))
239237end
240238function Base. ceil (x:: FD{T, f} ) where {T, f}
241239 powt = coefficient (FD{T, f})
242- quotient, remainder = fldmodinline (x. i, powt)
240+ quotient, remainder = fldmod_by_const (x. i, Val ( powt) )
243241 if remainder > 0
244242 FD {T, f} (quotient + one (quotient))
245243 else
@@ -435,7 +433,7 @@ function Base.checked_sub(x::T, y::T) where {T<:FD}
435433end
436434function Base. checked_mul (x:: FD{T,f} , y:: FD{T,f} ) where {T<: Integer ,f}
437435 powt = coefficient (FD{T, f})
438- quotient, remainder = fldmodinline (_widemul (x. i, y. i), powt)
436+ quotient, remainder = fldmod_by_const (_widemul (x. i, y. i), Val ( powt) )
439437 v = _round_to_nearest (quotient, remainder, powt)
440438 typemin (T) <= v <= typemax (T) || Base. Checked. throw_overflowerr_binaryop (:* , x, y)
441439 return reinterpret (FD{T, f}, T (v))
0 commit comments