| ... | @@ -3,20 +3,24 @@ const clz = @import("count0bits.zig"); | ... | @@ -3,20 +3,24 @@ const clz = @import("count0bits.zig"); |
| 3 | const testing = @import("std").testing; | 3 | const testing = @import("std").testing; |
| 4 | | 4 | |
| 5 | fn test__clzsi2(a: u32, expected: i32) !void { | 5 | fn test__clzsi2(a: u32, expected: i32) !void { |
| 6 | const nakedClzsi2 = clz.__clzsi2; | 6 | // stage1 and stage2 diverge on function pointer semantics |
| 7 | const fnProto = fn (a: i32) callconv(.C) i32; | 7 | switch (builtin.zig_backend) { |
| 8 | const fnProtoPtr = switch (builtin.zig_backend) { | 8 | .stage1 => { |
| 9 | .stage1 => fnProto, | 9 | // Use of `var` here is working around a stage1 bug. |
| 10 | else => *const fnProto, | 10 | var nakedClzsi2 = clz.__clzsi2; |
| 11 | }; | 11 | var actualClzsi2 = @ptrCast(fn (a: i32) callconv(.C) i32, nakedClzsi2); |
| 12 | const fn_ptr = switch (builtin.zig_backend) { | 12 | var x = @bitCast(i32, a); |
| 13 | .stage1 => nakedClzsi2, | 13 | var result = actualClzsi2(x); |
| 14 | else => &nakedClzsi2, | 14 | try testing.expectEqual(expected, result); |
| 15 | }; | 15 | }, |
| 16 | const actualClzsi2 = @ptrCast(fnProtoPtr, fn_ptr); | 16 | else => { |
| 17 | const x = @bitCast(i32, a); | 17 | const nakedClzsi2 = clz.__clzsi2; |
| 18 | const result = actualClzsi2(x); | 18 | const actualClzsi2 = @ptrCast(*const fn (a: i32) callconv(.C) i32, &nakedClzsi2); |
| 19 | try testing.expectEqual(expected, result); | 19 | const x = @bitCast(i32, a); |
| | 20 | const result = actualClzsi2(x); |
| | 21 | try testing.expectEqual(expected, result); |
| | 22 | }, |
| | 23 | } |
| 20 | } | 24 | } |
| 21 | | 25 | |
| 22 | test "clzsi2" { | 26 | test "clzsi2" { |