all: migrate code to new cast builtin syntax

Most of this migration was performed automatically with `zig fmt`. There
were a few exceptions which I had to manually fix:

* `@alignCast` and `@addrSpaceCast` cannot be automatically rewritten
* `@truncate`'s fixup is incorrect for vectors
* Test cases are not formatted, and their error locations change
This commit is contained in:
mlugg 2023-06-22 18:46:56 +01:00 committed by Andrew Kelley
parent 447ca4e3ff
commit f26dda2117
651 changed files with 8967 additions and 9039 deletions

View File

@ -24,28 +24,28 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
const significandMask = (@as(Z, 1) << significandBits) - 1; const significandMask = (@as(Z, 1) << significandBits) - 1;
const absMask = signBit - 1; const absMask = signBit - 1;
const qnanRep = @bitCast(Z, math.nan(T)) | quietBit; const qnanRep = @as(Z, @bitCast(math.nan(T))) | quietBit;
var aRep = @bitCast(Z, a); var aRep = @as(Z, @bitCast(a));
var bRep = @bitCast(Z, b); var bRep = @as(Z, @bitCast(b));
const aAbs = aRep & absMask; const aAbs = aRep & absMask;
const bAbs = bRep & absMask; const bAbs = bRep & absMask;
const infRep = @bitCast(Z, math.inf(T)); const infRep = @as(Z, @bitCast(math.inf(T)));
// Detect if a or b is zero, infinity, or NaN. // Detect if a or b is zero, infinity, or NaN.
if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or
bAbs -% @as(Z, 1) >= infRep - @as(Z, 1)) bAbs -% @as(Z, 1) >= infRep - @as(Z, 1))
{ {
// NaN + anything = qNaN // NaN + anything = qNaN
if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit); if (aAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(a)) | quietBit));
// anything + NaN = qNaN // anything + NaN = qNaN
if (bAbs > infRep) return @bitCast(T, @bitCast(Z, b) | quietBit); if (bAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(b)) | quietBit));
if (aAbs == infRep) { if (aAbs == infRep) {
// +/-infinity + -/+infinity = qNaN // +/-infinity + -/+infinity = qNaN
if ((@bitCast(Z, a) ^ @bitCast(Z, b)) == signBit) { if ((@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) == signBit) {
return @bitCast(T, qnanRep); return @as(T, @bitCast(qnanRep));
} }
// +/-infinity + anything remaining = +/- infinity // +/-infinity + anything remaining = +/- infinity
else { else {
@ -60,7 +60,7 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
if (aAbs == 0) { if (aAbs == 0) {
// but we need to get the sign right for zero + zero // but we need to get the sign right for zero + zero
if (bAbs == 0) { if (bAbs == 0) {
return @bitCast(T, @bitCast(Z, a) & @bitCast(Z, b)); return @as(T, @bitCast(@as(Z, @bitCast(a)) & @as(Z, @bitCast(b))));
} else { } else {
return b; return b;
} }
@ -78,8 +78,8 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
} }
// Extract the exponent and significand from the (possibly swapped) a and b. // Extract the exponent and significand from the (possibly swapped) a and b.
var aExponent = @intCast(i32, (aRep >> significandBits) & maxExponent); var aExponent = @as(i32, @intCast((aRep >> significandBits) & maxExponent));
var bExponent = @intCast(i32, (bRep >> significandBits) & maxExponent); var bExponent = @as(i32, @intCast((bRep >> significandBits) & maxExponent));
var aSignificand = aRep & significandMask; var aSignificand = aRep & significandMask;
var bSignificand = bRep & significandMask; var bSignificand = bRep & significandMask;
@ -101,11 +101,11 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
// Shift the significand of b by the difference in exponents, with a sticky // Shift the significand of b by the difference in exponents, with a sticky
// bottom bit to get rounding correct. // bottom bit to get rounding correct.
const @"align" = @intCast(u32, aExponent - bExponent); const @"align" = @as(u32, @intCast(aExponent - bExponent));
if (@"align" != 0) { if (@"align" != 0) {
if (@"align" < typeWidth) { if (@"align" < typeWidth) {
const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) @as(Z, 1) else 0; const sticky = if (bSignificand << @as(S, @intCast(typeWidth - @"align")) != 0) @as(Z, 1) else 0;
bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky; bSignificand = (bSignificand >> @as(S, @truncate(@"align"))) | sticky;
} else { } else {
bSignificand = 1; // sticky; b is known to be non-zero. bSignificand = 1; // sticky; b is known to be non-zero.
} }
@ -113,13 +113,13 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
if (subtraction) { if (subtraction) {
aSignificand -= bSignificand; aSignificand -= bSignificand;
// If a == -b, return +zero. // If a == -b, return +zero.
if (aSignificand == 0) return @bitCast(T, @as(Z, 0)); if (aSignificand == 0) return @as(T, @bitCast(@as(Z, 0)));
// If partial cancellation occured, we need to left-shift the result // If partial cancellation occured, we need to left-shift the result
// and adjust the exponent: // and adjust the exponent:
if (aSignificand < integerBit << 3) { if (aSignificand < integerBit << 3) {
const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(integerBit << 3)); const shift = @as(i32, @intCast(@clz(aSignificand))) - @as(i32, @intCast(@clz(integerBit << 3)));
aSignificand <<= @intCast(S, shift); aSignificand <<= @as(S, @intCast(shift));
aExponent -= shift; aExponent -= shift;
} }
} else { // addition } else { // addition
@ -135,13 +135,13 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
} }
// If we have overflowed the type, return +/- infinity: // If we have overflowed the type, return +/- infinity:
if (aExponent >= maxExponent) return @bitCast(T, infRep | resultSign); if (aExponent >= maxExponent) return @as(T, @bitCast(infRep | resultSign));
if (aExponent <= 0) { if (aExponent <= 0) {
// Result is denormal; the exponent and round/sticky bits are zero. // Result is denormal; the exponent and round/sticky bits are zero.
// All we need to do is shift the significand and apply the correct sign. // All we need to do is shift the significand and apply the correct sign.
aSignificand >>= @intCast(S, 4 - aExponent); aSignificand >>= @as(S, @intCast(4 - aExponent));
return @bitCast(T, resultSign | aSignificand); return @as(T, @bitCast(resultSign | aSignificand));
} }
// Low three bits are round, guard, and sticky. // Low three bits are round, guard, and sticky.
@ -151,7 +151,7 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
var result = (aSignificand >> 3) & significandMask; var result = (aSignificand >> 3) & significandMask;
// Insert the exponent and sign. // Insert the exponent and sign.
result |= @intCast(Z, aExponent) << significandBits; result |= @as(Z, @intCast(aExponent)) << significandBits;
result |= resultSign; result |= resultSign;
// Final rounding. The result may overflow to infinity, but that is the // Final rounding. The result may overflow to infinity, but that is the
@ -164,7 +164,7 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
if ((result >> significandBits) != 0) result |= integerBit; if ((result >> significandBits) != 0) result |= integerBit;
} }
return @bitCast(T, result); return @as(T, @bitCast(result));
} }
test { test {

View File

@ -5,7 +5,7 @@
const std = @import("std"); const std = @import("std");
const math = std.math; const math = std.math;
const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64); const qnan128 = @as(f128, @bitCast(@as(u128, 0x7fff800000000000) << 64));
const __addtf3 = @import("addtf3.zig").__addtf3; const __addtf3 = @import("addtf3.zig").__addtf3;
const __addxf3 = @import("addxf3.zig").__addxf3; const __addxf3 = @import("addxf3.zig").__addxf3;
@ -14,9 +14,9 @@ const __subtf3 = @import("subtf3.zig").__subtf3;
fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
const x = __addtf3(a, b); const x = __addtf3(a, b);
const rep = @bitCast(u128, x); const rep = @as(u128, @bitCast(x));
const hi = @intCast(u64, rep >> 64); const hi = @as(u64, @intCast(rep >> 64));
const lo = @truncate(u64, rep); const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo) { if (hi == expected_hi and lo == expected_lo) {
return; return;
@ -37,7 +37,7 @@ test "addtf3" {
try test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); try test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// NaN + any = NaN // NaN + any = NaN
try test__addtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); try test__addtf3(@as(f128, @bitCast((@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000))), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// inf + inf = inf // inf + inf = inf
try test__addtf3(math.inf(f128), math.inf(f128), 0x7fff000000000000, 0x0); try test__addtf3(math.inf(f128), math.inf(f128), 0x7fff000000000000, 0x0);
@ -53,9 +53,9 @@ test "addtf3" {
fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void { fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
const x = __subtf3(a, b); const x = __subtf3(a, b);
const rep = @bitCast(u128, x); const rep = @as(u128, @bitCast(x));
const hi = @intCast(u64, rep >> 64); const hi = @as(u64, @intCast(rep >> 64));
const lo = @truncate(u64, rep); const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo) { if (hi == expected_hi and lo == expected_lo) {
return; return;
@ -77,7 +77,7 @@ test "subtf3" {
try test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); try test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// NaN + any = NaN // NaN + any = NaN
try test__subtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0); try test__subtf3(@as(f128, @bitCast((@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000))), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// inf - any = inf // inf - any = inf
try test__subtf3(math.inf(f128), 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0); try test__subtf3(math.inf(f128), 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
@ -87,16 +87,16 @@ test "subtf3" {
try test__subtf3(0x1.ee9d7c52354a6936ab8d7654321fp-1, 0x1.234567829a3bcdef5678ade36734p+5, 0xc0041b8af1915166, 0xa44a7bca780a166c); try test__subtf3(0x1.ee9d7c52354a6936ab8d7654321fp-1, 0x1.234567829a3bcdef5678ade36734p+5, 0xc0041b8af1915166, 0xa44a7bca780a166c);
} }
const qnan80 = @bitCast(f80, @bitCast(u80, math.nan(f80)) | (1 << (math.floatFractionalBits(f80) - 1))); const qnan80 = @as(f80, @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))));
fn test__addxf3(a: f80, b: f80, expected: u80) !void { fn test__addxf3(a: f80, b: f80, expected: u80) !void {
const x = __addxf3(a, b); const x = __addxf3(a, b);
const rep = @bitCast(u80, x); const rep = @as(u80, @bitCast(x));
if (rep == expected) if (rep == expected)
return; return;
if (math.isNan(@bitCast(f80, expected)) and math.isNan(x)) if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x))
return; // We don't currently test NaN payload propagation return; // We don't currently test NaN payload propagation
return error.TestFailed; return error.TestFailed;
@ -104,33 +104,33 @@ fn test__addxf3(a: f80, b: f80, expected: u80) !void {
test "addxf3" { test "addxf3" {
// NaN + any = NaN // NaN + any = NaN
try test__addxf3(qnan80, 0x1.23456789abcdefp+5, @bitCast(u80, qnan80)); try test__addxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
try test__addxf3(@bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), 0x1.23456789abcdefp+5, @bitCast(u80, qnan80)); try test__addxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
// any + NaN = NaN // any + NaN = NaN
try test__addxf3(0x1.23456789abcdefp+5, qnan80, @bitCast(u80, qnan80)); try test__addxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));
try test__addxf3(0x1.23456789abcdefp+5, @bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), @bitCast(u80, qnan80)); try test__addxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
// NaN + inf = NaN // NaN + inf = NaN
try test__addxf3(qnan80, math.inf(f80), @bitCast(u80, qnan80)); try test__addxf3(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80)));
// inf + NaN = NaN // inf + NaN = NaN
try test__addxf3(math.inf(f80), qnan80, @bitCast(u80, qnan80)); try test__addxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80)));
// inf + inf = inf // inf + inf = inf
try test__addxf3(math.inf(f80), math.inf(f80), @bitCast(u80, math.inf(f80))); try test__addxf3(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
// inf + -inf = NaN // inf + -inf = NaN
try test__addxf3(math.inf(f80), -math.inf(f80), @bitCast(u80, qnan80)); try test__addxf3(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(qnan80)));
// -inf + inf = NaN // -inf + inf = NaN
try test__addxf3(-math.inf(f80), math.inf(f80), @bitCast(u80, qnan80)); try test__addxf3(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(qnan80)));
// inf + any = inf // inf + any = inf
try test__addxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @bitCast(u80, math.inf(f80))); try test__addxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80))));
// any + inf = inf // any + inf = inf
try test__addxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @bitCast(u80, math.inf(f80))); try test__addxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
// any + any // any + any
try test__addxf3(0x1.23456789abcdp+5, 0x1.dcba987654321p+5, 0x4005_BFFFFFFFFFFFC400); try test__addxf3(0x1.23456789abcdp+5, 0x1.dcba987654321p+5, 0x4005_BFFFFFFFFFFFC400);

View File

@ -192,6 +192,6 @@ pub fn __aeabi_ldivmod() callconv(.Naked) void {
} }
pub fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 { pub fn __aeabi_drsub(a: f64, b: f64) callconv(.AAPCS) f64 {
const neg_a = @bitCast(f64, @bitCast(u64, a) ^ (@as(u64, 1) << 63)); const neg_a = @as(f64, @bitCast(@as(u64, @bitCast(a)) ^ (@as(u64, 1) << 63)));
return b + neg_a; return b + neg_a;
} }

View File

