Skip to content

Commit

Permalink
compiler_rt: Update Windows ABI for float<->int conversion routines
Browse files Browse the repository at this point in the history
Starting with LLVM 14, the Libcalls to these functions are now lowered
using a Vec(2, u64) instead of the standard ABI for i128 integers, so
our compiler-rt implementation needs to be updated to expose the same
ABI on Windows.
  • Loading branch information
topolarity committed Jul 10, 2022
1 parent b88151e commit c8d2f5f
Show file tree
Hide file tree
Showing 21 changed files with 305 additions and 39 deletions.
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixdfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixdfti, .{ .name = "__fixdfti", .linkage = common.linkage });
const fixdfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixdfti_windows_x86_64;
} else __fixdfti;

@export(fixdfti_fn, .{ .name = "__fixdfti", .linkage = common.linkage });
}

pub fn __fixdfti(a: f64) callconv(.C) i128 {
return floatToInt(i128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixdfti_windows_x86_64(a: f64) callconv(.C) v128 {
return @bitCast(v128, floatToInt(i128, a));
}
18 changes: 16 additions & 2 deletions lib/compiler_rt/fixhfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixhfti, .{ .name = "__fixhfti", .linkage = common.linkage });
const fixhfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixhfti_windows_x86_64;
} else __fixhfti;

@export(fixhfti_fn, .{ .name = "__fixhfti", .linkage = common.linkage });
}

