diff options
| author | Veikka Tuominen <git@vexu.eu> | 2023-01-14 21:42:29 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-01-14 21:42:29 +0200 |
| commit | bb15e4057c9c8bb22084990de475ab10a44592c0 (patch) | |
| tree | c1dcacddfc3ff184bd924405db0759ae2625280f /test | |
| parent | 18191b80b6381eb41adb4354a243190865801212 (diff) | |
| parent | 0013042cbd539cf7eb463483633e9f7aa2fa8067 (diff) | |
| download | zig-bb15e4057c9c8bb22084990de475ab10a44592c0.tar.gz zig-bb15e4057c9c8bb22084990de475ab10a44592c0.zip | |
Merge pull request #14271 from Vexu/c-abi
float related C ABI fixes
Diffstat (limited to 'test')
| -rw-r--r-- | test/c_abi/cfuncs.c | 103 | ||||
| -rw-r--r-- | test/c_abi/main.zig | 100 | ||||
| -rw-r--r-- | test/tests.zig | 12 |
3 files changed, 209 insertions, 6 deletions
diff --git a/test/c_abi/cfuncs.c b/test/c_abi/cfuncs.c index 16851f1c7e..1cd2bbdcbc 100644 --- a/test/c_abi/cfuncs.c +++ b/test/c_abi/cfuncs.c @@ -4,7 +4,7 @@ #include <stdlib.h> #include <string.h> -void zig_panic(); +void zig_panic(void); static void assert_or_panic(bool ok) { if (!ok) { @@ -60,6 +60,54 @@ static void assert_or_panic(bool ok) { # define ZIG_NO_COMPLEX #endif +#ifdef __x86_64__ +#define ZIG_NO_RAW_F16 +#endif + +#ifdef __i386__ +#define ZIG_NO_RAW_F16 +#endif + +#ifdef __mips__ +#define ZIG_NO_RAW_F16 +#endif + +#ifdef __riscv +#define ZIG_NO_RAW_F16 +#endif + +#ifdef __wasm__ +#define ZIG_NO_RAW_F16 +#endif + +#ifdef __powerpc__ +#define ZIG_NO_RAW_F16 +#endif + +#ifdef __aarch64__ +#define ZIG_NO_F128 +#endif + +#ifdef __arm__ +#define ZIG_NO_F128 +#endif + +#ifdef __mips__ +#define ZIG_NO_F128 +#endif + +#ifdef __riscv +#define ZIG_NO_F128 +#endif + +#ifdef __powerpc__ +#define ZIG_NO_F128 +#endif + +#ifdef __APPLE__ +#define ZIG_NO_F128 +#endif + #ifndef ZIG_NO_I128 struct i128 { __int128 value; @@ -884,3 +932,56 @@ void c_func_ptr_byval(void *a, void *b, struct ByVal in, unsigned long c, void * assert_or_panic((intptr_t)d == 4); assert_or_panic(e == 5); } + +#ifndef ZIG_NO_RAW_F16 +__fp16 c_f16(__fp16 a) { + assert_or_panic(a == 12); + return 34; +} +#endif + +typedef struct { + __fp16 a; +} f16_struct; +f16_struct c_f16_struct(f16_struct a) { + assert_or_panic(a.a == 12); + return (f16_struct){34}; +} + +#if defined __x86_64__ || defined __i386__ +typedef long double f80; +f80 c_f80(f80 a) { + assert_or_panic((double)a == 12.34); + return 56.78; +} +typedef struct { + f80 a; +} f80_struct; +f80_struct c_f80_struct(f80_struct a) { + assert_or_panic((double)a.a == 12.34); + return (f80_struct){56.78}; +} +typedef struct { + f80 a; + int b; +} f80_extra_struct; +f80_extra_struct c_f80_extra_struct(f80_extra_struct a) { + assert_or_panic((double)a.a == 12.34); + assert_or_panic(a.b == 42); + return (f80_extra_struct){56.78, 24}; +} +#endif + +#ifndef ZIG_NO_F128 +__float128 c_f128(__float128 a) { + assert_or_panic((double)a == 12.34); + return 56.78; +} +typedef struct { + __float128 a; +} f128_struct; +f128_struct c_f128_struct(f128_struct a) { + assert_or_panic((double)a.a == 12.34); + return (f128_struct){56.78}; +} +#endif diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig index dcf4cbe46f..426651aa9e 100644 --- a/test/c_abi/main.zig +++ b/test/c_abi/main.zig @@ -4,7 +4,7 @@ //! To run all the tests on the tier 1 architecture you can use: //! zig build test-c-abi -fqemu //! To run the tests on a specific architecture: -//! zig test -fno-stage1 -lc main.zig cfuncs.c -target mips-linux --test-cmd qemu-mips --test-cmd-bin +//! zig test -lc main.zig cfuncs.c -target mips-linux --test-cmd qemu-mips --test-cmd-bin const std = @import("std"); const builtin = @import("builtin"); const print = std.debug.print; @@ -13,6 +13,9 @@ const expectEqual = std.testing.expectEqual; const has_i128 = builtin.cpu.arch != .x86 and !builtin.cpu.arch.isARM() and !builtin.cpu.arch.isMIPS() and !builtin.cpu.arch.isPPC(); +const has_f128 = builtin.cpu.arch.isX86() and !builtin.os.tag.isDarwin(); +const has_f80 = builtin.cpu.arch.isX86(); + extern fn run_c_tests() void; export fn zig_panic() noreturn { @@ -764,6 +767,7 @@ extern fn c_float_array_struct(FloatArrayStruct) void; extern fn c_ret_float_array_struct() FloatArrayStruct; test "Float array like struct" { + if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; @@ -824,7 +828,9 @@ extern fn c_big_vec(BigVec) void; extern fn c_ret_big_vec() BigVec; test "big simd vector" { + if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; + if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .macos and builtin.mode != .Debug) return error.SkipZigTest; c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 }); @@ -875,6 +881,8 @@ test "DC: Zig passes to C" { try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 })); } test "DC: Zig returns to C" { + if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; @@ -888,6 +896,8 @@ test "DC: C passes to Zig" { try expectOk(c_send_DC()); } test "DC: C returns to Zig" { + if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; @@ -920,6 +930,7 @@ test "CFF: Zig passes to C" { try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 })); } test "CFF: Zig returns to C" { + if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; @@ -927,6 +938,8 @@ test "CFF: Zig returns to C" { } test "CFF: C passes to Zig" { if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest; + if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; @@ -934,6 +947,9 @@ test "CFF: C passes to Zig" { try expectOk(c_send_CFF()); } test "CFF: C returns to Zig" { + if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest; + if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; @@ -967,6 +983,7 @@ test "PD: Zig passes to C" { } test "PD: Zig returns to C" { if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; try expectOk(c_assert_ret_PD()); @@ -980,6 +997,7 @@ test "PD: C passes to Zig" { } test "PD: C returns to Zig" { if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; try expectEqual(c_ret_PD(), .{ .v1 = null, .v2 = 0.5 }); @@ -1014,6 +1032,7 @@ extern fn c_modify_by_ref_param(ByRef) ByRef; test "C function modifies by ref param" { if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; + if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .windows and builtin.mode != .Debug) return error.SkipZigTest; const res = c_modify_by_ref_param(.{ .val = 1, .arr = undefined }); try expect(res.val == 42); @@ -1034,6 +1053,8 @@ const ByVal = extern struct { extern fn c_func_ptr_byval(*anyopaque, *anyopaque, ByVal, c_ulong, *anyopaque, c_ulong) void; test "C function that takes byval struct called via function pointer" { + if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; var fn_ptr = &c_func_ptr_byval; @@ -1049,3 +1070,80 @@ test "C function that takes byval struct called via function pointer" { @as(c_ulong, 5), ); } + +extern fn c_f16(f16) f16; +test "f16 bare" { + if (!comptime builtin.cpu.arch.isAARCH64()) return error.SkipZigTest; + + const a = c_f16(12); + try expect(a == 34); +} + +const f16_struct = extern struct { + a: f16, +}; +extern fn c_f16_struct(f16_struct) f16_struct; +test "f16 struct" { + if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; + if (comptime builtin.target.cpu.arch.isMIPS()) return error.SkipZigTest; + if (comptime builtin.target.cpu.arch.isPPC()) return error.SkipZigTest; + if (comptime builtin.target.cpu.arch.isPPC()) return error.SkipZigTest; + if (comptime builtin.cpu.arch.isARM() and builtin.mode != .Debug) return error.SkipZigTest; + + const a = c_f16_struct(.{ .a = 12 }); + try expect(a.a == 34); +} + +extern fn c_f80(f80) f80; +test "f80 bare" { + if (!has_f80) return error.SkipZigTest; + + const a = c_f80(12.34); + try expect(@floatCast(f64, a) == 56.78); +} + +const f80_struct = extern struct { + a: f80, +}; +extern fn c_f80_struct(f80_struct) f80_struct; +test "f80 struct" { + if (!has_f80) return error.SkipZigTest; + if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; + if (builtin.mode != .Debug) return error.SkipZigTest; + + const a = c_f80_struct(.{ .a = 12.34 }); + try expect(@floatCast(f64, a.a) == 56.78); +} + +const f80_extra_struct = extern struct { + a: f80, + b: c_int, +}; +extern fn c_f80_extra_struct(f80_extra_struct) f80_extra_struct; +test "f80 extra struct" { + if (!has_f80) return error.SkipZigTest; + if (builtin.target.cpu.arch == .x86) return error.SkipZigTest; + + const a = c_f80_extra_struct(.{ .a = 12.34, .b = 42 }); + try expect(@floatCast(f64, a.a) == 56.78); + try expect(a.b == 24); +} + +extern fn c_f128(f128) f128; +test "f128 bare" { + if (!has_f128) return error.SkipZigTest; + + const a = c_f128(12.34); + try expect(@floatCast(f64, a) == 56.78); +} + +const f128_struct = extern struct { + a: f128, +}; +extern fn c_f128_struct(f128_struct) f128_struct; +test "f128 struct" { + if (!has_f128) return error.SkipZigTest; + + const a = c_f128_struct(.{ .a = 12.34 }); + try expect(@floatCast(f64, a.a) == 56.78); +} diff --git a/test/tests.zig b/test/tests.zig index d884a41599..ec567c29b5 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -1323,10 +1323,12 @@ const c_abi_targets = [_]CrossTarget{ }, }; -pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool) *build.Step { +pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool, skip_release: bool) *build.Step { const step = b.step("test-c-abi", "Run the C ABI tests"); - for (c_abi_targets) |c_abi_target| { + const modes: [2]Mode = .{ .Debug, .ReleaseFast }; + + for (modes[0 .. @as(u8, 1) + @boolToInt(!skip_release)]) |mode| for (c_abi_targets) |c_abi_target| { if (skip_non_native and !c_abi_target.isNative()) continue; @@ -1339,14 +1341,16 @@ pub fn addCAbiTests(b: *build.Builder, skip_non_native: bool) *build.Step { } test_step.linkLibC(); test_step.addCSourceFile("test/c_abi/cfuncs.c", &.{"-std=c99"}); + test_step.setBuildMode(mode); const triple_prefix = c_abi_target.zigTriple(b.allocator) catch unreachable; - test_step.setNamePrefix(b.fmt("{s}-{s} ", .{ + test_step.setNamePrefix(b.fmt("{s}-{s}-{s} ", .{ "test-c-abi", triple_prefix, + @tagName(mode), })); step.dependOn(&test_step.step); - } + }; return step; } |