@ -232,16 +232,16 @@ fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T {
const addr = @intFromPtr(ptr); const addr = @intFromPtr(ptr);
const wide_addr = addr & ~(@as(T, smallest_atomic_fetch_exch_size) - 1); const wide_addr = addr & ~(@as(T, smallest_atomic_fetch_exch_size) - 1);
const wide_ptr = @alignCast(smallest_atomic_fetch_exch_size, @ptrFromInt(*WideAtomic, wide_addr)); const wide_ptr: *align(smallest_atomic_fetch_exch_size) WideAtomic = @alignCast(@as(*WideAtomic, @ptrFromInt(wide_addr)));
const inner_offset = addr & (@as(T, smallest_atomic_fetch_exch_size) - 1); const inner_offset = addr & (@as(T, smallest_atomic_fetch_exch_size) - 1);
const inner_shift = @intCast(std.math.Log2Int(T), inner_offset * 8); const inner_shift = @as(std.math.Log2Int(T), @intCast(inner_offset * 8));
const mask = @as(WideAtomic, std.math.maxInt(T)) << inner_shift; const mask = @as(WideAtomic, std.math.maxInt(T)) << inner_shift;
var wide_old = @atomicLoad(WideAtomic, wide_ptr, .SeqCst); var wide_old = @atomicLoad(WideAtomic, wide_ptr, .SeqCst);
while (true) { while (true) {
const old = @truncate(T, (wide_old & mask) >> inner_shift); const old = @as(T, @truncate((wide_old & mask) >> inner_shift));
const new = update(val, old); const new = update(val, old);
const wide_new = wide_old & ~mask | (@as(WideAtomic, new) << inner_shift); const wide_new = wide_old & ~mask | (@as(WideAtomic, new) << inner_shift);
if (@cmpxchgWeak(WideAtomic, wide_ptr, wide_old, wide_new, .SeqCst, .SeqCst)) |new_wide_old| { if (@cmpxchgWeak(WideAtomic, wide_ptr, wide_old, wide_new, .SeqCst, .SeqCst)) |new_wide_old| {

View File

@ -21,9 +21,9 @@ pub fn _alldiv(a: i64, b: i64) callconv(.Stdcall) i64 {
const an = (a ^ s_a) -% s_a; const an = (a ^ s_a) -% s_a;
const bn = (b ^ s_b) -% s_b; const bn = (b ^ s_b) -% s_b;
const r = @bitCast(u64, an) / @bitCast(u64, bn); const r = @as(u64, @bitCast(an)) / @as(u64, @bitCast(bn));
const s = s_a ^ s_b; const s = s_a ^ s_b;
return (@bitCast(i64, r) ^ s) -% s; return (@as(i64, @bitCast(r)) ^ s) -% s;
} }
pub fn _aulldiv() callconv(.Naked) void { pub fn _aulldiv() callconv(.Naked) void {

View File

@ -21,9 +21,9 @@ pub fn _allrem(a: i64, b: i64) callconv(.Stdcall) i64 {
const an = (a ^ s_a) -% s_a; const an = (a ^ s_a) -% s_a;
const bn = (b ^ s_b) -% s_b; const bn = (b ^ s_b) -% s_b;
const r = @bitCast(u64, an) % @bitCast(u64, bn); const r = @as(u64, @bitCast(an)) % @as(u64, @bitCast(bn));
const s = s_a ^ s_b; const s = s_a ^ s_b;
return (@bitCast(i64, r) ^ s) -% s; return (@as(i64, @bitCast(r)) ^ s) -% s;
} }
pub fn _aullrem() callconv(.Naked) void { pub fn _aullrem() callconv(.Naked) void {

View File

@ -27,12 +27,12 @@ comptime {
pub fn __ceilh(x: f16) callconv(.C) f16 { pub fn __ceilh(x: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, ceilf(x)); return @as(f16, @floatCast(ceilf(x)));
} }
pub fn ceilf(x: f32) callconv(.C) f32 { pub fn ceilf(x: f32) callconv(.C) f32 {
var u = @bitCast(u32, x); var u = @as(u32, @bitCast(x));
var e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; var e = @as(i32, @intCast((u >> 23) & 0xFF)) - 0x7F;
var m: u32 = undefined; var m: u32 = undefined;
// TODO: Shouldn't need this explicit check. // TODO: Shouldn't need this explicit check.
@ -43,7 +43,7 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
if (e >= 23) { if (e >= 23) {
return x; return x;
} else if (e >= 0) { } else if (e >= 0) {
m = @as(u32, 0x007FFFFF) >> @intCast(u5, e); m = @as(u32, 0x007FFFFF) >> @as(u5, @intCast(e));
if (u & m == 0) { if (u & m == 0) {
return x; return x;
} }
@ -52,7 +52,7 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
u += m; u += m;
} }
u &= ~m; u &= ~m;
return @bitCast(f32, u); return @as(f32, @bitCast(u));
} else { } else {
math.doNotOptimizeAway(x + 0x1.0p120); math.doNotOptimizeAway(x + 0x1.0p120);
if (u >> 31 != 0) { if (u >> 31 != 0) {
@ -66,7 +66,7 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
pub fn ceil(x: f64) callconv(.C) f64 { pub fn ceil(x: f64) callconv(.C) f64 {
const f64_toint = 1.0 / math.floatEps(f64); const f64_toint = 1.0 / math.floatEps(f64);
const u = @bitCast(u64, x); const u = @as(u64, @bitCast(x));
const e = (u >> 52) & 0x7FF; const e = (u >> 52) & 0x7FF;
var y: f64 = undefined; var y: f64 = undefined;
@ -96,13 +96,13 @@ pub fn ceil(x: f64) callconv(.C) f64 {
pub fn __ceilx(x: f80) callconv(.C) f80 { pub fn __ceilx(x: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, ceilq(x)); return @as(f80, @floatCast(ceilq(x)));
} }
pub fn ceilq(x: f128) callconv(.C) f128 { pub fn ceilq(x: f128) callconv(.C) f128 {
const f128_toint = 1.0 / math.floatEps(f128); const f128_toint = 1.0 / math.floatEps(f128);
const u = @bitCast(u128, x); const u = @as(u128, @bitCast(x));
const e = (u >> 112) & 0x7FFF; const e = (u >> 112) & 0x7FFF;
var y: f128 = undefined; var y: f128 = undefined;

View File

@ -102,7 +102,7 @@ fn clear_cache(start: usize, end: usize) callconv(.C) void {
// If CTR_EL0.IDC is set, data cache cleaning to the point of unification // If CTR_EL0.IDC is set, data cache cleaning to the point of unification
// is not required for instruction to data coherence. // is not required for instruction to data coherence.
if (((ctr_el0 >> 28) & 0x1) == 0x0) { if (((ctr_el0 >> 28) & 0x1) == 0x0) {
const dcache_line_size: usize = @as(usize, 4) << @intCast(u6, (ctr_el0 >> 16) & 15); const dcache_line_size: usize = @as(usize, 4) << @as(u6, @intCast((ctr_el0 >> 16) & 15));
addr = start & ~(dcache_line_size - 1); addr = start & ~(dcache_line_size - 1);
while (addr < end) : (addr += dcache_line_size) { while (addr < end) : (addr += dcache_line_size) {
asm volatile ("dc cvau, %[addr]" asm volatile ("dc cvau, %[addr]"
@ -115,7 +115,7 @@ fn clear_cache(start: usize, end: usize) callconv(.C) void {
// If CTR_EL0.DIC is set, instruction cache invalidation to the point of // If CTR_EL0.DIC is set, instruction cache invalidation to the point of
// unification is not required for instruction to data coherence. // unification is not required for instruction to data coherence.
if (((ctr_el0 >> 29) & 0x1) == 0x0) { if (((ctr_el0 >> 29) & 0x1) == 0x0) {
const icache_line_size: usize = @as(usize, 4) << @intCast(u6, (ctr_el0 >> 0) & 15); const icache_line_size: usize = @as(usize, 4) << @as(u6, @intCast((ctr_el0 >> 0) & 15));
addr = start & ~(icache_line_size - 1); addr = start & ~(icache_line_size - 1);
while (addr < end) : (addr += icache_line_size) { while (addr < end) : (addr += icache_line_size) {
asm volatile ("ic ivau, %[addr]" asm volatile ("ic ivau, %[addr]"

View File

@ -2,7 +2,7 @@ const clz = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__clzdi2(a: u64, expected: i64) !void { fn test__clzdi2(a: u64, expected: i64) !void {
var x = @bitCast(i64, a); var x = @as(i64, @bitCast(a));
var result = clz.__clzdi2(x); var result = clz.__clzdi2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -4,8 +4,8 @@ const testing = @import("std").testing;
fn test__clzsi2(a: u32, expected: i32) !void { fn test__clzsi2(a: u32, expected: i32) !void {
const nakedClzsi2 = clz.__clzsi2; const nakedClzsi2 = clz.__clzsi2;
const actualClzsi2 = @ptrCast(*const fn (a: i32) callconv(.C) i32, &nakedClzsi2); const actualClzsi2 = @as(*const fn (a: i32) callconv(.C) i32, @ptrCast(&nakedClzsi2));
const x = @bitCast(i32, a); const x = @as(i32, @bitCast(a));
const result = actualClzsi2(x); const result = actualClzsi2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -2,7 +2,7 @@ const clz = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__clzti2(a: u128, expected: i64) !void { fn test__clzti2(a: u128, expected: i64) !void {
var x = @bitCast(i128, a); var x = @as(i128, @bitCast(a));
var result = clz.__clzti2(x); var result = clz.__clzti2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -75,30 +75,30 @@ fn _Qp_cmp(a: *const f128, b: *const f128) callconv(.C) i32 {
} }
fn _Qp_feq(a: *const f128, b: *const f128) callconv(.C) bool { fn _Qp_feq(a: *const f128, b: *const f128) callconv(.C) bool {
return @enumFromInt(SparcFCMP, _Qp_cmp(a, b)) == .Equal; return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Equal;
} }
fn _Qp_fne(a: *const f128, b: *const f128) callconv(.C) bool { fn _Qp_fne(a: *const f128, b: *const f128) callconv(.C) bool {
return @enumFromInt(SparcFCMP, _Qp_cmp(a, b)) != .Equal; return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) != .Equal;
} }
fn _Qp_flt(a: *const f128, b: *const f128) callconv(.C) bool { fn _Qp_flt(a: *const f128, b: *const f128) callconv(.C) bool {
return @enumFromInt(SparcFCMP, _Qp_cmp(a, b)) == .Less; return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Less;
} }
fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.C) bool { fn _Qp_fgt(a: *const f128, b: *const f128) callconv(.C) bool {
return @enumFromInt(SparcFCMP, _Qp_cmp(a, b)) == .Greater; return @as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b))) == .Greater;
} }
fn _Qp_fge(a: *const f128, b: *const f128) callconv(.C) bool { fn _Qp_fge(a: *const f128, b: *const f128) callconv(.C) bool {
return switch (@enumFromInt(SparcFCMP, _Qp_cmp(a, b))) { return switch (@as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b)))) {
.Equal, .Greater => true, .Equal, .Greater => true,
.Less, .Unordered => false, .Less, .Unordered => false,
}; };
} }
fn _Qp_fle(a: *const f128, b: *const f128) callconv(.C) bool { fn _Qp_fle(a: *const f128, b: *const f128) callconv(.C) bool {
return switch (@enumFromInt(SparcFCMP, _Qp_cmp(a, b))) { return switch (@as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b)))) {
.Equal, .Less => true, .Equal, .Less => true,
.Greater, .Unordered => false, .Greater, .Unordered => false,
}; };

View File

@ -102,22 +102,22 @@ pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
u16 => { u16 => {
// 16x16 --> 32 bit multiply // 16x16 --> 32 bit multiply
const product = @as(u32, a) * @as(u32, b); const product = @as(u32, a) * @as(u32, b);
hi.* = @intCast(u16, product >> 16); hi.* = @as(u16, @intCast(product >> 16));
lo.* = @truncate(u16, product); lo.* = @as(u16, @truncate(product));
}, },
u32 => { u32 => {
// 32x32 --> 64 bit multiply // 32x32 --> 64 bit multiply
const product = @as(u64, a) * @as(u64, b); const product = @as(u64, a) * @as(u64, b);
hi.* = @truncate(u32, product >> 32); hi.* = @as(u32, @truncate(product >> 32));
lo.* = @truncate(u32, product); lo.* = @as(u32, @truncate(product));
}, },
u64 => { u64 => {
const S = struct { const S = struct {
fn loWord(x: u64) u64 { fn loWord(x: u64) u64 {
return @truncate(u32, x); return @as(u32, @truncate(x));
} }
fn hiWord(x: u64) u64 { fn hiWord(x: u64) u64 {
return @truncate(u32, x >> 32); return @as(u32, @truncate(x >> 32));
} }
}; };
// 64x64 -> 128 wide multiply for platforms that don't have such an operation; // 64x64 -> 128 wide multiply for platforms that don't have such an operation;
@ -141,16 +141,16 @@ pub fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
const Word_FullMask = @as(u64, 0xffffffffffffffff); const Word_FullMask = @as(u64, 0xffffffffffffffff);
const S = struct { const S = struct {
fn Word_1(x: u128) u64 { fn Word_1(x: u128) u64 {
return @truncate(u32, x >> 96); return @as(u32, @truncate(x >> 96));
} }
fn Word_2(x: u128) u64 { fn Word_2(x: u128) u64 {
return @truncate(u32, x >> 64); return @as(u32, @truncate(x >> 64));
} }
fn Word_3(x: u128) u64 { fn Word_3(x: u128) u64 {
return @truncate(u32, x >> 32); return @as(u32, @truncate(x >> 32));
} }
fn Word_4(x: u128) u64 { fn Word_4(x: u128) u64 {
return @truncate(u32, x); return @as(u32, @truncate(x));
} }
}; };
// 128x128 -> 256 wide multiply for platforms that don't have such an operation; // 128x128 -> 256 wide multiply for platforms that don't have such an operation;
@ -216,7 +216,7 @@ pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeIn
const integerBit = @as(Z, 1) << std.math.floatFractionalBits(T); const integerBit = @as(Z, 1) << std.math.floatFractionalBits(T);
const shift = @clz(significand.*) - @clz(integerBit); const shift = @clz(significand.*) - @clz(integerBit);
significand.* <<= @intCast(std.math.Log2Int(Z), shift); significand.* <<= @as(std.math.Log2Int(Z), @intCast(shift));
return @as(i32, 1) - shift; return @as(i32, 1) - shift;
} }
@ -228,8 +228,8 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {
.bits = bits, .bits = bits,
} }); } });
const sign_bit_mask = @as(U, 1) << (bits - 1); const sign_bit_mask = @as(U, 1) << (bits - 1);
const negated = @bitCast(U, a) ^ sign_bit_mask; const negated = @as(U, @bitCast(a)) ^ sign_bit_mask;
return @bitCast(F, negated); return @as(F, @bitCast(negated));
} }
/// Allows to access underlying bits as two equally sized lower and higher /// Allows to access underlying bits as two equally sized lower and higher

View File

@ -26,12 +26,12 @@ pub inline fn cmpf2(comptime T: type, comptime RT: type, a: T, b: T) RT {
const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
const absMask = signBit - 1; const absMask = signBit - 1;
const infT = comptime std.math.inf(T); const infT = comptime std.math.inf(T);
const infRep = @bitCast(rep_t, infT); const infRep = @as(rep_t, @bitCast(infT));
const aInt = @bitCast(srep_t, a); const aInt = @as(srep_t, @bitCast(a));
const bInt = @bitCast(srep_t, b); const bInt = @as(srep_t, @bitCast(b));
const aAbs = @bitCast(rep_t, aInt) & absMask; const aAbs = @as(rep_t, @bitCast(aInt)) & absMask;
const bAbs = @bitCast(rep_t, bInt) & absMask; const bAbs = @as(rep_t, @bitCast(bInt)) & absMask;
// If either a or b is NaN, they are unordered. // If either a or b is NaN, they are unordered.
if (aAbs > infRep or bAbs > infRep) return RT.Unordered; if (aAbs > infRep or bAbs > infRep) return RT.Unordered;
@ -81,7 +81,7 @@ pub inline fn cmp_f80(comptime RT: type, a: f80, b: f80) RT {
return .Equal; return .Equal;
} else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) { } else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
// signs are different // signs are different
if (@bitCast(i16, a_rep.exp) < @bitCast(i16, b_rep.exp)) { if (@as(i16, @bitCast(a_rep.exp)) < @as(i16, @bitCast(b_rep.exp))) {
return .Less; return .Less;
} else { } else {
return .Greater; return .Greater;
@ -104,10 +104,10 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
const exponentBits = std.math.floatExponentBits(T); const exponentBits = std.math.floatExponentBits(T);
const signBit = (@as(rep_t, 1) << (significandBits + exponentBits)); const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
const absMask = signBit - 1; const absMask = signBit - 1;
const infRep = @bitCast(rep_t, std.math.inf(T)); const infRep = @as(rep_t, @bitCast(std.math.inf(T)));
const aAbs: rep_t = @bitCast(rep_t, a) & absMask; const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask;
const bAbs: rep_t = @bitCast(rep_t, b) & absMask; const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask;
return @intFromBool(aAbs > infRep or bAbs > infRep); return @intFromBool(aAbs > infRep or bAbs > infRep);
} }

View File

@ -25,7 +25,7 @@ comptime {
pub fn __cosh(a: f16) callconv(.C) f16 { pub fn __cosh(a: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, cosf(a)); return @as(f16, @floatCast(cosf(a)));
} }
pub fn cosf(x: f32) callconv(.C) f32 { pub fn cosf(x: f32) callconv(.C) f32 {
@ -35,7 +35,7 @@ pub fn cosf(x: f32) callconv(.C) f32 {
const c3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2 const c3pio2: f64 = 3.0 * math.pi / 2.0; // 0x4012D97C, 0x7F3321D2
const c4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18 const c4pio2: f64 = 4.0 * math.pi / 2.0; // 0x401921FB, 0x54442D18
var ix = @bitCast(u32, x); var ix = @as(u32, @bitCast(x));
const sign = ix >> 31 != 0; const sign = ix >> 31 != 0;
ix &= 0x7fffffff; ix &= 0x7fffffff;
@ -86,7 +86,7 @@ pub fn cosf(x: f32) callconv(.C) f32 {
} }
pub fn cos(x: f64) callconv(.C) f64 { pub fn cos(x: f64) callconv(.C) f64 {
var ix = @bitCast(u64, x) >> 32; var ix = @as(u64, @bitCast(x)) >> 32;
ix &= 0x7fffffff; ix &= 0x7fffffff;
// |x| ~< pi/4 // |x| ~< pi/4
@ -116,12 +116,12 @@ pub fn cos(x: f64) callconv(.C) f64 {
pub fn __cosx(a: f80) callconv(.C) f80 { pub fn __cosx(a: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, cosq(a)); return @as(f80, @floatCast(cosq(a)));
} }
pub fn cosq(a: f128) callconv(.C) f128 { pub fn cosq(a: f128) callconv(.C) f128 {
// TODO: more correct implementation // TODO: more correct implementation
return cos(@floatCast(f64, a)); return cos(@as(f64, @floatCast(a)));
} }
pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble { pub fn cosl(x: c_longdouble) callconv(.C) c_longdouble {

View File

@ -32,9 +32,9 @@ comptime {
inline fn clzXi2(comptime T: type, a: T) i32 { inline fn clzXi2(comptime T: type, a: T) i32 {
var x = switch (@bitSizeOf(T)) { var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a), 32 => @as(u32, @bitCast(a)),
64 => @bitCast(u64, a), 64 => @as(u64, @bitCast(a)),
128 => @bitCast(u128, a), 128 => @as(u128, @bitCast(a)),
else => unreachable, else => unreachable,
}; };
var n: T = @bitSizeOf(T); var n: T = @bitSizeOf(T);
@ -49,7 +49,7 @@ inline fn clzXi2(comptime T: type, a: T) i32 {
x = y; x = y;
} }
} }
return @intCast(i32, n - @bitCast(T, x)); return @as(i32, @intCast(n - @as(T, @bitCast(x))));
} }
fn __clzsi2_thumb1() callconv(.Naked) void { fn __clzsi2_thumb1() callconv(.Naked) void {
@ -169,9 +169,9 @@ pub fn __clzti2(a: i128) callconv(.C) i32 {
inline fn ctzXi2(comptime T: type, a: T) i32 { inline fn ctzXi2(comptime T: type, a: T) i32 {
var x = switch (@bitSizeOf(T)) { var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a), 32 => @as(u32, @bitCast(a)),
64 => @bitCast(u64, a), 64 => @as(u64, @bitCast(a)),
128 => @bitCast(u128, a), 128 => @as(u128, @bitCast(a)),
else => unreachable, else => unreachable,
}; };
var n: T = 1; var n: T = 1;
@ -187,7 +187,7 @@ inline fn ctzXi2(comptime T: type, a: T) i32 {
x = x >> shift; x = x >> shift;
} }
} }
return @intCast(i32, n - @bitCast(T, (x & 1))); return @as(i32, @intCast(n - @as(T, @bitCast((x & 1)))));
} }
pub fn __ctzsi2(a: i32) callconv(.C) i32 { pub fn __ctzsi2(a: i32) callconv(.C) i32 {
@ -204,9 +204,9 @@ pub fn __ctzti2(a: i128) callconv(.C) i32 {
inline fn ffsXi2(comptime T: type, a: T) i32 { inline fn ffsXi2(comptime T: type, a: T) i32 {
var x = switch (@bitSizeOf(T)) { var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a), 32 => @as(u32, @bitCast(a)),
64 => @bitCast(u64, a), 64 => @as(u64, @bitCast(a)),
128 => @bitCast(u128, a), 128 => @as(u128, @bitCast(a)),
else => unreachable, else => unreachable,
}; };
var n: T = 1; var n: T = 1;
@ -224,7 +224,7 @@ inline fn ffsXi2(comptime T: type, a: T) i32 {
} }
} }
// return ctz + 1 // return ctz + 1
return @intCast(i32, n - @bitCast(T, (x & 1))) + @as(i32, 1); return @as(i32, @intCast(n - @as(T, @bitCast((x & 1))))) + @as(i32, 1);
} }
pub fn __ffssi2(a: i32) callconv(.C) i32 { pub fn __ffssi2(a: i32) callconv(.C) i32 {

View File

@ -2,7 +2,7 @@ const ctz = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__ctzdi2(a: u64, expected: i32) !void { fn test__ctzdi2(a: u64, expected: i32) !void {
var x = @bitCast(i64, a); var x = @as(i64, @bitCast(a));
var result = ctz.__ctzdi2(x); var result = ctz.__ctzdi2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -2,7 +2,7 @@ const ctz = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__ctzsi2(a: u32, expected: i32) !void { fn test__ctzsi2(a: u32, expected: i32) !void {
var x = @bitCast(i32, a); var x = @as(i32, @bitCast(a));
var result = ctz.__ctzsi2(x); var result = ctz.__ctzsi2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -2,7 +2,7 @@ const ctz = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__ctzti2(a: u128, expected: i32) !void { fn test__ctzti2(a: u128, expected: i32) !void {
var x = @bitCast(i128, a); var x = @as(i128, @bitCast(a));
var result = ctz.__ctzti2(x); var result = ctz.__ctzti2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -47,52 +47,52 @@ inline fn div(a: f64, b: f64) f64 {
const absMask = signBit - 1; const absMask = signBit - 1;
const exponentMask = absMask ^ significandMask; const exponentMask = absMask ^ significandMask;
const qnanRep = exponentMask | quietBit; const qnanRep = exponentMask | quietBit;
const infRep = @bitCast(Z, std.math.inf(f64)); const infRep = @as(Z, @bitCast(std.math.inf(f64)));
const aExponent = @truncate(u32, (@bitCast(Z, a) >> significandBits) & maxExponent); const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent); const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit; const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask; var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask; var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0; var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN. // Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask; const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask; const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// NaN / anything = qNaN // NaN / anything = qNaN
if (aAbs > infRep) return @bitCast(f64, @bitCast(Z, a) | quietBit); if (aAbs > infRep) return @as(f64, @bitCast(@as(Z, @bitCast(a)) | quietBit));
// anything / NaN = qNaN // anything / NaN = qNaN
if (bAbs > infRep) return @bitCast(f64, @bitCast(Z, b) | quietBit); if (bAbs > infRep) return @as(f64, @bitCast(@as(Z, @bitCast(b)) | quietBit));
if (aAbs == infRep) { if (aAbs == infRep) {
// infinity / infinity = NaN // infinity / infinity = NaN
if (bAbs == infRep) { if (bAbs == infRep) {
return @bitCast(f64, qnanRep); return @as(f64, @bitCast(qnanRep));
} }
// infinity / anything else = +/- infinity // infinity / anything else = +/- infinity
else { else {
return @bitCast(f64, aAbs | quotientSign); return @as(f64, @bitCast(aAbs | quotientSign));
} }
} }
// anything else / infinity = +/- 0 // anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(f64, quotientSign); if (bAbs == infRep) return @as(f64, @bitCast(quotientSign));
if (aAbs == 0) { if (aAbs == 0) {
// zero / zero = NaN // zero / zero = NaN
if (bAbs == 0) { if (bAbs == 0) {
return @bitCast(f64, qnanRep); return @as(f64, @bitCast(qnanRep));
} }
// zero / anything else = +/- zero // zero / anything else = +/- zero
else { else {
return @bitCast(f64, quotientSign); return @as(f64, @bitCast(quotientSign));
} }
} }
// anything else / zero = +/- infinity // anything else / zero = +/- infinity
if (bAbs == 0) return @bitCast(f64, infRep | quotientSign); if (bAbs == 0) return @as(f64, @bitCast(infRep | quotientSign));
// one or both of a or b is denormal, the other (if applicable) is a // one or both of a or b is denormal, the other (if applicable) is a
// normal number. Renormalize one or both of a and b, and set scale to // normal number. Renormalize one or both of a and b, and set scale to
@ -106,13 +106,13 @@ inline fn div(a: f64, b: f64) f64 {
// won't hurt anything.) // won't hurt anything.)
aSignificand |= implicitBit; aSignificand |= implicitBit;
bSignificand |= implicitBit; bSignificand |= implicitBit;
var quotientExponent: i32 = @bitCast(i32, aExponent -% bExponent) +% scale; var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale;
// Align the significand of b as a Q31 fixed-point number in the range // Align the significand of b as a Q31 fixed-point number in the range
// [1, 2.0) and get a Q32 approximate reciprocal using a small minimax // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// is accurate to about 3.5 binary digits. // is accurate to about 3.5 binary digits.
const q31b: u32 = @truncate(u32, bSignificand >> 21); const q31b: u32 = @as(u32, @truncate(bSignificand >> 21));
var recip32 = @as(u32, 0x7504f333) -% q31b; var recip32 = @as(u32, 0x7504f333) -% q31b;
// Now refine the reciprocal estimate using a Newton-Raphson iteration: // Now refine the reciprocal estimate using a Newton-Raphson iteration:
@ -123,12 +123,12 @@ inline fn div(a: f64, b: f64) f64 {
// with each iteration, so after three iterations, we have about 28 binary // with each iteration, so after three iterations, we have about 28 binary
// digits of accuracy. // digits of accuracy.
var correction32: u32 = undefined; var correction32: u32 = undefined;
correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1); correction32 = @as(u32, @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1));
recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31); recip32 = @as(u32, @truncate(@as(u64, recip32) *% correction32 >> 31));
correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1); correction32 = @as(u32, @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1));
recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31); recip32 = @as(u32, @truncate(@as(u64, recip32) *% correction32 >> 31));
correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1); correction32 = @as(u32, @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1));
recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31); recip32 = @as(u32, @truncate(@as(u64, recip32) *% correction32 >> 31));
// recip32 might have overflowed to exactly zero in the preceding // recip32 might have overflowed to exactly zero in the preceding
// computation if the high word of b is exactly 1.0. This would sabotage // computation if the high word of b is exactly 1.0. This would sabotage
@ -138,12 +138,12 @@ inline fn div(a: f64, b: f64) f64 {
// We need to perform one more iteration to get us to 56 binary digits; // We need to perform one more iteration to get us to 56 binary digits;
// The last iteration needs to happen with extra precision. // The last iteration needs to happen with extra precision.
const q63blo: u32 = @truncate(u32, bSignificand << 11); const q63blo: u32 = @as(u32, @truncate(bSignificand << 11));
var correction: u64 = undefined; var correction: u64 = undefined;
var reciprocal: u64 = undefined; var reciprocal: u64 = undefined;
correction = ~(@as(u64, recip32) *% q31b +% (@as(u64, recip32) *% q63blo >> 32)) +% 1; correction = ~(@as(u64, recip32) *% q31b +% (@as(u64, recip32) *% q63blo >> 32)) +% 1;
const cHi = @truncate(u32, correction >> 32); const cHi = @as(u32, @truncate(correction >> 32));
const cLo = @truncate(u32, correction); const cLo = @as(u32, @truncate(correction));
reciprocal = @as(u64, recip32) *% cHi +% (@as(u64, recip32) *% cLo >> 32); reciprocal = @as(u64, recip32) *% cHi +% (@as(u64, recip32) *% cLo >> 32);
// We already adjusted the 32-bit estimate, now we need to adjust the final // We already adjusted the 32-bit estimate, now we need to adjust the final
@ -195,7 +195,7 @@ inline fn div(a: f64, b: f64) f64 {
if (writtenExponent >= maxExponent) { if (writtenExponent >= maxExponent) {
// If we have overflowed the exponent, return infinity. // If we have overflowed the exponent, return infinity.
return @bitCast(f64, infRep | quotientSign); return @as(f64, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) { } else if (writtenExponent < 1) {
if (writtenExponent == 0) { if (writtenExponent == 0) {
// Check whether the rounded result is normal. // Check whether the rounded result is normal.
@ -206,22 +206,22 @@ inline fn div(a: f64, b: f64) f64 {
absResult += round; absResult += round;
if ((absResult & ~significandMask) != 0) { if ((absResult & ~significandMask) != 0) {
// The rounded result is normal; return it. // The rounded result is normal; return it.
return @bitCast(f64, absResult | quotientSign); return @as(f64, @bitCast(absResult | quotientSign));
} }
} }
// Flush denormals to zero. In the future, it would be nice to add // Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly. // code to round them correctly.
return @bitCast(f64, quotientSign); return @as(f64, @bitCast(quotientSign));
} else { } else {
const round = @intFromBool((residual << 1) > bSignificand); const round = @intFromBool((residual << 1) > bSignificand);
// Clear the implicit bit // Clear the implicit bit
var absResult = quotient & significandMask; var absResult = quotient & significandMask;
// Insert the exponent // Insert the exponent
absResult |= @bitCast(Z, @as(SignedZ, writtenExponent)) << significandBits; absResult |= @as(Z, @bitCast(@as(SignedZ, writtenExponent))) << significandBits;
// Round // Round
absResult +%= round; absResult +%= round;
// Insert the sign and return // Insert the sign and return
return @bitCast(f64, absResult | quotientSign); return @as(f64, @bitCast(absResult | quotientSign));
} }
} }

View File

@ -6,7 +6,7 @@ const __divdf3 = @import("divdf3.zig").__divdf3;
const testing = @import("std").testing; const testing = @import("std").testing;
fn compareResultD(result: f64, expected: u64) bool { fn compareResultD(result: f64, expected: u64) bool {
const rep = @bitCast(u64, result); const rep = @as(u64, @bitCast(result));
if (rep == expected) { if (rep == expected) {
return true; return true;

View File

@ -7,5 +7,5 @@ comptime {
pub fn __divhf3(a: f16, b: f16) callconv(.C) f16 { pub fn __divhf3(a: f16, b: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, divsf3.__divsf3(a, b)); return @as(f16, @floatCast(divsf3.__divsf3(a, b)));
} }

View File

@ -44,52 +44,52 @@ inline fn div(a: f32, b: f32) f32 {
const absMask = signBit - 1; const absMask = signBit - 1;
const exponentMask = absMask ^ significandMask; const exponentMask = absMask ^ significandMask;
const qnanRep = exponentMask | quietBit; const qnanRep = exponentMask | quietBit;
const infRep = @bitCast(Z, std.math.inf(f32)); const infRep = @as(Z, @bitCast(std.math.inf(f32)));
const aExponent = @truncate(u32, (@bitCast(Z, a) >> significandBits) & maxExponent); const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent); const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit; const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask; var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask; var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0; var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN. // Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask; const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask; const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// NaN / anything = qNaN // NaN / anything = qNaN
if (aAbs > infRep) return @bitCast(f32, @bitCast(Z, a) | quietBit); if (aAbs > infRep) return @as(f32, @bitCast(@as(Z, @bitCast(a)) | quietBit));
// anything / NaN = qNaN // anything / NaN = qNaN
if (bAbs > infRep) return @bitCast(f32, @bitCast(Z, b) | quietBit); if (bAbs > infRep) return @as(f32, @bitCast(@as(Z, @bitCast(b)) | quietBit));
if (aAbs == infRep) { if (aAbs == infRep) {
// infinity / infinity = NaN // infinity / infinity = NaN
if (bAbs == infRep) { if (bAbs == infRep) {
return @bitCast(f32, qnanRep); return @as(f32, @bitCast(qnanRep));
} }
// infinity / anything else = +/- infinity // infinity / anything else = +/- infinity
else { else {
return @bitCast(f32, aAbs | quotientSign); return @as(f32, @bitCast(aAbs | quotientSign));
} }
} }
// anything else / infinity = +/- 0 // anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(f32, quotientSign); if (bAbs == infRep) return @as(f32, @bitCast(quotientSign));
if (aAbs == 0) { if (aAbs == 0) {
// zero / zero = NaN // zero / zero = NaN
if (bAbs == 0) { if (bAbs == 0) {
return @bitCast(f32, qnanRep); return @as(f32, @bitCast(qnanRep));
} }
// zero / anything else = +/- zero // zero / anything else = +/- zero
else { else {
return @bitCast(f32, quotientSign); return @as(f32, @bitCast(quotientSign));
} }
} }
// anything else / zero = +/- infinity // anything else / zero = +/- infinity
if (bAbs == 0) return @bitCast(f32, infRep | quotientSign); if (bAbs == 0) return @as(f32, @bitCast(infRep | quotientSign));
// one or both of a or b is denormal, the other (if applicable) is a // one or both of a or b is denormal, the other (if applicable) is a
// normal number. Renormalize one or both of a and b, and set scale to // normal number. Renormalize one or both of a and b, and set scale to
@ -103,7 +103,7 @@ inline fn div(a: f32, b: f32) f32 {
// won't hurt anything.) // won't hurt anything.)
aSignificand |= implicitBit; aSignificand |= implicitBit;
bSignificand |= implicitBit; bSignificand |= implicitBit;
var quotientExponent: i32 = @bitCast(i32, aExponent -% bExponent) +% scale; var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale;
// Align the significand of b as a Q31 fixed-point number in the range // Align the significand of b as a Q31 fixed-point number in the range
// [1, 2.0) and get a Q32 approximate reciprocal using a small minimax // [1, 2.0) and get a Q32 approximate reciprocal using a small minimax
@ -120,12 +120,12 @@ inline fn div(a: f32, b: f32) f32 {
// with each iteration, so after three iterations, we have about 28 binary // with each iteration, so after three iterations, we have about 28 binary
// digits of accuracy. // digits of accuracy.
var correction: u32 = undefined; var correction: u32 = undefined;
correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1); correction = @as(u32, @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1));
reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31); reciprocal = @as(u32, @truncate(@as(u64, reciprocal) *% correction >> 31));
correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1); correction = @as(u32, @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1));
reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31); reciprocal = @as(u32, @truncate(@as(u64, reciprocal) *% correction >> 31));
correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1); correction = @as(u32, @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1));
reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31); reciprocal = @as(u32, @truncate(@as(u64, reciprocal) *% correction >> 31));
// Exhaustive testing shows that the error in reciprocal after three steps // Exhaustive testing shows that the error in reciprocal after three steps
// is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our
@ -147,7 +147,7 @@ inline fn div(a: f32, b: f32) f32 {
// is the error in the reciprocal of b scaled by the maximum // is the error in the reciprocal of b scaled by the maximum
// possible value of a. As a consequence of this error bound, // possible value of a. As a consequence of this error bound,
// either q or nextafter(q) is the correctly rounded // either q or nextafter(q) is the correctly rounded
var quotient: Z = @truncate(u32, @as(u64, reciprocal) *% (aSignificand << 1) >> 32); var quotient: Z = @as(u32, @truncate(@as(u64, reciprocal) *% (aSignificand << 1) >> 32));
// Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0). // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
// In either case, we are going to compute a residual of the form // In either case, we are going to compute a residual of the form
@ -175,7 +175,7 @@ inline fn div(a: f32, b: f32) f32 {
if (writtenExponent >= maxExponent) { if (writtenExponent >= maxExponent) {
// If we have overflowed the exponent, return infinity. // If we have overflowed the exponent, return infinity.
return @bitCast(f32, infRep | quotientSign); return @as(f32, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) { } else if (writtenExponent < 1) {
if (writtenExponent == 0) { if (writtenExponent == 0) {
// Check whether the rounded result is normal. // Check whether the rounded result is normal.
@ -186,22 +186,22 @@ inline fn div(a: f32, b: f32) f32 {
absResult += round; absResult += round;
if ((absResult & ~significandMask) > 0) { if ((absResult & ~significandMask) > 0) {
// The rounded result is normal; return it. // The rounded result is normal; return it.
return @bitCast(f32, absResult | quotientSign); return @as(f32, @bitCast(absResult | quotientSign));
} }
} }
// Flush denormals to zero. In the future, it would be nice to add // Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly. // code to round them correctly.
return @bitCast(f32, quotientSign); return @as(f32, @bitCast(quotientSign));
} else { } else {
const round = @intFromBool((residual << 1) > bSignificand); const round = @intFromBool((residual << 1) > bSignificand);
// Clear the implicit bit // Clear the implicit bit
var absResult = quotient & significandMask; var absResult = quotient & significandMask;
// Insert the exponent // Insert the exponent
absResult |= @bitCast(Z, writtenExponent) << significandBits; absResult |= @as(Z, @bitCast(writtenExponent)) << significandBits;
// Round // Round
absResult +%= round; absResult +%= round;
// Insert the sign and return // Insert the sign and return
return @bitCast(f32, absResult | quotientSign); return @as(f32, @bitCast(absResult | quotientSign));
} }
} }

View File

@ -6,7 +6,7 @@ const __divsf3 = @import("divsf3.zig").__divsf3;
const testing = @import("std").testing; const testing = @import("std").testing;
fn compareResultF(result: f32, expected: u32) bool { fn compareResultF(result: f32, expected: u32) bool {
const rep = @bitCast(u32, result); const rep = @as(u32, @bitCast(result));
if (rep == expected) { if (rep == expected) {
return true; return true;

View File

@ -41,52 +41,52 @@ inline fn div(a: f128, b: f128) f128 {
const absMask = signBit - 1; const absMask = signBit - 1;
const exponentMask = absMask ^ significandMask; const exponentMask = absMask ^ significandMask;
const qnanRep = exponentMask | quietBit; const qnanRep = exponentMask | quietBit;
const infRep = @bitCast(Z, std.math.inf(f128)); const infRep = @as(Z, @bitCast(std.math.inf(f128)));
const aExponent = @truncate(u32, (@bitCast(Z, a) >> significandBits) & maxExponent); const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent); const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit; const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask; var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask; var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0; var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN. // Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask; const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask; const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// NaN / anything = qNaN // NaN / anything = qNaN
if (aAbs > infRep) return @bitCast(f128, @bitCast(Z, a) | quietBit); if (aAbs > infRep) return @as(f128, @bitCast(@as(Z, @bitCast(a)) | quietBit));
// anything / NaN = qNaN // anything / NaN = qNaN
if (bAbs > infRep) return @bitCast(f128, @bitCast(Z, b) | quietBit); if (bAbs > infRep) return @as(f128, @bitCast(@as(Z, @bitCast(b)) | quietBit));
if (aAbs == infRep) { if (aAbs == infRep) {
// infinity / infinity = NaN // infinity / infinity = NaN
if (bAbs == infRep) { if (bAbs == infRep) {
return @bitCast(f128, qnanRep); return @as(f128, @bitCast(qnanRep));
} }
// infinity / anything else = +/- infinity // infinity / anything else = +/- infinity
else { else {
return @bitCast(f128, aAbs | quotientSign); return @as(f128, @bitCast(aAbs | quotientSign));
} }
} }
// anything else / infinity = +/- 0 // anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(f128, quotientSign); if (bAbs == infRep) return @as(f128, @bitCast(quotientSign));
if (aAbs == 0) { if (aAbs == 0) {
// zero / zero = NaN // zero / zero = NaN
if (bAbs == 0) { if (bAbs == 0) {
return @bitCast(f128, qnanRep); return @as(f128, @bitCast(qnanRep));
} }
// zero / anything else = +/- zero // zero / anything else = +/- zero
else { else {
return @bitCast(f128, quotientSign); return @as(f128, @bitCast(quotientSign));
} }
} }
// anything else / zero = +/- infinity // anything else / zero = +/- infinity
if (bAbs == 0) return @bitCast(f128, infRep | quotientSign); if (bAbs == 0) return @as(f128, @bitCast(infRep | quotientSign));
// one or both of a or b is denormal, the other (if applicable) is a // one or both of a or b is denormal, the other (if applicable) is a
// normal number. Renormalize one or both of a and b, and set scale to // normal number. Renormalize one or both of a and b, and set scale to
@ -100,13 +100,13 @@ inline fn div(a: f128, b: f128) f128 {
// won't hurt anything. // won't hurt anything.
aSignificand |= implicitBit; aSignificand |= implicitBit;
bSignificand |= implicitBit; bSignificand |= implicitBit;
var quotientExponent: i32 = @bitCast(i32, aExponent -% bExponent) +% scale; var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale;
// Align the significand of b as a Q63 fixed-point number in the range // Align the significand of b as a Q63 fixed-point number in the range
// [1, 2.0) and get a Q64 approximate reciprocal using a small minimax // [1, 2.0) and get a Q64 approximate reciprocal using a small minimax
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// is accurate to about 3.5 binary digits. // is accurate to about 3.5 binary digits.
const q63b = @truncate(u64, bSignificand >> 49); const q63b = @as(u64, @truncate(bSignificand >> 49));
var recip64 = @as(u64, 0x7504f333F9DE6484) -% q63b; var recip64 = @as(u64, 0x7504f333F9DE6484) -% q63b;
// 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2) // 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2)
@ -117,16 +117,16 @@ inline fn div(a: f128, b: f128) f128 {
// This doubles the number of correct binary digits in the approximation // This doubles the number of correct binary digits in the approximation
// with each iteration. // with each iteration.
var correction64: u64 = undefined; var correction64: u64 = undefined;
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
// The reciprocal may have overflowed to zero if the upper half of b is // The reciprocal may have overflowed to zero if the upper half of b is
// exactly 1.0. This would sabatoge the full-width final stage of the // exactly 1.0. This would sabatoge the full-width final stage of the
@ -135,7 +135,7 @@ inline fn div(a: f128, b: f128) f128 {
// We need to perform one more iteration to get us to 112 binary digits; // We need to perform one more iteration to get us to 112 binary digits;
// The last iteration needs to happen with extra precision. // The last iteration needs to happen with extra precision.
const q127blo: u64 = @truncate(u64, bSignificand << 15); const q127blo: u64 = @as(u64, @truncate(bSignificand << 15));
var correction: u128 = undefined; var correction: u128 = undefined;
var reciprocal: u128 = undefined; var reciprocal: u128 = undefined;
@ -151,8 +151,8 @@ inline fn div(a: f128, b: f128) f128 {
correction = -%(r64q63 + (r64q127 >> 64)); correction = -%(r64q63 + (r64q127 >> 64));
const cHi = @truncate(u64, correction >> 64); const cHi = @as(u64, @truncate(correction >> 64));
const cLo = @truncate(u64, correction); const cLo = @as(u64, @truncate(correction));
wideMultiply(u128, recip64, cHi, &dummy, &r64cH); wideMultiply(u128, recip64, cHi, &dummy, &r64cH);
wideMultiply(u128, recip64, cLo, &dummy, &r64cL); wideMultiply(u128, recip64, cLo, &dummy, &r64cL);
@ -210,7 +210,7 @@ inline fn div(a: f128, b: f128) f128 {
if (writtenExponent >= maxExponent) { if (writtenExponent >= maxExponent) {
// If we have overflowed the exponent, return infinity. // If we have overflowed the exponent, return infinity.
return @bitCast(f128, infRep | quotientSign); return @as(f128, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) { } else if (writtenExponent < 1) {
if (writtenExponent == 0) { if (writtenExponent == 0) {
// Check whether the rounded result is normal. // Check whether the rounded result is normal.
@ -221,22 +221,22 @@ inline fn div(a: f128, b: f128) f128 {
absResult += round; absResult += round;
if ((absResult & ~significandMask) > 0) { if ((absResult & ~significandMask) > 0) {
// The rounded result is normal; return it. // The rounded result is normal; return it.
return @bitCast(f128, absResult | quotientSign); return @as(f128, @bitCast(absResult | quotientSign));
} }
} }
// Flush denormals to zero. In the future, it would be nice to add // Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly. // code to round them correctly.
return @bitCast(f128, quotientSign); return @as(f128, @bitCast(quotientSign));
} else { } else {
const round = @intFromBool((residual << 1) >= bSignificand); const round = @intFromBool((residual << 1) >= bSignificand);
// Clear the implicit bit // Clear the implicit bit
var absResult = quotient & significandMask; var absResult = quotient & significandMask;
// Insert the exponent // Insert the exponent
absResult |= @intCast(Z, writtenExponent) << significandBits; absResult |= @as(Z, @intCast(writtenExponent)) << significandBits;
// Round // Round
absResult +%= round; absResult +%= round;
// Insert the sign and return // Insert the sign and return
return @bitCast(f128, absResult | quotientSign); return @as(f128, @bitCast(absResult | quotientSign));
} }
} }

View File

@ -5,9 +5,9 @@ const testing = std.testing;
const __divtf3 = @import("divtf3.zig").__divtf3; const __divtf3 = @import("divtf3.zig").__divtf3;
fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
const rep = @bitCast(u128, result); const rep = @as(u128, @bitCast(result));
const hi = @truncate(u64, rep >> 64); const hi = @as(u64, @truncate(rep >> 64));
const lo = @truncate(u64, rep); const lo = @as(u64, @truncate(rep));
if (hi == expectedHi and lo == expectedLo) { if (hi == expectedHi and lo == expectedLo) {
return true; return true;

View File

@ -21,7 +21,7 @@ pub fn __divti3(a: i128, b: i128) callconv(.C) i128 {
const v128 = @Vector(2, u64); const v128 = @Vector(2, u64);
fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 { fn __divti3_windows_x86_64(a: v128, b: v128) callconv(.C) v128 {
return @bitCast(v128, div(@bitCast(i128, a), @bitCast(i128, b))); return @as(v128, @bitCast(div(@as(i128, @bitCast(a)), @as(i128, @bitCast(b)))));
} }
inline fn div(a: i128, b: i128) i128 { inline fn div(a: i128, b: i128) i128 {
@ -31,9 +31,9 @@ inline fn div(a: i128, b: i128) i128 {
const an = (a ^ s_a) -% s_a; const an = (a ^ s_a) -% s_a;
const bn = (b ^ s_b) -% s_b; const bn = (b ^ s_b) -% s_b;
const r = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), null); const r = udivmod(u128, @as(u128, @bitCast(an)), @as(u128, @bitCast(bn)), null);
const s = s_a ^ s_b; const s = s_a ^ s_b;
return (@bitCast(i128, r) ^ s) -% s; return (@as(i128, @bitCast(r)) ^ s) -% s;
} }
test { test {

View File

@ -14,8 +14,8 @@ test "divti3" {
try test__divti3(-2, 1, -2); try test__divti3(-2, 1, -2);
try test__divti3(-2, -1, 2); try test__divti3(-2, -1, 2);
try test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), 1, @bitCast(i128, @as(u128, 0x8 << 124))); try test__divti3(@as(i128, @bitCast(@as(u128, 0x8 << 124))), 1, @as(i128, @bitCast(@as(u128, 0x8 << 124))));
try test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), -1, @bitCast(i128, @as(u128, 0x8 << 124))); try test__divti3(@as(i128, @bitCast(@as(u128, 0x8 << 124))), -1, @as(i128, @bitCast(@as(u128, 0x8 << 124))));
try test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), -2, @bitCast(i128, @as(u128, 0x4 << 124))); try test__divti3(@as(i128, @bitCast(@as(u128, 0x8 << 124))), -2, @as(i128, @bitCast(@as(u128, 0x4 << 124))));
try test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), 2, @bitCast(i128, @as(u128, 0xc << 124))); try test__divti3(@as(i128, @bitCast(@as(u128, 0x8 << 124))), 2, @as(i128, @bitCast(@as(u128, 0xc << 124))));
} }

View File

@ -29,53 +29,53 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
const significandMask = (@as(Z, 1) << significandBits) - 1; const significandMask = (@as(Z, 1) << significandBits) - 1;
const absMask = signBit - 1; const absMask = signBit - 1;
const qnanRep = @bitCast(Z, std.math.nan(T)) | quietBit; const qnanRep = @as(Z, @bitCast(std.math.nan(T))) | quietBit;
const infRep = @bitCast(Z, std.math.inf(T)); const infRep = @as(Z, @bitCast(std.math.inf(T)));
const aExponent = @truncate(u32, (@bitCast(Z, a) >> significandBits) & maxExponent); const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent); const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit; const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask; var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask; var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0; var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN. // Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask; const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask; const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// NaN / anything = qNaN // NaN / anything = qNaN
if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit); if (aAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(a)) | quietBit));
// anything / NaN = qNaN // anything / NaN = qNaN
if (bAbs > infRep) return @bitCast(T, @bitCast(Z, b) | quietBit); if (bAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(b)) | quietBit));
if (aAbs == infRep) { if (aAbs == infRep) {
// infinity / infinity = NaN // infinity / infinity = NaN
if (bAbs == infRep) { if (bAbs == infRep) {
return @bitCast(T, qnanRep); return @as(T, @bitCast(qnanRep));
} }
// infinity / anything else = +/- infinity // infinity / anything else = +/- infinity
else { else {
return @bitCast(T, aAbs | quotientSign); return @as(T, @bitCast(aAbs | quotientSign));
} }
} }
// anything else / infinity = +/- 0 // anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(T, quotientSign); if (bAbs == infRep) return @as(T, @bitCast(quotientSign));
if (aAbs == 0) { if (aAbs == 0) {
// zero / zero = NaN // zero / zero = NaN
if (bAbs == 0) { if (bAbs == 0) {
return @bitCast(T, qnanRep); return @as(T, @bitCast(qnanRep));
} }
// zero / anything else = +/- zero // zero / anything else = +/- zero
else { else {
return @bitCast(T, quotientSign); return @as(T, @bitCast(quotientSign));
} }
} }
// anything else / zero = +/- infinity // anything else / zero = +/- infinity
if (bAbs == 0) return @bitCast(T, infRep | quotientSign); if (bAbs == 0) return @as(T, @bitCast(infRep | quotientSign));
// one or both of a or b is denormal, the other (if applicable) is a // one or both of a or b is denormal, the other (if applicable) is a
// normal number. Renormalize one or both of a and b, and set scale to // normal number. Renormalize one or both of a and b, and set scale to
@ -83,13 +83,13 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
if (aAbs < integerBit) scale +%= normalize(T, &aSignificand); if (aAbs < integerBit) scale +%= normalize(T, &aSignificand);
if (bAbs < integerBit) scale -%= normalize(T, &bSignificand); if (bAbs < integerBit) scale -%= normalize(T, &bSignificand);
} }
var quotientExponent: i32 = @bitCast(i32, aExponent -% bExponent) +% scale; var quotientExponent: i32 = @as(i32, @bitCast(aExponent -% bExponent)) +% scale;
// Align the significand of b as a Q63 fixed-point number in the range // Align the significand of b as a Q63 fixed-point number in the range
// [1, 2.0) and get a Q64 approximate reciprocal using a small minimax // [1, 2.0) and get a Q64 approximate reciprocal using a small minimax
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// is accurate to about 3.5 binary digits. // is accurate to about 3.5 binary digits.
const q63b = @intCast(u64, bSignificand); const q63b = @as(u64, @intCast(bSignificand));
var recip64 = @as(u64, 0x7504f333F9DE6484) -% q63b; var recip64 = @as(u64, 0x7504f333F9DE6484) -% q63b;
// 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2) // 0x7504f333F9DE6484 / 2^64 + 1 = 3/4 + 1/sqrt(2)
@ -100,16 +100,16 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
// This doubles the number of correct binary digits in the approximation // This doubles the number of correct binary digits in the approximation
// with each iteration. // with each iteration.
var correction64: u64 = undefined; var correction64: u64 = undefined;
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1); correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63); recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
// The reciprocal may have overflowed to zero if the upper half of b is // The reciprocal may have overflowed to zero if the upper half of b is
// exactly 1.0. This would sabatoge the full-width final stage of the // exactly 1.0. This would sabatoge the full-width final stage of the
@ -128,8 +128,8 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
correction = -%correction; correction = -%correction;
const cHi = @truncate(u64, correction >> 64); const cHi = @as(u64, @truncate(correction >> 64));
const cLo = @truncate(u64, correction); const cLo = @as(u64, @truncate(correction));
var r64cH: u128 = undefined; var r64cH: u128 = undefined;
var r64cL: u128 = undefined; var r64cL: u128 = undefined;
@ -164,8 +164,8 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
// exponent accordingly. // exponent accordingly.
var quotient: u64 = if (quotient128 < (integerBit << 1)) b: { var quotient: u64 = if (quotient128 < (integerBit << 1)) b: {
quotientExponent -= 1; quotientExponent -= 1;
break :b @intCast(u64, quotient128); break :b @as(u64, @intCast(quotient128));
} else @intCast(u64, quotient128 >> 1); } else @as(u64, @intCast(quotient128 >> 1));
// We are going to compute a residual of the form // We are going to compute a residual of the form
// //
@ -182,26 +182,26 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
const writtenExponent = quotientExponent + exponentBias; const writtenExponent = quotientExponent + exponentBias;
if (writtenExponent >= maxExponent) { if (writtenExponent >= maxExponent) {
// If we have overflowed the exponent, return infinity. // If we have overflowed the exponent, return infinity.
return @bitCast(T, infRep | quotientSign); return @as(T, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) { } else if (writtenExponent < 1) {
if (writtenExponent == 0) { if (writtenExponent == 0) {
// Check whether the rounded result is normal. // Check whether the rounded result is normal.
if (residual > (bSignificand >> 1)) { // round if (residual > (bSignificand >> 1)) { // round
if (quotient == (integerBit - 1)) // If the rounded result is normal, return it if (quotient == (integerBit - 1)) // If the rounded result is normal, return it
return @bitCast(T, @bitCast(Z, std.math.floatMin(T)) | quotientSign); return @as(T, @bitCast(@as(Z, @bitCast(std.math.floatMin(T))) | quotientSign));
} }
} }
// Flush denormals to zero. In the future, it would be nice to add // Flush denormals to zero. In the future, it would be nice to add
// code to round them correctly. // code to round them correctly.
return @bitCast(T, quotientSign); return @as(T, @bitCast(quotientSign));
} else { } else {
const round = @intFromBool(residual > (bSignificand >> 1)); const round = @intFromBool(residual > (bSignificand >> 1));
// Insert the exponent // Insert the exponent
var absResult = quotient | (@intCast(Z, writtenExponent) << significandBits); var absResult = quotient | (@as(Z, @intCast(writtenExponent)) << significandBits);
// Round // Round
absResult +%= round; absResult +%= round;
// Insert the sign and return // Insert the sign and return
return @bitCast(T, absResult | quotientSign | integerBit); return @as(T, @bitCast(absResult | quotientSign | integerBit));
} }
} }

View File

@ -5,11 +5,11 @@ const testing = std.testing;
const __divxf3 = @import("divxf3.zig").__divxf3; const __divxf3 = @import("divxf3.zig").__divxf3;
fn compareResult(result: f80, expected: u80) bool { fn compareResult(result: f80, expected: u80) bool {
const rep = @bitCast(u80, result); const rep = @as(u80, @bitCast(result));
if (rep == expected) return true; if (rep == expected) return true;
// test other possible NaN representations (signal NaN) // test other possible NaN representations (signal NaN)
if (math.isNan(result) and math.isNan(@bitCast(f80, expected))) return true; if (math.isNan(result) and math.isNan(@as(f80, @bitCast(expected)))) return true;
return false; return false;
} }
@ -25,9 +25,9 @@ fn test__divxf3(a: f80, b: f80) !void {
const x = __divxf3(a, b); const x = __divxf3(a, b);
// Next float (assuming normal, non-zero result) // Next float (assuming normal, non-zero result)
const x_plus_eps = @bitCast(f80, (@bitCast(u80, x) + 1) | integerBit); const x_plus_eps = @as(f80, @bitCast((@as(u80, @bitCast(x)) + 1) | integerBit));
// Prev float (assuming normal, non-zero result) // Prev float (assuming normal, non-zero result)
const x_minus_eps = @bitCast(f80, (@bitCast(u80, x) - 1) | integerBit); const x_minus_eps = @as(f80, @bitCast((@as(u80, @bitCast(x)) - 1) | integerBit));
// Make sure result is more accurate than the adjacent floats // Make sure result is more accurate than the adjacent floats
const err_x = @fabs(@mulAdd(f80, x, b, -a)); const err_x = @fabs(@mulAdd(f80, x, b, -a));

View File

@ -33,18 +33,14 @@ pub fn __emutls_get_address(control: *emutls_control) callconv(.C) *anyopaque {
const simple_allocator = struct { const simple_allocator = struct {
/// Allocate a memory chunk for requested type. Return a pointer on the data. /// Allocate a memory chunk for requested type. Return a pointer on the data.
pub fn alloc(comptime T: type) *T { pub fn alloc(comptime T: type) *T {
return @ptrCast(*T, @alignCast( return @ptrCast(@alignCast(advancedAlloc(@alignOf(T), @sizeOf(T))));
@alignOf(T),
advancedAlloc(@alignOf(T), @sizeOf(T)),
));
} }
/// Allocate a slice of T, with len elements. /// Allocate a slice of T, with len elements.
pub fn allocSlice(comptime T: type, len: usize) []T { pub fn allocSlice(comptime T: type, len: usize) []T {
return @ptrCast([*]T, @alignCast( return @as([*]T, @ptrCast(@alignCast(
@alignOf(T),
advancedAlloc(@alignOf(T), @sizeOf(T) * len), advancedAlloc(@alignOf(T), @sizeOf(T) * len),
))[0 .. len - 1]; )))[0 .. len - 1];
} }
/// Allocate a memory chunk. /// Allocate a memory chunk.
@ -56,22 +52,19 @@ const simple_allocator = struct {
abort(); abort();
} }
return @ptrCast([*]u8, aligned_ptr); return @as([*]u8, @ptrCast(aligned_ptr));
} }
/// Resize a slice. /// Resize a slice.
pub fn reallocSlice(comptime T: type, slice: []T, len: usize) []T { pub fn reallocSlice(comptime T: type, slice: []T, len: usize) []T {
var c_ptr: *anyopaque = @ptrCast(*anyopaque, slice.ptr); var c_ptr: *anyopaque = @as(*anyopaque, @ptrCast(slice.ptr));
var new_array: [*]T = @ptrCast([*]T, @alignCast( var new_array: [*]T = @ptrCast(@alignCast(std.c.realloc(c_ptr, @sizeOf(T) * len) orelse abort()));
@alignOf(T),
std.c.realloc(c_ptr, @sizeOf(T) * len) orelse abort(),
));
return new_array[0..len]; return new_array[0..len];
} }
/// Free a memory chunk allocated with simple_allocator. /// Free a memory chunk allocated with simple_allocator.
pub fn free(ptr: anytype) void { pub fn free(ptr: anytype) void {
std.c.free(@ptrCast(*anyopaque, ptr)); std.c.free(@as(*anyopaque, @ptrCast(ptr)));
} }
}; };
@ -132,20 +125,20 @@ const ObjectArray = struct {
if (self.slots[index] == null) { if (self.slots[index] == null) {
// initialize the slot // initialize the slot
const size = control.size; const size = control.size;
const alignment = @truncate(u29, control.alignment); const alignment = @as(u29, @truncate(control.alignment));
var data = simple_allocator.advancedAlloc(alignment, size); var data = simple_allocator.advancedAlloc(alignment, size);
errdefer simple_allocator.free(data); errdefer simple_allocator.free(data);
if (control.default_value) |value| { if (control.default_value) |value| {
// default value: copy the content to newly allocated object. // default value: copy the content to newly allocated object.
@memcpy(data[0..size], @ptrCast([*]const u8, value)); @memcpy(data[0..size], @as([*]const u8, @ptrCast(value)));
} else { } else {
// no default: return zeroed memory. // no default: return zeroed memory.
@memset(data[0..size], 0); @memset(data[0..size], 0);
} }
self.slots[index] = @ptrCast(*anyopaque, data); self.slots[index] = @as(*anyopaque, @ptrCast(data));
} }
return self.slots[index].?; return self.slots[index].?;
@ -180,18 +173,12 @@ const current_thread_storage = struct {
/// Return casted thread specific value. /// Return casted thread specific value.
fn getspecific() ?*ObjectArray { fn getspecific() ?*ObjectArray {
return @ptrCast( return @ptrCast(@alignCast(std.c.pthread_getspecific(current_thread_storage.key)));
?*ObjectArray,
@alignCast(
@alignOf(ObjectArray),
std.c.pthread_getspecific(current_thread_storage.key),
),
);
} }
/// Set casted thread specific value. /// Set casted thread specific value.
fn setspecific(new: ?*ObjectArray) void { fn setspecific(new: ?*ObjectArray) void {
if (std.c.pthread_setspecific(current_thread_storage.key, @ptrCast(*anyopaque, new)) != 0) { if (std.c.pthread_setspecific(current_thread_storage.key, @as(*anyopaque, @ptrCast(new))) != 0) {
abort(); abort();
} }
} }
@ -205,10 +192,7 @@ const current_thread_storage = struct {
/// Invoked by pthread specific destructor. the passed argument is the ObjectArray pointer. /// Invoked by pthread specific destructor. the passed argument is the ObjectArray pointer.
fn deinit(arrayPtr: *anyopaque) callconv(.C) void { fn deinit(arrayPtr: *anyopaque) callconv(.C) void {
var array = @ptrCast( var array: *ObjectArray = @ptrCast(@alignCast(arrayPtr));
*ObjectArray,
@alignCast(@alignOf(ObjectArray), arrayPtr),
);
array.deinit(); array.deinit();
} }
}; };
@ -294,7 +278,7 @@ const emutls_control = extern struct {
.size = @sizeOf(T), .size = @sizeOf(T),
.alignment = @alignOf(T), .alignment = @alignOf(T),
.object = .{ .index = 0 }, .object = .{ .index = 0 },
.default_value = @ptrCast(?*const anyopaque, default_value), .default_value = @as(?*const anyopaque, @ptrCast(default_value)),
}; };
} }
@ -313,10 +297,7 @@ const emutls_control = extern struct {
pub fn get_typed_pointer(self: *emutls_control, comptime T: type) *T { pub fn get_typed_pointer(self: *emutls_control, comptime T: type) *T {
assert(self.size == @sizeOf(T)); assert(self.size == @sizeOf(T));
assert(self.alignment == @alignOf(T)); assert(self.alignment == @alignOf(T));
return @ptrCast( return @ptrCast(@alignCast(self.getPointer()));
*T,
@alignCast(@alignOf(T), self.getPointer()),
);
} }
}; };
@ -343,7 +324,7 @@ test "__emutls_get_address zeroed" {
try expect(ctl.object.index == 0); try expect(ctl.object.index == 0);
// retrieve a variable from ctl // retrieve a variable from ctl
var x = @ptrCast(*usize, @alignCast(@alignOf(usize), __emutls_get_address(&ctl))); var x: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl)));
try expect(ctl.object.index != 0); // index has been allocated for this ctl try expect(ctl.object.index != 0); // index has been allocated for this ctl
try expect(x.* == 0); // storage has been zeroed try expect(x.* == 0); // storage has been zeroed
@ -351,7 +332,7 @@ test "__emutls_get_address zeroed" {
x.* = 1234; x.* = 1234;
// retrieve a variable from ctl (same ctl) // retrieve a variable from ctl (same ctl)
var y = @ptrCast(*usize, @alignCast(@alignOf(usize), __emutls_get_address(&ctl))); var y: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl)));
try expect(y.* == 1234); // same content that x.* try expect(y.* == 1234); // same content that x.*
try expect(x == y); // same pointer try expect(x == y); // same pointer
@ -364,7 +345,7 @@ test "__emutls_get_address with default_value" {
var ctl = emutls_control.init(usize, &value); var ctl = emutls_control.init(usize, &value);
try expect(ctl.object.index == 0); try expect(ctl.object.index == 0);
var x: *usize = @ptrCast(*usize, @alignCast(@alignOf(usize), __emutls_get_address(&ctl))); var x: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl)));
try expect(ctl.object.index != 0); try expect(ctl.object.index != 0);
try expect(x.* == 5678); // storage initialized with default value try expect(x.* == 5678); // storage initialized with default value
@ -373,7 +354,7 @@ test "__emutls_get_address with default_value" {
try expect(value == 5678); // the default value didn't change try expect(value == 5678); // the default value didn't change
var y = @ptrCast(*usize, @alignCast(@alignOf(usize), __emutls_get_address(&ctl))); var y: *usize = @ptrCast(@alignCast(__emutls_get_address(&ctl)));
try expect(y.* == 9012); // the modified storage persists try expect(y.* == 9012); // the modified storage persists
} }

