stage2: implement comptime bitwise nand

This commit is contained in:
Andrew Kelley
2021-09-20 15:44:09 -07:00
parent f3147de7a2
commit 4b2d7a9c67
5 changed files with 48 additions and 36 deletions

View File

@@ -566,6 +566,7 @@ pub const Mutable = struct {
llor(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]);
r.len = b.limbs.len;
}
r.positive = a.positive or b.positive;
}
/// r = a & b
@@ -580,6 +581,7 @@ pub const Mutable = struct {
lland(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]);
r.normalize(a.limbs.len);
}
r.positive = a.positive and b.positive;
}
/// r = a ^ b
@@ -594,6 +596,7 @@ pub const Mutable = struct {
llxor(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]);
r.normalize(b.limbs.len);
}
r.positive = a.positive or b.positive;
}
/// rma may alias x or y.

View File

@@ -7871,7 +7871,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE
.Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target),
.Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target),
.And => try stored_val.bitwiseAnd (operand_val, sema.arena),
.Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena),
.Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target),
.Or => try stored_val.bitwiseOr (operand_val, sema.arena),
.Xor => try stored_val.bitwiseXor (operand_val, sema.arena),
.Max => try stored_val.numberMax (operand_val, sema.arena),

View File

@@ -1690,12 +1690,17 @@ pub const Value = extern union {
}
/// operands must be integers; handles undefined.
pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: *Allocator) !Value {
pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: *Allocator, target: Target) !Value {
if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef);
_ = ty;
_ = arena;
@panic("TODO comptime bitwise NAND");
const anded = try bitwiseAnd(lhs, rhs, arena);
const all_ones = if (ty.isSignedInt())
try Value.Tag.int_i64.create(arena, -1)
else
try ty.maxInt(arena, target);
return bitwiseXor(anded, all_ones, arena);
}
/// operands must be integers; handles undefined.

View File

@@ -167,3 +167,31 @@ fn testAtomicRmwFloat() !void {
_ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst);
try expect(x == 4);
}
test "atomicrmw with ints" {
try testAtomicRmwInt();
comptime try testAtomicRmwInt();
}
fn testAtomicRmwInt() !void {
var x: u8 = 1;
var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst);
try expect(x == 3 and res == 1);
_ = @atomicRmw(u8, &x, .Add, 3, .SeqCst);
try expect(x == 6);
_ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst);
try expect(x == 5);
_ = @atomicRmw(u8, &x, .And, 4, .SeqCst);
try expect(x == 4);
_ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst);
try expect(x == 0xfb);
_ = @atomicRmw(u8, &x, .Or, 6, .SeqCst);
try expect(x == 0xff);
_ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst);
try expect(x == 0xfd);
_ = @atomicRmw(u8, &x, .Max, 1, .SeqCst);
try expect(x == 0xfd);
_ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
try expect(x == 1);
}

View File

@@ -3,39 +3,15 @@ const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const builtin = @import("builtin");
test "atomicrmw with ints" {
try testAtomicRmwInt();
comptime try testAtomicRmwInt();
}
fn testAtomicRmwInt() !void {
var x: u8 = 1;
var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst);
try expect(x == 3 and res == 1);
_ = @atomicRmw(u8, &x, .Add, 3, .SeqCst);
try expect(x == 6);
_ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst);
try expect(x == 5);
_ = @atomicRmw(u8, &x, .And, 4, .SeqCst);
try expect(x == 4);
_ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst);
try expect(x == 0xfb);
_ = @atomicRmw(u8, &x, .Or, 6, .SeqCst);
try expect(x == 0xff);
_ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst);
try expect(x == 0xfd);
_ = @atomicRmw(u8, &x, .Max, 1, .SeqCst);
try expect(x == 0xfd);
_ = @atomicRmw(u8, &x, .Min, 1, .SeqCst);
try expect(x == 1);
}
test "atomics with different types" {
try testAtomicsWithType(bool, true, false);
inline for (.{ u1, i4, u5, i15, u24 }) |T| {
try testAtomicsWithType(T, 0, 1);
}
try testAtomicsWithType(u1, 0, 1);
try testAtomicsWithType(i4, 0, 1);
try testAtomicsWithType(u5, 0, 1);
try testAtomicsWithType(i15, 0, 1);
try testAtomicsWithType(u24, 0, 1);
try testAtomicsWithType(u0, 0, 0);
try testAtomicsWithType(i0, 0, 0);
}