| author | |
| committer | |
| log | 1ef6f068f57d1e0075c695149494420a4e387c7e |
| tree | 8d708e589e3cd387103f4483e033147c52fb3044 |
| parent | 9bc8a1e1d0a032e2666e2a5420211cc4b052de56 |
* Unify all the code paths with a generic function
* Add some EABI aliases
Closes #485311 files changed, 288 insertions(+), 135 deletions(-)
lib/std/special/compiler_rt.zig+10-3| ... | @@ -69,9 +69,12 @@ comptime { | ... | @@ -69,9 +69,12 @@ comptime { |
| 69 | @export(@import("compiler_rt/divdf3.zig").__divdf3, .{ .name = "__divdf3", .linkage = linkage }); | 69 | @export(@import("compiler_rt/divdf3.zig").__divdf3, .{ .name = "__divdf3", .linkage = linkage }); |
| 70 | @export(@import("compiler_rt/divtf3.zig").__divtf3, .{ .name = "__divtf3", .linkage = linkage }); | 70 | @export(@import("compiler_rt/divtf3.zig").__divtf3, .{ .name = "__divtf3", .linkage = linkage }); |
| 71 | 71 | ||
| 72 | @export(@import("compiler_rt/ashlti3.zig").__ashlti3, .{ .name = "__ashlti3", .linkage = linkage }); | 72 | @export(@import("compiler_rt/shift.zig").__ashldi3, .{ .name = "__ashldi3", .linkage = linkage }); |
| 73 | @export(@import("compiler_rt/lshrti3.zig").__lshrti3, .{ .name = "__lshrti3", .linkage = linkage }); | 73 | @export(@import("compiler_rt/shift.zig").__ashlti3, .{ .name = "__ashlti3", .linkage = linkage }); |
| 74 | @export(@import("compiler_rt/ashrti3.zig").__ashrti3, .{ .name = "__ashrti3", .linkage = linkage }); | 74 | @export(@import("compiler_rt/shift.zig").__ashrdi3, .{ .name = "__ashrdi3", .linkage = linkage }); |
| 75 | @export(@import("compiler_rt/shift.zig").__ashrti3, .{ .name = "__ashrti3", .linkage = linkage }); | ||
| 76 | @export(@import("compiler_rt/shift.zig").__lshrdi3, .{ .name = "__lshrdi3", .linkage = linkage }); | ||
| 77 | @export(@import("compiler_rt/shift.zig").__lshrti3, .{ .name = "__lshrti3", .linkage = linkage }); | ||
| 75 | 78 | ||
| 76 | @export(@import("compiler_rt/floatsiXf.zig").__floatsidf, .{ .name = "__floatsidf", .linkage = linkage }); | 79 | @export(@import("compiler_rt/floatsiXf.zig").__floatsidf, .{ .name = "__floatsidf", .linkage = linkage }); |
| 77 | @export(@import("compiler_rt/floatsiXf.zig").__floatsisf, .{ .name = "__floatsisf", .linkage = linkage }); | 80 | @export(@import("compiler_rt/floatsiXf.zig").__floatsisf, .{ .name = "__floatsisf", .linkage = linkage }); |
| ... | @@ -229,6 +232,10 @@ comptime { | ... | @@ -229,6 +232,10 @@ comptime { |
| 229 | @export(@import("compiler_rt/divsf3.zig").__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = linkage }); | 232 | @export(@import("compiler_rt/divsf3.zig").__aeabi_fdiv, .{ .name = "__aeabi_fdiv", .linkage = linkage }); |
| 230 | @export(@import("compiler_rt/divdf3.zig").__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = linkage }); | 233 | @export(@import("compiler_rt/divdf3.zig").__aeabi_ddiv, .{ .name = "__aeabi_ddiv", .linkage = linkage }); |
| 231 | 234 | ||
| 235 | @export(@import("compiler_rt/shift.zig").__aeabi_llsl, .{ .name = "__aeabi_llsl", .linkage = linkage }); | ||
| 236 | @export(@import("compiler_rt/shift.zig").__aeabi_lasr, .{ .name = "__aeabi_lasr", .linkage = linkage }); | ||
| 237 | @export(@import("compiler_rt/shift.zig").__aeabi_llsr, .{ .name = "__aeabi_llsr", .linkage = linkage }); | ||
| 238 | |||
| 232 | @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage }); | 239 | @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmpeq, .{ .name = "__aeabi_fcmpeq", .linkage = linkage }); |
| 233 | @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage }); | 240 | @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmplt, .{ .name = "__aeabi_fcmplt", .linkage = linkage }); |
| 234 | @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage }); | 241 | @export(@import("compiler_rt/compareXf2.zig").__aeabi_fcmple, .{ .name = "__aeabi_fcmple", .linkage = linkage }); |
lib/std/special/compiler_rt/ashldi3_test.zig created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | const __ashldi3 = @import("shift.zig").__ashldi3; | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__ashldi3(a: i64, b: i32, expected: u64) void { | ||
| 5 | const x = __ashldi3(a, b); | ||
| 6 | testing.expectEqual(@bitCast(i64, expected), x); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "ashldi3" { | ||
| 10 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 0, 0x123456789ABCDEF); | ||
| 11 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 1, 0x2468ACF13579BDE); | ||
| 12 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 2, 0x48D159E26AF37BC); | ||
| 13 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 3, 0x91A2B3C4D5E6F78); | ||
| 14 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 4, 0x123456789ABCDEF0); | ||
| 15 | |||
| 16 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 28, 0x789ABCDEF0000000); | ||
| 17 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 29, 0xF13579BDE0000000); | ||
| 18 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 30, 0xE26AF37BC0000000); | ||
| 19 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 31, 0xC4D5E6F780000000); | ||
| 20 | |||
| 21 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 32, 0x89ABCDEF00000000); | ||
| 22 | |||
| 23 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 33, 0x13579BDE00000000); | ||
| 24 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 34, 0x26AF37BC00000000); | ||
| 25 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 35, 0x4D5E6F7800000000); | ||
| 26 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 36, 0x9ABCDEF000000000); | ||
| 27 | |||
| 28 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 60, 0xF000000000000000); | ||
| 29 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 61, 0xE000000000000000); | ||
| 30 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 62, 0xC000000000000000); | ||
| 31 | test__ashldi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 63, 0x8000000000000000); | ||
| 32 | } | ||
lib/std/special/compiler_rt/ashlti3.zig deleted-41| ... | @@ -1,41 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | |||
| 4 | pub fn __ashlti3(a: i128, b: i32) callconv(.C) i128 { | ||
| 5 | var input = twords{ .all = a }; | ||
| 6 | var result: twords = undefined; | ||
| 7 | |||
| 8 | if (b > 63) { | ||
| 9 | // 64 <= b < 128 | ||
| 10 | result.s.low = 0; | ||
| 11 | result.s.high = input.s.low << @intCast(u6, b - 64); | ||
| 12 | } else { | ||
| 13 | // 0 <= b < 64 | ||
| 14 | if (b == 0) return a; | ||
| 15 | result.s.low = input.s.low << @intCast(u6, b); | ||
| 16 | result.s.high = input.s.low >> @intCast(u6, 64 - b); | ||
| 17 | result.s.high |= input.s.high << @intCast(u6, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | return result.all; | ||
| 21 | } | ||
| 22 | |||
| 23 | const twords = extern union { | ||
| 24 | all: i128, | ||
| 25 | s: S, | ||
| 26 | |||
| 27 | const S = if (builtin.endian == .Little) | ||
| 28 | struct { | ||
| 29 | low: u64, | ||
| 30 | high: u64, | ||
| 31 | } | ||
| 32 | else | ||
| 33 | struct { | ||
| 34 | high: u64, | ||
| 35 | low: u64, | ||
| 36 | }; | ||
| 37 | }; | ||
| 38 | |||
| 39 | test "import ashlti3" { | ||
| 40 | _ = @import("ashlti3_test.zig"); | ||
| 41 | } | ||
lib/std/special/compiler_rt/ashlti3_test.zig+2-2| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | const __ashlti3 = @import("ashlti3.zig").__ashlti3; | 1 | const __ashlti3 = @import("shift.zig").__ashlti3; |
| 2 | const testing = @import("std").testing; | 2 | const testing = @import("std").testing; |
| 3 | 3 | ||
| 4 | fn test__ashlti3(a: i128, b: i32, expected: i128) void { | 4 | fn test__ashlti3(a: i128, b: i32, expected: i128) void { |
| 5 | const x = __ashlti3(a, b); | 5 | const x = __ashlti3(a, b); |
| 6 | testing.expect(x == expected); | 6 | testing.expectEqual(expected, x); |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | test "ashlti3" { | 9 | test "ashlti3" { |
lib/std/special/compiler_rt/ashrdi3_test.zig created+55| ... | @@ -0,0 +1,55 @@ | ||
| 1 | const __ashrdi3 = @import("shift.zig").__ashrdi3; | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__ashrdi3(a: i64, b: i32, expected: u64) void { | ||
| 5 | const x = __ashrdi3(a, b); | ||
| 6 | testing.expectEqual(@bitCast(i64, expected), x); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "ashrdi3" { | ||
| 10 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 0, 0x123456789ABCDEF); | ||
| 11 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 1, 0x91A2B3C4D5E6F7); | ||
| 12 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 2, 0x48D159E26AF37B); | ||
| 13 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 3, 0x2468ACF13579BD); | ||
| 14 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 4, 0x123456789ABCDE); | ||
| 15 | |||
| 16 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 28, 0x12345678); | ||
| 17 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 29, 0x91A2B3C); | ||
| 18 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 30, 0x48D159E); | ||
| 19 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 31, 0x2468ACF); | ||
| 20 | |||
| 21 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 32, 0x1234567); | ||
| 22 | |||
| 23 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 33, 0x91A2B3); | ||
| 24 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 34, 0x48D159); | ||
| 25 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 35, 0x2468AC); | ||
| 26 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 36, 0x123456); | ||
| 27 | |||
| 28 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 60, 0); | ||
| 29 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 61, 0); | ||
| 30 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 62, 0); | ||
| 31 | test__ashrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 63, 0); | ||
| 32 | |||
| 33 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 0, 0xFEDCBA9876543210); | ||
| 34 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 1, 0xFF6E5D4C3B2A1908); | ||
| 35 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 2, 0xFFB72EA61D950C84); | ||
| 36 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 3, 0xFFDB97530ECA8642); | ||
| 37 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 4, 0xFFEDCBA987654321); | ||
| 38 | |||
| 39 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 28, 0xFFFFFFFFEDCBA987); | ||
| 40 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 29, 0xFFFFFFFFF6E5D4C3); | ||
| 41 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 30, 0xFFFFFFFFFB72EA61); | ||
| 42 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 31, 0xFFFFFFFFFDB97530); | ||
| 43 | |||
| 44 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 32, 0xFFFFFFFFFEDCBA98); | ||
| 45 | |||
| 46 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 33, 0xFFFFFFFFFF6E5D4C); | ||
| 47 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 34, 0xFFFFFFFFFFB72EA6); | ||
| 48 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 35, 0xFFFFFFFFFFDB9753); | ||
| 49 | test__ashrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 36, 0xFFFFFFFFFFEDCBA9); | ||
| 50 | |||
| 51 | test__ashrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 60, 0xFFFFFFFFFFFFFFFA); | ||
| 52 | test__ashrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 61, 0xFFFFFFFFFFFFFFFD); | ||
| 53 | test__ashrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 62, 0xFFFFFFFFFFFFFFFE); | ||
| 54 | test__ashrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 63, 0xFFFFFFFFFFFFFFFF); | ||
| 55 | } | ||
lib/std/special/compiler_rt/ashrti3.zig deleted-42| ... | @@ -1,42 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | |||
| 4 | pub fn __ashrti3(a: i128, b: i32) callconv(.C) i128 { | ||
| 5 | var input = twords{ .all = a }; | ||
| 6 | var result: twords = undefined; | ||
| 7 | |||
| 8 | if (b > 63) { | ||
| 9 | // 64 <= b < 128 | ||
| 10 | result.s.low = input.s.high >> @intCast(u6, b - 64); | ||
| 11 | result.s.high = input.s.high >> 63; | ||
| 12 | } else { | ||
| 13 | // 0 <= b < 64 | ||
| 14 | if (b == 0) return a; | ||
| 15 | result.s.low = input.s.high << @intCast(u6, 64 - b); | ||
| 16 | // Avoid sign-extension here | ||
| 17 | result.s.low |= @bitCast(i64, @bitCast(u64, input.s.low) >> @intCast(u6, b)); | ||
| 18 | result.s.high = input.s.high >> @intCast(u6, b); | ||
| 19 | } | ||
| 20 | |||
| 21 | return result.all; | ||
| 22 | } | ||
| 23 | |||
| 24 | const twords = extern union { | ||
| 25 | all: i128, | ||
| 26 | s: S, | ||
| 27 | |||
| 28 | const S = if (builtin.endian == .Little) | ||
| 29 | struct { | ||
| 30 | low: i64, | ||
| 31 | high: i64, | ||
| 32 | } | ||
| 33 | else | ||
| 34 | struct { | ||
| 35 | high: i64, | ||
| 36 | low: i64, | ||
| 37 | }; | ||
| 38 | }; | ||
| 39 | |||
| 40 | test "import ashrti3" { | ||
| 41 | _ = @import("ashrti3_test.zig"); | ||
| 42 | } | ||
lib/std/special/compiler_rt/ashrti3_test.zig+2-4| ... | @@ -1,11 +1,9 @@ | ... | @@ -1,11 +1,9 @@ |
| 1 | const __ashrti3 = @import("ashrti3.zig").__ashrti3; | 1 | const __ashrti3 = @import("shift.zig").__ashrti3; |
| 2 | const testing = @import("std").testing; | 2 | const testing = @import("std").testing; |
| 3 | 3 | ||
| 4 | fn test__ashrti3(a: i128, b: i32, expected: i128) void { | 4 | fn test__ashrti3(a: i128, b: i32, expected: i128) void { |
| 5 | const x = __ashrti3(a, b); | 5 | const x = __ashrti3(a, b); |
| 6 | // @import("std").debug.warn("got 0x{x}\nexp 0x{x}\n", .{@truncate(u64, | 6 | testing.expectEqual(expected, x); |
| 7 | // @bitCast(u128, x) >> 64), @truncate(u64, @bitCast(u128, expected)) >> 64}); | ||
| 8 | testing.expect(x == expected); | ||
| 9 | } | 7 | } |
| 10 | 8 | ||
| 11 | test "ashrti3" { | 9 | test "ashrti3" { |
lib/std/special/compiler_rt/lshrdi3_test.zig created+55| ... | @@ -0,0 +1,55 @@ | ||
| 1 | const __lshrdi3 = @import("shift.zig").__lshrdi3; | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__lshrdi3(a: i64, b: i32, expected: u64) void { | ||
| 5 | const x = __lshrdi3(a, b); | ||
| 6 | testing.expectEqual(@bitCast(i64, expected), x); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "lshrdi3" { | ||
| 10 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 0, 0x123456789ABCDEF); | ||
| 11 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 1, 0x91A2B3C4D5E6F7); | ||
| 12 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 2, 0x48D159E26AF37B); | ||
| 13 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 3, 0x2468ACF13579BD); | ||
| 14 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 4, 0x123456789ABCDE); | ||
| 15 | |||
| 16 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 28, 0x12345678); | ||
| 17 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 29, 0x91A2B3C); | ||
| 18 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 30, 0x48D159E); | ||
| 19 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 31, 0x2468ACF); | ||
| 20 | |||
| 21 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 32, 0x1234567); | ||
| 22 | |||
| 23 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 33, 0x91A2B3); | ||
| 24 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 34, 0x48D159); | ||
| 25 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 35, 0x2468AC); | ||
| 26 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 36, 0x123456); | ||
| 27 | |||
| 28 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 60, 0); | ||
| 29 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 61, 0); | ||
| 30 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 62, 0); | ||
| 31 | test__lshrdi3(@bitCast(i64, @as(u64, 0x0123456789ABCDEF)), 63, 0); | ||
| 32 | |||
| 33 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 0, 0xFEDCBA9876543210); | ||
| 34 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 1, 0x7F6E5D4C3B2A1908); | ||
| 35 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 2, 0x3FB72EA61D950C84); | ||
| 36 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 3, 0x1FDB97530ECA8642); | ||
| 37 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 4, 0xFEDCBA987654321); | ||
| 38 | |||
| 39 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 28, 0xFEDCBA987); | ||
| 40 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 29, 0x7F6E5D4C3); | ||
| 41 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 30, 0x3FB72EA61); | ||
| 42 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 31, 0x1FDB97530); | ||
| 43 | |||
| 44 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 32, 0xFEDCBA98); | ||
| 45 | |||
| 46 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 33, 0x7F6E5D4C); | ||
| 47 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 34, 0x3FB72EA6); | ||
| 48 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 35, 0x1FDB9753); | ||
| 49 | test__lshrdi3(@bitCast(i64, @as(u64, 0xFEDCBA9876543210)), 36, 0xFEDCBA9); | ||
| 50 | |||
| 51 | test__lshrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 60, 0xA); | ||
| 52 | test__lshrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 61, 0x5); | ||
| 53 | test__lshrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 62, 0x2); | ||
| 54 | test__lshrdi3(@bitCast(i64, @as(u64, 0xAEDCBA9876543210)), 63, 0x1); | ||
| 55 | } | ||
lib/std/special/compiler_rt/lshrti3.zig deleted-41| ... | @@ -1,41 +0,0 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const compiler_rt = @import("../compiler_rt.zig"); | ||
| 3 | |||
| 4 | pub fn __lshrti3(a: i128, b: i32) callconv(.C) i128 { | ||
| 5 | var input = twords{ .all = a }; | ||
| 6 | var result: twords = undefined; | ||
| 7 | |||
| 8 | if (b > 63) { | ||
| 9 | // 64 <= b < 128 | ||
| 10 | result.s.low = input.s.high >> @intCast(u6, b - 64); | ||
| 11 | result.s.high = 0; | ||
| 12 | } else { | ||
| 13 | // 0 <= b < 64 | ||
| 14 | if (b == 0) return a; | ||
| 15 | result.s.low = input.s.high << @intCast(u6, 64 - b); | ||
| 16 | result.s.low |= input.s.low >> @intCast(u6, b); | ||
| 17 | result.s.high = input.s.high >> @intCast(u6, b); | ||
| 18 | } | ||
| 19 | |||
| 20 | return result.all; | ||
| 21 | } | ||
| 22 | |||
| 23 | const twords = extern union { | ||
| 24 | all: i128, | ||
| 25 | s: S, | ||
| 26 | |||
| 27 | const S = if (builtin.endian == .Little) | ||
| 28 | struct { | ||
| 29 | low: u64, | ||
| 30 | high: u64, | ||
| 31 | } | ||
| 32 | else | ||
| 33 | struct { | ||
| 34 | high: u64, | ||
| 35 | low: u64, | ||
| 36 | }; | ||
| 37 | }; | ||
| 38 | |||
| 39 | test "import lshrti3" { | ||
| 40 | _ = @import("lshrti3_test.zig"); | ||
| 41 | } | ||
lib/std/special/compiler_rt/lshrti3_test.zig+2-2| ... | @@ -1,9 +1,9 @@ | ... | @@ -1,9 +1,9 @@ |
| 1 | const __lshrti3 = @import("lshrti3.zig").__lshrti3; | 1 | const __lshrti3 = @import("shift.zig").__lshrti3; |
| 2 | const testing = @import("std").testing; | 2 | const testing = @import("std").testing; |
| 3 | 3 | ||
| 4 | fn test__lshrti3(a: i128, b: i32, expected: i128) void { | 4 | fn test__lshrti3(a: i128, b: i32, expected: i128) void { |
| 5 | const x = __lshrti3(a, b); | 5 | const x = __lshrti3(a, b); |
| 6 | testing.expect(x == expected); | 6 | testing.expectEqual(expected, x); |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | test "lshrti3" { | 9 | test "lshrti3" { |
lib/std/special/compiler_rt/shift.zig created+130| ... | @@ -0,0 +1,130 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = std.builtin; | ||
| 3 | const Log2Int = std.math.Log2Int; | ||
| 4 | |||
| 5 | fn Dwords(comptime T: type, comptime signed_half: bool) type { | ||
| 6 | return extern union { | ||
| 7 | pub const HalfTU = std.meta.IntType(false, @divExact(T.bit_count, 2)); | ||
| 8 | pub const HalfTS = std.meta.IntType(true, @divExact(T.bit_count, 2)); | ||
| 9 | pub const HalfT = if (signed_half) HalfTS else HalfTU; | ||
| 10 | |||
| 11 | all: T, | ||
| 12 | s: if (builtin.endian == .Little) | ||
| 13 | struct { low: HalfT, high: HalfT } | ||
| 14 | else | ||
| 15 | struct { high: HalfT, low: HalfT }, | ||
| 16 | }; | ||
| 17 | } | ||
| 18 | |||
| 19 | // Arithmetic shift left | ||
| 20 | // Precondition: 0 <= b < bits_in_dword | ||
| 21 | pub fn ashlXi3(comptime T: type, a: T, b: i32) T { | ||
| 22 | const dwords = Dwords(T, false); | ||
| 23 | const S = Log2Int(dwords.HalfT); | ||
| 24 | |||
| 25 | const input = dwords{ .all = a }; | ||
| 26 | var output: dwords = undefined; | ||
| 27 | |||
| 28 | if (b >= dwords.HalfT.bit_count) { | ||
| 29 | output.s.low = 0; | ||
| 30 | output.s.high = input.s.low << @intCast(S, b - dwords.HalfT.bit_count); | ||
| 31 | } else if (b == 0) { | ||
| 32 | return a; | ||
| 33 | } else { | ||
| 34 | output.s.low = input.s.low << @intCast(S, b); | ||
| 35 | output.s.high = input.s.high << @intCast(S, b); | ||
| 36 | output.s.high |= input.s.low >> @intCast(S, dwords.HalfT.bit_count - b); | ||
| 37 | } | ||
| 38 | |||
| 39 | return output.all; | ||
| 40 | } | ||
| 41 | |||
| 42 | // Arithmetic shift right | ||
| 43 | // Precondition: 0 <= b < T.bit_count | ||
| 44 | pub fn ashrXi3(comptime T: type, a: T, b: i32) T { | ||
| 45 | const dwords = Dwords(T, true); | ||
| 46 | const S = Log2Int(dwords.HalfT); | ||
| 47 | |||
| 48 | const input = dwords{ .all = a }; | ||
| 49 | var output: dwords = undefined; | ||
| 50 | |||
| 51 | if (b >= dwords.HalfT.bit_count) { | ||
| 52 | output.s.high = input.s.high >> (dwords.HalfT.bit_count - 1); | ||
| 53 | output.s.low = input.s.high >> @intCast(S, b - dwords.HalfT.bit_count); | ||
| 54 | } else if (b == 0) { | ||
| 55 | return a; | ||
| 56 | } else { | ||
| 57 | output.s.high = input.s.high >> @intCast(S, b); | ||
| 58 | output.s.low = input.s.high << @intCast(S, dwords.HalfT.bit_count - b); | ||
| 59 | // Avoid sign-extension here | ||
| 60 | output.s.low |= @bitCast( | ||
| 61 | dwords.HalfT, | ||
| 62 | @bitCast(dwords.HalfTU, input.s.low) >> @intCast(S, b), | ||
| 63 | ); | ||
| 64 | } | ||
| 65 | |||
| 66 | return output.all; | ||
| 67 | } | ||
| 68 | |||
| 69 | // Logical shift right | ||
| 70 | // Precondition: 0 <= b < T.bit_count | ||
| 71 | pub fn lshrXi3(comptime T: type, a: T, b: i32) T { | ||
| 72 | const dwords = Dwords(T, false); | ||
| 73 | const S = Log2Int(dwords.HalfT); | ||
| 74 | |||
| 75 | const input = dwords{ .all = a }; | ||
| 76 | var output: dwords = undefined; | ||
| 77 | |||
| 78 | if (b >= dwords.HalfT.bit_count) { | ||
| 79 | output.s.high = 0; | ||
| 80 | output.s.low = input.s.high >> @intCast(S, b - dwords.HalfT.bit_count); | ||
| 81 | } else if (b == 0) { | ||
| 82 | return a; | ||
| 83 | } else { | ||
| 84 | output.s.high = input.s.high >> @intCast(S, b); | ||
| 85 | output.s.low = input.s.high << @intCast(S, dwords.HalfT.bit_count - b); | ||
| 86 | output.s.low |= input.s.low >> @intCast(S, b); | ||
| 87 | } | ||
| 88 | |||
| 89 | return output.all; | ||
| 90 | } | ||
| 91 | |||
| 92 | pub fn __ashldi3(a: i64, b: i32) callconv(.C) i64 { | ||
| 93 | return @call(.{ .modifier = .always_inline }, ashlXi3, .{ i64, a, b }); | ||
| 94 | } | ||
| 95 | pub fn __ashlti3(a: i128, b: i32) callconv(.C) i128 { | ||
| 96 | return @call(.{ .modifier = .always_inline }, ashlXi3, .{ i128, a, b }); | ||
| 97 | } | ||
| 98 | pub fn __ashrdi3(a: i64, b: i32) callconv(.C) i64 { | ||
| 99 | return @call(.{ .modifier = .always_inline }, ashrXi3, .{ i64, a, b }); | ||
| 100 | } | ||
| 101 | pub fn __ashrti3(a: i128, b: i32) callconv(.C) i128 { | ||
| 102 | return @call(.{ .modifier = .always_inline }, ashrXi3, .{ i128, a, b }); | ||
| 103 | } | ||
| 104 | pub fn __lshrdi3(a: i64, b: i32) callconv(.C) i64 { | ||
| 105 | return @call(.{ .modifier = .always_inline }, lshrXi3, .{ i64, a, b }); | ||
| 106 | } | ||
| 107 | pub fn __lshrti3(a: i128, b: i32) callconv(.C) i128 { | ||
| 108 | return @call(.{ .modifier = .always_inline }, lshrXi3, .{ i128, a, b }); | ||
| 109 | } | ||
| 110 | |||
| 111 | pub fn __aeabi_llsl(a: i64, b: i32) callconv(.AAPCS) i64 { | ||
| 112 | return __ashldi3(a, b); | ||
| 113 | } | ||
| 114 | pub fn __aeabi_lasr(a: i64, b: i32) callconv(.AAPCS) i64 { | ||
| 115 | return __ashrdi3(a, b); | ||
| 116 | } | ||
| 117 | pub fn __aeabi_llsr(a: i64, b: i32) callconv(.AAPCS) i64 { | ||
| 118 | return __lshrdi3(a, b); | ||
| 119 | } | ||
| 120 | |||
| 121 | test "" { | ||
| 122 | _ = @import("ashrdi3_test.zig"); | ||
| 123 | _ = @import("ashrti3_test.zig"); | ||
| 124 | |||
| 125 | _ = @import("ashldi3_test.zig"); | ||
| 126 | _ = @import("ashlti3_test.zig"); | ||
| 127 | |||
| 128 | _ = @import("lshrdi3_test.zig"); | ||
| 129 | _ = @import("lshrti3_test.zig"); | ||
| 130 | } | ||