View File

@ -27,7 +27,7 @@ comptime {
pub fn __exph(a: f16) callconv(.C) f16 { pub fn __exph(a: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, expf(a)); return @as(f16, @floatCast(expf(a)));
} }
pub fn expf(x_: f32) callconv(.C) f32 { pub fn expf(x_: f32) callconv(.C) f32 {
@ -39,8 +39,8 @@ pub fn expf(x_: f32) callconv(.C) f32 {
const P2 = -2.7667332906e-3; const P2 = -2.7667332906e-3;
var x = x_; var x = x_;
var hx = @bitCast(u32, x); var hx = @as(u32, @bitCast(x));
const sign = @intCast(i32, hx >> 31); const sign = @as(i32, @intCast(hx >> 31));
hx &= 0x7FFFFFFF; hx &= 0x7FFFFFFF;
if (math.isNan(x)) { if (math.isNan(x)) {
@ -74,12 +74,12 @@ pub fn expf(x_: f32) callconv(.C) f32 {
if (hx > 0x3EB17218) { if (hx > 0x3EB17218) {
// |x| > 1.5 * ln2 // |x| > 1.5 * ln2
if (hx > 0x3F851592) { if (hx > 0x3F851592) {
k = @intFromFloat(i32, invln2 * x + half[@intCast(usize, sign)]); k = @as(i32, @intFromFloat(invln2 * x + half[@as(usize, @intCast(sign))]));
} else { } else {
k = 1 - sign - sign; k = 1 - sign - sign;
} }
const fk = @floatFromInt(f32, k); const fk = @as(f32, @floatFromInt(k));
hi = x - fk * ln2hi; hi = x - fk * ln2hi;
lo = fk * ln2lo; lo = fk * ln2lo;
x = hi - lo; x = hi - lo;
@ -117,9 +117,9 @@ pub fn exp(x_: f64) callconv(.C) f64 {
const P5: f64 = 4.13813679705723846039e-08; const P5: f64 = 4.13813679705723846039e-08;
var x = x_; var x = x_;
var ux = @bitCast(u64, x); var ux = @as(u64, @bitCast(x));
var hx = ux >> 32; var hx = ux >> 32;
const sign = @intCast(i32, hx >> 31); const sign = @as(i32, @intCast(hx >> 31));
hx &= 0x7FFFFFFF; hx &= 0x7FFFFFFF;
if (math.isNan(x)) { if (math.isNan(x)) {
@ -157,12 +157,12 @@ pub fn exp(x_: f64) callconv(.C) f64 {
if (hx > 0x3FD62E42) { if (hx > 0x3FD62E42) {
// |x| >= 1.5 * ln2 // |x| >= 1.5 * ln2
if (hx > 0x3FF0A2B2) { if (hx > 0x3FF0A2B2) {
k = @intFromFloat(i32, invln2 * x + half[@intCast(usize, sign)]); k = @as(i32, @intFromFloat(invln2 * x + half[@as(usize, @intCast(sign))]));
} else { } else {
k = 1 - sign - sign; k = 1 - sign - sign;
} }
const dk = @floatFromInt(f64, k); const dk = @as(f64, @floatFromInt(k));
hi = x - dk * ln2hi; hi = x - dk * ln2hi;
lo = dk * ln2lo; lo = dk * ln2lo;
x = hi - lo; x = hi - lo;
@ -191,12 +191,12 @@ pub fn exp(x_: f64) callconv(.C) f64 {
pub fn __expx(a: f80) callconv(.C) f80 { pub fn __expx(a: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, expq(a)); return @as(f80, @floatCast(expq(a)));
} }
pub fn expq(a: f128) callconv(.C) f128 { pub fn expq(a: f128) callconv(.C) f128 {
// TODO: more correct implementation // TODO: more correct implementation
return exp(@floatCast(f64, a)); return exp(@as(f64, @floatCast(a)));
} }
pub fn expl(x: c_longdouble) callconv(.C) c_longdouble { pub fn expl(x: c_longdouble) callconv(.C) c_longdouble {

View File

@ -27,18 +27,18 @@ comptime {
pub fn __exp2h(x: f16) callconv(.C) f16 { pub fn __exp2h(x: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, exp2f(x)); return @as(f16, @floatCast(exp2f(x)));
} }
pub fn exp2f(x: f32) callconv(.C) f32 { pub fn exp2f(x: f32) callconv(.C) f32 {
const tblsiz = @intCast(u32, exp2ft.len); const tblsiz = @as(u32, @intCast(exp2ft.len));
const redux: f32 = 0x1.8p23 / @floatFromInt(f32, tblsiz); const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));
const P1: f32 = 0x1.62e430p-1; const P1: f32 = 0x1.62e430p-1;
const P2: f32 = 0x1.ebfbe0p-3; const P2: f32 = 0x1.ebfbe0p-3;
const P3: f32 = 0x1.c6b348p-5; const P3: f32 = 0x1.c6b348p-5;
const P4: f32 = 0x1.3b2c9cp-7; const P4: f32 = 0x1.3b2c9cp-7;
var u = @bitCast(u32, x); var u = @as(u32, @bitCast(x));
const ix = u & 0x7FFFFFFF; const ix = u & 0x7FFFFFFF;
// |x| > 126 // |x| > 126
@ -72,32 +72,32 @@ pub fn exp2f(x: f32) callconv(.C) f32 {
// intended result but should confirm how GCC/Clang handle this to ensure. // intended result but should confirm how GCC/Clang handle this to ensure.
var uf = x + redux; var uf = x + redux;
var i_0 = @bitCast(u32, uf); var i_0 = @as(u32, @bitCast(uf));
i_0 +%= tblsiz / 2; i_0 +%= tblsiz / 2;
const k = i_0 / tblsiz; const k = i_0 / tblsiz;
const uk = @bitCast(f64, @as(u64, 0x3FF + k) << 52); const uk = @as(f64, @bitCast(@as(u64, 0x3FF + k) << 52));
i_0 &= tblsiz - 1; i_0 &= tblsiz - 1;
uf -= redux; uf -= redux;
const z: f64 = x - uf; const z: f64 = x - uf;
var r: f64 = exp2ft[@intCast(usize, i_0)]; var r: f64 = exp2ft[@as(usize, @intCast(i_0))];
const t: f64 = r * z; const t: f64 = r * z;
r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4); r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
return @floatCast(f32, r * uk); return @as(f32, @floatCast(r * uk));
} }
pub fn exp2(x: f64) callconv(.C) f64 { pub fn exp2(x: f64) callconv(.C) f64 {
const tblsiz: u32 = @intCast(u32, exp2dt.len / 2); const tblsiz: u32 = @as(u32, @intCast(exp2dt.len / 2));
const redux: f64 = 0x1.8p52 / @floatFromInt(f64, tblsiz); const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz));
const P1: f64 = 0x1.62e42fefa39efp-1; const P1: f64 = 0x1.62e42fefa39efp-1;
const P2: f64 = 0x1.ebfbdff82c575p-3; const P2: f64 = 0x1.ebfbdff82c575p-3;
const P3: f64 = 0x1.c6b08d704a0a6p-5; const P3: f64 = 0x1.c6b08d704a0a6p-5;
const P4: f64 = 0x1.3b2ab88f70400p-7; const P4: f64 = 0x1.3b2ab88f70400p-7;
const P5: f64 = 0x1.5d88003875c74p-10; const P5: f64 = 0x1.5d88003875c74p-10;
const ux = @bitCast(u64, x); const ux = @as(u64, @bitCast(x));
const ix = @intCast(u32, ux >> 32) & 0x7FFFFFFF; const ix = @as(u32, @intCast(ux >> 32)) & 0x7FFFFFFF;
// TODO: This should be handled beneath. // TODO: This should be handled beneath.
if (math.isNan(x)) { if (math.isNan(x)) {
@ -119,7 +119,7 @@ pub fn exp2(x: f64) callconv(.C) f64 {
if (ux >> 63 != 0) { if (ux >> 63 != 0) {
// underflow // underflow
if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) { if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) {
math.doNotOptimizeAway(@floatCast(f32, -0x1.0p-149 / x)); math.doNotOptimizeAway(@as(f32, @floatCast(-0x1.0p-149 / x)));
} }
if (x <= -1075) { if (x <= -1075) {
return 0; return 0;
@ -139,18 +139,18 @@ pub fn exp2(x: f64) callconv(.C) f64 {
// reduce x // reduce x
var uf: f64 = x + redux; var uf: f64 = x + redux;
// NOTE: musl performs an implicit 64-bit to 32-bit u32 truncation here // NOTE: musl performs an implicit 64-bit to 32-bit u32 truncation here
var i_0: u32 = @truncate(u32, @bitCast(u64, uf)); var i_0: u32 = @as(u32, @truncate(@as(u64, @bitCast(uf))));
i_0 +%= tblsiz / 2; i_0 +%= tblsiz / 2;
const k: u32 = i_0 / tblsiz * tblsiz; const k: u32 = i_0 / tblsiz * tblsiz;
const ik: i32 = @divTrunc(@bitCast(i32, k), tblsiz); const ik: i32 = @divTrunc(@as(i32, @bitCast(k)), tblsiz);
i_0 %= tblsiz; i_0 %= tblsiz;
uf -= redux; uf -= redux;
// r = exp2(y) = exp2t[i_0] * p(z - eps[i]) // r = exp2(y) = exp2t[i_0] * p(z - eps[i])
var z: f64 = x - uf; var z: f64 = x - uf;
const t: f64 = exp2dt[@intCast(usize, 2 * i_0)]; const t: f64 = exp2dt[@as(usize, @intCast(2 * i_0))];
z -= exp2dt[@intCast(usize, 2 * i_0 + 1)]; z -= exp2dt[@as(usize, @intCast(2 * i_0 + 1))];
const r: f64 = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5)))); const r: f64 = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
return math.scalbn(r, ik); return math.scalbn(r, ik);
@ -158,12 +158,12 @@ pub fn exp2(x: f64) callconv(.C) f64 {
pub fn __exp2x(x: f80) callconv(.C) f80 { pub fn __exp2x(x: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, exp2q(x)); return @as(f80, @floatCast(exp2q(x)));
} }
pub fn exp2q(x: f128) callconv(.C) f128 { pub fn exp2q(x: f128) callconv(.C) f128 {
// TODO: more correct implementation // TODO: more correct implementation
return exp2(@floatCast(f64, x)); return exp2(@as(f64, @floatCast(x)));
} }
pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble { pub fn exp2l(x: c_longdouble) callconv(.C) c_longdouble {

View File

@ -13,9 +13,9 @@ comptime {
} }
pub fn __extenddftf2(a: f64) callconv(.C) f128 { pub fn __extenddftf2(a: f64) callconv(.C) f128 {
return extendf(f128, f64, @bitCast(u64, a)); return extendf(f128, f64, @as(u64, @bitCast(a)));
} }
fn _Qp_dtoq(c: *f128, a: f64) callconv(.C) void { fn _Qp_dtoq(c: *f128, a: f64) callconv(.C) void {
c.* = extendf(f128, f64, @bitCast(u64, a)); c.* = extendf(f128, f64, @as(u64, @bitCast(a)));
} }

View File

@ -8,5 +8,5 @@ comptime {
} }
pub fn __extenddfxf2(a: f64) callconv(.C) f80 { pub fn __extenddfxf2(a: f64) callconv(.C) f80 {
return extend_f80(f64, @bitCast(u64, a)); return extend_f80(f64, @as(u64, @bitCast(a)));
} }

View File

@ -33,7 +33,7 @@ pub inline fn extendf(
const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits; const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;
// Break a into a sign and representation of the absolute value // Break a into a sign and representation of the absolute value
const aRep: src_rep_t = @bitCast(src_rep_t, a); const aRep: src_rep_t = @as(src_rep_t, @bitCast(a));
const aAbs: src_rep_t = aRep & srcAbsMask; const aAbs: src_rep_t = aRep & srcAbsMask;
const sign: src_rep_t = aRep & srcSignMask; const sign: src_rep_t = aRep & srcSignMask;
var absResult: dst_rep_t = undefined; var absResult: dst_rep_t = undefined;
@ -58,10 +58,10 @@ pub inline fn extendf(
// the correct adjusted exponent in the destination type. // the correct adjusted exponent in the destination type.
const scale: u32 = @clz(aAbs) - const scale: u32 = @clz(aAbs) -
@clz(@as(src_rep_t, srcMinNormal)); @clz(@as(src_rep_t, srcMinNormal));
absResult = @as(dst_rep_t, aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale); absResult = @as(dst_rep_t, aAbs) << @as(DstShift, @intCast(dstSigBits - srcSigBits + scale));
absResult ^= dstMinNormal; absResult ^= dstMinNormal;
const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1; const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;
absResult |= @intCast(dst_rep_t, resultExponent) << dstSigBits; absResult |= @as(dst_rep_t, @intCast(resultExponent)) << dstSigBits;
} else { } else {
// a is zero. // a is zero.
absResult = 0; absResult = 0;
@ -69,7 +69,7 @@ pub inline fn extendf(
// Apply the signbit to (dst_t)abs(a). // Apply the signbit to (dst_t)abs(a).
const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits); const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits);
return @bitCast(dst_t, result); return @as(dst_t, @bitCast(result));
} }
pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits)) f80 { pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeInfo(src_t).Float.bits)) f80 {
@ -104,7 +104,7 @@ pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeI
// a is a normal number. // a is a normal number.
// Extend to the destination type by shifting the significand and // Extend to the destination type by shifting the significand and
// exponent into the proper position and rebiasing the exponent. // exponent into the proper position and rebiasing the exponent.
dst.exp = @intCast(u16, a_abs >> src_sig_bits); dst.exp = @as(u16, @intCast(a_abs >> src_sig_bits));
dst.exp += dst_exp_bias - src_exp_bias; dst.exp += dst_exp_bias - src_exp_bias;
dst.fraction = @as(u64, a_abs) << (dst_sig_bits - src_sig_bits); dst.fraction = @as(u64, a_abs) << (dst_sig_bits - src_sig_bits);
dst.fraction |= dst_int_bit; // bit 64 is always set for normal numbers dst.fraction |= dst_int_bit; // bit 64 is always set for normal numbers
@ -124,9 +124,9 @@ pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeI
const scale: u16 = @clz(a_abs) - const scale: u16 = @clz(a_abs) -
@clz(@as(src_rep_t, src_min_normal)); @clz(@as(src_rep_t, src_min_normal));
dst.fraction = @as(u64, a_abs) << @intCast(u6, dst_sig_bits - src_sig_bits + scale); dst.fraction = @as(u64, a_abs) << @as(u6, @intCast(dst_sig_bits - src_sig_bits + scale));
dst.fraction |= dst_int_bit; // bit 64 is always set for normal numbers dst.fraction |= dst_int_bit; // bit 64 is always set for normal numbers
dst.exp = @truncate(u16, a_abs >> @intCast(SrcShift, src_sig_bits - scale)); dst.exp = @as(u16, @truncate(a_abs >> @as(SrcShift, @intCast(src_sig_bits - scale))));
dst.exp ^= 1; dst.exp ^= 1;
dst.exp |= dst_exp_bias - src_exp_bias - scale + 1; dst.exp |= dst_exp_bias - src_exp_bias - scale + 1;
} else { } else {

View File

@ -11,12 +11,12 @@ const F16T = @import("./common.zig").F16T;
fn test__extenddfxf2(a: f64, expected: u80) !void { fn test__extenddfxf2(a: f64, expected: u80) !void {
const x = __extenddfxf2(a); const x = __extenddfxf2(a);
const rep = @bitCast(u80, x); const rep = @as(u80, @bitCast(x));
if (rep == expected) if (rep == expected)
return; return;
// test other possible NaN representation(signal NaN) // test other possible NaN representation(signal NaN)
if (math.isNan(@bitCast(f80, expected)) and math.isNan(x)) if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x))
return; return;
@panic("__extenddfxf2 test failure"); @panic("__extenddfxf2 test failure");
@ -25,9 +25,9 @@ fn test__extenddfxf2(a: f64, expected: u80) !void {
fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void { fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
const x = __extenddftf2(a); const x = __extenddftf2(a);
const rep = @bitCast(u128, x); const rep = @as(u128, @bitCast(x));
const hi = @intCast(u64, rep >> 64); const hi = @as(u64, @intCast(rep >> 64));
const lo = @truncate(u64, rep); const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo) if (hi == expected_hi and lo == expected_lo)
return; return;
@ -45,14 +45,14 @@ fn test__extenddftf2(a: f64, expected_hi: u64, expected_lo: u64) !void {
} }
fn test__extendhfsf2(a: u16, expected: u32) !void { fn test__extendhfsf2(a: u16, expected: u32) !void {
const x = __extendhfsf2(@bitCast(F16T(f32), a)); const x = __extendhfsf2(@as(F16T(f32), @bitCast(a)));
const rep = @bitCast(u32, x); const rep = @as(u32, @bitCast(x));
if (rep == expected) { if (rep == expected) {
if (rep & 0x7fffffff > 0x7f800000) { if (rep & 0x7fffffff > 0x7f800000) {
return; // NaN is always unequal. return; // NaN is always unequal.
} }
if (x == @bitCast(f32, expected)) { if (x == @as(f32, @bitCast(expected))) {
return; return;
} }
} }
@ -63,9 +63,9 @@ fn test__extendhfsf2(a: u16, expected: u32) !void {
fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void { fn test__extendsftf2(a: f32, expected_hi: u64, expected_lo: u64) !void {
const x = __extendsftf2(a); const x = __extendsftf2(a);
const rep = @bitCast(u128, x); const rep = @as(u128, @bitCast(x));
const hi = @intCast(u64, rep >> 64); const hi = @as(u64, @intCast(rep >> 64));
const lo = @truncate(u64, rep); const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo) if (hi == expected_hi and lo == expected_lo)
return; return;
@ -184,35 +184,35 @@ test "extendsftf2" {
} }
fn makeQNaN64() f64 { fn makeQNaN64() f64 {
return @bitCast(f64, @as(u64, 0x7ff8000000000000)); return @as(f64, @bitCast(@as(u64, 0x7ff8000000000000)));
} }
fn makeInf64() f64 { fn makeInf64() f64 {
return @bitCast(f64, @as(u64, 0x7ff0000000000000)); return @as(f64, @bitCast(@as(u64, 0x7ff0000000000000)));
} }
fn makeNaN64(rand: u64) f64 { fn makeNaN64(rand: u64) f64 {
return @bitCast(f64, 0x7ff0000000000000 | (rand & 0xfffffffffffff)); return @as(f64, @bitCast(0x7ff0000000000000 | (rand & 0xfffffffffffff)));
} }
fn makeQNaN32() f32 { fn makeQNaN32() f32 {
return @bitCast(f32, @as(u32, 0x7fc00000)); return @as(f32, @bitCast(@as(u32, 0x7fc00000)));
} }
fn makeNaN32(rand: u32) f32 { fn makeNaN32(rand: u32) f32 {
return @bitCast(f32, 0x7f800000 | (rand & 0x7fffff)); return @as(f32, @bitCast(0x7f800000 | (rand & 0x7fffff)));
} }
fn makeInf32() f32 { fn makeInf32() f32 {
return @bitCast(f32, @as(u32, 0x7f800000)); return @as(f32, @bitCast(@as(u32, 0x7f800000)));
} }
fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void { fn test__extendhftf2(a: u16, expected_hi: u64, expected_lo: u64) !void {
const x = __extendhftf2(@bitCast(F16T(f128), a)); const x = __extendhftf2(@as(F16T(f128), @bitCast(a)));
const rep = @bitCast(u128, x); const rep = @as(u128, @bitCast(x));
const hi = @intCast(u64, rep >> 64); const hi = @as(u64, @intCast(rep >> 64));
const lo = @truncate(u64, rep); const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo) if (hi == expected_hi and lo == expected_lo)
return; return;

View File

@ -8,5 +8,5 @@ comptime {
} }
pub fn __extendhfdf2(a: common.F16T(f64)) callconv(.C) f64 { pub fn __extendhfdf2(a: common.F16T(f64)) callconv(.C) f64 {
return extendf(f64, f16, @bitCast(u16, a)); return extendf(f64, f16, @as(u16, @bitCast(a)));
} }

View File

@ -13,13 +13,13 @@ comptime {
} }
pub fn __extendhfsf2(a: common.F16T(f32)) callconv(.C) f32 { pub fn __extendhfsf2(a: common.F16T(f32)) callconv(.C) f32 {
return extendf(f32, f16, @bitCast(u16, a)); return extendf(f32, f16, @as(u16, @bitCast(a)));
} }
fn __gnu_h2f_ieee(a: common.F16T(f32)) callconv(.C) f32 { fn __gnu_h2f_ieee(a: common.F16T(f32)) callconv(.C) f32 {
return extendf(f32, f16, @bitCast(u16, a)); return extendf(f32, f16, @as(u16, @bitCast(a)));
} }
fn __aeabi_h2f(a: u16) callconv(.AAPCS) f32 { fn __aeabi_h2f(a: u16) callconv(.AAPCS) f32 {
return extendf(f32, f16, @bitCast(u16, a)); return extendf(f32, f16, @as(u16, @bitCast(a)));
} }

View File

@ -8,5 +8,5 @@ comptime {
} }
pub fn __extendhftf2(a: common.F16T(f128)) callconv(.C) f128 { pub fn __extendhftf2(a: common.F16T(f128)) callconv(.C) f128 {
return extendf(f128, f16, @bitCast(u16, a)); return extendf(f128, f16, @as(u16, @bitCast(a)));
} }

View File

@ -8,5 +8,5 @@ comptime {
} }
fn __extendhfxf2(a: common.F16T(f80)) callconv(.C) f80 { fn __extendhfxf2(a: common.F16T(f80)) callconv(.C) f80 {
return extend_f80(f16, @bitCast(u16, a)); return extend_f80(f16, @as(u16, @bitCast(a)));
} }

View File

@ -12,9 +12,9 @@ comptime {
} }
fn __extendsfdf2(a: f32) callconv(.C) f64 { fn __extendsfdf2(a: f32) callconv(.C) f64 {
return extendf(f64, f32, @bitCast(u32, a)); return extendf(f64, f32, @as(u32, @bitCast(a)));
} }
fn __aeabi_f2d(a: f32) callconv(.AAPCS) f64 { fn __aeabi_f2d(a: f32) callconv(.AAPCS) f64 {
return extendf(f64, f32, @bitCast(u32, a)); return extendf(f64, f32, @as(u32, @bitCast(a)));
} }

View File

@ -13,9 +13,9 @@ comptime {
} }
pub fn __extendsftf2(a: f32) callconv(.C) f128 { pub fn __extendsftf2(a: f32) callconv(.C) f128 {
return extendf(f128, f32, @bitCast(u32, a)); return extendf(f128, f32, @as(u32, @bitCast(a)));
} }
fn _Qp_stoq(c: *f128, a: f32) callconv(.C) void { fn _Qp_stoq(c: *f128, a: f32) callconv(.C) void {
c.* = extendf(f128, f32, @bitCast(u32, a)); c.* = extendf(f128, f32, @as(u32, @bitCast(a)));
} }

View File

@ -8,5 +8,5 @@ comptime {
} }
fn __extendsfxf2(a: f32) callconv(.C) f80 { fn __extendsfxf2(a: f32) callconv(.C) f80 {
return extend_f80(f32, @bitCast(u32, a)); return extend_f80(f32, @as(u32, @bitCast(a)));
} }

View File

@ -39,12 +39,12 @@ fn __extendxftf2(a: f80) callconv(.C) f128 {
// renormalize the significand and clear the leading bit and integer part, // renormalize the significand and clear the leading bit and integer part,
// then insert the correct adjusted exponent in the destination type. // then insert the correct adjusted exponent in the destination type.
const scale: u32 = @clz(a_rep.fraction); const scale: u32 = @clz(a_rep.fraction);
abs_result = @as(u128, a_rep.fraction) << @intCast(u7, dst_sig_bits - src_sig_bits + scale + 1); abs_result = @as(u128, a_rep.fraction) << @as(u7, @intCast(dst_sig_bits - src_sig_bits + scale + 1));
abs_result ^= dst_min_normal; abs_result ^= dst_min_normal;
abs_result |= @as(u128, scale + 1) << dst_sig_bits; abs_result |= @as(u128, scale + 1) << dst_sig_bits;
} }
// Apply the signbit to (dst_t)abs(a). // Apply the signbit to (dst_t)abs(a).
const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16); const result: u128 align(@alignOf(f128)) = abs_result | @as(u128, sign) << (dst_bits - 16);
return @bitCast(f128, result); return @as(f128, @bitCast(result));
} }

View File

@ -51,7 +51,7 @@ pub fn fabsl(x: c_longdouble) callconv(.C) c_longdouble {
inline fn generic_fabs(x: anytype) @TypeOf(x) { inline fn generic_fabs(x: anytype) @TypeOf(x) {
const T = @TypeOf(x); const T = @TypeOf(x);
const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); const TBits = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
const float_bits = @bitCast(TBits, x); const float_bits = @as(TBits, @bitCast(x));
const remove_sign = ~@as(TBits, 0) >> 1; const remove_sign = ~@as(TBits, 0) >> 1;
return @bitCast(T, float_bits & remove_sign); return @as(T, @bitCast(float_bits & remove_sign));
} }

View File

@ -2,7 +2,7 @@ const ffs = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__ffsdi2(a: u64, expected: i32) !void { fn test__ffsdi2(a: u64, expected: i32) !void {
var x = @bitCast(i64, a); var x = @as(i64, @bitCast(a));
var result = ffs.__ffsdi2(x); var result = ffs.__ffsdi2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -2,7 +2,7 @@ const ffs = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__ffssi2(a: u32, expected: i32) !void { fn test__ffssi2(a: u32, expected: i32) !void {
var x = @bitCast(i32, a); var x = @as(i32, @bitCast(a));
var result = ffs.__ffssi2(x); var result = ffs.__ffssi2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -2,7 +2,7 @@ const ffs = @import("count0bits.zig");
const testing = @import("std").testing; const testing = @import("std").testing;
fn test__ffsti2(a: u128, expected: i32) !void { fn test__ffsti2(a: u128, expected: i32) !void {
var x = @bitCast(i128, a); var x = @as(i128, @bitCast(a));
var result = ffs.__ffsti2(x); var result = ffs.__ffsti2(x);
try testing.expectEqual(expected, result); try testing.expectEqual(expected, result);
} }

View File

@ -19,5 +19,5 @@ pub fn __fixdfti(a: f64) callconv(.C) i128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixdfti_windows_x86_64(a: f64) callconv(.C) v2u64 { fn __fixdfti_windows_x86_64(a: f64) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(i128, a)); return @as(v2u64, @bitCast(intFromFloat(i128, a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __fixhfti(a: f16) callconv(.C) i128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixhfti_windows_x86_64(a: f16) callconv(.C) v2u64 { fn __fixhfti_windows_x86_64(a: f16) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(i128, a)); return @as(v2u64, @bitCast(intFromFloat(i128, a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __fixsfti(a: f32) callconv(.C) i128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixsfti_windows_x86_64(a: f32) callconv(.C) v2u64 { fn __fixsfti_windows_x86_64(a: f32) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(i128, a)); return @as(v2u64, @bitCast(intFromFloat(i128, a)));
} }

View File

@ -21,5 +21,5 @@ pub fn __fixtfti(a: f128) callconv(.C) i128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixtfti_windows_x86_64(a: f128) callconv(.C) v2u64 { fn __fixtfti_windows_x86_64(a: f128) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(i128, a)); return @as(v2u64, @bitCast(intFromFloat(i128, a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __fixunsdfti(a: f64) callconv(.C) u128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixunsdfti_windows_x86_64(a: f64) callconv(.C) v2u64 { fn __fixunsdfti_windows_x86_64(a: f64) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(u128, a)); return @as(v2u64, @bitCast(intFromFloat(u128, a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __fixunshfti(a: f16) callconv(.C) u128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixunshfti_windows_x86_64(a: f16) callconv(.C) v2u64 { fn __fixunshfti_windows_x86_64(a: f16) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(u128, a)); return @as(v2u64, @bitCast(intFromFloat(u128, a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __fixunssfti(a: f32) callconv(.C) u128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixunssfti_windows_x86_64(a: f32) callconv(.C) v2u64 { fn __fixunssfti_windows_x86_64(a: f32) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(u128, a)); return @as(v2u64, @bitCast(intFromFloat(u128, a)));
} }

View File

@ -21,5 +21,5 @@ pub fn __fixunstfti(a: f128) callconv(.C) u128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixunstfti_windows_x86_64(a: f128) callconv(.C) v2u64 { fn __fixunstfti_windows_x86_64(a: f128) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(u128, a)); return @as(v2u64, @bitCast(intFromFloat(u128, a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __fixunsxfti(a: f80) callconv(.C) u128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixunsxfti_windows_x86_64(a: f80) callconv(.C) v2u64 { fn __fixunsxfti_windows_x86_64(a: f80) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(u128, a)); return @as(v2u64, @bitCast(intFromFloat(u128, a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __fixxfti(a: f80) callconv(.C) i128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __fixxfti_windows_x86_64(a: f80) callconv(.C) v2u64 { fn __fixxfti_windows_x86_64(a: f80) callconv(.C) v2u64 {
return @bitCast(v2u64, intFromFloat(i128, a)); return @as(v2u64, @bitCast(intFromFloat(i128, a)));
} }

View File

@ -25,17 +25,17 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
// Compute significand // Compute significand
var exp = int_bits - @clz(abs_val) - 1; var exp = int_bits - @clz(abs_val) - 1;
if (int_bits <= fractional_bits or exp <= fractional_bits) { if (int_bits <= fractional_bits or exp <= fractional_bits) {
const shift_amt = fractional_bits - @intCast(math.Log2Int(uT), exp); const shift_amt = fractional_bits - @as(math.Log2Int(uT), @intCast(exp));
// Shift up result to line up with the significand - no rounding required // Shift up result to line up with the significand - no rounding required
result = (@intCast(uT, abs_val) << shift_amt); result = (@as(uT, @intCast(abs_val)) << shift_amt);
result ^= implicit_bit; // Remove implicit integer bit result ^= implicit_bit; // Remove implicit integer bit
} else { } else {
var shift_amt = @intCast(math.Log2Int(Z), exp - fractional_bits); var shift_amt = @as(math.Log2Int(Z), @intCast(exp - fractional_bits));
const exact_tie: bool = @ctz(abs_val) == shift_amt - 1; const exact_tie: bool = @ctz(abs_val) == shift_amt - 1;
// Shift down result and remove implicit integer bit // Shift down result and remove implicit integer bit
result = @intCast(uT, (abs_val >> (shift_amt - 1))) ^ (implicit_bit << 1); result = @as(uT, @intCast((abs_val >> (shift_amt - 1)))) ^ (implicit_bit << 1);
// Round result, including round-to-even for exact ties // Round result, including round-to-even for exact ties
result = ((result + 1) >> 1) & ~@as(uT, @intFromBool(exact_tie)); result = ((result + 1) >> 1) & ~@as(uT, @intFromBool(exact_tie));
@ -43,14 +43,14 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
// Compute exponent // Compute exponent
if ((int_bits > max_exp) and (exp > max_exp)) // If exponent too large, overflow to infinity if ((int_bits > max_exp) and (exp > max_exp)) // If exponent too large, overflow to infinity
return @bitCast(T, sign_bit | @bitCast(uT, inf)); return @as(T, @bitCast(sign_bit | @as(uT, @bitCast(inf))));
result += (@as(uT, exp) + exp_bias) << math.floatMantissaBits(T); result += (@as(uT, exp) + exp_bias) << math.floatMantissaBits(T);
// If the result included a carry, we need to restore the explicit integer bit // If the result included a carry, we need to restore the explicit integer bit
if (T == f80) result |= 1 << fractional_bits; if (T == f80) result |= 1 << fractional_bits;
return @bitCast(T, sign_bit | result); return @as(T, @bitCast(sign_bit | result));
} }
test { test {

View File

@ -30,12 +30,12 @@ const __floatuntitf = @import("floatuntitf.zig").__floatuntitf;
fn test__floatsisf(a: i32, expected: u32) !void { fn test__floatsisf(a: i32, expected: u32) !void {
const r = __floatsisf(a); const r = __floatsisf(a);
try std.testing.expect(@bitCast(u32, r) == expected); try std.testing.expect(@as(u32, @bitCast(r)) == expected);
} }
fn test_one_floatunsisf(a: u32, expected: u32) !void { fn test_one_floatunsisf(a: u32, expected: u32) !void {
const r = __floatunsisf(a); const r = __floatunsisf(a);
try std.testing.expect(@bitCast(u32, r) == expected); try std.testing.expect(@as(u32, @bitCast(r)) == expected);
} }
test "floatsisf" { test "floatsisf" {
@ -43,7 +43,7 @@ test "floatsisf" {
try test__floatsisf(1, 0x3f800000); try test__floatsisf(1, 0x3f800000);
try test__floatsisf(-1, 0xbf800000); try test__floatsisf(-1, 0xbf800000);
try test__floatsisf(0x7FFFFFFF, 0x4f000000); try test__floatsisf(0x7FFFFFFF, 0x4f000000);
try test__floatsisf(@bitCast(i32, @intCast(u32, 0x80000000)), 0xcf000000); try test__floatsisf(@as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 0xcf000000);
} }
test "floatunsisf" { test "floatunsisf" {
@ -72,10 +72,10 @@ test "floatdisf" {
try test__floatdisf(-2, -2.0); try test__floatdisf(-2, -2.0);
try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62); try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
try test__floatdisf(@bitCast(i64, @as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000008000000000))), -0x1.FFFFFEp+62);
try test__floatdisf(@bitCast(i64, @as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000010000000000))), -0x1.FFFFFCp+62);
try test__floatdisf(@bitCast(i64, @as(u64, 0x8000000000000000)), -0x1.000000p+63); try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), -0x1.000000p+63);
try test__floatdisf(@bitCast(i64, @as(u64, 0x8000000000000001)), -0x1.000000p+63); try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), -0x1.000000p+63);
try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50); try test__floatdisf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50); try test__floatdisf(0x0007FB72EA000000, 0x1.FEDCBAp+50);
try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50); try test__floatdisf(0x0007FB72EB000000, 0x1.FEDCBAp+50);
@ -228,17 +228,17 @@ test "floatuntisf" {
try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76); try test__floatuntisf(make_uti(0x0000000000001FED, 0xCBE0000000000000), 0x1.FEDCBEp+76);
// Test overflow to infinity // Test overflow to infinity
try test__floatuntisf(@as(u128, math.maxInt(u128)), @bitCast(f32, math.inf(f32))); try test__floatuntisf(@as(u128, math.maxInt(u128)), @as(f32, @bitCast(math.inf(f32))));
} }
fn test_one_floatsidf(a: i32, expected: u64) !void { fn test_one_floatsidf(a: i32, expected: u64) !void {
const r = __floatsidf(a); const r = __floatsidf(a);
try std.testing.expect(@bitCast(u64, r) == expected); try std.testing.expect(@as(u64, @bitCast(r)) == expected);
} }
fn test_one_floatunsidf(a: u32, expected: u64) !void { fn test_one_floatunsidf(a: u32, expected: u64) !void {
const r = __floatunsidf(a); const r = __floatunsidf(a);
try std.testing.expect(@bitCast(u64, r) == expected); try std.testing.expect(@as(u64, @bitCast(r)) == expected);
} }
test "floatsidf" { test "floatsidf" {
@ -246,15 +246,15 @@ test "floatsidf" {
try test_one_floatsidf(1, 0x3ff0000000000000); try test_one_floatsidf(1, 0x3ff0000000000000);
try test_one_floatsidf(-1, 0xbff0000000000000); try test_one_floatsidf(-1, 0xbff0000000000000);
try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000); try test_one_floatsidf(0x7FFFFFFF, 0x41dfffffffc00000);
try test_one_floatsidf(@bitCast(i32, @intCast(u32, 0x80000000)), 0xc1e0000000000000); try test_one_floatsidf(@as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 0xc1e0000000000000);
} }
test "floatunsidf" { test "floatunsidf" {
try test_one_floatunsidf(0, 0x0000000000000000); try test_one_floatunsidf(0, 0x0000000000000000);
try test_one_floatunsidf(1, 0x3ff0000000000000); try test_one_floatunsidf(1, 0x3ff0000000000000);
try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000); try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000);
try test_one_floatunsidf(@intCast(u32, 0x80000000), 0x41e0000000000000); try test_one_floatunsidf(@as(u32, @intCast(0x80000000)), 0x41e0000000000000);
try test_one_floatunsidf(@intCast(u32, 0xFFFFFFFF), 0x41efffffffe00000); try test_one_floatunsidf(@as(u32, @intCast(0xFFFFFFFF)), 0x41efffffffe00000);
} }
fn test__floatdidf(a: i64, expected: f64) !void { fn test__floatdidf(a: i64, expected: f64) !void {
@ -279,12 +279,12 @@ test "floatdidf" {
try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62); try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62); try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62); try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000008000000000)), -0x1.FFFFFEp+62); try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000008000000000)))), -0x1.FFFFFEp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000000800)), -0x1.FFFFFFFFFFFFEp+62); try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000800)))), -0x1.FFFFFFFFFFFFEp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000010000000000)), -0x1.FFFFFCp+62); try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000010000000000)))), -0x1.FFFFFCp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000001000)), -0x1.FFFFFFFFFFFFCp+62); try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000001000)))), -0x1.FFFFFFFFFFFFCp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000000000)), -0x1.000000p+63); try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000000)))), -0x1.000000p+63);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000000001)), -0x1.000000p+63); // 0x8000000000000001 try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000001)))), -0x1.000000p+63); // 0x8000000000000001
try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50); try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50); try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50); try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
@ -505,7 +505,7 @@ test "floatuntidf" {
fn test__floatsitf(a: i32, expected: u128) !void { fn test__floatsitf(a: i32, expected: u128) !void {
const r = __floatsitf(a); const r = __floatsitf(a);
try std.testing.expect(@bitCast(u128, r) == expected); try std.testing.expect(@as(u128, @bitCast(r)) == expected);
} }
test "floatsitf" { test "floatsitf" {
@ -513,16 +513,16 @@ test "floatsitf" {
try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000); try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000);
try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000); try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000);
try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000); try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000);
try test__floatsitf(@bitCast(i32, @intCast(u32, 0xffffffff)), 0xbfff0000000000000000000000000000); try test__floatsitf(@as(i32, @bitCast(@as(u32, @intCast(0xffffffff)))), 0xbfff0000000000000000000000000000);
try test__floatsitf(@bitCast(i32, @intCast(u32, 0x80000000)), 0xc01e0000000000000000000000000000); try test__floatsitf(@as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 0xc01e0000000000000000000000000000);
} }
fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void { fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
const x = __floatunsitf(a); const x = __floatunsitf(a);
const x_repr = @bitCast(u128, x); const x_repr = @as(u128, @bitCast(x));
const x_hi = @intCast(u64, x_repr >> 64); const x_hi = @as(u64, @intCast(x_repr >> 64));
const x_lo = @truncate(u64, x_repr); const x_lo = @as(u64, @truncate(x_repr));
if (x_hi == expected_hi and x_lo == expected_lo) { if (x_hi == expected_hi and x_lo == expected_lo) {
return; return;
@ -552,9 +552,9 @@ fn test__floatditf(a: i64, expected: f128) !void {
fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void { fn test__floatunditf(a: u64, expected_hi: u64, expected_lo: u64) !void {
const x = __floatunditf(a); const x = __floatunditf(a);
const x_repr = @bitCast(u128, x); const x_repr = @as(u128, @bitCast(x));
const x_hi = @intCast(u64, x_repr >> 64); const x_hi = @as(u64, @intCast(x_repr >> 64));
const x_lo = @truncate(u64, x_repr); const x_lo = @as(u64, @truncate(x_repr));
if (x_hi == expected_hi and x_lo == expected_lo) { if (x_hi == expected_hi and x_lo == expected_lo) {
return; return;
@ -575,10 +575,10 @@ test "floatditf" {
try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0)); try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0));
try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0)); try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0));
try test__floatditf(0x0, make_tf(0x0, 0x0)); try test__floatditf(0x0, make_tf(0x0, 0x0));
try test__floatditf(@bitCast(i64, @as(u64, 0xffffffffffffffff)), make_tf(0xbfff000000000000, 0x0)); try test__floatditf(@as(i64, @bitCast(@as(u64, 0xffffffffffffffff))), make_tf(0xbfff000000000000, 0x0));
try test__floatditf(@bitCast(i64, @as(u64, 0xfffffffffffffffe)), make_tf(0xc000000000000000, 0x0)); try test__floatditf(@as(i64, @bitCast(@as(u64, 0xfffffffffffffffe))), make_tf(0xc000000000000000, 0x0));
try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000)); try test__floatditf(-0x123456789abcdef1, make_tf(0xc03b23456789abcd, 0xef10000000000000));
try test__floatditf(@bitCast(i64, @as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0)); try test__floatditf(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), make_tf(0xc03e000000000000, 0x0));
} }
test "floatunditf" { test "floatunditf" {
@ -773,7 +773,7 @@ fn make_ti(high: u64, low: u64) i128 {
var result: u128 = high; var result: u128 = high;
result <<= 64; result <<= 64;
result |= low; result |= low;
return @bitCast(i128, result); return @as(i128, @bitCast(result));
} }
fn make_uti(high: u64, low: u64) u128 { fn make_uti(high: u64, low: u64) u128 {
@ -787,7 +787,7 @@ fn make_tf(high: u64, low: u64) f128 {
var result: u128 = high; var result: u128 = high;
result <<= 64; result <<= 64;
result |= low; result |= low;
return @bitCast(f128, result); return @as(f128, @bitCast(result));
} }
test "conversion to f16" { test "conversion to f16" {
@ -815,22 +815,22 @@ test "conversion to f80" {
const floatFromInt = @import("./float_from_int.zig").floatFromInt; const floatFromInt = @import("./float_from_int.zig").floatFromInt;
try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12); try testing.expect(floatFromInt(f80, @as(i80, -12)) == -12);
try testing.expect(@intFromFloat(u80, floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0)) == math.maxInt(u64) + 0); try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0);
try testing.expect(@intFromFloat(u80, floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1)) == math.maxInt(u64) + 1); try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1);
try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0); try testing.expect(floatFromInt(f80, @as(u32, 0)) == 0.0);
try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0); try testing.expect(floatFromInt(f80, @as(u32, 1)) == 1.0);
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0)) == math.maxInt(u24)); try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24));
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0)) == math.maxInt(u64)); try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64));
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1)) == math.maxInt(u64) + 1); // Exact try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1))) == math.maxInt(u64) + 1); // Exact
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2)) == math.maxInt(u64) + 1); // Rounds down try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 2))) == math.maxInt(u64) + 1); // Rounds down
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3)) == math.maxInt(u64) + 3); // Tie - Exact try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 3))) == math.maxInt(u64) + 3); // Tie - Exact
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4)) == math.maxInt(u64) + 5); // Rounds up try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 4))) == math.maxInt(u64) + 5); // Rounds up
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0)) == math.maxInt(u65) + 1); // Rounds up try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 0))) == math.maxInt(u65) + 1); // Rounds up
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u65)) + 1)) == math.maxInt(u65) + 1); // Exact try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 1))) == math.maxInt(u65) + 1); // Exact
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u65)) + 2)) == math.maxInt(u65) + 1); // Rounds down try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 2))) == math.maxInt(u65) + 1); // Rounds down
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u65)) + 3)) == math.maxInt(u65) + 1); // Tie - Rounds down try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 3))) == math.maxInt(u65) + 1); // Tie - Rounds down
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u65)) + 4)) == math.maxInt(u65) + 5); // Rounds up try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 4))) == math.maxInt(u65) + 5); // Rounds up
try testing.expect(@intFromFloat(u128, floatFromInt(f80, @as(u80, math.maxInt(u65)) + 5)) == math.maxInt(u65) + 5); // Exact try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u65)) + 5))) == math.maxInt(u65) + 5); // Exact
} }

