| author | |
| committer | |
| log | efdb94486b78fa143f8d684609cb4c5d3de10124 |
| tree | 23aa9a69b88c421ac03e94f1e6184a99abaeac50 |
| parent | 97c0373fa7ee125d2d4e73f9b1dc8ea0e2c2e86a |
- each byte gets masked, shifted and combined
- use boring masks instead of comptime for readability
- tests: bit patterns with reverse operation, if applicable
See #12906 files changed, 148 insertions(+), 0 deletions(-)
CMakeLists.txt+1| ... | @@ -446,6 +446,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -446,6 +446,7 @@ set(ZIG_STAGE2_SOURCES |
| 446 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt.zig" | 446 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt.zig" |
| 447 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/addXf3.zig" | 447 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/addXf3.zig" |
| 448 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/atomics.zig" | 448 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/atomics.zig" |
| 449 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/bswap.zig" | ||
| 449 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clear_cache.zig" | 450 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clear_cache.zig" |
| 450 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/compareXf2.zig" | 451 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/compareXf2.zig" |
| 451 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/count0bits.zig" | 452 | "${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/count0bits.zig" |
lib/std/special/compiler_rt.zig+6| ... | @@ -263,6 +263,12 @@ comptime { | ... | @@ -263,6 +263,12 @@ comptime { |
| 263 | @export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage }); | 263 | @export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage }); |
| 264 | const __popcountti2 = @import("compiler_rt/popcount.zig").__popcountti2; | 264 | const __popcountti2 = @import("compiler_rt/popcount.zig").__popcountti2; |
| 265 | @export(__popcountti2, .{ .name = "__popcountti2", .linkage = linkage }); | 265 | @export(__popcountti2, .{ .name = "__popcountti2", .linkage = linkage }); |
| 266 | const __bswapsi2 = @import("compiler_rt/bswap.zig").__bswapsi2; | ||
| 267 | @export(__bswapsi2, .{ .name = "__bswapsi2", .linkage = linkage }); | ||
| 268 | const __bswapdi2 = @import("compiler_rt/bswap.zig").__bswapdi2; | ||
| 269 | @export(__bswapdi2, .{ .name = "__bswapdi2", .linkage = linkage }); | ||
| 270 | const __bswapti2 = @import("compiler_rt/bswap.zig").__bswapti2; | ||
| 271 | @export(__bswapti2, .{ .name = "__bswapti2", .linkage = linkage }); | ||
| 266 | 272 | ||
| 267 | // Integral / floating point conversion (part 1/2) | 273 | // Integral / floating point conversion (part 1/2) |
| 268 | const __floatsidf = @import("compiler_rt/floatsiXf.zig").__floatsidf; | 274 | const __floatsidf = @import("compiler_rt/floatsiXf.zig").__floatsidf; |
lib/std/special/compiler_rt/bswap.zig created+78| ... | @@ -0,0 +1,78 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | |||
| 4 | // bswap - byteswap | ||
| 5 | // - bswapXi2_generic for unoptimized big and little endian | ||
| 6 | // ie for u32 | ||
| 7 | // DE AD BE EF <- little|big endian | ||
| 8 | // FE BE AD DE <- big|little endian | ||
| 9 | // ie for u32 | ||
| 10 | // ff 00 00 00 >> 3*8 (leftmost byte) | ||
| 11 | // 00 ff 00 00 >> 1*8 (2nd left byte) | ||
| 12 | // 00 00 ff 00 << 1*8 (2n right byte) | ||
| 13 | // 00 00 00 ff << 3*8 (rightmost byte) | ||
| 14 | |||
| 15 | fn bswapXi2_generic(comptime T: type) fn (a: T) callconv(.C) T { | ||
| 16 | return struct { | ||
| 17 | fn f(a: T) callconv(.C) T { | ||
| 18 | @setRuntimeSafety(builtin.is_test); | ||
| 19 | switch (@bitSizeOf(T)) { | ||
| 20 | 32 => { | ||
| 21 | // zig fmt: off | ||
| 22 | return (((a & 0xff000000) >> 24) | ||
| 23 | | ((a & 0x00ff0000) >> 8 ) | ||
| 24 | | ((a & 0x0000ff00) << 8 ) | ||
| 25 | | ((a & 0x000000ff) << 24)); | ||
| 26 | // zig fmt: on | ||
| 27 | }, | ||
| 28 | 64 => { | ||
| 29 | // zig fmt: off | ||
| 30 | return (((a & 0xff00000000000000) >> 56) | ||
| 31 | | ((a & 0x00ff000000000000) >> 40 ) | ||
| 32 | | ((a & 0x0000ff0000000000) >> 24 ) | ||
| 33 | | ((a & 0x000000ff00000000) >> 8 ) | ||
| 34 | | ((a & 0x00000000ff000000) << 8 ) | ||
| 35 | | ((a & 0x0000000000ff0000) << 24 ) | ||
| 36 | | ((a & 0x000000000000ff00) << 40 ) | ||
| 37 | | ((a & 0x00000000000000ff) << 56)); | ||
| 38 | // zig fmt: on | ||
| 39 | }, | ||
| 40 | 128 => { | ||
| 41 | // zig fmt: off | ||
| 42 | return (((a & 0xff000000000000000000000000000000) >> 120) | ||
| 43 | | ((a & 0x00ff0000000000000000000000000000) >> 104) | ||
| 44 | | ((a & 0x0000ff00000000000000000000000000) >> 88 ) | ||
| 45 | | ((a & 0x000000ff000000000000000000000000) >> 72 ) | ||
| 46 | | ((a & 0x00000000ff0000000000000000000000) >> 56 ) | ||
| 47 | | ((a & 0x0000000000ff00000000000000000000) >> 40 ) | ||
| 48 | | ((a & 0x000000000000ff000000000000000000) >> 24 ) | ||
| 49 | | ((a & 0x00000000000000ff0000000000000000) >> 8 ) | ||
| 50 | | ((a & 0x0000000000000000ff00000000000000) << 8 ) | ||
| 51 | | ((a & 0x000000000000000000ff000000000000) << 24 ) | ||
| 52 | | ((a & 0x00000000000000000000ff0000000000) << 40 ) | ||
| 53 | | ((a & 0x0000000000000000000000ff00000000) << 56 ) | ||
| 54 | | ((a & 0x000000000000000000000000ff000000) << 72 ) | ||
| 55 | | ((a & 0x00000000000000000000000000ff0000) << 88 ) | ||
| 56 | | ((a & 0x0000000000000000000000000000ff00) << 104) | ||
| 57 | | ((a & 0x000000000000000000000000000000ff) << 120)); | ||
| 58 | // zig fmt: on | ||
| 59 | }, | ||
| 60 | else => { | ||
| 61 | unreachable; | ||
| 62 | }, | ||
| 63 | } | ||
| 64 | } | ||
| 65 | }.f; | ||
| 66 | } | ||
| 67 | |||
| 68 | pub const __bswapsi2 = bswapXi2_generic(u32); | ||
| 69 | |||
| 70 | pub const __bswapdi2 = bswapXi2_generic(u64); | ||
| 71 | |||
| 72 | pub const __bswapti2 = bswapXi2_generic(u128); | ||
| 73 | |||
| 74 | test { | ||
| 75 | _ = @import("bswapsi2_test.zig"); | ||
| 76 | _ = @import("bswapdi2_test.zig"); | ||
| 77 | _ = @import("bswapti2_test.zig"); | ||
| 78 | } | ||
lib/std/special/compiler_rt/bswapdi2_test.zig created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | const bswap = @import("bswap.zig"); | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__bswapdi2(a: u64, expected: u64) !void { | ||
| 5 | var result = bswap.__bswapdi2(a); | ||
| 6 | try testing.expectEqual(expected, result); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "bswapdi2" { | ||
| 10 | try test__bswapdi2(0x0123456789abcdef, 0xefcdab8967452301); // 0..f | ||
| 11 | try test__bswapdi2(0xefcdab8967452301, 0x0123456789abcdef); | ||
| 12 | try test__bswapdi2(0x89abcdef01234567, 0x67452301efcdab89); // 8..f0..7 | ||
| 13 | try test__bswapdi2(0x67452301efcdab89, 0x89abcdef01234567); | ||
| 14 | try test__bswapdi2(0xdeadbeefdeadbeef, 0xefbeaddeefbeadde); // deadbeefdeadbeef | ||
| 15 | try test__bswapdi2(0xefbeaddeefbeadde, 0xdeadbeefdeadbeef); | ||
| 16 | try test__bswapdi2(0xdeadfacedeadface, 0xcefaaddecefaadde); // deadfacedeadface | ||
| 17 | try test__bswapdi2(0xcefaaddecefaadde, 0xdeadfacedeadface); | ||
| 18 | try test__bswapdi2(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa); // uninitialized memory | ||
| 19 | try test__bswapdi2(0x0000000000000000, 0x0000000000000000); // 0s | ||
| 20 | try test__bswapdi2(0xffffffffffffffff, 0xffffffffffffffff); // fs | ||
| 21 | } | ||
lib/std/special/compiler_rt/bswapsi2_test.zig created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | const bswap = @import("bswap.zig"); | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__bswapsi2(a: u32, expected: u32) !void { | ||
| 5 | var result = bswap.__bswapsi2(a); | ||
| 6 | try testing.expectEqual(expected, result); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "bswapsi2" { | ||
| 10 | try test__bswapsi2(0x01234567, 0x67452301); // 0..7 | ||
| 11 | try test__bswapsi2(0x67452301, 0x01234567); | ||
| 12 | try test__bswapsi2(0x89abcdef, 0xefcdab89); // 8..f | ||
| 13 | try test__bswapsi2(0xefcdab89, 0x89abcdef); | ||
| 14 | try test__bswapsi2(0xdeadbeef, 0xefbeadde); // deadbeef | ||
| 15 | try test__bswapsi2(0xefbeadde, 0xdeadbeef); | ||
| 16 | try test__bswapsi2(0xdeadface, 0xcefaadde); // deadface | ||
| 17 | try test__bswapsi2(0xcefaadde, 0xdeadface); | ||
| 18 | try test__bswapsi2(0xaaaaaaaa, 0xaaaaaaaa); // uninitialized memory | ||
| 19 | try test__bswapsi2(0x00000000, 0x00000000); // 0s | ||
| 20 | try test__bswapsi2(0xffffffff, 0xffffffff); // fs | ||
| 21 | } | ||
lib/std/special/compiler_rt/bswapti2_test.zig created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | const bswap = @import("bswap.zig"); | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__bswapti2(a: u128, expected: u128) !void { | ||
| 5 | var result = bswap.__bswapti2(a); | ||
| 6 | try testing.expectEqual(expected, result); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "bswapti2" { | ||
| 10 | try test__bswapti2(0x0123456789abcdef0123456789abcdef, 0xefcdab8967452301efcdab8967452301); // 0..f | ||
| 11 | try test__bswapti2(0xefcdab8967452301efcdab8967452301, 0x0123456789abcdef0123456789abcdef); | ||
| 12 | try test__bswapti2(0x89abcdef0123456789abcdef01234567, 0x67452301efcdab8967452301efcdab89); // 8..f0..7 | ||
| 13 | try test__bswapti2(0x67452301efcdab8967452301efcdab89, 0x89abcdef0123456789abcdef01234567); | ||
| 14 | try test__bswapti2(0xdeadbeefdeadbeefdeadbeefdeadbeef, 0xefbeaddeefbeaddeefbeaddeefbeadde); // deadbeefdeadbeef | ||
| 15 | try test__bswapti2(0xefbeaddeefbeaddeefbeaddeefbeadde, 0xdeadbeefdeadbeefdeadbeefdeadbeef); | ||
| 16 | try test__bswapti2(0xdeadfacedeadfacedeadfacedeadface, 0xcefaaddecefaaddecefaaddecefaadde); // deadfacedeadface | ||
| 17 | try test__bswapti2(0xcefaaddecefaaddecefaaddecefaadde, 0xdeadfacedeadfacedeadfacedeadface); | ||
| 18 | try test__bswapti2(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa); // uninitialized memory | ||
| 19 | try test__bswapti2(0x00000000000000000000000000000000, 0x00000000000000000000000000000000); // 0s | ||
| 20 | try test__bswapti2(0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff); // fs | ||
| 21 | } | ||