authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-25 13:44:50-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-03-25 16:23:55-04:00
log1e080e505617b8a7961971630c059592f7366223
treea20ded8cf08eaddf48795549e649a3da0c622a6a
parent6d9bdc8733419ebfc9527d114b637c57d3fd8a42

x86_64: implement atomic loops


27 files changed, 250 insertions(+), 111 deletions(-)

src/arch/x86_64/CodeGen.zig+239-58
...@@ -1438,7 +1438,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {...@@ -1438,7 +1438,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1438 const min_abi_size = @min(dst_abi_size, src_abi_size);1438 const min_abi_size = @min(dst_abi_size, src_abi_size);
1439 const tag: Mir.Inst.Tag = switch (signedness) {1439 const tag: Mir.Inst.Tag = switch (signedness) {
1440 .signed => .movsx,1440 .signed => .movsx,
1441 .unsigned => if (min_abi_size == 4) .mov else .movzx,1441 .unsigned => if (min_abi_size > 2) .mov else .movzx,
1442 };1442 };
1443 const dst_alias = switch (tag) {1443 const dst_alias = switch (tag) {
1444 .movsx => dst_reg.to64(),1444 .movsx => dst_reg.to64(),
...@@ -3889,10 +3889,10 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:...@@ -3889,10 +3889,10 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
3889 const src_ty = self.air.typeOf(src_air);3889 const src_ty = self.air.typeOf(src_air);
3890 const src_mcv = try self.resolveInst(src_air);3890 const src_mcv = try self.resolveInst(src_air);
3891 if (src_ty.zigTypeTag() == .Vector) {3891 if (src_ty.zigTypeTag() == .Vector) {
3892 return self.fail("TODO implement genBinOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});3892 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});
3893 }3893 }
3894 if (src_ty.abiSize(self.target.*) > 8) {3894 if (src_ty.abiSize(self.target.*) > 8) {
3895 return self.fail("TODO implement genBinOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});3895 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(self.bin_file.options.module.?)});
3896 }3896 }
38973897
3898 switch (src_mcv) {3898 switch (src_mcv) {
...@@ -4192,7 +4192,7 @@ fn genShiftBinOp(...@@ -4192,7 +4192,7 @@ fn genShiftBinOp(
4192 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});4192 return self.fail("TODO implement genShiftBinOp for {}", .{lhs_ty.fmtDebug()});
4193 }4193 }
41944194
4195 self.register_manager.getRegAssumeFree(.rcx, null);4195 try self.register_manager.getReg(.rcx, null);
4196 const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx);4196 const rcx_lock = self.register_manager.lockRegAssumeUnused(.rcx);
4197 defer self.register_manager.unlockReg(rcx_lock);4197 defer self.register_manager.unlockReg(rcx_lock);
41984198
...@@ -4717,7 +4717,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu...@@ -4717,7 +4717,7 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu
4717 );4717 );
4718 }4718 }
4719 },4719 },
4720 else => return self.fail("TODO getBinOpMir implement large immediate ABI", .{}),4720 else => return self.fail("TODO genBinOpMir implement large immediate ABI", .{}),
4721 }4721 }
4722 },4722 },
4723 .memory,4723 .memory,
...@@ -4798,28 +4798,28 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu...@@ -4798,28 +4798,28 @@ fn genBinOpMir(self: *Self, mir_tag: Mir.Inst.Tag, dst_ty: Type, dst_mcv: MCValu
4798 );4798 );
4799 }4799 }
4800 },4800 },
4801 else => return self.fail("TODO getBinOpMir implement large immediate ABI", .{}),4801 else => return self.fail("TODO genBinOpMir implement large immediate ABI", .{}),
4802 }4802 }
4803 },4803 },
4804 .memory,4804 .memory,
4805 .stack_offset,4805 .stack_offset,
4806 .ptr_stack_offset,4806 .ptr_stack_offset,
4807 => {4807 => {
4808 return self.fail("TODO implement x86 ADD/SUB/CMP source memory", .{});4808 return self.fail("TODO implement x86 genBinOpMir source memory", .{});
4809 },4809 },
4810 .linker_load => {4810 .linker_load => {
4811 return self.fail("TODO implement x86 ADD/SUB/CMP source symbol at index in linker", .{});4811 return self.fail("TODO implement x86 genBinOpMir source symbol at index in linker", .{});
4812 },4812 },
4813 .eflags => {4813 .eflags => {
4814 return self.fail("TODO implement x86 ADD/SUB/CMP source eflags", .{});4814 return self.fail("TODO implement x86 genBinOpMir source eflags", .{});
4815 },4815 },
4816 }4816 }
4817 },4817 },
4818 .memory => {4818 .memory => {
4819 return self.fail("TODO implement x86 ADD/SUB/CMP destination memory", .{});4819 return self.fail("TODO implement x86 genBinOpMir destination memory", .{});
4820 },4820 },
4821 .linker_load => {4821 .linker_load => {
4822 return self.fail("TODO implement x86 ADD/SUB/CMP destination symbol at index", .{});4822 return self.fail("TODO implement x86 genBinOpMir destination symbol at index", .{});
4823 },4823 },
4824 }4824 }
4825}4825}
...@@ -7219,20 +7219,37 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {...@@ -7219,20 +7219,37 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
7219 const ptr_ty = self.air.typeOf(extra.ptr);7219 const ptr_ty = self.air.typeOf(extra.ptr);
7220 const ptr_mcv = try self.resolveInst(extra.ptr);7220 const ptr_mcv = try self.resolveInst(extra.ptr);
7221 const val_ty = self.air.typeOf(extra.expected_value);7221 const val_ty = self.air.typeOf(extra.expected_value);
7222 const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*));
7223
7224 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
7225 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });
7226 for (regs_lock) |lock| self.register_manager.unlockReg(lock);
72227227
7223 const exp_mcv = try self.resolveInst(extra.expected_value);7228 const exp_mcv = try self.resolveInst(extra.expected_value);
7224 try self.genSetReg(val_ty, .rax, exp_mcv);7229 if (val_abi_size > 8) switch (exp_mcv) {
7230 .stack_offset => |exp_off| {
7231 try self.genSetReg(Type.usize, .rax, .{ .stack_offset = exp_off - 0 });
7232 try self.genSetReg(Type.usize, .rdx, .{ .stack_offset = exp_off - 8 });
7233 },
7234 else => return self.fail("TODO implement cmpxchg for {s}", .{@tagName(exp_mcv)}),
7235 } else try self.genSetReg(val_ty, .rax, exp_mcv);
7225 const rax_lock = self.register_manager.lockRegAssumeUnused(.rax);7236 const rax_lock = self.register_manager.lockRegAssumeUnused(.rax);
7226 defer self.register_manager.unlockReg(rax_lock);7237 defer self.register_manager.unlockReg(rax_lock);
72277238
7228 const new_mcv = try self.resolveInst(extra.new_value);7239 const new_mcv = try self.resolveInst(extra.new_value);
7229 const new_reg = try self.copyToTmpRegister(val_ty, new_mcv);7240 const new_reg: Register = if (val_abi_size > 8) switch (new_mcv) {
7241 .stack_offset => |new_off| new: {
7242 try self.genSetReg(Type.usize, .rbx, .{ .stack_offset = new_off - 0 });
7243 try self.genSetReg(Type.usize, .rcx, .{ .stack_offset = new_off - 8 });
7244 break :new undefined;
7245 },
7246 else => return self.fail("TODO implement cmpxchg for {s}", .{@tagName(exp_mcv)}),
7247 } else try self.copyToTmpRegister(val_ty, new_mcv);
7230 const new_lock = self.register_manager.lockRegAssumeUnused(new_reg);7248 const new_lock = self.register_manager.lockRegAssumeUnused(new_reg);
7231 defer self.register_manager.unlockReg(new_lock);7249 defer self.register_manager.unlockReg(new_lock);
72327250
7233 const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*));
7234 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);7251 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);
7235 const ptr_mem: Memory = switch (ptr_mcv) {7252 const ptr_mem = switch (ptr_mcv) {
7236 .register => |reg| Memory.sib(ptr_size, .{ .base = reg }),7253 .register => |reg| Memory.sib(ptr_size, .{ .base = reg }),
7237 .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }),7254 .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }),
7238 else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }),7255 else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }),
...@@ -7241,16 +7258,30 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {...@@ -7241,16 +7258,30 @@ fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
7241 defer if (mem_lock) |lock| self.register_manager.unlockReg(lock);7258 defer if (mem_lock) |lock| self.register_manager.unlockReg(lock);
72427259
7243 try self.spillEflagsIfOccupied();7260 try self.spillEflagsIfOccupied();
7244 _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{7261 if (val_abi_size <= 8) {
7245 .r = registerAlias(new_reg, val_abi_size),7262 _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{
7246 .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)),7263 .r = registerAlias(new_reg, val_abi_size),
7247 } } });7264 .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)),
7265 } } });
7266 } else {
7267 _ = try self.addInst(.{ .tag = .cmpxchgb, .ops = .lock_m_sib, .data = .{
7268 .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)),
7269 } });
7270 }
72487271
7249 const result: MCValue = result: {7272 const result: MCValue = result: {
7250 if (self.liveness.isUnused(inst)) break :result .dead;7273 if (self.liveness.isUnused(inst)) break :result .dead;
72517274
7252 self.eflags_inst = inst;7275 if (val_abi_size <= 8) {
7253 break :result .{ .register_overflow = .{ .reg = .rax, .eflags = .ne } };7276 self.eflags_inst = inst;
7277 break :result .{ .register_overflow = .{ .reg = .rax, .eflags = .ne } };
7278 }
7279
7280 const dst_mcv = try self.allocRegOrMem(inst, false);
7281 try self.genSetStack(Type.bool, dst_mcv.stack_offset - 16, .{ .eflags = .ne }, .{});
7282 try self.genSetStack(Type.usize, dst_mcv.stack_offset - 8, .{ .register = .rdx }, .{});
7283 try self.genSetStack(Type.usize, dst_mcv.stack_offset - 0, .{ .register = .rax }, .{});
7284 break :result dst_mcv;
7254 };7285 };
7255 return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value });7286 return self.finishAir(inst, result, .{ extra.ptr, extra.expected_value, extra.new_value });
7256}7287}
...@@ -7263,9 +7294,10 @@ fn atomicOp(...@@ -7263,9 +7294,10 @@ fn atomicOp(
7263 ptr_ty: Type,7294 ptr_ty: Type,
7264 val_ty: Type,7295 val_ty: Type,
7265 unused: bool,7296 unused: bool,
7266 op: ?std.builtin.AtomicRmwOp,7297 rmw_op: ?std.builtin.AtomicRmwOp,
7267 order: std.builtin.AtomicOrder,7298 order: std.builtin.AtomicOrder,
7268) InnerError!void {7299) InnerError!void {
7300 const dst_mcv = MCValue{ .register = dst_reg };
7269 const dst_lock = self.register_manager.lockReg(dst_reg);7301 const dst_lock = self.register_manager.lockReg(dst_reg);
7270 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);7302 defer if (dst_lock) |lock| self.register_manager.unlockReg(lock);
72717303
...@@ -7283,7 +7315,7 @@ fn atomicOp(...@@ -7283,7 +7315,7 @@ fn atomicOp(
72837315
7284 const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*));7316 const val_abi_size = @intCast(u32, val_ty.abiSize(self.target.*));
7285 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);7317 const ptr_size = Memory.PtrSize.fromSize(val_abi_size);
7286 const ptr_mem: Memory = switch (ptr_mcv) {7318 const ptr_mem = switch (ptr_mcv) {
7287 .register => |reg| Memory.sib(ptr_size, .{ .base = reg }),7319 .register => |reg| Memory.sib(ptr_size, .{ .base = reg }),
7288 .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }),7320 .ptr_stack_offset => |off| Memory.sib(ptr_size, .{ .base = .rbp, .disp = -off }),
7289 else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }),7321 else => Memory.sib(ptr_size, .{ .base = try self.copyToTmpRegister(ptr_ty, ptr_mcv) }),
...@@ -7291,48 +7323,197 @@ fn atomicOp(...@@ -7291,48 +7323,197 @@ fn atomicOp(
7291 const mem_lock = if (ptr_mem.base()) |reg| self.register_manager.lockReg(reg) else null;7323 const mem_lock = if (ptr_mem.base()) |reg| self.register_manager.lockReg(reg) else null;
7292 defer if (mem_lock) |lock| self.register_manager.unlockReg(lock);7324 defer if (mem_lock) |lock| self.register_manager.unlockReg(lock);
72937325
7294 try self.genSetReg(val_ty, dst_reg, val_mcv);7326 const method: enum { lock, loop, libcall } = if (val_ty.isRuntimeFloat())
72957327 .loop
7296 const need_loop = val_ty.isRuntimeFloat() or if (op) |rmw| switch (rmw) {7328 else switch (rmw_op orelse .Xchg) {
7297 .Xchg, .Add, .Sub => false,7329 .Xchg,
7298 .And, .Or, .Xor => !unused,7330 .Add,
7299 .Nand, .Max, .Min => true,7331 .Sub,
7300 } else false;7332 => if (val_abi_size <= 8) .lock else if (val_abi_size <= 16) .loop else .libcall,
7301 if (!need_loop) {7333 .And,
7302 const tag: Mir.Inst.Tag = if (op) |rmw| switch (rmw) {7334 .Or,
7303 .Xchg => if (unused) .mov else .xchg,7335 .Xor,
7304 .Add => if (unused) .add else .xadd,7336 => if (val_abi_size <= 8 and unused) .lock else if (val_abi_size <= 16) .loop else .libcall,
7305 .Sub => if (unused) .sub else .xadd,7337 .Nand,
7306 .And => .@"and",7338 .Max,
7307 .Or => .@"or",7339 .Min,
7308 .Xor => .xor,7340 => if (val_abi_size <= 16) .loop else .libcall,
7309 else => unreachable,7341 };
7310 } else switch (order) {7342 switch (method) {
7311 .Unordered, .Monotonic, .Release, .AcqRel => .mov,7343 .lock => {
7312 .Acquire => unreachable,7344 const tag: Mir.Inst.Tag = if (rmw_op) |op| switch (op) {
7313 .SeqCst => .xchg,7345 .Xchg => if (unused) .mov else .xchg,
7314 };7346 .Add => if (unused) .add else .xadd,
7315 if (op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) {7347 .Sub => if (unused) .sub else .xadd,
7316 try self.genUnOpMir(.neg, val_ty, .{ .register = dst_reg });7348 .And => .@"and",
7317 }7349 .Or => .@"or",
7318 _ = try self.addInst(.{ .tag = tag, .ops = switch (tag) {7350 .Xor => .xor,
7319 .mov, .xchg => .mr_sib,7351 else => unreachable,
7320 .xadd, .add, .sub, .@"and", .@"or", .xor => .lock_mr_sib,7352 } else switch (order) {
7321 else => unreachable,7353 .Unordered, .Monotonic, .Release, .AcqRel => .mov,
7322 }, .data = .{ .rx = .{7354 .Acquire => unreachable,
7323 .r = registerAlias(dst_reg, val_abi_size),7355 .SeqCst => .xchg,
7324 .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)),7356 };
7325 } } });
7326 return;
7327 }
73287357
7329 return self.fail("TODO implement x86 atomic loop", .{});7358 try self.genSetReg(val_ty, dst_reg, val_mcv);
7359 if (rmw_op == std.builtin.AtomicRmwOp.Sub and tag == .xadd) {
7360 try self.genUnOpMir(.neg, val_ty, .{ .register = dst_reg });
7361 }
7362 _ = try self.addInst(.{ .tag = tag, .ops = switch (tag) {
7363 .mov, .xchg => .mr_sib,
7364 .xadd, .add, .sub, .@"and", .@"or", .xor => .lock_mr_sib,
7365 else => unreachable,
7366 }, .data = .{ .rx = .{
7367 .r = registerAlias(dst_reg, val_abi_size),
7368 .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)),
7369 } } });
7370 },
7371 .loop => _ = try self.asmJccReloc(if (val_abi_size <= 8) loop: {
7372 try self.genSetReg(val_ty, dst_reg, val_mcv);
7373 try self.asmRegisterMemory(.mov, registerAlias(.rax, val_abi_size), ptr_mem);
7374 const loop = @intCast(u32, self.mir_instructions.len);
7375 if (rmw_op != std.builtin.AtomicRmwOp.Xchg) {
7376 try self.genSetReg(val_ty, dst_reg, .{ .register = .rax });
7377 }
7378 if (rmw_op) |op| switch (op) {
7379 .Xchg => try self.genSetReg(val_ty, dst_reg, val_mcv),
7380 .Add => try self.genBinOpMir(.add, val_ty, dst_mcv, val_mcv),
7381 .Sub => try self.genBinOpMir(.sub, val_ty, dst_mcv, val_mcv),
7382 .And => try self.genBinOpMir(.@"and", val_ty, dst_mcv, val_mcv),
7383 .Nand => {
7384 try self.genBinOpMir(.@"and", val_ty, dst_mcv, val_mcv);
7385 try self.genUnOpMir(.not, val_ty, dst_mcv);
7386 },
7387 .Or => try self.genBinOpMir(.@"or", val_ty, dst_mcv, val_mcv),
7388 .Xor => try self.genBinOpMir(.xor, val_ty, dst_mcv, val_mcv),
7389 .Min, .Max => {
7390 const cc: Condition = switch (if (val_ty.isAbiInt())
7391 val_ty.intInfo(self.target.*).signedness
7392 else
7393 .unsigned) {
7394 .unsigned => switch (op) {
7395 .Min => .a,
7396 .Max => .b,
7397 else => unreachable,
7398 },
7399 .signed => switch (op) {
7400 .Min => .g,
7401 .Max => .l,
7402 else => unreachable,
7403 },
7404 };
7405
7406 try self.genBinOpMir(.cmp, val_ty, dst_mcv, val_mcv);
7407 switch (val_mcv) {
7408 .register => |val_reg| try self.asmCmovccRegisterRegister(
7409 registerAlias(dst_reg, val_abi_size),
7410 registerAlias(val_reg, val_abi_size),
7411 cc,
7412 ),
7413 .stack_offset => |val_off| try self.asmCmovccRegisterMemory(
7414 registerAlias(dst_reg, val_abi_size),
7415 Memory.sib(
7416 Memory.PtrSize.fromSize(val_abi_size),
7417 .{ .base = .rbp, .disp = -val_off },
7418 ),
7419 cc,
7420 ),
7421 else => {
7422 const val_reg = try self.copyToTmpRegister(val_ty, val_mcv);
7423 try self.asmCmovccRegisterRegister(
7424 registerAlias(dst_reg, val_abi_size),
7425 registerAlias(val_reg, val_abi_size),
7426 cc,
7427 );
7428 },
7429 }
7430 },
7431 };
7432 _ = try self.addInst(.{ .tag = .cmpxchg, .ops = .lock_mr_sib, .data = .{ .rx = .{
7433 .r = registerAlias(dst_reg, val_abi_size),
7434 .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)),
7435 } } });
7436 break :loop loop;
7437 } else loop: {
7438 try self.asmRegisterMemory(.mov, .rax, Memory.sib(.qword, .{
7439 .base = ptr_mem.sib.base,
7440 .scale_index = ptr_mem.sib.scale_index,
7441 .disp = ptr_mem.sib.disp + 0,
7442 }));
7443 try self.asmRegisterMemory(.mov, .rdx, Memory.sib(.qword, .{
7444 .base = ptr_mem.sib.base,
7445 .scale_index = ptr_mem.sib.scale_index,
7446 .disp = ptr_mem.sib.disp + 8,
7447 }));
7448 const loop = @intCast(u32, self.mir_instructions.len);
7449 switch (val_mcv) {
7450 .stack_offset => |val_off| {
7451 const val_lo_mem = Memory.sib(.qword, .{ .base = .rbp, .disp = 0 - val_off });
7452 const val_hi_mem = Memory.sib(.qword, .{ .base = .rbp, .disp = 8 - val_off });
7453
7454 if (rmw_op != std.builtin.AtomicRmwOp.Xchg) {
7455 try self.asmRegisterRegister(.mov, .rbx, .rax);
7456 try self.asmRegisterRegister(.mov, .rcx, .rdx);
7457 }
7458 if (rmw_op) |op| switch (op) {
7459 .Xchg => {
7460 try self.asmRegisterMemory(.mov, .rbx, val_lo_mem);
7461 try self.asmRegisterMemory(.mov, .rcx, val_hi_mem);
7462 },
7463 .Add => {
7464 try self.asmRegisterMemory(.add, .rbx, val_lo_mem);
7465 try self.asmRegisterMemory(.adc, .rcx, val_hi_mem);
7466 },
7467 .Sub => {
7468 try self.asmRegisterMemory(.sub, .rbx, val_lo_mem);
7469 try self.asmRegisterMemory(.sbb, .rcx, val_hi_mem);
7470 },
7471 .And => {
7472 try self.asmRegisterMemory(.@"and", .rbx, val_lo_mem);
7473 try self.asmRegisterMemory(.@"and", .rcx, val_hi_mem);
7474 },
7475 .Nand => {
7476 try self.asmRegisterMemory(.@"and", .rbx, val_lo_mem);
7477 try self.asmRegisterMemory(.@"and", .rcx, val_hi_mem);
7478 try self.asmRegister(.not, .rbx);
7479 try self.asmRegister(.not, .rcx);
7480 },
7481 .Or => {
7482 try self.asmRegisterMemory(.@"or", .rbx, val_lo_mem);
7483 try self.asmRegisterMemory(.@"or", .rcx, val_hi_mem);
7484 },
7485 .Xor => {
7486 try self.asmRegisterMemory(.xor, .rbx, val_lo_mem);
7487 try self.asmRegisterMemory(.xor, .rcx, val_hi_mem);
7488 },
7489 else => return self.fail(
7490 "TODO implement x86 atomic loop for large abi {s}",
7491 .{@tagName(op)},
7492 ),
7493 };
7494 },
7495 else => return self.fail(
7496 "TODO implement x86 atomic loop for large abi {s}",
7497 .{@tagName(val_mcv)},
7498 ),
7499 }
7500 _ = try self.addInst(.{ .tag = .cmpxchgb, .ops = .lock_m_sib, .data = .{
7501 .payload = try self.addExtra(Mir.MemorySib.encode(ptr_mem)),
7502 } });
7503 break :loop loop;
7504 }, .ne),
7505 .libcall => return self.fail("TODO implement x86 atomic libcall", .{}),
7506 }
7330}7507}
73317508
7332fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {7509fn airAtomicRmw(self: *Self, inst: Air.Inst.Index) !void {
7333 const pl_op = self.air.instructions.items(.data)[inst].pl_op;7510 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
7334 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;7511 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
73357512
7513 try self.spillRegisters(&.{ .rax, .rdx, .rbx, .rcx });
7514 const regs_lock = self.register_manager.lockRegsAssumeUnused(4, .{ .rax, .rdx, .rbx, .rcx });
7515 defer for (regs_lock) |lock| self.register_manager.unlockReg(lock);
7516
7336 const unused = self.liveness.isUnused(inst);7517 const unused = self.liveness.isUnused(inst);
7337 const dst_reg = try self.register_manager.allocReg(if (unused) null else inst, gp);7518 const dst_reg = try self.register_manager.allocReg(if (unused) null else inst, gp);
73387519
src/arch/x86_64/bits.zig+11-12
...@@ -411,20 +411,17 @@ pub const Memory = union(enum) {...@@ -411,20 +411,17 @@ pub const Memory = union(enum) {
411 dword,411 dword,
412 qword,412 qword,
413 tbyte,413 tbyte,
414 dqword,
414415
415 pub fn fromSize(size: u32) PtrSize {416 pub fn fromSize(size: u32) PtrSize {
416 return if (size <= 1)417 return switch (size) {
417 .byte418 1...1 => .byte,
418 else if (size <= 2)419 2...2 => .word,
419 .word420 3...4 => .dword,
420 else if (size <= 4)421 5...8 => .qword,
421 .dword422 9...16 => .dqword,
422 else if (size <= 8)423 else => unreachable,
423 .qword424 };
424 else if (size == 10)
425 .tbyte
426 else
427 unreachable;
428 }425 }
429426
430 pub fn fromBitSize(bit_size: u64) PtrSize {427 pub fn fromBitSize(bit_size: u64) PtrSize {
...@@ -434,6 +431,7 @@ pub const Memory = union(enum) {...@@ -434,6 +431,7 @@ pub const Memory = union(enum) {
434 32 => .dword,431 32 => .dword,
435 64 => .qword,432 64 => .qword,
436 80 => .tbyte,433 80 => .tbyte,
434 128 => .dqword,
437 else => unreachable,435 else => unreachable,
438 };436 };
439 }437 }
...@@ -445,6 +443,7 @@ pub const Memory = union(enum) {...@@ -445,6 +443,7 @@ pub const Memory = union(enum) {
445 .dword => 32,443 .dword => 32,
446 .qword => 64,444 .qword => 64,
447 .tbyte => 80,445 .tbyte => 80,
446 .dqword => 128,
448 };447 };
449 }448 }
450 };449 };
test/behavior/array.zig-2
...@@ -70,7 +70,6 @@ test "array concat with undefined" {...@@ -70,7 +70,6 @@ test "array concat with undefined" {
70test "array concat with tuple" {70test "array concat with tuple" {
71 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO71 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO72 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
73 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
7473
75 const array: [2]u8 = .{ 1, 2 };74 const array: [2]u8 = .{ 1, 2 };
76 {75 {
...@@ -641,7 +640,6 @@ test "tuple to array handles sentinel" {...@@ -641,7 +640,6 @@ test "tuple to array handles sentinel" {
641}640}
642641
643test "array init of container level array variable" {642test "array init of container level array variable" {
644 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
645 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO643 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
646 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO644 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
647 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO645 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/bugs/10684.zig-1
...@@ -4,7 +4,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;...@@ -4,7 +4,6 @@ const expectEqualStrings = std.testing.expectEqualStrings;
44
5test "slicing slices" {5test "slicing slices" {
6 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_x86) 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
test/behavior/bugs/12051.zig-1
...@@ -3,7 +3,6 @@ const builtin = @import("builtin");...@@ -3,7 +3,6 @@ const builtin = @import("builtin");
33
4test {4test {
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/bugs/12092.zig-1
...@@ -15,7 +15,6 @@ fn takeFoo(foo: *const Foo) !void {...@@ -15,7 +15,6 @@ fn takeFoo(foo: *const Foo) !void {
1515
16test {16test {
17 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
18 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
19 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO18 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
20 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
21 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO20 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/bugs/12142.zig-1
...@@ -20,7 +20,6 @@ fn letter(e: Letter) u8 {...@@ -20,7 +20,6 @@ fn letter(e: Letter) u8 {
2020
21test {21test {
22 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO22 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
23 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO25 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/bugs/6456.zig-1
...@@ -11,7 +11,6 @@ const text =...@@ -11,7 +11,6 @@ const text =
11;11;
1212
13test "issue 6456" {13test "issue 6456" {
14 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO14 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
16 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO15 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1716
test/behavior/bugs/8646.zig-1
...@@ -8,7 +8,6 @@ const array = [_][]const []const u8{...@@ -8,7 +8,6 @@ const array = [_][]const []const u8{
88
9test {9test {
10 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
test/behavior/empty_tuple_fields.zig-2
...@@ -3,7 +3,6 @@ const builtin = @import("builtin");...@@ -3,7 +3,6 @@ const builtin = @import("builtin");
33
4test "empty file level struct" {4test "empty file level struct" {
5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
87
9 const T = @import("empty_file_level_struct.zig");8 const T = @import("empty_file_level_struct.zig");
...@@ -15,7 +14,6 @@ test "empty file level struct" {...@@ -15,7 +14,6 @@ test "empty file level struct" {
1514
16test "empty file level union" {15test "empty file level union" {
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_x86_64) return error.SkipZigTest; // TODO
19 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO17 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
2018
21 const T = @import("empty_file_level_union.zig");19 const T = @import("empty_file_level_union.zig");
test/behavior/lower_strlit_to_vector.zig-1
...@@ -2,7 +2,6 @@ const std = @import("std");...@@ -2,7 +2,6 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4test "strlit to vector" {4test "strlit to vector" {
5 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
6 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO5 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO7 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/math.zig-1
...@@ -560,7 +560,6 @@ fn testUnsignedNegationWrappingEval(x: u16) !void {...@@ -560,7 +560,6 @@ fn testUnsignedNegationWrappingEval(x: u16) !void {
560test "negation wrapping" {560test "negation wrapping" {
561 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO561 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
562 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO562 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
563 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
564563
565 try expectEqual(@as(u1, 1), negateWrap(u1, 1));564 try expectEqual(@as(u1, 1), negateWrap(u1, 1));
566}565}
test/behavior/optional.zig-1
...@@ -431,7 +431,6 @@ test "alignment of wrapping an optional payload" {...@@ -431,7 +431,6 @@ test "alignment of wrapping an optional payload" {
431test "Optional slice size is optimized" {431test "Optional slice size is optimized" {
432 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;432 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
433 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;433 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
434 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
435 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO434 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
436435
437 try expect(@sizeOf(?[]u8) == @sizeOf([]u8));436 try expect(@sizeOf(?[]u8) == @sizeOf([]u8));
test/behavior/packed-struct.zig-2
...@@ -120,7 +120,6 @@ test "consistent size of packed structs" {...@@ -120,7 +120,6 @@ test "consistent size of packed structs" {
120}120}
121121
122test "correct sizeOf and offsets in packed structs" {122test "correct sizeOf and offsets in packed structs" {
123 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
124 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO123 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
125 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -188,7 +187,6 @@ test "correct sizeOf and offsets in packed structs" {...@@ -188,7 +187,6 @@ test "correct sizeOf and offsets in packed structs" {
188}187}
189188
190test "nested packed structs" {189test "nested packed structs" {
191 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
192 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO190 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
193 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO191 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO192 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/packed_struct_explicit_backing_int.zig-1
...@@ -6,7 +6,6 @@ const native_endian = builtin.cpu.arch.endian();...@@ -6,7 +6,6 @@ const native_endian = builtin.cpu.arch.endian();
66
7test "packed struct explicit backing integer" {7test "packed struct explicit backing integer" {
8 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO8 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO9 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO10 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO11 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/pointers.zig-2
...@@ -412,7 +412,6 @@ test "@ptrToInt on null optional at comptime" {...@@ -412,7 +412,6 @@ test "@ptrToInt on null optional at comptime" {
412test "indexing array with sentinel returns correct type" {412test "indexing array with sentinel returns correct type" {
413 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO413 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
414 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO414 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
415 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
416 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO415 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
417416
418 var s: [:0]const u8 = "abc";417 var s: [:0]const u8 = "abc";
...@@ -497,7 +496,6 @@ test "pointer to constant decl preserves alignment" {...@@ -497,7 +496,6 @@ test "pointer to constant decl preserves alignment" {
497test "ptrCast comptime known slice to C pointer" {496test "ptrCast comptime known slice to C pointer" {
498 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO497 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
499 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO498 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
500 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
501 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO499 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
502500
503 const s: [:0]const u8 = "foo";501 const s: [:0]const u8 = "foo";
test/behavior/slice.zig-3
...@@ -688,7 +688,6 @@ test "slice field ptr var" {...@@ -688,7 +688,6 @@ test "slice field ptr var" {
688test "global slice field access" {688test "global slice field access" {
689 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO689 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
690 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO690 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
691 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
692 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO691 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
693692
694 const S = struct {693 const S = struct {
...@@ -733,7 +732,6 @@ test "empty slice ptr is non null" {...@@ -733,7 +732,6 @@ test "empty slice ptr is non null" {
733test "slice decays to many pointer" {732test "slice decays to many pointer" {
734 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;733 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
735 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;734 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
736 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
737735
738 var buf: [8]u8 = "abcdefg\x00".*;736 var buf: [8]u8 = "abcdefg\x00".*;
739 const p: [*:0]const u8 = buf[0..7 :0];737 const p: [*:0]const u8 = buf[0..7 :0];
...@@ -744,7 +742,6 @@ test "write through pointer to optional slice arg" {...@@ -744,7 +742,6 @@ test "write through pointer to optional slice arg" {
744 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;742 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
745 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;743 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
746 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;744 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
747 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
748745
749 const S = struct {746 const S = struct {
750 fn bar(foo: *?[]const u8) !void {747 fn bar(foo: *?[]const u8) !void {
test/behavior/struct.zig-1
...@@ -935,7 +935,6 @@ test "comptime struct field" {...@@ -935,7 +935,6 @@ test "comptime struct field" {
935}935}
936936
937test "tuple element initialized with fn call" {937test "tuple element initialized with fn call" {
938 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
939 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO938 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
940 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO939 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
941 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO940 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/switch.zig-1
...@@ -620,7 +620,6 @@ test "switch on error set with single else" {...@@ -620,7 +620,6 @@ test "switch on error set with single else" {
620}620}
621621
622test "switch capture copies its payload" {622test "switch capture copies its payload" {
623 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
624 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO623 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
625 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO624 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
626 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO625 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/threadlocal.zig-1
...@@ -21,7 +21,6 @@ test "thread local variable" {...@@ -21,7 +21,6 @@ test "thread local variable" {
2121
22test "pointer to thread local array" {22test "pointer to thread local array" {
23 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO23 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
24 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
25 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO24 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
26 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO25 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {26 if (builtin.zig_backend == .stage2_llvm) switch (builtin.cpu.arch) {
test/behavior/translate_c_macros.zig-8
...@@ -23,7 +23,6 @@ test "casting to void with a macro" {...@@ -23,7 +23,6 @@ test "casting to void with a macro" {
23}23}
2424
25test "initializer list expression" {25test "initializer list expression" {
26 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
27 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO26 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
28 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO27 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
29 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO28 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -52,7 +51,6 @@ test "reference to a struct type" {...@@ -52,7 +51,6 @@ test "reference to a struct type" {
5251
53test "cast negative integer to pointer" {52test "cast negative integer to pointer" {
54 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO53 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
55 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
56 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO54 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
57 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO55 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
58 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO56 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -98,7 +96,6 @@ test "casting or calling a value with a paren-surrounded macro" {...@@ -98,7 +96,6 @@ test "casting or calling a value with a paren-surrounded macro" {
9896
99test "nested comma operator" {97test "nested comma operator" {
100 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO98 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
101 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
102 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO99 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO100 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
104 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO101 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -109,7 +106,6 @@ test "nested comma operator" {...@@ -109,7 +106,6 @@ test "nested comma operator" {
109106
110test "cast functions" {107test "cast functions" {
111 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO108 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
113 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO109 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
114 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO110 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
115 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO111 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -123,7 +119,6 @@ test "cast functions" {...@@ -123,7 +119,6 @@ test "cast functions" {
123119
124test "large integer macro" {120test "large integer macro" {
125 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO121 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
126 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
127 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO122 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
128 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO123 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO124 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -133,7 +128,6 @@ test "large integer macro" {...@@ -133,7 +128,6 @@ test "large integer macro" {
133128
134test "string literal macro with embedded tab character" {129test "string literal macro with embedded tab character" {
135 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO130 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
136 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO131 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO132 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
139 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO133 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -143,7 +137,6 @@ test "string literal macro with embedded tab character" {...@@ -143,7 +137,6 @@ test "string literal macro with embedded tab character" {
143137
144test "string and char literals that are not UTF-8 encoded. Issue #12784" {138test "string and char literals that are not UTF-8 encoded. Issue #12784" {
145 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO139 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
146 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
147 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
148 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
149 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -188,7 +181,6 @@ test "Macro that uses division operator. Issue #13162" {...@@ -188,7 +181,6 @@ test "Macro that uses division operator. Issue #13162" {
188181
189test "Macro that uses remainder operator. Issue #13346" {182test "Macro that uses remainder operator. Issue #13346" {
190 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO183 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
191 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
192 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO184 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO185 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
194 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO186 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/tuple.zig-1
...@@ -381,7 +381,6 @@ test "tuple of struct concatenation and coercion to array" {...@@ -381,7 +381,6 @@ test "tuple of struct concatenation and coercion to array" {
381test "nested runtime conditionals in tuple initializer" {381test "nested runtime conditionals in tuple initializer" {
382 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO382 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
383 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO383 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
384 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
385384
386 var data: u8 = 0;385 var data: u8 = 0;
387 const x = .{386 const x = .{
test/behavior/tuple_declarations.zig-2
...@@ -7,7 +7,6 @@ const expectEqualStrings = testing.expectEqualStrings;...@@ -7,7 +7,6 @@ const expectEqualStrings = testing.expectEqualStrings;
7test "tuple declaration type info" {7test "tuple declaration type info" {
8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;8 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;9 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
10 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
1110
12 {11 {
13 const T = struct { comptime u32 align(2) = 1, []const u8 };12 const T = struct { comptime u32 align(2) = 1, []const u8 };
...@@ -57,7 +56,6 @@ test "tuple declaration type info" {...@@ -57,7 +56,6 @@ test "tuple declaration type info" {
57test "Tuple declaration usage" {56test "Tuple declaration usage" {
58 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;57 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
59 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;58 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
60 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
6159
62 const T = struct { u32, []const u8 };60 const T = struct { u32, []const u8 };
63 var t: T = .{ 1, "foo" };61 var t: T = .{ 1, "foo" };
test/behavior/type.zig-2
...@@ -200,7 +200,6 @@ test "Type.ErrorUnion" {...@@ -200,7 +200,6 @@ test "Type.ErrorUnion" {
200200
201test "Type.Opaque" {201test "Type.Opaque" {
202 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO202 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
203 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
204 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO203 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
205 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO204 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
206 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO205 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -348,7 +347,6 @@ test "Type.Struct" {...@@ -348,7 +347,6 @@ test "Type.Struct" {
348}347}
349348
350test "Type.Enum" {349test "Type.Enum" {
351 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
352 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO350 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
353 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO351 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
354352
test/behavior/type_info.zig-1
...@@ -568,7 +568,6 @@ test "value from struct @typeInfo default_value can be loaded at comptime" {...@@ -568,7 +568,6 @@ test "value from struct @typeInfo default_value can be loaded at comptime" {
568test "@typeInfo decls and usingnamespace" {568test "@typeInfo decls and usingnamespace" {
569 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO569 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
570 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO570 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
571 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
572571
573 const A = struct {572 const A = struct {
574 const x = 5;573 const x = 5;
test/behavior/typename.zig-2
...@@ -64,7 +64,6 @@ test "anon field init" {...@@ -64,7 +64,6 @@ test "anon field init" {
64}64}
6565
66test "basic" {66test "basic" {
67 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
68 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO67 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
69 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO68 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO69 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -228,7 +227,6 @@ test "local variable" {...@@ -228,7 +227,6 @@ test "local variable" {
228}227}
229228
230test "comptime parameters not converted to anytype in function type" {229test "comptime parameters not converted to anytype in function type" {
231 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
232 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO230 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
233 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO231 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
234 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO232 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/vector.zig-1
...@@ -1267,7 +1267,6 @@ test "store to vector in slice" {...@@ -1267,7 +1267,6 @@ test "store to vector in slice" {
1267test "addition of vectors represented as strings" {1267test "addition of vectors represented as strings" {
1268 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO1268 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
1269 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1269 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1270 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
12711270
1272 const V = @Vector(3, u8);1271 const V = @Vector(3, u8);
1273 const foo: V = "foo".*;1272 const foo: V = "foo".*;