View File

@ -17,5 +17,5 @@ pub fn __floattidf(a: i128) callconv(.C) f64 {
} }
fn __floattidf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f64 { fn __floattidf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f64 {
return floatFromInt(f64, @bitCast(i128, a)); return floatFromInt(f64, @as(i128, @bitCast(a)));
} }

View File

@ -17,5 +17,5 @@ pub fn __floattihf(a: i128) callconv(.C) f16 {
} }
fn __floattihf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f16 { fn __floattihf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f16 {
return floatFromInt(f16, @bitCast(i128, a)); return floatFromInt(f16, @as(i128, @bitCast(a)));
} }

View File

@ -17,5 +17,5 @@ pub fn __floattisf(a: i128) callconv(.C) f32 {
} }
fn __floattisf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f32 { fn __floattisf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f32 {
return floatFromInt(f32, @bitCast(i128, a)); return floatFromInt(f32, @as(i128, @bitCast(a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __floattitf(a: i128) callconv(.C) f128 {
} }
fn __floattitf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f128 { fn __floattitf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f128 {
return floatFromInt(f128, @bitCast(i128, a)); return floatFromInt(f128, @as(i128, @bitCast(a)));
} }

View File

@ -17,5 +17,5 @@ pub fn __floattixf(a: i128) callconv(.C) f80 {
} }
fn __floattixf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f80 { fn __floattixf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f80 {
return floatFromInt(f80, @bitCast(i128, a)); return floatFromInt(f80, @as(i128, @bitCast(a)));
} }

View File

@ -17,5 +17,5 @@ pub fn __floatuntidf(a: u128) callconv(.C) f64 {
} }
fn __floatuntidf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f64 { fn __floatuntidf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f64 {
return floatFromInt(f64, @bitCast(u128, a)); return floatFromInt(f64, @as(u128, @bitCast(a)));
} }

View File

@ -17,5 +17,5 @@ pub fn __floatuntihf(a: u128) callconv(.C) f16 {
} }
fn __floatuntihf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f16 { fn __floatuntihf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f16 {
return floatFromInt(f16, @bitCast(u128, a)); return floatFromInt(f16, @as(u128, @bitCast(a)));
} }

View File

@ -17,5 +17,5 @@ pub fn __floatuntisf(a: u128) callconv(.C) f32 {
} }
fn __floatuntisf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f32 { fn __floatuntisf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f32 {
return floatFromInt(f32, @bitCast(u128, a)); return floatFromInt(f32, @as(u128, @bitCast(a)));
} }

