stage2: implement comptime bitwise nand
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user