Merge pull request #16163 from mlugg/feat/builtins-infer-dest-ty

Infer destination type of cast builtins using result type
This commit is contained in:
Andrew Kelley 2023-06-24 16:58:19 -07:00 committed by GitHub
commit 146b79af15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
654 changed files with 9885 additions and 9581 deletions

View File

@ -2410,7 +2410,7 @@ var some_integers: [100]i32 = undefined;
test "modify an array" {
for (&some_integers, 0..) |*item, i| {
item.* = @intCast(i32, i);
item.* = @intCast(i);
}
try expect(some_integers[10] == 10);
try expect(some_integers[99] == 99);
@ -2452,8 +2452,8 @@ var fancy_array = init: {
var initial_value: [10]Point = undefined;
for (&initial_value, 0..) |*pt, i| {
pt.* = Point{
.x = @intCast(i32, i),
.y = @intCast(i32, i) * 2,
.x = @intCast(i),
.y = @intCast(i * 2),
};
}
break :init initial_value;
@ -2769,7 +2769,7 @@ test "comptime pointers" {
const expect = @import("std").testing.expect;
test "@intFromPtr and @ptrFromInt" {
const ptr = @ptrFromInt(*i32, 0xdeadbee0);
const ptr: *i32 = @ptrFromInt(0xdeadbee0);
const addr = @intFromPtr(ptr);
try expect(@TypeOf(addr) == usize);
try expect(addr == 0xdeadbee0);
@ -2784,7 +2784,7 @@ test "comptime @ptrFromInt" {
comptime {
// Zig is able to do this at compile-time, as long as
// ptr is never dereferenced.
const ptr = @ptrFromInt(*i32, 0xdeadbee0);
const ptr: *i32 = @ptrFromInt(0xdeadbee0);
const addr = @intFromPtr(ptr);
try expect(@TypeOf(addr) == usize);
try expect(addr == 0xdeadbee0);
@ -2801,7 +2801,7 @@ test "comptime @ptrFromInt" {
const expect = @import("std").testing.expect;
test "volatile" {
const mmio_ptr = @ptrFromInt(*volatile u8, 0x12345678);
const mmio_ptr: *volatile u8 = @ptrFromInt(0x12345678);
try expect(@TypeOf(mmio_ptr) == *volatile u8);
}
{#code_end#}
@ -2822,7 +2822,7 @@ const expect = std.testing.expect;
test "pointer casting" {
const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 };
const u32_ptr = @ptrCast(*const u32, &bytes);
const u32_ptr: *const u32 = @ptrCast(&bytes);
try expect(u32_ptr.* == 0x12121212);
// Even this example is contrived - there are better ways to do the above than
@ -2831,7 +2831,7 @@ test "pointer casting" {
try expect(u32_value == 0x12121212);
// And even another way, the most straightforward way to do it:
try expect(@bitCast(u32, bytes) == 0x12121212);
try expect(@as(u32, @bitCast(bytes)) == 0x12121212);
}
test "pointer child type" {
@ -2921,7 +2921,7 @@ test "pointer alignment safety" {
}
fn foo(bytes: []u8) u32 {
const slice4 = bytes[1..5];
const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
const int_slice = std.mem.bytesAsSlice(u32, @as([]align(4) u8, @alignCast(slice4)));
return int_slice[0];
}
{#code_end#}
@ -2942,7 +2942,7 @@ const expect = std.testing.expect;
test "allowzero" {
var zero: usize = 0;
var ptr = @ptrFromInt(*allowzero i32, zero);
var ptr: *allowzero i32 = @ptrFromInt(zero);
try expect(@intFromPtr(ptr) == 0);
}
{#code_end#}
@ -3354,12 +3354,12 @@ fn doTheTest() !void {
try expect(@sizeOf(Full) == 2);
try expect(@sizeOf(Divided) == 2);
var full = Full{ .number = 0x1234 };
var divided = @bitCast(Divided, full);
var divided: Divided = @bitCast(full);
try expect(divided.half1 == 0x34);
try expect(divided.quarter3 == 0x2);
try expect(divided.quarter4 == 0x1);
var ordered = @bitCast([2]u8, full);
var ordered: [2]u8 = @bitCast(full);
switch (native_endian) {
.Big => {
try expect(ordered[0] == 0x12);
@ -4428,7 +4428,7 @@ fn getNum(u: U) u32 {
// `u.a` or `u.b` and `tag` is `u`'s comptime-known tag value.
inline else => |num, tag| {
if (tag == .b) {
return @intFromFloat(u32, num);
return @intFromFloat(num);
}
return num;
}
@ -4714,7 +4714,7 @@ test "for basics" {
var sum2: i32 = 0;
for (items, 0..) |_, i| {
try expect(@TypeOf(i) == usize);
sum2 += @intCast(i32, i);
sum2 += @as(i32, @intCast(i));
}
try expect(sum2 == 10);
@ -6363,7 +6363,7 @@ const mem = std.mem;
test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
const window_name = [1][*]const u8{"window name"};
const x: [*]const ?[*]const u8 = &window_name;
try expect(mem.eql(u8, std.mem.sliceTo(@ptrCast([*:0]const u8, x[0].?), 0), "window name"));
try expect(mem.eql(u8, std.mem.sliceTo(@as([*:0]const u8, @ptrCast(x[0].?)), 0), "window name"));
}
{#code_end#}
{#header_close#}
@ -6760,8 +6760,8 @@ fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
}
test "peer type resolution: *const T and ?*T" {
const a = @ptrFromInt(*const usize, 0x123456780);
const b = @ptrFromInt(?*usize, 0x123456780);
const a: *const usize = @ptrFromInt(0x123456780);
const b: ?*usize = @ptrFromInt(0x123456780);
try expect(a == b);
try expect(b == a);
}
@ -7762,12 +7762,13 @@ test "global assembly" {
at compile time.
</p>
{#header_open|@addrSpaceCast#}
<pre>{#syntax#}@addrSpaceCast(comptime addrspace: std.builtin.AddressSpace, ptr: anytype) anytype{#endsyntax#}</pre>
<pre>{#syntax#}@addrSpaceCast(ptr: anytype) anytype{#endsyntax#}</pre>
<p>
Converts a pointer from one address space to another. Depending on the current target and
address spaces, this cast may be a no-op, a complex operation, or illegal. If the cast is
legal, then the resulting pointer points to the same memory location as the pointer operand.
It is always valid to cast a pointer between the same address spaces.
Converts a pointer from one address space to another. The new address space is inferred
based on the result type. Depending on the current target and address spaces, this cast
may be a no-op, a complex operation, or illegal. If the cast is legal, then the resulting
pointer points to the same memory location as the pointer operand. It is always valid to
cast a pointer between the same address spaces.
</p>
{#header_close#}
{#header_open|@addWithOverflow#}
@ -7777,10 +7778,10 @@ test "global assembly" {
</p>
{#header_close#}
{#header_open|@alignCast#}
<pre>{#syntax#}@alignCast(comptime alignment: u29, ptr: anytype) anytype{#endsyntax#}</pre>
<pre>{#syntax#}@alignCast(ptr: anytype) anytype{#endsyntax#}</pre>
<p>
{#syntax#}ptr{#endsyntax#} can be {#syntax#}*T{#endsyntax#}, {#syntax#}?*T{#endsyntax#}, or {#syntax#}[]T{#endsyntax#}.
It returns the same type as {#syntax#}ptr{#endsyntax#} except with the alignment adjusted to the new value.
Changes the alignment of a pointer. The alignment to use is inferred based on the result type.
</p>
<p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added
to the generated code to make sure the pointer is aligned as promised.</p>
@ -7865,9 +7866,10 @@ comptime {
{#header_close#}
{#header_open|@bitCast#}
<pre>{#syntax#}@bitCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@bitCast(value: anytype) anytype{#endsyntax#}</pre>
<p>
Converts a value of one type to another type.
Converts a value of one type to another type. The return type is the
inferred result type.
</p>
<p>
Asserts that {#syntax#}@sizeOf(@TypeOf(value)) == @sizeOf(DestType){#endsyntax#}.
@ -8420,10 +8422,11 @@ test "main" {
{#header_close#}
{#header_open|@errSetCast#}
<pre>{#syntax#}@errSetCast(comptime T: DestType, value: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@errSetCast(value: anytype) anytype{#endsyntax#}</pre>
<p>
Converts an error value from one error set to another error set. Attempting to convert an error
which is not in the destination error set results in safety-protected {#link|Undefined Behavior#}.
Converts an error value from one error set to another error set. The return type is the
inferred result type. Attempting to convert an error which is not in the destination error
set results in safety-protected {#link|Undefined Behavior#}.
</p>
{#header_close#}
@ -8535,17 +8538,17 @@ test "decl access by string" {
{#header_close#}
{#header_open|@floatCast#}
<pre>{#syntax#}@floatCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@floatCast(value: anytype) anytype{#endsyntax#}</pre>
<p>
Convert from one float type to another. This cast is safe, but may cause the
numeric value to lose precision.
numeric value to lose precision. The return type is the inferred result type.
</p>
{#header_close#}
{#header_open|@intFromFloat#}
<pre>{#syntax#}@intFromFloat(comptime DestType: type, float: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@intFromFloat(float: anytype) anytype{#endsyntax#}</pre>
<p>
Converts the integer part of a floating point number to the destination type.
Converts the integer part of a floating point number to the inferred result type.
</p>
<p>
If the integer part of the floating point number cannot fit in the destination type,
@ -8660,16 +8663,17 @@ test "@hasDecl" {
{#header_close#}
{#header_open|@intCast#}
<pre>{#syntax#}@intCast(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@intCast(int: anytype) anytype{#endsyntax#}</pre>
<p>
Converts an integer to another integer while keeping the same numerical value.
The return type is the inferred result type.
Attempting to convert a number which is out of range of the destination type results in
safety-protected {#link|Undefined Behavior#}.
</p>
{#code_begin|test_err|test_intCast_builtin|cast truncated bits#}
test "integer cast panic" {
var a: u16 = 0xabcd;
var b: u8 = @intCast(u8, a);
var b: u8 = @intCast(a);
_ = b;
}
{#code_end#}
@ -8683,9 +8687,9 @@ test "integer cast panic" {
{#header_close#}
{#header_open|@enumFromInt#}
<pre>{#syntax#}@enumFromInt(comptime DestType: type, integer: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@enumFromInt(integer: anytype) anytype{#endsyntax#}</pre>
<p>
Converts an integer into an {#link|enum#} value.
Converts an integer into an {#link|enum#} value. The return type is the inferred result type.
</p>
<p>
Attempting to convert an integer which represents no value in the chosen enum type invokes
@ -8711,16 +8715,18 @@ test "integer cast panic" {
{#header_close#}
{#header_open|@floatFromInt#}
<pre>{#syntax#}@floatFromInt(comptime DestType: type, int: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@floatFromInt(int: anytype) anytype{#endsyntax#}</pre>
<p>
Converts an integer to the closest floating point representation. To convert the other way, use {#link|@intFromFloat#}. This cast is always safe.
Converts an integer to the closest floating point representation. The return type is the inferred result type.
To convert the other way, use {#link|@intFromFloat#}. This cast is always safe.
</p>
{#header_close#}
{#header_open|@ptrFromInt#}
<pre>{#syntax#}@ptrFromInt(comptime DestType: type, address: usize) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@ptrFromInt(address: usize) anytype{#endsyntax#}</pre>
<p>
Converts an integer to a {#link|pointer|Pointers#}. To convert the other way, use {#link|@intFromPtr#}. Casting an address of 0 to a destination type
Converts an integer to a {#link|pointer|Pointers#}. The return type is the inferred result type.
To convert the other way, use {#link|@intFromPtr#}. Casting an address of 0 to a destination type
which in not {#link|optional|Optional Pointers#} and does not have the {#syntax#}allowzero{#endsyntax#} attribute will result in a
{#link|Pointer Cast Invalid Null#} panic when runtime safety checks are enabled.
</p>
@ -8924,9 +8930,9 @@ pub const PrefetchOptions = struct {
{#header_close#}
{#header_open|@ptrCast#}
<pre>{#syntax#}@ptrCast(comptime DestType: type, value: anytype) DestType{#endsyntax#}</pre>
<pre>{#syntax#}@ptrCast(value: anytype) anytype{#endsyntax#}</pre>
<p>
Converts a pointer of one type to a pointer of another type.
Converts a pointer of one type to a pointer of another type. The return type is the inferred result type.
</p>
<p>
{#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
@ -9522,10 +9528,10 @@ fn List(comptime T: type) type {
{#header_close#}
{#header_open|@truncate#}
<pre>{#syntax#}@truncate(comptime T: type, integer: anytype) T{#endsyntax#}</pre>
<pre>{#syntax#}@truncate(integer: anytype) anytype{#endsyntax#}</pre>
<p>
This function truncates bits from an integer type, resulting in a smaller
or same-sized integer type.
or same-sized integer type. The return type is the inferred result type.
</p>
<p>
This function always truncates the significant bits of the integer, regardless
@ -9540,7 +9546,7 @@ const expect = std.testing.expect;
test "integer truncation" {
var a: u16 = 0xabcd;
var b: u8 = @truncate(u8, a);
var b: u8 = @truncate(a);
try expect(b == 0xcd);
}
{#code_end#}
@ -9838,7 +9844,7 @@ fn foo(x: []const u8) u8 {
{#code_begin|test_err|test_comptime_invalid_cast|type 'u32' cannot represent integer value '-1'#}
comptime {
var value: i32 = -1;
const unsigned = @intCast(u32, value);
const unsigned: u32 = @intCast(value);
_ = unsigned;
}
{#code_end#}
@ -9848,7 +9854,7 @@ const std = @import("std");
pub fn main() void {
var value: i32 = -1;
var unsigned = @intCast(u32, value);
var unsigned: u32 = @intCast(value);
std.debug.print("value: {}\n", .{unsigned});
}
{#code_end#}
@ -9861,7 +9867,7 @@ pub fn main() void {
{#code_begin|test_err|test_comptime_invalid_cast_truncate|type 'u8' cannot represent integer value '300'#}
comptime {
const spartan_count: u16 = 300;
const byte = @intCast(u8, spartan_count);
const byte: u8 = @intCast(spartan_count);
_ = byte;
}
{#code_end#}
@ -9871,7 +9877,7 @@ const std = @import("std");
pub fn main() void {
var spartan_count: u16 = 300;
const byte = @intCast(u8, spartan_count);
const byte: u8 = @intCast(spartan_count);
std.debug.print("value: {}\n", .{byte});
}
{#code_end#}
@ -10208,7 +10214,7 @@ const Foo = enum {
};
comptime {
const a: u2 = 3;
const b = @enumFromInt(Foo, a);
const b: Foo = @enumFromInt(a);
_ = b;
}
{#code_end#}
@ -10224,7 +10230,7 @@ const Foo = enum {
pub fn main() void {
var a: u2 = 3;
var b = @enumFromInt(Foo, a);
var b: Foo = @enumFromInt(a);
std.debug.print("value: {s}\n", .{@tagName(b)});
}
{#code_end#}
@ -10242,7 +10248,7 @@ const Set2 = error{
C,
};
comptime {
_ = @errSetCast(Set2, Set1.B);
_ = @as(Set2, @errSetCast(Set1.B));
}
{#code_end#}
<p>At runtime:</p>
@ -10261,7 +10267,7 @@ pub fn main() void {
foo(Set1.B);
}
fn foo(set1: Set1) void {
const x = @errSetCast(Set2, set1);
const x = @as(Set2, @errSetCast(set1));
std.debug.print("value: {}\n", .{x});
}
{#code_end#}
@ -10271,8 +10277,8 @@ fn foo(set1: Set1) void {
<p>At compile-time:</p>
{#code_begin|test_err|test_comptime_incorrect_pointer_alignment|pointer address 0x1 is not aligned to 4 bytes#}
comptime {
const ptr = @ptrFromInt(*align(1) i32, 0x1);
const aligned = @alignCast(4, ptr);
const ptr: *align(1) i32 = @ptrFromInt(0x1);
const aligned: *align(4) i32 = @alignCast(ptr);
_ = aligned;
}
{#code_end#}
@ -10286,7 +10292,7 @@ pub fn main() !void {
}
fn foo(bytes: []u8) u32 {
const slice4 = bytes[1..5];
const int_slice = mem.bytesAsSlice(u32, @alignCast(4, slice4));
const int_slice = mem.bytesAsSlice(u32, @as([]align(4) u8, @alignCast(slice4)));
return int_slice[0];
}
{#code_end#}
@ -10387,7 +10393,7 @@ fn bar(f: *Foo) void {
{#code_begin|test_err|test_comptime_invalid_null_pointer_cast|null pointer casted to type#}
comptime {
const opt_ptr: ?*i32 = null;
const ptr = @ptrCast(*i32, opt_ptr);
const ptr: *i32 = @ptrCast(opt_ptr);
_ = ptr;
}
{#code_end#}
@ -10395,7 +10401,7 @@ comptime {
{#code_begin|exe_err|runtime_invalid_null_pointer_cast#}
pub fn main() void {
var opt_ptr: ?*i32 = null;
var ptr = @ptrCast(*i32, opt_ptr);
var ptr: *i32 = @ptrCast(opt_ptr);
_ = ptr;
}
{#code_end#}

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 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 bRep = @bitCast(Z, b);
var aRep = @as(Z, @bitCast(a));
var bRep = @as(Z, @bitCast(b));
const aAbs = aRep & 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.
if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or
bAbs -% @as(Z, 1) >= infRep - @as(Z, 1))
{
// 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
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) {
// +/-infinity + -/+infinity = qNaN
if ((@bitCast(Z, a) ^ @bitCast(Z, b)) == signBit) {
return @bitCast(T, qnanRep);
if ((@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) == signBit) {
return @as(T, @bitCast(qnanRep));
}
// +/-infinity + anything remaining = +/- infinity
else {
@ -60,7 +60,7 @@ pub inline fn addf3(comptime T: type, a: T, b: T) T {
if (aAbs == 0) {
// but we need to get the sign right for zero + zero
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 {
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.
var aExponent = @intCast(i32, (aRep >> significandBits) & maxExponent);
var bExponent = @intCast(i32, (bRep >> significandBits) & maxExponent);
var aExponent = @as(i32, @intCast((aRep >> significandBits) & maxExponent));
var bExponent = @as(i32, @intCast((bRep >> significandBits) & maxExponent));
var aSignificand = aRep & 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
// bottom bit to get rounding correct.
const @"align" = @intCast(u32, aExponent - bExponent);
const @"align" = @as(u32, @intCast(aExponent - bExponent));
if (@"align" != 0) {
if (@"align" < typeWidth) {
const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) @as(Z, 1) else 0;
bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky;
const sticky = if (bSignificand << @as(S, @intCast(typeWidth - @"align")) != 0) @as(Z, 1) else 0;
bSignificand = (bSignificand >> @as(S, @truncate(@"align"))) | sticky;
} else {
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) {
aSignificand -= bSignificand;
// 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
// and adjust the exponent:
if (aSignificand < integerBit << 3) {
const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(integerBit << 3));
aSignificand <<= @intCast(S, shift);
const shift = @as(i32, @intCast(@clz(aSignificand))) - @as(i32, @intCast(@clz(integerBit << 3)));
aSignificand <<= @as(S, @intCast(shift));
aExponent -= shift;
}
} 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 (aExponent >= maxExponent) return @bitCast(T, infRep | resultSign);
if (aExponent >= maxExponent) return @as(T, @bitCast(infRep | resultSign));
if (aExponent <= 0) {
// 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.
aSignificand >>= @intCast(S, 4 - aExponent);
return @bitCast(T, resultSign | aSignificand);
aSignificand >>= @as(S, @intCast(4 - aExponent));
return @as(T, @bitCast(resultSign | aSignificand));
}
// 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;
// Insert the exponent and sign.
result |= @intCast(Z, aExponent) << significandBits;
result |= @as(Z, @intCast(aExponent)) << significandBits;
result |= resultSign;
// 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;
}
return @bitCast(T, result);
return @as(T, @bitCast(result));
}
test {

View File

@ -5,7 +5,7 @@
const std = @import("std");
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 __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 {
const x = __addtf3(a, b);
const rep = @bitCast(u128, x);
const hi = @intCast(u64, rep >> 64);
const lo = @truncate(u64, rep);
const rep = @as(u128, @bitCast(x));
const hi = @as(u64, @intCast(rep >> 64));
const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo) {
return;
@ -37,7 +37,7 @@ test "addtf3" {
try test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// 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
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 {
const x = __subtf3(a, b);
const rep = @bitCast(u128, x);
const hi = @intCast(u64, rep >> 64);
const lo = @truncate(u64, rep);
const rep = @as(u128, @bitCast(x));
const hi = @as(u64, @intCast(rep >> 64));
const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo) {
return;
@ -77,7 +77,7 @@ test "subtf3" {
try test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
// 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
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);
}
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 {
const x = __addxf3(a, b);
const rep = @bitCast(u80, x);
const rep = @as(u80, @bitCast(x));
if (rep == expected)
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 error.TestFailed;
@ -104,33 +104,33 @@ fn test__addxf3(a: f80, b: f80, expected: u80) !void {
test "addxf3" {
// NaN + any = NaN
try test__addxf3(qnan80, 0x1.23456789abcdefp+5, @bitCast(u80, qnan80));
try test__addxf3(@bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), 0x1.23456789abcdefp+5, @bitCast(u80, qnan80));
try test__addxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
try test__addxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
// any + NaN = NaN
try test__addxf3(0x1.23456789abcdefp+5, qnan80, @bitCast(u80, 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, qnan80, @as(u80, @bitCast(qnan80)));
try test__addxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
// 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
try test__addxf3(math.inf(f80), qnan80, @bitCast(u80, qnan80));
try test__addxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80)));
// 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
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
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
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
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
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 {
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;
}

View File

@ -232,16 +232,16 @@ fn wideUpdate(comptime T: type, ptr: *T, val: T, update: anytype) T {
const addr = @intFromPtr(ptr);
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_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;
var wide_old = @atomicLoad(WideAtomic, wide_ptr, .SeqCst);
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 wide_new = wide_old & ~mask | (@as(WideAtomic, new) << inner_shift);
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 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;
return (@bitCast(i64, r) ^ s) -% s;
return (@as(i64, @bitCast(r)) ^ s) -% s;
}
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 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;
return (@bitCast(i64, r) ^ s) -% s;
return (@as(i64, @bitCast(r)) ^ s) -% s;
}
pub fn _aullrem() callconv(.Naked) void {

View File

@ -27,12 +27,12 @@ comptime {
pub fn __ceilh(x: f16) callconv(.C) f16 {
// TODO: more efficient implementation
return @floatCast(f16, ceilf(x));
return @as(f16, @floatCast(ceilf(x)));
}
pub fn ceilf(x: f32) callconv(.C) f32 {
var u = @bitCast(u32, x);
var e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F;
var u = @as(u32, @bitCast(x));
var e = @as(i32, @intCast((u >> 23) & 0xFF)) - 0x7F;
var m: u32 = undefined;
// TODO: Shouldn't need this explicit check.
@ -43,7 +43,7 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
if (e >= 23) {
return x;
} else if (e >= 0) {
m = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
m = @as(u32, 0x007FFFFF) >> @as(u5, @intCast(e));
if (u & m == 0) {
return x;
}
@ -52,7 +52,7 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
u += m;
}
u &= ~m;
return @bitCast(f32, u);
return @as(f32, @bitCast(u));
} else {
math.doNotOptimizeAway(x + 0x1.0p120);
if (u >> 31 != 0) {
@ -66,7 +66,7 @@ pub fn ceilf(x: f32) callconv(.C) f32 {
pub fn ceil(x: f64) callconv(.C) 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;
var y: f64 = undefined;
@ -96,13 +96,13 @@ pub fn ceil(x: f64) callconv(.C) f64 {
pub fn __ceilx(x: f80) callconv(.C) f80 {
// TODO: more efficient implementation
return @floatCast(f80, ceilq(x));
return @as(f80, @floatCast(ceilq(x)));
}
pub fn ceilq(x: f128) callconv(.C) 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;
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
// is not required for instruction to data coherence.
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);
while (addr < end) : (addr += dcache_line_size) {
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
// unification is not required for instruction to data coherence.
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);
while (addr < end) : (addr += icache_line_size) {
asm volatile ("ic ivau, %[addr]"

View File

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

View File

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

View File

@ -2,7 +2,7 @@ const clz = @import("count0bits.zig");
const testing = @import("std").testing;
fn test__clzti2(a: u128, expected: i64) !void {
var x = @bitCast(i128, a);
var x = @as(i128, @bitCast(a));
var result = clz.__clzti2(x);
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 {
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 {
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 {
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 {
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 {
return switch (@enumFromInt(SparcFCMP, _Qp_cmp(a, b))) {
return switch (@as(SparcFCMP, @enumFromInt(_Qp_cmp(a, b)))) {
.Equal, .Greater => true,
.Less, .Unordered => false,
};
}
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,
.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 => {
// 16x16 --> 32 bit multiply
const product = @as(u32, a) * @as(u32, b);
hi.* = @intCast(u16, product >> 16);
lo.* = @truncate(u16, product);
hi.* = @as(u16, @intCast(product >> 16));
lo.* = @as(u16, @truncate(product));
},
u32 => {
// 32x32 --> 64 bit multiply
const product = @as(u64, a) * @as(u64, b);
hi.* = @truncate(u32, product >> 32);
lo.* = @truncate(u32, product);
hi.* = @as(u32, @truncate(product >> 32));
lo.* = @as(u32, @truncate(product));
},
u64 => {
const S = struct {
fn loWord(x: u64) u64 {
return @truncate(u32, x);
return @as(u32, @truncate(x));
}
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;
@ -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 S = struct {
fn Word_1(x: u128) u64 {
return @truncate(u32, x >> 96);
return @as(u32, @truncate(x >> 96));
}
fn Word_2(x: u128) u64 {
return @truncate(u32, x >> 64);
return @as(u32, @truncate(x >> 64));
}
fn Word_3(x: u128) u64 {
return @truncate(u32, x >> 32);
return @as(u32, @truncate(x >> 32));
}
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;
@ -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 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;
}
@ -228,8 +228,8 @@ pub inline fn fneg(a: anytype) @TypeOf(a) {
.bits = bits,
} });
const sign_bit_mask = @as(U, 1) << (bits - 1);
const negated = @bitCast(U, a) ^ sign_bit_mask;
return @bitCast(F, negated);
const negated = @as(U, @bitCast(a)) ^ sign_bit_mask;
return @as(F, @bitCast(negated));
}
/// 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 absMask = signBit - 1;
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 bInt = @bitCast(srep_t, b);
const aAbs = @bitCast(rep_t, aInt) & absMask;
const bAbs = @bitCast(rep_t, bInt) & absMask;
const aInt = @as(srep_t, @bitCast(a));
const bInt = @as(srep_t, @bitCast(b));
const aAbs = @as(rep_t, @bitCast(aInt)) & absMask;
const bAbs = @as(rep_t, @bitCast(bInt)) & absMask;
// If either a or b is NaN, they are 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;
} else if (a_rep.exp & sign_bit != b_rep.exp & sign_bit) {
// 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;
} else {
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 signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
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 bAbs: rep_t = @bitCast(rep_t, b) & absMask;
const aAbs: rep_t = @as(rep_t, @bitCast(a)) & absMask;
const bAbs: rep_t = @as(rep_t, @bitCast(b)) & absMask;
return @intFromBool(aAbs > infRep or bAbs > infRep);
}

View File

@ -25,7 +25,7 @@ comptime {
pub fn __cosh(a: f16) callconv(.C) f16 {
// TODO: more efficient implementation
return @floatCast(f16, cosf(a));
return @as(f16, @floatCast(cosf(a)));
}
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 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;
ix &= 0x7fffffff;
@ -86,7 +86,7 @@ pub fn cosf(x: f32) callconv(.C) f32 {
}
pub fn cos(x: f64) callconv(.C) f64 {
var ix = @bitCast(u64, x) >> 32;
var ix = @as(u64, @bitCast(x)) >> 32;
ix &= 0x7fffffff;
// |x| ~< pi/4
@ -116,12 +116,12 @@ pub fn cos(x: f64) callconv(.C) f64 {
pub fn __cosx(a: f80) callconv(.C) f80 {
// TODO: more efficient implementation
return @floatCast(f80, cosq(a));
return @as(f80, @floatCast(cosq(a)));
}
pub fn cosq(a: f128) callconv(.C) f128 {
// 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 {

View File

@ -32,9 +32,9 @@ comptime {
inline fn clzXi2(comptime T: type, a: T) i32 {
var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a),
64 => @bitCast(u64, a),
128 => @bitCast(u128, a),
32 => @as(u32, @bitCast(a)),
64 => @as(u64, @bitCast(a)),
128 => @as(u128, @bitCast(a)),
else => unreachable,
};
var n: T = @bitSizeOf(T);
@ -49,7 +49,7 @@ inline fn clzXi2(comptime T: type, a: T) i32 {
x = y;
}
}
return @intCast(i32, n - @bitCast(T, x));
return @as(i32, @intCast(n - @as(T, @bitCast(x))));
}
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 {
var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a),
64 => @bitCast(u64, a),
128 => @bitCast(u128, a),
32 => @as(u32, @bitCast(a)),
64 => @as(u64, @bitCast(a)),
128 => @as(u128, @bitCast(a)),
else => unreachable,
};
var n: T = 1;
@ -187,7 +187,7 @@ inline fn ctzXi2(comptime T: type, a: T) i32 {
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 {
@ -204,9 +204,9 @@ pub fn __ctzti2(a: i128) callconv(.C) i32 {
inline fn ffsXi2(comptime T: type, a: T) i32 {
var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a),
64 => @bitCast(u64, a),
128 => @bitCast(u128, a),
32 => @as(u32, @bitCast(a)),
64 => @as(u64, @bitCast(a)),
128 => @as(u128, @bitCast(a)),
else => unreachable,
};
var n: T = 1;
@ -224,7 +224,7 @@ inline fn ffsXi2(comptime T: type, a: T) i32 {
}
}
// 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 {

View File

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

View File

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

View File

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

View File

@ -47,52 +47,52 @@ inline fn div(a: f64, b: f64) f64 {
const absMask = signBit - 1;
const exponentMask = absMask ^ significandMask;
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 bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent);
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit;
const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask;
var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask;
const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// 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
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) {
// infinity / infinity = NaN
if (bAbs == infRep) {
return @bitCast(f64, qnanRep);
return @as(f64, @bitCast(qnanRep));
}
// infinity / anything else = +/- infinity
else {
return @bitCast(f64, aAbs | quotientSign);
return @as(f64, @bitCast(aAbs | quotientSign));
}
}
// anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(f64, quotientSign);
if (bAbs == infRep) return @as(f64, @bitCast(quotientSign));
if (aAbs == 0) {
// zero / zero = NaN
if (bAbs == 0) {
return @bitCast(f64, qnanRep);
return @as(f64, @bitCast(qnanRep));
}
// zero / anything else = +/- zero
else {
return @bitCast(f64, quotientSign);
return @as(f64, @bitCast(quotientSign));
}
}
// 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
// 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.)
aSignificand |= 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
// [1, 2.0) and get a Q32 approximate reciprocal using a small minimax
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// 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;
// 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
// digits of accuracy.
var correction32: u32 = undefined;
correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
correction32 = @as(u32, @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1));
recip32 = @as(u32, @truncate(@as(u64, recip32) *% correction32 >> 31));
correction32 = @as(u32, @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1));
recip32 = @as(u32, @truncate(@as(u64, recip32) *% correction32 >> 31));
correction32 = @as(u32, @truncate(~(@as(u64, recip32) *% q31b >> 32) +% 1));
recip32 = @as(u32, @truncate(@as(u64, recip32) *% correction32 >> 31));
// recip32 might have overflowed to exactly zero in the preceding
// 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;
// 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 reciprocal: u64 = undefined;
correction = ~(@as(u64, recip32) *% q31b +% (@as(u64, recip32) *% q63blo >> 32)) +% 1;
const cHi = @truncate(u32, correction >> 32);
const cLo = @truncate(u32, correction);
const cHi = @as(u32, @truncate(correction >> 32));
const cLo = @as(u32, @truncate(correction));
reciprocal = @as(u64, recip32) *% cHi +% (@as(u64, recip32) *% cLo >> 32);
// 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 we have overflowed the exponent, return infinity.
return @bitCast(f64, infRep | quotientSign);
return @as(f64, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) {
if (writtenExponent == 0) {
// Check whether the rounded result is normal.
@ -206,22 +206,22 @@ inline fn div(a: f64, b: f64) f64 {
absResult += round;
if ((absResult & ~significandMask) != 0) {
// 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
// code to round them correctly.
return @bitCast(f64, quotientSign);
return @as(f64, @bitCast(quotientSign));
} else {
const round = @intFromBool((residual << 1) > bSignificand);
// Clear the implicit bit
var absResult = quotient & significandMask;
// Insert the exponent
absResult |= @bitCast(Z, @as(SignedZ, writtenExponent)) << significandBits;
absResult |= @as(Z, @bitCast(@as(SignedZ, writtenExponent))) << significandBits;
// Round
absResult +%= round;
// 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;
fn compareResultD(result: f64, expected: u64) bool {
const rep = @bitCast(u64, result);
const rep = @as(u64, @bitCast(result));
if (rep == expected) {
return true;

View File

@ -7,5 +7,5 @@ comptime {
pub fn __divhf3(a: f16, b: f16) callconv(.C) f16 {
// 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 exponentMask = absMask ^ significandMask;
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 bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent);
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit;
const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask;
var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask;
const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// 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
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) {
// infinity / infinity = NaN
if (bAbs == infRep) {
return @bitCast(f32, qnanRep);
return @as(f32, @bitCast(qnanRep));
}
// infinity / anything else = +/- infinity
else {
return @bitCast(f32, aAbs | quotientSign);
return @as(f32, @bitCast(aAbs | quotientSign));
}
}
// anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(f32, quotientSign);
if (bAbs == infRep) return @as(f32, @bitCast(quotientSign));
if (aAbs == 0) {
// zero / zero = NaN
if (bAbs == 0) {
return @bitCast(f32, qnanRep);
return @as(f32, @bitCast(qnanRep));
}
// zero / anything else = +/- zero
else {
return @bitCast(f32, quotientSign);
return @as(f32, @bitCast(quotientSign));
}
}
// 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
// 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.)
aSignificand |= 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
// [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
// digits of accuracy.
var correction: u32 = undefined;
correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
correction = @as(u32, @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1));
reciprocal = @as(u32, @truncate(@as(u64, reciprocal) *% correction >> 31));
correction = @as(u32, @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1));
reciprocal = @as(u32, @truncate(@as(u64, reciprocal) *% correction >> 31));
correction = @as(u32, @truncate(~(@as(u64, reciprocal) *% q31b >> 32) +% 1));
reciprocal = @as(u32, @truncate(@as(u64, reciprocal) *% correction >> 31));
// 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
@ -147,7 +147,7 @@ inline fn div(a: f32, b: f32) f32 {
// is the error in the reciprocal of b scaled by the maximum
// possible value of a. As a consequence of this error bound,
// 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).
// 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 we have overflowed the exponent, return infinity.
return @bitCast(f32, infRep | quotientSign);
return @as(f32, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) {
if (writtenExponent == 0) {
// Check whether the rounded result is normal.
@ -186,22 +186,22 @@ inline fn div(a: f32, b: f32) f32 {
absResult += round;
if ((absResult & ~significandMask) > 0) {
// 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
// code to round them correctly.
return @bitCast(f32, quotientSign);
return @as(f32, @bitCast(quotientSign));
} else {
const round = @intFromBool((residual << 1) > bSignificand);
// Clear the implicit bit
var absResult = quotient & significandMask;
// Insert the exponent
absResult |= @bitCast(Z, writtenExponent) << significandBits;
absResult |= @as(Z, @bitCast(writtenExponent)) << significandBits;
// Round
absResult +%= round;
// 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;
fn compareResultF(result: f32, expected: u32) bool {
const rep = @bitCast(u32, result);
const rep = @as(u32, @bitCast(result));
if (rep == expected) {
return true;

View File

@ -41,52 +41,52 @@ inline fn div(a: f128, b: f128) f128 {
const absMask = signBit - 1;
const exponentMask = absMask ^ significandMask;
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 bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent);
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit;
const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask;
var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask;
const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// 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
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) {
// infinity / infinity = NaN
if (bAbs == infRep) {
return @bitCast(f128, qnanRep);
return @as(f128, @bitCast(qnanRep));
}
// infinity / anything else = +/- infinity
else {
return @bitCast(f128, aAbs | quotientSign);
return @as(f128, @bitCast(aAbs | quotientSign));
}
}
// anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(f128, quotientSign);
if (bAbs == infRep) return @as(f128, @bitCast(quotientSign));
if (aAbs == 0) {
// zero / zero = NaN
if (bAbs == 0) {
return @bitCast(f128, qnanRep);
return @as(f128, @bitCast(qnanRep));
}
// zero / anything else = +/- zero
else {
return @bitCast(f128, quotientSign);
return @as(f128, @bitCast(quotientSign));
}
}
// 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
// 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.
aSignificand |= 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
// [1, 2.0) and get a Q64 approximate reciprocal using a small minimax
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// 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;
// 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
// with each iteration.
var correction64: u64 = undefined;
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
// 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
@ -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;
// 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 reciprocal: u128 = undefined;
@ -151,8 +151,8 @@ inline fn div(a: f128, b: f128) f128 {
correction = -%(r64q63 + (r64q127 >> 64));
const cHi = @truncate(u64, correction >> 64);
const cLo = @truncate(u64, correction);
const cHi = @as(u64, @truncate(correction >> 64));
const cLo = @as(u64, @truncate(correction));
wideMultiply(u128, recip64, cHi, &dummy, &r64cH);
wideMultiply(u128, recip64, cLo, &dummy, &r64cL);
@ -210,7 +210,7 @@ inline fn div(a: f128, b: f128) f128 {
if (writtenExponent >= maxExponent) {
// If we have overflowed the exponent, return infinity.
return @bitCast(f128, infRep | quotientSign);
return @as(f128, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) {
if (writtenExponent == 0) {
// Check whether the rounded result is normal.
@ -221,22 +221,22 @@ inline fn div(a: f128, b: f128) f128 {
absResult += round;
if ((absResult & ~significandMask) > 0) {
// 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
// code to round them correctly.
return @bitCast(f128, quotientSign);
return @as(f128, @bitCast(quotientSign));
} else {
const round = @intFromBool((residual << 1) >= bSignificand);
// Clear the implicit bit
var absResult = quotient & significandMask;
// Insert the exponent
absResult |= @intCast(Z, writtenExponent) << significandBits;
absResult |= @as(Z, @intCast(writtenExponent)) << significandBits;
// Round
absResult +%= round;
// 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;
fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
const rep = @bitCast(u128, result);
const hi = @truncate(u64, rep >> 64);
const lo = @truncate(u64, rep);
const rep = @as(u128, @bitCast(result));
const hi = @as(u64, @truncate(rep >> 64));
const lo = @as(u64, @truncate(rep));
if (hi == expectedHi and lo == expectedLo) {
return true;

View File

@ -21,7 +21,7 @@ pub fn __divti3(a: i128, b: i128) callconv(.C) i128 {
const v128 = @Vector(2, u64);
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 {
@ -31,9 +31,9 @@ inline fn div(a: i128, b: i128) i128 {
const an = (a ^ s_a) -% s_a;
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;
return (@bitCast(i128, r) ^ s) -% s;
return (@as(i128, @bitCast(r)) ^ s) -% s;
}
test {

View File

@ -14,8 +14,8 @@ test "divti3" {
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(@bitCast(i128, @as(u128, 0x8 << 124)), -1, @bitCast(i128, @as(u128, 0x8 << 124)));
try test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), -2, @bitCast(i128, @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))), 1, @as(i128, @bitCast(@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(@as(i128, @bitCast(@as(u128, 0x8 << 124))), -2, @as(i128, @bitCast(@as(u128, 0x4 << 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 absMask = signBit - 1;
const qnanRep = @bitCast(Z, std.math.nan(T)) | quietBit;
const infRep = @bitCast(Z, std.math.inf(T));
const qnanRep = @as(Z, @bitCast(std.math.nan(T))) | quietBit;
const infRep = @as(Z, @bitCast(std.math.inf(T)));
const aExponent = @truncate(u32, (@bitCast(Z, a) >> significandBits) & maxExponent);
const bExponent = @truncate(u32, (@bitCast(Z, b) >> significandBits) & maxExponent);
const quotientSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit;
const aExponent = @as(u32, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @as(u32, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const quotientSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: Z = @bitCast(Z, a) & significandMask;
var bSignificand: Z = @bitCast(Z, b) & significandMask;
var aSignificand: Z = @as(Z, @bitCast(a)) & significandMask;
var bSignificand: Z = @as(Z, @bitCast(b)) & significandMask;
var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask;
const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// 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
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) {
// infinity / infinity = NaN
if (bAbs == infRep) {
return @bitCast(T, qnanRep);
return @as(T, @bitCast(qnanRep));
}
// infinity / anything else = +/- infinity
else {
return @bitCast(T, aAbs | quotientSign);
return @as(T, @bitCast(aAbs | quotientSign));
}
}
// anything else / infinity = +/- 0
if (bAbs == infRep) return @bitCast(T, quotientSign);
if (bAbs == infRep) return @as(T, @bitCast(quotientSign));
if (aAbs == 0) {
// zero / zero = NaN
if (bAbs == 0) {
return @bitCast(T, qnanRep);
return @as(T, @bitCast(qnanRep));
}
// zero / anything else = +/- zero
else {
return @bitCast(T, quotientSign);
return @as(T, @bitCast(quotientSign));
}
}
// 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
// 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 (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
// [1, 2.0) and get a Q64 approximate reciprocal using a small minimax
// polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
// 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;
// 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
// with each iteration.
var correction64: u64 = undefined;
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @truncate(u64, ~(@as(u128, recip64) *% q63b >> 64) +% 1);
recip64 = @truncate(u64, @as(u128, recip64) *% correction64 >> 63);
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
correction64 = @as(u64, @truncate(~(@as(u128, recip64) *% q63b >> 64) +% 1));
recip64 = @as(u64, @truncate(@as(u128, recip64) *% correction64 >> 63));
// 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
@ -128,8 +128,8 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
correction = -%correction;
const cHi = @truncate(u64, correction >> 64);
const cLo = @truncate(u64, correction);
const cHi = @as(u64, @truncate(correction >> 64));
const cLo = @as(u64, @truncate(correction));
var r64cH: u128 = undefined;
var r64cL: u128 = undefined;
@ -164,8 +164,8 @@ pub fn __divxf3(a: f80, b: f80) callconv(.C) f80 {
// exponent accordingly.
var quotient: u64 = if (quotient128 < (integerBit << 1)) b: {
quotientExponent -= 1;
break :b @intCast(u64, quotient128);
} else @intCast(u64, quotient128 >> 1);
break :b @as(u64, @intCast(quotient128));
} else @as(u64, @intCast(quotient128 >> 1));
// 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;
if (writtenExponent >= maxExponent) {
// If we have overflowed the exponent, return infinity.
return @bitCast(T, infRep | quotientSign);
return @as(T, @bitCast(infRep | quotientSign));
} else if (writtenExponent < 1) {
if (writtenExponent == 0) {
// Check whether the rounded result is normal.
if (residual > (bSignificand >> 1)) { // round
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
// code to round them correctly.
return @bitCast(T, quotientSign);
return @as(T, @bitCast(quotientSign));
} else {
const round = @intFromBool(residual > (bSignificand >> 1));
// Insert the exponent
var absResult = quotient | (@intCast(Z, writtenExponent) << significandBits);
var absResult = quotient | (@as(Z, @intCast(writtenExponent)) << significandBits);
// Round
absResult +%= round;
// 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;
fn compareResult(result: f80, expected: u80) bool {
const rep = @bitCast(u80, result);
const rep = @as(u80, @bitCast(result));
if (rep == expected) return true;
// 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;
}
@ -25,9 +25,9 @@ fn test__divxf3(a: f80, b: f80) !void {
const x = __divxf3(a, b);
// 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)
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
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 {
/// Allocate a memory chunk for requested type. Return a pointer on the data.
pub fn alloc(comptime T: type) *T {
return @ptrCast(*T, @alignCast(
@alignOf(T),
advancedAlloc(@alignOf(T), @sizeOf(T)),
));
return @ptrCast(@alignCast(advancedAlloc(@alignOf(T), @sizeOf(T))));
}
/// Allocate a slice of T, with len elements.
pub fn allocSlice(comptime T: type, len: usize) []T {
return @ptrCast([*]T, @alignCast(
@alignOf(T),
return @as([*]T, @ptrCast(@alignCast(
advancedAlloc(@alignOf(T), @sizeOf(T) * len),
))[0 .. len - 1];
)))[0 .. len - 1];
}
/// Allocate a memory chunk.
@ -56,22 +52,19 @@ const simple_allocator = struct {
abort();
}
return @ptrCast([*]u8, aligned_ptr);
return @as([*]u8, @ptrCast(aligned_ptr));
}
/// Resize a slice.
pub fn reallocSlice(comptime T: type, slice: []T, len: usize) []T {
var c_ptr: *anyopaque = @ptrCast(*anyopaque, slice.ptr);
var new_array: [*]T = @ptrCast([*]T, @alignCast(
@alignOf(T),
std.c.realloc(c_ptr, @sizeOf(T) * len) orelse abort(),
));
var c_ptr: *anyopaque = @as(*anyopaque, @ptrCast(slice.ptr));
var new_array: [*]T = @ptrCast(@alignCast(std.c.realloc(c_ptr, @sizeOf(T) * len) orelse abort()));
return new_array[0..len];
}
/// Free a memory chunk allocated with simple_allocator.
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) {
// initialize the slot
const size = control.size;
const alignment = @truncate(u29, control.alignment);
const alignment = @as(u29, @truncate(control.alignment));
var data = simple_allocator.advancedAlloc(alignment, size);
errdefer simple_allocator.free(data);
if (control.default_value) |value| {
// 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 {
// no default: return zeroed memory.
@memset(data[0..size], 0);
}
self.slots[index] = @ptrCast(*anyopaque, data);
self.slots[index] = @as(*anyopaque, @ptrCast(data));
}
return self.slots[index].?;
@ -180,18 +173,12 @@ const current_thread_storage = struct {
/// Return casted thread specific value.
fn getspecific() ?*ObjectArray {
return @ptrCast(
?*ObjectArray,
@alignCast(
@alignOf(ObjectArray),
std.c.pthread_getspecific(current_thread_storage.key),
),
);
return @ptrCast(@alignCast(std.c.pthread_getspecific(current_thread_storage.key)));
}
/// Set casted thread specific value.
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();
}
}
@ -205,10 +192,7 @@ const current_thread_storage = struct {
/// Invoked by pthread specific destructor. the passed argument is the ObjectArray pointer.
fn deinit(arrayPtr: *anyopaque) callconv(.C) void {
var array = @ptrCast(
*ObjectArray,
@alignCast(@alignOf(ObjectArray), arrayPtr),
);
var array: *ObjectArray = @ptrCast(@alignCast(arrayPtr));
array.deinit();
}
};
@ -294,7 +278,7 @@ const emutls_control = extern struct {
.size = @sizeOf(T),
.alignment = @alignOf(T),
.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 {
assert(self.size == @sizeOf(T));
assert(self.alignment == @alignOf(T));
return @ptrCast(
*T,
@alignCast(@alignOf(T), self.getPointer()),
);
return @ptrCast(@alignCast(self.getPointer()));
}
};
@ -343,7 +324,7 @@ test "__emutls_get_address zeroed" {
try expect(ctl.object.index == 0);
// 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(x.* == 0); // storage has been zeroed
@ -351,7 +332,7 @@ test "__emutls_get_address zeroed" {
x.* = 1234;
// 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(x == y); // same pointer
@ -364,7 +345,7 @@ test "__emutls_get_address with default_value" {
var ctl = emutls_control.init(usize, &value);
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(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
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
}

View File

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

View File

@ -27,18 +27,18 @@ comptime {
pub fn __exp2h(x: f16) callconv(.C) f16 {
// TODO: more efficient implementation
return @floatCast(f16, exp2f(x));
return @as(f16, @floatCast(exp2f(x)));
}
pub fn exp2f(x: f32) callconv(.C) f32 {
const tblsiz = @intCast(u32, exp2ft.len);
const redux: f32 = 0x1.8p23 / @floatFromInt(f32, tblsiz);
const tblsiz = @as(u32, @intCast(exp2ft.len));
const redux: f32 = 0x1.8p23 / @as(f32, @floatFromInt(tblsiz));
const P1: f32 = 0x1.62e430p-1;
const P2: f32 = 0x1.ebfbe0p-3;
const P3: f32 = 0x1.c6b348p-5;
const P4: f32 = 0x1.3b2c9cp-7;
var u = @bitCast(u32, x);
var u = @as(u32, @bitCast(x));
const ix = u & 0x7FFFFFFF;
// |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.
var uf = x + redux;
var i_0 = @bitCast(u32, uf);
var i_0 = @as(u32, @bitCast(uf));
i_0 +%= tblsiz / 2;
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;
uf -= redux;
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;
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 {
const tblsiz: u32 = @intCast(u32, exp2dt.len / 2);
const redux: f64 = 0x1.8p52 / @floatFromInt(f64, tblsiz);
const tblsiz: u32 = @as(u32, @intCast(exp2dt.len / 2));
const redux: f64 = 0x1.8p52 / @as(f64, @floatFromInt(tblsiz));
const P1: f64 = 0x1.62e42fefa39efp-1;
const P2: f64 = 0x1.ebfbdff82c575p-3;
const P3: f64 = 0x1.c6b08d704a0a6p-5;
const P4: f64 = 0x1.3b2ab88f70400p-7;
const P5: f64 = 0x1.5d88003875c74p-10;
const ux = @bitCast(u64, x);
const ix = @intCast(u32, ux >> 32) & 0x7FFFFFFF;
const ux = @as(u64, @bitCast(x));
const ix = @as(u32, @intCast(ux >> 32)) & 0x7FFFFFFF;
// TODO: This should be handled beneath.
if (math.isNan(x)) {
@ -119,7 +119,7 @@ pub fn exp2(x: f64) callconv(.C) f64 {
if (ux >> 63 != 0) {
// underflow
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) {
return 0;
@ -139,18 +139,18 @@ pub fn exp2(x: f64) callconv(.C) f64 {
// reduce x
var uf: f64 = x + redux;
// 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;
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;
uf -= redux;
// r = exp2(y) = exp2t[i_0] * p(z - eps[i])
var z: f64 = x - uf;
const t: f64 = exp2dt[@intCast(usize, 2 * i_0)];
z -= exp2dt[@intCast(usize, 2 * i_0 + 1)];
const t: f64 = exp2dt[@as(usize, @intCast(2 * i_0))];
z -= exp2dt[@as(usize, @intCast(2 * i_0 + 1))];
const r: f64 = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
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 {
// TODO: more efficient implementation
return @floatCast(f80, exp2q(x));
return @as(f80, @floatCast(exp2q(x)));
}
pub fn exp2q(x: f128) callconv(.C) f128 {
// 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 {

View File

@ -13,9 +13,9 @@ comptime {
}
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 {
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 {
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;
// 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 sign: src_rep_t = aRep & srcSignMask;
var absResult: dst_rep_t = undefined;
@ -58,10 +58,10 @@ pub inline fn extendf(
// the correct adjusted exponent in the destination type.
const scale: u32 = @clz(aAbs) -
@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;
const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;
absResult |= @intCast(dst_rep_t, resultExponent) << dstSigBits;
absResult |= @as(dst_rep_t, @intCast(resultExponent)) << dstSigBits;
} else {
// a is zero.
absResult = 0;
@ -69,7 +69,7 @@ pub inline fn extendf(
// 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);
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 {
@ -104,7 +104,7 @@ pub inline fn extend_f80(comptime src_t: type, a: std.meta.Int(.unsigned, @typeI
// a is a normal number.
// Extend to the destination type by shifting the significand and
// 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.fraction = @as(u64, a_abs) << (dst_sig_bits - src_sig_bits);
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) -
@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.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 |= dst_exp_bias - src_exp_bias - scale + 1;
} else {

View File

@ -11,12 +11,12 @@ const F16T = @import("./common.zig").F16T;
fn test__extenddfxf2(a: f64, expected: u80) !void {
const x = __extenddfxf2(a);
const rep = @bitCast(u80, x);
const rep = @as(u80, @bitCast(x));
if (rep == expected)
return;
// 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;
@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 {
const x = __extenddftf2(a);
const rep = @bitCast(u128, x);
const hi = @intCast(u64, rep >> 64);
const lo = @truncate(u64, rep);
const rep = @as(u128, @bitCast(x));
const hi = @as(u64, @intCast(rep >> 64));
const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo)
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 {
const x = __extendhfsf2(@bitCast(F16T(f32), a));
const rep = @bitCast(u32, x);
const x = __extendhfsf2(@as(F16T(f32), @bitCast(a)));
const rep = @as(u32, @bitCast(x));
if (rep == expected) {
if (rep & 0x7fffffff > 0x7f800000) {
return; // NaN is always unequal.
}
if (x == @bitCast(f32, expected)) {
if (x == @as(f32, @bitCast(expected))) {
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 {
const x = __extendsftf2(a);
const rep = @bitCast(u128, x);
const hi = @intCast(u64, rep >> 64);
const lo = @truncate(u64, rep);
const rep = @as(u128, @bitCast(x));
const hi = @as(u64, @intCast(rep >> 64));
const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo)
return;
@ -184,35 +184,35 @@ test "extendsftf2" {
}
fn makeQNaN64() f64 {
return @bitCast(f64, @as(u64, 0x7ff8000000000000));
return @as(f64, @bitCast(@as(u64, 0x7ff8000000000000)));
}
fn makeInf64() f64 {
return @bitCast(f64, @as(u64, 0x7ff0000000000000));
return @as(f64, @bitCast(@as(u64, 0x7ff0000000000000)));
}
fn makeNaN64(rand: u64) f64 {
return @bitCast(f64, 0x7ff0000000000000 | (rand & 0xfffffffffffff));
return @as(f64, @bitCast(0x7ff0000000000000 | (rand & 0xfffffffffffff)));
}
fn makeQNaN32() f32 {
return @bitCast(f32, @as(u32, 0x7fc00000));
return @as(f32, @bitCast(@as(u32, 0x7fc00000)));
}
fn makeNaN32(rand: u32) f32 {
return @bitCast(f32, 0x7f800000 | (rand & 0x7fffff));
return @as(f32, @bitCast(0x7f800000 | (rand & 0x7fffff)));
}
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 {
const x = __extendhftf2(@bitCast(F16T(f128), a));
const x = __extendhftf2(@as(F16T(f128), @bitCast(a)));
const rep = @bitCast(u128, x);
const hi = @intCast(u64, rep >> 64);
const lo = @truncate(u64, rep);
const rep = @as(u128, @bitCast(x));
const hi = @as(u64, @intCast(rep >> 64));
const lo = @as(u64, @truncate(rep));
if (hi == expected_hi and lo == expected_lo)
return;

View File

@ -8,5 +8,5 @@ comptime {
}
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 {
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 {
return extendf(f32, f16, @bitCast(u16, a));
return extendf(f32, f16, @as(u16, @bitCast(a)));
}
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 {
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 {
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 {
return extendf(f64, f32, @bitCast(u32, a));
return extendf(f64, f32, @as(u32, @bitCast(a)));
}
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 {
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 {
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 {
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,
// then insert the correct adjusted exponent in the destination type.
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 |= @as(u128, scale + 1) << dst_sig_bits;
}
// Apply the signbit to (dst_t)abs(a).
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) {
const T = @TypeOf(x);
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;
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;
fn test__ffsdi2(a: u64, expected: i32) !void {
var x = @bitCast(i64, a);
var x = @as(i64, @bitCast(a));
var result = ffs.__ffsdi2(x);
try testing.expectEqual(expected, result);
}

View File

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

View File

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

View File

@ -19,5 +19,5 @@ pub fn __fixdfti(a: f64) callconv(.C) i128 {
const v2u64 = @Vector(2, u64);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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
var exp = int_bits - @clz(abs_val) - 1;
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
result = (@intCast(uT, abs_val) << shift_amt);
result = (@as(uT, @intCast(abs_val)) << shift_amt);
result ^= implicit_bit; // Remove implicit integer bit
} 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;
// 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
result = ((result + 1) >> 1) & ~@as(uT, @intFromBool(exact_tie));
@ -43,14 +43,14 @@ pub fn floatFromInt(comptime T: type, x: anytype) T {
// Compute exponent
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);
// If the result included a carry, we need to restore the explicit integer bit
if (T == f80) result |= 1 << fractional_bits;
return @bitCast(T, sign_bit | result);
return @as(T, @bitCast(sign_bit | result));
}
test {

View File

@ -30,12 +30,12 @@ const __floatuntitf = @import("floatuntitf.zig").__floatuntitf;
fn test__floatsisf(a: i32, expected: u32) !void {
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 {
const r = __floatunsisf(a);
try std.testing.expect(@bitCast(u32, r) == expected);
try std.testing.expect(@as(u32, @bitCast(r)) == expected);
}
test "floatsisf" {
@ -43,7 +43,7 @@ test "floatsisf" {
try test__floatsisf(1, 0x3f800000);
try test__floatsisf(-1, 0xbf800000);
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" {
@ -72,10 +72,10 @@ test "floatdisf" {
try test__floatdisf(-2, -2.0);
try test__floatdisf(0x7FFFFF8000000000, 0x1.FFFFFEp+62);
try test__floatdisf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
try test__floatdisf(@bitCast(i64, @as(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
try test__floatdisf(@bitCast(i64, @as(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
try test__floatdisf(@bitCast(i64, @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, 0x8000008000000000))), -0x1.FFFFFEp+62);
try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000010000000000))), -0x1.FFFFFCp+62);
try test__floatdisf(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), -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(0x0007FB72EA000000, 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);
// 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 {
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 {
const r = __floatunsidf(a);
try std.testing.expect(@bitCast(u64, r) == expected);
try std.testing.expect(@as(u64, @bitCast(r)) == expected);
}
test "floatsidf" {
@ -246,15 +246,15 @@ test "floatsidf" {
try test_one_floatsidf(1, 0x3ff0000000000000);
try test_one_floatsidf(-1, 0xbff0000000000000);
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" {
try test_one_floatunsidf(0, 0x0000000000000000);
try test_one_floatunsidf(1, 0x3ff0000000000000);
try test_one_floatunsidf(0x7FFFFFFF, 0x41dfffffffc00000);
try test_one_floatunsidf(@intCast(u32, 0x80000000), 0x41e0000000000000);
try test_one_floatunsidf(@intCast(u32, 0xFFFFFFFF), 0x41efffffffe00000);
try test_one_floatunsidf(@as(u32, @intCast(0x80000000)), 0x41e0000000000000);
try test_one_floatunsidf(@as(u32, @intCast(0xFFFFFFFF)), 0x41efffffffe00000);
}
fn test__floatdidf(a: i64, expected: f64) !void {
@ -279,12 +279,12 @@ test "floatdidf" {
try test__floatdidf(0x7FFFFFFFFFFFF800, 0x1.FFFFFFFFFFFFEp+62);
try test__floatdidf(0x7FFFFF0000000000, 0x1.FFFFFCp+62);
try test__floatdidf(0x7FFFFFFFFFFFF000, 0x1.FFFFFFFFFFFFCp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000008000000000)), -0x1.FFFFFEp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000000800)), -0x1.FFFFFFFFFFFFEp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000010000000000)), -0x1.FFFFFCp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 0x8000000000001000)), -0x1.FFFFFFFFFFFFCp+62);
try test__floatdidf(@bitCast(i64, @intCast(u64, 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(0x8000008000000000)))), -0x1.FFFFFEp+62);
try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000800)))), -0x1.FFFFFFFFFFFFEp+62);
try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000010000000000)))), -0x1.FFFFFCp+62);
try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000001000)))), -0x1.FFFFFFFFFFFFCp+62);
try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000000)))), -0x1.000000p+63);
try test__floatdidf(@as(i64, @bitCast(@as(u64, @intCast(0x8000000000000001)))), -0x1.000000p+63); // 0x8000000000000001
try test__floatdidf(0x0007FB72E8000000, 0x1.FEDCBAp+50);
try test__floatdidf(0x0007FB72EA000000, 0x1.FEDCBA8p+50);
try test__floatdidf(0x0007FB72EB000000, 0x1.FEDCBACp+50);
@ -505,7 +505,7 @@ test "floatuntidf" {
fn test__floatsitf(a: i32, expected: u128) !void {
const r = __floatsitf(a);
try std.testing.expect(@bitCast(u128, r) == expected);
try std.testing.expect(@as(u128, @bitCast(r)) == expected);
}
test "floatsitf" {
@ -513,16 +513,16 @@ test "floatsitf" {
try test__floatsitf(0x7FFFFFFF, 0x401dfffffffc00000000000000000000);
try test__floatsitf(0x12345678, 0x401b2345678000000000000000000000);
try test__floatsitf(-0x12345678, 0xc01b2345678000000000000000000000);
try test__floatsitf(@bitCast(i32, @intCast(u32, 0xffffffff)), 0xbfff0000000000000000000000000000);
try test__floatsitf(@bitCast(i32, @intCast(u32, 0x80000000)), 0xc01e0000000000000000000000000000);
try test__floatsitf(@as(i32, @bitCast(@as(u32, @intCast(0xffffffff)))), 0xbfff0000000000000000000000000000);
try test__floatsitf(@as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 0xc01e0000000000000000000000000000);
}
fn test__floatunsitf(a: u32, expected_hi: u64, expected_lo: u64) !void {
const x = __floatunsitf(a);
const x_repr = @bitCast(u128, x);
const x_hi = @intCast(u64, x_repr >> 64);
const x_lo = @truncate(u64, x_repr);
const x_repr = @as(u128, @bitCast(x));
const x_hi = @as(u64, @intCast(x_repr >> 64));
const x_lo = @as(u64, @truncate(x_repr));
if (x_hi == expected_hi and x_lo == expected_lo) {
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 {
const x = __floatunditf(a);
const x_repr = @bitCast(u128, x);
const x_hi = @intCast(u64, x_repr >> 64);
const x_lo = @truncate(u64, x_repr);
const x_repr = @as(u128, @bitCast(x));
const x_hi = @as(u64, @intCast(x_repr >> 64));
const x_lo = @as(u64, @truncate(x_repr));
if (x_hi == expected_hi and x_lo == expected_lo) {
return;
@ -575,10 +575,10 @@ test "floatditf" {
try test__floatditf(0x2, make_tf(0x4000000000000000, 0x0));
try test__floatditf(0x1, make_tf(0x3fff000000000000, 0x0));
try test__floatditf(0x0, make_tf(0x0, 0x0));
try test__floatditf(@bitCast(i64, @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, 0xffffffffffffffff))), make_tf(0xbfff000000000000, 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(@bitCast(i64, @as(u64, 0x8000000000000000)), make_tf(0xc03e000000000000, 0x0));
try test__floatditf(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), make_tf(0xc03e000000000000, 0x0));
}
test "floatunditf" {
@ -773,7 +773,7 @@ fn make_ti(high: u64, low: u64) i128 {
var result: u128 = high;
result <<= 64;
result |= low;
return @bitCast(i128, result);
return @as(i128, @bitCast(result));
}
fn make_uti(high: u64, low: u64) u128 {
@ -787,7 +787,7 @@ fn make_tf(high: u64, low: u64) f128 {
var result: u128 = high;
result <<= 64;
result |= low;
return @bitCast(f128, result);
return @as(f128, @bitCast(result));
}
test "conversion to f16" {
@ -815,22 +815,22 @@ test "conversion to f80" {
const floatFromInt = @import("./float_from_int.zig").floatFromInt;
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(@intFromFloat(u80, floatFromInt(f80, @as(u80, math.maxInt(u64)) + 1)) == math.maxInt(u64) + 1);
try testing.expect(@as(u80, @intFromFloat(floatFromInt(f80, @as(u64, math.maxInt(u64)) + 0))) == math.maxInt(u64) + 0);
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, 1)) == 1.0);
try testing.expect(@intFromFloat(u128, 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(@intFromFloat(u128, 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(@intFromFloat(u128, 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(u32, math.maxInt(u24)) + 0))) == math.maxInt(u24));
try testing.expect(@as(u128, @intFromFloat(floatFromInt(f80, @as(u80, math.maxInt(u64)) + 0))) == math.maxInt(u64));
try testing.expect(@as(u128, @intFromFloat(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)) + 2))) == math.maxInt(u64) + 1); // Rounds down
try testing.expect(@as(u128, @intFromFloat(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)) + 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(@intFromFloat(u128, 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(@intFromFloat(u128, 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(@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)) + 0))) == math.maxInt(u65) + 1); // Rounds up
try testing.expect(@as(u128, @intFromFloat(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)) + 2))) == math.maxInt(u65) + 1); // 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(@as(u128, @intFromFloat(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)) + 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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
var u = @bitCast(u16, x);
const e = @intCast(i16, (u >> 10) & 31) - 15;
var u = @as(u16, @bitCast(x));
const e = @as(i16, @intCast((u >> 10) & 31)) - 15;
var m: u16 = undefined;
// TODO: Shouldn't need this explicit check.
@ -40,7 +40,7 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
}
if (e >= 0) {
m = @as(u16, 1023) >> @intCast(u4, e);
m = @as(u16, 1023) >> @as(u4, @intCast(e));
if (u & m == 0) {
return x;
}
@ -48,7 +48,7 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
if (u >> 15 != 0) {
u += m;
}
return @bitCast(f16, u & ~m);
return @as(f16, @bitCast(u & ~m));
} else {
math.doNotOptimizeAway(x + 0x1.0p120);
if (u >> 15 == 0) {
@ -60,8 +60,8 @@ pub fn __floorh(x: f16) callconv(.C) f16 {
}
pub fn floorf(x: f32) callconv(.C) f32 {
var u = @bitCast(u32, x);
const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F;
var u = @as(u32, @bitCast(x));
const e = @as(i32, @intCast((u >> 23) & 0xFF)) - 0x7F;
var m: u32 = undefined;
// TODO: Shouldn't need this explicit check.
@ -74,7 +74,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
}
if (e >= 0) {
m = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
m = @as(u32, 0x007FFFFF) >> @as(u5, @intCast(e));
if (u & m == 0) {
return x;
}
@ -82,7 +82,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
if (u >> 31 != 0) {
u += m;
}
return @bitCast(f32, u & ~m);
return @as(f32, @bitCast(u & ~m));
} else {
math.doNotOptimizeAway(x + 0x1.0p120);
if (u >> 31 == 0) {
@ -96,7 +96,7 @@ pub fn floorf(x: f32) callconv(.C) f32 {
pub fn floor(x: f64) callconv(.C) 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;
var y: f64 = undefined;
@ -126,13 +126,13 @@ pub fn floor(x: f64) callconv(.C) f64 {
pub fn __floorx(x: f80) callconv(.C) f80 {
// TODO: more efficient implementation
return @floatCast(f80, floorq(x));
return @as(f80, @floatCast(floorq(x)));
}
pub fn floorq(x: f128) callconv(.C) 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;
var y: f128 = undefined;

View File

@ -28,20 +28,20 @@ comptime {
pub fn __fmah(x: f16, y: f16, z: f16) callconv(.C) f16 {
// 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 {
const xy = @as(f64, x) * y;
const xy_z = xy + z;
const u = @bitCast(u64, xy_z);
const u = @as(u64, @bitCast(xy_z));
const e = (u >> 52) & 0x7FF;
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 {
// 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 {
// 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.
@ -201,12 +201,12 @@ fn dd_mul(a: f64, b: f64) dd {
fn add_adjusted(a: f64, b: f64) f64 {
var sum = dd_add(a, b);
if (sum.lo != 0) {
var uhii = @bitCast(u64, sum.hi);
var uhii = @as(u64, @bitCast(sum.hi));
if (uhii & 1 == 0) {
// 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);
sum.hi = @bitCast(f64, uhii);
sum.hi = @as(f64, @bitCast(uhii));
}
}
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 {
var sum = dd_add(a, b);
if (sum.lo != 0) {
var uhii = @bitCast(u64, sum.hi);
const bits_lost = -@intCast(i32, (uhii >> 52) & 0x7FF) - scale + 1;
var uhii = @as(u64, @bitCast(sum.hi));
const bits_lost = -@as(i32, @intCast((uhii >> 52) & 0x7FF)) - scale + 1;
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);
sum.hi = @bitCast(f64, uhii);
sum.hi = @as(f64, @bitCast(uhii));
}
}
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 {
var sum = dd_add128(a, b);
if (sum.lo != 0) {
var uhii = @bitCast(u128, sum.hi);
var uhii = @as(u128, @bitCast(sum.hi));
if (uhii & 1 == 0) {
// 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);
sum.hi = @bitCast(f128, uhii);
sum.hi = @as(f128, @bitCast(uhii));
}
}
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
// break the ties manually.
if (sum.lo != 0) {
var uhii = @bitCast(u128, sum.hi);
const bits_lost = -@intCast(i32, (uhii >> 112) & 0x7FFF) - scale + 1;
var uhii = @as(u128, @bitCast(sum.hi));
const bits_lost = -@as(i32, @intCast((uhii >> 112) & 0x7FFF)) - scale + 1;
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);
sum.hi = @bitCast(f128, uhii);
sum.hi = @as(f128, @bitCast(uhii));
}
}
return math.scalbn(sum.hi, scale);

View File

@ -22,7 +22,7 @@ comptime {
pub fn __fmodh(x: f16, y: f16) callconv(.C) f16 {
// 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 {
@ -46,12 +46,12 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
const signBit = (@as(Z, 1) << (significandBits + exponentBits));
const maxExponent = ((1 << exponentBits) - 1);
var aRep = @bitCast(Z, a);
var bRep = @bitCast(Z, b);
var aRep = @as(Z, @bitCast(a));
var bRep = @as(Z, @bitCast(b));
const signA = aRep & signBit;
var expA = @intCast(i32, (@bitCast(Z, a) >> significandBits) & maxExponent);
var expB = @intCast(i32, (@bitCast(Z, b) >> significandBits) & maxExponent);
var expA = @as(i32, @intCast((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
var expB = @as(i32, @intCast((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
// There are 3 cases where the answer is undefined, check for:
// - fmodx(val, 0)
@ -82,8 +82,8 @@ pub fn __fmodx(a: f80, b: f80) callconv(.C) f80 {
var highA: u64 = 0;
var highB: u64 = 0;
var lowA: u64 = @truncate(u64, aRep);
var lowB: u64 = @truncate(u64, bRep);
var lowA: u64 = @as(u64, @truncate(aRep));
var lowB: u64 = @as(u64, @truncate(bRep));
while (expA > expB) : (expA -= 1) {
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
if (expA < -fractionalBits) {
return @bitCast(T, signA);
return @as(T, @bitCast(signA));
} 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 {
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 {
var amod = a;
var bmod = b;
const aPtr_u64 = @ptrCast([*]u64, &amod);
const bPtr_u64 = @ptrCast([*]u64, &bmod);
const aPtr_u16 = @ptrCast([*]u16, &amod);
const bPtr_u16 = @ptrCast([*]u16, &bmod);
const aPtr_u64 = @as([*]u64, @ptrCast(&amod));
const bPtr_u64 = @as([*]u64, @ptrCast(&bmod));
const aPtr_u16 = @as([*]u16, @ptrCast(&amod));
const bPtr_u16 = @as([*]u16, @ptrCast(&bmod));
const exp_and_sign_index = comptime switch (builtin.target.cpu.arch.endian()) {
.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;
var expA = @intCast(i32, (aPtr_u16[exp_and_sign_index] & 0x7fff));
var expB = @intCast(i32, (bPtr_u16[exp_and_sign_index] & 0x7fff));
var expA = @as(i32, @intCast((aPtr_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:
// - fmodq(val, 0)
@ -173,8 +173,8 @@ pub fn fmodq(a: f128, b: f128) callconv(.C) f128 {
}
// Remove the sign from both
aPtr_u16[exp_and_sign_index] = @bitCast(u16, @intCast(i16, expA));
bPtr_u16[exp_and_sign_index] = @bitCast(u16, @intCast(i16, expB));
aPtr_u16[exp_and_sign_index] = @as(u16, @bitCast(@as(i16, @intCast(expA))));
bPtr_u16[exp_and_sign_index] = @as(u16, @bitCast(@as(i16, @intCast(expB))));
if (amod <= bmod) {
if (amod == bmod) {
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
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;
} 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;
@ -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 bits_minus_1 = bits - 1;
const mask = if (T == f32) 0xff else 0x7ff;
var ux = @bitCast(uint, x);
var uy = @bitCast(uint, y);
var ex = @intCast(i32, (ux >> digits) & mask);
var ey = @intCast(i32, (uy >> digits) & mask);
const sx = if (T == f32) @intCast(u32, ux & 0x80000000) else @intCast(i32, ux >> bits_minus_1);
var ux = @as(uint, @bitCast(x));
var uy = @as(uint, @bitCast(y));
var ex = @as(i32, @intCast((ux >> digits) & mask));
var ey = @as(i32, @intCast((uy >> digits) & mask));
const sx = if (T == f32) @as(u32, @intCast(ux & 0x80000000)) else @as(i32, @intCast(ux >> bits_minus_1));
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);
if (ux << 1 <= uy << 1) {
@ -293,7 +293,7 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
ex -= 1;
i <<= 1;
}) {}
ux <<= @intCast(log2uint, @bitCast(u32, -ex + 1));
ux <<= @as(log2uint, @intCast(@as(u32, @bitCast(-ex + 1))));
} else {
ux &= math.maxInt(uint) >> exp_bits;
ux |= 1 << digits;
@ -304,7 +304,7 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
ey -= 1;
i <<= 1;
}) {}
uy <<= @intCast(log2uint, @bitCast(u32, -ey + 1));
uy <<= @as(log2uint, @intCast(@as(u32, @bitCast(-ey + 1))));
} else {
uy &= math.maxInt(uint) >> exp_bits;
uy |= 1 << digits;
@ -334,16 +334,16 @@ inline fn generic_fmod(comptime T: type, x: T, y: T) T {
// scale result up
if (ex > 0) {
ux -%= 1 << digits;
ux |= @as(uint, @bitCast(u32, ex)) << digits;
ux |= @as(uint, @as(u32, @bitCast(ex))) << digits;
} else {
ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1));
ux >>= @as(log2uint, @intCast(@as(u32, @bitCast(-ex + 1))));
}
if (T == f32) {
ux |= sx;
} 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" {

View File

@ -52,8 +52,8 @@ test "test_divmodti4" {
[_]i128{ -7, 5, -1, -2 },
[_]i128{ 19, 5, 3, 4 },
[_]i128{ 19, -5, -3, 4 },
[_]i128{ @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 8, @bitCast(i128, @as(u128, 0xf0000000000000000000000000000000)), 0 },
[_]i128{ @bitCast(i128, @as(u128, 0x80000000000000000000000000000007)), 8, @bitCast(i128, @as(u128, 0xf0000000000000000000000000000001)), -1 },
[_]i128{ @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 8, @as(i128, @bitCast(@as(u128, 0xf0000000000000000000000000000000))), 0 },
[_]i128{ @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000007))), 8, @as(i128, @bitCast(@as(u128, 0xf0000000000000000000000000000001))), -1 },
};
for (cases) |case| {
@ -85,8 +85,8 @@ test "test_divmoddi4" {
[_]i64{ -7, 5, -1, -2 },
[_]i64{ 19, 5, 3, 4 },
[_]i64{ 19, -5, -3, 4 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 8, @bitCast(i64, @as(u64, 0xf000000000000000)), 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000007)), 8, @bitCast(i64, @as(u64, 0xf000000000000001)), -1 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000000))), 0 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000007))), 8, @as(i64, @bitCast(@as(u64, 0xf000000000000001))), -1 },
};
for (cases) |case| {
@ -110,14 +110,14 @@ test "test_udivmoddi4" {
pub fn __divdi3(a: i64, b: i64) callconv(.C) i64 {
// 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).
const abs_a = (a ^ (a >> 63)) -% (a >> 63);
const abs_b = (b ^ (b >> 63)) -% (b >> 63);
// 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.
return @bitCast(i64, (res ^ sign) -% sign);
return @as(i64, @bitCast((res ^ sign) -% sign));
}
test "test_divdi3" {
@ -129,10 +129,10 @@ test "test_divdi3" {
[_]i64{ -2, 1, -2 },
[_]i64{ -2, -1, 2 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0x4000000000000000 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0xC000000000000000)) },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))) },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, 0x4000000000000000 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, @as(i64, @bitCast(@as(u64, 0xC000000000000000))) },
};
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);
// Unsigned division
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.
return (@bitCast(i64, r) ^ (a >> 63)) -% (a >> 63);
return (@as(i64, @bitCast(r)) ^ (a >> 63)) -% (a >> 63);
}
test "test_moddi3" {
@ -165,12 +165,12 @@ test "test_moddi3" {
[_]i64{ -5, 3, -2 },
[_]i64{ -5, -3, -2 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 3, -2 },
[_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -3, -2 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, 0 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -1, 0 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, 0 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -2, 0 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 3, -2 },
[_]i64{ @as(i64, @bitCast(@as(u64, 0x8000000000000000))), -3, -2 },
};
for (cases) |case| {
@ -225,8 +225,8 @@ test "test_divmodsi4" {
[_]i32{ 19, 5, 3, 4 },
[_]i32{ 19, -5, -3, 4 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 8, @bitCast(i32, @as(u32, 0xf0000000)), 0 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000007)), 8, @bitCast(i32, @as(u32, 0xf0000001)), -1 },
[_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 8, @as(i32, @bitCast(@as(u32, 0xf0000000))), 0 },
[_]i32{ @as(i32, @bitCast(@as(u32, 0x80000007))), 8, @as(i32, @bitCast(@as(u32, 0xf0000001))), -1 },
};
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 {
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;
}
@ -256,14 +256,14 @@ fn __aeabi_idiv(n: i32, d: i32) callconv(.AAPCS) i32 {
inline fn div_i32(n: i32, d: i32) i32 {
// 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).
const abs_n = (n ^ (n >> 31)) -% (n >> 31);
const abs_d = (d ^ (d >> 31)) -% (d >> 31);
// 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.
return @bitCast(i32, (res ^ sign) -% sign);
return @as(i32, @bitCast((res ^ sign) -% sign));
}
test "test_divsi3" {
@ -275,10 +275,10 @@ test "test_divsi3" {
[_]i32{ -2, 1, -2 },
[_]i32{ -2, -1, 2 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)) },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)) },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -2, 0x40000000 },
[_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0xC0000000)) },
[_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 1, @as(i32, @bitCast(@as(u32, 0x80000000))) },
[_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), -1, @as(i32, @bitCast(@as(u32, 0x80000000))) },
[_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), -2, 0x40000000 },
[_]i32{ @as(i32, @bitCast(@as(u32, 0x80000000))), 2, @as(i32, @bitCast(@as(u32, 0xC0000000))) },
};
for (cases) |case| {
@ -304,7 +304,7 @@ inline fn div_u32(n: u32, d: u32) u32 {
// special cases
if (d == 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
if (sr > n_uword_bits - 1) {
// d > r
@ -317,12 +317,12 @@ inline fn div_u32(n: u32, d: u32) u32 {
sr += 1;
// 1 <= sr <= n_uword_bits - 1
// Not a special case
var q: u32 = n << @intCast(u5, n_uword_bits - sr);
var r: u32 = n >> @intCast(u5, sr);
var q: u32 = n << @as(u5, @intCast(n_uword_bits - sr));
var r: u32 = n >> @as(u5, @intCast(sr));
var carry: u32 = 0;
while (sr > 0) : (sr -= 1) {
// 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;
// carry = 0;
// if (r.all >= d.all)
@ -330,9 +330,9 @@ inline fn div_u32(n: u32, d: u32) u32 {
// r.all -= d.all;
// carry = 1;
// }
const s = @bitCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1);
carry = @intCast(u32, s & 1);
r -= d & @bitCast(u32, s);
const s = @as(i32, @bitCast(d -% r -% 1)) >> @as(u5, @intCast(n_uword_bits - 1));
carry = @as(u32, @intCast(s & 1));
r -= d & @as(u32, @bitCast(s));
}
q = (q << 1) | carry;
return q;
@ -496,11 +496,11 @@ test "test_modsi3" {
[_]i32{ 5, -3, 2 },
[_]i32{ -5, 3, -2 },
[_]i32{ -5, -3, -2 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 1, 0x0 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 2, 0x0 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -2, 0x0 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), 3, -2 },
[_]i32{ @bitCast(i32, @intCast(u32, 0x80000000)), -3, -2 },
[_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 1, 0x0 },
[_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 2, 0x0 },
[_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), -2, 0x0 },
[_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), 3, -2 },
[_]i32{ @as(i32, @bitCast(@as(u32, @intCast(0x80000000)))), -3, -2 },
};
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;
// 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 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;
// 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) {
.unsigned => {
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);
},
}
@ -40,9 +40,9 @@ pub inline fn intFromFloat(comptime I: type, a: anytype) I {
// Otherwise, shift left.
var result: I = undefined;
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 {
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)

View File

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

View File

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

View File

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

View File

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

View File

@ -33,5 +33,5 @@ fn make_ti(high: u64, low: u64) i128 {
var result: u128 = high;
result <<= 64;
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 {
var ua = @bitCast(u32, a);
var ub = @bitCast(u32, b);
var ua = @as(u32, @bitCast(a));
var ub = @as(u32, @bitCast(b));
var r: u32 = 0;
while (ua > 0) {
@ -31,7 +31,7 @@ pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 {
ub <<= 1;
}
return @bitCast(i32, r);
return @as(i32, @bitCast(r));
}
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);
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 {

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(4194303, 8192, @truncate(i32, 34359730176));
try test_one_mulsi3(-4194303, 8192, @truncate(i32, -34359730176));
try test_one_mulsi3(4194303, -8192, @truncate(i32, -34359730176));
try test_one_mulsi3(-4194303, -8192, @truncate(i32, 34359730176));
try test_one_mulsi3(8192, 4194303, @truncate(i32, 34359730176));
try test_one_mulsi3(-8192, 4194303, @truncate(i32, -34359730176));
try test_one_mulsi3(8192, -4194303, @truncate(i32, -34359730176));
try test_one_mulsi3(-8192, -4194303, @truncate(i32, 34359730176));
try test_one_mulsi3(4194303, 8192, @as(i32, @truncate(34359730176)));
try test_one_mulsi3(-4194303, 8192, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(4194303, -8192, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(-4194303, -8192, @as(i32, @truncate(34359730176)));
try test_one_mulsi3(8192, 4194303, @as(i32, @truncate(34359730176)));
try test_one_mulsi3(-8192, 4194303, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(8192, -4194303, @as(i32, @truncate(-34359730176)));
try test_one_mulsi3(-8192, -4194303, @as(i32, @truncate(34359730176)));
}
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 absMask = signBit - 1;
const qnanRep = @bitCast(Z, math.nan(T)) | quietBit;
const infRep = @bitCast(Z, math.inf(T));
const minNormalRep = @bitCast(Z, math.floatMin(T));
const qnanRep = @as(Z, @bitCast(math.nan(T))) | quietBit;
const infRep = @as(Z, @bitCast(math.inf(T)));
const minNormalRep = @as(Z, @bitCast(math.floatMin(T)));
const ZExp = if (typeWidth >= 32) u32 else Z;
const aExponent = @truncate(ZExp, (@bitCast(Z, a) >> significandBits) & maxExponent);
const bExponent = @truncate(ZExp, (@bitCast(Z, b) >> significandBits) & maxExponent);
const productSign: Z = (@bitCast(Z, a) ^ @bitCast(Z, b)) & signBit;
const aExponent = @as(ZExp, @truncate((@as(Z, @bitCast(a)) >> significandBits) & maxExponent));
const bExponent = @as(ZExp, @truncate((@as(Z, @bitCast(b)) >> significandBits) & maxExponent));
const productSign: Z = (@as(Z, @bitCast(a)) ^ @as(Z, @bitCast(b))) & signBit;
var aSignificand: ZSignificand = @intCast(ZSignificand, @bitCast(Z, a) & significandMask);
var bSignificand: ZSignificand = @intCast(ZSignificand, @bitCast(Z, b) & significandMask);
var aSignificand: ZSignificand = @as(ZSignificand, @intCast(@as(Z, @bitCast(a)) & significandMask));
var bSignificand: ZSignificand = @as(ZSignificand, @intCast(@as(Z, @bitCast(b)) & significandMask));
var scale: i32 = 0;
// Detect if a or b is zero, denormal, infinity, or NaN.
if (aExponent -% 1 >= maxExponent - 1 or bExponent -% 1 >= maxExponent - 1) {
const aAbs: Z = @bitCast(Z, a) & absMask;
const bAbs: Z = @bitCast(Z, b) & absMask;
const aAbs: Z = @as(Z, @bitCast(a)) & absMask;
const bAbs: Z = @as(Z, @bitCast(b)) & absMask;
// 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
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) {
// infinity * non-zero = +/- infinity
if (bAbs != 0) {
return @bitCast(T, aAbs | productSign);
return @as(T, @bitCast(aAbs | productSign));
} else {
// infinity * zero = NaN
return @bitCast(T, qnanRep);
return @as(T, @bitCast(qnanRep));
}
}
if (bAbs == infRep) {
//? non-zero * infinity = +/- infinity
if (aAbs != 0) {
return @bitCast(T, bAbs | productSign);
return @as(T, @bitCast(bAbs | productSign));
} else {
// zero * infinity = NaN
return @bitCast(T, qnanRep);
return @as(T, @bitCast(qnanRep));
}
}
// zero * anything = +/- zero
if (aAbs == 0) return @bitCast(T, productSign);
if (aAbs == 0) return @as(T, @bitCast(productSign));
// 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
// 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;
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.
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 (productExponent >= maxExponent) return @bitCast(T, infRep | productSign);
if (productExponent >= maxExponent) return @as(T, @bitCast(infRep | productSign));
var result: Z = undefined;
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
// handle this case separately, but we make it a special case to
// simplify the shift logic.
const shift: u32 = @truncate(u32, @as(Z, 1) -% @bitCast(u32, productExponent));
if (shift >= ZSignificandBits) return @bitCast(T, productSign);
const shift: u32 = @as(u32, @truncate(@as(Z, 1) -% @as(u32, @bitCast(productExponent))));
if (shift >= ZSignificandBits) return @as(T, @bitCast(productSign));
// Otherwise, shift the significand of the result so that the round
// bit is the high bit of productLo.
@ -135,7 +135,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
} else {
// Result is normal before rounding; insert the exponent.
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
@ -156,7 +156,7 @@ pub inline fn mulf3(comptime T: type, a: T, b: T) T {
// Insert the sign of the result:
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)
@ -168,12 +168,12 @@ fn wideShrWithTruncation(comptime Z: type, hi: *Z, lo: *Z, count: u32) bool {
const S = math.Log2Int(Z);
var inexact = false;
if (count < typeWidth) {
inexact = (lo.* << @intCast(S, typeWidth -% count)) != 0;
lo.* = (hi.* << @intCast(S, typeWidth -% count)) | (lo.* >> @intCast(S, count));
hi.* = hi.* >> @intCast(S, count);
inexact = (lo.* << @as(S, @intCast(typeWidth -% count))) != 0;
lo.* = (hi.* << @as(S, @intCast(typeWidth -% count))) | (lo.* >> @as(S, @intCast(count)));
hi.* = hi.* >> @as(S, @intCast(count));
} else if (count < 2 * typeWidth) {
inexact = (hi.* << @intCast(S, 2 * typeWidth -% count) | lo.*) != 0;
lo.* = hi.* >> @intCast(S, count -% typeWidth);
inexact = (hi.* << @as(S, @intCast(2 * typeWidth -% count)) | lo.*) != 0;
lo.* = hi.* >> @as(S, @intCast(count -% typeWidth));
hi.* = 0;
} else {
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 shift = @clz(significand.*) - @clz(integerBit);
significand.* <<= @intCast(math.Log2Int(Z), shift);
significand.* <<= @as(math.Log2Int(Z), @intCast(shift));
return @as(i32, 1) - shift;
}

View File

@ -4,8 +4,8 @@
const std = @import("std");
const math = std.math;
const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64);
const inf128 = @bitCast(f128, @as(u128, 0x7fff000000000000) << 64);
const qnan128 = @as(f128, @bitCast(@as(u128, 0x7fff800000000000) << 64));
const inf128 = @as(f128, @bitCast(@as(u128, 0x7fff000000000000) << 64));
const __multf3 = @import("multf3.zig").__multf3;
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
// because 128-bit integer constant can't be assigned directly
fn compareResultLD(result: f128, expectedHi: u64, expectedLo: u64) bool {
const rep = @bitCast(u128, result);
const hi = @intCast(u64, rep >> 64);
const lo = @truncate(u64, rep);
const rep = @as(u128, @bitCast(result));
const hi = @as(u64, @intCast(rep >> 64));
const lo = @as(u64, @truncate(rep));
if (hi == expectedHi and lo == expectedLo) {
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 {
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;
}
test "multf3" {
@ -60,15 +60,15 @@ test "multf3" {
// any * any
try test__multf3(
@bitCast(f128, @as(u128, 0x40042eab345678439abcdefea5678234)),
@bitCast(f128, @as(u128, 0x3ffeedcb34a235253948765432134675)),
@as(f128, @bitCast(@as(u128, 0x40042eab345678439abcdefea5678234))),
@as(f128, @bitCast(@as(u128, 0x3ffeedcb34a235253948765432134675))),
0x400423e7f9e3c9fc,
0xd906c2c2a85777c4,
);
try test__multf3(
@bitCast(f128, @as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50)),
@bitCast(f128, @as(u128, 0x3ff6ed8764648369535adf4be3214568)),
@as(f128, @bitCast(@as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50))),
@as(f128, @bitCast(@as(u128, 0x3ff6ed8764648369535adf4be3214568))),
0x3fc52a163c6223fc,
0xc94c4bf0430768b4,
);
@ -81,8 +81,8 @@ test "multf3" {
);
try test__multf3(
@bitCast(f128, @as(u128, 0x3f154356473c82a9fabf2d22ace345df)),
@bitCast(f128, @as(u128, 0x3e38eda98765476743ab21da23d45679)),
@as(f128, @bitCast(@as(u128, 0x3f154356473c82a9fabf2d22ace345df))),
@as(f128, @bitCast(@as(u128, 0x3e38eda98765476743ab21da23d45679))),
0x3d4f37c1a3137cae,
0xfc6807048bc2836a,
);
@ -108,16 +108,16 @@ test "multf3" {
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 {
const x = __mulxf3(a, b);
const rep = @bitCast(u80, x);
const rep = @as(u80, @bitCast(x));
if (rep == expected)
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 error.TestFailed;
@ -125,33 +125,33 @@ fn test__mulxf3(a: f80, b: f80, expected: u80) !void {
test "mulxf3" {
// NaN * any = NaN
try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @bitCast(u80, qnan80));
try test__mulxf3(@bitCast(f80, @as(u80, 0x7fff_8000_8000_3000_0000)), 0x1.23456789abcdefp+5, @bitCast(u80, qnan80));
try test__mulxf3(qnan80, 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
try test__mulxf3(@as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), 0x1.23456789abcdefp+5, @as(u80, @bitCast(qnan80)));
// any * NaN = NaN
try test__mulxf3(0x1.23456789abcdefp+5, qnan80, @bitCast(u80, 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, qnan80, @as(u80, @bitCast(qnan80)));
try test__mulxf3(0x1.23456789abcdefp+5, @as(f80, @bitCast(@as(u80, 0x7fff_8000_8000_3000_0000))), @as(u80, @bitCast(qnan80)));
// 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
try test__mulxf3(math.inf(f80), qnan80, @bitCast(u80, qnan80));
try test__mulxf3(math.inf(f80), qnan80, @as(u80, @bitCast(qnan80)));
// 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
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
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
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
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
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}
if (res < min or max < res)
overflow.* = 1;
return @truncate(ST, res);
return @as(ST, @truncate(res));
}
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(-2, 0x7FFFFFFFFFFFFFFF, 2, 1);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
try test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @as(i64, @bitCast(@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(0, 0x7FFFFFFFFFFFFFFF, 0, 0);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, 1, 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(1, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
try test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
try test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @as(i64, @bitCast(@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(-2, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
try test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0, 0);
try test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)), 0);
try test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
try test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000000)), @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, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), @as(i64, @bitCast(@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, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0, 0, 0);
try test__mulodi4(0, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0, 0);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0);
try test__mulodi4(1, @as(i64, @bitCast(@as(u64, 0x8000000000000000))), @as(i64, @bitCast(@as(u64, 0x8000000000000000))), 0);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000000))), 2, @as(i64, @bitCast(@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(-2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), -1, 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0, 0);
try test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
try test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
try test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
try test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), -2, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1);
try test__mulodi4(-2, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), -1, 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(-1, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0x7FFFFFFFFFFFFFFF, 0);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0, 0, 0);
try test__mulodi4(0, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0, 0);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), 1, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0);
try test__mulodi4(1, @as(i64, @bitCast(@as(u64, 0x8000000000000001))), @as(i64, @bitCast(@as(u64, 0x8000000000000001))), 0);
try test__mulodi4(@as(i64, @bitCast(@as(u64, 0x8000000000000001))), 2, @as(i64, @bitCast(@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(-0x1234567, 1, -0x1234567, 0);
try test__mulosi4(0x7FFFFFFF, -2, @bitCast(i32, @as(u32, 0x80000001)), 1);
try test__mulosi4(-2, 0x7FFFFFFF, @bitCast(i32, @as(u32, 0x80000001)), 1);
try test__mulosi4(0x7FFFFFFF, -1, @bitCast(i32, @as(u32, 0x80000001)), 0);
try test__mulosi4(-1, 0x7FFFFFFF, @bitCast(i32, @as(u32, 0x80000001)), 0);
try test__mulosi4(0x7FFFFFFF, -2, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(-2, 0x7FFFFFFF, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(0x7FFFFFFF, -1, @as(i32, @bitCast(@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(0, 0x7FFFFFFF, 0, 0);
try test__mulosi4(0x7FFFFFFF, 1, 0x7FFFFFFF, 0);
try test__mulosi4(1, 0x7FFFFFFF, 0x7FFFFFFF, 0);
try test__mulosi4(0x7FFFFFFF, 2, @bitCast(i32, @as(u32, 0x80000001)), 1);
try test__mulosi4(2, 0x7FFFFFFF, @bitCast(i32, @as(u32, 0x80000001)), 1);
try test__mulosi4(0x7FFFFFFF, 2, @as(i32, @bitCast(@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(-2, @bitCast(i32, @as(u32, 0x80000000)), @bitCast(i32, @as(u32, 0x80000000)), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)), 1);
try test__mulosi4(-1, @bitCast(i32, @as(u32, 0x80000000)), @bitCast(i32, @as(u32, 0x80000000)), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), 0, 0, 0);
try test__mulosi4(0, @bitCast(i32, @as(u32, 0x80000000)), 0, 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)), 0);
try test__mulosi4(1, @bitCast(i32, @as(u32, 0x80000000)), @bitCast(i32, @as(u32, 0x80000000)), 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0x80000000)), 1);
try test__mulosi4(2, @bitCast(i32, @as(u32, 0x80000000)), @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, @as(i32, @bitCast(@as(u32, 0x80000000))), @as(i32, @bitCast(@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, @as(i32, @bitCast(@as(u32, 0x80000000))), @as(i32, @bitCast(@as(u32, 0x80000000))), 1);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), 0, 0, 0);
try test__mulosi4(0, @as(i32, @bitCast(@as(u32, 0x80000000))), 0, 0);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), 1, @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__mulosi4(1, @as(i32, @bitCast(@as(u32, 0x80000000))), @as(i32, @bitCast(@as(u32, 0x80000000))), 0);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000000))), 2, @as(i32, @bitCast(@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(-2, @bitCast(i32, @as(u32, 0x80000001)), @bitCast(i32, @as(u32, 0x80000001)), 1);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), -1, 0x7FFFFFFF, 0);
try test__mulosi4(-1, @bitCast(i32, @as(u32, 0x80000001)), 0x7FFFFFFF, 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), 0, 0, 0);
try test__mulosi4(0, @bitCast(i32, @as(u32, 0x80000001)), 0, 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), 1, @bitCast(i32, @as(u32, 0x80000001)), 0);
try test__mulosi4(1, @bitCast(i32, @as(u32, 0x80000001)), @bitCast(i32, @as(u32, 0x80000001)), 0);
try test__mulosi4(@bitCast(i32, @as(u32, 0x80000001)), 2, @bitCast(i32, @as(u32, 0x80000000)), 1);
try test__mulosi4(2, @bitCast(i32, @as(u32, 0x80000001)), @bitCast(i32, @as(u32, 0x80000000)), 1);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), -2, @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(-2, @as(i32, @bitCast(@as(u32, 0x80000001))), @as(i32, @bitCast(@as(u32, 0x80000001))), 1);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), -1, 0x7FFFFFFF, 0);
try test__mulosi4(-1, @as(i32, @bitCast(@as(u32, 0x80000001))), 0x7FFFFFFF, 0);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), 0, 0, 0);
try test__mulosi4(0, @as(i32, @bitCast(@as(u32, 0x80000001))), 0, 0);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), 1, @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__mulosi4(1, @as(i32, @bitCast(@as(u32, 0x80000001))), @as(i32, @bitCast(@as(u32, 0x80000001))), 0);
try test__mulosi4(@as(i32, @bitCast(@as(u32, 0x80000001))), 2, @as(i32, @bitCast(@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(@bitCast(i128, @as(u128, 0x00000000000000B504F333F9DE5BE000)), @bitCast(i128, @as(u128, 0x000000000000000000B504F333F9DE5B)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFF328DF915DA296E8A000)), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
try test__muloti4(-2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
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(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), -2, @as(i128, @bitCast(@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(-1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0, 0);
try test__muloti4(0, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
try test__muloti4(1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
try test__muloti4(2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), -1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(-1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0, 0, 0);
try test__muloti4(0, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0, 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 2, @as(i128, @bitCast(@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(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), -1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
try test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0, 0);
try test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0);
try test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
try test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @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, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), @as(i128, @bitCast(@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, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0, 0, 0);
try test__muloti4(0, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0, 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0);
try test__muloti4(1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000000))), 2, @as(i128, @bitCast(@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(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), -1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
try test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0, 0);
try test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
try test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
try test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
try test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), -2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(-2, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), -1, @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(-1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), @as(i128, @bitCast(@as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))), 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0, 0, 0);
try test__muloti4(0, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0, 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(1, @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), @as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 0);
try test__muloti4(@as(i128, @bitCast(@as(u128, 0x80000000000000000000000000000001))), 2, @as(i128, @bitCast(@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,
};
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)
@panic("compiler_rt negv: overflow");
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 {
var x = switch (@bitSizeOf(T)) {
32 => @bitCast(u32, a),
64 => @bitCast(u64, a),
128 => @bitCast(u128, a),
32 => @as(u32, @bitCast(a)),
64 => @as(u64, @bitCast(a)),
128 => @as(u128, @bitCast(a)),
else => unreachable,
};
// Bit Twiddling Hacks: Compute parity in parallel
@ -39,7 +39,7 @@ inline fn parityXi2(comptime T: type, a: T) i32 {
shift = shift >> 1;
}
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 {

View File

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

View File

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

View File

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

View File

@ -37,7 +37,7 @@ inline fn popcountXi2(comptime ST: type, a: ST) i32 {
i128 => u128,
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 >> 2) & (~@as(UT, 0) / 5)) // 0x33...33, aggregate nibbles
+ (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) + ..
x *%= ~@as(UT, 0) / 255; // 0x01...01
x >>= (@bitSizeOf(ST) - 8);
return @intCast(i32, x);
return @as(i32, @intCast(x));
}
test {

View File

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

View File

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

View File

@ -5,8 +5,8 @@ const testing = std.testing;
fn popcountti2Naive(a: i128) i32 {
var x = a;
var r: i32 = 0;
while (x != 0) : (x = @bitCast(i128, @bitCast(u128, x) >> 1)) {
r += @intCast(i32, x & 1);
while (x != 0) : (x = @as(i128, @bitCast(@as(u128, @bitCast(x)) >> 1))) {
r += @as(i32, @intCast(x & 1));
}
return r;
}
@ -21,9 +21,9 @@ test "popcountti2" {
try test__popcountti2(0);
try test__popcountti2(1);
try test__popcountti2(2);
try test__popcountti2(@bitCast(i128, @as(u128, 0xffffffff_ffffffff_ffffffff_fffffffd)));
try test__popcountti2(@bitCast(i128, @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_fffffffd))));
try test__popcountti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_fffffffe))));
try test__popcountti2(@as(i128, @bitCast(@as(u128, 0xffffffff_ffffffff_ffffffff_ffffffff))));
const RndGen = std.rand.DefaultPrng;
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;
var r: FT = 1.0;
while (true) {
if (@bitCast(u32, x_b) & @as(u32, 1) != 0) {
if (@as(u32, @bitCast(x_b)) & @as(u32, 1) != 0) {
r *= x_a;
}
x_b = @divTrunc(x_b, @as(i32, 2));

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