View File

@ -19,5 +19,5 @@ pub fn __floatuntitf(a: u128) callconv(.C) f128 {
} }
fn __floatuntitf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f128 { fn __floatuntitf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f128 {
return floatFromInt(f128, @bitCast(u128, a)); return floatFromInt(f128, @as(u128, @bitCast(a)));
} }

View File

@ -17,5 +17,5 @@ pub fn __floatuntixf(a: u128) callconv(.C) f80 {
} }
fn __floatuntixf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f80 { fn __floatuntixf_windows_x86_64(a: @Vector(2, u64)) callconv(.C) f80 {
return floatFromInt(f80, @bitCast(u128, a)); return floatFromInt(f80, @as(u128, @bitCast(a)));
} }

View File

@ -26,8 +26,8 @@ comptime {
} }
pub fn __floorh(x: f16) callconv(.C) f16 { pub fn __floorh(x: f16) callconv(.C) f16 {
var u = @bitCast(u16, x); var u = @as(u16, @bitCast(x));
const e = @intCast(i16, (u >> 10) & 31) - 15; const e = @as(i16, @intCast((u >> 10) & 31)) - 15;
var m: u16 = undefined; var m: u16 = undefined;
// TODO: Shouldn't need this explicit check. // TODO: Shouldn't need this explicit check.
@ -40,7 +40,7 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
} }
if (e >= 0) { if (e >= 0) {
m = @as(u16, 1023) >> @intCast(u4, e); m = @as(u16, 1023) >> @as(u4, @intCast(e));
if (u & m == 0) { if (u & m == 0) {
return x; return x;
} }
@ -48,7 +48,7 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
if (u >> 15 != 0) { if (u >> 15 != 0) {
u += m; u += m;
} }
return @bitCast(f16, u & ~m); return @as(f16, @bitCast(u & ~m));
} else { } else {
math.doNotOptimizeAway(x + 0x1.0p120); math.doNotOptimizeAway(x + 0x1.0p120);
if (u >> 15 == 0) { if (u >> 15 == 0) {
@ -60,8 +60,8 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
} }
pub fn floorf(x: f32) callconv(.C) f32 { pub fn floorf(x: f32) callconv(.C) f32 {
var u = @bitCast(u32, x); var u = @as(u32, @bitCast(x));
const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; const e = @as(i32, @intCast((u >> 23) & 0xFF)) - 0x7F;
var m: u32 = undefined; var m: u32 = undefined;
// TODO: Shouldn't need this explicit check. // TODO: Shouldn't need this explicit check.
@ -74,7 +74,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
} }
if (e >= 0) { if (e >= 0) {
m = @as(u32, 0x007FFFFF) >> @intCast(u5, e); m = @as(u32, 0x007FFFFF) >> @as(u5, @intCast(e));
if (u & m == 0) { if (u & m == 0) {
return x; return x;
} }
@ -82,7 +82,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
if (u >> 31 != 0) { if (u >> 31 != 0) {
u += m; u += m;
} }
return @bitCast(f32, u & ~m); return @as(f32, @bitCast(u & ~m));
} else { } else {
math.doNotOptimizeAway(x + 0x1.0p120); math.doNotOptimizeAway(x + 0x1.0p120);
if (u >> 31 == 0) { if (u >> 31 == 0) {
@ -96,7 +96,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
pub fn floor(x: f64) callconv(.C) f64 { pub fn floor(x: f64) callconv(.C) f64 {
const f64_toint = 1.0 / math.floatEps(f64); const f64_toint = 1.0 / math.floatEps(f64);
const u = @bitCast(u64, x); const u = @as(u64, @bitCast(x));
const e = (u >> 52) & 0x7FF; const e = (u >> 52) & 0x7FF;
var y: f64 = undefined; var y: f64 = undefined;
@ -126,13 +126,13 @@ pub fn floor(x: f64) callconv(.C) f64 {
pub fn __floorx(x: f80) callconv(.C) f80 { pub fn __floorx(x: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, floorq(x)); return @as(f80, @floatCast(floorq(x)));
} }
pub fn floorq(x: f128) callconv(.C) f128 { pub fn floorq(x: f128) callconv(.C) f128 {
const f128_toint = 1.0 / math.floatEps(f128); const f128_toint = 1.0 / math.floatEps(f128);
const u = @bitCast(u128, x); const u = @as(u128, @bitCast(x));
const e = (u >> 112) & 0x7FFF; const e = (u >> 112) & 0x7FFF;
var y: f128 = undefined; var y: f128 = undefined;

View File

@ -28,20 +28,20 @@ comptime {
pub fn __fmah(x: f16, y: f16, z: f16) callconv(.C) f16 { pub fn __fmah(x: f16, y: f16, z: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, fmaf(x, y, z)); return @as(f16, @floatCast(fmaf(x, y, z)));
} }
pub fn fmaf(x: f32, y: f32, z: f32) callconv(.C) f32 { pub fn fmaf(x: f32, y: f32, z: f32) callconv(.C) f32 {
const xy = @as(f64, x) * y; const xy = @as(f64, x) * y;
const xy_z = xy + z; const xy_z = xy + z;
const u = @bitCast(u64, xy_z); const u = @as(u64, @bitCast(xy_z));
const e = (u >> 52) & 0x7FF; const e = (u >> 52) & 0x7FF;
if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or (xy_z - xy == z and xy_z - z == xy)) { if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or (xy_z - xy == z and xy_z - z == xy)) {
return @floatCast(f32, xy_z); return @as(f32, @floatCast(xy_z));
} else { } else {
// TODO: Handle inexact case with double-rounding // TODO: Handle inexact case with double-rounding
return @floatCast(f32, xy_z); return @as(f32, @floatCast(xy_z));
} }
} }
@ -95,7 +95,7 @@ pub fn fma(x: f64, y: f64, z: f64) callconv(.C) f64 {
pub fn __fmax(a: f80, b: f80, c: f80) callconv(.C) f80 { pub fn __fmax(a: f80, b: f80, c: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, fmaq(a, b, c)); return @as(f80, @floatCast(fmaq(a, b, c)));
} }
/// Fused multiply-add: Compute x * y + z with a single rounding error. /// Fused multiply-add: Compute x * y + z with a single rounding error.
@ -201,12 +201,12 @@ fn dd_mul(a: f64, b: f64) dd {
fn add_adjusted(a: f64, b: f64) f64 { fn add_adjusted(a: f64, b: f64) f64 {
var sum = dd_add(a, b); var sum = dd_add(a, b);
if (sum.lo != 0) { if (sum.lo != 0) {
var uhii = @bitCast(u64, sum.hi); var uhii = @as(u64, @bitCast(sum.hi));
if (uhii & 1 == 0) { if (uhii & 1 == 0) {
// hibits += copysign(1.0, sum.hi, sum.lo) // hibits += copysign(1.0, sum.hi, sum.lo)
const uloi = @bitCast(u64, sum.lo); const uloi = @as(u64, @bitCast(sum.lo));
uhii += 1 - ((uhii ^ uloi) >> 62); uhii += 1 - ((uhii ^ uloi) >> 62);
sum.hi = @bitCast(f64, uhii); sum.hi = @as(f64, @bitCast(uhii));
} }
} }
return sum.hi; return sum.hi;
@ -215,12 +215,12 @@ fn add_adjusted(a: f64, b: f64) f64 {
fn add_and_denorm(a: f64, b: f64, scale: i32) f64 { fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
var sum = dd_add(a, b); var sum = dd_add(a, b);
if (sum.lo != 0) { if (sum.lo != 0) {
var uhii = @bitCast(u64, sum.hi); var uhii = @as(u64, @bitCast(sum.hi));
const bits_lost = -@intCast(i32, (uhii >> 52) & 0x7FF) - scale + 1; const bits_lost = -@as(i32, @intCast((uhii >> 52) & 0x7FF)) - scale + 1;
if ((bits_lost != 1) == (uhii & 1 != 0)) { if ((bits_lost != 1) == (uhii & 1 != 0)) {
const uloi = @bitCast(u64, sum.lo); const uloi = @as(u64, @bitCast(sum.lo));
uhii += 1 - (((uhii ^ uloi) >> 62) & 2); uhii += 1 - (((uhii ^ uloi) >> 62) & 2);
sum.hi = @bitCast(f64, uhii); sum.hi = @as(f64, @bitCast(uhii));
} }
} }
return math.scalbn(sum.hi, scale); return math.scalbn(sum.hi, scale);
@ -257,12 +257,12 @@ fn dd_add128(a: f128, b: f128) dd128 {
fn add_adjusted128(a: f128, b: f128) f128 { fn add_adjusted128(a: f128, b: f128) f128 {
var sum = dd_add128(a, b); var sum = dd_add128(a, b);
if (sum.lo != 0) { if (sum.lo != 0) {
var uhii = @bitCast(u128, sum.hi); var uhii = @as(u128, @bitCast(sum.hi));
if (uhii & 1 == 0) { if (uhii & 1 == 0) {
// hibits += copysign(1.0, sum.hi, sum.lo) // hibits += copysign(1.0, sum.hi, sum.lo)
const uloi = @bitCast(u128, sum.lo); const uloi = @as(u128, @bitCast(sum.lo));
uhii += 1 - ((uhii ^ uloi) >> 126); uhii += 1 - ((uhii ^ uloi) >> 126);
sum.hi = @bitCast(f128, uhii); sum.hi = @as(f128, @bitCast(uhii));
} }
} }
return sum.hi; return sum.hi;
@ -282,12 +282,12 @@ fn add_and_denorm128(a: f128, b: f128, scale: i32) f128 {
// If we are losing only one bit to denormalization, however, we must // If we are losing only one bit to denormalization, however, we must
// break the ties manually. // break the ties manually.
if (sum.lo != 0) { if (sum.lo != 0) {
var uhii = @bitCast(u128, sum.hi); var uhii = @as(u128, @bitCast(sum.hi));
const bits_lost = -@intCast(i32, (uhii >> 112) & 0x7FFF) - scale + 1; const bits_lost = -@as(i32, @intCast((uhii >> 112) & 0x7FFF)) - scale + 1;
if ((bits_lost != 1) == (uhii & 1 != 0)) { if ((bits_lost != 1) == (uhii & 1 != 0)) {
const uloi = @bitCast(u128, sum.lo); const uloi = @as(u128, @bitCast(sum.lo));
uhii += 1 - (((uhii ^ uloi) >> 126) & 2); uhii += 1 - (((uhii ^ uloi) >> 126) & 2);
sum.hi = @bitCast(f128, uhii); sum.hi = @as(f128, @bitCast(uhii));
} }
} }
return math.scalbn(sum.hi, scale); return math.scalbn(sum.hi, scale);

View File

@ -22,7 +22,7 @@ comptime {
pub fn __fmodh(x: f16, y: f16) callconv(.C) f16 { pub fn __fmodh(x: f16, y: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, fmodf(x, y)); return @as(f16, @floatCast(fmodf(x, y)));
} }
pub fn fmodf(x: f32, y: f32) callconv(.C) f32 { pub fn fmodf(x: f32, y: f32) callconv(.C) f32 {
@ -46,12 +46,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
const signBit = (@as(Z, 1) << (significandBits + exponentBits)); const signBit = (@as(Z, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1); const maxExponent = ((1 << exponentBits) - 1);
var aRep = @bitCast(Z, a); var aRep = @as(Z, @bitCast(a));
var bRep = @bitCast(Z, b); var bRep = @as(Z, @bitCast(b));
const signA = aRep & signBit; const signA = aRep & signBit;
var expA = @intCast(i32, (@bitCast(Z, a) >> significandBits) & maxExponent); var expA = @as(i32, @intCast((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
var expB = @intCast(i32, (@bitCast(Z, b) >> significandBits) & maxExponent); var expB = @as(i32, @intCast((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
// There are 3 cases where the answer is undefined, check for: // There are 3 cases where the answer is undefined, check for:
// - fmodx(val, 0) // - fmodx(val, 0)
@ -82,8 +82,8 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
var highA: u64 = 0; var highA: u64 = 0;
var highB: u64 = 0; var highB: u64 = 0;
var lowA: u64 = @truncate(u64, aRep); var lowA: u64 = @as(u64, @truncate(aRep));
var lowB: u64 = @truncate(u64, bRep); var lowB: u64 = @as(u64, @truncate(bRep));
while (expA > expB) : (expA -= 1) { while (expA > expB) : (expA -= 1) {
var high = highA -% highB; var high = highA -% highB;
@ -123,11 +123,11 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
// Combine the exponent with the sign and significand, normalize if happened to be denormalized // Combine the exponent with the sign and significand, normalize if happened to be denormalized
if (expA < -fractionalBits) { if (expA < -fractionalBits) {
return @bitCast(T, signA); return @as(T, @bitCast(signA));
} else if (expA <= 0) { } else if (expA <= 0) {
return @bitCast(T, (lowA >> @intCast(math.Log2Int(u64), 1 - expA)) | signA); return @as(T, @bitCast((lowA >> @as(math.Log2Int(u64), @intCast(1 - expA))) | signA));
} else { } else {
return @bitCast(T, lowA | (@as(Z, @intCast(u16, expA)) << significandBits) | signA); return @as(T, @bitCast(lowA | (@as(Z, @as(u16, @intCast(expA))) << significandBits) | signA));
} }
} }
@ -136,10 +136,10 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
pub fn fmodq(a: f128, b: f128) callconv(.C) f128 { pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
var amod = a; var amod = a;
var bmod = b; var bmod = b;
const aPtr_u64 = @ptrCast([*]u64, &amod); const aPtr_u64 = @as([*]u64, @ptrCast(&amod));
const bPtr_u64 = @ptrCast([*]u64, &bmod); const bPtr_u64 = @as([*]u64, @ptrCast(&bmod));
const aPtr_u16 = @ptrCast([*]u16, &amod); const aPtr_u16 = @as([*]u16, @ptrCast(&amod));
const bPtr_u16 = @ptrCast([*]u16, &bmod); const bPtr_u16 = @as([*]u16, @ptrCast(&bmod));
const exp_and_sign_index = comptime switch (builtin.target.cpu.arch.endian()) { const exp_and_sign_index = comptime switch (builtin.target.cpu.arch.endian()) {
.Little => 7, .Little => 7,
@ -155,8 +155,8 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
}; };
const signA = aPtr_u16[exp_and_sign_index] & 0x8000; const signA = aPtr_u16[exp_and_sign_index] & 0x8000;
var expA = @intCast(i32, (aPtr_u16[exp_and_sign_index] & 0x7fff)); var expA = @as(i32, @intCast((aPtr_u16[exp_and_sign_index] & 0x7fff)));
var expB = @intCast(i32, (bPtr_u16[exp_and_sign_index] & 0x7fff)); var expB = @as(i32, @intCast((bPtr_u16[exp_and_sign_index] & 0x7fff)));
// There are 3 cases where the answer is undefined, check for: // There are 3 cases where the answer is undefined, check for:
// - fmodq(val, 0) // - fmodq(val, 0)
@ -173,8 +173,8 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
} }
// Remove the sign from both // Remove the sign from both
aPtr_u16[exp_and_sign_index] = @bitCast(u16, @intCast(i16, expA)); aPtr_u16[exp_and_sign_index] = @as(u16, @bitCast(@as(i16, @intCast(expA))));
bPtr_u16[exp_and_sign_index] = @bitCast(u16, @intCast(i16, expB)); bPtr_u16[exp_and_sign_index] = @as(u16, @bitCast(@as(i16, @intCast(expB))));
if (amod <= bmod) { if (amod <= bmod) {
if (amod == bmod) { if (amod == bmod) {
return 0 * a; return 0 * a;
@ -241,10 +241,10 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
// Combine the exponent with the sign, normalize if happend to be denormalized // Combine the exponent with the sign, normalize if happend to be denormalized
if (expA <= 0) { if (expA <= 0) {
aPtr_u16[exp_and_sign_index] = @truncate(u16, @bitCast(u32, (expA +% 120))) | signA; aPtr_u16[exp_and_sign_index] = @as(u16, @truncate(@as(u32, @bitCast((expA +% 120))))) | signA;
amod *= 0x1p-120; amod *= 0x1p-120;
} else { } else {
aPtr_u16[exp_and_sign_index] = @truncate(u16, @bitCast(u32, expA)) | signA; aPtr_u16[exp_and_sign_index] = @as(u16, @truncate(@as(u32, @bitCast(expA)))) | signA;
} }
return amod; return amod;
@ -270,14 +270,14 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
const exp_bits = if (T == f32) 9 else 12; const exp_bits = if (T == f32) 9 else 12;
const bits_minus_1 = bits - 1; const bits_minus_1 = bits - 1;
const mask = if (T == f32) 0xff else 0x7ff; const mask = if (T == f32) 0xff else 0x7ff;
var ux = @bitCast(uint, x); var ux = @as(uint, @bitCast(x));
var uy = @bitCast(uint, y); var uy = @as(uint, @bitCast(y));
var ex = @intCast(i32, (ux >> digits) & mask); var ex = @as(i32, @intCast((ux >> digits) & mask));
var ey = @intCast(i32, (uy >> digits) & mask); var ey = @as(i32, @intCast((uy >> digits) & mask));
const sx = if (T == f32) @intCast(u32, ux & 0x80000000) else @intCast(i32, ux >> bits_minus_1); const sx = if (T == f32) @as(u32, @intCast(ux & 0x80000000)) else @as(i32, @intCast(ux >> bits_minus_1));
var i: uint = undefined; var i: uint = undefined;
if (uy << 1 == 0 or math.isNan(@bitCast(T, uy)) or ex == mask) if (uy << 1 == 0 or math.isNan(@as(T, @bitCast(uy))) or ex == mask)
return (x * y) / (x * y); return (x * y) / (x * y);
if (ux << 1 <= uy << 1) { if (ux << 1 <= uy << 1) {
@ -293,7 +293,7 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
ex -= 1; ex -= 1;
i <<= 1; i <<= 1;
}) {} }) {}
ux <<= @intCast(log2uint, @bitCast(u32, -ex + 1)); ux <<= @as(log2uint, @intCast(@as(u32, @bitCast(-ex + 1))));
} else { } else {
ux &= math.maxInt(uint) >> exp_bits; ux &= math.maxInt(uint) >> exp_bits;
ux |= 1 << digits; ux |= 1 << digits;
@ -304,7 +304,7 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
ey -= 1; ey -= 1;
i <<= 1; i <<= 1;
}) {} }) {}
uy <<= @intCast(log2uint, @bitCast(u32, -ey + 1)); uy <<= @as(log2uint, @intCast(@as(u32, @bitCast(-ey + 1))));
} else { } else {
uy &= math.maxInt(uint) >> exp_bits; uy &= math.maxInt(uint) >> exp_bits;
uy |= 1 << digits; uy |= 1 << digits;
@ -334,16 +334,16 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
// scale result up // scale result up
if (ex > 0) { if (ex > 0) {
ux -%= 1 << digits; ux -%= 1 << digits;
ux |= @as(uint, @bitCast(u32, ex)) << digits; ux |= @as(uint, @as(u32, @bitCast(ex))) << digits;
} else { } else {
ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1)); ux >>= @as(log2uint, @intCast(@as(u32, @bitCast(-ex + 1))));
} }
if (T == f32) { if (T == f32) {
ux |= sx; ux |= sx;
} else { } else {
ux |= @intCast(uint, sx) << bits_minus_1; ux |= @as(uint, @intCast(sx)) << bits_minus_1;
} }
return @bitCast(T, ux); return @as(T, @bitCast(ux));
} }
test "fmodf" { test "fmodf" {

View File

@ -52,8 +52,8 @@ test "test_divmodti4" {
[_]i128{ -7, 5, -1, -2 }, [_]i128{ -7, 5, -1, -2 },
[_]i128{ 19, 5, 3, 4 }, [_]i128{ 19, 5, 3, 4 },
[_]i128{ 19, -5, -3, 4 }, [_]i128{ 19, -5, -3, 4 },
[_]i128{ @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 8, @bitCast(i128, @as(u128, 0xf0000000000000000000000000000000)), 0 }, [_]i128{ @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 8, @as(i128, @bitCast(@as(u128, 0xf0000000000000000000000000000000))), 0 },
[_]i128{ @bitCast(i128, @as(u128, 0x80000000000000000000000000000007)), 8, @bitCast(i128, @as(u128, 0xf0000000000000000000000000000001)), -1 }, [_]i128{ @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000007))), 8, @as(i128, @bitCast(@as(u128, 0xf0000000000000000000000000000001))), -1 },
}; };
for (cases) |case| { for (cases) |case| {
@ -85,8 +85,8 @@ test "test_divmoddi4" {
[_]i64{ -7, 5, -1, -2 }, [_]i64{ -7, 5, -1, -2 },
[_]i64{ 19, 5, 3, 4 }, [_]i64{ 19, 5, 3, 4 },
[_]i64{ 19, -5, -3, 4 }, [_]i64{ 19, -5, -3, 4 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 8, @bitCast(i64, @as(u64, 0xf000000000000000)), 0 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000007)), 8, @bitCast(i64, @as(u64, 0xf000000000000001)), -1 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },
}; };
for (cases) |case| { for (cases) |case| {
@ -110,14 +110,14 @@ test "test_udivmoddi4" {
pub fn __divdi3(a: i64, b: i64) callconv(.C) i64 { pub fn __divdi3(a: i64, b: i64) callconv(.C) i64 {
// Set aside the sign of the quotient. // Set aside the sign of the quotient.
const sign = @bitCast(u64, (a ^ b) >> 63); const sign = @as(u64, @bitCast((a ^ b) >> 63));
// Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63). // Take absolute value of a and b via abs(x) = (x^(x >> 63)) - (x >> 63).
const abs_a = (a ^ (a >> 63)) -% (a >> 63); const abs_a = (a ^ (a >> 63)) -% (a >> 63);
const abs_b = (b ^ (b >> 63)) -% (b >> 63); const abs_b = (b ^ (b >> 63)) -% (b >> 63);
// Unsigned division // Unsigned division
const res = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), null); const res = __udivmoddi4(@as(u64, @bitCast(abs_a)), @as(u64, @bitCast(abs_b)), null);
// Apply sign of quotient to result and return. // Apply sign of quotient to result and return.
return @bitCast(i64, (res ^ sign) -% sign); return @as(i64, @bitCast((res ^ sign) -% sign));
} }
test "test_divdi3" { test "test_divdi3" {
@ -129,10 +129,10 @@ test "test_divdi3" {
[_]i64{ -2, 1, -2 }, [_]i64{ -2, 1, -2 },
[_]i64{ -2, -1, 2 }, [_]i64{ -2, -1, 2 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)) }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)) }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0x4000000000000000 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, 0x4000000000000000 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0xC000000000000000)) }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, @as(i64, @bitCast(@as(u64, 0xC000000000000000))) },
}; };
for (cases) |case| { for (cases) |case| {
@ -151,9 +151,9 @@ pub fn __moddi3(a: i64, b: i64) callconv(.C) i64 {
const abs_b = (b ^ (b >> 63)) -% (b >> 63); const abs_b = (b ^ (b >> 63)) -% (b >> 63);
// Unsigned division // Unsigned division
var r: u64 = undefined; var r: u64 = undefined;
_ = __udivmoddi4(@bitCast(u64, abs_a), @bitCast(u64, abs_b), &r); _ = __udivmoddi4(@as(u64, @bitCast(abs_a)), @as(u64, @bitCast(abs_b)), &r);
// Apply the sign of the dividend and return. // Apply the sign of the dividend and return.
return (@bitCast(i64, r) ^ (a >> 63)) -% (a >> 63); return (@as(i64, @bitCast(r)) ^ (a >> 63)) -% (a >> 63);
} }
test "test_moddi3" { test "test_moddi3" {
@ -165,12 +165,12 @@ test "test_moddi3" {
[_]i64{ -5, 3, -2 }, [_]i64{ -5, 3, -2 },
[_]i64{ -5, -3, -2 }, [_]i64{ -5, -3, -2 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, 0 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, 0 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, 0 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 3, -2 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 3, -2 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -3, -2 }, [_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -3, -2 },
}; };
for (cases) |case| { for (cases) |case| {
@ -225,8 +225,8 @@ test "test_divmodsi4" {
[_]i32{ 19, 5, 3, 4 }, [_]i32{ 19, 5, 3, 4 },
[_]i32{ 19, -5, -3, 4 }, [_]i32{ 19, -5, -3, 4 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 8, @bitCast(i32, @as(u32, 0xf0000000)), 0 }, [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 8, @as(i32, @bitCast(@as(u32, 0xf0000000))), 0 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000007)), 8, @bitCast(i32, @as(u32, 0xf0000001)), -1 }, [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000007))), 8, @as(i32, @bitCast(@as(u32, 0xf0000001))), -1 },
}; };
for (cases) |case| { for (cases) |case| {
@ -242,7 +242,7 @@ fn test_one_divmodsi4(a: i32, b: i32, expected_q: i32, expected_r: i32) !void {
pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 { pub fn __udivmodsi4(a: u32, b: u32, rem: *u32) callconv(.C) u32 {
const d = __udivsi3(a, b); const d = __udivsi3(a, b);
rem.* = @bitCast(u32, @bitCast(i32, a) -% (@bitCast(i32, d) * @bitCast(i32, b))); rem.* = @as(u32, @bitCast(@as(i32, @bitCast(a)) -% (@as(i32, @bitCast(d)) * @as(i32, @bitCast(b)))));
return d; return d;
} }
@ -256,14 +256,14 @@ fn __aeabi_idiv(n: i32, d: i32) callconv(.AAPCS) i32 {
inline fn div_i32(n: i32, d: i32) i32 { inline fn div_i32(n: i32, d: i32) i32 {
// Set aside the sign of the quotient. // Set aside the sign of the quotient.
const sign = @bitCast(u32, (n ^ d) >> 31); const sign = @as(u32, @bitCast((n ^ d) >> 31));
// Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
const abs_n = (n ^ (n >> 31)) -% (n >> 31); const abs_n = (n ^ (n >> 31)) -% (n >> 31);
const abs_d = (d ^ (d >> 31)) -% (d >> 31); const abs_d = (d ^ (d >> 31)) -% (d >> 31);
// abs(a) / abs(b) // abs(a) / abs(b)
const res = @bitCast(u32, abs_n) / @bitCast(u32, abs_d); const res = @as(u32, @bitCast(abs_n)) / @as(u32, @bitCast(abs_d));
// Apply sign of quotient to result and return. // Apply sign of quotient to result and return.
return @bitCast(i32, (res ^ sign) -% sign); return @as(i32, @bitCast((res ^ sign) -% sign));
} }
test "test_divsi3" { test "test_divsi3" {
@ -275,10 +275,10 @@ test "test_divsi3" {
[_]i32{ -2, 1, -2 }, [_]i32{ -2, 1, -2 },
[_]i32{ -2, -1, 2 }, [_]i32{ -2, -1, 2 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)) }, [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 1, @as(i32, @bitCast(@as(u32, 0x80000000))) },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)) }, [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), -1, @as(i32, @bitCast(@as(u32, 0x80000000))) },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -2, 0x40000000 }, [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), -2, 0x40000000 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0xC0000000)) }, [_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 2, @as(i32, @bitCast(@as(u32, 0xC0000000))) },
}; };
for (cases) |case| { for (cases) |case| {
@ -304,7 +304,7 @@ inline fn div_u32(n: u32, d: u32) u32 {
// special cases // special cases
if (d == 0) return 0; // ?! if (d == 0) return 0; // ?!
if (n == 0) return 0; if (n == 0) return 0;
var sr = @bitCast(c_uint, @as(c_int, @clz(d)) - @as(c_int, @clz(n))); var sr = @as(c_uint, @bitCast(@as(c_int, @clz(d)) - @as(c_int, @clz(n))));
// 0 <= sr <= n_uword_bits - 1 or sr large // 0 <= sr <= n_uword_bits - 1 or sr large
if (sr > n_uword_bits - 1) { if (sr > n_uword_bits - 1) {
// d > r // d > r
@ -317,12 +317,12 @@ inline fn div_u32(n: u32, d: u32) u32 {
sr += 1; sr += 1;
// 1 <= sr <= n_uword_bits - 1 // 1 <= sr <= n_uword_bits - 1
// Not a special case // Not a special case
var q: u32 = n << @intCast(u5, n_uword_bits - sr); var q: u32 = n << @as(u5, @intCast(n_uword_bits - sr));
var r: u32 = n >> @intCast(u5, sr); var r: u32 = n >> @as(u5, @intCast(sr));
var carry: u32 = 0; var carry: u32 = 0;
while (sr > 0) : (sr -= 1) { while (sr > 0) : (sr -= 1) {
// r:q = ((r:q) << 1) | carry // r:q = ((r:q) << 1) | carry
r = (r << 1) | (q >> @intCast(u5, n_uword_bits - 1)); r = (r << 1) | (q >> @as(u5, @intCast(n_uword_bits - 1)));
q = (q << 1) | carry; q = (q << 1) | carry;
// carry = 0; // carry = 0;
// if (r.all >= d.all) // if (r.all >= d.all)
@ -330,9 +330,9 @@ inline fn div_u32(n: u32, d: u32) u32 {
// r.all -= d.all; // r.all -= d.all;
// carry = 1; // carry = 1;
// } // }
const s = @bitCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1); const s = @as(i32, @bitCast(d -% r -% 1)) >> @as(u5, @intCast(n_uword_bits - 1));
carry = @intCast(u32, s & 1); carry = @as(u32, @intCast(s & 1));
r -= d & @bitCast(u32, s); r -= d & @as(u32, @bitCast(s));
} }
q = (q << 1) | carry; q = (q << 1) | carry;
return q; return q;
@ -496,11 +496,11 @@ test "test_modsi3" {
[_]i32{ 5, -3, 2 }, [_]i32{ 5, -3, 2 },
[_]i32{ -5, 3, -2 }, [_]i32{ -5, 3, -2 },
[_]i32{ -5, -3, -2 }, [_]i32{ -5, -3, -2 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0 }, [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 1, 0x0 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0 }, [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 2, 0x0 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0 }, [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), -2, 0x0 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 3, -2 }, [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 3, -2 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -3, -2 }, [_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), -3, -2 },
}; };
for (cases) |case| { for (cases) |case| {

View File

@ -17,9 +17,9 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
const sig_mask = (@as(rep_t, 1) << sig_bits) - 1; const sig_mask = (@as(rep_t, 1) << sig_bits) - 1;
// Break a into sign, exponent, significand // Break a into sign, exponent, significand
const a_rep: rep_t = @bitCast(rep_t, a); const a_rep: rep_t = @as(rep_t, @bitCast(a));
const negative = (a_rep >> (float_bits - 1)) != 0; const negative = (a_rep >> (float_bits - 1)) != 0;
const exponent = @intCast(i32, (a_rep << 1) >> (sig_bits + 1)) - exp_bias; const exponent = @as(i32, @intCast((a_rep << 1) >> (sig_bits + 1))) - exp_bias;
const significand: rep_t = (a_rep & sig_mask) | implicit_bit; const significand: rep_t = (a_rep & sig_mask) | implicit_bit;
// If the exponent is negative, the result rounds to zero. // If the exponent is negative, the result rounds to zero.
@ -29,9 +29,9 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
switch (@typeInfo(I).Int.signedness) { switch (@typeInfo(I).Int.signedness) {
.unsigned => { .unsigned => {
if (negative) return 0; if (negative) return 0;
if (@intCast(c_uint, exponent) >= @min(int_bits, max_exp)) return math.maxInt(I); if (@as(c_uint, @intCast(exponent)) >= @min(int_bits, max_exp)) return math.maxInt(I);
}, },
.signed => if (@intCast(c_uint, exponent) >= @min(int_bits - 1, max_exp)) { .signed => if (@as(c_uint, @intCast(exponent)) >= @min(int_bits - 1, max_exp)) {
return if (negative) math.minInt(I) else math.maxInt(I); return if (negative) math.minInt(I) else math.maxInt(I);
}, },
} }
@ -40,9 +40,9 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
// Otherwise, shift left. // Otherwise, shift left.
var result: I = undefined; var result: I = undefined;
if (exponent < fractional_bits) { if (exponent < fractional_bits) {
result = @intCast(I, significand >> @intCast(Log2Int(rep_t), fractional_bits - exponent)); result = @as(I, @intCast(significand >> @as(Log2Int(rep_t), @intCast(fractional_bits - exponent))));
} else { } else {
result = @intCast(I, significand) << @intCast(Log2Int(I), exponent - fractional_bits); result = @as(I, @intCast(significand)) << @as(Log2Int(I), @intCast(exponent - fractional_bits));
} }
if ((@typeInfo(I).Int.signedness == .signed) and negative) if ((@typeInfo(I).Int.signedness == .signed) and negative)

View File

@ -27,7 +27,7 @@ comptime {
pub fn __logh(a: f16) callconv(.C) f16 { pub fn __logh(a: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, logf(a)); return @as(f16, @floatCast(logf(a)));
} }
pub fn logf(x_: f32) callconv(.C) f32 { pub fn logf(x_: f32) callconv(.C) f32 {
@ -39,7 +39,7 @@ pub fn logf(x_: f32) callconv(.C) f32 {
const Lg4: f32 = 0xf89e26.0p-26; const Lg4: f32 = 0xf89e26.0p-26;
var x = x_; var x = x_;
var ix = @bitCast(u32, x); var ix = @as(u32, @bitCast(x));
var k: i32 = 0; var k: i32 = 0;
// x < 2^(-126) // x < 2^(-126)
@ -56,7 +56,7 @@ pub fn logf(x_: f32) callconv(.C) f32 {
// subnormal, scale x // subnormal, scale x
k -= 25; k -= 25;
x *= 0x1.0p25; x *= 0x1.0p25;
ix = @bitCast(u32, x); ix = @as(u32, @bitCast(x));
} else if (ix >= 0x7F800000) { } else if (ix >= 0x7F800000) {
return x; return x;
} else if (ix == 0x3F800000) { } else if (ix == 0x3F800000) {
@ -65,9 +65,9 @@ pub fn logf(x_: f32) callconv(.C) f32 {
// x into [sqrt(2) / 2, sqrt(2)] // x into [sqrt(2) / 2, sqrt(2)]
ix += 0x3F800000 - 0x3F3504F3; ix += 0x3F800000 - 0x3F3504F3;
k += @intCast(i32, ix >> 23) - 0x7F; k += @as(i32, @intCast(ix >> 23)) - 0x7F;
ix = (ix & 0x007FFFFF) + 0x3F3504F3; ix = (ix & 0x007FFFFF) + 0x3F3504F3;
x = @bitCast(f32, ix); x = @as(f32, @bitCast(ix));
const f = x - 1.0; const f = x - 1.0;
const s = f / (2.0 + f); const s = f / (2.0 + f);
@ -77,7 +77,7 @@ pub fn logf(x_: f32) callconv(.C) f32 {
const t2 = z * (Lg1 + w * Lg3); const t2 = z * (Lg1 + w * Lg3);
const R = t2 + t1; const R = t2 + t1;
const hfsq = 0.5 * f * f; const hfsq = 0.5 * f * f;
const dk = @floatFromInt(f32, k); const dk = @as(f32, @floatFromInt(k));
return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
} }
@ -94,8 +94,8 @@ pub fn log(x_: f64) callconv(.C) f64 {
const Lg7: f64 = 1.479819860511658591e-01; const Lg7: f64 = 1.479819860511658591e-01;
var x = x_; var x = x_;
var ix = @bitCast(u64, x); var ix = @as(u64, @bitCast(x));
var hx = @intCast(u32, ix >> 32); var hx = @as(u32, @intCast(ix >> 32));
var k: i32 = 0; var k: i32 = 0;
if (hx < 0x00100000 or hx >> 31 != 0) { if (hx < 0x00100000 or hx >> 31 != 0) {
@ -111,7 +111,7 @@ pub fn log(x_: f64) callconv(.C) f64 {
// subnormal, scale x // subnormal, scale x
k -= 54; k -= 54;
x *= 0x1.0p54; x *= 0x1.0p54;
hx = @intCast(u32, @bitCast(u64, ix) >> 32); hx = @as(u32, @intCast(@as(u64, @bitCast(ix)) >> 32));
} else if (hx >= 0x7FF00000) { } else if (hx >= 0x7FF00000) {
return x; return x;
} else if (hx == 0x3FF00000 and ix << 32 == 0) { } else if (hx == 0x3FF00000 and ix << 32 == 0) {
@ -120,10 +120,10 @@ pub fn log(x_: f64) callconv(.C) f64 {
// x into [sqrt(2) / 2, sqrt(2)] // x into [sqrt(2) / 2, sqrt(2)]
hx += 0x3FF00000 - 0x3FE6A09E; hx += 0x3FF00000 - 0x3FE6A09E;
k += @intCast(i32, hx >> 20) - 0x3FF; k += @as(i32, @intCast(hx >> 20)) - 0x3FF;
hx = (hx & 0x000FFFFF) + 0x3FE6A09E; hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF); ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
x = @bitCast(f64, ix); x = @as(f64, @bitCast(ix));
const f = x - 1.0; const f = x - 1.0;
const hfsq = 0.5 * f * f; const hfsq = 0.5 * f * f;
@ -133,19 +133,19 @@ pub fn log(x_: f64) callconv(.C) f64 {
const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); const t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
const R = t2 + t1; const R = t2 + t1;
const dk = @floatFromInt(f64, k); const dk = @as(f64, @floatFromInt(k));
return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
} }
pub fn __logx(a: f80) callconv(.C) f80 { pub fn __logx(a: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, logq(a)); return @as(f80, @floatCast(logq(a)));
} }
pub fn logq(a: f128) callconv(.C) f128 { pub fn logq(a: f128) callconv(.C) f128 {
// TODO: more correct implementation // TODO: more correct implementation
return log(@floatCast(f64, a)); return log(@as(f64, @floatCast(a)));
} }
pub fn logl(x: c_longdouble) callconv(.C) c_longdouble { pub fn logl(x: c_longdouble) callconv(.C) c_longdouble {

View File

@ -28,7 +28,7 @@ comptime {
pub fn __log10h(a: f16) callconv(.C) f16 { pub fn __log10h(a: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, log10f(a)); return @as(f16, @floatCast(log10f(a)));
} }
pub fn log10f(x_: f32) callconv(.C) f32 { pub fn log10f(x_: f32) callconv(.C) f32 {
@ -42,7 +42,7 @@ pub fn log10f(x_: f32) callconv(.C) f32 {
const Lg4: f32 = 0xf89e26.0p-26; const Lg4: f32 = 0xf89e26.0p-26;
var x = x_; var x = x_;
var u = @bitCast(u32, x); var u = @as(u32, @bitCast(x));
var ix = u; var ix = u;
var k: i32 = 0; var k: i32 = 0;
@ -59,7 +59,7 @@ pub fn log10f(x_: f32) callconv(.C) f32 {
k -= 25; k -= 25;
x *= 0x1.0p25; x *= 0x1.0p25;
ix = @bitCast(u32, x); ix = @as(u32, @bitCast(x));
} else if (ix >= 0x7F800000) { } else if (ix >= 0x7F800000) {
return x; return x;
} else if (ix == 0x3F800000) { } else if (ix == 0x3F800000) {
@ -68,9 +68,9 @@ pub fn log10f(x_: f32) callconv(.C) f32 {
// x into [sqrt(2) / 2, sqrt(2)] // x into [sqrt(2) / 2, sqrt(2)]
ix += 0x3F800000 - 0x3F3504F3; ix += 0x3F800000 - 0x3F3504F3;
k += @intCast(i32, ix >> 23) - 0x7F; k += @as(i32, @intCast(ix >> 23)) - 0x7F;
ix = (ix & 0x007FFFFF) + 0x3F3504F3; ix = (ix & 0x007FFFFF) + 0x3F3504F3;
x = @bitCast(f32, ix); x = @as(f32, @bitCast(ix));
const f = x - 1.0; const f = x - 1.0;
const s = f / (2.0 + f); const s = f / (2.0 + f);
@ -82,11 +82,11 @@ pub fn log10f(x_: f32) callconv(.C) f32 {
const hfsq = 0.5 * f * f; const hfsq = 0.5 * f * f;
var hi = f - hfsq; var hi = f - hfsq;
u = @bitCast(u32, hi); u = @as(u32, @bitCast(hi));
u &= 0xFFFFF000; u &= 0xFFFFF000;
hi = @bitCast(f32, u); hi = @as(f32, @bitCast(u));
const lo = f - hi - hfsq + s * (hfsq + R); const lo = f - hi - hfsq + s * (hfsq + R);
const dk = @floatFromInt(f32, k); const dk = @as(f32, @floatFromInt(k));
return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
} }
@ -105,8 +105,8 @@ pub fn log10(x_: f64) callconv(.C) f64 {
const Lg7: f64 = 1.479819860511658591e-01; const Lg7: f64 = 1.479819860511658591e-01;
var x = x_; var x = x_;
var ix = @bitCast(u64, x); var ix = @as(u64, @bitCast(x));
var hx = @intCast(u32, ix >> 32); var hx = @as(u32, @intCast(ix >> 32));
var k: i32 = 0; var k: i32 = 0;
if (hx < 0x00100000 or hx >> 31 != 0) { if (hx < 0x00100000 or hx >> 31 != 0) {
@ -122,7 +122,7 @@ pub fn log10(x_: f64) callconv(.C) f64 {
// subnormal, scale x // subnormal, scale x
k -= 54; k -= 54;
x *= 0x1.0p54; x *= 0x1.0p54;
hx = @intCast(u32, @bitCast(u64, x) >> 32); hx = @as(u32, @intCast(@as(u64, @bitCast(x)) >> 32));
} else if (hx >= 0x7FF00000) { } else if (hx >= 0x7FF00000) {
return x; return x;
} else if (hx == 0x3FF00000 and ix << 32 == 0) { } else if (hx == 0x3FF00000 and ix << 32 == 0) {
@ -131,10 +131,10 @@ pub fn log10(x_: f64) callconv(.C) f64 {
// x into [sqrt(2) / 2, sqrt(2)] // x into [sqrt(2) / 2, sqrt(2)]
hx += 0x3FF00000 - 0x3FE6A09E; hx += 0x3FF00000 - 0x3FE6A09E;
k += @intCast(i32, hx >> 20) - 0x3FF; k += @as(i32, @intCast(hx >> 20)) - 0x3FF;
hx = (hx & 0x000FFFFF) + 0x3FE6A09E; hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF); ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
x = @bitCast(f64, ix); x = @as(f64, @bitCast(ix));
const f = x - 1.0; const f = x - 1.0;
const hfsq = 0.5 * f * f; const hfsq = 0.5 * f * f;
@ -147,14 +147,14 @@ pub fn log10(x_: f64) callconv(.C) f64 {
// hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f) // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)
var hi = f - hfsq; var hi = f - hfsq;
var hii = @bitCast(u64, hi); var hii = @as(u64, @bitCast(hi));
hii &= @as(u64, maxInt(u64)) << 32; hii &= @as(u64, maxInt(u64)) << 32;
hi = @bitCast(f64, hii); hi = @as(f64, @bitCast(hii));
const lo = f - hi - hfsq + s * (hfsq + R); const lo = f - hi - hfsq + s * (hfsq + R);
// val_hi + val_lo ~ log10(1 + f) + k * log10(2) // val_hi + val_lo ~ log10(1 + f) + k * log10(2)
var val_hi = hi * ivln10hi; var val_hi = hi * ivln10hi;
const dk = @floatFromInt(f64, k); const dk = @as(f64, @floatFromInt(k));
const y = dk * log10_2hi; const y = dk * log10_2hi;
var val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi; var val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi;
@ -168,12 +168,12 @@ pub fn log10(x_: f64) callconv(.C) f64 {
pub fn __log10x(a: f80) callconv(.C) f80 { pub fn __log10x(a: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, log10q(a)); return @as(f80, @floatCast(log10q(a)));
} }
pub fn log10q(a: f128) callconv(.C) f128 { pub fn log10q(a: f128) callconv(.C) f128 {
// TODO: more correct implementation // TODO: more correct implementation
return log10(@floatCast(f64, a)); return log10(@as(f64, @floatCast(a)));
} }
pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble { pub fn log10l(x: c_longdouble) callconv(.C) c_longdouble {

View File

@ -28,7 +28,7 @@ comptime {
pub fn __log2h(a: f16) callconv(.C) f16 { pub fn __log2h(a: f16) callconv(.C) f16 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f16, log2f(a)); return @as(f16, @floatCast(log2f(a)));
} }
pub fn log2f(x_: f32) callconv(.C) f32 { pub fn log2f(x_: f32) callconv(.C) f32 {
@ -40,7 +40,7 @@ pub fn log2f(x_: f32) callconv(.C) f32 {
const Lg4: f32 = 0xf89e26.0p-26; const Lg4: f32 = 0xf89e26.0p-26;
var x = x_; var x = x_;
var u = @bitCast(u32, x); var u = @as(u32, @bitCast(x));
var ix = u; var ix = u;
var k: i32 = 0; var k: i32 = 0;
@ -57,7 +57,7 @@ pub fn log2f(x_: f32) callconv(.C) f32 {
k -= 25; k -= 25;
x *= 0x1.0p25; x *= 0x1.0p25;
ix = @bitCast(u32, x); ix = @as(u32, @bitCast(x));
} else if (ix >= 0x7F800000) { } else if (ix >= 0x7F800000) {
return x; return x;
} else if (ix == 0x3F800000) { } else if (ix == 0x3F800000) {
@ -66,9 +66,9 @@ pub fn log2f(x_: f32) callconv(.C) f32 {
// x into [sqrt(2) / 2, sqrt(2)] // x into [sqrt(2) / 2, sqrt(2)]
ix += 0x3F800000 - 0x3F3504F3; ix += 0x3F800000 - 0x3F3504F3;
k += @intCast(i32, ix >> 23) - 0x7F; k += @as(i32, @intCast(ix >> 23)) - 0x7F;
ix = (ix & 0x007FFFFF) + 0x3F3504F3; ix = (ix & 0x007FFFFF) + 0x3F3504F3;
x = @bitCast(f32, ix); x = @as(f32, @bitCast(ix));
const f = x - 1.0; const f = x - 1.0;
const s = f / (2.0 + f); const s = f / (2.0 + f);
@ -80,11 +80,11 @@ pub fn log2f(x_: f32) callconv(.C) f32 {
const hfsq = 0.5 * f * f; const hfsq = 0.5 * f * f;
var hi = f - hfsq; var hi = f - hfsq;
u = @bitCast(u32, hi); u = @as(u32, @bitCast(hi));
u &= 0xFFFFF000; u &= 0xFFFFF000;
hi = @bitCast(f32, u); hi = @as(f32, @bitCast(u));
const lo = f - hi - hfsq + s * (hfsq + R); const lo = f - hi - hfsq + s * (hfsq + R);
return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @floatFromInt(f32, k); return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @as(f32, @floatFromInt(k));
} }
pub fn log2(x_: f64) callconv(.C) f64 { pub fn log2(x_: f64) callconv(.C) f64 {
@ -99,8 +99,8 @@ pub fn log2(x_: f64) callconv(.C) f64 {
const Lg7: f64 = 1.479819860511658591e-01; const Lg7: f64 = 1.479819860511658591e-01;
var x = x_; var x = x_;
var ix = @bitCast(u64, x); var ix = @as(u64, @bitCast(x));
var hx = @intCast(u32, ix >> 32); var hx = @as(u32, @intCast(ix >> 32));
var k: i32 = 0; var k: i32 = 0;
if (hx < 0x00100000 or hx >> 31 != 0) { if (hx < 0x00100000 or hx >> 31 != 0) {
@ -116,7 +116,7 @@ pub fn log2(x_: f64) callconv(.C) f64 {
// subnormal, scale x // subnormal, scale x
k -= 54; k -= 54;
x *= 0x1.0p54; x *= 0x1.0p54;
hx = @intCast(u32, @bitCast(u64, x) >> 32); hx = @as(u32, @intCast(@as(u64, @bitCast(x)) >> 32));
} else if (hx >= 0x7FF00000) { } else if (hx >= 0x7FF00000) {
return x; return x;
} else if (hx == 0x3FF00000 and ix << 32 == 0) { } else if (hx == 0x3FF00000 and ix << 32 == 0) {
@ -125,10 +125,10 @@ pub fn log2(x_: f64) callconv(.C) f64 {
// x into [sqrt(2) / 2, sqrt(2)] // x into [sqrt(2) / 2, sqrt(2)]
hx += 0x3FF00000 - 0x3FE6A09E; hx += 0x3FF00000 - 0x3FE6A09E;
k += @intCast(i32, hx >> 20) - 0x3FF; k += @as(i32, @intCast(hx >> 20)) - 0x3FF;
hx = (hx & 0x000FFFFF) + 0x3FE6A09E; hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF); ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
x = @bitCast(f64, ix); x = @as(f64, @bitCast(ix));
const f = x - 1.0; const f = x - 1.0;
const hfsq = 0.5 * f * f; const hfsq = 0.5 * f * f;
@ -141,16 +141,16 @@ pub fn log2(x_: f64) callconv(.C) f64 {
// hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f) // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)
var hi = f - hfsq; var hi = f - hfsq;
var hii = @bitCast(u64, hi); var hii = @as(u64, @bitCast(hi));
hii &= @as(u64, maxInt(u64)) << 32; hii &= @as(u64, maxInt(u64)) << 32;
hi = @bitCast(f64, hii); hi = @as(f64, @bitCast(hii));
const lo = f - hi - hfsq + s * (hfsq + R); const lo = f - hi - hfsq + s * (hfsq + R);
var val_hi = hi * ivln2hi; var val_hi = hi * ivln2hi;
var val_lo = (lo + hi) * ivln2lo + lo * ivln2hi; var val_lo = (lo + hi) * ivln2lo + lo * ivln2hi;
// spadd(val_hi, val_lo, y) // spadd(val_hi, val_lo, y)
const y = @floatFromInt(f64, k); const y = @as(f64, @floatFromInt(k));
const ww = y + val_hi; const ww = y + val_hi;
val_lo += (y - ww) + val_hi; val_lo += (y - ww) + val_hi;
val_hi = ww; val_hi = ww;
@ -160,12 +160,12 @@ pub fn log2(x_: f64) callconv(.C) f64 {
pub fn __log2x(a: f80) callconv(.C) f80 { pub fn __log2x(a: f80) callconv(.C) f80 {
// TODO: more efficient implementation // TODO: more efficient implementation
return @floatCast(f80, log2q(a)); return @as(f80, @floatCast(log2q(a)));
} }
pub fn log2q(a: f128) callconv(.C) f128 { pub fn log2q(a: f128) callconv(.C) f128 {
// TODO: more correct implementation // TODO: more correct implementation
return log2(@floatCast(f64, a)); return log2(@as(f64, @floatCast(a)));
} }
pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble { pub fn log2l(x: c_longdouble) callconv(.C) c_longdouble {

View File

@ -24,7 +24,7 @@ pub fn __modti3(a: i128, b: i128) callconv(.C) i128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __modti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { fn __modti3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
return @bitCast(v2u64, mod(@bitCast(i128, a), @bitCast(i128, b))); return @as(v2u64, @bitCast(mod(@as(i128, @bitCast(a)), @as(i128, @bitCast(b)))));
} }
inline fn mod(a: i128, b: i128) i128 { inline fn mod(a: i128, b: i128) i128 {
@ -35,8 +35,8 @@ inline fn mod(a: i128, b: i128) i128 {
const bn = (b ^ s_b) -% s_b; // negate if s == -1 const bn = (b ^ s_b) -% s_b; // negate if s == -1
var r: u128 = undefined; var r: u128 = undefined;
_ = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), &r); _ = udivmod(u128, @as(u128, @bitCast(an)), @as(u128, @bitCast(bn)), &r);
return (@bitCast(i128, r) ^ s_a) -% s_a; // negate if s == -1 return (@as(i128, @bitCast(r)) ^ s_a) -% s_a; // negate if s == -1
} }
test { test {

View File

@ -33,5 +33,5 @@ fn make_ti(high: u64, low: u64) i128 {
var result: u128 = high; var result: u128 = high;
result <<= 64; result <<= 64;
result |= low; result |= low;
return @bitCast(i128, result); return @as(i128, @bitCast(result));
} }

View File

@ -21,8 +21,8 @@ comptime {
} }
pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 { pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 {
var ua = @bitCast(u32, a); var ua = @as(u32, @bitCast(a));
var ub = @bitCast(u32, b); var ub = @as(u32, @bitCast(b));
var r: u32 = 0; var r: u32 = 0;
while (ua > 0) { while (ua > 0) {
@ -31,7 +31,7 @@ pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 {
ub <<= 1; ub <<= 1;
} }
return @bitCast(i32, r); return @as(i32, @bitCast(r));
} }
pub fn __muldi3(a: i64, b: i64) callconv(.C) i64 { pub fn __muldi3(a: i64, b: i64) callconv(.C) i64 {
@ -93,7 +93,7 @@ pub fn __multi3(a: i128, b: i128) callconv(.C) i128 {
const v2u64 = @Vector(2, u64); const v2u64 = @Vector(2, u64);
fn __multi3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { fn __multi3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 {
return @bitCast(v2u64, mulX(i128, @bitCast(i128, a), @bitCast(i128, b))); return @as(v2u64, @bitCast(mulX(i128, @as(i128, @bitCast(a)), @as(i128, @bitCast(b)))));
} }
test { test {

View File

@ -46,14 +46,14 @@ test "mulsi3" {
try test_one_mulsi3(-46340, 46340, -2147395600); try test_one_mulsi3(-46340, 46340, -2147395600);
try test_one_mulsi3(46340, -46340, -2147395600); try test_one_mulsi3(46340, -46340, -2147395600);
try test_one_mulsi3(-46340, -46340, 2147395600); try test_one_mulsi3(-46340, -46340, 2147395600);
try test_one_mulsi3(4194303, 8192, @truncate(i32, 34359730176)); try test_one_mulsi3(4194303, 8192, @as(i32, @truncate(34359730176)));
try test_one_mulsi3(-4194303, 8192, @truncate(i32, -34359730176)); try test_one_mulsi3(-4194303, 8192, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(4194303, -8192, @truncate(i32, -34359730176)); try test_one_mulsi3(4194303, -8192, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(-4194303, -8192, @truncate(i32, 34359730176)); try test_one_mulsi3(-4194303, -8192, @as(i32, @truncate(34359730176)));
try test_one_mulsi3(8192, 4194303, @truncate(i32, 34359730176)); try test_one_mulsi3(8192, 4194303, @as(i32, @truncate(34359730176)));
try test_one_mulsi3(-8192, 4194303, @truncate(i32, -34359730176)); try test_one_mulsi3(-8192, 4194303, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(8192, -4194303, @truncate(i32, -34359730176)); try test_one_mulsi3(8192, -4194303, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(-8192, -4194303, @truncate(i32, 34359730176)); try test_one_mulsi3(-8192, -4194303, @as(i32, @truncate(34359730176)));
} }
test "muldi3" { test "muldi3" {

View File

@ -28,53 +28,53 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
const significandMask = (@as(Z, 1) << significandBits) - 1; const significandMask = (@as(Z, 1) << significandBits) - 1;
const absMask = signBit - 1; const absMask = signBit - 1;
const qnanRep = @bitCast(Z, math.nan(T)) | quietBit; const qnanRep = @as(Z, @bitCast(math.nan(T))) | quietBit;
const infRep = @bitCast(Z, math.inf(T)); const infRep = @as(Z, @bitCast(math.inf(T)));
const minNormalRep = @bitCast(Z, math.floatMin(T)); const minNormalRep = @as(Z, @bitCast(math.floatMin(T)));
const ZExp = if (typeWidth >= 32) u32 else Z; const ZExp = if (typeWidth >= 32) u32 else Z;
const aExponent = @truncate(ZExp, (@bitCast(Z, a) >> significandBits) & maxExponent); const aExponent = @as(ZExp, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @truncate(ZExp, (@bitCast(Z, b) >> significandBits) & maxExponent); const bExponent = @as(ZExp, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const productSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit; const productSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: ZSignificand = @intCast(ZSignificand, @bitCast(Z, a) & significandMask); var aSignificand: ZSignificand = @as(ZSignificand, @intCast(@as(Z, @bitCast(a)) & significandMask));
var bSignificand: ZSignificand = @intCast(ZSignificand, @bitCast(Z, b) & significandMask); var bSignificand: ZSignificand = @as(ZSignificand, @intCast(@as(Z, @bitCast(b)) & significandMask));
var scale: i32 = 0; var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN. // Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) { if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask; const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask; const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// NaN * anything = qNaN // NaN * anything = qNaN
if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit); if (aAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(a)) | quietBit));
// anything * NaN = qNaN // anything * NaN = qNaN
if (bAbs > infRep) return @bitCast(T, @bitCast(Z, b) | quietBit); if (bAbs > infRep) return @as(T, @bitCast(@as(Z, @bitCast(b)) | quietBit));
if (aAbs == infRep) { if (aAbs == infRep) {
// infinity * non-zero = +/- infinity // infinity * non-zero = +/- infinity
if (bAbs != 0) { if (bAbs != 0) {
return @bitCast(T, aAbs | productSign); return @as(T, @bitCast(aAbs | productSign));
} else { } else {
// infinity * zero = NaN // infinity * zero = NaN
return @bitCast(T, qnanRep); return @as(T, @bitCast(qnanRep));
} }
} }
if (bAbs == infRep) { if (bAbs == infRep) {
//? non-zero * infinity = +/- infinity //? non-zero * infinity = +/- infinity
if (aAbs != 0) { if (aAbs != 0) {
return @bitCast(T, bAbs | productSign); return @as(T, @bitCast(bAbs | productSign));
} else { } else {
// zero * infinity = NaN // zero * infinity = NaN
return @bitCast(T, qnanRep); return @as(T, @bitCast(qnanRep));
} }
} }
// zero * anything = +/- zero // zero * anything = +/- zero
if (aAbs == 0) return @bitCast(T, productSign); if (aAbs == 0) return @as(T, @bitCast(productSign));
// anything * zero = +/- zero // anything * zero = +/- zero
if (bAbs == 0) return @bitCast(T, productSign); if (bAbs == 0) return @as(T, @bitCast(productSign));
// one or both of a or b is denormal, the other (if applicable) is a // one or both of a or b is denormal, the other (if applicable) is a
// normal number. Renormalize one or both of a and b, and set scale to // normal number. Renormalize one or both of a and b, and set scale to
@ -99,7 +99,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
const left_align_shift = ZSignificandBits - fractionalBits - 1; const left_align_shift = ZSignificandBits - fractionalBits - 1;
common.wideMultiply(ZSignificand, aSignificand, bSignificand << left_align_shift, &productHi, &productLo); common.wideMultiply(ZSignificand, aSignificand, bSignificand << left_align_shift, &productHi, &productLo);
var productExponent: i32 = @intCast(i32, aExponent + bExponent) - exponentBias + scale; var productExponent: i32 = @as(i32, @intCast(aExponent + bExponent)) - exponentBias + scale;
// Normalize the significand, adjust exponent if needed. // Normalize the significand, adjust exponent if needed.
if ((productHi & integerBit) != 0) { if ((productHi & integerBit) != 0) {
@ -110,7 +110,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
} }
// If we have overflowed the type, return +/- infinity. // If we have overflowed the type, return +/- infinity.
if (productExponent >= maxExponent) return @bitCast(T, infRep | productSign); if (productExponent >= maxExponent) return @as(T, @bitCast(infRep | productSign));
var result: Z = undefined; var result: Z = undefined;
if (productExponent <= 0) { if (productExponent <= 0) {
@ -120,8 +120,8 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
// a zero of the appropriate sign. Mathematically there is no need to // a zero of the appropriate sign. Mathematically there is no need to
// handle this case separately, but we make it a special case to // handle this case separately, but we make it a special case to
// simplify the shift logic. // simplify the shift logic.
const shift: u32 = @truncate(u32, @as(Z, 1) -% @bitCast(u32, productExponent)); const shift: u32 = @as(u32, @truncate(@as(Z, 1) -% @as(u32, @bitCast(productExponent))));
if (shift >= ZSignificandBits) return @bitCast(T, productSign); if (shift >= ZSignificandBits) return @as(T, @bitCast(productSign));
// Otherwise, shift the significand of the result so that the round // Otherwise, shift the significand of the result so that the round
// bit is the high bit of productLo. // bit is the high bit of productLo.
@ -135,7 +135,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
} else { } else {
// Result is normal before rounding; insert the exponent. // Result is normal before rounding; insert the exponent.
result = productHi & significandMask; result = productHi & significandMask;
result |= @intCast(Z, productExponent) << significandBits; result |= @as(Z, @intCast(productExponent)) << significandBits;
} }
// Final rounding. The final result may overflow to infinity, or underflow // Final rounding. The final result may overflow to infinity, or underflow
@ -156,7 +156,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
// Insert the sign of the result: // Insert the sign of the result:
result |= productSign; result |= productSign;
return @bitCast(T, result); return @as(T, @bitCast(result));
} }
/// Returns `true` if the right shift is inexact (i.e. any bit shifted out is non-zero) /// Returns `true` if the right shift is inexact (i.e. any bit shifted out is non-zero)
@ -168,12 +168,12 @@ fn wideShrWithTruncation(comptime Z: type, hi: *Z, lo: *Z, count: u32) bool {
const S = math.Log2Int(Z); const S = math.Log2Int(Z);
var inexact = false; var inexact = false;
if (count < typeWidth) { if (count < typeWidth) {
inexact = (lo.* << @intCast(S, typeWidth -% count)) != 0; inexact = (lo.* << @as(S, @intCast(typeWidth -% count))) != 0;
lo.* = (hi.* << @intCast(S, typeWidth -% count)) | (lo.* >> @intCast(S, count)); lo.* = (hi.* << @as(S, @intCast(typeWidth -% count))) | (lo.* >> @as(S, @intCast(count)));
hi.* = hi.* >> @intCast(S, count); hi.* = hi.* >> @as(S, @intCast(count));
} else if (count < 2 * typeWidth) { } else if (count < 2 * typeWidth) {
inexact = (hi.* << @intCast(S, 2 * typeWidth -% count) | lo.*) != 0; inexact = (hi.* << @as(S, @intCast(2 * typeWidth -% count)) | lo.*) != 0;
lo.* = hi.* >> @intCast(S, count -% typeWidth); lo.* = hi.* >> @as(S, @intCast(count -% typeWidth));
hi.* = 0; hi.* = 0;
} else { } else {
inexact = (hi.* | lo.*) != 0; inexact = (hi.* | lo.*) != 0;
@ -188,7 +188,7 @@ fn normalize(comptime T: type, significand: *PowerOfTwoSignificandZ(T)) i32 {
const integerBit = @as(Z, 1) << math.floatFractionalBits(T); const integerBit = @as(Z, 1) << math.floatFractionalBits(T);
const shift = @clz(significand.*) - @clz(integerBit); const shift = @clz(significand.*) - @clz(integerBit);
significand.* <<= @intCast(math.Log2Int(Z), shift); significand.* <<= @as(math.Log2Int(Z), @intCast(shift));
return @as(i32, 1) - shift; return @as(i32, 1) - shift;
} }

View File

@ -4,8 +4,8 @@
const std = @import("std"); const std = @import("std");
const math = std.math; const math = std.math;
const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64); const qnan128 = @as(f128, @bitCast(@as(u128, 0x7fff800000000000) << 64));
const inf128 = @bitCast(f128, @as(u128, 0x7fff000000000000) << 64); const inf128 = @as(f128, @bitCast(@as(u128, 0x7fff000000000000) << 64));
const __multf3 = @import("multf3.zig").__multf3; const __multf3 = @import("multf3.zig").__multf3;
const __mulxf3 = @import("mulxf3.zig").__mulxf3; const __mulxf3 = @import("mulxf3.zig").__mulxf3;
@ -16,9 +16,9 @@ const __mulsf3 = @import("mulsf3.zig").__mulsf3;
// use two 64-bit integers intead of one 128-bit integer // use two 64-bit integers intead of one 128-bit integer
// because 128-bit integer constant can't be assigned directly // because 128-bit integer constant can't be assigned directly
fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool { fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
const rep = @bitCast(u128, result); const rep = @as(u128, @bitCast(result));
const hi = @intCast(u64, rep >> 64); const hi = @as(u64, @intCast(rep >> 64));
const lo = @truncate(u64, rep); const lo = @as(u64, @truncate(rep));
if (hi == expectedHi and lo == expectedLo) { if (hi == expectedHi and lo == expectedLo) {
return true; return true;
@ -45,7 +45,7 @@ fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) !void {
fn makeNaN128(rand: u64) f128 { fn makeNaN128(rand: u64) f128 {
const int_result = @as(u128, 0x7fff000000000000 | (rand & 0xffffffffffff)) << 64; const int_result = @as(u128, 0x7fff000000000000 | (rand & 0xffffffffffff)) << 64;
const float_result = @bitCast(f128, int_result); const float_result = @as(f128, @bitCast(int_result));
return float_result; return float_result;
} }
test "multf3" { test "multf3" {
@ -60,15 +60,15 @@ test "multf3" {
// any * any // any * any
try test__multf3( try test__multf3(
@bitCast(f128, @as(u128, 0x40042eab345678439abcdefea5678234)), @as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),
@bitCast(f128, @as(u128, 0x3ffeedcb34a235253948765432134675)), @as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),
0x400423e7f9e3c9fc, 0x400423e7f9e3c9fc,
0xd906c2c2a85777c4, 0xd906c2c2a85777c4,
); );
try test__multf3( try test__multf3(
@bitCast(f128, @as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50)), @as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),
@bitCast(f128, @as(u128, 0x3ff6ed8764648369535adf4be3214568)), @as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),
0x3fc52a163c6223fc, 0x3fc52a163c6223fc,
0xc94c4bf0430768b4, 0xc94c4bf0430768b4,
); );
@ -81,8 +81,8 @@ test "multf3" {
); );
try test__multf3( try test__multf3(
@bitCast(f128, @as(u128, 0x3f154356473c82a9fabf2d22ace345df)), @as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),
@bitCast(f128, @as(u128, 0x3e38eda98765476743ab21da23d45679)), @as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),
0x3d4f37c1a3137cae, 0x3d4f37c1a3137cae,
0xfc6807048bc2836a, 0xfc6807048bc2836a,
); );
@ -108,16 +108,16 @@ test "multf3" {
try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002); try test__multf3(2.0, math.floatTrueMin(f128), 0x0000_0000_0000_0000, 0x0000_0000_0000_0002);
} }
const qnan80 = @bitCast(f80, @bitCast(u80, math.nan(f80)) | (1 << (math.floatFractionalBits(f80) - 1))); const qnan80 = @as(f80, @bitCast(@as(u80, @bitCast(math.nan(f80))) | (1 << (math.floatFractionalBits(f80) - 1))));
fn test__mulxf3(a: f80, b: f80, expected: u80) !void { fn test__mulxf3(a: f80, b: f80, expected: u80) !void {
const x = __mulxf3(a, b); const x = __mulxf3(a, b);
const rep = @bitCast(u80, x); const rep = @as(u80, @bitCast(x));
if (rep == expected) if (rep == expected)
return; return;
if (math.isNan(@bitCast(f80, expected)) and math.isNan(x)) if (math.isNan(@as(f80, @bitCast(expected))) and math.isNan(x))
return; // We don't currently test NaN payload propagation return; // We don't currently test NaN payload propagation
return error.TestFailed; return error.TestFailed;
@ -125,33 +125,33 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void {
test "mulxf3" { test "mulxf3" {
// NaN * any = NaN // NaN * any = NaN
try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @bitCast(u80, qnan80)); try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
try test__mulxf3(@bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), 0x1.23456789abcdefp+5, @bitCast(u80, qnan80)); try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
// any * NaN = NaN // any * NaN = NaN
try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @bitCast(u80, qnan80)); try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @as(u80, @bitCast(qnan80)));
try test__mulxf3(0x1.23456789abcdefp+5, @bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), @bitCast(u80, qnan80)); try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
// NaN * inf = NaN // NaN * inf = NaN
try test__mulxf3(qnan80, math.inf(f80), @bitCast(u80, qnan80)); try test__mulxf3(qnan80, math.inf(f80), @as(u80, @bitCast(qnan80)));
// inf * NaN = NaN // inf * NaN = NaN
try test__mulxf3(math.inf(f80), qnan80, @bitCast(u80, qnan80)); try test__mulxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80)));
// inf * inf = inf // inf * inf = inf
try test__mulxf3(math.inf(f80), math.inf(f80), @bitCast(u80, math.inf(f80))); try test__mulxf3(math.inf(f80), math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
// inf * -inf = -inf // inf * -inf = -inf
try test__mulxf3(math.inf(f80), -math.inf(f80), @bitCast(u80, -math.inf(f80))); try test__mulxf3(math.inf(f80), -math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));
// -inf + inf = -inf // -inf + inf = -inf
try test__mulxf3(-math.inf(f80), math.inf(f80), @bitCast(u80, -math.inf(f80))); try test__mulxf3(-math.inf(f80), math.inf(f80), @as(u80, @bitCast(-math.inf(f80))));
// inf * any = inf // inf * any = inf
try test__mulxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @bitCast(u80, math.inf(f80))); try test__mulxf3(math.inf(f80), 0x1.2335653452436234723489432abcdefp+5, @as(u80, @bitCast(math.inf(f80))));
// any * inf = inf // any * inf = inf
try test__mulxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @bitCast(u80, math.inf(f80))); try test__mulxf3(0x1.2335653452436234723489432abcdefp+5, math.inf(f80), @as(u80, @bitCast(math.inf(f80))));
// any * any // any * any
try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800); try test__mulxf3(0x1.0p+0, 0x1.dcba987654321p+5, 0x4004_ee5d_4c3b_2a19_0800);

View File

@ -45,7 +45,7 @@ inline fn muloXi4_genericFast(comptime ST: type, a: ST, b: ST, overflow: *c_int)
//invariant: -2^{bitwidth(EST)} < res < 2^{bitwidth(EST)-1} //invariant: -2^{bitwidth(EST)} < res < 2^{bitwidth(EST)-1}
if (res < min or max < res) if (res < min or max < res)
overflow.* = 1; overflow.* = 1;
return @truncate(ST, res); return @as(ST, @truncate(res));
} }
pub fn __mulosi4(a: i32, b: i32, overflow: *c_int) callconv(.C) i32 { pub fn __mulosi4(a: i32, b: i32, overflow: *c_int) callconv(.C) i32 {

View File

@ -54,34 +54,34 @@ test "mulodi4" {
try test__mulodi4(0x7FFFFFFFFFFFFFFF, -2, 2, 1); try test__mulodi4(0x7FFFFFFFFFFFFFFF, -2, 2, 1);
try test__mulodi4(-2, 0x7FFFFFFFFFFFFFFF, 2, 1); try test__mulodi4(-2, 0x7FFFFFFFFFFFFFFF, 2, 1);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0); try test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0);
try test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 0); try test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, 0, 0, 0); try test__mulodi4(0x7FFFFFFFFFFFFFFF, 0, 0, 0);
try test__mulodi4(0, 0x7FFFFFFFFFFFFFFF, 0, 0); try test__mulodi4(0, 0x7FFFFFFFFFFFFFFF, 0, 0);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, 1, 0x7FFFFFFFFFFFFFFF, 0); try test__mulodi4(0x7FFFFFFFFFFFFFFF, 1, 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(1, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0); try test__mulodi4(1, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @bitCast(i64, @as(u64, 0x8000000000000001)), 1); try test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1);
try test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 1); try test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), -2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(-2, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(-2, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(-1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0, 0); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0, 0, 0);
try test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0); try test__mulodi4(0, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0, 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)), 0); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0);
try test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 0); try test__mulodi4(1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(2, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), -2, @bitCast(i64, @as(u64, 0x8000000000000001)), 1); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), -2, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1);
try test__mulodi4(-2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 1); try test__mulodi4(-2, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), -1, 0x7FFFFFFFFFFFFFFF, 0); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), -1, 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0x7FFFFFFFFFFFFFFF, 0); try test__mulodi4(-1, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0, 0); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0, 0, 0);
try test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0); try test__mulodi4(0, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0, 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0);
try test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 0); try test__mulodi4(1, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), 2, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1); try test__mulodi4(2, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
} }

View File

@ -37,36 +37,36 @@ test "mulosi4" {
try test__mulosi4(1, -0x1234567, -0x1234567, 0); try test__mulosi4(1, -0x1234567, -0x1234567, 0);
try test__mulosi4(-0x1234567, 1, -0x1234567, 0); try test__mulosi4(-0x1234567, 1, -0x1234567, 0);
try test__mulosi4(0x7FFFFFFF, -2, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__mulosi4(0x7FFFFFFF, -2, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(-2, 0x7FFFFFFF, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__mulosi4(-2, 0x7FFFFFFF, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(0x7FFFFFFF, -1, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__mulosi4(0x7FFFFFFF, -1, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__mulosi4(-1, 0x7FFFFFFF, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__mulosi4(-1, 0x7FFFFFFF, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__mulosi4(0x7FFFFFFF, 0, 0, 0); try test__mulosi4(0x7FFFFFFF, 0, 0, 0);
try test__mulosi4(0, 0x7FFFFFFF, 0, 0); try test__mulosi4(0, 0x7FFFFFFF, 0, 0);
try test__mulosi4(0x7FFFFFFF, 1, 0x7FFFFFFF, 0); try test__mulosi4(0x7FFFFFFF, 1, 0x7FFFFFFF, 0);
try test__mulosi4(1, 0x7FFFFFFF, 0x7FFFFFFF, 0); try test__mulosi4(1, 0x7FFFFFFF, 0x7FFFFFFF, 0);
try test__mulosi4(0x7FFFFFFF, 2, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__mulosi4(0x7FFFFFFF, 2, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(2, 0x7FFFFFFF, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__mulosi4(2, 0x7FFFFFFF, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), -2, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), -2, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(-2, @bitCast(i32, @as(u32, 0x80000000)), @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(-2, @as(i32, @bitCast(@as(u32, 0x80000000))), @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), -1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(-1, @bitCast(i32, @as(u32, 0x80000000)), @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(-1, @as(i32, @bitCast(@as(u32, 0x80000000))), @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), 0, 0, 0); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), 0, 0, 0);
try test__mulosi4(0, @bitCast(i32, @as(u32, 0x80000000)), 0, 0); try test__mulosi4(0, @as(i32, @bitCast(@as(u32, 0x80000000))), 0, 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), 1, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__mulosi4(1, @bitCast(i32, @as(u32, 0x80000000)), @bitCast(i32, @as(u32, 0x80000000)), 0); try test__mulosi4(1, @as(i32, @bitCast(@as(u32, 0x80000000))), @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), 2, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(2, @bitCast(i32, @as(u32, 0x80000000)), @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(2, @as(i32, @bitCast(@as(u32, 0x80000000))), @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), -2, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), -2, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(-2, @bitCast(i32, @as(u32, 0x80000001)), @bitCast(i32, @as(u32, 0x80000001)), 1); try test__mulosi4(-2, @as(i32, @bitCast(@as(u32, 0x80000001))), @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), -1, 0x7FFFFFFF, 0); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), -1, 0x7FFFFFFF, 0);
try test__mulosi4(-1, @bitCast(i32, @as(u32, 0x80000001)), 0x7FFFFFFF, 0); try test__mulosi4(-1, @as(i32, @bitCast(@as(u32, 0x80000001))), 0x7FFFFFFF, 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), 0, 0, 0); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), 0, 0, 0);
try test__mulosi4(0, @bitCast(i32, @as(u32, 0x80000001)), 0, 0); try test__mulosi4(0, @as(i32, @bitCast(@as(u32, 0x80000001))), 0, 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), 1, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), 1, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__mulosi4(1, @bitCast(i32, @as(u32, 0x80000001)), @bitCast(i32, @as(u32, 0x80000001)), 0); try test__mulosi4(1, @as(i32, @bitCast(@as(u32, 0x80000001))), @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), 2, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), 2, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(2, @bitCast(i32, @as(u32, 0x80000001)), @bitCast(i32, @as(u32, 0x80000000)), 1); try test__mulosi4(2, @as(i32, @bitCast(@as(u32, 0x80000001))), @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
} }

View File

@ -52,38 +52,38 @@ test "muloti4" {
try test__muloti4(2097152, -4398046511103, -9223372036852678656, 0); try test__muloti4(2097152, -4398046511103, -9223372036852678656, 0);
try test__muloti4(-2097152, -4398046511103, 9223372036852678656, 0); try test__muloti4(-2097152, -4398046511103, 9223372036852678656, 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x00000000000000B504F333F9DE5BE000)), @bitCast(i128, @as(u128, 0x000000000000000000B504F333F9DE5B)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFF328DF915DA296E8A000)), 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x00000000000000B504F333F9DE5BE000))), @as(i128, @bitCast(@as(u128, 0x000000000000000000B504F333F9DE5B))), @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFF328DF915DA296E8A000))), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), -2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(-2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1); try test__muloti4(-2, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), -1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(-1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0); try test__muloti4(-1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0, 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0, 0, 0);
try test__muloti4(0, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0); try test__muloti4(0, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0, 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0); try test__muloti4(1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1); try test__muloti4(2, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), -2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(-2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), -1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), -1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(-1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0, 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0, 0, 0);
try test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0); try test__muloti4(0, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0, 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0);
try test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0); try test__muloti4(1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), -2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1); try test__muloti4(-2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), -1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), -1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0); try test__muloti4(-1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0, 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0, 0, 0);
try test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0); try test__muloti4(0, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0, 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0); try test__muloti4(1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1); try test__muloti4(2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
} }