fn __fixhfti(a: f16) callconv(.C) i128 {
pub fn __fixhfti(a: f16) callconv(.C) i128 {
return floatToInt(i128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixhfti_windows_x86_64(a: f16) callconv(.C) v128 {
return @bitCast(v128, floatToInt(i128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixsfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixsfti, .{ .name = "__fixsfti", .linkage = common.linkage });
const fixsfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixsfti_windows_x86_64;
} else __fixsfti;

@export(fixsfti_fn, .{ .name = "__fixsfti", .linkage = common.linkage });
}

pub fn __fixsfti(a: f32) callconv(.C) i128 {
return floatToInt(i128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixsfti_windows_x86_64(a: f32) callconv(.C) v128 {
return @bitCast(v128, floatToInt(i128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixtfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixtfti, .{ .name = "__fixtfti", .linkage = common.linkage });
const fixtfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixtfti_windows_x86_64;
} else __fixtfti;

@export(fixtfti_fn, .{ .name = "__fixtfti", .linkage = common.linkage });
}

pub fn __fixtfti(a: f128) callconv(.C) i128 {
return floatToInt(i128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixtfti_windows_x86_64(a: f128) callconv(.C) v128 {
return @bitCast(v128, floatToInt(i128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixunsdfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixunsdfti, .{ .name = "__fixunsdfti", .linkage = common.linkage });
const fixunsdfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixunsdfti_windows_x86_64;
} else __fixunsdfti;

@export(fixunsdfti_fn, .{ .name = "__fixunsdfti", .linkage = common.linkage });
}

pub fn __fixunsdfti(a: f64) callconv(.C) u128 {
return floatToInt(u128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixunsdfti_windows_x86_64(a: f64) callconv(.C) v128 {
return @bitCast(v128, floatToInt(u128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixunshfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixunshfti, .{ .name = "__fixunshfti", .linkage = common.linkage });
const fixunshfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixunshfti_windows_x86_64;
} else __fixunshfti;

@export(fixunshfti_fn, .{ .name = "__fixunshfti", .linkage = common.linkage });
}

pub fn __fixunshfti(a: f16) callconv(.C) u128 {
return floatToInt(u128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixunshfti_windows_x86_64(a: f16) callconv(.C) v128 {
return @bitCast(v128, floatToInt(u128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixunssfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixunssfti, .{ .name = "__fixunssfti", .linkage = common.linkage });
const fixunssfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixunssfti_windows_x86_64;
} else __fixunssfti;

@export(fixunssfti_fn, .{ .name = "__fixunssfti", .linkage = common.linkage });
}

pub fn __fixunssfti(a: f32) callconv(.C) u128 {
return floatToInt(u128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixunssfti_windows_x86_64(a: f32) callconv(.C) v128 {
return @bitCast(v128, floatToInt(u128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixunstfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixunstfti, .{ .name = "__fixunstfti", .linkage = common.linkage });
const fixunstfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixunstfti_windows_x86_64;
} else __fixunstfti;

@export(fixunstfti_fn, .{ .name = "__fixunstfti", .linkage = common.linkage });
}

pub fn __fixunstfti(a: f128) callconv(.C) u128 {
return floatToInt(u128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixunstfti_windows_x86_64(a: f128) callconv(.C) v128 {
return @bitCast(v128, floatToInt(u128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/fixunsxfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixunsxfti, .{ .name = "__fixunsxfti", .linkage = common.linkage });
const fixunsxfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixunsxfti_windows_x86_64;
} else __fixunsxfti;

@export(fixunsxfti_fn, .{ .name = "__fixunsxfti", .linkage = common.linkage });
}

pub fn __fixunsxfti(a: f80) callconv(.C) u128 {
return floatToInt(u128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixunsxfti_windows_x86_64(a: f80) callconv(.C) v128 {
return @bitCast(v128, floatToInt(u128, a));
}
18 changes: 16 additions & 2 deletions lib/compiler_rt/fixxfti.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const floatToInt = @import("./float_to_int.zig").floatToInt;

pub const panic = common.panic;

comptime {
@export(__fixxfti, .{ .name = "__fixxfti", .linkage = common.linkage });
const fixxfti_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __fixxfti_windows_x86_64;
} else __fixxfti;

@export(fixxfti_fn, .{ .name = "__fixxfti", .linkage = common.linkage });
}

fn __fixxfti(a: f80) callconv(.C) i128 {
pub fn __fixxfti(a: f80) callconv(.C) i128 {
return floatToInt(i128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __fixxfti_windows_x86_64(a: f80) callconv(.C) v128 {
return @bitCast(v128, floatToInt(i128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/floattidf.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const intToFloat = @import("./int_to_float.zig").intToFloat;

pub const panic = common.panic;

comptime {
@export(__floattidf, .{ .name = "__floattidf", .linkage = common.linkage });
const floattidf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __floattidf_windows_x86_64;
} else __floattidf;

@export(floattidf_fn, .{ .name = "__floattidf", .linkage = common.linkage });
}

pub fn __floattidf(a: i128) callconv(.C) f64 {
return intToFloat(f64, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __floattidf_windows_x86_64(a: v128) callconv(.C) f64 {
return intToFloat(f64, @bitCast(i128, a));
}
18 changes: 16 additions & 2 deletions lib/compiler_rt/floattihf.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const intToFloat = @import("./int_to_float.zig").intToFloat;

pub const panic = common.panic;

comptime {
@export(__floattihf, .{ .name = "__floattihf", .linkage = common.linkage });
const floattihf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __floattihf_windows_x86_64;
} else __floattihf;

@export(floattihf_fn, .{ .name = "__floattihf", .linkage = common.linkage });
}

fn __floattihf(a: i128) callconv(.C) f16 {
pub fn __floattihf(a: i128) callconv(.C) f16 {
return intToFloat(f16, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __floattihf_windows_x86_64(a: v128) callconv(.C) f16 {
return intToFloat(f16, @bitCast(i128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/floattisf.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const intToFloat = @import("./int_to_float.zig").intToFloat;

pub const panic = common.panic;

comptime {
@export(__floattisf, .{ .name = "__floattisf", .linkage = common.linkage });
const floattisf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __floattisf_windows_x86_64;
} else __floattisf;

@export(floattisf_fn, .{ .name = "__floattisf", .linkage = common.linkage });
}

pub fn __floattisf(a: i128) callconv(.C) f32 {
return intToFloat(f32, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __floattisf_windows_x86_64(a: v128) callconv(.C) f32 {
return intToFloat(f32, @bitCast(i128, a));
}
16 changes: 15 additions & 1 deletion lib/compiler_rt/floattitf.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
const builtin = @import("builtin");
const arch = builtin.cpu.arch;
const common = @import("./common.zig");
const intToFloat = @import("./int_to_float.zig").intToFloat;

pub const panic = common.panic;

comptime {
@export(__floattitf, .{ .name = "__floattitf", .linkage = common.linkage });
const floattitf_fn = if (builtin.os.tag == .windows and arch == .x86_64) b: {
// The "ti" functions must use Vector(2, u64) return types to adhere to the ABI
// that LLVM expects compiler-rt to have.
break :b __floattitf_windows_x86_64;
} else __floattitf;

@export(floattitf_fn, .{ .name = "__floattitf", .linkage = common.linkage });
}

pub fn __floattitf(a: i128) callconv(.C) f128 {
return intToFloat(f128, a);
}

const v128 = @import("std").meta.Vector(2, u64);

fn __floattitf_windows_x86_64(a: v128) callconv(.C) f128 {
return intToFloat(f128, @bitCast(i128, a));
}
Loading

0 comments on commit c8d2f5f

Please sign in to comment.