| ... | ... | @@ -598,6 +598,8 @@ test "shr" { |
| 598 | 598 | pub fn rotr(comptime T: type, x: T, r: anytype) T { |
| 599 | 599 | if (@typeInfo(T) == .Vector) { |
| 600 | 600 | const C = @typeInfo(T).Vector.child; |
| 601 | if (C == u0) return 0; |
| 602 | |
| 601 | 603 | if (@typeInfo(C).Int.signedness == .signed) { |
| 602 | 604 | @compileError("cannot rotate signed integers"); |
| 603 | 605 | } |
| ... | ... | @@ -606,8 +608,15 @@ pub fn rotr(comptime T: type, x: T, r: anytype) T { |
| 606 | 608 | } else if (@typeInfo(T).Int.signedness == .signed) { |
| 607 | 609 | @compileError("cannot rotate signed integer"); |
| 608 | 610 | } else { |
| 609 | | const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits)); |
| 610 | | return x >> ar | x << (1 +% ~ar); |
| 611 | if (T == u0) return 0; |
| 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 | } |
| 613 | 622 | |
| ... | ... | @@ -618,6 +627,9 @@ test "rotr" { |
| 618 | 627 | // https://github.com/ziglang/zig/issues/12012 |
| 619 | 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 | 633 | try testing.expect(rotr(u8, 0b00000001, @as(usize, 0)) == 0b00000001); |
| 622 | 634 | try testing.expect(rotr(u8, 0b00000001, @as(usize, 9)) == 0b10000000); |
| 623 | 635 | try testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001); |
| ... | ... | @@ -632,6 +644,8 @@ test "rotr" { |
| 632 | 644 | pub fn rotl(comptime T: type, x: T, r: anytype) T { |
| 633 | 645 | if (@typeInfo(T) == .Vector) { |
| 634 | 646 | const C = @typeInfo(T).Vector.child; |
| 647 | if (C == u0) return 0; |
| 648 | |
| 635 | 649 | if (@typeInfo(C).Int.signedness == .signed) { |
| 636 | 650 | @compileError("cannot rotate signed integers"); |
| 637 | 651 | } |
| ... | ... | @@ -640,8 +654,15 @@ pub fn rotl(comptime T: type, x: T, r: anytype) T { |
| 640 | 654 | } else if (@typeInfo(T).Int.signedness == .signed) { |
| 641 | 655 | @compileError("cannot rotate signed integer"); |
| 642 | 656 | } else { |
| 643 | | const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits)); |
| 644 | | return x << ar | x >> 1 +% ~ar; |
| 657 | if (T == u0) return 0; |
| 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 | } |
| 647 | 668 | |
| ... | ... | @@ -652,6 +673,9 @@ test "rotl" { |
| 652 | 673 | // https://github.com/ziglang/zig/issues/12012 |
| 653 | 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 | 679 | try testing.expect(rotl(u8, 0b00000001, @as(usize, 0)) == 0b00000001); |
| 656 | 680 | try testing.expect(rotl(u8, 0b00000001, @as(usize, 9)) == 0b00000010); |
| 657 | 681 | try testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001); |