mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
compiler_rt: add __bswapsi2, __bswapdi2 and __bswapti2
- each byte gets masked, shifted and combined - use boring masks instead of comptime for readability - tests: bit patterns with reverse operation, if applicable See #1290
This commit is contained in:
parent
97c0373fa7
commit
efdb94486b
@ -446,6 +446,7 @@ set(ZIG_STAGE2_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/addXf3.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/atomics.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/bswap.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/clear_cache.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/compareXf2.zig"
|
||||
"${CMAKE_SOURCE_DIR}/lib/std/special/compiler_rt/count0bits.zig"
|
||||
|
||||
@ -263,6 +263,12 @@ comptime {
|
||||
@export(__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
|
||||
const __popcountti2 = @import("compiler_rt/popcount.zig").__popcountti2;
|
||||
@export(__popcountti2, .{ .name = "__popcountti2", .linkage = linkage });
|
||||
const __bswapsi2 = @import("compiler_rt/bswap.zig").__bswapsi2;
|
||||
@export(__bswapsi2, .{ .name = "__bswapsi2", .linkage = linkage });
|
||||
const __bswapdi2 = @import("compiler_rt/bswap.zig").__bswapdi2;
|
||||
@export(__bswapdi2, .{ .name = "__bswapdi2", .linkage = linkage });
|
||||
const __bswapti2 = @import("compiler_rt/bswap.zig").__bswapti2;
|
||||
@export(__bswapti2, .{ .name = "__bswapti2", .linkage = linkage });
|
||||
|
||||
// Integral / floating point conversion (part 1/2)
|
||||
const __floatsidf = @import("compiler_rt/floatsiXf.zig").__floatsidf;
|
||||
|
||||
78
lib/std/special/compiler_rt/bswap.zig
Normal file
78
lib/std/special/compiler_rt/bswap.zig
Normal file
@ -0,0 +1,78 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
// bswap - byteswap
|
||||
// - bswapXi2_generic for unoptimized big and little endian
|
||||
// ie for u32
|
||||
// DE AD BE EF <- little|big endian
|
||||
// FE BE AD DE <- big|little endian
|
||||
// ie for u32
|
||||
// ff 00 00 00 >> 3*8 (leftmost byte)
|
||||
// 00 ff 00 00 >> 1*8 (2nd left byte)
|
||||
// 00 00 ff 00 << 1*8 (2n right byte)
|
||||
// 00 00 00 ff << 3*8 (rightmost byte)
|
||||
|
||||
fn bswapXi2_generic(comptime T: type) fn (a: T) callconv(.C) T {
|
||||
return struct {
|
||||
fn f(a: T) callconv(.C) T {
|
||||
@setRuntimeSafety(builtin.is_test);
|
||||
switch (@bitSizeOf(T)) {
|
||||
32 => {
|
||||
// zig fmt: off
|
||||
return (((a & 0xff000000) >> 24)
|
||||
| ((a & 0x00ff0000) >> 8 )
|
||||
| ((a & 0x0000ff00) << 8 )
|
||||
| ((a & 0x000000ff) << 24));
|
||||
// zig fmt: on
|
||||
},
|
||||
64 => {
|
||||
// zig fmt: off
|
||||
return (((a & 0xff00000000000000) >> 56)
|
||||
| ((a & 0x00ff000000000000) >> 40 )
|
||||
| ((a & 0x0000ff0000000000) >> 24 )
|
||||
| ((a & 0x000000ff00000000) >> 8 )
|
||||
| ((a & 0x00000000ff000000) << 8 )
|
||||
| ((a & 0x0000000000ff0000) << 24 )
|
||||
| ((a & 0x000000000000ff00) << 40 )
|
||||
| ((a & 0x00000000000000ff) << 56));
|
||||
// zig fmt: on
|
||||
},
|
||||
128 => {
|
||||
// zig fmt: off
|
||||
return (((a & 0xff000000000000000000000000000000) >> 120)
|
||||
| ((a & 0x00ff0000000000000000000000000000) >> 104)
|
||||
| ((a & 0x0000ff00000000000000000000000000) >> 88 )
|
||||
| ((a & 0x000000ff000000000000000000000000) >> 72 )
|
||||
| ((a & 0x00000000ff0000000000000000000000) >> 56 )
|
||||
| ((a & 0x0000000000ff00000000000000000000) >> 40 )
|
||||
| ((a & 0x000000000000ff000000000000000000) >> 24 )
|
||||
| ((a & 0x00000000000000ff0000000000000000) >> 8 )
|
||||
| ((a & 0x0000000000000000ff00000000000000) << 8 )
|
||||
| ((a & 0x000000000000000000ff000000000000) << 24 )
|
||||
| ((a & 0x00000000000000000000ff0000000000) << 40 )
|
||||
| ((a & 0x0000000000000000000000ff00000000) << 56 )
|
||||
| ((a & 0x000000000000000000000000ff000000) << 72 )
|
||||
| ((a & 0x00000000000000000000000000ff0000) << 88 )
|
||||
| ((a & 0x0000000000000000000000000000ff00) << 104)
|
||||
| ((a & 0x000000000000000000000000000000ff) << 120));
|
||||
// zig fmt: on
|
||||
},
|
||||
else => {
|
||||
unreachable;
|
||||
},
|
||||
}
|
||||
}
|
||||
}.f;
|
||||
}
|
||||
|
||||
pub const __bswapsi2 = bswapXi2_generic(u32);
|
||||
|
||||
pub const __bswapdi2 = bswapXi2_generic(u64);
|
||||
|
||||
pub const __bswapti2 = bswapXi2_generic(u128);
|
||||
|
||||
test {
|
||||
_ = @import("bswapsi2_test.zig");
|
||||
_ = @import("bswapdi2_test.zig");
|
||||
_ = @import("bswapti2_test.zig");
|
||||
}
|
||||
21
lib/std/special/compiler_rt/bswapdi2_test.zig
Normal file
21
lib/std/special/compiler_rt/bswapdi2_test.zig
Normal file
@ -0,0 +1,21 @@
|
||||
const bswap = @import("bswap.zig");
|
||||
const testing = @import("std").testing;
|
||||
|
||||
fn test__bswapdi2(a: u64, expected: u64) !void {
|
||||
var result = bswap.__bswapdi2(a);
|
||||
try testing.expectEqual(expected, result);
|
||||
}
|
||||
|
||||
test "bswapdi2" {
|
||||
try test__bswapdi2(0x0123456789abcdef, 0xefcdab8967452301); // 0..f
|
||||
try test__bswapdi2(0xefcdab8967452301, 0x0123456789abcdef);
|
||||
try test__bswapdi2(0x89abcdef01234567, 0x67452301efcdab89); // 8..f0..7
|
||||
try test__bswapdi2(0x67452301efcdab89, 0x89abcdef01234567);
|
||||
try test__bswapdi2(0xdeadbeefdeadbeef, 0xefbeaddeefbeadde); // deadbeefdeadbeef
|
||||
try test__bswapdi2(0xefbeaddeefbeadde, 0xdeadbeefdeadbeef);
|
||||
try test__bswapdi2(0xdeadfacedeadface, 0xcefaaddecefaadde); // deadfacedeadface
|
||||
try test__bswapdi2(0xcefaaddecefaadde, 0xdeadfacedeadface);
|
||||
try test__bswapdi2(0xaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaa); // uninitialized memory
|
||||
try test__bswapdi2(0x0000000000000000, 0x0000000000000000); // 0s
|
||||
try test__bswapdi2(0xffffffffffffffff, 0xffffffffffffffff); // fs
|
||||
}
|
||||
21
lib/std/special/compiler_rt/bswapsi2_test.zig
Normal file
21
lib/std/special/compiler_rt/bswapsi2_test.zig
Normal file
@ -0,0 +1,21 @@
|
||||
const bswap = @import("bswap.zig");
|
||||
const testing = @import("std").testing;
|
||||
|
||||
fn test__bswapsi2(a: u32, expected: u32) !void {
|
||||
var result = bswap.__bswapsi2(a);
|
||||
try testing.expectEqual(expected, result);
|
||||
}
|
||||
|
||||
test "bswapsi2" {
|
||||
try test__bswapsi2(0x01234567, 0x67452301); // 0..7
|
||||
try test__bswapsi2(0x67452301, 0x01234567);
|
||||
try test__bswapsi2(0x89abcdef, 0xefcdab89); // 8..f
|
||||
try test__bswapsi2(0xefcdab89, 0x89abcdef);
|
||||
try test__bswapsi2(0xdeadbeef, 0xefbeadde); // deadbeef
|
||||
try test__bswapsi2(0xefbeadde, 0xdeadbeef);
|
||||
try test__bswapsi2(0xdeadface, 0xcefaadde); // deadface
|
||||
try test__bswapsi2(0xcefaadde, 0xdeadface);
|
||||
try test__bswapsi2(0xaaaaaaaa, 0xaaaaaaaa); // uninitialized memory
|
||||
try test__bswapsi2(0x00000000, 0x00000000); // 0s
|
||||
try test__bswapsi2(0xffffffff, 0xffffffff); // fs
|
||||
}
|
||||
21
lib/std/special/compiler_rt/bswapti2_test.zig
Normal file
21
lib/std/special/compiler_rt/bswapti2_test.zig
Normal file
@ -0,0 +1,21 @@
|
||||
const bswap = @import("bswap.zig");
|
||||
const testing = @import("std").testing;
|
||||
|
||||
fn test__bswapti2(a: u128, expected: u128) !void {
|
||||
var result = bswap.__bswapti2(a);
|
||||
try testing.expectEqual(expected, result);
|
||||
}
|
||||
|
||||
test "bswapti2" {
|
||||
try test__bswapti2(0x0123456789abcdef0123456789abcdef, 0xefcdab8967452301efcdab8967452301); // 0..f
|
||||
try test__bswapti2(0xefcdab8967452301efcdab8967452301, 0x0123456789abcdef0123456789abcdef);
|
||||
try test__bswapti2(0x89abcdef0123456789abcdef01234567, 0x67452301efcdab8967452301efcdab89); // 8..f0..7
|
||||
try test__bswapti2(0x67452301efcdab8967452301efcdab89, 0x89abcdef0123456789abcdef01234567);
|
||||
try test__bswapti2(0xdeadbeefdeadbeefdeadbeefdeadbeef, 0xefbeaddeefbeaddeefbeaddeefbeadde); // deadbeefdeadbeef
|
||||
try test__bswapti2(0xefbeaddeefbeaddeefbeaddeefbeadde, 0xdeadbeefdeadbeefdeadbeefdeadbeef);
|
||||
try test__bswapti2(0xdeadfacedeadfacedeadfacedeadface, 0xcefaaddecefaaddecefaaddecefaadde); // deadfacedeadface
|
||||
try test__bswapti2(0xcefaaddecefaaddecefaaddecefaadde, 0xdeadfacedeadfacedeadfacedeadface);
|
||||
try test__bswapti2(0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa); // uninitialized memory
|
||||
try test__bswapti2(0x00000000000000000000000000000000, 0x00000000000000000000000000000000); // 0s
|
||||
try test__bswapti2(0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff); // fs
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user