authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-10-09 23:24:29-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-10-09 23:24:29-07:00
loga06185f3620953b8402b26a12e80aee12cd9ac8d
treeafb96b39522c4f267b9bfc59b80ce6296c76e096
parent879fb0c57cb483317ba671352144792e6d674779

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.

2 files changed, 176 insertions(+), 0 deletions(-)

test/c_abi/cfuncs.c+81
...@@ -2,6 +2,7 @@...@@ -2,6 +2,7 @@
2#include <stdlib.h>2#include <stdlib.h>
3#include <stdbool.h>3#include <stdbool.h>
4#include <string.h>4#include <string.h>
5#include <complex.h>
56
6void zig_panic();7void zig_panic();
78
...@@ -50,6 +51,13 @@ void zig_ptr(void *);...@@ -50,6 +51,13 @@ void zig_ptr(void *);
5051
51void zig_bool(bool);52void zig_bool(bool);
5253
54// Note: These two functions match the signature of __mulsc3 and __muldc3 in compiler-rt (and libgcc)
55float complex zig_cmultf_comp(float a_r, float a_i, float b_r, float b_i);
56double complex zig_cmultd_comp(double a_r, double a_i, double b_r, double b_i);
57
58float complex zig_cmultf(float complex a, float complex b);
59double complex zig_cmultd(double complex a, double complex b);
60
53struct BigStruct {61struct BigStruct {
54 uint64_t a;62 uint64_t a;
55 uint64_t b;63 uint64_t b;
...@@ -167,6 +175,43 @@ void run_c_tests(void) {...@@ -167,6 +175,43 @@ void run_c_tests(void) {
167175
168 zig_bool(true);176 zig_bool(true);
169177
178 // TODO: Resolve https://github.com/ziglang/zig/issues/8465
179 //{
180 // float complex a = 1.25f + I * 2.6f;
181 // float complex b = 11.3f - I * 1.5f;
182 // float complex z = zig_cmultf(a, b);
183 // assert_or_panic(creal(z) == 1.5f);
184 // assert_or_panic(cimag(z) == 13.5f);
185 //}
186
187 {
188 double complex a = 1.25 + I * 2.6;
189 double complex b = 11.3 - I * 1.5;
190 double complex z = zig_cmultd(a, b);
191 assert_or_panic(creal(z) == 1.5);
192 assert_or_panic(cimag(z) == 13.5);
193 }
194
195 {
196 float a_r = 1.25f;
197 float a_i = 2.6f;
198 float b_r = 11.3f;
199 float b_i = -1.5f;
200 float complex z = zig_cmultf_comp(a_r, a_i, b_r, b_i);
201 assert_or_panic(creal(z) == 1.5f);
202 assert_or_panic(cimag(z) == 13.5f);
203 }
204
205 {
206 double a_r = 1.25;
207 double a_i = 2.6;
208 double b_r = 11.3;
209 double b_i = -1.5;
210 double complex z = zig_cmultd_comp(a_r, a_i, b_r, b_i);
211 assert_or_panic(creal(z) == 1.5);
212 assert_or_panic(cimag(z) == 13.5);
213 }
214
170 {215 {
171 struct BigStruct s = {1, 2, 3, 4, 5};216 struct BigStruct s = {1, 2, 3, 4, 5};
172 zig_big_struct(s);217 zig_big_struct(s);
...@@ -321,6 +366,42 @@ void c_five_floats(float a, float b, float c, float d, float e) {...@@ -321,6 +366,42 @@ void c_five_floats(float a, float b, float c, float d, float e) {
321 assert_or_panic(e == 5.0);366 assert_or_panic(e == 5.0);
322}367}
323368
369float complex c_cmultf_comp(float a_r, float a_i, float b_r, float b_i) {
370 assert_or_panic(a_r == 1.25f);
371 assert_or_panic(a_i == 2.6f);
372 assert_or_panic(b_r == 11.3f);
373 assert_or_panic(b_i == -1.5f);
374
375 return 1.5f + I * 13.5f;
376}
377
378double complex c_cmultd_comp(double a_r, double a_i, double b_r, double b_i) {
379 assert_or_panic(a_r == 1.25);
380 assert_or_panic(a_i == 2.6);
381 assert_or_panic(b_r == 11.3);
382 assert_or_panic(b_i == -1.5);
383
384 return 1.5 + I * 13.5;
385}
386
387float complex c_cmultf(float complex a, float complex b) {
388 assert_or_panic(creal(a) == 1.25f);
389 assert_or_panic(cimag(a) == 2.6f);
390 assert_or_panic(creal(b) == 11.3f);
391 assert_or_panic(cimag(b) == -1.5f);
392
393 return 1.5f + I * 13.5f;
394}
395
396double complex c_cmultd(double complex a, double complex b) {
397 assert_or_panic(creal(a) == 1.25);
398 assert_or_panic(cimag(a) == 2.6);
399 assert_or_panic(creal(b) == 11.3);
400 assert_or_panic(cimag(b) == -1.5);
401
402 return 1.5 + I * 13.5;
403}
404
324void c_big_struct(struct BigStruct x) {405void c_big_struct(struct BigStruct x) {
325 assert_or_panic(x.a == 1);406 assert_or_panic(x.a == 1);
326 assert_or_panic(x.b == 2);407 assert_or_panic(x.b == 2);
test/c_abi/main.zig+95
...@@ -145,6 +145,101 @@ export fn zig_bool(x: bool) void {...@@ -145,6 +145,101 @@ export fn zig_bool(x: bool) void {
145 expect(x) catch @panic("test failure: zig_bool");145 expect(x) catch @panic("test failure: zig_bool");
146}146}
147147
148// TODO: Replace these with the correct types once we resolve
149// https://github.com/ziglang/zig/issues/8465
150//
151// For now, we have no way of referring to the _Complex C types from Zig,
152// so our ABI is unavoidably broken on some platforms (such as i386)
153const ComplexFloat = extern struct {
154 real: f32,
155 imag: f32,
156};
157const ComplexDouble = extern struct {
158 real: f64,
159 imag: f64,
160};
161
162// Note: These two functions match the signature of __mulsc3 and __muldc3 in compiler-rt (and libgcc)
163extern fn c_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat;
164extern fn c_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble;
165
166extern fn c_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat;
167extern fn c_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble;
168
169test "C ABI complex float" {
170 if (true) return error.SkipZigTest; // See https://github.com/ziglang/zig/issues/8465
171
172 const a = ComplexFloat{ .real = 1.25, .imag = 2.6 };
173 const b = ComplexFloat{ .real = 11.3, .imag = -1.5 };
174
175 const z = c_cmultf(a, b);
176 expect(z.real == 1.5) catch @panic("test failure: zig_complex_float 1");
177 expect(z.imag == 13.5) catch @panic("test failure: zig_complex_float 2");
178}
179
180test "C ABI complex float by component" {
181 const a = ComplexFloat{ .real = 1.25, .imag = 2.6 };
182 const b = ComplexFloat{ .real = 11.3, .imag = -1.5 };
183
184 const z2 = c_cmultf_comp(a.real, a.imag, b.real, b.imag);
185 expect(z2.real == 1.5) catch @panic("test failure: zig_complex_float 3");
186 expect(z2.imag == 13.5) catch @panic("test failure: zig_complex_float 4");
187}
188
189test "C ABI complex double" {
190 const a = ComplexDouble{ .real = 1.25, .imag = 2.6 };
191 const b = ComplexDouble{ .real = 11.3, .imag = -1.5 };
192
193 const z = c_cmultd(a, b);
194 expect(z.real == 1.5) catch @panic("test failure: zig_complex_double 1");
195 expect(z.imag == 13.5) catch @panic("test failure: zig_complex_double 2");
196}
197
198test "C ABI complex double by component" {
199 const a = ComplexDouble{ .real = 1.25, .imag = 2.6 };
200 const b = ComplexDouble{ .real = 11.3, .imag = -1.5 };
201
202 const z = c_cmultd_comp(a.real, a.imag, b.real, b.imag);
203 expect(z.real == 1.5) catch @panic("test failure: zig_complex_double 3");
204 expect(z.imag == 13.5) catch @panic("test failure: zig_complex_double 4");
205}
206
207export fn zig_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat {
208 expect(a.real == 1.25) catch @panic("test failure: zig_cmultf 1");
209 expect(a.imag == 2.6) catch @panic("test failure: zig_cmultf 2");
210 expect(b.real == 11.3) catch @panic("test failure: zig_cmultf 3");
211 expect(b.imag == -1.5) catch @panic("test failure: zig_cmultf 4");
212
213 return .{ .real = 1.5, .imag = 13.5 };
214}
215
216export fn zig_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble {
217 expect(a.real == 1.25) catch @panic("test failure: zig_cmultd 1");
218 expect(a.imag == 2.6) catch @panic("test failure: zig_cmultd 2");
219 expect(b.real == 11.3) catch @panic("test failure: zig_cmultd 3");
220 expect(b.imag == -1.5) catch @panic("test failure: zig_cmultd 4");
221
222 return .{ .real = 1.5, .imag = 13.5 };
223}
224
225export fn zig_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat {
226 expect(a_r == 1.25) catch @panic("test failure: zig_cmultf_comp 1");
227 expect(a_i == 2.6) catch @panic("test failure: zig_cmultf_comp 2");
228 expect(b_r == 11.3) catch @panic("test failure: zig_cmultf_comp 3");
229 expect(b_i == -1.5) catch @panic("test failure: zig_cmultf_comp 4");
230
231 return .{ .real = 1.5, .imag = 13.5 };
232}
233
234export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble {
235 expect(a_r == 1.25) catch @panic("test failure: zig_cmultd_comp 1");
236 expect(a_i == 2.6) catch @panic("test failure: zig_cmultd_comp 2");
237 expect(b_r == 11.3) catch @panic("test failure: zig_cmultd_comp 3");
238 expect(b_i == -1.5) catch @panic("test failure: zig_cmultd_comp 4");
239
240 return .{ .real = 1.5, .imag = 13.5 };
241}
242
148const BigStruct = extern struct {243const BigStruct = extern struct {
149 a: u64,244 a: u64,
150 b: u64,245 b: u64,