Commit a06185f362
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);
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,