authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-01 22:10:15-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-04-02 04:49:53-04:00
log83a208c3551ae470f92753592a4c88984d2154d3
treea0f878390944963fe6810944eb4640933f488b16
parent677427bc3ac839629654175f0a2aaaec9fd6fb6c

x86_64: implement large cmp


23 files changed, 226 insertions(+), 299 deletions(-)

lib/std/os.zig+2
...@@ -1937,6 +1937,8 @@ pub fn getenv(key: []const u8) ?[]const u8 {...@@ -1937,6 +1937,8 @@ pub fn getenv(key: []const u8) ?[]const u8 {
1937 if (builtin.os.tag == .windows) {1937 if (builtin.os.tag == .windows) {
1938 @compileError("std.os.getenv is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");1938 @compileError("std.os.getenv is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");
1939 }1939 }
1940 // The simplified start logic doesn't populate environ.
1941 if (std.start.simplified_logic) return null;
1940 // TODO see https://github.com/ziglang/zig/issues/45241942 // TODO see https://github.com/ziglang/zig/issues/4524
1941 for (environ) |ptr| {1943 for (environ) |ptr| {
1942 var line_i: usize = 0;1944 var line_i: usize = 0;
lib/std/start.zig+13-11
...@@ -14,22 +14,24 @@ var argc_argv_ptr: [*]usize = undefined;...@@ -14,22 +14,24 @@ var argc_argv_ptr: [*]usize = undefined;
1414
15const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start";15const start_sym_name = if (native_arch.isMIPS()) "__start" else "_start";
1616
17// The self-hosted compiler is not fully capable of handling all of this start.zig file.
18// Until then, we have simplified logic here for self-hosted. TODO remove this once
19// self-hosted is capable enough to handle all of the real start.zig logic.
20pub const simplified_logic =
21 builtin.zig_backend == .stage2_wasm or
22 builtin.zig_backend == .stage2_x86_64 or
23 builtin.zig_backend == .stage2_x86 or
24 builtin.zig_backend == .stage2_aarch64 or
25 builtin.zig_backend == .stage2_arm or
26 builtin.zig_backend == .stage2_riscv64 or
27 builtin.zig_backend == .stage2_sparc64;
28
17comptime {29comptime {
18 // No matter what, we import the root file, so that any export, test, comptime30 // No matter what, we import the root file, so that any export, test, comptime
19 // decls there get run.31 // decls there get run.
20 _ = root;32 _ = root;
2133
22 // The self-hosted compiler is not fully capable of handling all of this start.zig file.34 if (simplified_logic) {
23 // Until then, we have simplified logic here for self-hosted. TODO remove this once
24 // self-hosted is capable enough to handle all of the real start.zig logic.
25 if (builtin.zig_backend == .stage2_wasm or
26 builtin.zig_backend == .stage2_x86_64 or
27 builtin.zig_backend == .stage2_x86 or
28 builtin.zig_backend == .stage2_aarch64 or
29 builtin.zig_backend == .stage2_arm or
30 builtin.zig_backend == .stage2_riscv64 or
31 builtin.zig_backend == .stage2_sparc64)
32 {
33 if (builtin.output_mode == .Exe) {35 if (builtin.output_mode == .Exe) {
34 if ((builtin.link_libc or builtin.object_format == .c) and @hasDecl(root, "main")) {36 if ((builtin.link_libc or builtin.object_format == .c) and @hasDecl(root, "main")) {
35 if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) {37 if (@typeInfo(@TypeOf(root.main)).Fn.calling_convention != .C) {
src/arch/x86_64/CodeGen.zig+197-252
...@@ -3986,7 +3986,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue...@@ -3986,7 +3986,7 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue
3986 .eflags => unreachable,3986 .eflags => unreachable,
3987 .register_overflow => unreachable,3987 .register_overflow => unreachable,
3988 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),3988 .register => |dst_reg| try self.asmRegister(mir_tag, registerAlias(dst_reg, abi_size)),
3989 .ptr_stack_offset, .stack_offset => |off| {3989 .stack_offset => |off| {
3990 if (abi_size > 8) {3990 if (abi_size > 8) {
3991 return self.fail("TODO implement {} for stack dst with large ABI", .{mir_tag});3991 return self.fail("TODO implement {} for stack dst with large ABI", .{mir_tag});
3992 }3992 }
...@@ -3996,20 +3996,13 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue...@@ -3996,20 +3996,13 @@ fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValue
3996 .disp = -off,3996 .disp = -off,
3997 }));3997 }));
3998 },3998 },
3999 .ptr_stack_offset => unreachable,
3999 .memory, .linker_load => {4000 .memory, .linker_load => {
4000 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();4001 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
4001 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);4002 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
4002 defer self.register_manager.unlockReg(addr_reg_lock);4003 defer self.register_manager.unlockReg(addr_reg_lock);
40034004
4004 try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_mcv);4005 try self.loadMemPtrIntoRegister(addr_reg, Type.usize, dst_mcv);
4005
4006 // To get the actual address of the value we want to modify we have to go through the GOT
4007 try self.asmRegisterMemory(
4008 .mov,
4009 addr_reg,
4010 Memory.sib(.qword, .{ .base = addr_reg }),
4011 );
4012
4013 try self.asmMemory(4006 try self.asmMemory(
4014 mir_tag,4007 mir_tag,
4015 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),4008 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),
...@@ -4454,7 +4447,7 @@ fn genBinOp(...@@ -4454,7 +4447,7 @@ fn genBinOp(
44544447
4455 else => false,4448 else => false,
4456 };4449 };
4457 const needs_reg_dst = switch (tag) {4450 const dst_mem_ok = switch (tag) {
4458 .add,4451 .add,
4459 .addwrap,4452 .addwrap,
4460 .sub,4453 .sub,
...@@ -4464,9 +4457,9 @@ fn genBinOp(...@@ -4464,9 +4457,9 @@ fn genBinOp(
4464 .div_exact,4457 .div_exact,
4465 .div_trunc,4458 .div_trunc,
4466 .div_floor,4459 .div_floor,
4467 => lhs_ty.isRuntimeFloat(),4460 => !lhs_ty.isRuntimeFloat(),
44684461
4469 else => false,4462 else => true,
4470 };4463 };
44714464
4472 const lhs_lock: ?RegisterLock = switch (lhs) {4465 const lhs_lock: ?RegisterLock = switch (lhs) {
...@@ -4482,18 +4475,21 @@ fn genBinOp(...@@ -4482,18 +4475,21 @@ fn genBinOp(
4482 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);4475 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
44834476
4484 var flipped: bool = false;4477 var flipped: bool = false;
4485 const dst_mcv: MCValue = blk: {4478 const dst_mcv: MCValue = dst: {
4486 if (maybe_inst) |inst| {4479 if (maybe_inst) |inst| {
4487 if ((!needs_reg_dst or lhs.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs)) {4480 if ((dst_mem_ok or lhs.isRegister()) and self.reuseOperand(inst, lhs_air, 0, lhs)) {
4488 break :blk lhs;4481 break :dst lhs;
4489 }4482 }
4490 if (is_commutative and (!needs_reg_dst or rhs.isRegister()) and self.reuseOperand(inst, rhs_air, 1, rhs)) {4483 if (is_commutative and (dst_mem_ok or rhs.isRegister()) and
4484 self.reuseOperand(inst, rhs_air, 1, rhs))
4485 {
4491 flipped = true;4486 flipped = true;
4492 break :blk rhs;4487 break :dst rhs;
4493 }4488 }
4494 break :blk try self.copyToRegisterWithInstTracking(inst, lhs_ty, lhs);
4495 }4489 }
4496 break :blk MCValue{ .register = try self.copyToTmpRegister(lhs_ty, lhs) };4490 const dst_mcv = try self.allocRegOrMemAdvanced(lhs_ty, maybe_inst, true);
4491 try self.setRegOrMem(lhs_ty, dst_mcv, lhs);
4492 break :dst dst_mcv;
4497 };4493 };
4498 const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) {4494 const dst_mcv_lock: ?RegisterLock = switch (dst_mcv) {
4499 .register => |reg| self.register_manager.lockReg(reg),4495 .register => |reg| self.register_manager.lockReg(reg),
...@@ -4501,17 +4497,7 @@ fn genBinOp(...@@ -4501,17 +4497,7 @@ fn genBinOp(
4501 };4497 };
4502 defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock);4498 defer if (dst_mcv_lock) |lock| self.register_manager.unlockReg(lock);
45034499
4504 const src_mcv: MCValue = blk: {4500 const src_mcv = if (flipped) lhs else rhs;
4505 const mcv = if (flipped) lhs else rhs;
4506 if (mcv.isRegister() or mcv.isMemory()) break :blk mcv;
4507 break :blk MCValue{ .register = try self.copyToTmpRegister(rhs_ty, mcv) };
4508 };
4509 const src_mcv_lock: ?RegisterLock = switch (src_mcv) {
4510 .register => |reg| self.register_manager.lockReg(reg),
4511 else => null,
4512 };
4513 defer if (src_mcv_lock) |lock| self.register_manager.unlockReg(lock);
4514
4515 switch (tag) {4501 switch (tag) {
4516 .add,4502 .add,
4517 .addwrap,4503 .addwrap,
...@@ -4573,14 +4559,18 @@ fn genBinOp(...@@ -4573,14 +4559,18 @@ fn genBinOp(
4573 .ptr_add,4559 .ptr_add,
4574 .ptr_sub,4560 .ptr_sub,
4575 => {4561 => {
4576 const mir_tag: Mir.Inst.Tag = switch (tag) {4562 const tmp_reg = try self.copyToTmpRegister(rhs_ty, src_mcv);
4563 const tmp_mcv = MCValue{ .register = tmp_reg };
4564 const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg);
4565 defer self.register_manager.unlockReg(tmp_lock);
4566
4567 const elem_size = lhs_ty.elemType2().abiSize(self.target.*);
4568 try self.genIntMulComplexOpMir(rhs_ty, tmp_mcv, .{ .immediate = elem_size });
4569 try self.genBinOpMir(switch (tag) {
4577 .ptr_add => .add,4570 .ptr_add => .add,
4578 .ptr_sub => .sub,4571 .ptr_sub => .sub,
4579 else => unreachable,4572 else => unreachable,
4580 };4573 }, lhs_ty, dst_mcv, tmp_mcv);
4581 const elem_size = lhs_ty.elemType2().abiSize(self.target.*);
4582 try self.genIntMulComplexOpMir(rhs_ty, src_mcv, .{ .immediate = elem_size });
4583 try self.genBinOpMir(mir_tag, lhs_ty, dst_mcv, src_mcv);
4584 },4574 },
45854575
4586 .bool_or,4576 .bool_or,
...@@ -4657,16 +4647,8 @@ fn genBinOp(...@@ -4657,16 +4647,8 @@ fn genBinOp(
4657 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();4647 const addr_reg = (try self.register_manager.allocReg(null, gp)).to64();
4658 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);4648 const addr_reg_lock = self.register_manager.lockRegAssumeUnused(addr_reg);
4659 defer self.register_manager.unlockReg(addr_reg_lock);4649 defer self.register_manager.unlockReg(addr_reg_lock);
4660 try self.loadMemPtrIntoRegister(addr_reg, Type.usize, mat_src_mcv);
4661
4662 // To get the actual address of the value we want to modify we
4663 // we have to go through the GOT
4664 try self.asmRegisterMemory(
4665 .mov,
4666 addr_reg,
4667 Memory.sib(.qword, .{ .base = addr_reg }),
4668 );
46694650
4651 try self.loadMemPtrIntoRegister(addr_reg, Type.usize, mat_src_mcv);
4670 try self.asmCmovccRegisterMemory(4652 try self.asmCmovccRegisterMemory(
4671 registerAlias(tmp_reg, abi_size),4653 registerAlias(tmp_reg, abi_size),
4672 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),4654 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = addr_reg }),
...@@ -4706,6 +4688,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4706,6 +4688,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4706 .eflags => unreachable,4688 .eflags => unreachable,
4707 .register_overflow => unreachable,4689 .register_overflow => unreachable,
4708 .register => |dst_reg| {4690 .register => |dst_reg| {
4691 const dst_alias = registerAlias(dst_reg, abi_size);
4709 switch (src_mcv) {4692 switch (src_mcv) {
4710 .none => unreachable,4693 .none => unreachable,
4711 .undef => unreachable,4694 .undef => unreachable,
...@@ -4728,41 +4711,47 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4728,41 +4711,47 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4728 },4711 },
4729 else => try self.asmRegisterRegister(4712 else => try self.asmRegisterRegister(
4730 mir_tag,4713 mir_tag,
4731 registerAlias(dst_reg, abi_size),4714 dst_alias,
4732 registerAlias(src_reg, abi_size),4715 registerAlias(src_reg, abi_size),
4733 ),4716 ),
4734 },4717 },
4735 .immediate => |imm| {4718 .immediate => |imm| {
4736 switch (self.regBitSize(ty)) {4719 switch (self.regBitSize(ty)) {
4737 8, 16, 32 => {4720 8 => try self.asmRegisterImmediate(
4738 try self.asmRegisterImmediate(4721 mir_tag,
4739 mir_tag,4722 dst_alias,
4740 registerAlias(dst_reg, abi_size),4723 if (math.cast(i8, @bitCast(i64, imm))) |small|
4724 Immediate.s(small)
4725 else
4726 Immediate.u(@intCast(u8, imm)),
4727 ),
4728 16 => try self.asmRegisterImmediate(
4729 mir_tag,
4730 dst_alias,
4731 if (math.cast(i16, @bitCast(i64, imm))) |small|
4732 Immediate.s(small)
4733 else
4734 Immediate.u(@intCast(u16, imm)),
4735 ),
4736 32 => try self.asmRegisterImmediate(
4737 mir_tag,
4738 dst_alias,
4739 if (math.cast(i32, @bitCast(i64, imm))) |small|
4740 Immediate.s(small)
4741 else
4741 Immediate.u(@intCast(u32, imm)),4742 Immediate.u(@intCast(u32, imm)),
4742 );4743 ),
4743 },4744 64 => if (math.cast(i32, @bitCast(i64, imm))) |small|
4744 64 => {4745 try self.asmRegisterImmediate(mir_tag, dst_alias, Immediate.s(small))
4745 if (math.cast(i32, @bitCast(i64, imm))) |small| {4746 else
4746 try self.asmRegisterImmediate(4747 try self.asmRegisterRegister(mir_tag, dst_alias, registerAlias(
4747 mir_tag,4748 try self.copyToTmpRegister(ty, src_mcv),
4748 registerAlias(dst_reg, abi_size),4749 abi_size,
4749 Immediate.s(small),4750 )),
4750 );4751 else => unreachable,
4751 } else {
4752 try self.asmRegisterRegister(
4753 mir_tag,
4754 registerAlias(dst_reg, abi_size),
4755 registerAlias(try self.copyToTmpRegister(ty, src_mcv), abi_size),
4756 );
4757 }
4758 },
4759 else => return self.fail("TODO genBinOpMir implement large immediate ABI", .{}),
4760 }4752 }
4761 },4753 },
4762 .memory,4754 .memory, .linker_load, .eflags => {
4763 .linker_load,
4764 .eflags,
4765 => {
4766 assert(abi_size <= 8);4755 assert(abi_size <= 8);
4767 const dst_reg_lock = self.register_manager.lockReg(dst_reg);4756 const dst_reg_lock = self.register_manager.lockReg(dst_reg);
4768 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);4757 defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock);
...@@ -4779,7 +4768,27 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4779,7 +4768,27 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4779 },4768 },
4780 }4769 }
4781 },4770 },
4782 .ptr_stack_offset, .stack_offset => |dst_off| {4771 .memory, .linker_load, .stack_offset => {
4772 const dst: ?struct {
4773 addr_reg: Register,
4774 addr_lock: RegisterLock,
4775 } = switch (dst_mcv) {
4776 else => unreachable,
4777 .memory, .linker_load => dst: {
4778 const dst_addr_reg = try self.register_manager.allocReg(null, gp);
4779 const dst_addr_lock = self.register_manager.lockRegAssumeUnused(dst_addr_reg);
4780 errdefer self.register_manager.unlockReg(dst_addr_lock);
4781
4782 try self.loadMemPtrIntoRegister(dst_addr_reg, Type.usize, dst_mcv);
4783 break :dst .{
4784 .addr_reg = dst_addr_reg,
4785 .addr_lock = dst_addr_lock,
4786 };
4787 },
4788 .stack_offset => null,
4789 };
4790 defer if (dst) |lock| self.register_manager.unlockReg(lock.addr_lock);
4791
4783 const src: ?struct {4792 const src: ?struct {
4784 limb_reg: Register,4793 limb_reg: Register,
4785 limb_lock: RegisterLock,4794 limb_lock: RegisterLock,
...@@ -4787,7 +4796,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4787,7 +4796,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4787 addr_lock: RegisterLock,4796 addr_lock: RegisterLock,
4788 } = switch (src_mcv) {4797 } = switch (src_mcv) {
4789 else => null,4798 else => null,
4790 .memory, .linker_load => addr: {4799 .memory, .linker_load => src: {
4791 const src_limb_reg = try self.register_manager.allocReg(null, gp);4800 const src_limb_reg = try self.register_manager.allocReg(null, gp);
4792 const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg);4801 const src_limb_lock = self.register_manager.lockRegAssumeUnused(src_limb_reg);
4793 errdefer self.register_manager.unlockReg(src_limb_lock);4802 errdefer self.register_manager.unlockReg(src_limb_lock);
...@@ -4797,15 +4806,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4797,15 +4806,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4797 errdefer self.register_manager.unlockReg(src_addr_lock);4806 errdefer self.register_manager.unlockReg(src_addr_lock);
47984807
4799 try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_mcv);4808 try self.loadMemPtrIntoRegister(src_addr_reg, Type.usize, src_mcv);
4800 // To get the actual address of the value we want to modify we4809 break :src .{
4801 // we have to go through the GOT
4802 try self.asmRegisterMemory(
4803 .mov,
4804 src_addr_reg,
4805 Memory.sib(.qword, .{ .base = src_addr_reg }),
4806 );
4807
4808 break :addr .{
4809 .addr_reg = src_addr_reg,4810 .addr_reg = src_addr_reg,
4810 .addr_lock = src_addr_lock,4811 .addr_lock = src_addr_lock,
4811 .limb_reg = src_limb_reg,4812 .limb_reg = src_limb_reg,
...@@ -4831,7 +4832,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4831,7 +4832,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4831 0 => mir_tag,4832 0 => mir_tag,
4832 else => switch (mir_tag) {4833 else => switch (mir_tag) {
4833 .add => .adc,4834 .add => .adc,
4834 .sub => .sbb,4835 .sub, .cmp => .sbb,
4835 .@"or", .@"and", .xor => mir_tag,4836 .@"or", .@"and", .xor => mir_tag,
4836 else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{4837 else => return self.fail("TODO genBinOpMir implement large ABI for {s}", .{
4837 @tagName(mir_tag),4838 @tagName(mir_tag),
...@@ -4840,7 +4841,14 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4840,7 +4841,14 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4840 };4841 };
4841 const dst_limb_mem = Memory.sib(4842 const dst_limb_mem = Memory.sib(
4842 Memory.PtrSize.fromSize(limb_abi_size),4843 Memory.PtrSize.fromSize(limb_abi_size),
4843 .{ .base = .rbp, .disp = off - dst_off },4844 switch (dst_mcv) {
4845 else => unreachable,
4846 .stack_offset => |dst_off| .{
4847 .base = .rbp,
4848 .disp = off - dst_off,
4849 },
4850 .memory, .linker_load => .{ .base = dst.?.addr_reg, .disp = off },
4851 },
4844 );4852 );
4845 switch (src_mcv) {4853 switch (src_mcv) {
4846 .none => unreachable,4854 .none => unreachable,
...@@ -4861,34 +4869,45 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4861,34 +4869,45 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4861 .unsigned => 0,4869 .unsigned => 0,
4862 };4870 };
4863 switch (self.regBitSize(limb_ty)) {4871 switch (self.regBitSize(limb_ty)) {
4864 8, 16, 32 => {4872 8 => try self.asmMemoryImmediate(
4873 mir_limb_tag,
4874 dst_limb_mem,
4875 if (math.cast(i8, @bitCast(i64, imm))) |small|
4876 Immediate.s(small)
4877 else
4878 Immediate.u(@intCast(u8, imm)),
4879 ),
4880 16 => try self.asmMemoryImmediate(
4881 mir_limb_tag,
4882 dst_limb_mem,
4883 if (math.cast(i16, @bitCast(i64, imm))) |small|
4884 Immediate.s(small)
4885 else
4886 Immediate.u(@intCast(u16, imm)),
4887 ),
4888 32 => try self.asmMemoryImmediate(
4889 mir_limb_tag,
4890 dst_limb_mem,
4891 if (math.cast(i32, @bitCast(i64, imm))) |small|
4892 Immediate.s(small)
4893 else
4894 Immediate.u(@intCast(u32, imm)),
4895 ),
4896 64 => if (math.cast(i32, @bitCast(i64, imm))) |small|
4865 try self.asmMemoryImmediate(4897 try self.asmMemoryImmediate(
4866 mir_limb_tag,4898 mir_limb_tag,
4867 dst_limb_mem,4899 dst_limb_mem,
4868 if (math.cast(i32, @bitCast(i64, imm))) |small|4900 Immediate.s(small),
4869 Immediate.s(small)4901 )
4870 else4902 else
4871 Immediate.u(@intCast(u32, imm)),4903 try self.asmMemoryRegister(
4872 );4904 mir_limb_tag,
4873 },4905 dst_limb_mem,
4874 64 => {4906 registerAlias(
4875 if (math.cast(i32, @bitCast(i64, imm))) |small| {4907 try self.copyToTmpRegister(limb_ty, .{ .immediate = imm }),
4876 try self.asmMemoryImmediate(4908 limb_abi_size,
4877 mir_limb_tag,4909 ),
4878 dst_limb_mem,4910 ),
4879 Immediate.s(small),
4880 );
4881 } else {
4882 try self.asmMemoryRegister(
4883 mir_limb_tag,
4884 dst_limb_mem,
4885 registerAlias(
4886 try self.copyToTmpRegister(limb_ty, .{ .immediate = imm }),
4887 limb_abi_size,
4888 ),
4889 );
4890 }
4891 },
4892 else => unreachable,4911 else => unreachable,
4893 }4912 }
4894 },4913 },
...@@ -4930,12 +4949,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s...@@ -4930,12 +4949,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, ty: Type, dst_mcv: MCValue, s
4930 }4949 }
4931 }4950 }
4932 },4951 },
4933 .memory => {4952 .ptr_stack_offset => unreachable,
4934 return self.fail("TODO implement x86 genBinOpMir destination memory", .{});
4935 },
4936 .linker_load => {
4937 return self.fail("TODO implement x86 genBinOpMir destination symbol at index", .{});
4938 },
4939 }4953 }
4940}4954}
49414955
...@@ -5452,79 +5466,61 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {...@@ -5452,79 +5466,61 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
54525466
5453fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {5467fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
5454 const bin_op = self.air.instructions.items(.data)[inst].bin_op;5468 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
5469 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
5470 const ty = self.air.typeOf(bin_op.lhs);
5471 const ty_abi_size = ty.abiSize(self.target.*);
5472 const can_reuse = ty_abi_size <= 8;
54555473
5456 if (self.liveness.isUnused(inst)) {5474 try self.spillEflagsIfOccupied();
5457 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });5475 self.eflags_inst = inst;
5458 }
5459
5460 const ty = self.air.typeOf(bin_op.lhs);
5461 const abi_size = ty.abiSize(self.target.*);
5462 if (abi_size > 8) return self.fail("TODO implement cmp for large values", .{});
5463
5464 const signedness: std.builtin.Signedness = blk: {
5465 // For non-int types, we treat the values as unsigned
5466 if (ty.zigTypeTag() != .Int) break :blk .unsigned;
5467
5468 // Otherwise, we take the signedness of the actual int
5469 break :blk ty.intInfo(self.target.*).signedness;
5470 };
5471
5472 try self.spillEflagsIfOccupied();
5473 self.eflags_inst = inst;
54745476
5475 const result: MCValue = result: {5477 const lhs_mcv = try self.resolveInst(bin_op.lhs);
5476 // There are 2 operands, destination and source.5478 const lhs_lock = switch (lhs_mcv) {
5477 // Either one, but not both, can be a memory operand.
5478 // Source operand can be an immediate, 8 bits or 32 bits.
5479 // TODO look into reusing the operand
5480 const lhs = try self.resolveInst(bin_op.lhs);
5481 const lhs_lock: ?RegisterLock = switch (lhs) {
5482 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),5479 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
5483 else => null,5480 else => null,
5484 };5481 };
5485 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);5482 defer if (lhs_lock) |lock| self.register_manager.unlockReg(lock);
54865483
5487 const dst_reg = try self.copyToTmpRegister(ty, lhs);5484 const rhs_mcv = try self.resolveInst(bin_op.rhs);
5488 const dst_reg_lock = self.register_manager.lockRegAssumeUnused(dst_reg);5485 const rhs_lock = switch (rhs_mcv) {
5489 defer self.register_manager.unlockReg(dst_reg_lock);5486 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
54905487 else => null,
5491 const dst_mcv = MCValue{ .register = dst_reg };
5492
5493 const rhs_ty = self.air.typeOf(bin_op.rhs);
5494 // This instruction supports only signed 32-bit immediates at most.
5495 const src_mcv: MCValue = blk: {
5496 switch (rhs_ty.zigTypeTag()) {
5497 .Float => {
5498 const rhs = try self.resolveInst(bin_op.rhs);
5499 const rhs_lock: ?RegisterLock = switch (rhs) {
5500 .register => |reg| self.register_manager.lockRegAssumeUnused(reg),
5501 else => null,
5502 };
5503 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
5504 const src_reg = try self.copyToTmpRegister(rhs_ty, rhs);
5505 break :blk MCValue{ .register = src_reg };
5506 },
5507 else => break :blk try self.limitImmediateType(bin_op.rhs, i32),
5508 }
5509 };5488 };
5510 const src_lock: ?RegisterLock = switch (src_mcv) {5489 defer if (rhs_lock) |lock| self.register_manager.unlockReg(lock);
5490
5491 const dst_mem_ok = !ty.isRuntimeFloat();
5492 var flipped = false;
5493 const dst_mcv: MCValue = if (can_reuse and !lhs_mcv.isImmediate() and
5494 (dst_mem_ok or lhs_mcv.isRegister()) and self.liveness.operandDies(inst, 0))
5495 lhs_mcv
5496 else if (can_reuse and !rhs_mcv.isImmediate() and
5497 (dst_mem_ok or rhs_mcv.isRegister()) and self.liveness.operandDies(inst, 1))
5498 dst: {
5499 flipped = true;
5500 break :dst rhs_mcv;
5501 } else if (dst_mem_ok) dst: {
5502 const dst_mcv = try self.allocTempRegOrMem(ty, true);
5503 try self.setRegOrMem(ty, dst_mcv, lhs_mcv);
5504 break :dst dst_mcv;
5505 } else .{ .register = try self.copyToTmpRegister(ty, lhs_mcv) };
5506 const dst_lock = switch (dst_mcv) {
5511 .register => |reg| self.register_manager.lockReg(reg),5507 .register => |reg| self.register_manager.lockReg(reg),
5512 else => null,5508 else => null,
5513 };5509 };
5514 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);5510 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
55155511
5512 const src_mcv = if (flipped) lhs_mcv else rhs_mcv;
5516 try self.genBinOpMir(switch (ty.tag()) {5513 try self.genBinOpMir(switch (ty.tag()) {
5517 else => .cmp,5514 else => .cmp,
5518 .f32 => .ucomiss,5515 .f32 => .ucomiss,
5519 .f64 => .ucomisd,5516 .f64 => .ucomisd,
5520 }, ty, dst_mcv, src_mcv);5517 }, ty, dst_mcv, src_mcv);
55215518
5522 break :result switch (signedness) {5519 const signedness = if (ty.isAbiInt()) ty.intInfo(self.target.*).signedness else .unsigned;
5523 .signed => MCValue{ .eflags = Condition.fromCompareOperatorSigned(op) },5520 break :result .{
5524 .unsigned => MCValue{ .eflags = Condition.fromCompareOperatorUnsigned(op) },5521 .eflags = Condition.fromCompareOperator(signedness, if (flipped) op.reverse() else op),
5525 };5522 };
5526 };5523 };
5527
5528 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });5524 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
5529}5525}
55305526
...@@ -5785,13 +5781,6 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC...@@ -5785,13 +5781,6 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
57855781
5786 try self.loadMemPtrIntoRegister(addr_reg, Type.usize, opt_mcv);5782 try self.loadMemPtrIntoRegister(addr_reg, Type.usize, opt_mcv);
57875783
5788 // To get the actual address of the value we want to modify we have to go through the GOT
5789 try self.asmRegisterMemory(
5790 .mov,
5791 addr_reg,
5792 Memory.sib(.qword, .{ .base = addr_reg }),
5793 );
5794
5795 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));5784 const some_abi_size = @intCast(u32, some_info.ty.abiSize(self.target.*));
5796 try self.asmMemoryImmediate(.cmp, Memory.sib(5785 try self.asmMemoryImmediate(.cmp, Memory.sib(
5797 Memory.PtrSize.fromSize(some_abi_size),5786 Memory.PtrSize.fromSize(some_abi_size),
...@@ -6803,22 +6792,14 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl...@@ -6803,22 +6792,14 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: i32, mcv: MCValue, opts: Inl
6803 },6792 },
6804 }6793 }
6805 },6794 },
6806 .memory, .linker_load => {6795 .memory, .linker_load, .stack_offset, .ptr_stack_offset => {
6807 if (abi_size <= 8) {6796 switch (mcv) {
6808 const reg = try self.copyToTmpRegister(ty, mcv);6797 else => unreachable,
6809 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);6798 .memory, .linker_load, .ptr_stack_offset => {},
6810 }6799 .stack_offset => |src_off| if (stack_offset == src_off) {
68116800 // Copy stack variable to itself; nothing to do.
6812 try self.genInlineMemcpy(.{ .stack_offset = stack_offset }, mcv, .{ .immediate = abi_size }, opts);6801 return;
6813 },6802 },
6814 .ptr_stack_offset => {
6815 const reg = try self.copyToTmpRegister(ty, mcv);
6816 return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }, opts);
6817 },
6818 .stack_offset => |off| {
6819 if (stack_offset == off) {
6820 // Copy stack variable to itself; nothing to do.
6821 return;
6822 }6803 }
68236804
6824 if (abi_size <= 8) {6805 if (abi_size <= 8) {
...@@ -7096,69 +7077,38 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -7096,69 +7077,38 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
70967077
7097 try self.asmRegisterRegister(.mov, registerAlias(reg, abi_size), registerAlias(src_reg, abi_size));7078 try self.asmRegisterRegister(.mov, registerAlias(reg, abi_size), registerAlias(src_reg, abi_size));
7098 },7079 },
7099 .linker_load => {7080 .memory, .linker_load => switch (ty.zigTypeTag()) {
7100 switch (ty.zigTypeTag()) {
7101 .Float => {
7102 const base_reg = try self.register_manager.allocReg(null, gp);
7103 try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv);
7104
7105 if (intrinsicsAllowed(self.target.*, ty)) {
7106 const tag: Mir.Inst.Tag = switch (ty.tag()) {
7107 .f32 => .movss,
7108 .f64 => .movsd,
7109 else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}),
7110 };
7111 const ptr_size: Memory.PtrSize = switch (ty.tag()) {
7112 .f32 => .dword,
7113 .f64 => .qword,
7114 else => unreachable,
7115 };
7116 return self.asmRegisterMemory(
7117 tag,
7118 reg.to128(),
7119 Memory.sib(ptr_size, .{ .base = base_reg.to64() }),
7120 );
7121 }
7122
7123 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
7124 },
7125 else => {
7126 try self.loadMemPtrIntoRegister(reg, Type.usize, mcv);
7127 try self.asmRegisterMemory(
7128 .mov,
7129 registerAlias(reg, abi_size),
7130 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }),
7131 );
7132 },
7133 }
7134 },
7135 .memory => |x| switch (ty.zigTypeTag()) {
7136 .Float => {7081 .Float => {
7137 const base_reg = try self.register_manager.allocReg(null, gp);7082 const base_reg = try self.register_manager.allocReg(null, gp);
7138 try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv);7083 try self.loadMemPtrIntoRegister(base_reg, Type.usize, mcv);
71397084
7140 if (intrinsicsAllowed(self.target.*, ty)) {7085 if (intrinsicsAllowed(self.target.*, ty)) {
7141 const tag: Mir.Inst.Tag = switch (ty.tag()) {
7142 .f32 => .movss,
7143 .f64 => .movsd,
7144 else => return self.fail("TODO genSetReg from memory for {}", .{ty.fmtDebug()}),
7145 };
7146 const ptr_size: Memory.PtrSize = switch (ty.tag()) {
7147 .f32 => .dword,
7148 .f64 => .qword,
7149 else => unreachable,
7150 };
7151 return self.asmRegisterMemory(7086 return self.asmRegisterMemory(
7152 tag,7087 switch (ty.tag()) {
7088 .f32 => .movss,
7089 .f64 => .movsd,
7090 else => return self.fail("TODO genSetReg from memory for {}", .{
7091 ty.fmt(self.bin_file.options.module.?),
7092 }),
7093 },
7153 reg.to128(),7094 reg.to128(),
7154 Memory.sib(ptr_size, .{ .base = base_reg.to64() }),7095 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = base_reg.to64() }),
7155 );7096 );
7156 }7097 }
71577098
7158 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});7099 return self.fail("TODO genSetReg from memory for float with no intrinsics", .{});
7159 },7100 },
7160 else => {7101 else => switch (mcv) {
7161 if (x <= math.maxInt(i32)) {7102 else => unreachable,
7103 .linker_load => {
7104 try self.loadMemPtrIntoRegister(reg, Type.usize, mcv);
7105 try self.asmRegisterMemory(
7106 .mov,
7107 registerAlias(reg, abi_size),
7108 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }),
7109 );
7110 },
7111 .memory => |x| if (x <= math.maxInt(i32)) {
7162 try self.asmRegisterMemory(7112 try self.asmRegisterMemory(
7163 .mov,7113 .mov,
7164 registerAlias(reg, abi_size),7114 registerAlias(reg, abi_size),
...@@ -7185,7 +7135,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -7185,7 +7135,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
7185 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }),7135 Memory.sib(Memory.PtrSize.fromSize(abi_size), .{ .base = reg.to64() }),
7186 );7136 );
7187 }7137 }
7188 }7138 },
7189 },7139 },
7190 },7140 },
7191 .stack_offset => |off| {7141 .stack_offset => |off| {
...@@ -7226,15 +7176,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void...@@ -7226,15 +7176,10 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
7226 .{ty.fmtDebug()},7176 .{ty.fmtDebug()},
7227 ),7177 ),
7228 };7178 };
7229 const ptr_size: Memory.PtrSize = switch (ty.tag()) {7179 return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(
7230 .f32 => .dword,7180 Memory.PtrSize.fromSize(abi_size),
7231 .f64 => .qword,7181 .{ .base = .rbp, .disp = -off },
7232 else => unreachable,7182 ));
7233 };
7234 return self.asmRegisterMemory(tag, reg.to128(), Memory.sib(ptr_size, .{
7235 .base = .rbp,
7236 .disp = -off,
7237 }));
7238 }7183 }
7239 return self.fail("TODO genSetReg from stack offset for float with no intrinsics", .{});7184 return self.fail("TODO genSetReg from stack offset for float with no intrinsics", .{});
7240 },7185 },
src/arch/x86_64/bits.zig+10
...@@ -100,6 +100,16 @@ pub const Condition = enum(u5) {...@@ -100,6 +100,16 @@ pub const Condition = enum(u5) {
100 };100 };
101 }101 }
102102
103 pub fn fromCompareOperator(
104 signedness: std.builtin.Signedness,
105 op: std.math.CompareOperator,
106 ) Condition {
107 return switch (signedness) {
108 .signed => fromCompareOperatorSigned(op),
109 .unsigned => fromCompareOperatorUnsigned(op),
110 };
111 }
112
103 /// Returns the condition which is true iff the given condition is false113 /// Returns the condition which is true iff the given condition is false
104 pub fn negate(cond: Condition) Condition {114 pub fn negate(cond: Condition) Condition {
105 return switch (cond) {115 return switch (cond) {
test/behavior/align.zig-3
...@@ -271,7 +271,6 @@ fn sliceExpects4(slice: []align(4) u32) void {...@@ -271,7 +271,6 @@ fn sliceExpects4(slice: []align(4) u32) void {
271271
272test "return error union with 128-bit integer" {272test "return error union with 128-bit integer" {
273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;273 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
274 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
275 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;274 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
276 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO275 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
277276
...@@ -477,7 +476,6 @@ const DefaultAligned = struct {...@@ -477,7 +476,6 @@ const DefaultAligned = struct {
477476
478test "read 128-bit field from default aligned struct in stack memory" {477test "read 128-bit field from default aligned struct in stack memory" {
479 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;478 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
480 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
481 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;479 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
482 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO480 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
483481
...@@ -494,7 +492,6 @@ var default_aligned_global = DefaultAligned{...@@ -494,7 +492,6 @@ var default_aligned_global = DefaultAligned{
494};492};
495493
496test "read 128-bit field from default aligned struct in global memory" {494test "read 128-bit field from default aligned struct in global memory" {
497 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
498 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;495 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
499 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;496 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO497 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/basic.zig-8
...@@ -39,7 +39,6 @@ test "truncate to non-power-of-two integers" {...@@ -39,7 +39,6 @@ test "truncate to non-power-of-two integers" {
3939
40test "truncate to non-power-of-two integers from 128-bit" {40test "truncate to non-power-of-two integers from 128-bit" {
41 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO41 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
42 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
43 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO42 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
44 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO43 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
45 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO44 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -345,7 +344,6 @@ fn copy(src: *const u64, dst: *u64) void {...@@ -345,7 +344,6 @@ fn copy(src: *const u64, dst: *u64) void {
345test "call result of if else expression" {344test "call result of if else expression" {
346 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;345 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
347 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;346 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
348 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
349 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO347 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
350348
351 try expect(mem.eql(u8, f2(true), "a"));349 try expect(mem.eql(u8, f2(true), "a"));
...@@ -663,7 +661,6 @@ test "multiline string literal is null terminated" {...@@ -663,7 +661,6 @@ test "multiline string literal is null terminated" {
663test "string escapes" {661test "string escapes" {
664 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;662 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
665 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;663 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
666 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
667 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO664 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
668665
669 try expectEqualStrings("\"", "\x22");666 try expectEqualStrings("\"", "\x22");
...@@ -682,8 +679,6 @@ test "explicit cast optional pointers" {...@@ -682,8 +679,6 @@ test "explicit cast optional pointers" {
682}679}
683680
684test "pointer comparison" {681test "pointer comparison" {
685 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
686
687 const a = @as([]const u8, "a");682 const a = @as([]const u8, "a");
688 const b = &a;683 const b = &a;
689 try expect(ptrEql(b, b));684 try expect(ptrEql(b, b));
...@@ -695,7 +690,6 @@ fn ptrEql(a: *const []const u8, b: *const []const u8) bool {...@@ -695,7 +690,6 @@ fn ptrEql(a: *const []const u8, b: *const []const u8) bool {
695test "string concatenation" {690test "string concatenation" {
696 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;691 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
697 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;692 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
698 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
699 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO693 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
700694
701 const a = "OK" ++ " IT " ++ "WORKED";695 const a = "OK" ++ " IT " ++ "WORKED";
...@@ -916,7 +910,6 @@ test "vector initialized with array init syntax has proper type" {...@@ -916,7 +910,6 @@ test "vector initialized with array init syntax has proper type" {
916}910}
917911
918test "weird array and tuple initializations" {912test "weird array and tuple initializations" {
919 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
920 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO913 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
921 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO914 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
922 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO915 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1060,7 +1053,6 @@ test "inline call of function with a switch inside the return statement" {...@@ -1060,7 +1053,6 @@ test "inline call of function with a switch inside the return statement" {
10601053
1061test "namespace lookup ignores decl causing the lookup" {1054test "namespace lookup ignores decl causing the lookup" {
1062 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1055 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1063 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1064 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1056 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1065 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1057 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
10661058
test/behavior/bitcast.zig-1
...@@ -20,7 +20,6 @@ test "@bitCast iX -> uX (32, 64)" {...@@ -20,7 +20,6 @@ test "@bitCast iX -> uX (32, 64)" {
2020
21test "@bitCast iX -> uX (8, 16, 128)" {21test "@bitCast iX -> uX (8, 16, 128)" {
22 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;22 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
24 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;23 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
25 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2625
test/behavior/bugs/6905.zig-1
...@@ -3,7 +3,6 @@ const builtin = @import("builtin");...@@ -3,7 +3,6 @@ const builtin = @import("builtin");
33
4test "sentinel-terminated 0-length slices" {4test "sentinel-terminated 0-length slices" {
5 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO5 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/builtin_functions_returning_void_or_noreturn.zig-1
...@@ -8,7 +8,6 @@ var x: u8 = 1;...@@ -8,7 +8,6 @@ var x: u8 = 1;
8test {8test {
9 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/cast.zig-1
...@@ -1178,7 +1178,6 @@ fn castToOptionalSlice() ?[]const u8 {...@@ -1178,7 +1178,6 @@ fn castToOptionalSlice() ?[]const u8 {
1178test "cast u128 to f128 and back" {1178test "cast u128 to f128 and back" {
1179 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;1179 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1180 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1181 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
1182 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO1181 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1183 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1182 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
11841183
test/behavior/cast_int.zig-1
...@@ -5,7 +5,6 @@ const maxInt = std.math.maxInt;...@@ -5,7 +5,6 @@ const maxInt = std.math.maxInt;
55
6test "@intCast i32 to u7" {6test "@intCast i32 to u7" {
7 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/error.zig-2
...@@ -561,7 +561,6 @@ test "error union comptime caching" {...@@ -561,7 +561,6 @@ test "error union comptime caching" {
561}561}
562562
563test "@errorName" {563test "@errorName" {
564 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
565 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;564 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
566 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;565 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
567 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO566 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -798,7 +797,6 @@ test "error union of noreturn used with catch" {...@@ -798,7 +797,6 @@ test "error union of noreturn used with catch" {
798}797}
799798
800test "alignment of wrapping an error union payload" {799test "alignment of wrapping an error union payload" {
801 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
802 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;800 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
803 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;801 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
804 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO802 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/eval.zig-1
...@@ -458,7 +458,6 @@ test "binary math operator in partially inlined function" {...@@ -458,7 +458,6 @@ test "binary math operator in partially inlined function" {
458458
459test "comptime shl" {459test "comptime shl" {
460 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO460 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
461 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
462 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO461 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
463 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO462 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
464 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO463 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/int128.zig-3
...@@ -5,7 +5,6 @@ const minInt = std.math.minInt;...@@ -5,7 +5,6 @@ const minInt = std.math.minInt;
5const builtin = @import("builtin");5const builtin = @import("builtin");
66
7test "uint128" {7test "uint128" {
8 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -24,7 +23,6 @@ test "uint128" {...@@ -24,7 +23,6 @@ test "uint128" {
24}23}
2524
26test "undefined 128 bit int" {25test "undefined 128 bit int" {
27 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO26 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
29 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO27 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
30 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO28 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -87,7 +85,6 @@ test "truncate int128" {...@@ -87,7 +85,6 @@ test "truncate int128" {
8785
88test "shift int128" {86test "shift int128" {
89 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO87 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
90 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
91 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO88 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
92 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO89 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
93 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO90 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/int_div.zig-1
...@@ -97,7 +97,6 @@ test "large integer division" {...@@ -97,7 +97,6 @@ test "large integer division" {
97 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;97 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
98 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;98 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
99 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;99 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
100 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
101100
102 {101 {
103 var numerator: u256 = 99999999999999999997315645440;102 var numerator: u256 = 99999999999999999997315645440;
test/behavior/optional.zig-1
...@@ -412,7 +412,6 @@ test "orelse on C pointer" {...@@ -412,7 +412,6 @@ test "orelse on C pointer" {
412}412}
413413
414test "alignment of wrapping an optional payload" {414test "alignment of wrapping an optional payload" {
415 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
416 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;415 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
417 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;416 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
418 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO417 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/pointers.zig-1
...@@ -160,7 +160,6 @@ test "implicit casting between C pointer and optional non-C pointer" {...@@ -160,7 +160,6 @@ test "implicit casting between C pointer and optional non-C pointer" {
160}160}
161161
162test "implicit cast error unions with non-optional to optional pointer" {162test "implicit cast error unions with non-optional to optional pointer" {
163 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
164 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO163 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
165 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
166 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO165 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/struct.zig-1
...@@ -800,7 +800,6 @@ test "fn with C calling convention returns struct by value" {...@@ -800,7 +800,6 @@ test "fn with C calling convention returns struct by value" {
800}800}
801801
802test "non-packed struct with u128 entry in union" {802test "non-packed struct with u128 entry in union" {
803 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
804 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO803 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
805 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO804 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
806 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO805 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/typename.zig-6
...@@ -12,7 +12,6 @@ const expectStringStartsWith = std.testing.expectStringStartsWith;...@@ -12,7 +12,6 @@ const expectStringStartsWith = std.testing.expectStringStartsWith;
12// failures.12// failures.
1313
14test "anon fn param" {14test "anon fn param" {
15 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
17 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -38,7 +37,6 @@ test "anon fn param" {...@@ -38,7 +37,6 @@ test "anon fn param" {
38}37}
3938
40test "anon field init" {39test "anon field init" {
41 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
42 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO40 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
43 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO41 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
44 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO42 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -87,7 +85,6 @@ test "basic" {...@@ -87,7 +85,6 @@ test "basic" {
87}85}
8886
89test "top level decl" {87test "top level decl" {
90 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
91 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO88 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
92 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO89 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
93 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO90 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -137,7 +134,6 @@ const B = struct {...@@ -137,7 +134,6 @@ const B = struct {
137};134};
138135
139test "fn param" {136test "fn param" {
140 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO137 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO138 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
143 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -208,7 +204,6 @@ pub fn expectEqualStringsIgnoreDigits(expected: []const u8, actual: []const u8)...@@ -208,7 +204,6 @@ pub fn expectEqualStringsIgnoreDigits(expected: []const u8, actual: []const u8)
208}204}
209205
210test "local variable" {206test "local variable" {
211 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO207 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
213 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO208 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
214 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO209 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -236,7 +231,6 @@ test "comptime parameters not converted to anytype in function type" {...@@ -236,7 +231,6 @@ test "comptime parameters not converted to anytype in function type" {
236}231}
237232
238test "anon name strategy used in sub expression" {233test "anon name strategy used in sub expression" {
239 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO234 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO235 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
242 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO236 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/cases/aarch64-macos/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=aarch64-macos3// target=aarch64-macos
4//4//
5// :108:9: error: root struct of file 'tmp' has no member named 'main'5// :110:9: error: root struct of file 'tmp' has no member named 'main'
test/cases/x86_64-linux/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-linux3// target=x86_64-linux
4//4//
5// :108:9: error: root struct of file 'tmp' has no member named 'main'5// :110:9: error: root struct of file 'tmp' has no member named 'main'
test/cases/x86_64-macos/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-macos3// target=x86_64-macos
4//4//
5// :108:9: error: root struct of file 'tmp' has no member named 'main'5// :110:9: error: root struct of file 'tmp' has no member named 'main'
test/cases/x86_64-windows/hello_world_with_updates.0.zig+1-1
...@@ -2,4 +2,4 @@...@@ -2,4 +2,4 @@
2// output_mode=Exe2// output_mode=Exe
3// target=x86_64-windows3// target=x86_64-windows
4//4//
5// :129:9: error: root struct of file 'tmp' has no member named 'main'5// :131:9: error: root struct of file 'tmp' has no member named 'main'