| author | |
| committer | |
| log | 4b2d7a9c67760aa9a81bfd364ac0d88cbb9737f1 |
| tree | 2b3b5a2faf3a6c335d032c05bd7884e371ebabae |
| parent | f3147de7a28767a27406355fd2d93d1bbcec9437 |
5 files changed, 48 insertions(+), 36 deletions(-)
lib/std/math/big/int.zig+3| ... | @@ -566,6 +566,7 @@ pub const Mutable = struct { | ... | @@ -566,6 +566,7 @@ pub const Mutable = struct { |
| 566 | llor(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]); | 566 | llor(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]); |
| 567 | r.len = b.limbs.len; | 567 | r.len = b.limbs.len; |
| 568 | } | 568 | } |
| 569 | r.positive = a.positive or b.positive; | ||
| 569 | } | 570 | } |
| 570 | 571 | ||
| 571 | /// r = a & b | 572 | /// r = a & b |
| ... | @@ -580,6 +581,7 @@ pub const Mutable = struct { | ... | @@ -580,6 +581,7 @@ pub const Mutable = struct { |
| 580 | lland(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]); | 581 | lland(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]); |
| 581 | r.normalize(a.limbs.len); | 582 | r.normalize(a.limbs.len); |
| 582 | } | 583 | } |
| 584 | r.positive = a.positive and b.positive; | ||
| 583 | } | 585 | } |
| 584 | 586 | ||
| 585 | /// r = a ^ b | 587 | /// r = a ^ b |
| ... | @@ -594,6 +596,7 @@ pub const Mutable = struct { | ... | @@ -594,6 +596,7 @@ pub const Mutable = struct { |
| 594 | llxor(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]); | 596 | llxor(r.limbs[0..], b.limbs[0..b.limbs.len], a.limbs[0..a.limbs.len]); |
| 595 | r.normalize(b.limbs.len); | 597 | r.normalize(b.limbs.len); |
| 596 | } | 598 | } |
| 599 | r.positive = a.positive or b.positive; | ||
| 597 | } | 600 | } |
| 598 | 601 | ||
| 599 | /// rma may alias x or y. | 602 | /// rma may alias x or y. |
src/Sema.zig+1-1| ... | @@ -7871,7 +7871,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -7871,7 +7871,7 @@ fn zirAtomicRmw(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 7871 | .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target), | 7871 | .Add => try stored_val.numberAddWrap(operand_val, operand_ty, sema.arena, target), |
| 7872 | .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target), | 7872 | .Sub => try stored_val.numberSubWrap(operand_val, operand_ty, sema.arena, target), |
| 7873 | .And => try stored_val.bitwiseAnd (operand_val, sema.arena), | 7873 | .And => try stored_val.bitwiseAnd (operand_val, sema.arena), |
| 7874 | .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena), | 7874 | .Nand => try stored_val.bitwiseNand (operand_val, operand_ty, sema.arena, target), |
| 7875 | .Or => try stored_val.bitwiseOr (operand_val, sema.arena), | 7875 | .Or => try stored_val.bitwiseOr (operand_val, sema.arena), |
| 7876 | .Xor => try stored_val.bitwiseXor (operand_val, sema.arena), | 7876 | .Xor => try stored_val.bitwiseXor (operand_val, sema.arena), |
| 7877 | .Max => try stored_val.numberMax (operand_val, sema.arena), | 7877 | .Max => try stored_val.numberMax (operand_val, sema.arena), |
src/value.zig+9-4| ... | @@ -1690,12 +1690,17 @@ pub const Value = extern union { | ... | @@ -1690,12 +1690,17 @@ pub const Value = extern union { |
| 1690 | } | 1690 | } |
| 1691 | 1691 | ||
| 1692 | /// operands must be integers; handles undefined. | 1692 | /// operands must be integers; handles undefined. |
| 1693 | pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: *Allocator) !Value { | 1693 | pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: *Allocator, target: Target) !Value { |
| 1694 | if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef); | 1694 | if (lhs.isUndef() or rhs.isUndef()) return Value.initTag(.undef); |
| 1695 | 1695 | ||
| 1696 | _ = ty; | 1696 | const anded = try bitwiseAnd(lhs, rhs, arena); |
| 1697 | _ = arena; | 1697 | |
| 1698 | @panic("TODO comptime bitwise NAND"); | 1698 | const all_ones = if (ty.isSignedInt()) |
| 1699 | try Value.Tag.int_i64.create(arena, -1) | ||
| 1700 | else | ||
| 1701 | try ty.maxInt(arena, target); | ||
| 1702 | |||
| 1703 | return bitwiseXor(anded, all_ones, arena); | ||
| 1699 | } | 1704 | } |
| 1700 | 1705 | ||
| 1701 | /// operands must be integers; handles undefined. | 1706 | /// operands must be integers; handles undefined. |
test/behavior/atomics.zig+28| ... | @@ -167,3 +167,31 @@ fn testAtomicRmwFloat() !void { | ... | @@ -167,3 +167,31 @@ fn testAtomicRmwFloat() !void { |
| 167 | _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst); | 167 | _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst); |
| 168 | try expect(x == 4); | 168 | try expect(x == 4); |
| 169 | } | 169 | } |
| 170 | |||
| 171 | test "atomicrmw with ints" { | ||
| 172 | try testAtomicRmwInt(); | ||
| 173 | comptime try testAtomicRmwInt(); | ||
| 174 | } | ||
| 175 | |||
| 176 | fn testAtomicRmwInt() !void { | ||
| 177 | var x: u8 = 1; | ||
| 178 | var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst); | ||
| 179 | try expect(x == 3 and res == 1); | ||
| 180 | _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst); | ||
| 181 | try expect(x == 6); | ||
| 182 | _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst); | ||
| 183 | try expect(x == 5); | ||
| 184 | _ = @atomicRmw(u8, &x, .And, 4, .SeqCst); | ||
| 185 | try expect(x == 4); | ||
| 186 | _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst); | ||
| 187 | try expect(x == 0xfb); | ||
| 188 | _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst); | ||
| 189 | try expect(x == 0xff); | ||
| 190 | _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst); | ||
| 191 | try expect(x == 0xfd); | ||
| 192 | |||
| 193 | _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst); | ||
| 194 | try expect(x == 0xfd); | ||
| 195 | _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst); | ||
| 196 | try expect(x == 1); | ||
| 197 | } |
test/behavior/atomics_stage1.zig+7-31| ... | @@ -3,39 +3,15 @@ const expect = std.testing.expect; | ... | @@ -3,39 +3,15 @@ const expect = std.testing.expect; |
| 3 | const expectEqual = std.testing.expectEqual; | 3 | const expectEqual = std.testing.expectEqual; |
| 4 | const builtin = @import("builtin"); | 4 | const builtin = @import("builtin"); |
| 5 | 5 | ||
| 6 | test "atomicrmw with ints" { | ||
| 7 | try testAtomicRmwInt(); | ||
| 8 | comptime try testAtomicRmwInt(); | ||
| 9 | } | ||
| 10 | |||
| 11 | fn testAtomicRmwInt() !void { | ||
| 12 | var x: u8 = 1; | ||
| 13 | var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst); | ||
| 14 | try expect(x == 3 and res == 1); | ||
| 15 | _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst); | ||
| 16 | try expect(x == 6); | ||
| 17 | _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst); | ||
| 18 | try expect(x == 5); | ||
| 19 | _ = @atomicRmw(u8, &x, .And, 4, .SeqCst); | ||
| 20 | try expect(x == 4); | ||
| 21 | _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst); | ||
| 22 | try expect(x == 0xfb); | ||
| 23 | _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst); | ||
| 24 | try expect(x == 0xff); | ||
| 25 | _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst); | ||
| 26 | try expect(x == 0xfd); | ||
| 27 | |||
| 28 | _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst); | ||
| 29 | try expect(x == 0xfd); | ||
| 30 | _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst); | ||
| 31 | try expect(x == 1); | ||
| 32 | } | ||
| 33 | |||
| 34 | test "atomics with different types" { | 6 | test "atomics with different types" { |
| 35 | try testAtomicsWithType(bool, true, false); | 7 | try testAtomicsWithType(bool, true, false); |
| 36 | inline for (.{ u1, i4, u5, i15, u24 }) |T| { | 8 | |
| 37 | try testAtomicsWithType(T, 0, 1); | 9 | try testAtomicsWithType(u1, 0, 1); |
| 38 | } | 10 | try testAtomicsWithType(i4, 0, 1); |
| 11 | try testAtomicsWithType(u5, 0, 1); | ||
| 12 | try testAtomicsWithType(i15, 0, 1); | ||
| 13 | try testAtomicsWithType(u24, 0, 1); | ||
| 14 | |||
| 39 | try testAtomicsWithType(u0, 0, 0); | 15 | try testAtomicsWithType(u0, 0, 0); |
| 40 | try testAtomicsWithType(i0, 0, 0); | 16 | try testAtomicsWithType(i0, 0, 0); |
| 41 | } | 17 | } |