aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-01-14 21:42:29 +0200
committerGitHub <noreply@github.com>2023-01-14 21:42:29 +0200
commitbb15e4057c9c8bb22084990de475ab10a44592c0 (patch)
treec1dcacddfc3ff184bd924405db0759ae2625280f /test
parent18191b80b6381eb41adb4354a243190865801212 (diff)
parent0013042cbd539cf7eb463483633e9f7aa2fa8067 (diff)
downloadzig-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.c103
-rw-r--r--test/c_abi/main.zig100
-rw-r--r--test/tests.zig12
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;
}