add C ABI tests for exotic float types

This commit is contained in:
Veikka Tuominen
2023-01-11 22:39:25 +02:00
parent 474848ac0b
commit 5572c67e73
4 changed files with 215 additions and 24 deletions

View File

@@ -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

View File

@@ -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 {
@@ -1069,3 +1072,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);
}