HaraldHofstaetter / Quadmath.jl

Float128 and libquadmath for the Julia language
Other
4 stars 2 forks source link

Use `VecElement` to work around the register issues #1

Open simonbyrne opened 7 years ago

simonbyrne commented 7 years ago

Firstly, thanks! I was looking into wrapping libquadmath, but luckily decided to search beforehand.

I think I may have figured out a solution to your register passing woes, which should allow getting rid of the C shim. Instead of using a bitstype you can instead pass a Tuple of VecElements, which can fool the compiler into thinking you're using SIMD vectors (see http://docs.julialang.org/en/stable/stdlib/simd-types/).

As a quick demo:

const libquadmath = "libquadmath.0"

import Base: cconvert, convert, +

typealias CFloat128 NTuple{2,VecElement{Float64}}

immutable Float128 <: AbstractFloat
    data::CFloat128
end
Float128(x::Number) = convert(Float128, x)

Base.cconvert(::Type{CFloat128}, x::Float128) = x.data

convert(::Type{Float128}, x::Float64) =
    Float128(ccall((:__extenddftf2, libquadmath), CFloat128, (Float64,), x))

convert(::Type{Float64}, x::Float128) =
    ccall((:__trunctfdf2, libquadmath), Float64, (CFloat128,), x)

(+)(x::Float128, y::Float128) =
    Float128(ccall((:__addtf3,libquadmath), CFloat128, (CFloat128,CFloat128), x, y))

gives:

julia> Float64(Float128(1.0) + Float128(2.0))
3.0

p.s. Please consider registering the package in METADATA: it is really useful!