View File

@ -33,7 +33,7 @@ inline fn negvXi(comptime ST: type, a: ST) ST {
else => unreachable, else => unreachable,
}; };
const N: UT = @bitSizeOf(ST); const N: UT = @bitSizeOf(ST);
const min: ST = @bitCast(ST, (@as(UT, 1) << (N - 1))); const min: ST = @as(ST, @bitCast((@as(UT, 1) << (N - 1))));
if (a == min) if (a == min)
@panic("compiler_rt negv: overflow"); @panic("compiler_rt negv: overflow");
return -a; return -a;

View File

@ -27,9 +27,9 @@ pub fn __parityti2(a: i128) callconv(.C) i32 {
inline fn parityXi2(comptime T: type, a: T) i32 { inline fn parityXi2(comptime T: type, a: T) i32 {
var x = switch (@bitSizeOf(T)) { var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a), 32 => @as(u32, @bitCast(a)),
64 => @bitCast(u64, a), 64 => @as(u64, @bitCast(a)),
128 => @bitCast(u128, a), 128 => @as(u128, @bitCast(a)),
else => unreachable, else => unreachable,
}; };
// Bit Twiddling Hacks: Compute parity in parallel // Bit Twiddling Hacks: Compute parity in parallel
@ -39,7 +39,7 @@ inline fn parityXi2(comptime T: type, a: T) i32 {
shift = shift >> 1; shift = shift >> 1;
} }
x &= 0xf; x &= 0xf;
return (@intCast(u16, 0x6996) >> @intCast(u4, x)) & 1; // optimization for >>2 and >>1 return (@as(u16, @intCast(0x6996)) >> @as(u4, @intCast(x))) & 1; // optimization for >>2 and >>1
} }
test { test {

View File

@ -3,13 +3,13 @@ const parity = @import("parity.zig");
const testing = std.testing; const testing = std.testing;
fn paritydi2Naive(a: i64) i32 { fn paritydi2Naive(a: i64) i32 {
var x = @bitCast(u64, a); var x = @as(u64, @bitCast(a));
var has_parity: bool = false; var has_parity: bool = false;
while (x > 0) { while (x > 0) {
has_parity = !has_parity; has_parity = !has_parity;
x = x & (x - 1); x = x & (x - 1);
} }
return @intCast(i32, @intFromBool(has_parity)); return @as(i32, @intCast(@intFromBool(has_parity)));
} }
fn test__paritydi2(a: i64) !void { fn test__paritydi2(a: i64) !void {
@ -22,9 +22,9 @@ test "paritydi2" {
try test__paritydi2(0); try test__paritydi2(0);
try test__paritydi2(1); try test__paritydi2(1);
try test__paritydi2(2); try test__paritydi2(2);
try test__paritydi2(@bitCast(i64, @as(u64, 0xffffffff_fffffffd))); try test__paritydi2(@as(i64, @bitCast(@as(u64, 0xffffffff_fffffffd))));
try test__paritydi2(@bitCast(i64, @as(u64, 0xffffffff_fffffffe))); try test__paritydi2(@as(i64, @bitCast(@as(u64, 0xffffffff_fffffffe))));
try test__paritydi2(@bitCast(i64, @as(u64, 0xffffffff_ffffffff))); try test__paritydi2(@as(i64, @bitCast(@as(u64, 0xffffffff_ffffffff))));
const RndGen = std.rand.DefaultPrng; const RndGen = std.rand.DefaultPrng;
var rnd = RndGen.init(42); var rnd = RndGen.init(42);

View File

@ -3,13 +3,13 @@ const parity = @import("parity.zig");
const testing = std.testing; const testing = std.testing;
fn paritysi2Naive(a: i32) i32 { fn paritysi2Naive(a: i32) i32 {
var x = @bitCast(u32, a); var x = @as(u32, @bitCast(a));
var has_parity: bool = false; var has_parity: bool = false;
while (x > 0) { while (x > 0) {
has_parity = !has_parity; has_parity = !has_parity;
x = x & (x - 1); x = x & (x - 1);
} }
return @intCast(i32, @intFromBool(has_parity)); return @as(i32, @intCast(@intFromBool(has_parity)));
} }
fn test__paritysi2(a: i32) !void { fn test__paritysi2(a: i32) !void {
@ -22,9 +22,9 @@ test "paritysi2" {
try test__paritysi2(0); try test__paritysi2(0);
try test__paritysi2(1); try test__paritysi2(1);
try test__paritysi2(2); try test__paritysi2(2);
try test__paritysi2(@bitCast(i32, @as(u32, 0xfffffffd))); try test__paritysi2(@as(i32, @bitCast(@as(u32, 0xfffffffd))));
try test__paritysi2(@bitCast(i32, @as(u32, 0xfffffffe))); try test__paritysi2(@as(i32, @bitCast(@as(u32, 0xfffffffe))));
try test__paritysi2(@bitCast(i32, @as(u32, 0xffffffff))); try test__paritysi2(@as(i32, @bitCast(@as(u32, 0xffffffff))));
const RndGen = std.rand.DefaultPrng; const RndGen = std.rand.DefaultPrng;
var rnd = RndGen.init(42); var rnd = RndGen.init(42);

View File

@ -3,13 +3,13 @@ const parity = @import("parity.zig");
const testing = std.testing; const testing = std.testing;
fn parityti2Naive(a: i128) i32 { fn parityti2Naive(a: i128) i32 {
var x = @bitCast(u128, a); var x = @as(u128, @bitCast(a));
var has_parity: bool = false; var has_parity: bool = false;
while (x > 0) { while (x > 0) {
has_parity = !has_parity; has_parity = !has_parity;
x = x & (x - 1); x = x & (x - 1);
} }
return @intCast(i32, @intFromBool(has_parity)); return @as(i32, @intCast(@intFromBool(has_parity)));
} }
fn test__parityti2(a: i128) !void { fn test__parityti2(a: i128) !void {
@ -22,9 +22,9 @@ test "parityti2" {
try test__parityti2(0); try test__parityti2(0);
try test__parityti2(1); try test__parityti2(1);
try test__parityti2(2); try test__parityti2(2);
try test__parityti2(@bitCast(i128, @as(u128, 0xffffffff_ffffffff_ffffffff_fffffffd))); try test__parityti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffd))));
try test__parityti2(@bitCast(i128, @as(u128, 0xffffffff_ffffffff_ffffffff_fffffffe))); try test__parityti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffe))));
try test__parityti2(@bitCast(i128, @as(u128, 0xffffffff_ffffffff_ffffffff_ffffffff))); try test__parityti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_ffffffff))));
const RndGen = std.rand.DefaultPrng; const RndGen = std.rand.DefaultPrng;
var rnd = RndGen.init(42); var rnd = RndGen.init(42);

