| author | |
| committer | |
| log | d7f8368da86241f47e97257e737b6fb14bf5f773 |
| tree | 260d9d2d3aa68a96d1ea7594234fae0c3b90640e |
| parent | ea3f5905f0635d0c0cb3983ba5ca6c92859e9d81 |
| parent | cd019ee502d6792c1615b0fab10827db419beab4 |
| signature |
compiler-rt: avoid symbol collisions with Windows libc23 files changed, 271 insertions(+), 24 deletions(-)
lib/compiler_rt.zig+27-24| ... | ... | @@ -724,25 +724,25 @@ comptime { |
| 724 | 724 | @export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage }); |
| 725 | 725 | } |
| 726 | 726 | |
| 727 | mathExport("ceil", @import("./compiler_rt/ceil.zig"), true); | |
| 728 | mathExport("cos", @import("./compiler_rt/cos.zig"), true); | |
| 729 | mathExport("exp", @import("./compiler_rt/exp.zig"), true); | |
| 730 | mathExport("exp2", @import("./compiler_rt/exp2.zig"), true); | |
| 731 | mathExport("fabs", @import("./compiler_rt/fabs.zig"), true); | |
| 732 | mathExport("floor", @import("./compiler_rt/floor.zig"), true); | |
| 733 | mathExport("fma", @import("./compiler_rt/fma.zig"), true); | |
| 734 | mathExport("fmax", @import("./compiler_rt/fmax.zig"), true); | |
| 735 | mathExport("fmin", @import("./compiler_rt/fmin.zig"), true); | |
| 736 | mathExport("fmod", @import("./compiler_rt/fmod.zig"), true); | |
| 737 | mathExport("log", @import("./compiler_rt/log.zig"), true); | |
| 738 | mathExport("log10", @import("./compiler_rt/log10.zig"), true); | |
| 739 | mathExport("log2", @import("./compiler_rt/log2.zig"), true); | |
| 740 | mathExport("round", @import("./compiler_rt/round.zig"), true); | |
| 741 | mathExport("sin", @import("./compiler_rt/sin.zig"), true); | |
| 742 | mathExport("sincos", @import("./compiler_rt/sincos.zig"), true); | |
| 743 | mathExport("sqrt", @import("./compiler_rt/sqrt.zig"), true); | |
| 744 | mathExport("tan", @import("./compiler_rt/tan.zig"), false); | |
| 745 | mathExport("trunc", @import("./compiler_rt/trunc.zig"), true); | |
| 727 | mathExport("ceil", @import("./compiler_rt/ceil.zig")); | |
| 728 | mathExport("cos", @import("./compiler_rt/cos.zig")); | |
| 729 | mathExport("exp", @import("./compiler_rt/exp.zig")); | |
| 730 | mathExport("exp2", @import("./compiler_rt/exp2.zig")); | |
| 731 | mathExport("fabs", @import("./compiler_rt/fabs.zig")); | |
| 732 | mathExport("floor", @import("./compiler_rt/floor.zig")); | |
| 733 | mathExport("fma", @import("./compiler_rt/fma.zig")); | |
| 734 | mathExport("fmax", @import("./compiler_rt/fmax.zig")); | |
| 735 | mathExport("fmin", @import("./compiler_rt/fmin.zig")); | |
| 736 | mathExport("fmod", @import("./compiler_rt/fmod.zig")); | |
| 737 | mathExport("log", @import("./compiler_rt/log.zig")); | |
| 738 | mathExport("log10", @import("./compiler_rt/log10.zig")); | |
| 739 | mathExport("log2", @import("./compiler_rt/log2.zig")); | |
| 740 | mathExport("round", @import("./compiler_rt/round.zig")); | |
| 741 | mathExport("sin", @import("./compiler_rt/sin.zig")); | |
| 742 | mathExport("sincos", @import("./compiler_rt/sincos.zig")); | |
| 743 | mathExport("sqrt", @import("./compiler_rt/sqrt.zig")); | |
| 744 | mathExport("tan", @import("./compiler_rt/tan.zig")); | |
| 745 | mathExport("trunc", @import("./compiler_rt/trunc.zig")); | |
| 746 | 746 | |
| 747 | 747 | if (arch.isSPARC()) { |
| 748 | 748 | // SPARC systems use a different naming scheme |
| ... | ... | @@ -825,7 +825,7 @@ comptime { |
| 825 | 825 | } |
| 826 | 826 | } |
| 827 | 827 | |
| 828 | inline fn mathExport(double_name: []const u8, comptime import: type, is_standard: bool) void { | |
| 828 | inline fn mathExport(double_name: []const u8, comptime import: type) void { | |
| 829 | 829 | const half_name = "__" ++ double_name ++ "h"; |
| 830 | 830 | const half_fn = @field(import, half_name); |
| 831 | 831 | const float_name = double_name ++ "f"; |
| ... | ... | @@ -853,9 +853,12 @@ inline fn mathExport(double_name: []const u8, comptime import: type, is_standard |
| 853 | 853 | .{ f128, quad_fn }, |
| 854 | 854 | }; |
| 855 | 855 | |
| 856 | // Weak aliases don't work on Windows, so we avoid exporting the `l` alias | |
| 857 | // on this platform for functions we know will collide. | |
| 858 | if (builtin.os.tag != .windows or !builtin.link_libc or !is_standard) { | |
| 856 | if (builtin.os.tag == .windows) { | |
| 857 | // Weak aliases don't work on Windows, so we have to provide the 'l' variants | |
| 858 | // as additional function definitions that jump to the real definition. | |
| 859 | const long_double_fn = @field(import, long_double_name); | |
| 860 | @export(long_double_fn, .{ .name = long_double_name, .linkage = linkage }); | |
| 861 | } else { | |
| 859 | 862 | inline for (pairs) |pair| { |
| 860 | 863 | const F = pair[0]; |
| 861 | 864 | const func = pair[1]; |
| ... | ... | @@ -865,7 +868,7 @@ inline fn mathExport(double_name: []const u8, comptime import: type, is_standard |
| 865 | 868 | } |
| 866 | 869 | } |
| 867 | 870 | |
| 868 | if (is_ppc and is_standard) { | |
| 871 | if (is_ppc) { | |
| 869 | 872 | // LLVM PPC backend lowers f128 ops with the suffix `f128` instead of `l`. |
| 870 | 873 | @export(quad_fn, .{ .name = double_name ++ "f128", .linkage = linkage }); |
| 871 | 874 | } |
lib/compiler_rt/ceil.zig+11| ... | ... | @@ -111,6 +111,17 @@ pub fn ceilq(x: f128) callconv(.C) f128 { |
| 111 | 111 | } |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | pub fn ceill(x: c_longdouble) callconv(.C) c_longdouble { | |
| 115 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 116 | 16 => return __ceilh(x), | |
| 117 | 32 => return ceilf(x), | |
| 118 | 64 => return ceil(x), | |
| 119 | 80 => return __ceilx(x), | |
| 120 | 128 => return ceilq(x), | |
| 121 | else => @compileError("unreachable"), | |
| 122 | } | |
| 123 | } | |
| 124 | ||
| 114 | 125 | test "ceil32" { |
| 115 | 126 | try expect(ceilf(1.3) == 2.0); |
| 116 | 127 | try expect(ceilf(-1.3) == -1.0); |
lib/compiler_rt/cos.zig+11| ... | ... | @@ -107,6 +107,17 @@ pub fn cosq(a: f128) callconv(.C) f128 { |
| 107 | 107 | return cos(@floatCast(f64, a)); |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 111 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 112 | 16 => return __cosh(x), | |
| 113 | 32 => return cosf(x), | |
| 114 | 64 => return cos(x), | |
| 115 | 80 => return __cosx(x), | |
| 116 | 128 => return cosq(x), | |
| 117 | else => @compileError("unreachable"), | |
| 118 | } | |
| 119 | } | |
| 120 | ||
| 110 | 121 | test "cos32" { |
| 111 | 122 | const epsilon = 0.00001; |
| 112 | 123 |
lib/compiler_rt/exp.zig+11| ... | ... | @@ -182,6 +182,17 @@ pub fn expq(a: f128) callconv(.C) f128 { |
| 182 | 182 | return exp(@floatCast(f64, a)); |
| 183 | 183 | } |
| 184 | 184 | |
| 185 | pub fn expl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 186 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 187 | 16 => return __exph(x), | |
| 188 | 32 => return expf(x), | |
| 189 | 64 => return exp(x), | |
| 190 | 80 => return __expx(x), | |
| 191 | 128 => return expq(x), | |
| 192 | else => @compileError("unreachable"), | |
| 193 | } | |
| 194 | } | |
| 195 | ||
| 185 | 196 | test "exp32" { |
| 186 | 197 | const epsilon = 0.000001; |
| 187 | 198 |
lib/compiler_rt/exp2.zig+11| ... | ... | @@ -149,6 +149,17 @@ pub fn exp2q(x: f128) callconv(.C) f128 { |
| 149 | 149 | return exp2(@floatCast(f64, x)); |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble { | |
| 153 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 154 | 16 => return __exp2h(x), | |
| 155 | 32 => return exp2f(x), | |
| 156 | 64 => return exp2(x), | |
| 157 | 80 => return __exp2x(x), | |
| 158 | 128 => return exp2q(x), | |
| 159 | else => @compileError("unreachable"), | |
| 160 | } | |
| 161 | } | |
| 162 | ||
| 152 | 163 | const exp2ft = [_]f64{ |
| 153 | 164 | 0x1.6a09e667f3bcdp-1, |
| 154 | 165 | 0x1.7a11473eb0187p-1, |
lib/compiler_rt/fabs.zig+11| ... | ... | @@ -20,6 +20,17 @@ pub fn fabsq(a: f128) callconv(.C) f128 { |
| 20 | 20 | return generic_fabs(a); |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | pub fn fabsl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 24 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 25 | 16 => return __fabsh(x), | |
| 26 | 32 => return fabsf(x), | |
| 27 | 64 => return fabs(x), | |
| 28 | 80 => return __fabsx(x), | |
| 29 | 128 => return fabsq(x), | |
| 30 | else => @compileError("unreachable"), | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 23 | 34 | inline fn generic_fabs(x: anytype) @TypeOf(x) { |
| 24 | 35 | const T = @TypeOf(x); |
| 25 | 36 | const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); |
lib/compiler_rt/floor.zig+11| ... | ... | @@ -141,6 +141,17 @@ pub fn floorq(x: f128) callconv(.C) f128 { |
| 141 | 141 | } |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | pub fn floorl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 145 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 146 | 16 => return __floorh(x), | |
| 147 | 32 => return floorf(x), | |
| 148 | 64 => return floor(x), | |
| 149 | 80 => return __floorx(x), | |
| 150 | 128 => return floorq(x), | |
| 151 | else => @compileError("unreachable"), | |
| 152 | } | |
| 153 | } | |
| 154 | ||
| 144 | 155 | test "floor16" { |
| 145 | 156 | try expect(__floorh(1.3) == 1.0); |
| 146 | 157 | try expect(__floorh(-1.3) == -2.0); |
lib/compiler_rt/fma.zig+11| ... | ... | @@ -135,6 +135,17 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.C) f128 { |
| 135 | 135 | } |
| 136 | 136 | } |
| 137 | 137 | |
| 138 | pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.C) c_longdouble { | |
| 139 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 140 | 16 => return __fmah(x, y, z), | |
| 141 | 32 => return fmaf(x, y, z), | |
| 142 | 64 => return fma(x, y, z), | |
| 143 | 80 => return __fmax(x, y, z), | |
| 144 | 128 => return fmaq(x, y, z), | |
| 145 | else => @compileError("unreachable"), | |
| 146 | } | |
| 147 | } | |
| 148 | ||
| 138 | 149 | const dd = struct { |
| 139 | 150 | hi: f64, |
| 140 | 151 | lo: f64, |
lib/compiler_rt/fmax.zig+11| ... | ... | @@ -21,6 +21,17 @@ pub fn fmaxq(x: f128, y: f128) callconv(.C) f128 { |
| 21 | 21 | return generic_fmax(f128, x, y); |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble { | |
| 25 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 26 | 16 => return __fmaxh(x, y), | |
| 27 | 32 => return fmaxf(x, y), | |
| 28 | 64 => return fmax(x, y), | |
| 29 | 80 => return __fmaxx(x, y), | |
| 30 | 128 => return fmaxq(x, y), | |
| 31 | else => @compileError("unreachable"), | |
| 32 | } | |
| 33 | } | |
| 34 | ||
| 24 | 35 | inline fn generic_fmax(comptime T: type, x: T, y: T) T { |
| 25 | 36 | if (math.isNan(x)) |
| 26 | 37 | return y; |
lib/compiler_rt/fmin.zig+11| ... | ... | @@ -21,6 +21,17 @@ pub fn fminq(x: f128, y: f128) callconv(.C) f128 { |
| 21 | 21 | return generic_fmin(f128, x, y); |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble { | |
| 25 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 26 | 16 => return __fminh(x, y), | |
| 27 | 32 => return fminf(x, y), | |
| 28 | 64 => return fmin(x, y), | |
| 29 | 80 => return __fminx(x, y), | |
| 30 | 128 => return fminq(x, y), | |
| 31 | else => @compileError("unreachable"), | |
| 32 | } | |
| 33 | } | |
| 34 | ||
| 24 | 35 | inline fn generic_fmin(comptime T: type, x: T, y: T) T { |
| 25 | 36 | if (math.isNan(x)) |
| 26 | 37 | return y; |
lib/compiler_rt/fmod.zig+11| ... | ... | @@ -237,6 +237,17 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 { |
| 237 | 237 | return amod; |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.C) c_longdouble { | |
| 241 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 242 | 16 => return __fmodh(a, b), | |
| 243 | 32 => return fmodf(a, b), | |
| 244 | 64 => return fmod(a, b), | |
| 245 | 80 => return __fmodx(a, b), | |
| 246 | 128 => return fmodq(a, b), | |
| 247 | else => @compileError("unreachable"), | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 240 | 251 | inline fn generic_fmod(comptime T: type, x: T, y: T) T { |
| 241 | 252 | @setRuntimeSafety(false); |
| 242 | 253 |
lib/compiler_rt/log.zig+11| ... | ... | @@ -131,6 +131,17 @@ pub fn logq(a: f128) callconv(.C) f128 { |
| 131 | 131 | return log(@floatCast(f64, a)); |
| 132 | 132 | } |
| 133 | 133 | |
| 134 | pub fn logl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 135 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 136 | 16 => return __logh(x), | |
| 137 | 32 => return logf(x), | |
| 138 | 64 => return log(x), | |
| 139 | 80 => return __logx(x), | |
| 140 | 128 => return logq(x), | |
| 141 | else => @compileError("unreachable"), | |
| 142 | } | |
| 143 | } | |
| 144 | ||
| 134 | 145 | test "ln32" { |
| 135 | 146 | const epsilon = 0.000001; |
| 136 | 147 |
lib/compiler_rt/log10.zig+11| ... | ... | @@ -159,6 +159,17 @@ pub fn log10q(a: f128) callconv(.C) f128 { |
| 159 | 159 | return log10(@floatCast(f64, a)); |
| 160 | 160 | } |
| 161 | 161 | |
| 162 | pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble { | |
| 163 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 164 | 16 => return __log10h(x), | |
| 165 | 32 => return log10f(x), | |
| 166 | 64 => return log10(x), | |
| 167 | 80 => return __log10x(x), | |
| 168 | 128 => return log10q(x), | |
| 169 | else => @compileError("unreachable"), | |
| 170 | } | |
| 171 | } | |
| 172 | ||
| 162 | 173 | test "log10_32" { |
| 163 | 174 | const epsilon = 0.000001; |
| 164 | 175 |
lib/compiler_rt/log2.zig+11| ... | ... | @@ -150,6 +150,17 @@ pub fn log2q(a: f128) callconv(.C) f128 { |
| 150 | 150 | return math.log2(a); |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble { | |
| 154 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 155 | 16 => return __log2h(x), | |
| 156 | 32 => return log2f(x), | |
| 157 | 64 => return log2(x), | |
| 158 | 80 => return __log2x(x), | |
| 159 | 128 => return log2q(x), | |
| 160 | else => @compileError("unreachable"), | |
| 161 | } | |
| 162 | } | |
| 163 | ||
| 153 | 164 | test "log2_32" { |
| 154 | 165 | const epsilon = 0.000001; |
| 155 | 166 |
lib/compiler_rt/round.zig+11| ... | ... | @@ -123,6 +123,17 @@ pub fn roundq(x_: f128) callconv(.C) f128 { |
| 123 | 123 | } |
| 124 | 124 | } |
| 125 | 125 | |
| 126 | pub fn roundl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 127 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 128 | 16 => return __roundh(x), | |
| 129 | 32 => return roundf(x), | |
| 130 | 64 => return round(x), | |
| 131 | 80 => return __roundx(x), | |
| 132 | 128 => return roundq(x), | |
| 133 | else => @compileError("unreachable"), | |
| 134 | } | |
| 135 | } | |
| 136 | ||
| 126 | 137 | test "round32" { |
| 127 | 138 | try expect(roundf(1.3) == 1.0); |
| 128 | 139 | try expect(roundf(-1.3) == -1.0); |
lib/compiler_rt/sin.zig+11| ... | ... | @@ -111,6 +111,17 @@ pub fn sinq(x: f128) callconv(.C) f128 { |
| 111 | 111 | return sin(@floatCast(f64, x)); |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | pub fn sinl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 115 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 116 | 16 => return __sinh(x), | |
| 117 | 32 => return sinf(x), | |
| 118 | 64 => return sin(x), | |
| 119 | 80 => return __sinx(x), | |
| 120 | 128 => return sinq(x), | |
| 121 | else => @compileError("unreachable"), | |
| 122 | } | |
| 123 | } | |
| 124 | ||
| 114 | 125 | test "sin32" { |
| 115 | 126 | const epsilon = 0.00001; |
| 116 | 127 |
lib/compiler_rt/sincos.zig+11| ... | ... | @@ -181,6 +181,17 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void { |
| 181 | 181 | r_cos.* = small_cos; |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.C) void { | |
| 185 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 186 | 16 => return __sincosh(x, r_sin, r_cos), | |
| 187 | 32 => return sincosf(x, r_sin, r_cos), | |
| 188 | 64 => return sincos(x, r_sin, r_cos), | |
| 189 | 80 => return __sincosx(x, r_sin, r_cos), | |
| 190 | 128 => return sincosq(x, r_sin, r_cos), | |
| 191 | else => @compileError("unreachable"), | |
| 192 | } | |
| 193 | } | |
| 194 | ||
| 184 | 195 | const rem_pio2_generic = @compileError("TODO"); |
| 185 | 196 | |
| 186 | 197 | /// Ported from musl sincosl.c. Needs the following dependencies to be complete: |
lib/compiler_rt/sqrt.zig+11| ... | ... | @@ -225,6 +225,17 @@ pub fn sqrtq(x: f128) callconv(.C) f128 { |
| 225 | 225 | return sqrt(@floatCast(f64, x)); |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | pub fn sqrtl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 229 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 230 | 16 => return __sqrth(x), | |
| 231 | 32 => return sqrtf(x), | |
| 232 | 64 => return sqrt(x), | |
| 233 | 80 => return __sqrtx(x), | |
| 234 | 128 => return sqrtq(x), | |
| 235 | else => @compileError("unreachable"), | |
| 236 | } | |
| 237 | } | |
| 238 | ||
| 228 | 239 | test "sqrtf" { |
| 229 | 240 | const V = [_]f32{ |
| 230 | 241 | 0.0, |
lib/compiler_rt/tan.zig+11| ... | ... | @@ -96,6 +96,17 @@ pub fn tanq(x: f128) callconv(.C) f128 { |
| 96 | 96 | return tan(@floatCast(f64, x)); |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | pub fn tanl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 100 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 101 | 16 => return __tanh(x), | |
| 102 | 32 => return tanf(x), | |
| 103 | 64 => return tan(x), | |
| 104 | 80 => return __tanx(x), | |
| 105 | 128 => return tanq(x), | |
| 106 | else => @compileError("unreachable"), | |
| 107 | } | |
| 108 | } | |
| 109 | ||
| 99 | 110 | test "tan" { |
| 100 | 111 | try expect(tan(@as(f32, 0.0)) == tanf(0.0)); |
| 101 | 112 | try expect(tan(@as(f64, 0.0)) == tan(0.0)); |
lib/compiler_rt/trunc.zig+11| ... | ... | @@ -81,6 +81,17 @@ pub fn truncq(x: f128) callconv(.C) f128 { |
| 81 | 81 | } |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | pub fn truncl(x: c_longdouble) callconv(.C) c_longdouble { | |
| 85 | switch (@typeInfo(c_longdouble).Float.bits) { | |
| 86 | 16 => return __trunch(x), | |
| 87 | 32 => return truncf(x), | |
| 88 | 64 => return trunc(x), | |
| 89 | 80 => return __truncx(x), | |
| 90 | 128 => return truncq(x), | |
| 91 | else => @compileError("unreachable"), | |
| 92 | } | |
| 93 | } | |
| 94 | ||
| 84 | 95 | test "trunc32" { |
| 85 | 96 | try expect(truncf(1.3) == 1.0); |
| 86 | 97 | try expect(truncf(-1.3) == -1.0); |
src/Sema.zig+9| ... | ... | @@ -18673,6 +18673,15 @@ fn coerceInMemoryAllowed( |
| 18673 | 18673 | } |
| 18674 | 18674 | } |
| 18675 | 18675 | |
| 18676 | // Differently-named floats with the same number of bits. | |
| 18677 | if (dest_ty.zigTypeTag() == .Float and src_ty.zigTypeTag() == .Float) { | |
| 18678 | const dest_bits = dest_ty.floatBits(target); | |
| 18679 | const src_bits = src_ty.floatBits(target); | |
| 18680 | if (dest_bits == src_bits) { | |
| 18681 | return .ok; | |
| 18682 | } | |
| 18683 | } | |
| 18684 | ||
| 18676 | 18685 | // Pointers / Pointer-like Optionals |
| 18677 | 18686 | var dest_buf: Type.Payload.ElemType = undefined; |
| 18678 | 18687 | var src_buf: Type.Payload.ElemType = undefined; |
src/stage1/ir.cpp+6| ... | ... | @@ -4480,6 +4480,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 4480 | 4480 | return result; |
| 4481 | 4481 | } |
| 4482 | 4482 | |
| 4483 | if (wanted_type->id == ZigTypeIdFloat && actual_type->id == ZigTypeIdFloat) { | |
| 4484 | if (wanted_type->data.floating.bit_count == actual_type->data.floating.bit_count) { | |
| 4485 | return result; | |
| 4486 | } | |
| 4487 | } | |
| 4488 | ||
| 4483 | 4489 | if (wanted_type->id == ZigTypeIdVector && actual_type->id == ZigTypeIdVector) { |
| 4484 | 4490 | if (actual_type->data.vector.len != wanted_type->data.vector.len) { |
| 4485 | 4491 | result.id = ConstCastResultIdVectorLength; |
test/behavior/cast.zig+20| ... | ... | @@ -1426,3 +1426,23 @@ test "pointer to empty struct literal to mutable slice" { |
| 1426 | 1426 | var x: []i32 = &.{}; |
| 1427 | 1427 | try expect(x.len == 0); |
| 1428 | 1428 | } |
| 1429 | ||
| 1430 | test "coerce between pointers of compatible differently-named floats" { | |
| 1431 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 1432 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 1433 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 1434 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 1435 | ||
| 1436 | const F = switch (@typeInfo(c_longdouble).Float.bits) { | |
| 1437 | 16 => f16, | |
| 1438 | 32 => f32, | |
| 1439 | 64 => f64, | |
| 1440 | 80 => f80, | |
| 1441 | 128 => f128, | |
| 1442 | else => @compileError("unreachable"), | |
| 1443 | }; | |
| 1444 | var f1: F = 12.34; | |
| 1445 | var f2: *c_longdouble = &f1; | |
| 1446 | f2.* += 1; | |
| 1447 | try expect(f1 == @as(F, 12.34) + 1); | |
| 1448 | } |