From 6a44a490527e83a25ec1395f65c967fdeed5fef0 Mon Sep 17 00:00:00 2001 From: Quinton Miller Date: Fri, 24 Mar 2023 17:53:33 +0800 Subject: [PATCH] Workaround for more `Int128`-and-float methods on Windows with LLVM 14+ (#13218) --- src/crystal/compiler_rt.cr | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/crystal/compiler_rt.cr b/src/crystal/compiler_rt.cr index e1681dac4186..2c23b672f69b 100644 --- a/src/crystal/compiler_rt.cr +++ b/src/crystal/compiler_rt.cr @@ -24,6 +24,7 @@ require "./compiler_rt/divmod128.cr" # those functions directly # note that the following defs redefine the ones in `primitives.cr` + # https://github.com/llvm/llvm-project/commit/4a406d32e97b1748c4eed6674a2c1819b9cf98ea struct Int128 {% for int2 in [Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128] %} @[AlwaysInline] @@ -83,4 +84,82 @@ require "./compiler_rt/divmod128.cr" end {% end %} {% end %} + + # https://github.com/llvm/llvm-project/commit/d6216e2cd1a5e07f8509215ee5422ff5ee358da8 + {% if compare_versions(Crystal::LLVM_VERSION, "14.0.0") >= 0 %} + {% for v in [ + {Int128, "to_f32", Float32, "__floattisf"}, + {Int128, "to_f64", Float64, "__floattidf"}, + {UInt128, "to_f32", Float32, "__floatuntisf"}, + {UInt128, "to_f64", Float64, "__floatuntidf"}, + {Float32, "to_i128", Int128, "__fixsfti"}, + {Float32, "to_u128", UInt128, "__fixunssfti"}, + {Float64, "to_i128", Int128, "__fixdfti"}, + {Float64, "to_u128", UInt128, "__fixunsdfti"}, + ] %} + {% type, method, ret, rt_method = v %} + struct {{ type.id }} + @[AlwaysInline] + def {{ method.id }} : {{ ret.id }} + raise OverflowError.new unless {{ ret.id }}::MIN <= self <= {{ ret.id }}::MAX + {{ ret.id }}.new!({{ rt_method.id }}(self)) + end + + @[AlwaysInline] + def {{ method.id }}! : {{ ret.id }} + {{ ret.id }}.new!({{ rt_method.id }}(self)) + end + end + {% end %} + + {% for op in {"+", "-", "*", "fdiv"} %} + struct Int128 + @[AlwaysInline] + def {{ op.id }}(other : Float32) : Float32 + to_f32 {{ op.id }} other + end + + @[AlwaysInline] + def {{ op.id }}(other : Float64) : Float64 + to_f64 {{ op.id }} other + end + end + + struct UInt128 + @[AlwaysInline] + def {{ op.id }}(other : Float32) : Float32 + to_f32 {{ op.id }} other + end + + @[AlwaysInline] + def {{ op.id }}(other : Float64) : Float64 + to_f64 {{ op.id }} other + end + end + + struct Float32 + @[AlwaysInline] + def {{ op.id }}(other : Int128) : Float32 + self.{{ op.id }}(other.to_f32) + end + + @[AlwaysInline] + def {{ op.id }}(other : UInt128) : Float32 + self.{{ op.id }}(other.to_f32) + end + end + + struct Float64 + @[AlwaysInline] + def {{ op.id }}(other : Int128) : Float64 + self.{{ op.id }}(other.to_f64) + end + + @[AlwaysInline] + def {{ op.id }}(other : UInt128) : Float64 + self.{{ op.id }}(other.to_f64) + end + end + {% end %} + {% end %} {% end %}