View File

@ -37,7 +37,7 @@ inline fn popcountXi2(comptime ST: type, a: ST) i32 {
i128 => u128, i128 => u128,
else => unreachable, else => unreachable,
}; };
var x = @bitCast(UT, a); var x = @as(UT, @bitCast(a));
x -= (x >> 1) & (~@as(UT, 0) / 3); // 0x55...55, aggregate duos x -= (x >> 1) & (~@as(UT, 0) / 3); // 0x55...55, aggregate duos
x = ((x >> 2) & (~@as(UT, 0) / 5)) // 0x33...33, aggregate nibbles x = ((x >> 2) & (~@as(UT, 0) / 5)) // 0x33...33, aggregate nibbles
+ (x & (~@as(UT, 0) / 5)); + (x & (~@as(UT, 0) / 5));
@ -46,7 +46,7 @@ inline fn popcountXi2(comptime ST: type, a: ST) i32 {
// 8 most significant bits of x + (x<<8) + (x<<16) + .. // 8 most significant bits of x + (x<<8) + (x<<16) + ..
x *%= ~@as(UT, 0) / 255; // 0x01...01 x *%= ~@as(UT, 0) / 255; // 0x01...01
x >>= (@bitSizeOf(ST) - 8); x >>= (@bitSizeOf(ST) - 8);
return @intCast(i32, x); return @as(i32, @intCast(x));
} }
test { test {

View File

@ -5,8 +5,8 @@ const testing = std.testing;
fn popcountdi2Naive(a: i64) i32 { fn popcountdi2Naive(a: i64) i32 {
var x = a; var x = a;
var r: i32 = 0; var r: i32 = 0;
while (x != 0) : (x = @bitCast(i64, @bitCast(u64, x) >> 1)) { while (x != 0) : (x = @as(i64, @bitCast(@as(u64, @bitCast(x)) >> 1))) {
r += @intCast(i32, x & 1); r += @as(i32, @intCast(x & 1));
} }
return r; return r;
} }
@ -21,9 +21,9 @@ test "popcountdi2" {
try test__popcountdi2(0); try test__popcountdi2(0);
try test__popcountdi2(1); try test__popcountdi2(1);
try test__popcountdi2(2); try test__popcountdi2(2);
try test__popcountdi2(@bitCast(i64, @as(u64, 0xffffffff_fffffffd))); try test__popcountdi2(@as(i64, @bitCast(@as(u64, 0xffffffff_fffffffd))));
try test__popcountdi2(@bitCast(i64, @as(u64, 0xffffffff_fffffffe))); try test__popcountdi2(@as(i64, @bitCast(@as(u64, 0xffffffff_fffffffe))));
try test__popcountdi2(@bitCast(i64, @as(u64, 0xffffffff_ffffffff))); try test__popcountdi2(@as(i64, @bitCast(@as(u64, 0xffffffff_ffffffff))));
const RndGen = std.rand.DefaultPrng; const RndGen = std.rand.DefaultPrng;
var rnd = RndGen.init(42); var rnd = RndGen.init(42);

View File

@ -5,8 +5,8 @@ const testing = std.testing;
fn popcountsi2Naive(a: i32) i32 { fn popcountsi2Naive(a: i32) i32 {
var x = a; var x = a;
var r: i32 = 0; var r: i32 = 0;
while (x != 0) : (x = @bitCast(i32, @bitCast(u32, x) >> 1)) { while (x != 0) : (x = @as(i32, @bitCast(@as(u32, @bitCast(x)) >> 1))) {
r += @intCast(i32, x & 1); r += @as(i32, @intCast(x & 1));
} }
return r; return r;
} }
@ -21,9 +21,9 @@ test "popcountsi2" {
try test__popcountsi2(0); try test__popcountsi2(0);
try test__popcountsi2(1); try test__popcountsi2(1);
try test__popcountsi2(2); try test__popcountsi2(2);
try test__popcountsi2(@bitCast(i32, @as(u32, 0xfffffffd))); try test__popcountsi2(@as(i32, @bitCast(@as(u32, 0xfffffffd))));
try test__popcountsi2(@bitCast(i32, @as(u32, 0xfffffffe))); try test__popcountsi2(@as(i32, @bitCast(@as(u32, 0xfffffffe))));
try test__popcountsi2(@bitCast(i32, @as(u32, 0xffffffff))); try test__popcountsi2(@as(i32, @bitCast(@as(u32, 0xffffffff))));
const RndGen = std.rand.DefaultPrng; const RndGen = std.rand.DefaultPrng;
var rnd = RndGen.init(42); var rnd = RndGen.init(42);

View File

@ -5,8 +5,8 @@ const testing = std.testing;
fn popcountti2Naive(a: i128) i32 { fn popcountti2Naive(a: i128) i32 {
var x = a; var x = a;
var r: i32 = 0; var r: i32 = 0;
while (x != 0) : (x = @bitCast(i128, @bitCast(u128, x) >> 1)) { while (x != 0) : (x = @as(i128, @bitCast(@as(u128, @bitCast(x)) >> 1))) {
r += @intCast(i32, x & 1); r += @as(i32, @intCast(x & 1));
} }
return r; return r;
} }
@ -21,9 +21,9 @@ test "popcountti2" {
try test__popcountti2(0); try test__popcountti2(0);
try test__popcountti2(1); try test__popcountti2(1);
try test__popcountti2(2); try test__popcountti2(2);
try test__popcountti2(@bitCast(i128, @as(u128, 0xffffffff_ffffffff_ffffffff_fffffffd))); try test__popcountti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffd))));
try test__popcountti2(@bitCast(i128, @as(u128, 0xffffffff_ffffffff_ffffffff_fffffffe))); try test__popcountti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffe))));
try test__popcountti2(@bitCast(i128, @as(u128, 0xffffffff_ffffffff_ffffffff_ffffffff))); try test__popcountti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_ffffffff))));
const RndGen = std.rand.DefaultPrng; const RndGen = std.rand.DefaultPrng;
var rnd = RndGen.init(42); var rnd = RndGen.init(42);

