authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-27 22:51:58-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-27 23:31:20-04:00
loga440cf6d4454d3febfe07b6235745120d104cfa0
treea8c74967623411292b22b574956df98b97f43423
parentaecdf6ad50fef3ef68d699c2ef72b5904fdd3553

x86_64: fix c abi test failures


8 files changed, 489 insertions(+), 404 deletions(-)

lib/compiler_rt/tan.zig-2
...@@ -144,8 +144,6 @@ test "tan32" {...@@ -144,8 +144,6 @@ test "tan32" {
144}144}
145145
146test "tan64" {146test "tan64" {
147 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
148
149 const epsilon = 0.000001;147 const epsilon = 0.000001;
150148
151 try expect(math.approxEqAbs(f64, tan(0.0), 0.0, epsilon));149 try expect(math.approxEqAbs(f64, tan(0.0), 0.0, epsilon));
lib/std/atomic/Atomic.zig-2
...@@ -374,8 +374,6 @@ const atomic_rmw_orderings = [_]Ordering{...@@ -374,8 +374,6 @@ const atomic_rmw_orderings = [_]Ordering{
374};374};
375375
376test "Atomic.swap" {376test "Atomic.swap" {
377 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
378
379 inline for (atomic_rmw_orderings) |ordering| {377 inline for (atomic_rmw_orderings) |ordering| {
380 var x = Atomic(usize).init(5);378 var x = Atomic(usize).init(5);
381 try testing.expectEqual(x.swap(10, ordering), 5);379 try testing.expectEqual(x.swap(10, ordering), 5);
lib/std/debug.zig-2
...@@ -2513,8 +2513,6 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {...@@ -2513,8 +2513,6 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
2513}2513}
25142514
2515test "manage resources correctly" {2515test "manage resources correctly" {
2516 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
2517
2518 if (builtin.os.tag == .wasi) return error.SkipZigTest;2516 if (builtin.os.tag == .wasi) return error.SkipZigTest;
25192517
2520 if (builtin.os.tag == .windows) {2518 if (builtin.os.tag == .windows) {
lib/std/fmt/parse_float.zig+1-12
...@@ -2,7 +2,6 @@ pub const parseFloat = @import("parse_float/parse_float.zig").parseFloat;...@@ -2,7 +2,6 @@ pub const parseFloat = @import("parse_float/parse_float.zig").parseFloat;
2pub const ParseFloatError = @import("parse_float/parse_float.zig").ParseFloatError;2pub const ParseFloatError = @import("parse_float/parse_float.zig").ParseFloatError;
33
4const std = @import("std");4const std = @import("std");
5const builtin = @import("builtin");
6const math = std.math;5const math = std.math;
7const testing = std.testing;6const testing = std.testing;
8const expect = testing.expect;7const expect = testing.expect;
...@@ -14,8 +13,6 @@ const epsilon = 1e-7;...@@ -14,8 +13,6 @@ const epsilon = 1e-7;
14// See https://github.com/tiehuis/parse-number-fxx-test-data for a wider-selection of test-data.13// See https://github.com/tiehuis/parse-number-fxx-test-data for a wider-selection of test-data.
1514
16test "fmt.parseFloat" {15test "fmt.parseFloat" {
17 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
18
19 inline for ([_]type{ f16, f32, f64, f128 }) |T| {16 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
20 try testing.expectError(error.InvalidCharacter, parseFloat(T, ""));17 try testing.expectError(error.InvalidCharacter, parseFloat(T, ""));
21 try testing.expectError(error.InvalidCharacter, parseFloat(T, " 1"));18 try testing.expectError(error.InvalidCharacter, parseFloat(T, " 1"));
...@@ -72,8 +69,6 @@ test "fmt.parseFloat" {...@@ -72,8 +69,6 @@ test "fmt.parseFloat" {
72}69}
7370
74test "fmt.parseFloat nan and inf" {71test "fmt.parseFloat nan and inf" {
75 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
76
77 inline for ([_]type{ f16, f32, f64, f128 }) |T| {72 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
78 const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);73 const Z = std.meta.Int(.unsigned, @typeInfo(T).Float.bits);
7974
...@@ -88,7 +83,7 @@ test "fmt.parseFloat #11169" {...@@ -88,7 +83,7 @@ test "fmt.parseFloat #11169" {
88}83}
8984
90test "fmt.parseFloat hex.special" {85test "fmt.parseFloat hex.special" {
91 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;86 if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest;
9287
93 try testing.expect(math.isNan(try parseFloat(f32, "nAn")));88 try testing.expect(math.isNan(try parseFloat(f32, "nAn")));
94 try testing.expect(math.isPositiveInf(try parseFloat(f32, "iNf")));89 try testing.expect(math.isPositiveInf(try parseFloat(f32, "iNf")));
...@@ -96,8 +91,6 @@ test "fmt.parseFloat hex.special" {...@@ -96,8 +91,6 @@ test "fmt.parseFloat hex.special" {
96 try testing.expect(math.isNegativeInf(try parseFloat(f32, "-iNf")));91 try testing.expect(math.isNegativeInf(try parseFloat(f32, "-iNf")));
97}92}
98test "fmt.parseFloat hex.zero" {93test "fmt.parseFloat hex.zero" {
99 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
100
101 try testing.expectEqual(@as(f32, 0.0), try parseFloat(f32, "0x0"));94 try testing.expectEqual(@as(f32, 0.0), try parseFloat(f32, "0x0"));
102 try testing.expectEqual(@as(f32, 0.0), try parseFloat(f32, "-0x0"));95 try testing.expectEqual(@as(f32, 0.0), try parseFloat(f32, "-0x0"));
103 try testing.expectEqual(@as(f32, 0.0), try parseFloat(f32, "0x0p42"));96 try testing.expectEqual(@as(f32, 0.0), try parseFloat(f32, "0x0p42"));
...@@ -106,8 +99,6 @@ test "fmt.parseFloat hex.zero" {...@@ -106,8 +99,6 @@ test "fmt.parseFloat hex.zero" {
106}99}
107100
108test "fmt.parseFloat hex.f16" {101test "fmt.parseFloat hex.f16" {
109 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
110
111 try testing.expectEqual(try parseFloat(f16, "0x1p0"), 1.0);102 try testing.expectEqual(try parseFloat(f16, "0x1p0"), 1.0);
112 try testing.expectEqual(try parseFloat(f16, "-0x1p-1"), -0.5);103 try testing.expectEqual(try parseFloat(f16, "-0x1p-1"), -0.5);
113 try testing.expectEqual(try parseFloat(f16, "0x10p+10"), 16384.0);104 try testing.expectEqual(try parseFloat(f16, "0x10p+10"), 16384.0);
...@@ -124,8 +115,6 @@ test "fmt.parseFloat hex.f16" {...@@ -124,8 +115,6 @@ test "fmt.parseFloat hex.f16" {
124}115}
125116
126test "fmt.parseFloat hex.f32" {117test "fmt.parseFloat hex.f32" {
127 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
128
129 try testing.expectError(error.InvalidCharacter, parseFloat(f32, "0x"));118 try testing.expectError(error.InvalidCharacter, parseFloat(f32, "0x"));
130 try testing.expectEqual(try parseFloat(f32, "0x1p0"), 1.0);119 try testing.expectEqual(try parseFloat(f32, "0x1p0"), 1.0);
131 try testing.expectEqual(try parseFloat(f32, "-0x1p-1"), -0.5);120 try testing.expectEqual(try parseFloat(f32, "-0x1p-1"), -0.5);
lib/std/json/static_test.zig-2
...@@ -785,8 +785,6 @@ test "max_value_len" {...@@ -785,8 +785,6 @@ test "max_value_len" {
785}785}
786786
787test "parse into vector" {787test "parse into vector" {
788 if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest;
789
790 const T = struct {788 const T = struct {
791 vec_i32: @Vector(4, i32),789 vec_i32: @Vector(4, i32),
792 vec_f32: @Vector(2, f32),790 vec_f32: @Vector(2, f32),
src/arch/x86_64/CodeGen.zig+480-291
...@@ -6587,12 +6587,15 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -6587,12 +6587,15 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
6587 const src_reg_lock = self.register_manager.lockRegAssumeUnused(src_reg);6587 const src_reg_lock = self.register_manager.lockRegAssumeUnused(src_reg);
6588 defer self.register_manager.unlockReg(src_reg_lock);6588 defer self.register_manager.unlockReg(src_reg_lock);
65896589
6590 const dst_reg = if (field_rc.supersetOf(container_rc) and6590 const src_in_field_rc =
6591 self.reuseOperand(inst, operand, 0, src_mcv))6591 field_rc.isSet(RegisterManager.indexOfRegIntoTracked(src_reg).?);
6592 const dst_reg = if (src_in_field_rc and self.reuseOperand(inst, operand, 0, src_mcv))
6592 src_reg6593 src_reg
6594 else if (field_off == 0)
6595 (try self.copyToRegisterWithInstTracking(inst, field_ty, src_mcv)).register
6593 else6596 else
6594 try self.copyToTmpRegister(Type.usize, .{ .register = src_reg });6597 try self.copyToTmpRegister(Type.usize, .{ .register = src_reg });
6595 const dst_mcv = MCValue{ .register = dst_reg };6598 const dst_mcv: MCValue = .{ .register = dst_reg };
6596 const dst_lock = self.register_manager.lockReg(dst_reg);6599 const dst_lock = self.register_manager.lockReg(dst_reg);
6597 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);6600 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
65986601
...@@ -6602,9 +6605,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -6602,9 +6605,11 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
6602 dst_mcv,6605 dst_mcv,
6603 .{ .immediate = field_off },6606 .{ .immediate = field_off },
6604 );6607 );
6605 if (self.regExtraBits(field_ty) > 0) try self.truncateRegister(field_ty, dst_reg);6608 if (abi.RegisterClass.gp.isSet(RegisterManager.indexOfRegIntoTracked(dst_reg).?) and
6609 container_ty.abiSize(mod) * 8 > field_ty.bitSize(mod))
6610 try self.truncateRegister(field_ty, dst_reg);
66066611
6607 break :result if (field_rc.supersetOf(abi.RegisterClass.gp))6612 break :result if (field_off == 0 or field_rc.supersetOf(abi.RegisterClass.gp))
6608 dst_mcv6613 dst_mcv
6609 else6614 else
6610 try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv);6615 try self.copyToRegisterWithInstTracking(inst, field_ty, dst_mcv);
...@@ -9674,17 +9679,25 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -9674,17 +9679,25 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
9674 self.arg_index = arg_index + 1;9679 self.arg_index = arg_index + 1;
96759680
9676 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {9681 const result: MCValue = if (self.liveness.isUnused(inst)) .unreach else result: {
9677 const dst_mcv = self.args[arg_index];9682 const arg_ty = self.typeOfIndex(inst);
9678 switch (dst_mcv) {9683 const src_mcv = self.args[arg_index];
9679 .register, .register_pair, .load_frame => for (dst_mcv.getRegs()) |reg|9684 const dst_mcv = switch (src_mcv) {
9680 self.register_manager.getRegAssumeFree(reg, inst),9685 .register, .register_pair, .load_frame => dst: {
9681 else => return self.fail("TODO implement arg for {}", .{dst_mcv}),9686 for (src_mcv.getRegs()) |reg| self.register_manager.getRegAssumeFree(reg, inst);
9682 }9687 break :dst src_mcv;
9688 },
9689 .indirect => |reg_off| dst: {
9690 self.register_manager.getRegAssumeFree(reg_off.reg, inst);
9691 const dst_mcv = try self.allocRegOrMem(inst, false);
9692 try self.genCopy(arg_ty, dst_mcv, src_mcv);
9693 break :dst dst_mcv;
9694 },
9695 else => return self.fail("TODO implement arg for {}", .{src_mcv}),
9696 };
96839697
9684 const ty = self.typeOfIndex(inst);
9685 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;9698 const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
9686 const name = mod.getParamName(self.owner.func_index, src_index);9699 const name = mod.getParamName(self.owner.func_index, src_index);
9687 try self.genArgDbgInfo(ty, name, dst_mcv);9700 try self.genArgDbgInfo(arg_ty, name, src_mcv);
96889701
9689 break :result dst_mcv;9702 break :result dst_mcv;
9690 };9703 };
...@@ -9863,7 +9876,8 @@ fn genCall(self: *Self, info: union(enum) {...@@ -9863,7 +9876,8 @@ fn genCall(self: *Self, info: union(enum) {
98639876
9864 const ExpectedContents = extern struct {9877 const ExpectedContents = extern struct {
9865 var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),9878 var_args: [16][@sizeOf(Type)]u8 align(@alignOf(Type)),
9866 arg_regs: [16][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),9879 frame_indices: [16]FrameIndex,
9880 reg_locks: [16][@sizeOf(?RegisterLock)]u8 align(@alignOf(?RegisterLock)),
9867 };9881 };
9868 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =9882 var stack align(@max(@alignOf(ExpectedContents), @alignOf(std.heap.StackFallbackAllocator(0)))) =
9869 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);9883 std.heap.stackFallback(@sizeOf(ExpectedContents), self.gpa);
...@@ -9873,10 +9887,13 @@ fn genCall(self: *Self, info: union(enum) {...@@ -9873,10 +9887,13 @@ fn genCall(self: *Self, info: union(enum) {
9873 defer allocator.free(var_args);9887 defer allocator.free(var_args);
9874 for (var_args, arg_types[fn_info.param_types.len..]) |*var_arg, arg_ty| var_arg.* = arg_ty;9888 for (var_args, arg_types[fn_info.param_types.len..]) |*var_arg, arg_ty| var_arg.* = arg_ty;
98759889
9876 var arg_locks = std.ArrayList(?RegisterLock).init(allocator);9890 const frame_indices = try allocator.alloc(FrameIndex, args.len);
9877 defer arg_locks.deinit();9891 defer allocator.free(frame_indices);
9878 try arg_locks.ensureTotalCapacity(16);9892
9879 defer for (arg_locks.items) |arg_lock| if (arg_lock) |lock| self.register_manager.unlockReg(lock);9893 var reg_locks = std.ArrayList(?RegisterLock).init(allocator);
9894 defer reg_locks.deinit();
9895 try reg_locks.ensureTotalCapacity(16);
9896 defer for (reg_locks.items) |reg_lock| if (reg_lock) |lock| self.register_manager.unlockReg(lock);
98809897
9881 var call_info = try self.resolveCallingConventionValues(fn_info, var_args, .call_frame);9898 var call_info = try self.resolveCallingConventionValues(fn_info, var_args, .call_frame);
9882 defer call_info.deinit(self);9899 defer call_info.deinit(self);
...@@ -9908,44 +9925,69 @@ fn genCall(self: *Self, info: union(enum) {...@@ -9908,44 +9925,69 @@ fn genCall(self: *Self, info: union(enum) {
9908 .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}),9925 .indirect => |reg_off| try self.spillRegisters(&.{reg_off.reg}),
9909 else => unreachable,9926 else => unreachable,
9910 }9927 }
9911 for (call_info.args, arg_types, args) |dst_arg, arg_ty, src_arg| switch (dst_arg) {9928 for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, *frame_index|
9912 .none => {},9929 switch (dst_arg) {
9913 .register => |reg| {9930 .none => {},
9914 try self.spillRegisters(&.{reg});9931 .register => |reg| {
9915 try arg_locks.append(self.register_manager.lockReg(reg));9932 try self.spillRegisters(&.{reg});
9916 },9933 try reg_locks.append(self.register_manager.lockReg(reg));
9917 .register_pair => |regs| {9934 },
9918 try self.spillRegisters(&regs);9935 .register_pair => |regs| {
9919 try arg_locks.appendSlice(&self.register_manager.lockRegs(2, regs));9936 try self.spillRegisters(&regs);
9920 },9937 try reg_locks.appendSlice(&self.register_manager.lockRegs(2, regs));
9921 .load_frame => {9938 },
9922 try self.genCopy(arg_ty, dst_arg, src_arg);9939 .indirect => |reg_off| {
9923 try self.freeValue(src_arg);9940 frame_index.* = try self.allocFrameIndex(FrameAlloc.initType(arg_ty, mod));
9924 },9941 try self.genSetMem(.{ .frame = frame_index.* }, 0, arg_ty, src_arg);
9925 else => unreachable,9942 try self.spillRegisters(&.{reg_off.reg});
9926 };9943 try reg_locks.append(self.register_manager.lockReg(reg_off.reg));
9944 },
9945 .load_frame => {
9946 try self.genCopy(arg_ty, dst_arg, src_arg);
9947 try self.freeValue(src_arg);
9948 },
9949 else => unreachable,
9950 };
99279951
9928 // now we are free to set register arguments9952 // now we are free to set register arguments
9929 const ret_lock = switch (call_info.return_value.long) {9953 switch (call_info.return_value.long) {
9930 .none, .unreach => null,9954 .none, .unreach => {},
9931 .indirect => |reg_off| lock: {9955 .indirect => |reg_off| {
9932 const ret_ty = fn_info.return_type.toType();9956 const ret_ty = fn_info.return_type.toType();
9933 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ret_ty, mod));9957 const frame_index = try self.allocFrameIndex(FrameAlloc.initType(ret_ty, mod));
9934 try self.genSetReg(reg_off.reg, Type.usize, .{9958 try self.genSetReg(reg_off.reg, Type.usize, .{
9935 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },9959 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
9936 });9960 });
9937 call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } };9961 call_info.return_value.short = .{ .load_frame = .{ .index = frame_index } };
9938 break :lock self.register_manager.lockRegAssumeUnused(reg_off.reg);9962 try reg_locks.append(self.register_manager.lockReg(reg_off.reg));
9939 },9963 },
9940 else => unreachable,9964 else => unreachable,
9941 };9965 }
9942 defer if (ret_lock) |lock| self.register_manager.unlockReg(lock);
99439966
9944 for (call_info.args, arg_types, args) |dst_arg, arg_ty, src_arg| switch (dst_arg) {9967 for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, frame_index|
9945 .none, .load_frame => {},9968 switch (dst_arg) {
9946 .register, .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg),9969 .none, .load_frame => {},
9947 else => unreachable,9970 .register => |dst_reg| switch (fn_info.cc) {
9948 };9971 else => try self.genSetReg(
9972 registerAlias(dst_reg, @intCast(arg_ty.abiSize(mod))),
9973 arg_ty,
9974 src_arg,
9975 ),
9976 .C, .SysV, .Win64 => {
9977 const promoted_ty = self.promoteInt(arg_ty);
9978 const promoted_abi_size: u32 = @intCast(promoted_ty.abiSize(mod));
9979 const dst_alias = registerAlias(dst_reg, promoted_abi_size);
9980 try self.genSetReg(dst_alias, promoted_ty, src_arg);
9981 if (promoted_ty.toIntern() != arg_ty.toIntern())
9982 try self.truncateRegister(arg_ty, dst_alias);
9983 },
9984 },
9985 .register_pair => try self.genCopy(arg_ty, dst_arg, src_arg),
9986 .indirect => |reg_off| try self.genSetReg(reg_off.reg, Type.usize, .{
9987 .lea_frame = .{ .index = frame_index, .off = -reg_off.off },
9988 }),
9989 else => unreachable,
9990 };
99499991
9950 if (fn_info.is_var_args)9992 if (fn_info.is_var_args)
9951 try self.asmRegisterImmediate(.{ ._, .mov }, .al, Immediate.u(call_info.fp_count));9993 try self.asmRegisterImmediate(.{ ._, .mov }, .al, Immediate.u(call_info.fp_count));
...@@ -10054,7 +10096,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -10054,7 +10096,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
10054 const ptr_ty = self.typeOf(un_op);10096 const ptr_ty = self.typeOf(un_op);
10055 switch (self.ret_mcv.short) {10097 switch (self.ret_mcv.short) {
10056 .none => {},10098 .none => {},
10057 .register => try self.load(self.ret_mcv.short, ptr_ty, ptr),10099 .register, .register_pair => try self.load(self.ret_mcv.short, ptr_ty, ptr),
10058 .indirect => |reg_off| try self.genSetReg(reg_off.reg, ptr_ty, ptr),10100 .indirect => |reg_off| try self.genSetReg(reg_off.reg, ptr_ty, ptr),
10059 else => unreachable,10101 else => unreachable,
10060 }10102 }
...@@ -10115,20 +10157,28 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -10115,20 +10157,28 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
10115 try self.spillEflagsIfOccupied();10157 try self.spillEflagsIfOccupied();
1011610158
10117 const lhs_mcv = try self.resolveInst(bin_op.lhs);10159 const lhs_mcv = try self.resolveInst(bin_op.lhs);
10118 const lhs_lock = switch (lhs_mcv) {10160 const lhs_locks: [2]?RegisterLock = switch (lhs_mcv) {
10119 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),10161 .register => |lhs_reg| .{ self.register_manager.lockRegAssumeUnused(lhs_reg), null },
10120 .register_offset => |ro| self.register_manager.lockRegAssumeUnused(ro.reg),10162 .register_pair => |lhs_regs| locks: {
10121 else => null,10163 const locks = self.register_manager.lockRegsAssumeUnused(2, lhs_regs);
10164 break :locks .{ locks[0], locks[1] };
10165 },
10166 .register_offset => |lhs_ro| .{
10167 self.register_manager.lockRegAssumeUnused(lhs_ro.reg),
10168 null,
10169 },
10170 else => .{null} ** 2,
10122 };10171 };
10123 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);10172 defer for (lhs_locks) |lhs_lock| if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
1012410173
10125 const rhs_mcv = try self.resolveInst(bin_op.rhs);10174 const rhs_mcv = try self.resolveInst(bin_op.rhs);
10126 const rhs_lock = switch (rhs_mcv) {10175 const rhs_locks: [2]?RegisterLock = switch (rhs_mcv) {
10127 .register => |reg| self.register_manager.lockReg(reg),10176 .register => |rhs_reg| .{ self.register_manager.lockReg(rhs_reg), null },
10128 .register_offset => |ro| self.register_manager.lockReg(ro.reg),10177 .register_pair => |rhs_regs| self.register_manager.lockRegs(2, rhs_regs),
10129 else => null,10178 .register_offset => |rhs_ro| .{ self.register_manager.lockReg(rhs_ro.reg), null },
10179 else => .{null} ** 2,
10130 };10180 };
10131 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);10181 defer for (rhs_locks) |rhs_lock| if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
1013210182
10133 switch (ty.zigTypeTag(mod)) {10183 switch (ty.zigTypeTag(mod)) {
10134 else => {10184 else => {
...@@ -10159,7 +10209,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -10159,7 +10209,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
10159 if (dst_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;10209 if (dst_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
10160 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);10210 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
1016110211
10162 const src_mcv = if (flipped) lhs_mcv else rhs_mcv;10212 const src_mcv = try self.resolveInst(if (flipped) bin_op.lhs else bin_op.rhs);
10163 const src_lock =10213 const src_lock =
10164 if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;10214 if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
10165 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);10215 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
...@@ -10350,13 +10400,10 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {...@@ -10350,13 +10400,10 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
10350 },10400 },
10351 );10401 );
1035210402
10353 if (limb_i > 0) try self.asmRegisterRegister(10403 if (limb_i > 0)
10354 .{ ._, .@"or" },10404 try self.asmRegisterRegister(.{ ._, .@"or" }, acc_reg, tmp_reg);
10355 acc_reg,
10356 tmp_reg,
10357 );
10358 }10405 }
10359 try self.asmRegisterRegister(.{ ._, .@"test" }, acc_reg, acc_reg);10406 assert(limbs_len >= 2); // use flags from or
10360 break :result_op flipped_op;10407 break :result_op flipped_op;
10361 },10408 },
10362 };10409 };
...@@ -11798,6 +11845,7 @@ const MoveStrategy = union(enum) {...@@ -11798,6 +11845,7 @@ const MoveStrategy = union(enum) {
11798 .move => |tag| try self.asmRegisterMemory(tag, dst_reg, src_mem),11845 .move => |tag| try self.asmRegisterMemory(tag, dst_reg, src_mem),
11799 .x87_load_store => {11846 .x87_load_store => {
11800 try self.asmMemory(.{ .f_, .ld }, src_mem);11847 try self.asmMemory(.{ .f_, .ld }, src_mem);
11848 assert(dst_reg != .st7);
11801 try self.asmRegister(.{ .f_p, .st }, @enumFromInt(@intFromEnum(dst_reg) + 1));11849 try self.asmRegister(.{ .f_p, .st }, @enumFromInt(@intFromEnum(dst_reg) + 1));
11802 },11850 },
11803 .insert_extract => |ie| try self.asmRegisterMemoryImmediate(11851 .insert_extract => |ie| try self.asmRegisterMemoryImmediate(
...@@ -11831,188 +11879,284 @@ const MoveStrategy = union(enum) {...@@ -11831,188 +11879,284 @@ const MoveStrategy = union(enum) {
11831 }11879 }
11832 }11880 }
11833};11881};
11834fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy {11882fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !MoveStrategy {
11835 const mod = self.bin_file.options.module.?;11883 const mod = self.bin_file.options.module.?;
11836 switch (ty.zigTypeTag(mod)) {11884 switch (class) {
11837 else => return .{ .move = .{ ._, .mov } },11885 .general_purpose, .segment => return .{ .move = .{ ._, .mov } },
11838 .Float => switch (ty.floatBits(self.target.*)) {11886 .x87 => return .x87_load_store,
11839 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{11887 .mmx => {},
11840 .insert = .{ .vp_w, .insr },11888 .sse => {
11841 .extract = .{ .vp_w, .extr },11889 switch (ty.zigTypeTag(mod)) {
11842 } } else .{ .insert_extract = .{11890 else => {
11843 .insert = .{ .p_w, .insr },11891 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none);
11844 .extract = .{ .p_w, .extr },11892 assert(std.mem.indexOfNone(abi.Class, classes, &.{
11845 } },11893 .integer, .sse, .float, .float_combine,
11846 32 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_ss, .mov } else .{ ._ss, .mov } },11894 }) == null);
11847 64 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_sd, .mov } else .{ ._sd, .mov } },11895 const abi_size = ty.abiSize(mod);
11848 80 => return .x87_load_store,11896 if (abi_size < 4 or
11849 128 => return .{ .move = if (self.hasFeature(.avx))11897 std.mem.indexOfScalar(abi.Class, classes, .integer) != null) switch (abi_size) {
11850 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }11898 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{
11851 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },11899 .insert = .{ .vp_b, .insr },
11852 else => {},11900 .extract = .{ .vp_b, .extr },
11853 },11901 } } else if (self.hasFeature(.sse4_2)) return .{ .insert_extract = .{
11854 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {11902 .insert = .{ .p_b, .insr },
11855 .Bool => return .{ .move = .{ ._, .mov } },11903 .extract = .{ .p_b, .extr },
11856 .Int => switch (ty.childType(mod).intInfo(mod).bits) {11904 } },
11857 8 => switch (ty.vectorLen(mod)) {11905 2 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
11858 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{11906 .insert = .{ .vp_w, .insr },
11859 .insert = .{ .vp_b, .insr },11907 .extract = .{ .vp_w, .extr },
11860 .extract = .{ .vp_b, .extr },11908 } } else .{ .insert_extract = .{
11861 } } else if (self.hasFeature(.sse4_2)) return .{ .insert_extract = .{11909 .insert = .{ .p_w, .insr },
11862 .insert = .{ .p_b, .insr },11910 .extract = .{ .p_w, .extr },
11863 .extract = .{ .p_b, .extr },11911 } },
11864 } },11912 3...4 => return .{ .move = if (self.hasFeature(.avx))
11865 2 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{11913 .{ .v_d, .mov }
11866 .insert = .{ .vp_w, .insr },11914 else
11867 .extract = .{ .vp_w, .extr },11915 .{ ._d, .mov } },
11868 } } else .{ .insert_extract = .{11916 5...8 => return .{ .move = if (self.hasFeature(.avx))
11869 .insert = .{ .p_w, .insr },11917 .{ .v_q, .mov }
11870 .extract = .{ .p_w, .extr },11918 else
11871 } },11919 .{ ._q, .mov } },
11872 3...4 => return .{ .move = if (self.hasFeature(.avx))11920 9...16 => return .{ .move = if (self.hasFeature(.avx))
11873 .{ .v_d, .mov }11921 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
11874 else11922 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
11875 .{ ._d, .mov } },11923 17...32 => if (self.hasFeature(.avx))
11876 5...8 => return .{ .move = if (self.hasFeature(.avx))11924 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
11877 .{ .v_q, .mov }11925 else => {},
11878 else11926 } else switch (abi_size) {
11879 .{ ._q, .mov } },11927 4 => return .{ .move = if (self.hasFeature(.avx))
11880 9...16 => return .{ .move = if (self.hasFeature(.avx))11928 .{ .v_ss, .mov }
11881 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }11929 else
11882 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },11930 .{ ._ss, .mov } },
11883 17...32 => if (self.hasFeature(.avx))11931 5...8 => return .{ .move = if (self.hasFeature(.avx))
11884 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },11932 .{ .v_sd, .mov }
11885 else => {},11933 else
11886 },11934 .{ ._sd, .mov } },
11887 16 => switch (ty.vectorLen(mod)) {11935 9...16 => return .{ .move = if (self.hasFeature(.avx))
11888 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{11936 if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu }
11889 .insert = .{ .vp_w, .insr },11937 else if (aligned) .{ ._pd, .mova } else .{ ._pd, .movu } },
11890 .extract = .{ .vp_w, .extr },11938 17...32 => if (self.hasFeature(.avx)) return .{ .move = if (aligned)
11891 } } else .{ .insert_extract = .{11939 .{ .v_pd, .mova }
11892 .insert = .{ .p_w, .insr },11940 else
11893 .extract = .{ .p_w, .extr },11941 .{ .v_pd, .movu } },
11894 } },11942 else => {},
11895 2 => return .{ .move = if (self.hasFeature(.avx))11943 }
11896 .{ .v_d, .mov }
11897 else
11898 .{ ._d, .mov } },
11899 3...4 => return .{ .move = if (self.hasFeature(.avx))
11900 .{ .v_q, .mov }
11901 else
11902 .{ ._q, .mov } },
11903 5...8 => return .{ .move = if (self.hasFeature(.avx))
11904 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
11905 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
11906 9...16 => if (self.hasFeature(.avx))
11907 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
11908 else => {},
11909 },
11910 32 => switch (ty.vectorLen(mod)) {
11911 1 => return .{ .move = if (self.hasFeature(.avx))
11912 .{ .v_d, .mov }
11913 else
11914 .{ ._d, .mov } },
11915 2 => return .{ .move = if (self.hasFeature(.avx))
11916 .{ .v_q, .mov }
11917 else
11918 .{ ._q, .mov } },
11919 3...4 => return .{ .move = if (self.hasFeature(.avx))
11920 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
11921 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
11922 5...8 => if (self.hasFeature(.avx))
11923 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
11924 else => {},
11925 },
11926 64 => switch (ty.vectorLen(mod)) {
11927 1 => return .{ .move = if (self.hasFeature(.avx))
11928 .{ .v_q, .mov }
11929 else
11930 .{ ._q, .mov } },
11931 2 => return .{ .move = if (self.hasFeature(.avx))
11932 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
11933 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
11934 3...4 => if (self.hasFeature(.avx))
11935 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
11936 else => {},
11937 },
11938 128 => switch (ty.vectorLen(mod)) {
11939 1 => return .{ .move = if (self.hasFeature(.avx))
11940 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
11941 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
11942 2 => if (self.hasFeature(.avx))
11943 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
11944 else => {},
11945 },
11946 256 => switch (ty.vectorLen(mod)) {
11947 1 => if (self.hasFeature(.avx))
11948 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
11949 else => {},
11950 },11944 },
11951 else => {},11945 .Float => switch (ty.floatBits(self.target.*)) {
11952 },11946 16 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
11953 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
11954 16 => switch (ty.vectorLen(mod)) {
11955 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
11956 .insert = .{ .vp_w, .insr },11947 .insert = .{ .vp_w, .insr },
11957 .extract = .{ .vp_w, .extr },11948 .extract = .{ .vp_w, .extr },
11958 } } else .{ .insert_extract = .{11949 } } else .{ .insert_extract = .{
11959 .insert = .{ .p_w, .insr },11950 .insert = .{ .p_w, .insr },
11960 .extract = .{ .p_w, .extr },11951 .extract = .{ .p_w, .extr },
11961 } },11952 } },
11962 2 => return .{ .move = if (self.hasFeature(.avx))11953 32 => return .{ .move = if (self.hasFeature(.avx))
11963 .{ .v_d, .mov }
11964 else
11965 .{ ._d, .mov } },
11966 3...4 => return .{ .move = if (self.hasFeature(.avx))
11967 .{ .v_q, .mov }
11968 else
11969 .{ ._q, .mov } },
11970 5...8 => return .{ .move = if (self.hasFeature(.avx))
11971 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
11972 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
11973 9...16 => if (self.hasFeature(.avx))
11974 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
11975 else => {},
11976 },
11977 32 => switch (ty.vectorLen(mod)) {
11978 1 => return .{ .move = if (self.hasFeature(.avx))
11979 .{ .v_ss, .mov }11954 .{ .v_ss, .mov }
11980 else11955 else
11981 .{ ._ss, .mov } },11956 .{ ._ss, .mov } },
11982 2 => return .{ .move = if (self.hasFeature(.avx))11957 64 => return .{ .move = if (self.hasFeature(.avx))
11983 .{ .v_sd, .mov }11958 .{ .v_sd, .mov }
11984 else11959 else
11985 .{ ._sd, .mov } },11960 .{ ._sd, .mov } },
11986 3...4 => return .{ .move = if (self.hasFeature(.avx))11961 128 => return .{ .move = if (self.hasFeature(.avx))
11987 if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }
11988 else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } },
11989 5...8 => if (self.hasFeature(.avx))
11990 return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } },
11991 else => {},
11992 },
11993 64 => switch (ty.vectorLen(mod)) {
11994 1 => return .{ .move = if (self.hasFeature(.avx))
11995 .{ .v_sd, .mov }
11996 else
11997 .{ ._sd, .mov } },
11998 2 => return .{ .move = if (self.hasFeature(.avx))
11999 if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu }
12000 else if (aligned) .{ ._pd, .mova } else .{ ._pd, .movu } },
12001 3...4 => if (self.hasFeature(.avx))
12002 return .{ .move = if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu } },
12003 else => {},
12004 },
12005 128 => switch (ty.vectorLen(mod)) {
12006 1 => return .{ .move = if (self.hasFeature(.avx))
12007 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }11962 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
12008 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },11963 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
12009 2 => if (self.hasFeature(.avx))
12010 return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } },
12011 else => {},11964 else => {},
12012 },11965 },
12013 else => {},11966 .Vector => switch (ty.childType(mod).zigTypeTag(mod)) {
12014 },11967 .Bool => return .{ .move = .{ ._, .mov } },
12015 else => {},11968 .Int => switch (ty.childType(mod).intInfo(mod).bits) {
11969 8 => switch (ty.vectorLen(mod)) {
11970 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{
11971 .insert = .{ .vp_b, .insr },
11972 .extract = .{ .vp_b, .extr },
11973 } } else if (self.hasFeature(.sse4_2)) return .{ .insert_extract = .{
11974 .insert = .{ .p_b, .insr },
11975 .extract = .{ .p_b, .extr },
11976 } },
11977 2 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
11978 .insert = .{ .vp_w, .insr },
11979 .extract = .{ .vp_w, .extr },
11980 } } else .{ .insert_extract = .{
11981 .insert = .{ .p_w, .insr },
11982 .extract = .{ .p_w, .extr },
11983 } },
11984 3...4 => return .{ .move = if (self.hasFeature(.avx))
11985 .{ .v_d, .mov }
11986 else
11987 .{ ._d, .mov } },
11988 5...8 => return .{ .move = if (self.hasFeature(.avx))
11989 .{ .v_q, .mov }
11990 else
11991 .{ ._q, .mov } },
11992 9...16 => return .{ .move = if (self.hasFeature(.avx))
11993 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
11994 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
11995 17...32 => if (self.hasFeature(.avx))
11996 return .{ .move = if (aligned)
11997 .{ .v_, .movdqa }
11998 else
11999 .{ .v_, .movdqu } },
12000 else => {},
12001 },
12002 16 => switch (ty.vectorLen(mod)) {
12003 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
12004 .insert = .{ .vp_w, .insr },
12005 .extract = .{ .vp_w, .extr },
12006 } } else .{ .insert_extract = .{
12007 .insert = .{ .p_w, .insr },
12008 .extract = .{ .p_w, .extr },
12009 } },
12010 2 => return .{ .move = if (self.hasFeature(.avx))
12011 .{ .v_d, .mov }
12012 else
12013 .{ ._d, .mov } },
12014 3...4 => return .{ .move = if (self.hasFeature(.avx))
12015 .{ .v_q, .mov }
12016 else
12017 .{ ._q, .mov } },
12018 5...8 => return .{ .move = if (self.hasFeature(.avx))
12019 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
12020 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
12021 9...16 => if (self.hasFeature(.avx))
12022 return .{ .move = if (aligned)
12023 .{ .v_, .movdqa }
12024 else
12025 .{ .v_, .movdqu } },
12026 else => {},
12027 },
12028 32 => switch (ty.vectorLen(mod)) {
12029 1 => return .{ .move = if (self.hasFeature(.avx))
12030 .{ .v_d, .mov }
12031 else
12032 .{ ._d, .mov } },
12033 2 => return .{ .move = if (self.hasFeature(.avx))
12034 .{ .v_q, .mov }
12035 else
12036 .{ ._q, .mov } },
12037 3...4 => return .{ .move = if (self.hasFeature(.avx))
12038 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
12039 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
12040 5...8 => if (self.hasFeature(.avx))
12041 return .{ .move = if (aligned)
12042 .{ .v_, .movdqa }
12043 else
12044 .{ .v_, .movdqu } },
12045 else => {},
12046 },
12047 64 => switch (ty.vectorLen(mod)) {
12048 1 => return .{ .move = if (self.hasFeature(.avx))
12049 .{ .v_q, .mov }
12050 else
12051 .{ ._q, .mov } },
12052 2 => return .{ .move = if (self.hasFeature(.avx))
12053 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
12054 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
12055 3...4 => if (self.hasFeature(.avx))
12056 return .{ .move = if (aligned)
12057 .{ .v_, .movdqa }
12058 else
12059 .{ .v_, .movdqu } },
12060 else => {},
12061 },
12062 128 => switch (ty.vectorLen(mod)) {
12063 1 => return .{ .move = if (self.hasFeature(.avx))
12064 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
12065 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
12066 2 => if (self.hasFeature(.avx))
12067 return .{ .move = if (aligned)
12068 .{ .v_, .movdqa }
12069 else
12070 .{ .v_, .movdqu } },
12071 else => {},
12072 },
12073 256 => switch (ty.vectorLen(mod)) {
12074 1 => if (self.hasFeature(.avx))
12075 return .{ .move = if (aligned)
12076 .{ .v_, .movdqa }
12077 else
12078 .{ .v_, .movdqu } },
12079 else => {},
12080 },
12081 else => {},
12082 },
12083 .Float => switch (ty.childType(mod).floatBits(self.target.*)) {
12084 16 => switch (ty.vectorLen(mod)) {
12085 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{
12086 .insert = .{ .vp_w, .insr },
12087 .extract = .{ .vp_w, .extr },
12088 } } else .{ .insert_extract = .{
12089 .insert = .{ .p_w, .insr },
12090 .extract = .{ .p_w, .extr },
12091 } },
12092 2 => return .{ .move = if (self.hasFeature(.avx))
12093 .{ .v_d, .mov }
12094 else
12095 .{ ._d, .mov } },
12096 3...4 => return .{ .move = if (self.hasFeature(.avx))
12097 .{ .v_q, .mov }
12098 else
12099 .{ ._q, .mov } },
12100 5...8 => return .{ .move = if (self.hasFeature(.avx))
12101 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
12102 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
12103 9...16 => if (self.hasFeature(.avx))
12104 return .{ .move = if (aligned)
12105 .{ .v_, .movdqa }
12106 else
12107 .{ .v_, .movdqu } },
12108 else => {},
12109 },
12110 32 => switch (ty.vectorLen(mod)) {
12111 1 => return .{ .move = if (self.hasFeature(.avx))
12112 .{ .v_ss, .mov }
12113 else
12114 .{ ._ss, .mov } },
12115 2 => return .{ .move = if (self.hasFeature(.avx))
12116 .{ .v_sd, .mov }
12117 else
12118 .{ ._sd, .mov } },
12119 3...4 => return .{ .move = if (self.hasFeature(.avx))
12120 if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu }
12121 else if (aligned) .{ ._ps, .mova } else .{ ._ps, .movu } },
12122 5...8 => if (self.hasFeature(.avx))
12123 return .{ .move = if (aligned)
12124 .{ .v_ps, .mova }
12125 else
12126 .{ .v_ps, .movu } },
12127 else => {},
12128 },
12129 64 => switch (ty.vectorLen(mod)) {
12130 1 => return .{ .move = if (self.hasFeature(.avx))
12131 .{ .v_sd, .mov }
12132 else
12133 .{ ._sd, .mov } },
12134 2 => return .{ .move = if (self.hasFeature(.avx))
12135 if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu }
12136 else if (aligned) .{ ._pd, .mova } else .{ ._pd, .movu } },
12137 3...4 => if (self.hasFeature(.avx))
12138 return .{ .move = if (aligned)
12139 .{ .v_pd, .mova }
12140 else
12141 .{ .v_pd, .movu } },
12142 else => {},
12143 },
12144 128 => switch (ty.vectorLen(mod)) {
12145 1 => return .{ .move = if (self.hasFeature(.avx))
12146 if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu }
12147 else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } },
12148 2 => if (self.hasFeature(.avx))
12149 return .{ .move = if (aligned)
12150 .{ .v_, .movdqa }
12151 else
12152 .{ .v_, .movdqu } },
12153 else => {},
12154 },
12155 else => {},
12156 },
12157 else => {},
12158 },
12159 }
12016 },12160 },
12017 }12161 }
12018 return self.fail("TODO moveStrategy for {}", .{ty.fmt(mod)});12162 return self.fail("TODO moveStrategy for {}", .{ty.fmt(mod)});
...@@ -12060,28 +12204,49 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError...@@ -12060,28 +12204,49 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
12060 } },12204 } },
12061 }),12205 }),
12062 .register_pair => |dst_regs| {12206 .register_pair => |dst_regs| {
12063 switch (src_mcv) {12207 const src_info: ?struct { addr_reg: Register, addr_lock: RegisterLock } = switch (src_mcv) {
12208 .register_pair, .memory, .indirect, .load_frame => null,
12209 .load_direct, .load_got, .load_extern_got, .load_tlv => src: {
12210 const src_addr_reg =
12211 (try self.register_manager.allocReg(null, abi.RegisterClass.gp)).to64();
12212 const src_addr_lock = self.register_manager.lockRegAssumeUnused(src_addr_reg);
12213 errdefer self.register_manager.unlockReg(src_addr_lock);
12214
12215 try self.genSetReg(src_addr_reg, Type.usize, src_mcv.address());
12216 break :src .{ .addr_reg = src_addr_reg, .addr_lock = src_addr_lock };
12217 },
12064 .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref)),12218 .air_ref => |src_ref| return self.genCopy(ty, dst_mcv, try self.resolveInst(src_ref)),
12065 else => {},12219 else => return self.fail("TODO implement genCopy for {s} of {}", .{
12066 }12220 @tagName(src_mcv), ty.fmt(mod),
12221 }),
12222 };
12223 defer if (src_info) |info| self.register_manager.unlockReg(info.addr_lock);
12224
12067 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none);12225 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none);
12068 for (dst_regs, classes, 0..) |dst_reg, class, dst_reg_i| {12226 for (dst_regs, classes, 0..) |dst_reg, class, dst_reg_i| {
12069 const class_ty = switch (class) {12227 const class_ty = switch (class) {
12070 .integer => Type.usize,12228 .integer => Type.usize,
12071 .sse => Type.f64,12229 .sse, .float, .float_combine => Type.f64,
12072 else => unreachable,12230 else => unreachable,
12073 };12231 };
12232 const off: i32 = @intCast(dst_reg_i * 8);
12074 switch (src_mcv) {12233 switch (src_mcv) {
12075 .register_pair => |src_regs| try self.genSetReg(12234 .register_pair => |src_regs| try self.genSetReg(
12076 dst_reg,12235 dst_reg,
12077 class_ty,12236 class_ty,
12078 .{ .register = src_regs[dst_reg_i] },12237 .{ .register = src_regs[dst_reg_i] },
12079 ),12238 ),
12080 else => try self.genSetReg(12239 .memory, .indirect, .load_frame => try self.genSetReg(
12240 dst_reg,
12241 class_ty,
12242 src_mcv.address().offset(off).deref(),
12243 ),
12244 .load_direct, .load_got, .load_extern_got, .load_tlv => try self.genSetReg(
12081 dst_reg,12245 dst_reg,
12082 class_ty,12246 class_ty,
12083 src_mcv.address().offset(@intCast(dst_reg_i * 8)).deref(),12247 .{ .indirect = .{ .reg = src_info.?.addr_reg, .off = off } },
12084 ),12248 ),
12249 else => unreachable,
12085 }12250 }
12086 }12251 }
12087 },12252 },
...@@ -12157,6 +12322,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12157,6 +12322,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12157 registerAlias(dst_reg, abi_size),12322 registerAlias(dst_reg, abi_size),
12158 src_reg,12323 src_reg,
12159 ),12324 ),
12325 .x87, .mmx => unreachable,
12160 .sse => try self.asmRegisterRegister(12326 .sse => try self.asmRegisterRegister(
12161 switch (abi_size) {12327 switch (abi_size) {
12162 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },12328 1...4 => if (self.hasFeature(.avx)) .{ .v_d, .mov } else .{ ._d, .mov },
...@@ -12166,17 +12332,30 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12166,17 +12332,30 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12166 registerAlias(dst_reg, @max(abi_size, 4)),12332 registerAlias(dst_reg, @max(abi_size, 4)),
12167 src_reg.to128(),12333 src_reg.to128(),
12168 ),12334 ),
12169 .x87, .mmx => unreachable,
12170 },12335 },
12171 .segment => try self.asmRegisterRegister(12336 .segment => try self.asmRegisterRegister(
12172 .{ ._, .mov },12337 .{ ._, .mov },
12173 dst_reg,12338 dst_reg,
12174 switch (src_reg.class()) {12339 switch (src_reg.class()) {
12175 .general_purpose, .segment => registerAlias(src_reg, abi_size),12340 .general_purpose, .segment => registerAlias(src_reg, abi_size),
12176 .sse => try self.copyToTmpRegister(ty, src_mcv),
12177 .x87, .mmx => unreachable,12341 .x87, .mmx => unreachable,
12342 .sse => try self.copyToTmpRegister(ty, src_mcv),
12178 },12343 },
12179 ),12344 ),
12345 .x87 => switch (src_reg.class()) {
12346 .general_purpose, .segment => unreachable,
12347 .x87 => switch (src_reg) {
12348 .st0 => try self.asmRegister(.{ .f_, .st }, dst_reg),
12349 .st1, .st2, .st3, .st4, .st5, .st6 => {
12350 try self.asmRegister(.{ .f_, .ld }, src_reg);
12351 assert(dst_reg != .st7);
12352 try self.asmRegister(.{ .f_p, .st }, @enumFromInt(@intFromEnum(dst_reg) + 1));
12353 },
12354 else => unreachable,
12355 },
12356 .mmx, .sse => unreachable,
12357 },
12358 .mmx => unreachable,
12180 .sse => switch (src_reg.class()) {12359 .sse => switch (src_reg.class()) {
12181 .general_purpose => try self.asmRegisterRegister(12360 .general_purpose => try self.asmRegisterRegister(
12182 switch (abi_size) {12361 switch (abi_size) {
...@@ -12192,6 +12371,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12192,6 +12371,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12192 ty,12371 ty,
12193 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },12372 .{ .register = try self.copyToTmpRegister(ty, src_mcv) },
12194 ),12373 ),
12374 .x87, .mmx => unreachable,
12195 .sse => try self.asmRegisterRegister(12375 .sse => try self.asmRegisterRegister(
12196 @as(?Mir.Inst.FixedTag, switch (ty.scalarType(mod).zigTypeTag(mod)) {12376 @as(?Mir.Inst.FixedTag, switch (ty.scalarType(mod).zigTypeTag(mod)) {
12197 else => switch (abi_size) {12377 else => switch (abi_size) {
...@@ -12217,9 +12397,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12217,9 +12397,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12217 registerAlias(dst_reg, abi_size),12397 registerAlias(dst_reg, abi_size),
12218 registerAlias(src_reg, abi_size),12398 registerAlias(src_reg, abi_size),
12219 ),12399 ),
12220 .x87, .mmx => unreachable,
12221 },12400 },
12222 .x87, .mmx => unreachable,
12223 },12401 },
12224 .register_pair => |src_regs| try self.genSetReg(dst_reg, ty, .{ .register = src_regs[0] }),12402 .register_pair => |src_regs| try self.genSetReg(dst_reg, ty, .{ .register = src_regs[0] }),
12225 .register_offset,12403 .register_offset,
...@@ -12231,9 +12409,10 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12231,9 +12409,10 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12231 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }),12409 0 => return self.genSetReg(dst_reg, ty, .{ .register = reg_off.reg }),
12232 else => .{ .move = .{ ._, .lea } },12410 else => .{ .move = .{ ._, .lea } },
12233 },12411 },
12234 .indirect => try self.moveStrategy(ty, false),12412 .indirect => try self.moveStrategy(ty, dst_reg.class(), false),
12235 .load_frame => |frame_addr| try self.moveStrategy(12413 .load_frame => |frame_addr| try self.moveStrategy(
12236 ty,12414 ty,
12415 dst_reg.class(),
12237 self.getFrameAddrAlignment(frame_addr).compare(.gte, ty.abiAlignment(mod)),12416 self.getFrameAddrAlignment(frame_addr).compare(.gte, ty.abiAlignment(mod)),
12238 ),12417 ),
12239 .lea_frame => .{ .move = .{ ._, .lea } },12418 .lea_frame => .{ .move = .{ ._, .lea } },
...@@ -12257,13 +12436,14 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12257,13 +12436,14 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12257 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|12436 .memory => |addr| if (math.cast(i32, @as(i64, @bitCast(addr)))) |small_addr|
12258 return (try self.moveStrategy(12437 return (try self.moveStrategy(
12259 ty,12438 ty,
12439 dst_reg.class(),
12260 ty.abiAlignment(mod).check(@as(u32, @bitCast(small_addr))),12440 ty.abiAlignment(mod).check(@as(u32, @bitCast(small_addr))),
12261 )).read(self, registerAlias(dst_reg, abi_size), Memory.sib(12441 )).read(self, registerAlias(dst_reg, abi_size), Memory.sib(
12262 self.memPtrSize(ty),12442 self.memPtrSize(ty),
12263 .{ .base = .{ .reg = .ds }, .disp = small_addr },12443 .{ .base = .{ .reg = .ds }, .disp = small_addr },
12264 )),12444 )),
12265 .load_direct => |sym_index| switch (ty.zigTypeTag(mod)) {12445 .load_direct => |sym_index| switch (dst_reg.class()) {
12266 else => {12446 .general_purpose => {
12267 const atom_index = try self.owner.getSymbolIndex(self);12447 const atom_index = try self.owner.getSymbolIndex(self);
12268 _ = try self.addInst(.{12448 _ = try self.addInst(.{
12269 .tag = .mov,12449 .tag = .mov,
...@@ -12278,7 +12458,8 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12278,7 +12458,8 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12278 });12458 });
12279 return;12459 return;
12280 },12460 },
12281 .Float, .Vector => {},12461 .segment, .mmx => unreachable,
12462 .x87, .sse => {},
12282 },12463 },
12283 .load_got, .load_extern_got, .load_tlv => {},12464 .load_got, .load_extern_got, .load_tlv => {},
12284 else => unreachable,12465 else => unreachable,
...@@ -12288,7 +12469,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr...@@ -12288,7 +12469,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
12288 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);12469 const addr_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
12289 defer self.register_manager.unlockReg(addr_lock);12470 defer self.register_manager.unlockReg(addr_lock);
1229012471
12291 try (try self.moveStrategy(ty, false)).read(12472 try (try self.moveStrategy(ty, dst_reg.class(), false)).read(
12292 self,12473 self,
12293 registerAlias(dst_reg, abi_size),12474 registerAlias(dst_reg, abi_size),
12294 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),12475 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = .{ .reg = addr_reg } }),
...@@ -12393,7 +12574,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -12393,7 +12574,7 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
12393 },12574 },
12394 },12575 },
12395 .eflags => |cc| try self.asmSetccMemory(cc, Memory.sib(.byte, .{ .base = base, .disp = disp })),12576 .eflags => |cc| try self.asmSetccMemory(cc, Memory.sib(.byte, .{ .base = base, .disp = disp })),
12396 .register => |src_reg| try (try self.moveStrategy(ty, switch (base) {12577 .register => |src_reg| try (try self.moveStrategy(ty, src_reg.class(), switch (base) {
12397 .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),12578 .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),
12398 .reg => |reg| switch (reg) {12579 .reg => |reg| switch (reg) {
12399 .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),12580 .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),
...@@ -12408,17 +12589,21 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -12408,17 +12589,21 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
12408 registerAlias(src_reg, abi_size),12589 registerAlias(src_reg, abi_size),
12409 ),12590 ),
12410 .register_pair => |src_regs| for (src_regs, 0..) |src_reg, src_reg_i| {12591 .register_pair => |src_regs| for (src_regs, 0..) |src_reg, src_reg_i| {
12411 const part_size = @min(abi_size - src_reg_i * 8, 8);12592 const part_size: u16 = @min(abi_size - src_reg_i * 8, 8);
12412 try (try self.moveStrategy(ty, switch (base) {12593 try (try self.moveStrategy(
12413 .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),12594 try mod.intType(.unsigned, part_size * 8),
12414 .reg => |reg| switch (reg) {12595 src_reg.class(),
12415 .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),12596 switch (base) {
12416 else => false,12597 .none => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),
12598 .reg => |reg| switch (reg) {
12599 .es, .cs, .ss, .ds => ty.abiAlignment(mod).check(@as(u32, @bitCast(disp))),
12600 else => false,
12601 },
12602 .frame => |frame_index| self.getFrameAddrAlignment(
12603 .{ .index = frame_index, .off = disp },
12604 ).compare(.gte, ty.abiAlignment(mod)),
12417 },12605 },
12418 .frame => |frame_index| self.getFrameAddrAlignment(12606 )).write(self, Memory.sib(
12419 .{ .index = frame_index, .off = disp },
12420 ).compare(.gte, ty.abiAlignment(mod)),
12421 })).write(self, Memory.sib(
12422 Memory.PtrSize.fromSize(part_size),12607 Memory.PtrSize.fromSize(part_size),
12423 .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) },12608 .{ .base = base, .disp = disp + @as(i32, @intCast(src_reg_i * 8)) },
12424 ), registerAlias(src_reg, part_size));12609 ), registerAlias(src_reg, part_size));
...@@ -12482,9 +12667,9 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal...@@ -12482,9 +12667,9 @@ fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCVal
12482}12667}
1248312668
12484fn genInlineMemcpy(self: *Self, dst_ptr: MCValue, src_ptr: MCValue, len: MCValue) InnerError!void {12669fn genInlineMemcpy(self: *Self, dst_ptr: MCValue, src_ptr: MCValue, len: MCValue) InnerError!void {
12485 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });12670 try self.spillRegisters(&.{ .rsi, .rdi, .rcx });
12486 try self.genSetReg(.rdi, Type.usize, dst_ptr);
12487 try self.genSetReg(.rsi, Type.usize, src_ptr);12671 try self.genSetReg(.rsi, Type.usize, src_ptr);
12672 try self.genSetReg(.rdi, Type.usize, dst_ptr);
12488 try self.genSetReg(.rcx, Type.usize, len);12673 try self.genSetReg(.rcx, Type.usize, len);
12489 try self.asmOpOnly(.{ .@"rep _sb", .mov });12674 try self.asmOpOnly(.{ .@"rep _sb", .mov });
12490}12675}
...@@ -14730,16 +14915,22 @@ fn resolveCallingConventionValues(...@@ -14730,16 +14915,22 @@ fn resolveCallingConventionValues(
14730 arg_mcv_i += 1;14915 arg_mcv_i += 1;
14731 },14916 },
14732 .sseup => assert(arg_mcv[arg_mcv_i - 1].register.class() == .sse),14917 .sseup => assert(arg_mcv[arg_mcv_i - 1].register.class() == .sse),
14733 .x87, .x87up, .complex_x87, .memory => break,14918 .x87, .x87up, .complex_x87, .memory, .win_i128 => switch (resolved_cc) {
14734 .none => unreachable,14919 .SysV => switch (class) {
14735 .win_i128 => {14920 .x87, .x87up, .complex_x87, .memory => break,
14736 const param_int_reg =14921 else => unreachable,
14737 abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64();14922 },
14738 param_int_reg_i += 1;14923 .Win64 => if (ty.abiSize(mod) > 8) {
1473914924 const param_int_reg =
14740 arg_mcv[arg_mcv_i] = .{ .indirect = .{ .reg = param_int_reg } };14925 abi.getCAbiIntParamRegs(resolved_cc)[param_int_reg_i].to64();
14741 arg_mcv_i += 1;14926 param_int_reg_i += 1;
14927
14928 arg_mcv[arg_mcv_i] = .{ .indirect = .{ .reg = param_int_reg } };
14929 arg_mcv_i += 1;
14930 } else break,
14931 else => unreachable,
14742 },14932 },
14933 .none => unreachable,
14743 } else {14934 } else {
14744 arg.* = switch (arg_mcv_i) {14935 arg.* = switch (arg_mcv_i) {
14745 else => unreachable,14936 else => unreachable,
...@@ -15017,34 +15208,32 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 {...@@ -15017,34 +15208,32 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 {
15017 };15208 };
15018}15209}
1501915210
15020fn promoteVarArg(self: *Self, ty: Type) Type {15211fn promoteInt(self: *Self, ty: Type) Type {
15021 const mod = self.bin_file.options.module.?;15212 const mod = self.bin_file.options.module.?;
15022 switch (ty.zigTypeTag(mod)) {15213 const int_info: InternPool.Key.IntType = switch (ty.toIntern()) {
15023 .Bool => return Type.c_int,15214 .bool_type => .{ .signedness = .unsigned, .bits = 1 },
15024 else => {15215 else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty,
15025 const int_info = ty.intInfo(mod);15216 };
15026 for ([_]Type{15217 for ([_]Type{
15027 Type.c_int, Type.c_uint,15218 Type.c_int, Type.c_uint,
15028 Type.c_long, Type.c_ulong,15219 Type.c_long, Type.c_ulong,
15029 Type.c_longlong, Type.c_ulonglong,15220 Type.c_longlong, Type.c_ulonglong,
15030 }) |promote_ty| {15221 }) |promote_ty| {
15031 const promote_info = promote_ty.intInfo(mod);15222 const promote_info = promote_ty.intInfo(mod);
15032 if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue;15223 if (int_info.signedness == .signed and promote_info.signedness == .unsigned) continue;
15033 if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and15224 if (int_info.bits + @intFromBool(int_info.signedness == .unsigned and
15034 promote_info.signedness == .signed) <= promote_info.bits) return promote_ty;15225 promote_info.signedness == .signed) <= promote_info.bits) return promote_ty;
15035 }15226 }
15036 unreachable;15227 return ty;
15037 },15228}
15038 .Float => switch (ty.floatBits(self.target.*)) {15229
15039 32, 64 => return Type.f64,15230fn promoteVarArg(self: *Self, ty: Type) Type {
15040 else => |float_bits| {15231 if (!ty.isRuntimeFloat()) return self.promoteInt(ty);
15041 assert(float_bits == self.target.c_type_bit_size(.longdouble));15232 switch (ty.floatBits(self.target.*)) {
15042 return Type.c_longdouble;15233 32, 64 => return Type.f64,
15043 },15234 else => |float_bits| {
15044 },15235 assert(float_bits == self.target.c_type_bit_size(.longdouble));
15045 .Pointer => {15236 return Type.c_longdouble;
15046 assert(!ty.isSlice(mod));
15047 return ty;
15048 },15237 },
15049 }15238 }
15050}15239}
test/c_abi/cfuncs.c+3-7
...@@ -73,10 +73,6 @@ static void assert_or_panic(bool ok) {...@@ -73,10 +73,6 @@ static void assert_or_panic(bool ok) {
73#define ZIG_NO_RAW_F1673#define ZIG_NO_RAW_F16
74#endif74#endif
7575
76#ifdef ZIG_BACKEND_STAGE2_X86_64
77#define ZIG_NO_COMPLEX
78#endif
79
80#ifdef __i386__76#ifdef __i386__
81#define ZIG_NO_RAW_F1677#define ZIG_NO_RAW_F16
82#endif78#endif
...@@ -278,7 +274,7 @@ void run_c_tests(void) {...@@ -278,7 +274,7 @@ void run_c_tests(void) {
278 zig_u32(0xfffffffd);274 zig_u32(0xfffffffd);
279 zig_u64(0xfffffffffffffffc);275 zig_u64(0xfffffffffffffffc);
280276
281#if !defined ZIG_NO_I128 && !defined ZIG_BACKEND_STAGE2_X86_64277#ifndef ZIG_NO_I128
282 {278 {
283 struct u128 s = {0xfffffffffffffffc};279 struct u128 s = {0xfffffffffffffffc};
284 zig_struct_u128(s);280 zig_struct_u128(s);
...@@ -292,7 +288,7 @@ void run_c_tests(void) {...@@ -292,7 +288,7 @@ void run_c_tests(void) {
292 zig_i32(-3);288 zig_i32(-3);
293 zig_i64(-4);289 zig_i64(-4);
294290
295#if !defined ZIG_NO_I128 && !defined ZIG_BACKEND_STAGE2_X86_64291#ifndef ZIG_NO_I128
296 {292 {
297 struct i128 s = {-6};293 struct i128 s = {-6};
298 zig_struct_i128(s);294 zig_struct_i128(s);
...@@ -433,7 +429,7 @@ void run_c_tests(void) {...@@ -433,7 +429,7 @@ void run_c_tests(void) {
433 }429 }
434#endif430#endif
435431
436#if !defined __mips__ && !defined ZIG_PPC32 && !defined ZIG_BACKEND_STAGE2_X86_64432#if !defined __mips__ && !defined ZIG_PPC32
437 {433 {
438 struct FloatRect r1 = {1, 21, 16, 4};434 struct FloatRect r1 = {1, 21, 16, 4};
439 struct FloatRect r2 = {178, 189, 21, 15};435 struct FloatRect r2 = {178, 189, 21, 15};
test/c_abi/main.zig+5-86
...@@ -49,8 +49,6 @@ export fn zig_five_integers(a: i32, b: i32, c: i32, d: i32, e: i32) void {...@@ -49,8 +49,6 @@ export fn zig_five_integers(a: i32, b: i32, c: i32, d: i32, e: i32) void {
49}49}
5050
51test "C ABI integers" {51test "C ABI integers" {
52 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
53
54 c_u8(0xff);52 c_u8(0xff);
55 c_u16(0xfffe);53 c_u16(0xfffe);
56 c_u32(0xfffffffd);54 c_u32(0xfffffffd);
...@@ -187,10 +185,8 @@ const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.is...@@ -187,10 +185,8 @@ const complex_abi_compatible = builtin.cpu.arch != .x86 and !builtin.cpu.arch.is
187 !builtin.cpu.arch.isARM() and !builtin.cpu.arch.isPPC() and !builtin.cpu.arch.isRISCV();185 !builtin.cpu.arch.isARM() and !builtin.cpu.arch.isPPC() and !builtin.cpu.arch.isRISCV();
188186
189test "C ABI complex float" {187test "C ABI complex float" {
190 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
191
192 if (!complex_abi_compatible) return error.SkipZigTest;188 if (!complex_abi_compatible) return error.SkipZigTest;
193 if (builtin.cpu.arch == .x86_64) return error.SkipZigTest; // See https://github.com/ziglang/zig/issues/8465189 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64) return error.SkipZigTest; // See https://github.com/ziglang/zig/issues/8465
194190
195 const a = ComplexFloat{ .real = 1.25, .imag = 2.6 };191 const a = ComplexFloat{ .real = 1.25, .imag = 2.6 };
196 const b = ComplexFloat{ .real = 11.3, .imag = -1.5 };192 const b = ComplexFloat{ .real = 11.3, .imag = -1.5 };
...@@ -201,8 +197,6 @@ test "C ABI complex float" {...@@ -201,8 +197,6 @@ test "C ABI complex float" {
201}197}
202198
203test "C ABI complex float by component" {199test "C ABI complex float by component" {
204 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
205
206 if (!complex_abi_compatible) return error.SkipZigTest;200 if (!complex_abi_compatible) return error.SkipZigTest;
207201
208 const a = ComplexFloat{ .real = 1.25, .imag = 2.6 };202 const a = ComplexFloat{ .real = 1.25, .imag = 2.6 };
...@@ -214,8 +208,6 @@ test "C ABI complex float by component" {...@@ -214,8 +208,6 @@ test "C ABI complex float by component" {
214}208}
215209
216test "C ABI complex double" {210test "C ABI complex double" {
217 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
218
219 if (!complex_abi_compatible) return error.SkipZigTest;211 if (!complex_abi_compatible) return error.SkipZigTest;
220212
221 const a = ComplexDouble{ .real = 1.25, .imag = 2.6 };213 const a = ComplexDouble{ .real = 1.25, .imag = 2.6 };
...@@ -227,8 +219,6 @@ test "C ABI complex double" {...@@ -227,8 +219,6 @@ test "C ABI complex double" {
227}219}
228220
229test "C ABI complex double by component" {221test "C ABI complex double by component" {
230 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
231
232 if (!complex_abi_compatible) return error.SkipZigTest;222 if (!complex_abi_compatible) return error.SkipZigTest;
233223
234 const a = ComplexDouble{ .real = 1.25, .imag = 2.6 };224 const a = ComplexDouble{ .real = 1.25, .imag = 2.6 };
...@@ -240,8 +230,6 @@ test "C ABI complex double by component" {...@@ -240,8 +230,6 @@ test "C ABI complex double by component" {
240}230}
241231
242export fn zig_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat {232export fn zig_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat {
243 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
244
245 expect(a.real == 1.25) catch @panic("test failure: zig_cmultf 1");233 expect(a.real == 1.25) catch @panic("test failure: zig_cmultf 1");
246 expect(a.imag == 2.6) catch @panic("test failure: zig_cmultf 2");234 expect(a.imag == 2.6) catch @panic("test failure: zig_cmultf 2");
247 expect(b.real == 11.3) catch @panic("test failure: zig_cmultf 3");235 expect(b.real == 11.3) catch @panic("test failure: zig_cmultf 3");
...@@ -251,8 +239,6 @@ export fn zig_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat {...@@ -251,8 +239,6 @@ export fn zig_cmultf(a: ComplexFloat, b: ComplexFloat) ComplexFloat {
251}239}
252240
253export fn zig_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble {241export fn zig_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble {
254 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
255
256 expect(a.real == 1.25) catch @panic("test failure: zig_cmultd 1");242 expect(a.real == 1.25) catch @panic("test failure: zig_cmultd 1");
257 expect(a.imag == 2.6) catch @panic("test failure: zig_cmultd 2");243 expect(a.imag == 2.6) catch @panic("test failure: zig_cmultd 2");
258 expect(b.real == 11.3) catch @panic("test failure: zig_cmultd 3");244 expect(b.real == 11.3) catch @panic("test failure: zig_cmultd 3");
...@@ -262,8 +248,6 @@ export fn zig_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble {...@@ -262,8 +248,6 @@ export fn zig_cmultd(a: ComplexDouble, b: ComplexDouble) ComplexDouble {
262}248}
263249
264export fn zig_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat {250export fn zig_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat {
265 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
266
267 expect(a_r == 1.25) catch @panic("test failure: zig_cmultf_comp 1");251 expect(a_r == 1.25) catch @panic("test failure: zig_cmultf_comp 1");
268 expect(a_i == 2.6) catch @panic("test failure: zig_cmultf_comp 2");252 expect(a_i == 2.6) catch @panic("test failure: zig_cmultf_comp 2");
269 expect(b_r == 11.3) catch @panic("test failure: zig_cmultf_comp 3");253 expect(b_r == 11.3) catch @panic("test failure: zig_cmultf_comp 3");
...@@ -273,8 +257,6 @@ export fn zig_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat {...@@ -273,8 +257,6 @@ export fn zig_cmultf_comp(a_r: f32, a_i: f32, b_r: f32, b_i: f32) ComplexFloat {
273}257}
274258
275export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble {259export fn zig_cmultd_comp(a_r: f64, a_i: f64, b_r: f64, b_i: f64) ComplexDouble {
276 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
277
278 expect(a_r == 1.25) catch @panic("test failure: zig_cmultd_comp 1");260 expect(a_r == 1.25) catch @panic("test failure: zig_cmultd_comp 1");
279 expect(a_i == 2.6) catch @panic("test failure: zig_cmultd_comp 2");261 expect(a_i == 2.6) catch @panic("test failure: zig_cmultd_comp 2");
280 expect(b_r == 11.3) catch @panic("test failure: zig_cmultd_comp 3");262 expect(b_r == 11.3) catch @panic("test failure: zig_cmultd_comp 3");
...@@ -352,8 +334,6 @@ extern fn c_med_struct_mixed(MedStructMixed) void;...@@ -352,8 +334,6 @@ extern fn c_med_struct_mixed(MedStructMixed) void;
352extern fn c_ret_med_struct_mixed() MedStructMixed;334extern fn c_ret_med_struct_mixed() MedStructMixed;
353335
354test "C ABI medium struct of ints and floats" {336test "C ABI medium struct of ints and floats" {
355 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
356
357 if (builtin.cpu.arch == .x86) return error.SkipZigTest;337 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
358 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;338 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
359 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;339 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -422,8 +402,6 @@ extern fn c_med_struct_ints(MedStructInts) void;...@@ -422,8 +402,6 @@ extern fn c_med_struct_ints(MedStructInts) void;
422extern fn c_ret_med_struct_ints() MedStructInts;402extern fn c_ret_med_struct_ints() MedStructInts;
423403
424test "C ABI medium struct of ints" {404test "C ABI medium struct of ints" {
425 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
426
427 if (builtin.cpu.arch == .x86) return error.SkipZigTest;405 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
428 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;406 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
429 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;407 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -531,8 +509,6 @@ extern fn c_split_struct_mixed(SplitStructMixed) void;...@@ -531,8 +509,6 @@ extern fn c_split_struct_mixed(SplitStructMixed) void;
531extern fn c_ret_split_struct_mixed() SplitStructMixed;509extern fn c_ret_split_struct_mixed() SplitStructMixed;
532510
533test "C ABI split struct of ints and floats" {511test "C ABI split struct of ints and floats" {
534 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
535
536 if (builtin.cpu.arch == .x86) return error.SkipZigTest;512 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
537 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;513 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
538 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;514 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -614,8 +590,6 @@ const Vector5 = extern struct {...@@ -614,8 +590,6 @@ const Vector5 = extern struct {
614extern fn c_big_struct_floats(Vector5) void;590extern fn c_big_struct_floats(Vector5) void;
615591
616test "C ABI structs of floats as parameter" {592test "C ABI structs of floats as parameter" {
617 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
618
619 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;593 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
620 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;594 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
621 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;595 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
...@@ -683,8 +657,6 @@ const FloatRect = extern struct {...@@ -683,8 +657,6 @@ const FloatRect = extern struct {
683};657};
684658
685export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void {659export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void {
686 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
687
688 expect(x.left == 1) catch @panic("test failure");660 expect(x.left == 1) catch @panic("test failure");
689 expect(x.right == 21) catch @panic("test failure");661 expect(x.right == 21) catch @panic("test failure");
690 expect(x.top == 16) catch @panic("test failure");662 expect(x.top == 16) catch @panic("test failure");
...@@ -696,8 +668,6 @@ export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void {...@@ -696,8 +668,6 @@ export fn zig_multiple_struct_floats(x: FloatRect, y: FloatRect) void {
696}668}
697669
698test "C ABI structs of floats as multiple parameters" {670test "C ABI structs of floats as multiple parameters" {
699 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
700
701 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;671 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
702 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;672 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
703673
...@@ -754,8 +724,6 @@ export fn zig_ret_small_struct_ints() SmallStructInts {...@@ -754,8 +724,6 @@ export fn zig_ret_small_struct_ints() SmallStructInts {
754}724}
755725
756export fn zig_ret_med_struct_ints() MedStructInts {726export fn zig_ret_med_struct_ints() MedStructInts {
757 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
758
759 return .{727 return .{
760 .x = 1,728 .x = 1,
761 .y = 2,729 .y = 2,
...@@ -764,8 +732,6 @@ export fn zig_ret_med_struct_ints() MedStructInts {...@@ -764,8 +732,6 @@ export fn zig_ret_med_struct_ints() MedStructInts {
764}732}
765733
766export fn zig_ret_med_struct_mixed() MedStructMixed {734export fn zig_ret_med_struct_mixed() MedStructMixed {
767 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
768
769 return .{735 return .{
770 .a = 1234,736 .a = 1234,
771 .b = 100.0,737 .b = 100.0,
...@@ -774,8 +740,6 @@ export fn zig_ret_med_struct_mixed() MedStructMixed {...@@ -774,8 +740,6 @@ export fn zig_ret_med_struct_mixed() MedStructMixed {
774}740}
775741
776export fn zig_ret_split_struct_mixed() SplitStructMixed {742export fn zig_ret_split_struct_mixed() SplitStructMixed {
777 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
778
779 return .{743 return .{
780 .a = 1234,744 .a = 1234,
781 .b = 100,745 .b = 100,
...@@ -816,8 +780,6 @@ extern fn c_struct_with_array(StructWithArray) void;...@@ -816,8 +780,6 @@ extern fn c_struct_with_array(StructWithArray) void;
816extern fn c_ret_struct_with_array() StructWithArray;780extern fn c_ret_struct_with_array() StructWithArray;
817781
818test "Struct with array as padding." {782test "Struct with array as padding." {
819 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
820
821 if (builtin.cpu.arch == .x86) return error.SkipZigTest;783 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
822 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;784 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
823 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;785 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -889,7 +851,8 @@ extern fn c_medium_vec(MediumVec) void;...@@ -889,7 +851,8 @@ extern fn c_medium_vec(MediumVec) void;
889extern fn c_ret_medium_vec() MediumVec;851extern fn c_ret_medium_vec() MediumVec;
890852
891test "medium simd vector" {853test "medium simd vector" {
892 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;854 if (builtin.zig_backend == .stage2_x86_64 and
855 !comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx)) return error.SkipZigTest;
893856
894 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;857 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
895858
...@@ -912,7 +875,7 @@ test "big simd vector" {...@@ -912,7 +875,7 @@ test "big simd vector" {
912875
913 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;876 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
914 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;877 if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest;
915 if (builtin.cpu.arch == .x86_64 and builtin.os.tag == .macos and builtin.mode != .Debug) return error.SkipZigTest;878 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .x86_64 and builtin.os.tag == .macos and builtin.mode != .Debug) return error.SkipZigTest;
916879
917 c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 });880 c_big_vec(.{ 1, 2, 3, 4, 5, 6, 7, 8 });
918881
...@@ -933,8 +896,6 @@ extern fn c_ptr_size_float_struct(Vector2) void;...@@ -933,8 +896,6 @@ extern fn c_ptr_size_float_struct(Vector2) void;
933extern fn c_ret_ptr_size_float_struct() Vector2;896extern fn c_ret_ptr_size_float_struct() Vector2;
934897
935test "C ABI pointer sized float struct" {898test "C ABI pointer sized float struct" {
936 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
937
938 if (builtin.cpu.arch == .x86) return error.SkipZigTest;899 if (builtin.cpu.arch == .x86) return error.SkipZigTest;
939 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;900 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
940 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;901 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
...@@ -958,8 +919,6 @@ pub inline fn expectOk(c_err: c_int) !void {...@@ -958,8 +919,6 @@ pub inline fn expectOk(c_err: c_int) !void {
958/// Tests for Double + Char struct919/// Tests for Double + Char struct
959const DC = extern struct { v1: f64, v2: u8 };920const DC = extern struct { v1: f64, v2: u8 };
960test "DC: Zig passes to C" {921test "DC: Zig passes to C" {
961 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
962
963 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;922 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
964 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;923 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
965 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;924 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -967,8 +926,6 @@ test "DC: Zig passes to C" {...@@ -967,8 +926,6 @@ test "DC: Zig passes to C" {
967 try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 }));926 try expectOk(c_assert_DC(.{ .v1 = -0.25, .v2 = 15 }));
968}927}
969test "DC: Zig returns to C" {928test "DC: Zig returns to C" {
970 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
971
972 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;929 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
973 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;930 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
974 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;931 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
...@@ -977,8 +934,6 @@ test "DC: Zig returns to C" {...@@ -977,8 +934,6 @@ test "DC: Zig returns to C" {
977 try expectOk(c_assert_ret_DC());934 try expectOk(c_assert_ret_DC());
978}935}
979test "DC: C passes to Zig" {936test "DC: C passes to Zig" {
980 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
981
982 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;937 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
983 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;938 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
984 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;939 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -986,8 +941,6 @@ test "DC: C passes to Zig" {...@@ -986,8 +941,6 @@ test "DC: C passes to Zig" {
986 try expectOk(c_send_DC());941 try expectOk(c_send_DC());
987}942}
988test "DC: C returns to Zig" {943test "DC: C returns to Zig" {
989 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
990
991 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;944 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
992 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;945 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
993 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;946 if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest;
...@@ -1001,8 +954,6 @@ pub extern fn c_assert_ret_DC() c_int;...@@ -1001,8 +954,6 @@ pub extern fn c_assert_ret_DC() c_int;
1001pub extern fn c_send_DC() c_int;954pub extern fn c_send_DC() c_int;
1002pub extern fn c_ret_DC() DC;955pub extern fn c_ret_DC() DC;
1003pub export fn zig_assert_DC(lv: DC) c_int {956pub export fn zig_assert_DC(lv: DC) c_int {
1004 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
1005
1006 var err: c_int = 0;957 var err: c_int = 0;
1007 if (lv.v1 != -0.25) err = 1;958 if (lv.v1 != -0.25) err = 1;
1008 if (lv.v2 != 15) err = 2;959 if (lv.v2 != 15) err = 2;
...@@ -1010,8 +961,6 @@ pub export fn zig_assert_DC(lv: DC) c_int {...@@ -1010,8 +961,6 @@ pub export fn zig_assert_DC(lv: DC) c_int {
1010 return err;961 return err;
1011}962}
1012pub export fn zig_ret_DC() DC {963pub export fn zig_ret_DC() DC {
1013 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
1014
1015 return .{ .v1 = -0.25, .v2 = 15 };964 return .{ .v1 = -0.25, .v2 = 15 };
1016}965}
1017966
...@@ -1019,8 +968,6 @@ pub export fn zig_ret_DC() DC {...@@ -1019,8 +968,6 @@ pub export fn zig_ret_DC() DC {
1019const CFF = extern struct { v1: u8, v2: f32, v3: f32 };968const CFF = extern struct { v1: u8, v2: f32, v3: f32 };
1020969
1021test "CFF: Zig passes to C" {970test "CFF: Zig passes to C" {
1022 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1023
1024 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;971 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1025 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;972 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
1026 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;973 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -1028,8 +975,6 @@ test "CFF: Zig passes to C" {...@@ -1028,8 +975,6 @@ test "CFF: Zig passes to C" {
1028 try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }));975 try expectOk(c_assert_CFF(.{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }));
1029}976}
1030test "CFF: Zig returns to C" {977test "CFF: Zig returns to C" {
1031 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1032
1033 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;978 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
1034 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;979 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
1035 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;980 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -1037,8 +982,6 @@ test "CFF: Zig returns to C" {...@@ -1037,8 +982,6 @@ test "CFF: Zig returns to C" {
1037 try expectOk(c_assert_ret_CFF());982 try expectOk(c_assert_ret_CFF());
1038}983}
1039test "CFF: C passes to Zig" {984test "CFF: C passes to Zig" {
1040 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1041
1042 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;985 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1043 if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;986 if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
1044 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;987 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
...@@ -1049,8 +992,6 @@ test "CFF: C passes to Zig" {...@@ -1049,8 +992,6 @@ test "CFF: C passes to Zig" {
1049 try expectOk(c_send_CFF());992 try expectOk(c_send_CFF());
1050}993}
1051test "CFF: C returns to Zig" {994test "CFF: C returns to Zig" {
1052 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1053
1054 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;995 if (builtin.cpu.arch == .x86 and builtin.mode != .Debug) return error.SkipZigTest;
1055 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;996 if (builtin.cpu.arch == .aarch64 and builtin.mode != .Debug) return error.SkipZigTest;
1056 if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;997 if (comptime builtin.cpu.arch.isRISCV() and builtin.mode != .Debug) return error.SkipZigTest;
...@@ -1064,8 +1005,6 @@ pub extern fn c_assert_ret_CFF() c_int;...@@ -1064,8 +1005,6 @@ pub extern fn c_assert_ret_CFF() c_int;
1064pub extern fn c_send_CFF() c_int;1005pub extern fn c_send_CFF() c_int;
1065pub extern fn c_ret_CFF() CFF;1006pub extern fn c_ret_CFF() CFF;
1066pub export fn zig_assert_CFF(lv: CFF) c_int {1007pub export fn zig_assert_CFF(lv: CFF) c_int {
1067 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
1068
1069 var err: c_int = 0;1008 var err: c_int = 0;
1070 if (lv.v1 != 39) err = 1;1009 if (lv.v1 != 39) err = 1;
1071 if (lv.v2 != 0.875) err = 2;1010 if (lv.v2 != 0.875) err = 2;
...@@ -1074,8 +1013,6 @@ pub export fn zig_assert_CFF(lv: CFF) c_int {...@@ -1074,8 +1013,6 @@ pub export fn zig_assert_CFF(lv: CFF) c_int {
1074 return err;1013 return err;
1075}1014}
1076pub export fn zig_ret_CFF() CFF {1015pub export fn zig_ret_CFF() CFF {
1077 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
1078
1079 return .{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 };1016 return .{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 };
1080}1017}
10811018
...@@ -1083,8 +1020,6 @@ pub export fn zig_ret_CFF() CFF {...@@ -1083,8 +1020,6 @@ pub export fn zig_ret_CFF() CFF {
1083const PD = extern struct { v1: ?*anyopaque, v2: f64 };1020const PD = extern struct { v1: ?*anyopaque, v2: f64 };
10841021
1085test "PD: Zig passes to C" {1022test "PD: Zig passes to C" {
1086 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1087
1088 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;1023 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1089 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;1024 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
1090 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;1025 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -1092,8 +1027,6 @@ test "PD: Zig passes to C" {...@@ -1092,8 +1027,6 @@ test "PD: Zig passes to C" {
1092 try expectOk(c_assert_PD(.{ .v1 = null, .v2 = 0.5 }));1027 try expectOk(c_assert_PD(.{ .v1 = null, .v2 = 0.5 }));
1093}1028}
1094test "PD: Zig returns to C" {1029test "PD: Zig returns to C" {
1095 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1096
1097 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;1030 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1098 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;1031 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
1099 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;1032 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -1101,8 +1034,6 @@ test "PD: Zig returns to C" {...@@ -1101,8 +1034,6 @@ test "PD: Zig returns to C" {
1101 try expectOk(c_assert_ret_PD());1034 try expectOk(c_assert_ret_PD());
1102}1035}
1103test "PD: C passes to Zig" {1036test "PD: C passes to Zig" {
1104 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1105
1106 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;1037 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1107 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;1038 if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest;
1108 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;1039 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -1110,8 +1041,6 @@ test "PD: C passes to Zig" {...@@ -1110,8 +1041,6 @@ test "PD: C passes to Zig" {
1110 try expectOk(c_send_PD());1041 try expectOk(c_send_PD());
1111}1042}
1112test "PD: C returns to Zig" {1043test "PD: C returns to Zig" {
1113 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1114
1115 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;1044 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1116 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;1045 if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest;
1117 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;1046 if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest;
...@@ -1123,8 +1052,6 @@ pub extern fn c_assert_ret_PD() c_int;...@@ -1123,8 +1052,6 @@ pub extern fn c_assert_ret_PD() c_int;
1123pub extern fn c_send_PD() c_int;1052pub extern fn c_send_PD() c_int;
1124pub extern fn c_ret_PD() PD;1053pub extern fn c_ret_PD() PD;
1125pub export fn zig_c_assert_PD(lv: PD) c_int {1054pub export fn zig_c_assert_PD(lv: PD) c_int {
1126 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
1127
1128 var err: c_int = 0;1055 var err: c_int = 0;
1129 if (lv.v1 != null) err = 1;1056 if (lv.v1 != null) err = 1;
1130 if (lv.v2 != 0.5) err = 2;1057 if (lv.v2 != 0.5) err = 2;
...@@ -1132,13 +1059,9 @@ pub export fn zig_c_assert_PD(lv: PD) c_int {...@@ -1132,13 +1059,9 @@ pub export fn zig_c_assert_PD(lv: PD) c_int {
1132 return err;1059 return err;
1133}1060}
1134pub export fn zig_ret_PD() PD {1061pub export fn zig_ret_PD() PD {
1135 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
1136
1137 return .{ .v1 = null, .v2 = 0.5 };1062 return .{ .v1 = null, .v2 = 0.5 };
1138}1063}
1139pub export fn zig_assert_PD(lv: PD) c_int {1064pub export fn zig_assert_PD(lv: PD) c_int {
1140 if (builtin.zig_backend == .stage2_x86_64) @panic("error.SkipZigTest");
1141
1142 var err: c_int = 0;1065 var err: c_int = 0;
1143 if (lv.v1 != null) err = 1;1066 if (lv.v1 != null) err = 1;
1144 if (lv.v2 != 0.5) err = 2;1067 if (lv.v2 != 0.5) err = 2;
...@@ -1228,11 +1151,9 @@ const f80_struct = extern struct {...@@ -1228,11 +1151,9 @@ const f80_struct = extern struct {
1228};1151};
1229extern fn c_f80_struct(f80_struct) f80_struct;1152extern fn c_f80_struct(f80_struct) f80_struct;
1230test "f80 struct" {1153test "f80 struct" {
1231 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1232
1233 if (!has_f80) return error.SkipZigTest;1154 if (!has_f80) return error.SkipZigTest;
1234 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;1155 if (builtin.target.cpu.arch == .x86) return error.SkipZigTest;
1235 if (builtin.mode != .Debug) return error.SkipZigTest;1156 if (builtin.zig_backend == .stage2_llvm and builtin.mode != .Debug) return error.SkipZigTest;
12361157
1237 const a = c_f80_struct(.{ .a = 12.34 });1158 const a = c_f80_struct(.{ .a = 12.34 });
1238 try expect(@as(f64, @floatCast(a.a)) == 56.78);1159 try expect(@as(f64, @floatCast(a.a)) == 56.78);
...@@ -1317,8 +1238,6 @@ test "Stdcall ABI big union" {...@@ -1317,8 +1238,6 @@ test "Stdcall ABI big union" {
13171238
1318extern fn c_explict_win64(ByRef) callconv(.Win64) ByRef;1239extern fn c_explict_win64(ByRef) callconv(.Win64) ByRef;
1319test "explicit SysV calling convention" {1240test "explicit SysV calling convention" {
1320 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1321
1322 if (builtin.cpu.arch != .x86_64) return error.SkipZigTest;1241 if (builtin.cpu.arch != .x86_64) return error.SkipZigTest;
13231242
1324 const res = c_explict_win64(.{ .val = 1, .arr = undefined });1243 const res = c_explict_win64(.{ .val = 1, .arr = undefined });