mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
Merge pull request #11609 from ziglang/win-compiler-rt
compiler-rt: avoid symbol collisions with Windows libc
This commit is contained in:
commit
d7f8368da8
@ -724,25 +724,25 @@ comptime {
|
||||
@export(_aullrem, .{ .name = "\x01__aullrem", .linkage = strong_linkage });
|
||||
}
|
||||
|
||||
mathExport("ceil", @import("./compiler_rt/ceil.zig"), true);
|
||||
mathExport("cos", @import("./compiler_rt/cos.zig"), true);
|
||||
mathExport("exp", @import("./compiler_rt/exp.zig"), true);
|
||||
mathExport("exp2", @import("./compiler_rt/exp2.zig"), true);
|
||||
mathExport("fabs", @import("./compiler_rt/fabs.zig"), true);
|
||||
mathExport("floor", @import("./compiler_rt/floor.zig"), true);
|
||||
mathExport("fma", @import("./compiler_rt/fma.zig"), true);
|
||||
mathExport("fmax", @import("./compiler_rt/fmax.zig"), true);
|
||||
mathExport("fmin", @import("./compiler_rt/fmin.zig"), true);
|
||||
mathExport("fmod", @import("./compiler_rt/fmod.zig"), true);
|
||||
mathExport("log", @import("./compiler_rt/log.zig"), true);
|
||||
mathExport("log10", @import("./compiler_rt/log10.zig"), true);
|
||||
mathExport("log2", @import("./compiler_rt/log2.zig"), true);
|
||||
mathExport("round", @import("./compiler_rt/round.zig"), true);
|
||||
mathExport("sin", @import("./compiler_rt/sin.zig"), true);
|
||||
mathExport("sincos", @import("./compiler_rt/sincos.zig"), true);
|
||||
mathExport("sqrt", @import("./compiler_rt/sqrt.zig"), true);
|
||||
mathExport("tan", @import("./compiler_rt/tan.zig"), false);
|
||||
mathExport("trunc", @import("./compiler_rt/trunc.zig"), true);
|
||||
mathExport("ceil", @import("./compiler_rt/ceil.zig"));
|
||||
mathExport("cos", @import("./compiler_rt/cos.zig"));
|
||||
mathExport("exp", @import("./compiler_rt/exp.zig"));
|
||||
mathExport("exp2", @import("./compiler_rt/exp2.zig"));
|
||||
mathExport("fabs", @import("./compiler_rt/fabs.zig"));
|
||||
mathExport("floor", @import("./compiler_rt/floor.zig"));
|
||||
mathExport("fma", @import("./compiler_rt/fma.zig"));
|
||||
mathExport("fmax", @import("./compiler_rt/fmax.zig"));
|
||||
mathExport("fmin", @import("./compiler_rt/fmin.zig"));
|
||||
mathExport("fmod", @import("./compiler_rt/fmod.zig"));
|
||||
mathExport("log", @import("./compiler_rt/log.zig"));
|
||||
mathExport("log10", @import("./compiler_rt/log10.zig"));
|
||||
mathExport("log2", @import("./compiler_rt/log2.zig"));
|
||||
mathExport("round", @import("./compiler_rt/round.zig"));
|
||||
mathExport("sin", @import("./compiler_rt/sin.zig"));
|
||||
mathExport("sincos", @import("./compiler_rt/sincos.zig"));
|
||||
mathExport("sqrt", @import("./compiler_rt/sqrt.zig"));
|
||||
mathExport("tan", @import("./compiler_rt/tan.zig"));
|
||||
mathExport("trunc", @import("./compiler_rt/trunc.zig"));
|
||||
|
||||
if (arch.isSPARC()) {
|
||||
// SPARC systems use a different naming scheme
|
||||
@ -825,7 +825,7 @@ comptime {
|
||||
}
|
||||
}
|
||||
|
||||
inline fn mathExport(double_name: []const u8, comptime import: type, is_standard: bool) void {
|
||||
inline fn mathExport(double_name: []const u8, comptime import: type) void {
|
||||
const half_name = "__" ++ double_name ++ "h";
|
||||
const half_fn = @field(import, half_name);
|
||||
const float_name = double_name ++ "f";
|
||||
@ -853,9 +853,12 @@ inline fn mathExport(double_name: []const u8, comptime import: type, is_standard
|
||||
.{ f128, quad_fn },
|
||||
};
|
||||
|
||||
// Weak aliases don't work on Windows, so we avoid exporting the `l` alias
|
||||
// on this platform for functions we know will collide.
|
||||
if (builtin.os.tag != .windows or !builtin.link_libc or !is_standard) {
|
||||
if (builtin.os.tag == .windows) {
|
||||
// Weak aliases don't work on Windows, so we have to provide the 'l' variants
|
||||
// as additional function definitions that jump to the real definition.
|
||||
const long_double_fn = @field(import, long_double_name);
|
||||
@export(long_double_fn, .{ .name = long_double_name, .linkage = linkage });
|
||||
} else {
|
||||
inline for (pairs) |pair| {
|
||||
const F = pair[0];
|
||||
const func = pair[1];
|
||||
@ -865,7 +868,7 @@ inline fn mathExport(double_name: []const u8, comptime import: type, is_standard
|
||||
}
|
||||
}
|
||||
|
||||
if (is_ppc and is_standard) {
|
||||
if (is_ppc) {
|
||||
// LLVM PPC backend lowers f128 ops with the suffix `f128` instead of `l`.
|
||||
@export(quad_fn, .{ .name = double_name ++ "f128", .linkage = linkage });
|
||||
}
|
||||
|
||||
@ -111,6 +111,17 @@ pub fn ceilq(x: f128) callconv(.C) f128 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ceill(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __ceilh(x),
|
||||
32 => return ceilf(x),
|
||||
64 => return ceil(x),
|
||||
80 => return __ceilx(x),
|
||||
128 => return ceilq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "ceil32" {
|
||||
try expect(ceilf(1.3) == 2.0);
|
||||
try expect(ceilf(-1.3) == -1.0);
|
||||
|
||||
@ -107,6 +107,17 @@ pub fn cosq(a: f128) callconv(.C) f128 {
|
||||
return cos(@floatCast(f64, a));
|
||||
}
|
||||
|
||||
pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __cosh(x),
|
||||
32 => return cosf(x),
|
||||
64 => return cos(x),
|
||||
80 => return __cosx(x),
|
||||
128 => return cosq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "cos32" {
|
||||
const epsilon = 0.00001;
|
||||
|
||||
|
||||
@ -182,6 +182,17 @@ pub fn expq(a: f128) callconv(.C) f128 {
|
||||
return exp(@floatCast(f64, a));
|
||||
}
|
||||
|
||||
pub fn expl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __exph(x),
|
||||
32 => return expf(x),
|
||||
64 => return exp(x),
|
||||
80 => return __expx(x),
|
||||
128 => return expq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "exp32" {
|
||||
const epsilon = 0.000001;
|
||||
|
||||
|
||||
@ -149,6 +149,17 @@ pub fn exp2q(x: f128) callconv(.C) f128 {
|
||||
return exp2(@floatCast(f64, x));
|
||||
}
|
||||
|
||||
pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __exp2h(x),
|
||||
32 => return exp2f(x),
|
||||
64 => return exp2(x),
|
||||
80 => return __exp2x(x),
|
||||
128 => return exp2q(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
const exp2ft = [_]f64{
|
||||
0x1.6a09e667f3bcdp-1,
|
||||
0x1.7a11473eb0187p-1,
|
||||
|
||||
@ -20,6 +20,17 @@ pub fn fabsq(a: f128) callconv(.C) f128 {
|
||||
return generic_fabs(a);
|
||||
}
|
||||
|
||||
pub fn fabsl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __fabsh(x),
|
||||
32 => return fabsf(x),
|
||||
64 => return fabs(x),
|
||||
80 => return __fabsx(x),
|
||||
128 => return fabsq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
inline fn generic_fabs(x: anytype) @TypeOf(x) {
|
||||
const T = @TypeOf(x);
|
||||
const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
|
||||
|
||||
@ -141,6 +141,17 @@ pub fn floorq(x: f128) callconv(.C) f128 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn floorl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __floorh(x),
|
||||
32 => return floorf(x),
|
||||
64 => return floor(x),
|
||||
80 => return __floorx(x),
|
||||
128 => return floorq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "floor16" {
|
||||
try expect(__floorh(1.3) == 1.0);
|
||||
try expect(__floorh(-1.3) == -2.0);
|
||||
|
||||
@ -135,6 +135,17 @@ pub fn fmaq(x: f128, y: f128, z: f128) callconv(.C) f128 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fmal(x: c_longdouble, y: c_longdouble, z: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __fmah(x, y, z),
|
||||
32 => return fmaf(x, y, z),
|
||||
64 => return fma(x, y, z),
|
||||
80 => return __fmax(x, y, z),
|
||||
128 => return fmaq(x, y, z),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
const dd = struct {
|
||||
hi: f64,
|
||||
lo: f64,
|
||||
|
||||
@ -21,6 +21,17 @@ pub fn fmaxq(x: f128, y: f128) callconv(.C) f128 {
|
||||
return generic_fmax(f128, x, y);
|
||||
}
|
||||
|
||||
pub fn fmaxl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __fmaxh(x, y),
|
||||
32 => return fmaxf(x, y),
|
||||
64 => return fmax(x, y),
|
||||
80 => return __fmaxx(x, y),
|
||||
128 => return fmaxq(x, y),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
inline fn generic_fmax(comptime T: type, x: T, y: T) T {
|
||||
if (math.isNan(x))
|
||||
return y;
|
||||
|
||||
@ -21,6 +21,17 @@ pub fn fminq(x: f128, y: f128) callconv(.C) f128 {
|
||||
return generic_fmin(f128, x, y);
|
||||
}
|
||||
|
||||
pub fn fminl(x: c_longdouble, y: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __fminh(x, y),
|
||||
32 => return fminf(x, y),
|
||||
64 => return fmin(x, y),
|
||||
80 => return __fminx(x, y),
|
||||
128 => return fminq(x, y),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
inline fn generic_fmin(comptime T: type, x: T, y: T) T {
|
||||
if (math.isNan(x))
|
||||
return y;
|
||||
|
||||
@ -237,6 +237,17 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
|
||||
return amod;
|
||||
}
|
||||
|
||||
pub fn fmodl(a: c_longdouble, b: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __fmodh(a, b),
|
||||
32 => return fmodf(a, b),
|
||||
64 => return fmod(a, b),
|
||||
80 => return __fmodx(a, b),
|
||||
128 => return fmodq(a, b),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
inline fn generic_fmod(comptime T: type, x: T, y: T) T {
|
||||
@setRuntimeSafety(false);
|
||||
|
||||
|
||||
@ -131,6 +131,17 @@ pub fn logq(a: f128) callconv(.C) f128 {
|
||||
return log(@floatCast(f64, a));
|
||||
}
|
||||
|
||||
pub fn logl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __logh(x),
|
||||
32 => return logf(x),
|
||||
64 => return log(x),
|
||||
80 => return __logx(x),
|
||||
128 => return logq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "ln32" {
|
||||
const epsilon = 0.000001;
|
||||
|
||||
|
||||
@ -159,6 +159,17 @@ pub fn log10q(a: f128) callconv(.C) f128 {
|
||||
return log10(@floatCast(f64, a));
|
||||
}
|
||||
|
||||
pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __log10h(x),
|
||||
32 => return log10f(x),
|
||||
64 => return log10(x),
|
||||
80 => return __log10x(x),
|
||||
128 => return log10q(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "log10_32" {
|
||||
const epsilon = 0.000001;
|
||||
|
||||
|
||||
@ -150,6 +150,17 @@ pub fn log2q(a: f128) callconv(.C) f128 {
|
||||
return math.log2(a);
|
||||
}
|
||||
|
||||
pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __log2h(x),
|
||||
32 => return log2f(x),
|
||||
64 => return log2(x),
|
||||
80 => return __log2x(x),
|
||||
128 => return log2q(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "log2_32" {
|
||||
const epsilon = 0.000001;
|
||||
|
||||
|
||||
@ -123,6 +123,17 @@ pub fn roundq(x_: f128) callconv(.C) f128 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn roundl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __roundh(x),
|
||||
32 => return roundf(x),
|
||||
64 => return round(x),
|
||||
80 => return __roundx(x),
|
||||
128 => return roundq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "round32" {
|
||||
try expect(roundf(1.3) == 1.0);
|
||||
try expect(roundf(-1.3) == -1.0);
|
||||
|
||||
@ -111,6 +111,17 @@ pub fn sinq(x: f128) callconv(.C) f128 {
|
||||
return sin(@floatCast(f64, x));
|
||||
}
|
||||
|
||||
pub fn sinl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __sinh(x),
|
||||
32 => return sinf(x),
|
||||
64 => return sin(x),
|
||||
80 => return __sinx(x),
|
||||
128 => return sinq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "sin32" {
|
||||
const epsilon = 0.00001;
|
||||
|
||||
|
||||
@ -181,6 +181,17 @@ pub fn sincosq(x: f128, r_sin: *f128, r_cos: *f128) callconv(.C) void {
|
||||
r_cos.* = small_cos;
|
||||
}
|
||||
|
||||
pub fn sincosl(x: c_longdouble, r_sin: *c_longdouble, r_cos: *c_longdouble) callconv(.C) void {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __sincosh(x, r_sin, r_cos),
|
||||
32 => return sincosf(x, r_sin, r_cos),
|
||||
64 => return sincos(x, r_sin, r_cos),
|
||||
80 => return __sincosx(x, r_sin, r_cos),
|
||||
128 => return sincosq(x, r_sin, r_cos),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
const rem_pio2_generic = @compileError("TODO");
|
||||
|
||||
/// Ported from musl sincosl.c. Needs the following dependencies to be complete:
|
||||
|
||||
@ -225,6 +225,17 @@ pub fn sqrtq(x: f128) callconv(.C) f128 {
|
||||
return sqrt(@floatCast(f64, x));
|
||||
}
|
||||
|
||||
pub fn sqrtl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __sqrth(x),
|
||||
32 => return sqrtf(x),
|
||||
64 => return sqrt(x),
|
||||
80 => return __sqrtx(x),
|
||||
128 => return sqrtq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "sqrtf" {
|
||||
const V = [_]f32{
|
||||
0.0,
|
||||
|
||||
@ -96,6 +96,17 @@ pub fn tanq(x: f128) callconv(.C) f128 {
|
||||
return tan(@floatCast(f64, x));
|
||||
}
|
||||
|
||||
pub fn tanl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __tanh(x),
|
||||
32 => return tanf(x),
|
||||
64 => return tan(x),
|
||||
80 => return __tanx(x),
|
||||
128 => return tanq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "tan" {
|
||||
try expect(tan(@as(f32, 0.0)) == tanf(0.0));
|
||||
try expect(tan(@as(f64, 0.0)) == tan(0.0));
|
||||
|
||||
@ -81,6 +81,17 @@ pub fn truncq(x: f128) callconv(.C) f128 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn truncl(x: c_longdouble) callconv(.C) c_longdouble {
|
||||
switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => return __trunch(x),
|
||||
32 => return truncf(x),
|
||||
64 => return trunc(x),
|
||||
80 => return __truncx(x),
|
||||
128 => return truncq(x),
|
||||
else => @compileError("unreachable"),
|
||||
}
|
||||
}
|
||||
|
||||
test "trunc32" {
|
||||
try expect(truncf(1.3) == 1.0);
|
||||
try expect(truncf(-1.3) == -1.0);
|
||||
|
||||
@ -18673,6 +18673,15 @@ fn coerceInMemoryAllowed(
|
||||
}
|
||||
}
|
||||
|
||||
// Differently-named floats with the same number of bits.
|
||||
if (dest_ty.zigTypeTag() == .Float and src_ty.zigTypeTag() == .Float) {
|
||||
const dest_bits = dest_ty.floatBits(target);
|
||||
const src_bits = src_ty.floatBits(target);
|
||||
if (dest_bits == src_bits) {
|
||||
return .ok;
|
||||
}
|
||||
}
|
||||
|
||||
// Pointers / Pointer-like Optionals
|
||||
var dest_buf: Type.Payload.ElemType = undefined;
|
||||
var src_buf: Type.Payload.ElemType = undefined;
|
||||
|
||||
@ -4480,6 +4480,12 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
|
||||
return result;
|
||||
}
|
||||
|
||||
if (wanted_type->id == ZigTypeIdFloat && actual_type->id == ZigTypeIdFloat) {
|
||||
if (wanted_type->data.floating.bit_count == actual_type->data.floating.bit_count) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (wanted_type->id == ZigTypeIdVector && actual_type->id == ZigTypeIdVector) {
|
||||
if (actual_type->data.vector.len != wanted_type->data.vector.len) {
|
||||
result.id = ConstCastResultIdVectorLength;
|
||||
|
||||
@ -1426,3 +1426,23 @@ test "pointer to empty struct literal to mutable slice" {
|
||||
var x: []i32 = &.{};
|
||||
try expect(x.len == 0);
|
||||
}
|
||||
|
||||
test "coerce between pointers of compatible differently-named floats" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const F = switch (@typeInfo(c_longdouble).Float.bits) {
|
||||
16 => f16,
|
||||
32 => f32,
|
||||
64 => f64,
|
||||
80 => f80,
|
||||
128 => f128,
|
||||
else => @compileError("unreachable"),
|
||||
};
|
||||
var f1: F = 12.34;
|
||||
var f2: *c_longdouble = &f1;
|
||||
f2.* += 1;
|
||||
try expect(f1 == @as(F, 12.34) + 1);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user