View File

@ -25,7 +25,7 @@ inline fn powiXf2(comptime FT: type, a: FT, b: i32) FT {
const is_recip: bool = b < 0; const is_recip: bool = b < 0;
var r: FT = 1.0; var r: FT = 1.0;
while (true) { while (true) {
if (@bitCast(u32, x_b) & @as(u32, 1) != 0) { if (@as(u32, @bitCast(x_b)) & @as(u32, 1) != 0) {
r *= x_a; r *= x_a;
} }
x_b = @divTrunc(x_b, @as(i32, 2)); x_b = @divTrunc(x_b, @as(i32, 2));

View File

@ -49,76 +49,76 @@ test "powihf2" {
try test__powihf2(0, 2, 0); try test__powihf2(0, 2, 0);
try test__powihf2(0, 3, 0); try test__powihf2(0, 3, 0);
try test__powihf2(0, 4, 0); try test__powihf2(0, 4, 0);
try test__powihf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powihf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 0); try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
try test__powihf2(-0.0, 1, -0.0); try test__powihf2(-0.0, 1, -0.0);
try test__powihf2(-0.0, 2, 0); try test__powihf2(-0.0, 2, 0);
try test__powihf2(-0.0, 3, -0.0); try test__powihf2(-0.0, 3, -0.0);
try test__powihf2(-0.0, 4, 0); try test__powihf2(-0.0, 4, 0);
try test__powihf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powihf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -0.0); try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
try test__powihf2(1, 1, 1); try test__powihf2(1, 1, 1);
try test__powihf2(1, 2, 1); try test__powihf2(1, 2, 1);
try test__powihf2(1, 3, 1); try test__powihf2(1, 3, 1);
try test__powihf2(1, 4, 1); try test__powihf2(1, 4, 1);
try test__powihf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 1); try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
try test__powihf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 1); try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
try test__powihf2(inf_f16, 1, inf_f16); try test__powihf2(inf_f16, 1, inf_f16);
try test__powihf2(inf_f16, 2, inf_f16); try test__powihf2(inf_f16, 2, inf_f16);
try test__powihf2(inf_f16, 3, inf_f16); try test__powihf2(inf_f16, 3, inf_f16);
try test__powihf2(inf_f16, 4, inf_f16); try test__powihf2(inf_f16, 4, inf_f16);
try test__powihf2(inf_f16, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f16); try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
try test__powihf2(inf_f16, @bitCast(i32, @as(u32, 0x7FFFFFFF)), inf_f16); try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f16);
try test__powihf2(-inf_f16, 1, -inf_f16); try test__powihf2(-inf_f16, 1, -inf_f16);
try test__powihf2(-inf_f16, 2, inf_f16); try test__powihf2(-inf_f16, 2, inf_f16);
try test__powihf2(-inf_f16, 3, -inf_f16); try test__powihf2(-inf_f16, 3, -inf_f16);
try test__powihf2(-inf_f16, 4, inf_f16); try test__powihf2(-inf_f16, 4, inf_f16);
try test__powihf2(-inf_f16, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f16); try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f16);
try test__powihf2(-inf_f16, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -inf_f16); try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f16);
// //
try test__powihf2(0, -1, inf_f16); try test__powihf2(0, -1, inf_f16);
try test__powihf2(0, -2, inf_f16); try test__powihf2(0, -2, inf_f16);
try test__powihf2(0, -3, inf_f16); try test__powihf2(0, -3, inf_f16);
try test__powihf2(0, -4, inf_f16); try test__powihf2(0, -4, inf_f16);
try test__powihf2(0, @bitCast(i32, @as(u32, 0x80000002)), inf_f16); // 0 ^ anything = +inf try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // 0 ^ anything = +inf
try test__powihf2(0, @bitCast(i32, @as(u32, 0x80000001)), inf_f16); try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f16);
try test__powihf2(0, @bitCast(i32, @as(u32, 0x80000000)), inf_f16); try test__powihf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
try test__powihf2(-0.0, -1, -inf_f16); try test__powihf2(-0.0, -1, -inf_f16);
try test__powihf2(-0.0, -2, inf_f16); try test__powihf2(-0.0, -2, inf_f16);
try test__powihf2(-0.0, -3, -inf_f16); try test__powihf2(-0.0, -3, -inf_f16);
try test__powihf2(-0.0, -4, inf_f16); try test__powihf2(-0.0, -4, inf_f16);
try test__powihf2(-0.0, @bitCast(i32, @as(u32, 0x80000002)), inf_f16); // -0 ^ anything even = +inf try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f16); // -0 ^ anything even = +inf
try test__powihf2(-0.0, @bitCast(i32, @as(u32, 0x80000001)), -inf_f16); // -0 ^ anything odd = -inf try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f16); // -0 ^ anything odd = -inf
try test__powihf2(-0.0, @bitCast(i32, @as(u32, 0x80000000)), inf_f16); try test__powihf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f16);
try test__powihf2(1, -1, 1); try test__powihf2(1, -1, 1);
try test__powihf2(1, -2, 1); try test__powihf2(1, -2, 1);
try test__powihf2(1, -3, 1); try test__powihf2(1, -3, 1);
try test__powihf2(1, -4, 1); try test__powihf2(1, -4, 1);
try test__powihf2(1, @bitCast(i32, @as(u32, 0x80000002)), 1); // 1.0 ^ anything = 1 try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1); // 1.0 ^ anything = 1
try test__powihf2(1, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__powihf2(1, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__powihf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__powihf2(inf_f16, -1, 0); try test__powihf2(inf_f16, -1, 0);
try test__powihf2(inf_f16, -2, 0); try test__powihf2(inf_f16, -2, 0);
try test__powihf2(inf_f16, -3, 0); try test__powihf2(inf_f16, -3, 0);
try test__powihf2(inf_f16, -4, 0); try test__powihf2(inf_f16, -4, 0);
try test__powihf2(inf_f16, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powihf2(inf_f16, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__powihf2(inf_f16, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powihf2(inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
// //
try test__powihf2(-inf_f16, -1, -0.0); try test__powihf2(-inf_f16, -1, -0.0);
try test__powihf2(-inf_f16, -2, 0); try test__powihf2(-inf_f16, -2, 0);
try test__powihf2(-inf_f16, -3, -0.0); try test__powihf2(-inf_f16, -3, -0.0);
try test__powihf2(-inf_f16, -4, 0); try test__powihf2(-inf_f16, -4, 0);
try test__powihf2(-inf_f16, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powihf2(-inf_f16, @bitCast(i32, @as(u32, 0x80000001)), -0.0); try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
try test__powihf2(-inf_f16, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powihf2(-inf_f16, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powihf2(2, 10, 1024.0); try test__powihf2(2, 10, 1024.0);
try test__powihf2(-2, 10, 1024.0); try test__powihf2(-2, 10, 1024.0);
@ -158,76 +158,76 @@ test "powisf2" {
try test__powisf2(0, 2, 0); try test__powisf2(0, 2, 0);
try test__powisf2(0, 3, 0); try test__powisf2(0, 3, 0);
try test__powisf2(0, 4, 0); try test__powisf2(0, 4, 0);
try test__powisf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powisf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 0); try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
try test__powisf2(-0.0, 1, -0.0); try test__powisf2(-0.0, 1, -0.0);
try test__powisf2(-0.0, 2, 0); try test__powisf2(-0.0, 2, 0);
try test__powisf2(-0.0, 3, -0.0); try test__powisf2(-0.0, 3, -0.0);
try test__powisf2(-0.0, 4, 0); try test__powisf2(-0.0, 4, 0);
try test__powisf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powisf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -0.0); try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
try test__powisf2(1, 1, 1); try test__powisf2(1, 1, 1);
try test__powisf2(1, 2, 1); try test__powisf2(1, 2, 1);
try test__powisf2(1, 3, 1); try test__powisf2(1, 3, 1);
try test__powisf2(1, 4, 1); try test__powisf2(1, 4, 1);
try test__powisf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 1); try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
try test__powisf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 1); try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
try test__powisf2(inf_f32, 1, inf_f32); try test__powisf2(inf_f32, 1, inf_f32);
try test__powisf2(inf_f32, 2, inf_f32); try test__powisf2(inf_f32, 2, inf_f32);
try test__powisf2(inf_f32, 3, inf_f32); try test__powisf2(inf_f32, 3, inf_f32);
try test__powisf2(inf_f32, 4, inf_f32); try test__powisf2(inf_f32, 4, inf_f32);
try test__powisf2(inf_f32, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f32); try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
try test__powisf2(inf_f32, @bitCast(i32, @as(u32, 0x7FFFFFFF)), inf_f32); try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f32);
try test__powisf2(-inf_f32, 1, -inf_f32); try test__powisf2(-inf_f32, 1, -inf_f32);
try test__powisf2(-inf_f32, 2, inf_f32); try test__powisf2(-inf_f32, 2, inf_f32);
try test__powisf2(-inf_f32, 3, -inf_f32); try test__powisf2(-inf_f32, 3, -inf_f32);
try test__powisf2(-inf_f32, 4, inf_f32); try test__powisf2(-inf_f32, 4, inf_f32);
try test__powisf2(-inf_f32, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f32); try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f32);
try test__powisf2(-inf_f32, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -inf_f32); try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f32);
try test__powisf2(0, -1, inf_f32); try test__powisf2(0, -1, inf_f32);
try test__powisf2(0, -2, inf_f32); try test__powisf2(0, -2, inf_f32);
try test__powisf2(0, -3, inf_f32); try test__powisf2(0, -3, inf_f32);
try test__powisf2(0, -4, inf_f32); try test__powisf2(0, -4, inf_f32);
try test__powisf2(0, @bitCast(i32, @as(u32, 0x80000002)), inf_f32); try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
try test__powisf2(0, @bitCast(i32, @as(u32, 0x80000001)), inf_f32); try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f32);
try test__powisf2(0, @bitCast(i32, @as(u32, 0x80000000)), inf_f32); try test__powisf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
try test__powisf2(-0.0, -1, -inf_f32); try test__powisf2(-0.0, -1, -inf_f32);
try test__powisf2(-0.0, -2, inf_f32); try test__powisf2(-0.0, -2, inf_f32);
try test__powisf2(-0.0, -3, -inf_f32); try test__powisf2(-0.0, -3, -inf_f32);
try test__powisf2(-0.0, -4, inf_f32); try test__powisf2(-0.0, -4, inf_f32);
try test__powisf2(-0.0, @bitCast(i32, @as(u32, 0x80000002)), inf_f32); try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f32);
try test__powisf2(-0.0, @bitCast(i32, @as(u32, 0x80000001)), -inf_f32); try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f32);
try test__powisf2(-0.0, @bitCast(i32, @as(u32, 0x80000000)), inf_f32); try test__powisf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f32);
try test__powisf2(1, -1, 1); try test__powisf2(1, -1, 1);
try test__powisf2(1, -2, 1); try test__powisf2(1, -2, 1);
try test__powisf2(1, -3, 1); try test__powisf2(1, -3, 1);
try test__powisf2(1, -4, 1); try test__powisf2(1, -4, 1);
try test__powisf2(1, @bitCast(i32, @as(u32, 0x80000002)), 1); try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
try test__powisf2(1, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__powisf2(1, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__powisf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__powisf2(inf_f32, -1, 0); try test__powisf2(inf_f32, -1, 0);
try test__powisf2(inf_f32, -2, 0); try test__powisf2(inf_f32, -2, 0);
try test__powisf2(inf_f32, -3, 0); try test__powisf2(inf_f32, -3, 0);
try test__powisf2(inf_f32, -4, 0); try test__powisf2(inf_f32, -4, 0);
try test__powisf2(inf_f32, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powisf2(inf_f32, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__powisf2(inf_f32, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powisf2(inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powisf2(-inf_f32, -1, -0.0); try test__powisf2(-inf_f32, -1, -0.0);
try test__powisf2(-inf_f32, -2, 0); try test__powisf2(-inf_f32, -2, 0);
try test__powisf2(-inf_f32, -3, -0.0); try test__powisf2(-inf_f32, -3, -0.0);
try test__powisf2(-inf_f32, -4, 0); try test__powisf2(-inf_f32, -4, 0);
try test__powisf2(-inf_f32, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powisf2(-inf_f32, @bitCast(i32, @as(u32, 0x80000001)), -0.0); try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
try test__powisf2(-inf_f32, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powisf2(-inf_f32, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powisf2(2.0, 10, 1024.0); try test__powisf2(2.0, 10, 1024.0);
try test__powisf2(-2, 10, 1024.0); try test__powisf2(-2, 10, 1024.0);
@ -263,76 +263,76 @@ test "powidf2" {
try test__powidf2(0, 2, 0); try test__powidf2(0, 2, 0);
try test__powidf2(0, 3, 0); try test__powidf2(0, 3, 0);
try test__powidf2(0, 4, 0); try test__powidf2(0, 4, 0);
try test__powidf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powidf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 0); try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
try test__powidf2(-0.0, 1, -0.0); try test__powidf2(-0.0, 1, -0.0);
try test__powidf2(-0.0, 2, 0); try test__powidf2(-0.0, 2, 0);
try test__powidf2(-0.0, 3, -0.0); try test__powidf2(-0.0, 3, -0.0);
try test__powidf2(-0.0, 4, 0); try test__powidf2(-0.0, 4, 0);
try test__powidf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powidf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -0.0); try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
try test__powidf2(1, 1, 1); try test__powidf2(1, 1, 1);
try test__powidf2(1, 2, 1); try test__powidf2(1, 2, 1);
try test__powidf2(1, 3, 1); try test__powidf2(1, 3, 1);
try test__powidf2(1, 4, 1); try test__powidf2(1, 4, 1);
try test__powidf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 1); try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
try test__powidf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 1); try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
try test__powidf2(inf_f64, 1, inf_f64); try test__powidf2(inf_f64, 1, inf_f64);
try test__powidf2(inf_f64, 2, inf_f64); try test__powidf2(inf_f64, 2, inf_f64);
try test__powidf2(inf_f64, 3, inf_f64); try test__powidf2(inf_f64, 3, inf_f64);
try test__powidf2(inf_f64, 4, inf_f64); try test__powidf2(inf_f64, 4, inf_f64);
try test__powidf2(inf_f64, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f64); try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
try test__powidf2(inf_f64, @bitCast(i32, @as(u32, 0x7FFFFFFF)), inf_f64); try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f64);
try test__powidf2(-inf_f64, 1, -inf_f64); try test__powidf2(-inf_f64, 1, -inf_f64);
try test__powidf2(-inf_f64, 2, inf_f64); try test__powidf2(-inf_f64, 2, inf_f64);
try test__powidf2(-inf_f64, 3, -inf_f64); try test__powidf2(-inf_f64, 3, -inf_f64);
try test__powidf2(-inf_f64, 4, inf_f64); try test__powidf2(-inf_f64, 4, inf_f64);
try test__powidf2(-inf_f64, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f64); try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f64);
try test__powidf2(-inf_f64, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -inf_f64); try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f64);
try test__powidf2(0, -1, inf_f64); try test__powidf2(0, -1, inf_f64);
try test__powidf2(0, -2, inf_f64); try test__powidf2(0, -2, inf_f64);
try test__powidf2(0, -3, inf_f64); try test__powidf2(0, -3, inf_f64);
try test__powidf2(0, -4, inf_f64); try test__powidf2(0, -4, inf_f64);
try test__powidf2(0, @bitCast(i32, @as(u32, 0x80000002)), inf_f64); try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
try test__powidf2(0, @bitCast(i32, @as(u32, 0x80000001)), inf_f64); try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f64);
try test__powidf2(0, @bitCast(i32, @as(u32, 0x80000000)), inf_f64); try test__powidf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
try test__powidf2(-0.0, -1, -inf_f64); try test__powidf2(-0.0, -1, -inf_f64);
try test__powidf2(-0.0, -2, inf_f64); try test__powidf2(-0.0, -2, inf_f64);
try test__powidf2(-0.0, -3, -inf_f64); try test__powidf2(-0.0, -3, -inf_f64);
try test__powidf2(-0.0, -4, inf_f64); try test__powidf2(-0.0, -4, inf_f64);
try test__powidf2(-0.0, @bitCast(i32, @as(u32, 0x80000002)), inf_f64); try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f64);
try test__powidf2(-0.0, @bitCast(i32, @as(u32, 0x80000001)), -inf_f64); try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f64);
try test__powidf2(-0.0, @bitCast(i32, @as(u32, 0x80000000)), inf_f64); try test__powidf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f64);
try test__powidf2(1, -1, 1); try test__powidf2(1, -1, 1);
try test__powidf2(1, -2, 1); try test__powidf2(1, -2, 1);
try test__powidf2(1, -3, 1); try test__powidf2(1, -3, 1);
try test__powidf2(1, -4, 1); try test__powidf2(1, -4, 1);
try test__powidf2(1, @bitCast(i32, @as(u32, 0x80000002)), 1); try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
try test__powidf2(1, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__powidf2(1, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__powidf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__powidf2(inf_f64, -1, 0); try test__powidf2(inf_f64, -1, 0);
try test__powidf2(inf_f64, -2, 0); try test__powidf2(inf_f64, -2, 0);
try test__powidf2(inf_f64, -3, 0); try test__powidf2(inf_f64, -3, 0);
try test__powidf2(inf_f64, -4, 0); try test__powidf2(inf_f64, -4, 0);
try test__powidf2(inf_f64, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powidf2(inf_f64, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__powidf2(inf_f64, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powidf2(inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powidf2(-inf_f64, -1, -0.0); try test__powidf2(-inf_f64, -1, -0.0);
try test__powidf2(-inf_f64, -2, 0); try test__powidf2(-inf_f64, -2, 0);
try test__powidf2(-inf_f64, -3, -0.0); try test__powidf2(-inf_f64, -3, -0.0);
try test__powidf2(-inf_f64, -4, 0); try test__powidf2(-inf_f64, -4, 0);
try test__powidf2(-inf_f64, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powidf2(-inf_f64, @bitCast(i32, @as(u32, 0x80000001)), -0.0); try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
try test__powidf2(-inf_f64, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powidf2(-inf_f64, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powidf2(2, 10, 1024.0); try test__powidf2(2, 10, 1024.0);
try test__powidf2(-2, 10, 1024.0); try test__powidf2(-2, 10, 1024.0);
@ -368,76 +368,76 @@ test "powitf2" {
try test__powitf2(0, 2, 0); try test__powitf2(0, 2, 0);
try test__powitf2(0, 3, 0); try test__powitf2(0, 3, 0);
try test__powitf2(0, 4, 0); try test__powitf2(0, 4, 0);
try test__powitf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powitf2(0, 0x7FFFFFFF, 0); try test__powitf2(0, 0x7FFFFFFF, 0);
try test__powitf2(-0.0, 1, -0.0); try test__powitf2(-0.0, 1, -0.0);
try test__powitf2(-0.0, 2, 0); try test__powitf2(-0.0, 2, 0);
try test__powitf2(-0.0, 3, -0.0); try test__powitf2(-0.0, 3, -0.0);
try test__powitf2(-0.0, 4, 0); try test__powitf2(-0.0, 4, 0);
try test__powitf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powitf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -0.0); try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
try test__powitf2(1, 1, 1); try test__powitf2(1, 1, 1);
try test__powitf2(1, 2, 1); try test__powitf2(1, 2, 1);
try test__powitf2(1, 3, 1); try test__powitf2(1, 3, 1);
try test__powitf2(1, 4, 1); try test__powitf2(1, 4, 1);
try test__powitf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 1); try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
try test__powitf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 1); try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
try test__powitf2(inf_f128, 1, inf_f128); try test__powitf2(inf_f128, 1, inf_f128);
try test__powitf2(inf_f128, 2, inf_f128); try test__powitf2(inf_f128, 2, inf_f128);
try test__powitf2(inf_f128, 3, inf_f128); try test__powitf2(inf_f128, 3, inf_f128);
try test__powitf2(inf_f128, 4, inf_f128); try test__powitf2(inf_f128, 4, inf_f128);
try test__powitf2(inf_f128, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f128); try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
try test__powitf2(inf_f128, @bitCast(i32, @as(u32, 0x7FFFFFFF)), inf_f128); try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f128);
try test__powitf2(-inf_f128, 1, -inf_f128); try test__powitf2(-inf_f128, 1, -inf_f128);
try test__powitf2(-inf_f128, 2, inf_f128); try test__powitf2(-inf_f128, 2, inf_f128);
try test__powitf2(-inf_f128, 3, -inf_f128); try test__powitf2(-inf_f128, 3, -inf_f128);
try test__powitf2(-inf_f128, 4, inf_f128); try test__powitf2(-inf_f128, 4, inf_f128);
try test__powitf2(-inf_f128, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f128); try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f128);
try test__powitf2(-inf_f128, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -inf_f128); try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f128);
try test__powitf2(0, -1, inf_f128); try test__powitf2(0, -1, inf_f128);
try test__powitf2(0, -2, inf_f128); try test__powitf2(0, -2, inf_f128);
try test__powitf2(0, -3, inf_f128); try test__powitf2(0, -3, inf_f128);
try test__powitf2(0, -4, inf_f128); try test__powitf2(0, -4, inf_f128);
try test__powitf2(0, @bitCast(i32, @as(u32, 0x80000002)), inf_f128); try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
try test__powitf2(0, @bitCast(i32, @as(u32, 0x80000001)), inf_f128); try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f128);
try test__powitf2(0, @bitCast(i32, @as(u32, 0x80000000)), inf_f128); try test__powitf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
try test__powitf2(-0.0, -1, -inf_f128); try test__powitf2(-0.0, -1, -inf_f128);
try test__powitf2(-0.0, -2, inf_f128); try test__powitf2(-0.0, -2, inf_f128);
try test__powitf2(-0.0, -3, -inf_f128); try test__powitf2(-0.0, -3, -inf_f128);
try test__powitf2(-0.0, -4, inf_f128); try test__powitf2(-0.0, -4, inf_f128);
try test__powitf2(-0.0, @bitCast(i32, @as(u32, 0x80000002)), inf_f128); try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f128);
try test__powitf2(-0.0, @bitCast(i32, @as(u32, 0x80000001)), -inf_f128); try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f128);
try test__powitf2(-0.0, @bitCast(i32, @as(u32, 0x80000000)), inf_f128); try test__powitf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f128);
try test__powitf2(1, -1, 1); try test__powitf2(1, -1, 1);
try test__powitf2(1, -2, 1); try test__powitf2(1, -2, 1);
try test__powitf2(1, -3, 1); try test__powitf2(1, -3, 1);
try test__powitf2(1, -4, 1); try test__powitf2(1, -4, 1);
try test__powitf2(1, @bitCast(i32, @as(u32, 0x80000002)), 1); try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
try test__powitf2(1, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__powitf2(1, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__powitf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__powitf2(inf_f128, -1, 0); try test__powitf2(inf_f128, -1, 0);
try test__powitf2(inf_f128, -2, 0); try test__powitf2(inf_f128, -2, 0);
try test__powitf2(inf_f128, -3, 0); try test__powitf2(inf_f128, -3, 0);
try test__powitf2(inf_f128, -4, 0); try test__powitf2(inf_f128, -4, 0);
try test__powitf2(inf_f128, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powitf2(inf_f128, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__powitf2(inf_f128, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powitf2(inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powitf2(-inf_f128, -1, -0.0); try test__powitf2(-inf_f128, -1, -0.0);
try test__powitf2(-inf_f128, -2, 0); try test__powitf2(-inf_f128, -2, 0);
try test__powitf2(-inf_f128, -3, -0.0); try test__powitf2(-inf_f128, -3, -0.0);
try test__powitf2(-inf_f128, -4, 0); try test__powitf2(-inf_f128, -4, 0);
try test__powitf2(-inf_f128, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powitf2(-inf_f128, @bitCast(i32, @as(u32, 0x80000001)), -0.0); try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
try test__powitf2(-inf_f128, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powitf2(-inf_f128, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powitf2(2, 10, 1024.0); try test__powitf2(2, 10, 1024.0);
try test__powitf2(-2, 10, 1024.0); try test__powitf2(-2, 10, 1024.0);
@ -473,76 +473,76 @@ test "powixf2" {
try test__powixf2(0, 2, 0); try test__powixf2(0, 2, 0);
try test__powixf2(0, 3, 0); try test__powixf2(0, 3, 0);
try test__powixf2(0, 4, 0); try test__powixf2(0, 4, 0);
try test__powixf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powixf2(0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 0); try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 0);
try test__powixf2(-0.0, 1, -0.0); try test__powixf2(-0.0, 1, -0.0);
try test__powixf2(-0.0, 2, 0); try test__powixf2(-0.0, 2, 0);
try test__powixf2(-0.0, 3, -0.0); try test__powixf2(-0.0, 3, -0.0);
try test__powixf2(-0.0, 4, 0); try test__powixf2(-0.0, 4, 0);
try test__powixf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 0); try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 0);
try test__powixf2(-0.0, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -0.0); try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -0.0);
try test__powixf2(1, 1, 1); try test__powixf2(1, 1, 1);
try test__powixf2(1, 2, 1); try test__powixf2(1, 2, 1);
try test__powixf2(1, 3, 1); try test__powixf2(1, 3, 1);
try test__powixf2(1, 4, 1); try test__powixf2(1, 4, 1);
try test__powixf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFE)), 1); try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), 1);
try test__powixf2(1, @bitCast(i32, @as(u32, 0x7FFFFFFF)), 1); try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), 1);
try test__powixf2(inf_f80, 1, inf_f80); try test__powixf2(inf_f80, 1, inf_f80);
try test__powixf2(inf_f80, 2, inf_f80); try test__powixf2(inf_f80, 2, inf_f80);
try test__powixf2(inf_f80, 3, inf_f80); try test__powixf2(inf_f80, 3, inf_f80);
try test__powixf2(inf_f80, 4, inf_f80); try test__powixf2(inf_f80, 4, inf_f80);
try test__powixf2(inf_f80, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f80); try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
try test__powixf2(inf_f80, @bitCast(i32, @as(u32, 0x7FFFFFFF)), inf_f80); try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), inf_f80);
try test__powixf2(-inf_f80, 1, -inf_f80); try test__powixf2(-inf_f80, 1, -inf_f80);
try test__powixf2(-inf_f80, 2, inf_f80); try test__powixf2(-inf_f80, 2, inf_f80);
try test__powixf2(-inf_f80, 3, -inf_f80); try test__powixf2(-inf_f80, 3, -inf_f80);
try test__powixf2(-inf_f80, 4, inf_f80); try test__powixf2(-inf_f80, 4, inf_f80);
try test__powixf2(-inf_f80, @bitCast(i32, @as(u32, 0x7FFFFFFE)), inf_f80); try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFE))), inf_f80);
try test__powixf2(-inf_f80, @bitCast(i32, @as(u32, 0x7FFFFFFF)), -inf_f80); try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x7FFFFFFF))), -inf_f80);
try test__powixf2(0, -1, inf_f80); try test__powixf2(0, -1, inf_f80);
try test__powixf2(0, -2, inf_f80); try test__powixf2(0, -2, inf_f80);
try test__powixf2(0, -3, inf_f80); try test__powixf2(0, -3, inf_f80);
try test__powixf2(0, -4, inf_f80); try test__powixf2(0, -4, inf_f80);
try test__powixf2(0, @bitCast(i32, @as(u32, 0x80000002)), inf_f80); try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
try test__powixf2(0, @bitCast(i32, @as(u32, 0x80000001)), inf_f80); try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000001))), inf_f80);
try test__powixf2(0, @bitCast(i32, @as(u32, 0x80000000)), inf_f80); try test__powixf2(0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
try test__powixf2(-0.0, -1, -inf_f80); try test__powixf2(-0.0, -1, -inf_f80);
try test__powixf2(-0.0, -2, inf_f80); try test__powixf2(-0.0, -2, inf_f80);
try test__powixf2(-0.0, -3, -inf_f80); try test__powixf2(-0.0, -3, -inf_f80);
try test__powixf2(-0.0, -4, inf_f80); try test__powixf2(-0.0, -4, inf_f80);
try test__powixf2(-0.0, @bitCast(i32, @as(u32, 0x80000002)), inf_f80); try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000002))), inf_f80);
try test__powixf2(-0.0, @bitCast(i32, @as(u32, 0x80000001)), -inf_f80); try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000001))), -inf_f80);
try test__powixf2(-0.0, @bitCast(i32, @as(u32, 0x80000000)), inf_f80); try test__powixf2(-0.0, @as(i32, @bitCast(@as(u32, 0x80000000))), inf_f80);
try test__powixf2(1, -1, 1); try test__powixf2(1, -1, 1);
try test__powixf2(1, -2, 1); try test__powixf2(1, -2, 1);
try test__powixf2(1, -3, 1); try test__powixf2(1, -3, 1);
try test__powixf2(1, -4, 1); try test__powixf2(1, -4, 1);
try test__powixf2(1, @bitCast(i32, @as(u32, 0x80000002)), 1); try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000002))), 1);
try test__powixf2(1, @bitCast(i32, @as(u32, 0x80000001)), 1); try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__powixf2(1, @bitCast(i32, @as(u32, 0x80000000)), 1); try test__powixf2(1, @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__powixf2(inf_f80, -1, 0); try test__powixf2(inf_f80, -1, 0);
try test__powixf2(inf_f80, -2, 0); try test__powixf2(inf_f80, -2, 0);
try test__powixf2(inf_f80, -3, 0); try test__powixf2(inf_f80, -3, 0);
try test__powixf2(inf_f80, -4, 0); try test__powixf2(inf_f80, -4, 0);
try test__powixf2(inf_f80, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powixf2(inf_f80, @bitCast(i32, @as(u32, 0x80000001)), 0); try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__powixf2(inf_f80, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powixf2(inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powixf2(-inf_f80, -1, -0.0); try test__powixf2(-inf_f80, -1, -0.0);
try test__powixf2(-inf_f80, -2, 0); try test__powixf2(-inf_f80, -2, 0);
try test__powixf2(-inf_f80, -3, -0.0); try test__powixf2(-inf_f80, -3, -0.0);
try test__powixf2(-inf_f80, -4, 0); try test__powixf2(-inf_f80, -4, 0);
try test__powixf2(-inf_f80, @bitCast(i32, @as(u32, 0x80000002)), 0); try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000002))), 0);
try test__powixf2(-inf_f80, @bitCast(i32, @as(u32, 0x80000001)), -0.0); try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000001))), -0.0);
try test__powixf2(-inf_f80, @bitCast(i32, @as(u32, 0x80000000)), 0); try test__powixf2(-inf_f80, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__powixf2(2, 10, 1024.0); try test__powixf2(2, 10, 1024.0);
try test__powixf2(-2, 10, 1024.0); try test__powixf2(-2, 10, 1024.0);

Some files were not shown because too many files have changed in this diff Show More