diff options
| author | Cody Tapscott <topolarity@tapscott.me> | 2022-10-09 23:24:29 -0700 |
|---|---|---|
| committer | Cody Tapscott <topolarity@tapscott.me> | 2022-10-09 23:24:29 -0700 |
| commit | a06185f3620953b8402b26a12e80aee12cd9ac8d (patch) | |
| tree | afb96b39522c4f267b9bfc59b80ce6296c76e096 | |
| parent | 879fb0c57cb483317ba671352144792e6d674779 (diff) | |
| download | zig-a06185f3620953b8402b26a12e80aee12cd9ac8d.tar.gz zig-a06185f3620953b8402b26a12e80aee12cd9ac8d.zip | |
C ABI: Add tests for complex float/double support
These tests will be failing on many platforms until #8465 is resolved.
Luckily, the particular function signature used for __divXc3 and __mulXc3
seems to be OK on x86-64.
| -rw-r--r-- | test/c_abi/cfuncs.c | 81 | ||||
| -rw-r--r-- | test/c_abi/main.zig | 95 |
2 files changed, 176 insertions, 0 deletions
diff --git a/test/c_abi/cfuncs.c b/test/c_abi/cfuncs.c index 89de8ebcb6..004dc9c406 100644 --- a/test/c_abi/cfuncs.c +++ b/test/c_abi/cfuncs.c @@ -2,6 +2,7 @@ #include <stdlib.h> #include <stdbool.h> #include <string.h> +#include <complex.h> void zig_panic(); @@ -50,6 +51,13 @@ void zig_ptr(void *); void zig_bool(bool); +// Note: These two functions match the signature of __mulsc3 and __muldc3 in compiler-rt (and libgcc) +float complex zig_cmultf_comp(float a_r, float a_i, float b_r, float b_i); +double complex zig_cmultd_comp(double a_r, double a_i, double b_r, double b_i); + +float complex zig_cmultf(float complex a, float complex b); +double complex zig_cmultd(double complex a, double complex b); + struct BigStruct { uint64_t a; uint64_t b; @@ -167,6 +175,43 @@ void run_c_tests(void) { zig_bool(true); + // TODO: Resolve https://github.com/ziglang/zig/issues/8465 + //{ + // float complex a = 1.25f + I * 2.6f; + // float complex b = 11.3f - I * 1.5f; + // float complex z = zig_cmultf(a, b); + // assert_or_panic(creal(z) == 1.5f); + // assert_or_panic(cimag(z) == 13.5f); + //} + + { + double complex a = 1.25 + I * 2.6; + double complex b = 11.3 - I * 1.5; + double complex z = zig_cmultd(a, b); + assert_or_panic(creal(z) == 1.5); + assert_or_panic(cimag(z) == 13.5); + } + + { + float a_r = 1.25f; + float a_i = 2.6f; + float b_r = 11.3f; + float b_i = -1.5f; + float complex z = zig_cmultf_comp(a_r, a_i, b_r, b_i); + assert_or_panic(creal(z) == 1.5f); + assert_or_panic(cimag(z) == 13.5f); + } + + { + double a_r = 1.25; + double a_i = 2.6; + double b_r = 11.3; + double b_i = -1.5; + double complex z = zig_cmultd_comp(a_r, a_i, b_r, b_i); + assert_or_panic(creal(z) == 1.5); + assert_or_panic(cimag(z) == 13.5); + } + { struct BigStruct s = {1, 2, 3, 4, 5}; zig_big_struct(s); @@ -321,6 +366,42 @@ void c_five_floats(float a, float b, float c, float d, float e) { assert_or_panic(e == 5.0); } +float complex c_cmultf_comp(float a_r, float a_i, float b_r, float b_i) { + assert_or_panic(a_r == 1.25f); + assert_or_panic(a_i == 2.6f); + assert_or_panic(b_r == 11.3f); + assert_or_panic(b_i == -1.5f); + + return 1.5f + I * 13.5f; +} + +double complex c_cmultd_comp(double a_r, double a_i, double b_r, double b_i) { + assert_or_panic(a_r == 1.25); + assert_or_panic(a_i == 2.6); + assert_or_panic(b_r == 11.3); + assert_or_panic(b_i == -1.5); + + return 1.5 + I * 13.5; +} + +float complex c_cmultf(float complex a, float complex b) { + assert_or_panic(creal(a) == 1.25f); + assert_or_panic(cimag(a) == 2.6f); + assert_or_panic(creal(b) == 11.3f); + assert_or_panic(cimag(b) == -1.5f); + + return 1.5f + I * 13.5f; +} + +double complex c_cmultd(double complex a, double complex b) { + assert_or_panic(creal(a) == 1.25); + assert_or_panic(cimag(a) == 2.6); + assert_or_panic(creal(b) == 11.3); + assert_or_panic(cimag(b) == -1.5); + + return 1.5 + I * 13.5; +} + void c_big_struct(struct BigStruct x) { assert_or_panic(x.a == 1); assert_or_panic(x.b == 2); diff --git a/test/c_abi/main.zig b/test/c_abi/main.zig index e8e2f4861c..9344c2efae 100644 --- a/test/c_abi/main.zig +++ b/test/c_abi/main.zig @@ -145,6 +145,101 @@ export fn zig_bool(x: bool) void { expect(x) catch @panic("test failure: zig_bool"); } +// TODO: Replace these with the correct types once we resolve +// https://github.com/ziglang/zig/issues/8465 +// +// For now, we have no way of referring to the _Complex C types from Zig, +// so our ABI is unavoidably broken on some platforms (such as i386) +const ComplexFloat = extern struct { + real: f32, + imag: f32, +}; +const ComplexDouble = extern struct { + real: f64, + imag: f64, +}; + +// Note: These two functions match the signature of __mulsc3 and __muldc3 in compiler-rt (and libgcc) +extern fn c_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat; +extern fn c_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble; + +extern fn c_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat; +extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble; + +test "C ABI complex float" { + if (true) return error.SkipZigTest; // See https://github.com/ziglang/zig/issues/8465 + + const a = ComplexFloat{ .real = 1.25, .imag = 2.6 }; + const b = ComplexFloat{ .real = 11.3, .imag = -1.5 }; + + const z = c_cmultf(a, b); + expect(z.real == 1.5) catch @panic("test failure: zig_complex_float 1"); + expect(z.imag == 13.5) catch @panic("test failure: zig_complex_float 2"); +} + +test "C ABI complex float by component" { + const a = ComplexFloat{ .real = 1.25, .imag = 2.6 }; + const b = ComplexFloat{ .real = 11.3, .imag = -1.5 }; + + const z2 = c_cmultf_comp(a.real, a.imag, b.real, b.imag); + expect(z2.real == 1.5) catch @panic("test failure: zig_complex_float 3"); + expect(z2.imag == 13.5) catch @panic("test failure: zig_complex_float 4"); +} + +test "C ABI complex double" { + const a = ComplexDouble{ .real = 1.25, .imag = 2.6 }; + const b = ComplexDouble{ .real = 11.3, .imag = -1.5 }; + + const z = c_cmultd(a, b); + expect(z.real == 1.5) catch @panic("test failure: zig_complex_double 1"); + expect(z.imag == 13.5) catch @panic("test failure: zig_complex_double 2"); +} + +test "C ABI complex double by component" { + const a = ComplexDouble{ .real = 1.25, .imag = 2.6 }; + const b = ComplexDouble{ .real = 11.3, .imag = -1.5 }; + + const z = c_cmultd_comp(a.real, a.imag, b.real, b.imag); + expect(z.real == 1.5) catch @panic("test failure: zig_complex_double 3"); + expect(z.imag == 13.5) catch @panic("test failure: zig_complex_double 4"); +} + +export fn zig_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat { + expect(a.real == 1.25) catch @panic("test failure: zig_cmultf 1"); + expect(a.imag == 2.6) catch @panic("test failure: zig_cmultf 2"); + expect(b.real == 11.3) catch @panic("test failure: zig_cmultf 3"); + expect(b.imag == -1.5) catch @panic("test failure: zig_cmultf 4"); + + return .{ .real = 1.5, .imag = 13.5 }; +} + +export fn zig_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble { + expect(a.real == 1.25) catch @panic("test failure: zig_cmultd 1"); + expect(a.imag == 2.6) catch @panic("test failure: zig_cmultd 2"); + expect(b.real == 11.3) catch @panic("test failure: zig_cmultd 3"); + expect(b.imag == -1.5) catch @panic("test failure: zig_cmultd 4"); + + return .{ .real = 1.5, .imag = 13.5 }; +} + +export fn zig_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat { + expect(a_r == 1.25) catch @panic("test failure: zig_cmultf_comp 1"); + expect(a_i == 2.6) catch @panic("test failure: zig_cmultf_comp 2"); + expect(b_r == 11.3) catch @panic("test failure: zig_cmultf_comp 3"); + expect(b_i == -1.5) catch @panic("test failure: zig_cmultf_comp 4"); + + return .{ .real = 1.5, .imag = 13.5 }; +} + +export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble { + expect(a_r == 1.25) catch @panic("test failure: zig_cmultd_comp 1"); + expect(a_i == 2.6) catch @panic("test failure: zig_cmultd_comp 2"); + expect(b_r == 11.3) catch @panic("test failure: zig_cmultd_comp 3"); + expect(b_i == -1.5) catch @panic("test failure: zig_cmultd_comp 4"); + + return .{ .real = 1.5, .imag = 13.5 }; +} + const BigStruct = extern struct { a: u64, b: u64, |
