authorgravatar for rekai@musuka.devRekai Nyangadzayi Musuka <rekai@musuka.dev> 2022-10-10 18:22:35-03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-10-11 00:22:35+03:00
logdacdc95ea24c12e2f1771f928ffa4bbd18cc3a19
tree9bef8812cafba9d79c9672a2beb3560a70e64755
parent02fff6fd0172502545389dcf335b173b4f951dda
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std/math.zig: use previous rotate code with non-power-of-two integers


1 files changed, 28 insertions(+), 4 deletions(-)

lib/std/math.zig+28-4
...@@ -598,6 +598,8 @@ test "shr" {...@@ -598,6 +598,8 @@ test "shr" {
598pub fn rotr(comptime T: type, x: T, r: anytype) T {598pub fn rotr(comptime T: type, x: T, r: anytype) T {
599 if (@typeInfo(T) == .Vector) {599 if (@typeInfo(T) == .Vector) {
600 const C = @typeInfo(T).Vector.child;600 const C = @typeInfo(T).Vector.child;
601 if (C == u0) return 0;
602
601 if (@typeInfo(C).Int.signedness == .signed) {603 if (@typeInfo(C).Int.signedness == .signed) {
602 @compileError("cannot rotate signed integers");604 @compileError("cannot rotate signed integers");
603 }605 }
...@@ -606,8 +608,15 @@ pub fn rotr(comptime T: type, x: T, r: anytype) T {...@@ -606,8 +608,15 @@ pub fn rotr(comptime T: type, x: T, r: anytype) T {
606 } else if (@typeInfo(T).Int.signedness == .signed) {608 } else if (@typeInfo(T).Int.signedness == .signed) {
607 @compileError("cannot rotate signed integer");609 @compileError("cannot rotate signed integer");
608 } else {610 } else {
609 const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits));611 if (T == u0) return 0;
610 return x >> ar | x << (1 +% ~ar);612
613 if (isPowerOfTwo(@typeInfo(T).Int.bits)) {
614 const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits));
615 return x >> ar | x << (1 +% ~ar);
616 } else {
617 const ar = @mod(r, @typeInfo(T).Int.bits);
618 return shr(T, x, ar) | shl(T, x, @typeInfo(T).Int.bits - ar);
619 }
611 }620 }
612}621}
613622
...@@ -618,6 +627,9 @@ test "rotr" {...@@ -618,6 +627,9 @@ test "rotr" {
618 // https://github.com/ziglang/zig/issues/12012627 // https://github.com/ziglang/zig/issues/12012
619 return error.SkipZigTest;628 return error.SkipZigTest;
620 }629 }
630 try testing.expect(rotr(u0, 0b0, @as(usize, 3)) == 0b0);
631 try testing.expect(rotr(u5, 0b00001, @as(usize, 0)) == 0b00001);
632 try testing.expect(rotr(u6, 0b000001, @as(usize, 7)) == 0b100000);
621 try testing.expect(rotr(u8, 0b00000001, @as(usize, 0)) == 0b00000001);633 try testing.expect(rotr(u8, 0b00000001, @as(usize, 0)) == 0b00000001);
622 try testing.expect(rotr(u8, 0b00000001, @as(usize, 9)) == 0b10000000);634 try testing.expect(rotr(u8, 0b00000001, @as(usize, 9)) == 0b10000000);
623 try testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001);635 try testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001);
...@@ -632,6 +644,8 @@ test "rotr" {...@@ -632,6 +644,8 @@ test "rotr" {
632pub fn rotl(comptime T: type, x: T, r: anytype) T {644pub fn rotl(comptime T: type, x: T, r: anytype) T {
633 if (@typeInfo(T) == .Vector) {645 if (@typeInfo(T) == .Vector) {
634 const C = @typeInfo(T).Vector.child;646 const C = @typeInfo(T).Vector.child;
647 if (C == u0) return 0;
648
635 if (@typeInfo(C).Int.signedness == .signed) {649 if (@typeInfo(C).Int.signedness == .signed) {
636 @compileError("cannot rotate signed integers");650 @compileError("cannot rotate signed integers");
637 }651 }
...@@ -640,8 +654,15 @@ pub fn rotl(comptime T: type, x: T, r: anytype) T {...@@ -640,8 +654,15 @@ pub fn rotl(comptime T: type, x: T, r: anytype) T {
640 } else if (@typeInfo(T).Int.signedness == .signed) {654 } else if (@typeInfo(T).Int.signedness == .signed) {
641 @compileError("cannot rotate signed integer");655 @compileError("cannot rotate signed integer");
642 } else {656 } else {
643 const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits));657 if (T == u0) return 0;
644 return x << ar | x >> 1 +% ~ar;658
659 if (isPowerOfTwo(@typeInfo(T).Int.bits)) {
660 const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits));
661 return x << ar | x >> 1 +% ~ar;
662 } else {
663 const ar = @mod(r, @typeInfo(T).Int.bits);
664 return shl(T, x, ar) | shr(T, x, @typeInfo(T).Int.bits - ar);
665 }
645 }666 }
646}667}
647668
...@@ -652,6 +673,9 @@ test "rotl" {...@@ -652,6 +673,9 @@ test "rotl" {
652 // https://github.com/ziglang/zig/issues/12012673 // https://github.com/ziglang/zig/issues/12012
653 return error.SkipZigTest;674 return error.SkipZigTest;
654 }675 }
676 try testing.expect(rotl(u0, 0b0, @as(usize, 3)) == 0b0);
677 try testing.expect(rotl(u5, 0b00001, @as(usize, 0)) == 0b00001);
678 try testing.expect(rotl(u6, 0b000001, @as(usize, 7)) == 0b000010);
655 try testing.expect(rotl(u8, 0b00000001, @as(usize, 0)) == 0b00000001);679 try testing.expect(rotl(u8, 0b00000001, @as(usize, 0)) == 0b00000001);
656 try testing.expect(rotl(u8, 0b00000001, @as(usize, 9)) == 0b00000010);680 try testing.expect(rotl(u8, 0b00000001, @as(usize, 9)) == 0b00000010);
657 try testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001);681 try testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001);