authorgravatar for gwenzek@users.noreply.github.comGuillaume Wenzek <gwenzek@users.noreply.github.com> 2022-11-20 10:14:02+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-11-20 01:14:02-08:00
log476b946802e8a5500ece44822c8f6d103a71bbb5
tree7a8aa192c4decf18b4675b9021a456f0a3dee351
parentfca776f8f5f6c31e66ddf8e858483b718618fbdf
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

compute LLVMTypes in ParamTypeIterator (#13592)

follow up on #13376 - fixes a bug in the x86_64 C ABI. Co-authored-by: Veikka Tuominen <git@vexu.eu>

3 files changed, 77 insertions(+), 137 deletions(-)

src/arch/x86_64/abi.zig+45
...@@ -507,3 +507,48 @@ pub const RegisterClass = struct {...@@ -507,3 +507,48 @@ pub const RegisterClass = struct {
507 break :blk set;507 break :blk set;
508 };508 };
509};509};
510
511const testing = std.testing;
512const Module = @import("../../Module.zig");
513const Value = @import("../../value.zig").Value;
514const builtin = @import("builtin");
515
516fn _field(comptime tag: Type.Tag, offset: u32) Module.Struct.Field {
517 return .{
518 .ty = Type.initTag(tag),
519 .default_val = Value.initTag(.unreachable_value),
520 .abi_align = 0,
521 .offset = offset,
522 .is_comptime = false,
523 };
524}
525
526test "C_C_D" {
527 var fields = Module.Struct.Fields{};
528 // const C_C_D = extern struct { v1: i8, v2: i8, v3: f64 };
529 try fields.ensureTotalCapacity(testing.allocator, 3);
530 defer fields.deinit(testing.allocator);
531 fields.putAssumeCapacity("v1", _field(.i8, 0));
532 fields.putAssumeCapacity("v2", _field(.i8, 1));
533 fields.putAssumeCapacity("v3", _field(.f64, 4));
534
535 var C_C_D_struct = Module.Struct{
536 .fields = fields,
537 .namespace = undefined,
538 .owner_decl = undefined,
539 .zir_index = undefined,
540 .layout = .Extern,
541 .status = .fully_resolved,
542 .known_non_opv = true,
543 };
544 var C_C_D = Type.Payload.Struct{ .data = &C_C_D_struct };
545
546 try testing.expectEqual(
547 [_]Class{ .integer, .sse, .none, .none, .none, .none, .none, .none },
548 classifySystemV(Type.initPayload(&C_C_D.base), builtin.target, .ret),
549 );
550 try testing.expectEqual(
551 [_]Class{ .integer, .sse, .none, .none, .none, .none, .none, .none },
552 classifySystemV(Type.initPayload(&C_C_D.base), builtin.target, .arg),
553 );
554}
src/codegen/llvm.zig+28-125
...@@ -1049,60 +1049,20 @@ pub const Object = struct {...@@ -1049,60 +1049,20 @@ pub const Object = struct {
1049 const aggregate = builder.buildInsertValue(partial, len_param, 1, "");1049 const aggregate = builder.buildInsertValue(partial, len_param, 1, "");
1050 try args.append(aggregate);1050 try args.append(aggregate);
1051 },1051 },
1052 .multiple_llvm_ints => {1052 .multiple_llvm_types => {
1053 assert(!it.byval_attr);1053 assert(!it.byval_attr);
1054 const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len];1054 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];
1055 const param_ty = fn_info.param_types[it.zig_index - 1];1055 const param_ty = fn_info.param_types[it.zig_index - 1];
1056 const param_llvm_ty = try dg.lowerType(param_ty);1056 const param_llvm_ty = try dg.lowerType(param_ty);
1057 const param_alignment = param_ty.abiAlignment(target);1057 const param_alignment = param_ty.abiAlignment(target);
1058 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);1058 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1059 var field_types_buf: [8]*llvm.Type = undefined;1059 const llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
1060 const field_types = field_types_buf[0..llvm_ints.len];1060 const casted_ptr = builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), "");
1061 for (llvm_ints) |int_bits, i| {1061 for (field_types) |_, field_i_usize| {
1062 field_types[i] = dg.context.intType(int_bits);
1063 }
1064 const ints_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
1065 const casted_ptr = builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), "");
1066 for (llvm_ints) |_, field_i_usize| {
1067 const field_i = @intCast(c_uint, field_i_usize);1062 const field_i = @intCast(c_uint, field_i_usize);
1068 const param = llvm_func.getParam(llvm_arg_i);1063 const param = llvm_func.getParam(llvm_arg_i);
1069 llvm_arg_i += 1;1064 llvm_arg_i += 1;
1070 const field_ptr = builder.buildStructGEP(ints_llvm_ty, casted_ptr, field_i, "");1065 const field_ptr = builder.buildStructGEP(llvm_ty, casted_ptr, field_i, "");
1071 const store_inst = builder.buildStore(param, field_ptr);
1072 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
1073 }
1074
1075 const is_by_ref = isByRef(param_ty);
1076 const loaded = if (is_by_ref) arg_ptr else l: {
1077 const load_inst = builder.buildLoad(param_llvm_ty, arg_ptr, "");
1078 load_inst.setAlignment(param_alignment);
1079 break :l load_inst;
1080 };
1081 try args.append(loaded);
1082 },
1083 .multiple_llvm_float => {
1084 assert(!it.byval_attr);
1085 const llvm_floats = it.llvm_types_buffer[0..it.llvm_types_len];
1086 const param_ty = fn_info.param_types[it.zig_index - 1];
1087 const param_llvm_ty = try dg.lowerType(param_ty);
1088 const param_alignment = param_ty.abiAlignment(target);
1089 const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty, param_alignment, target);
1090 var field_types_buf: [8]*llvm.Type = undefined;
1091 const field_types = field_types_buf[0..llvm_floats.len];
1092 for (llvm_floats) |float_bits, i| {
1093 switch (float_bits) {
1094 64 => field_types[i] = dg.context.doubleType(),
1095 80 => field_types[i] = dg.context.x86FP80Type(),
1096 else => {},
1097 }
1098 }
1099 const floats_llvm_ty = dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
1100 const casted_ptr = builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), "");
1101 for (llvm_floats) |_, field_i_usize| {
1102 const field_i = @intCast(c_uint, field_i_usize);
1103 const param = llvm_func.getParam(llvm_arg_i);
1104 llvm_arg_i += 1;
1105 const field_ptr = builder.buildStructGEP(floats_llvm_ty, casted_ptr, field_i, "");
1106 const store_inst = builder.buildStore(param, field_ptr);1066 const store_inst = builder.buildStore(param, field_ptr);
1107 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);1067 store_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
1108 }1068 }
...@@ -2626,8 +2586,7 @@ pub const DeclGen = struct {...@@ -2626,8 +2586,7 @@ pub const DeclGen = struct {
2626 // No attributes needed for these.2586 // No attributes needed for these.
2627 .no_bits,2587 .no_bits,
2628 .abi_sized_int,2588 .abi_sized_int,
2629 .multiple_llvm_ints,2589 .multiple_llvm_types,
2630 .multiple_llvm_float,
2631 .as_u16,2590 .as_u16,
2632 .float_array,2591 .float_array,
2633 .i32_array,2592 .i32_array,
...@@ -3167,25 +3126,8 @@ pub const DeclGen = struct {...@@ -3167,25 +3126,8 @@ pub const DeclGen = struct {
3167 llvm_params.appendAssumeCapacity(ptr_llvm_ty);3126 llvm_params.appendAssumeCapacity(ptr_llvm_ty);
3168 llvm_params.appendAssumeCapacity(len_llvm_ty);3127 llvm_params.appendAssumeCapacity(len_llvm_ty);
3169 },3128 },
3170 .multiple_llvm_ints => {3129 .multiple_llvm_types => {
3171 const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len];3130 try llvm_params.appendSlice(it.llvm_types_buffer[0..it.llvm_types_len]);
3172 try llvm_params.ensureUnusedCapacity(it.llvm_types_len);
3173 for (llvm_ints) |int_bits| {
3174 const big_int_ty = dg.context.intType(int_bits);
3175 llvm_params.appendAssumeCapacity(big_int_ty);
3176 }
3177 },
3178 .multiple_llvm_float => {
3179 const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len];
3180 try llvm_params.ensureUnusedCapacity(it.llvm_types_len);
3181 for (llvm_ints) |float_bits| {
3182 const float_ty = switch (float_bits) {
3183 64 => dg.context.doubleType(),
3184 80 => dg.context.x86FP80Type(),
3185 else => unreachable,
3186 };
3187 llvm_params.appendAssumeCapacity(float_ty);
3188 }
3189 },3131 },
3190 .as_u16 => {3132 .as_u16 => {
3191 try llvm_params.append(dg.context.intType(16));3133 try llvm_params.append(dg.context.intType(16));
...@@ -4824,10 +4766,10 @@ pub const FuncGen = struct {...@@ -4824,10 +4766,10 @@ pub const FuncGen = struct {
4824 llvm_args.appendAssumeCapacity(ptr);4766 llvm_args.appendAssumeCapacity(ptr);
4825 llvm_args.appendAssumeCapacity(len);4767 llvm_args.appendAssumeCapacity(len);
4826 },4768 },
4827 .multiple_llvm_ints => {4769 .multiple_llvm_types => {
4828 const arg = args[it.zig_index - 1];4770 const arg = args[it.zig_index - 1];
4829 const param_ty = self.air.typeOf(arg);4771 const param_ty = self.air.typeOf(arg);
4830 const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len];4772 const llvm_types = it.llvm_types_buffer[0..it.llvm_types_len];
4831 const llvm_arg = try self.resolveInst(arg);4773 const llvm_arg = try self.resolveInst(arg);
4832 const is_by_ref = isByRef(param_ty);4774 const is_by_ref = isByRef(param_ty);
4833 const arg_ptr = if (is_by_ref) llvm_arg else p: {4775 const arg_ptr = if (is_by_ref) llvm_arg else p: {
...@@ -4837,51 +4779,13 @@ pub const FuncGen = struct {...@@ -4837,51 +4779,13 @@ pub const FuncGen = struct {
4837 break :p p;4779 break :p p;
4838 };4780 };
48394781
4840 var field_types_buf: [8]*llvm.Type = undefined;4782 const llvm_ty = self.dg.context.structType(llvm_types.ptr, @intCast(c_uint, llvm_types.len), .False);
4841 const field_types = field_types_buf[0..llvm_ints.len];4783 const casted_ptr = self.builder.buildBitCast(arg_ptr, llvm_ty.pointerType(0), "");
4842 for (llvm_ints) |int_bits, i| {
4843 field_types[i] = self.dg.context.intType(int_bits);
4844 }
4845 const ints_llvm_ty = self.dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
4846 const casted_ptr = self.builder.buildBitCast(arg_ptr, ints_llvm_ty.pointerType(0), "");
4847 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);4784 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
4848 for (llvm_ints) |_, i_usize| {4785 for (llvm_types) |field_ty, i_usize| {
4849 const i = @intCast(c_uint, i_usize);4786 const i = @intCast(c_uint, i_usize);
4850 const field_ptr = self.builder.buildStructGEP(ints_llvm_ty, casted_ptr, i, "");4787 const field_ptr = self.builder.buildStructGEP(llvm_ty, casted_ptr, i, "");
4851 const load_inst = self.builder.buildLoad(field_types[i], field_ptr, "");4788 const load_inst = self.builder.buildLoad(field_ty, field_ptr, "");
4852 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
4853 llvm_args.appendAssumeCapacity(load_inst);
4854 }
4855 },
4856 .multiple_llvm_float => {
4857 const arg = args[it.zig_index - 1];
4858 const param_ty = self.air.typeOf(arg);
4859 const llvm_floats = it.llvm_types_buffer[0..it.llvm_types_len];
4860 const llvm_arg = try self.resolveInst(arg);
4861 const is_by_ref = isByRef(param_ty);
4862 const arg_ptr = if (is_by_ref) llvm_arg else p: {
4863 const p = self.buildAlloca(llvm_arg.typeOf(), null);
4864 const store_inst = self.builder.buildStore(llvm_arg, p);
4865 store_inst.setAlignment(param_ty.abiAlignment(target));
4866 break :p p;
4867 };
4868
4869 var field_types_buf: [8]*llvm.Type = undefined;
4870 const field_types = field_types_buf[0..llvm_floats.len];
4871 for (llvm_floats) |float_bits, i| {
4872 switch (float_bits) {
4873 64 => field_types[i] = self.dg.context.doubleType(),
4874 80 => field_types[i] = self.dg.context.x86FP80Type(),
4875 else => {},
4876 }
4877 }
4878 const floats_llvm_ty = self.dg.context.structType(field_types.ptr, @intCast(c_uint, field_types.len), .False);
4879 const casted_ptr = self.builder.buildBitCast(arg_ptr, floats_llvm_ty.pointerType(0), "");
4880 try llvm_args.ensureUnusedCapacity(it.llvm_types_len);
4881 for (llvm_floats) |_, i_usize| {
4882 const i = @intCast(c_uint, i_usize);
4883 const field_ptr = self.builder.buildStructGEP(floats_llvm_ty, casted_ptr, i, "");
4884 const load_inst = self.builder.buildLoad(field_types[i], field_ptr, "");
4885 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);4789 load_inst.setAlignment(target.cpu.arch.ptrBitWidth() / 8);
4886 llvm_args.appendAssumeCapacity(load_inst);4790 llvm_args.appendAssumeCapacity(load_inst);
4887 }4791 }
...@@ -10473,7 +10377,7 @@ const ParamTypeIterator = struct {...@@ -10473,7 +10377,7 @@ const ParamTypeIterator = struct {
10473 llvm_index: u32,10377 llvm_index: u32,
10474 target: std.Target,10378 target: std.Target,
10475 llvm_types_len: u32,10379 llvm_types_len: u32,
10476 llvm_types_buffer: [8]u16,10380 llvm_types_buffer: [8]*llvm.Type,
10477 byval_attr: bool,10381 byval_attr: bool,
1047810382
10479 const Lowering = union(enum) {10383 const Lowering = union(enum) {
...@@ -10481,8 +10385,7 @@ const ParamTypeIterator = struct {...@@ -10481,8 +10385,7 @@ const ParamTypeIterator = struct {
10481 byval,10385 byval,
10482 byref,10386 byref,
10483 abi_sized_int,10387 abi_sized_int,
10484 multiple_llvm_ints,10388 multiple_llvm_types,
10485 multiple_llvm_float,
10486 slice,10389 slice,
10487 as_u16,10390 as_u16,
10488 float_array: u8,10391 float_array: u8,
...@@ -10515,7 +10418,7 @@ const ParamTypeIterator = struct {...@@ -10515,7 +10418,7 @@ const ParamTypeIterator = struct {
10515 it.zig_index += 1;10418 it.zig_index += 1;
10516 return .no_bits;10419 return .no_bits;
10517 }10420 }
1051810421 const dg = it.dg;
10519 switch (it.fn_info.cc) {10422 switch (it.fn_info.cc) {
10520 .Unspecified, .Inline => {10423 .Unspecified, .Inline => {
10521 it.zig_index += 1;10424 it.zig_index += 1;
...@@ -10584,28 +10487,28 @@ const ParamTypeIterator = struct {...@@ -10584,28 +10487,28 @@ const ParamTypeIterator = struct {
10584 it.llvm_index += 1;10487 it.llvm_index += 1;
10585 return .byval;10488 return .byval;
10586 }10489 }
10587 var llvm_types_buffer: [8]u16 = undefined;10490 var llvm_types_buffer: [8]*llvm.Type = undefined;
10588 var llvm_types_index: u32 = 0;10491 var llvm_types_index: u32 = 0;
10589 for (classes) |class| {10492 for (classes) |class| {
10590 switch (class) {10493 switch (class) {
10591 .integer => {10494 .integer => {
10592 llvm_types_buffer[llvm_types_index] = 64;10495 llvm_types_buffer[llvm_types_index] = dg.context.intType(64);
10593 llvm_types_index += 1;10496 llvm_types_index += 1;
10594 },10497 },
10595 .sse => {10498 .sse => {
10596 llvm_types_buffer[llvm_types_index] = 64;10499 llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
10597 llvm_types_index += 1;10500 llvm_types_index += 1;
10598 },10501 },
10599 .sseup => {10502 .sseup => {
10600 llvm_types_buffer[llvm_types_index] = 64;10503 llvm_types_buffer[llvm_types_index] = dg.context.doubleType();
10601 llvm_types_index += 1;10504 llvm_types_index += 1;
10602 },10505 },
10603 .x87 => {10506 .x87 => {
10604 llvm_types_buffer[llvm_types_index] = 80;10507 llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();
10605 llvm_types_index += 1;10508 llvm_types_index += 1;
10606 },10509 },
10607 .x87up => {10510 .x87up => {
10608 llvm_types_buffer[llvm_types_index] = 80;10511 llvm_types_buffer[llvm_types_index] = dg.context.x86FP80Type();
10609 llvm_types_index += 1;10512 llvm_types_index += 1;
10610 },10513 },
10611 .complex_x87 => {10514 .complex_x87 => {
...@@ -10625,7 +10528,7 @@ const ParamTypeIterator = struct {...@@ -10625,7 +10528,7 @@ const ParamTypeIterator = struct {
10625 it.llvm_types_len = llvm_types_index;10528 it.llvm_types_len = llvm_types_index;
10626 it.llvm_index += llvm_types_index;10529 it.llvm_index += llvm_types_index;
10627 it.zig_index += 1;10530 it.zig_index += 1;
10628 return if (classes[0] == .integer) .multiple_llvm_ints else .multiple_llvm_float;10531 return .multiple_llvm_types;
10629 },10532 },
10630 },10533 },
10631 .wasm32 => {10534 .wasm32 => {
...@@ -10649,8 +10552,8 @@ const ParamTypeIterator = struct {...@@ -10649,8 +10552,8 @@ const ParamTypeIterator = struct {
10649 .byval => return .byval,10552 .byval => return .byval,
10650 .integer => {10553 .integer => {
10651 it.llvm_types_len = 1;10554 it.llvm_types_len = 1;
10652 it.llvm_types_buffer[0] = 64;10555 it.llvm_types_buffer[0] = dg.context.intType(64);
10653 return .multiple_llvm_ints;10556 return .multiple_llvm_types;
10654 },10557 },
10655 .double_integer => return Lowering{ .i64_array = 2 },10558 .double_integer => return Lowering{ .i64_array = 2 },
10656 }10559 }
test/c_abi/main.zig+4-12
...@@ -851,8 +851,6 @@ pub inline fn expectOk(c_err: c_int) !void {...@@ -851,8 +851,6 @@ pub inline fn expectOk(c_err: c_int) !void {
851/// Tests for Double + Char struct851/// Tests for Double + Char struct
852const DC = extern struct { v1: f64, v2: u8 };852const DC = extern struct { v1: f64, v2: u8 };
853test "DC: Zig passes to C" {853test "DC: Zig passes to C" {
854 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag != .windows)
855 return error.SkipZigTest;
856 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;854 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
857 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;855 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
858 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;856 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -866,8 +864,6 @@ test "DC: Zig returns to C" {...@@ -866,8 +864,6 @@ test "DC: Zig returns to C" {
866 try expectOk(c_assert_ret_DC());864 try expectOk(c_assert_ret_DC());
867}865}
868test "DC: C passes to Zig" {866test "DC: C passes to Zig" {
869 if (builtin.target.cpu.arch == .x86_64 and builtin.target.os.tag != .windows)
870 return error.SkipZigTest;
871 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;867 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
872 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;868 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
873 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;869 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -900,8 +896,7 @@ pub export fn zig_ret_DC() DC {...@@ -900,8 +896,7 @@ pub export fn zig_ret_DC() DC {
900const CFF = extern struct { v1: u8, v2: f32, v3: f32 };896const CFF = extern struct { v1: u8, v2: f32, v3: f32 };
901897
902test "CFF: Zig passes to C" {898test "CFF: Zig passes to C" {
903 if (builtin.target.cpu.arch.isX86() and builtin.target.os.tag != .windows)899 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
904 return error.SkipZigTest;
905 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;900 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
906 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;901 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
907 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;902 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
...@@ -914,8 +909,7 @@ test "CFF: Zig returns to C" {...@@ -914,8 +909,7 @@ test "CFF: Zig returns to C" {
914 try expectOk(c_assert_ret_CFF());909 try expectOk(c_assert_ret_CFF());
915}910}
916test "CFF: C passes to Zig" {911test "CFF: C passes to Zig" {
917 if (builtin.target.cpu.arch.isX86() and builtin.target.os.tag != .windows)912 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
918 return error.SkipZigTest;
919 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;913 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
920 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;914 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
921 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;915 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
...@@ -950,8 +944,7 @@ pub export fn zig_ret_CFF() CFF {...@@ -950,8 +944,7 @@ pub export fn zig_ret_CFF() CFF {
950const PD = extern struct { v1: ?*anyopaque, v2: f64 };944const PD = extern struct { v1: ?*anyopaque, v2: f64 };
951945
952test "PD: Zig passes to C" {946test "PD: Zig passes to C" {
953 if (builtin.target.cpu.arch.isX86() and builtin.target.os.tag != .windows)947 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
954 return error.SkipZigTest;
955 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;948 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
956 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;949 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
957 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;950 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
...@@ -964,8 +957,7 @@ test "PD: Zig returns to C" {...@@ -964,8 +957,7 @@ test "PD: Zig returns to C" {
964 try expectOk(c_assert_ret_PD());957 try expectOk(c_assert_ret_PD());
965}958}
966test "PD: C passes to Zig" {959test "PD: C passes to Zig" {
967 if (builtin.target.cpu.arch.isX86() and builtin.target.os.tag != .windows)960 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
968 return error.SkipZigTest;
969 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;961 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
970 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;962 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
971 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;963 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;