forked from ziglang/zig
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
compiler_rt: add __negvsi2, __negvdi2, __negvti2
- neg can only overflow, if a == MIN - case `-0` is properly handled by hardware, so overflow check by comparing `a == MIN` is sufficient - tests: MIN, MIN+1, MIN+4, -42, -7, -1, 0, 1, 7.. See ziglang#1290
- Loading branch information
Showing
6 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// negv - negate oVerflow | ||
// * @panic, if result can not be represented | ||
// - negvXi4_generic for unoptimized version | ||
|
||
// assume -0 == 0 is gracefully handled by the hardware | ||
fn negvXi_generic(comptime ST: type) fn (a: ST) callconv(.C) ST { | ||
return struct { | ||
fn f(a: ST) callconv(.C) ST { | ||
const UT = switch (ST) { | ||
i32 => u32, | ||
i64 => u64, | ||
i128 => u128, | ||
else => unreachable, | ||
}; | ||
const N: UT = @bitSizeOf(ST); | ||
const min: ST = @bitCast(ST, (@as(UT, 1) << (N - 1))); | ||
if (a == min) | ||
@panic("compiler_rt negv: overflow"); | ||
return -a; | ||
} | ||
}.f; | ||
} | ||
pub const __negvsi2 = negvXi_generic(i32); | ||
pub const __negvdi2 = negvXi_generic(i64); | ||
pub const __negvti2 = negvXi_generic(i128); | ||
|
||
test { | ||
_ = @import("negvsi2_test.zig"); | ||
_ = @import("negvdi2_test.zig"); | ||
_ = @import("negvti2_test.zig"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const negv = @import("negv.zig"); | ||
const testing = @import("std").testing; | ||
|
||
fn test__negvdi2(a: i64, expected: i64) !void { | ||
var result = negv.__negvdi2(a); | ||
try testing.expectEqual(expected, result); | ||
} | ||
|
||
test "negvdi2" { | ||
// -2^63 <= i64 <= 2^63-1 | ||
// 2^63 = 9223372036854775808 | ||
// 2^63-1 = 9223372036854775807 | ||
// TODO write panic handler for testing panics | ||
//try test__negvdi2(-9223372036854775808, -5); // tested with return -5; and panic | ||
try test__negvdi2(-9223372036854775807, 9223372036854775807); | ||
try test__negvdi2(-9223372036854775806, 9223372036854775806); | ||
try test__negvdi2(-9223372036854775805, 9223372036854775805); | ||
try test__negvdi2(-9223372036854775804, 9223372036854775804); | ||
try test__negvdi2(-42, 42); | ||
try test__negvdi2(-7, 7); | ||
try test__negvdi2(-1, 1); | ||
try test__negvdi2(0, 0); | ||
try test__negvdi2(1, -1); | ||
try test__negvdi2(7, -7); | ||
try test__negvdi2(42, -42); | ||
try test__negvdi2(9223372036854775804, -9223372036854775804); | ||
try test__negvdi2(9223372036854775805, -9223372036854775805); | ||
try test__negvdi2(9223372036854775806, -9223372036854775806); | ||
try test__negvdi2(9223372036854775807, -9223372036854775807); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const negv = @import("negv.zig"); | ||
const testing = @import("std").testing; | ||
|
||
fn test__negvsi2(a: i32, expected: i32) !void { | ||
var result = negv.__negvsi2(a); | ||
try testing.expectEqual(expected, result); | ||
} | ||
|
||
test "negvsi2" { | ||
// -2^31 <= i32 <= 2^31-1 | ||
// 2^31 = 2147483648 | ||
// 2^31-1 = 2147483647 | ||
// TODO write panic handler for testing panics | ||
//try test__negvsi2(-2147483648, -5); // tested with return -5; and panic | ||
try test__negvsi2(-2147483647, 2147483647); | ||
try test__negvsi2(-2147483646, 2147483646); | ||
try test__negvsi2(-2147483645, 2147483645); | ||
try test__negvsi2(-2147483644, 2147483644); | ||
try test__negvsi2(-42, 42); | ||
try test__negvsi2(-7, 7); | ||
try test__negvsi2(-1, 1); | ||
try test__negvsi2(0, 0); | ||
try test__negvsi2(1, -1); | ||
try test__negvsi2(7, -7); | ||
try test__negvsi2(42, -42); | ||
try test__negvsi2(2147483644, -2147483644); | ||
try test__negvsi2(2147483645, -2147483645); | ||
try test__negvsi2(2147483646, -2147483646); | ||
try test__negvsi2(2147483647, -2147483647); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const negv = @import("negv.zig"); | ||
const testing = @import("std").testing; | ||
|
||
fn test__negvti2(a: i128, expected: i128) !void { | ||
var result = negv.__negvti2(a); | ||
try testing.expectEqual(expected, result); | ||
} | ||
|
||
test "negvti2" { | ||
// -2^127 <= i128 <= 2^127-1 | ||
// 2^127 = 170141183460469231731687303715884105728 | ||
// 2^127+1 = 170141183460469231731687303715884105727 | ||
// TODO write panic handler for testing panics | ||
//try test__negvti2(-170141183460469231731687303715884105728, -5); // tested with return -5; and panic | ||
try test__negvti2(-170141183460469231731687303715884105727, 170141183460469231731687303715884105727); | ||
try test__negvti2(-170141183460469231731687303715884105726, 170141183460469231731687303715884105726); | ||
try test__negvti2(-170141183460469231731687303715884105725, 170141183460469231731687303715884105725); | ||
try test__negvti2(-170141183460469231731687303715884105724, 170141183460469231731687303715884105724); | ||
try test__negvti2(-42, 42); | ||
try test__negvti2(-7, 7); | ||
try test__negvti2(-1, 1); | ||
try test__negvti2(0, 0); | ||
try test__negvti2(1, -1); | ||
try test__negvti2(7, -7); | ||
try test__negvti2(42, -42); | ||
try test__negvti2(170141183460469231731687303715884105724, -170141183460469231731687303715884105724); | ||
try test__negvti2(170141183460469231731687303715884105725, -170141183460469231731687303715884105725); | ||
try test__negvti2(170141183460469231731687303715884105726, -170141183460469231731687303715884105726); | ||
try test__negvti2(170141183460469231731687303715884105727, -170141183460469231731687303715884105727); | ||
} |