| author | |
| committer | |
| log | 97b9facb98cffa05064315d69a11b96836aa5be3 |
| tree | 063bb8d02a752df2d33fc8d2d8a2b1def1ee3728 |
| parent | 5f70c36fa88a17c045839b8b422e04db3b545426 |
| signature |
- Combine mulXi3 routines for follow-up cleanup.
- DRY up Dwords and Twords
- rename both to HalveInt and use instance
* Justification: Not all processors have word size 32 bit.
* remove test file from CMakeLists
* DRY things.11 files changed, 294 insertions(+), 354 deletions(-)
CMakeLists.txt+3-5| ... | @@ -434,13 +434,12 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -434,13 +434,12 @@ set(ZIG_STAGE2_SOURCES |
| 434 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/log10.zig" | 434 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/log10.zig" |
| 435 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/log2.zig" | 435 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/log2.zig" |
| 436 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/modti3.zig" | 436 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/modti3.zig" |
| 437 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulXi3.zig" | ||
| 437 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/muldf3.zig" | 438 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/muldf3.zig" |
| 438 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/muldi3.zig" | ||
| 439 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulf3.zig" | 439 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulf3.zig" |
| 440 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulo.zig" | 440 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulo.zig" |
| 441 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulsf3.zig" | 441 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulsf3.zig" |
| 442 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/multf3.zig" | 442 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/multf3.zig" |
| 443 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/multi3.zig" | ||
| 444 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulxf3.zig" | 443 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/mulxf3.zig" |
| 445 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/negXi2.zig" | 444 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/negXi2.zig" |
| 446 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/negv.zig" | 445 | "${CMAKE_SOURCE_DIR}/lib/compiler_rt/negv.zig" |
| ... | @@ -613,7 +612,6 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -613,7 +612,6 @@ set(ZIG_STAGE2_SOURCES |
| 613 | "${CMAKE_SOURCE_DIR}/src/link/tapi.zig" | 612 | "${CMAKE_SOURCE_DIR}/src/link/tapi.zig" |
| 614 | "${CMAKE_SOURCE_DIR}/src/link/tapi/Tokenizer.zig" | 613 | "${CMAKE_SOURCE_DIR}/src/link/tapi/Tokenizer.zig" |
| 615 | "${CMAKE_SOURCE_DIR}/src/link/tapi/parse.zig" | 614 | "${CMAKE_SOURCE_DIR}/src/link/tapi/parse.zig" |
| 616 | "${CMAKE_SOURCE_DIR}/src/link/tapi/parse/test.zig" | ||
| 617 | "${CMAKE_SOURCE_DIR}/src/link/tapi/yaml.zig" | 615 | "${CMAKE_SOURCE_DIR}/src/link/tapi/yaml.zig" |
| 618 | "${CMAKE_SOURCE_DIR}/src/main.zig" | 616 | "${CMAKE_SOURCE_DIR}/src/main.zig" |
| 619 | "${CMAKE_SOURCE_DIR}/src/mingw.zig" | 617 | "${CMAKE_SOURCE_DIR}/src/mingw.zig" |
| ... | @@ -753,7 +751,7 @@ set(BUILD_ZIG2_ARGS | ... | @@ -753,7 +751,7 @@ set(BUILD_ZIG2_ARGS |
| 753 | --deps build_options | 751 | --deps build_options |
| 754 | -target "${HOST_TARGET_TRIPLE}" | 752 | -target "${HOST_TARGET_TRIPLE}" |
| 755 | ) | 753 | ) |
| 756 | 754 | ||
| 757 | add_custom_command( | 755 | add_custom_command( |
| 758 | OUTPUT "${ZIG2_C_SOURCE}" | 756 | OUTPUT "${ZIG2_C_SOURCE}" |
| 759 | COMMAND zig1 ${BUILD_ZIG2_ARGS} | 757 | COMMAND zig1 ${BUILD_ZIG2_ARGS} |
| ... | @@ -771,7 +769,7 @@ set(BUILD_COMPILER_RT_ARGS | ... | @@ -771,7 +769,7 @@ set(BUILD_COMPILER_RT_ARGS |
| 771 | --deps build_options | 769 | --deps build_options |
| 772 | -target "${HOST_TARGET_TRIPLE}" | 770 | -target "${HOST_TARGET_TRIPLE}" |
| 773 | ) | 771 | ) |
| 774 | 772 | ||
| 775 | add_custom_command( | 773 | add_custom_command( |
| 776 | OUTPUT "${ZIG_COMPILER_RT_C_SOURCE}" | 774 | OUTPUT "${ZIG_COMPILER_RT_C_SOURCE}" |
| 777 | COMMAND zig1 ${BUILD_COMPILER_RT_ARGS} | 775 | COMMAND zig1 ${BUILD_COMPILER_RT_ARGS} |
lib/compiler_rt.zig+1-2| ... | @@ -13,8 +13,7 @@ comptime { | ... | @@ -13,8 +13,7 @@ comptime { |
| 13 | _ = @import("compiler_rt/shift.zig"); | 13 | _ = @import("compiler_rt/shift.zig"); |
| 14 | _ = @import("compiler_rt/negXi2.zig"); | 14 | _ = @import("compiler_rt/negXi2.zig"); |
| 15 | _ = @import("compiler_rt/int.zig"); | 15 | _ = @import("compiler_rt/int.zig"); |
| 16 | _ = @import("compiler_rt/muldi3.zig"); | 16 | _ = @import("compiler_rt/mulXi3.zig"); |
| 17 | _ = @import("compiler_rt/multi3.zig"); | ||
| 18 | _ = @import("compiler_rt/divti3.zig"); | 17 | _ = @import("compiler_rt/divti3.zig"); |
| 19 | _ = @import("compiler_rt/udivti3.zig"); | 18 | _ = @import("compiler_rt/udivti3.zig"); |
| 20 | _ = @import("compiler_rt/modti3.zig"); | 19 | _ = @import("compiler_rt/modti3.zig"); |
lib/compiler_rt/common.zig+18| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const native_endian = builtin.cpu.arch.endian(); | ||
| 3 | 4 | ||
| 4 | pub const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak; | 5 | pub const linkage: std.builtin.GlobalLinkage = if (builtin.is_test) .Internal else .Weak; |
| 5 | /// Determines the symbol's visibility to other objects. | 6 | /// Determines the symbol's visibility to other objects. |
| ... | @@ -221,3 +222,20 @@ pub inline fn fneg(a: anytype) @TypeOf(a) { | ... | @@ -221,3 +222,20 @@ pub inline fn fneg(a: anytype) @TypeOf(a) { |
| 221 | const negated = @bitCast(U, a) ^ sign_bit_mask; | 222 | const negated = @bitCast(U, a) ^ sign_bit_mask; |
| 222 | return @bitCast(F, negated); | 223 | return @bitCast(F, negated); |
| 223 | } | 224 | } |
| 225 | |||
| 226 | /// Allows to access underlying bits as two equally sized lower and higher | ||
| 227 | /// signed or unsigned integers. | ||
| 228 | pub fn HalveInt(comptime T: type, comptime signed_half: bool) type { | ||
| 229 | return extern union { | ||
| 230 | pub const bits = @divExact(@typeInfo(T).Int.bits, 2); | ||
| 231 | pub const HalfTU = std.meta.Int(.unsigned, bits); | ||
| 232 | pub const HalfTS = std.meta.Int(.signed, bits); | ||
| 233 | pub const HalfT = if (signed_half) HalfTS else HalfTU; | ||
| 234 | |||
| 235 | all: T, | ||
| 236 | s: if (native_endian == .Little) | ||
| 237 | extern struct { low: HalfT, high: HalfT } | ||
| 238 | else | ||
| 239 | extern struct { high: HalfT, low: HalfT }, | ||
| 240 | }; | ||
| 241 | } |
lib/compiler_rt/int.zig-57| ... | @@ -16,7 +16,6 @@ pub const panic = common.panic; | ... | @@ -16,7 +16,6 @@ pub const panic = common.panic; |
| 16 | comptime { | 16 | comptime { |
| 17 | @export(__divmodti4, .{ .name = "__divmodti4", .linkage = common.linkage, .visibility = common.visibility }); | 17 | @export(__divmodti4, .{ .name = "__divmodti4", .linkage = common.linkage, .visibility = common.visibility }); |
| 18 | @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = common.linkage, .visibility = common.visibility }); | 18 | @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = common.linkage, .visibility = common.visibility }); |
| 19 | @export(__mulsi3, .{ .name = "__mulsi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 20 | @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = common.linkage, .visibility = common.visibility }); | 19 | @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = common.linkage, .visibility = common.visibility }); |
| 21 | if (common.want_aeabi) { | 20 | if (common.want_aeabi) { |
| 22 | @export(__aeabi_idiv, .{ .name = "__aeabi_idiv", .linkage = common.linkage, .visibility = common.visibility }); | 21 | @export(__aeabi_idiv, .{ .name = "__aeabi_idiv", .linkage = common.linkage, .visibility = common.visibility }); |
| ... | @@ -663,59 +662,3 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { | ... | @@ -663,59 +662,3 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) !void { |
| 663 | const r: u32 = __umodsi3(a, b); | 662 | const r: u32 = __umodsi3(a, b); |
| 664 | try testing.expect(r == expected_r); | 663 | try testing.expect(r == expected_r); |
| 665 | } | 664 | } |
| 666 | |||
| 667 | pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 { | ||
| 668 | var ua = @bitCast(u32, a); | ||
| 669 | var ub = @bitCast(u32, b); | ||
| 670 | var r: u32 = 0; | ||
| 671 | |||
| 672 | while (ua > 0) { | ||
| 673 | if ((ua & 1) != 0) r +%= ub; | ||
| 674 | ua >>= 1; | ||
| 675 | ub <<= 1; | ||
| 676 | } | ||
| 677 | |||
| 678 | return @bitCast(i32, r); | ||
| 679 | } | ||
| 680 | |||
| 681 | fn test_one_mulsi3(a: i32, b: i32, result: i32) !void { | ||
| 682 | try testing.expectEqual(result, __mulsi3(a, b)); | ||
| 683 | } | ||
| 684 | |||
| 685 | test "mulsi3" { | ||
| 686 | try test_one_mulsi3(0, 0, 0); | ||
| 687 | try test_one_mulsi3(0, 1, 0); | ||
| 688 | try test_one_mulsi3(1, 0, 0); | ||
| 689 | try test_one_mulsi3(0, 10, 0); | ||
| 690 | try test_one_mulsi3(10, 0, 0); | ||
| 691 | try test_one_mulsi3(0, maxInt(i32), 0); | ||
| 692 | try test_one_mulsi3(maxInt(i32), 0, 0); | ||
| 693 | try test_one_mulsi3(0, -1, 0); | ||
| 694 | try test_one_mulsi3(-1, 0, 0); | ||
| 695 | try test_one_mulsi3(0, -10, 0); | ||
| 696 | try test_one_mulsi3(-10, 0, 0); | ||
| 697 | try test_one_mulsi3(0, minInt(i32), 0); | ||
| 698 | try test_one_mulsi3(minInt(i32), 0, 0); | ||
| 699 | try test_one_mulsi3(1, 1, 1); | ||
| 700 | try test_one_mulsi3(1, 10, 10); | ||
| 701 | try test_one_mulsi3(10, 1, 10); | ||
| 702 | try test_one_mulsi3(1, maxInt(i32), maxInt(i32)); | ||
| 703 | try test_one_mulsi3(maxInt(i32), 1, maxInt(i32)); | ||
| 704 | try test_one_mulsi3(1, -1, -1); | ||
| 705 | try test_one_mulsi3(1, -10, -10); | ||
| 706 | try test_one_mulsi3(-10, 1, -10); | ||
| 707 | try test_one_mulsi3(1, minInt(i32), minInt(i32)); | ||
| 708 | try test_one_mulsi3(minInt(i32), 1, minInt(i32)); | ||
| 709 | try test_one_mulsi3(46340, 46340, 2147395600); | ||
| 710 | try test_one_mulsi3(-46340, 46340, -2147395600); | ||
| 711 | try test_one_mulsi3(46340, -46340, -2147395600); | ||
| 712 | try test_one_mulsi3(-46340, -46340, 2147395600); | ||
| 713 | try test_one_mulsi3(4194303, 8192, @truncate(i32, 34359730176)); | ||
| 714 | try test_one_mulsi3(-4194303, 8192, @truncate(i32, -34359730176)); | ||
| 715 | try test_one_mulsi3(4194303, -8192, @truncate(i32, -34359730176)); | ||
| 716 | try test_one_mulsi3(-4194303, -8192, @truncate(i32, 34359730176)); | ||
| 717 | try test_one_mulsi3(8192, 4194303, @truncate(i32, 34359730176)); | ||
| 718 | try test_one_mulsi3(-8192, 4194303, @truncate(i32, -34359730176)); | ||
| 719 | try test_one_mulsi3(8192, -4194303, @truncate(i32, -34359730176)); | ||
| 720 | try test_one_mulsi3(-8192, -4194303, @truncate(i32, 34359730176)); | ||
| 721 | } |
lib/compiler_rt/mulXi3.zig created+101| ... | @@ -0,0 +1,101 @@ | ||
| 1 | const builtin = @import("builtin"); | ||
| 2 | const std = @import("std"); | ||
| 3 | const testing = std.testing; | ||
| 4 | const common = @import("common.zig"); | ||
| 5 | const native_endian = builtin.cpu.arch.endian(); | ||
| 6 | |||
| 7 | pub const panic = common.panic; | ||
| 8 | |||
| 9 | comptime { | ||
| 10 | @export(__mulsi3, .{ .name = "__mulsi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 11 | if (common.want_aeabi) { | ||
| 12 | @export(__aeabi_lmul, .{ .name = "__aeabi_lmul", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 13 | } else { | ||
| 14 | @export(__muldi3, .{ .name = "__muldi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 15 | } | ||
| 16 | if (common.want_windows_v2u64_abi) { | ||
| 17 | @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 18 | } else { | ||
| 19 | @export(__multi3, .{ .name = "__multi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 { | ||
| 24 | var ua = @bitCast(u32, a); | ||
| 25 | var ub = @bitCast(u32, b); | ||
| 26 | var r: u32 = 0; | ||
| 27 | |||
| 28 | while (ua > 0) { | ||
| 29 | if ((ua & 1) != 0) r +%= ub; | ||
| 30 | ua >>= 1; | ||
| 31 | ub <<= 1; | ||
| 32 | } | ||
| 33 | |||
| 34 | return @bitCast(i32, r); | ||
| 35 | } | ||
| 36 | |||
| 37 | pub fn __muldi3(a: i64, b: i64) callconv(.C) i64 { | ||
| 38 | return mulX(i64, a, b); | ||
| 39 | } | ||
| 40 | |||
| 41 | fn __aeabi_lmul(a: i64, b: i64) callconv(.AAPCS) i64 { | ||
| 42 | return mulX(i64, a, b); | ||
| 43 | } | ||
| 44 | |||
| 45 | inline fn mulX(comptime T: type, a: T, b: T) T { | ||
| 46 | const word_t = common.HalveInt(T, false); | ||
| 47 | const x = word_t{ .all = a }; | ||
| 48 | const y = word_t{ .all = b }; | ||
| 49 | var r = switch (T) { | ||
| 50 | i64, i128 => word_t{ .all = muldXi(word_t.HalfT, x.s.low, y.s.low) }, | ||
| 51 | else => unreachable, | ||
| 52 | }; | ||
| 53 | r.s.high +%= x.s.high *% y.s.low +% x.s.low *% y.s.high; | ||
| 54 | return r.all; | ||
| 55 | } | ||
| 56 | |||
| 57 | fn DoubleInt(comptime T: type) type { | ||
| 58 | return switch (T) { | ||
| 59 | u32 => i64, | ||
| 60 | u64 => i128, | ||
| 61 | i32 => i64, | ||
| 62 | i64 => i128, | ||
| 63 | else => unreachable, | ||
| 64 | }; | ||
| 65 | } | ||
| 66 | |||
| 67 | fn muldXi(comptime T: type, a: T, b: T) DoubleInt(T) { | ||
| 68 | const DT = DoubleInt(T); | ||
| 69 | const word_t = common.HalveInt(DT, false); | ||
| 70 | const bits_in_word_2 = @sizeOf(T) * 8 / 2; | ||
| 71 | const lower_mask = (~@as(T, 0)) >> bits_in_word_2; | ||
| 72 | |||
| 73 | var r: word_t = undefined; | ||
| 74 | r.s.low = (a & lower_mask) *% (b & lower_mask); | ||
| 75 | var t: T = r.s.low >> bits_in_word_2; | ||
| 76 | r.s.low &= lower_mask; | ||
| 77 | t += (a >> bits_in_word_2) *% (b & lower_mask); | ||
| 78 | r.s.low +%= (t & lower_mask) << bits_in_word_2; | ||
| 79 | r.s.high = t >> bits_in_word_2; | ||
| 80 | t = r.s.low >> bits_in_word_2; | ||
| 81 | r.s.low &= lower_mask; | ||
| 82 | t +%= (b >> bits_in_word_2) *% (a & lower_mask); | ||
| 83 | r.s.low +%= (t & lower_mask) << bits_in_word_2; | ||
| 84 | r.s.high +%= t >> bits_in_word_2; | ||
| 85 | r.s.high +%= (a >> bits_in_word_2) *% (b >> bits_in_word_2); | ||
| 86 | return r.all; | ||
| 87 | } | ||
| 88 | |||
| 89 | pub fn __multi3(a: i128, b: i128) callconv(.C) i128 { | ||
| 90 | return mulX(i128, a, b); | ||
| 91 | } | ||
| 92 | |||
| 93 | const v2u64 = @Vector(2, u64); | ||
| 94 | |||
| 95 | fn __multi3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { | ||
| 96 | return @bitCast(v2u64, mulX(i128, @bitCast(i128, a), @bitCast(i128, b))); | ||
| 97 | } | ||
| 98 | |||
| 99 | test { | ||
| 100 | _ = @import("mulXi3_test.zig"); | ||
| 101 | } | ||
lib/compiler_rt/mulXi3_test.zig created+147| ... | @@ -0,0 +1,147 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const testing = std.testing; | ||
| 3 | const mulXi3 = @import("mulXi3.zig"); | ||
| 4 | const maxInt = std.math.maxInt; | ||
| 5 | const minInt = std.math.minInt; | ||
| 6 | |||
| 7 | fn test_one_mulsi3(a: i32, b: i32, result: i32) !void { | ||
| 8 | try testing.expectEqual(result, mulXi3.__mulsi3(a, b)); | ||
| 9 | } | ||
| 10 | |||
| 11 | fn test__muldi3(a: i64, b: i64, expected: i64) !void { | ||
| 12 | const x = mulXi3.__muldi3(a, b); | ||
| 13 | try testing.expect(x == expected); | ||
| 14 | } | ||
| 15 | |||
| 16 | fn test__multi3(a: i128, b: i128, expected: i128) !void { | ||
| 17 | const x = mulXi3.__multi3(a, b); | ||
| 18 | try testing.expect(x == expected); | ||
| 19 | } | ||
| 20 | |||
| 21 | test "mulsi3" { | ||
| 22 | try test_one_mulsi3(0, 0, 0); | ||
| 23 | try test_one_mulsi3(0, 1, 0); | ||
| 24 | try test_one_mulsi3(1, 0, 0); | ||
| 25 | try test_one_mulsi3(0, 10, 0); | ||
| 26 | try test_one_mulsi3(10, 0, 0); | ||
| 27 | try test_one_mulsi3(0, maxInt(i32), 0); | ||
| 28 | try test_one_mulsi3(maxInt(i32), 0, 0); | ||
| 29 | try test_one_mulsi3(0, -1, 0); | ||
| 30 | try test_one_mulsi3(-1, 0, 0); | ||
| 31 | try test_one_mulsi3(0, -10, 0); | ||
| 32 | try test_one_mulsi3(-10, 0, 0); | ||
| 33 | try test_one_mulsi3(0, minInt(i32), 0); | ||
| 34 | try test_one_mulsi3(minInt(i32), 0, 0); | ||
| 35 | try test_one_mulsi3(1, 1, 1); | ||
| 36 | try test_one_mulsi3(1, 10, 10); | ||
| 37 | try test_one_mulsi3(10, 1, 10); | ||
| 38 | try test_one_mulsi3(1, maxInt(i32), maxInt(i32)); | ||
| 39 | try test_one_mulsi3(maxInt(i32), 1, maxInt(i32)); | ||
| 40 | try test_one_mulsi3(1, -1, -1); | ||
| 41 | try test_one_mulsi3(1, -10, -10); | ||
| 42 | try test_one_mulsi3(-10, 1, -10); | ||
| 43 | try test_one_mulsi3(1, minInt(i32), minInt(i32)); | ||
| 44 | try test_one_mulsi3(minInt(i32), 1, minInt(i32)); | ||
| 45 | try test_one_mulsi3(46340, 46340, 2147395600); | ||
| 46 | try test_one_mulsi3(-46340, 46340, -2147395600); | ||
| 47 | try test_one_mulsi3(46340, -46340, -2147395600); | ||
| 48 | try test_one_mulsi3(-46340, -46340, 2147395600); | ||
| 49 | try test_one_mulsi3(4194303, 8192, @truncate(i32, 34359730176)); | ||
| 50 | try test_one_mulsi3(-4194303, 8192, @truncate(i32, -34359730176)); | ||
| 51 | try test_one_mulsi3(4194303, -8192, @truncate(i32, -34359730176)); | ||
| 52 | try test_one_mulsi3(-4194303, -8192, @truncate(i32, 34359730176)); | ||
| 53 | try test_one_mulsi3(8192, 4194303, @truncate(i32, 34359730176)); | ||
| 54 | try test_one_mulsi3(-8192, 4194303, @truncate(i32, -34359730176)); | ||
| 55 | try test_one_mulsi3(8192, -4194303, @truncate(i32, -34359730176)); | ||
| 56 | try test_one_mulsi3(-8192, -4194303, @truncate(i32, 34359730176)); | ||
| 57 | } | ||
| 58 | |||
| 59 | test "muldi3" { | ||
| 60 | try test__muldi3(0, 0, 0); | ||
| 61 | try test__muldi3(0, 1, 0); | ||
| 62 | try test__muldi3(1, 0, 0); | ||
| 63 | try test__muldi3(0, 10, 0); | ||
| 64 | try test__muldi3(10, 0, 0); | ||
| 65 | try test__muldi3(0, 81985529216486895, 0); | ||
| 66 | try test__muldi3(81985529216486895, 0, 0); | ||
| 67 | |||
| 68 | try test__muldi3(0, -1, 0); | ||
| 69 | try test__muldi3(-1, 0, 0); | ||
| 70 | try test__muldi3(0, -10, 0); | ||
| 71 | try test__muldi3(-10, 0, 0); | ||
| 72 | try test__muldi3(0, -81985529216486895, 0); | ||
| 73 | try test__muldi3(-81985529216486895, 0, 0); | ||
| 74 | |||
| 75 | try test__muldi3(1, 1, 1); | ||
| 76 | try test__muldi3(1, 10, 10); | ||
| 77 | try test__muldi3(10, 1, 10); | ||
| 78 | try test__muldi3(1, 81985529216486895, 81985529216486895); | ||
| 79 | try test__muldi3(81985529216486895, 1, 81985529216486895); | ||
| 80 | |||
| 81 | try test__muldi3(1, -1, -1); | ||
| 82 | try test__muldi3(1, -10, -10); | ||
| 83 | try test__muldi3(-10, 1, -10); | ||
| 84 | try test__muldi3(1, -81985529216486895, -81985529216486895); | ||
| 85 | try test__muldi3(-81985529216486895, 1, -81985529216486895); | ||
| 86 | |||
| 87 | try test__muldi3(3037000499, 3037000499, 9223372030926249001); | ||
| 88 | try test__muldi3(-3037000499, 3037000499, -9223372030926249001); | ||
| 89 | try test__muldi3(3037000499, -3037000499, -9223372030926249001); | ||
| 90 | try test__muldi3(-3037000499, -3037000499, 9223372030926249001); | ||
| 91 | |||
| 92 | try test__muldi3(4398046511103, 2097152, 9223372036852678656); | ||
| 93 | try test__muldi3(-4398046511103, 2097152, -9223372036852678656); | ||
| 94 | try test__muldi3(4398046511103, -2097152, -9223372036852678656); | ||
| 95 | try test__muldi3(-4398046511103, -2097152, 9223372036852678656); | ||
| 96 | |||
| 97 | try test__muldi3(2097152, 4398046511103, 9223372036852678656); | ||
| 98 | try test__muldi3(-2097152, 4398046511103, -9223372036852678656); | ||
| 99 | try test__muldi3(2097152, -4398046511103, -9223372036852678656); | ||
| 100 | try test__muldi3(-2097152, -4398046511103, 9223372036852678656); | ||
| 101 | } | ||
| 102 | |||
| 103 | test "multi3" { | ||
| 104 | try test__multi3(0, 0, 0); | ||
| 105 | try test__multi3(0, 1, 0); | ||
| 106 | try test__multi3(1, 0, 0); | ||
| 107 | try test__multi3(0, 10, 0); | ||
| 108 | try test__multi3(10, 0, 0); | ||
| 109 | try test__multi3(0, 81985529216486895, 0); | ||
| 110 | try test__multi3(81985529216486895, 0, 0); | ||
| 111 | |||
| 112 | try test__multi3(0, -1, 0); | ||
| 113 | try test__multi3(-1, 0, 0); | ||
| 114 | try test__multi3(0, -10, 0); | ||
| 115 | try test__multi3(-10, 0, 0); | ||
| 116 | try test__multi3(0, -81985529216486895, 0); | ||
| 117 | try test__multi3(-81985529216486895, 0, 0); | ||
| 118 | |||
| 119 | try test__multi3(1, 1, 1); | ||
| 120 | try test__multi3(1, 10, 10); | ||
| 121 | try test__multi3(10, 1, 10); | ||
| 122 | try test__multi3(1, 81985529216486895, 81985529216486895); | ||
| 123 | try test__multi3(81985529216486895, 1, 81985529216486895); | ||
| 124 | |||
| 125 | try test__multi3(1, -1, -1); | ||
| 126 | try test__multi3(1, -10, -10); | ||
| 127 | try test__multi3(-10, 1, -10); | ||
| 128 | try test__multi3(1, -81985529216486895, -81985529216486895); | ||
| 129 | try test__multi3(-81985529216486895, 1, -81985529216486895); | ||
| 130 | |||
| 131 | try test__multi3(3037000499, 3037000499, 9223372030926249001); | ||
| 132 | try test__multi3(-3037000499, 3037000499, -9223372030926249001); | ||
| 133 | try test__multi3(3037000499, -3037000499, -9223372030926249001); | ||
| 134 | try test__multi3(-3037000499, -3037000499, 9223372030926249001); | ||
| 135 | |||
| 136 | try test__multi3(4398046511103, 2097152, 9223372036852678656); | ||
| 137 | try test__multi3(-4398046511103, 2097152, -9223372036852678656); | ||
| 138 | try test__multi3(4398046511103, -2097152, -9223372036852678656); | ||
| 139 | try test__multi3(-4398046511103, -2097152, 9223372036852678656); | ||
| 140 | |||
| 141 | try test__multi3(2097152, 4398046511103, 9223372036852678656); | ||
| 142 | try test__multi3(-2097152, 4398046511103, -9223372036852678656); | ||
| 143 | try test__multi3(2097152, -4398046511103, -9223372036852678656); | ||
| 144 | try test__multi3(-2097152, -4398046511103, 9223372036852678656); | ||
| 145 | |||
| 146 | try test__multi3(0x00000000000000B504F333F9DE5BE000, 0x000000000000000000B504F333F9DE5B, 0x7FFFFFFFFFFFF328DF915DA296E8A000); | ||
| 147 | } | ||
lib/compiler_rt/muldi3.zig deleted-71| ... | @@ -1,71 +0,0 @@ | ||
| 1 | //! Ported from | ||
| 2 | //! https://github.com/llvm/llvm-project/blob/llvmorg-9.0.0/compiler-rt/lib/builtins/muldi3.c | ||
| 3 | |||
| 4 | const std = @import("std"); | ||
| 5 | const builtin = @import("builtin"); | ||
| 6 | const native_endian = builtin.cpu.arch.endian(); | ||
| 7 | const common = @import("common.zig"); | ||
| 8 | |||
| 9 | pub const panic = common.panic; | ||
| 10 | |||
| 11 | comptime { | ||
| 12 | if (common.want_aeabi) { | ||
| 13 | @export(__aeabi_lmul, .{ .name = "__aeabi_lmul", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 14 | } else { | ||
| 15 | @export(__muldi3, .{ .name = "__muldi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | pub fn __muldi3(a: i64, b: i64) callconv(.C) i64 { | ||
| 20 | return mul(a, b); | ||
| 21 | } | ||
| 22 | |||
| 23 | fn __aeabi_lmul(a: i64, b: i64) callconv(.AAPCS) i64 { | ||
| 24 | return mul(a, b); | ||
| 25 | } | ||
| 26 | |||
| 27 | inline fn mul(a: i64, b: i64) i64 { | ||
| 28 | const x = dwords{ .all = a }; | ||
| 29 | const y = dwords{ .all = b }; | ||
| 30 | var r = dwords{ .all = muldsi3(x.s.low, y.s.low) }; | ||
| 31 | r.s.high +%= x.s.high *% y.s.low +% x.s.low *% y.s.high; | ||
| 32 | return r.all; | ||
| 33 | } | ||
| 34 | |||
| 35 | const dwords = extern union { | ||
| 36 | all: i64, | ||
| 37 | s: switch (native_endian) { | ||
| 38 | .Little => extern struct { | ||
| 39 | low: u32, | ||
| 40 | high: u32, | ||
| 41 | }, | ||
| 42 | .Big => extern struct { | ||
| 43 | high: u32, | ||
| 44 | low: u32, | ||
| 45 | }, | ||
| 46 | }, | ||
| 47 | }; | ||
| 48 | |||
| 49 | fn muldsi3(a: u32, b: u32) i64 { | ||
| 50 | const bits_in_word_2 = @sizeOf(i32) * 8 / 2; | ||
| 51 | const lower_mask = (~@as(u32, 0)) >> bits_in_word_2; | ||
| 52 | |||
| 53 | var r: dwords = undefined; | ||
| 54 | r.s.low = (a & lower_mask) *% (b & lower_mask); | ||
| 55 | var t: u32 = r.s.low >> bits_in_word_2; | ||
| 56 | r.s.low &= lower_mask; | ||
| 57 | t += (a >> bits_in_word_2) *% (b & lower_mask); | ||
| 58 | r.s.low +%= (t & lower_mask) << bits_in_word_2; | ||
| 59 | r.s.high = t >> bits_in_word_2; | ||
| 60 | t = r.s.low >> bits_in_word_2; | ||
| 61 | r.s.low &= lower_mask; | ||
| 62 | t +%= (b >> bits_in_word_2) *% (a & lower_mask); | ||
| 63 | r.s.low +%= (t & lower_mask) << bits_in_word_2; | ||
| 64 | r.s.high +%= t >> bits_in_word_2; | ||
| 65 | r.s.high +%= (a >> bits_in_word_2) *% (b >> bits_in_word_2); | ||
| 66 | return r.all; | ||
| 67 | } | ||
| 68 | |||
| 69 | test { | ||
| 70 | _ = @import("muldi3_test.zig"); | ||
| 71 | } | ||
lib/compiler_rt/muldi3_test.zig deleted-51| ... | @@ -1,51 +0,0 @@ | ||
| 1 | const __muldi3 = @import("muldi3.zig").__muldi3; | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__muldi3(a: i64, b: i64, expected: i64) !void { | ||
| 5 | const x = __muldi3(a, b); | ||
| 6 | try testing.expect(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "muldi3" { | ||
| 10 | try test__muldi3(0, 0, 0); | ||
| 11 | try test__muldi3(0, 1, 0); | ||
| 12 | try test__muldi3(1, 0, 0); | ||
| 13 | try test__muldi3(0, 10, 0); | ||
| 14 | try test__muldi3(10, 0, 0); | ||
| 15 | try test__muldi3(0, 81985529216486895, 0); | ||
| 16 | try test__muldi3(81985529216486895, 0, 0); | ||
| 17 | |||
| 18 | try test__muldi3(0, -1, 0); | ||
| 19 | try test__muldi3(-1, 0, 0); | ||
| 20 | try test__muldi3(0, -10, 0); | ||
| 21 | try test__muldi3(-10, 0, 0); | ||
| 22 | try test__muldi3(0, -81985529216486895, 0); | ||
| 23 | try test__muldi3(-81985529216486895, 0, 0); | ||
| 24 | |||
| 25 | try test__muldi3(1, 1, 1); | ||
| 26 | try test__muldi3(1, 10, 10); | ||
| 27 | try test__muldi3(10, 1, 10); | ||
| 28 | try test__muldi3(1, 81985529216486895, 81985529216486895); | ||
| 29 | try test__muldi3(81985529216486895, 1, 81985529216486895); | ||
| 30 | |||
| 31 | try test__muldi3(1, -1, -1); | ||
| 32 | try test__muldi3(1, -10, -10); | ||
| 33 | try test__muldi3(-10, 1, -10); | ||
| 34 | try test__muldi3(1, -81985529216486895, -81985529216486895); | ||
| 35 | try test__muldi3(-81985529216486895, 1, -81985529216486895); | ||
| 36 | |||
| 37 | try test__muldi3(3037000499, 3037000499, 9223372030926249001); | ||
| 38 | try test__muldi3(-3037000499, 3037000499, -9223372030926249001); | ||
| 39 | try test__muldi3(3037000499, -3037000499, -9223372030926249001); | ||
| 40 | try test__muldi3(-3037000499, -3037000499, 9223372030926249001); | ||
| 41 | |||
| 42 | try test__muldi3(4398046511103, 2097152, 9223372036852678656); | ||
| 43 | try test__muldi3(-4398046511103, 2097152, -9223372036852678656); | ||
| 44 | try test__muldi3(4398046511103, -2097152, -9223372036852678656); | ||
| 45 | try test__muldi3(-4398046511103, -2097152, 9223372036852678656); | ||
| 46 | |||
| 47 | try test__muldi3(2097152, 4398046511103, 9223372036852678656); | ||
| 48 | try test__muldi3(-2097152, 4398046511103, -9223372036852678656); | ||
| 49 | try test__muldi3(2097152, -4398046511103, -9223372036852678656); | ||
| 50 | try test__muldi3(-2097152, -4398046511103, 9223372036852678656); | ||
| 51 | } | ||
lib/compiler_rt/multi3.zig deleted-75| ... | @@ -1,75 +0,0 @@ | ||
| 1 | //! Ported from git@github.com:llvm-project/llvm-project-20170507.git | ||
| 2 | //! ae684fad6d34858c014c94da69c15e7774a633c3 | ||
| 3 | //! 2018-08-13 | ||
| 4 | |||
| 5 | const std = @import("std"); | ||
| 6 | const builtin = @import("builtin"); | ||
| 7 | const native_endian = builtin.cpu.arch.endian(); | ||
| 8 | const common = @import("common.zig"); | ||
| 9 | |||
| 10 | pub const panic = common.panic; | ||
| 11 | |||
| 12 | comptime { | ||
| 13 | if (common.want_windows_v2u64_abi) { | ||
| 14 | @export(__multi3_windows_x86_64, .{ .name = "__multi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 15 | } else { | ||
| 16 | @export(__multi3, .{ .name = "__multi3", .linkage = common.linkage, .visibility = common.visibility }); | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | pub fn __multi3(a: i128, b: i128) callconv(.C) i128 { | ||
| 21 | return mul(a, b); | ||
| 22 | } | ||
| 23 | |||
| 24 | const v2u64 = @Vector(2, u64); | ||
| 25 | |||
| 26 | fn __multi3_windows_x86_64(a: v2u64, b: v2u64) callconv(.C) v2u64 { | ||
| 27 | return @bitCast(v2u64, mul(@bitCast(i128, a), @bitCast(i128, b))); | ||
| 28 | } | ||
| 29 | |||
| 30 | inline fn mul(a: i128, b: i128) i128 { | ||
| 31 | const x = twords{ .all = a }; | ||
| 32 | const y = twords{ .all = b }; | ||
| 33 | var r = twords{ .all = mulddi3(x.s.low, y.s.low) }; | ||
| 34 | r.s.high +%= x.s.high *% y.s.low +% x.s.low *% y.s.high; | ||
| 35 | return r.all; | ||
| 36 | } | ||
| 37 | |||
| 38 | fn mulddi3(a: u64, b: u64) i128 { | ||
| 39 | const bits_in_dword_2 = (@sizeOf(i64) * 8) / 2; | ||
| 40 | const lower_mask = ~@as(u64, 0) >> bits_in_dword_2; | ||
| 41 | var r: twords = undefined; | ||
| 42 | r.s.low = (a & lower_mask) *% (b & lower_mask); | ||
| 43 | var t: u64 = r.s.low >> bits_in_dword_2; | ||
| 44 | r.s.low &= lower_mask; | ||
| 45 | t +%= (a >> bits_in_dword_2) *% (b & lower_mask); | ||
| 46 | r.s.low +%= (t & lower_mask) << bits_in_dword_2; | ||
| 47 | r.s.high = t >> bits_in_dword_2; | ||
| 48 | t = r.s.low >> bits_in_dword_2; | ||
| 49 | r.s.low &= lower_mask; | ||
| 50 | t +%= (b >> bits_in_dword_2) *% (a & lower_mask); | ||
| 51 | r.s.low +%= (t & lower_mask) << bits_in_dword_2; | ||
| 52 | r.s.high +%= t >> bits_in_dword_2; | ||
| 53 | r.s.high +%= (a >> bits_in_dword_2) *% (b >> bits_in_dword_2); | ||
| 54 | return r.all; | ||
| 55 | } | ||
| 56 | |||
| 57 | const twords = extern union { | ||
| 58 | all: i128, | ||
| 59 | s: S, | ||
| 60 | |||
| 61 | const S = if (native_endian == .Little) | ||
| 62 | extern struct { | ||
| 63 | low: u64, | ||
| 64 | high: u64, | ||
| 65 | } | ||
| 66 | else | ||
| 67 | extern struct { | ||
| 68 | high: u64, | ||
| 69 | low: u64, | ||
| 70 | }; | ||
| 71 | }; | ||
| 72 | |||
| 73 | test { | ||
| 74 | _ = @import("multi3_test.zig"); | ||
| 75 | } | ||
lib/compiler_rt/multi3_test.zig deleted-53| ... | @@ -1,53 +0,0 @@ | ||
| 1 | const __multi3 = @import("multi3.zig").__multi3; | ||
| 2 | const testing = @import("std").testing; | ||
| 3 | |||
| 4 | fn test__multi3(a: i128, b: i128, expected: i128) !void { | ||
| 5 | const x = __multi3(a, b); | ||
| 6 | try testing.expect(x == expected); | ||
| 7 | } | ||
| 8 | |||
| 9 | test "multi3" { | ||
| 10 | try test__multi3(0, 0, 0); | ||
| 11 | try test__multi3(0, 1, 0); | ||
| 12 | try test__multi3(1, 0, 0); | ||
| 13 | try test__multi3(0, 10, 0); | ||
| 14 | try test__multi3(10, 0, 0); | ||
| 15 | try test__multi3(0, 81985529216486895, 0); | ||
| 16 | try test__multi3(81985529216486895, 0, 0); | ||
| 17 | |||
| 18 | try test__multi3(0, -1, 0); | ||
| 19 | try test__multi3(-1, 0, 0); | ||
| 20 | try test__multi3(0, -10, 0); | ||
| 21 | try test__multi3(-10, 0, 0); | ||
| 22 | try test__multi3(0, -81985529216486895, 0); | ||
| 23 | try test__multi3(-81985529216486895, 0, 0); | ||
| 24 | |||
| 25 | try test__multi3(1, 1, 1); | ||
| 26 | try test__multi3(1, 10, 10); | ||
| 27 | try test__multi3(10, 1, 10); | ||
| 28 | try test__multi3(1, 81985529216486895, 81985529216486895); | ||
| 29 | try test__multi3(81985529216486895, 1, 81985529216486895); | ||
| 30 | |||
| 31 | try test__multi3(1, -1, -1); | ||
| 32 | try test__multi3(1, -10, -10); | ||
| 33 | try test__multi3(-10, 1, -10); | ||
| 34 | try test__multi3(1, -81985529216486895, -81985529216486895); | ||
| 35 | try test__multi3(-81985529216486895, 1, -81985529216486895); | ||
| 36 | |||
| 37 | try test__multi3(3037000499, 3037000499, 9223372030926249001); | ||
| 38 | try test__multi3(-3037000499, 3037000499, -9223372030926249001); | ||
| 39 | try test__multi3(3037000499, -3037000499, -9223372030926249001); | ||
| 40 | try test__multi3(-3037000499, -3037000499, 9223372030926249001); | ||
| 41 | |||
| 42 | try test__multi3(4398046511103, 2097152, 9223372036852678656); | ||
| 43 | try test__multi3(-4398046511103, 2097152, -9223372036852678656); | ||
| 44 | try test__multi3(4398046511103, -2097152, -9223372036852678656); | ||
| 45 | try test__multi3(-4398046511103, -2097152, 9223372036852678656); | ||
| 46 | |||
| 47 | try test__multi3(2097152, 4398046511103, 9223372036852678656); | ||
| 48 | try test__multi3(-2097152, 4398046511103, -9223372036852678656); | ||
| 49 | try test__multi3(2097152, -4398046511103, -9223372036852678656); | ||
| 50 | try test__multi3(-2097152, -4398046511103, 9223372036852678656); | ||
| 51 | |||
| 52 | try test__multi3(0x00000000000000B504F333F9DE5BE000, 0x000000000000000000B504F333F9DE5B, 0x7FFFFFFFFFFFF328DF915DA296E8A000); | ||
| 53 | } | ||
lib/compiler_rt/shift.zig+24-40| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | const Log2Int = std.math.Log2Int; | 3 | const Log2Int = std.math.Log2Int; |
| 4 | const native_endian = builtin.cpu.arch.endian(); | ||
| 5 | const common = @import("common.zig"); | 4 | const common = @import("common.zig"); |
| 6 | 5 | ||
| 7 | pub const panic = common.panic; | 6 | pub const panic = common.panic; |
| ... | @@ -27,39 +26,24 @@ comptime { | ... | @@ -27,39 +26,24 @@ comptime { |
| 27 | } | 26 | } |
| 28 | } | 27 | } |
| 29 | 28 | ||
| 30 | fn Dwords(comptime T: type, comptime signed_half: bool) type { | ||
| 31 | return extern union { | ||
| 32 | const bits = @divExact(@typeInfo(T).Int.bits, 2); | ||
| 33 | const HalfTU = std.meta.Int(.unsigned, bits); | ||
| 34 | const HalfTS = std.meta.Int(.signed, bits); | ||
| 35 | const HalfT = if (signed_half) HalfTS else HalfTU; | ||
| 36 | |||
| 37 | all: T, | ||
| 38 | s: if (native_endian == .Little) | ||
| 39 | extern struct { low: HalfT, high: HalfT } | ||
| 40 | else | ||
| 41 | extern struct { high: HalfT, low: HalfT }, | ||
| 42 | }; | ||
| 43 | } | ||
| 44 | |||
| 45 | // Arithmetic shift left: shift in 0 from right to left | 29 | // Arithmetic shift left: shift in 0 from right to left |
| 46 | // Precondition: 0 <= b < bits_in_dword | 30 | // Precondition: 0 <= b < bits_in_dword |
| 47 | inline fn ashlXi3(comptime T: type, a: T, b: i32) T { | 31 | inline fn ashlXi3(comptime T: type, a: T, b: i32) T { |
| 48 | const dwords = Dwords(T, false); | 32 | const word_t = common.HalveInt(T, false); |
| 49 | const S = Log2Int(dwords.HalfT); | 33 | const S = Log2Int(word_t.HalfT); |
| 50 | 34 | ||
| 51 | const input = dwords{ .all = a }; | 35 | const input = word_t{ .all = a }; |
| 52 | var output: dwords = undefined; | 36 | var output: word_t = undefined; |
| 53 | 37 | ||
| 54 | if (b >= dwords.bits) { | 38 | if (b >= word_t.bits) { |
| 55 | output.s.low = 0; | 39 | output.s.low = 0; |
| 56 | output.s.high = input.s.low << @intCast(S, b - dwords.bits); | 40 | output.s.high = input.s.low << @intCast(S, b - word_t.bits); |
| 57 | } else if (b == 0) { | 41 | } else if (b == 0) { |
| 58 | return a; | 42 | return a; |
| 59 | } else { | 43 | } else { |
| 60 | output.s.low = input.s.low << @intCast(S, b); | 44 | output.s.low = input.s.low << @intCast(S, b); |
| 61 | output.s.high = input.s.high << @intCast(S, b); | 45 | output.s.high = input.s.high << @intCast(S, b); |
| 62 | output.s.high |= input.s.low >> @intCast(S, dwords.bits - b); | 46 | output.s.high |= input.s.low >> @intCast(S, word_t.bits - b); |
| 63 | } | 47 | } |
| 64 | 48 | ||
| 65 | return output.all; | 49 | return output.all; |
| ... | @@ -68,24 +52,24 @@ inline fn ashlXi3(comptime T: type, a: T, b: i32) T { | ... | @@ -68,24 +52,24 @@ inline fn ashlXi3(comptime T: type, a: T, b: i32) T { |
| 68 | // Arithmetic shift right: shift in 1 from left to right | 52 | // Arithmetic shift right: shift in 1 from left to right |
| 69 | // Precondition: 0 <= b < T.bit_count | 53 | // Precondition: 0 <= b < T.bit_count |
| 70 | inline fn ashrXi3(comptime T: type, a: T, b: i32) T { | 54 | inline fn ashrXi3(comptime T: type, a: T, b: i32) T { |
| 71 | const dwords = Dwords(T, true); | 55 | const word_t = common.HalveInt(T, true); |
| 72 | const S = Log2Int(dwords.HalfT); | 56 | const S = Log2Int(word_t.HalfT); |
| 73 | 57 | ||
| 74 | const input = dwords{ .all = a }; | 58 | const input = word_t{ .all = a }; |
| 75 | var output: dwords = undefined; | 59 | var output: word_t = undefined; |
| 76 | 60 | ||
| 77 | if (b >= dwords.bits) { | 61 | if (b >= word_t.bits) { |
| 78 | output.s.high = input.s.high >> (dwords.bits - 1); | 62 | output.s.high = input.s.high >> (word_t.bits - 1); |
| 79 | output.s.low = input.s.high >> @intCast(S, b - dwords.bits); | 63 | output.s.low = input.s.high >> @intCast(S, b - word_t.bits); |
| 80 | } else if (b == 0) { | 64 | } else if (b == 0) { |
| 81 | return a; | 65 | return a; |
| 82 | } else { | 66 | } else { |
| 83 | output.s.high = input.s.high >> @intCast(S, b); | 67 | output.s.high = input.s.high >> @intCast(S, b); |
| 84 | output.s.low = input.s.high << @intCast(S, dwords.bits - b); | 68 | output.s.low = input.s.high << @intCast(S, word_t.bits - b); |
| 85 | // Avoid sign-extension here | 69 | // Avoid sign-extension here |
| 86 | output.s.low |= @bitCast( | 70 | output.s.low |= @bitCast( |
| 87 | dwords.HalfT, | 71 | word_t.HalfT, |
| 88 | @bitCast(dwords.HalfTU, input.s.low) >> @intCast(S, b), | 72 | @bitCast(word_t.HalfTU, input.s.low) >> @intCast(S, b), |
| 89 | ); | 73 | ); |
| 90 | } | 74 | } |
| 91 | 75 | ||
| ... | @@ -95,20 +79,20 @@ inline fn ashrXi3(comptime T: type, a: T, b: i32) T { | ... | @@ -95,20 +79,20 @@ inline fn ashrXi3(comptime T: type, a: T, b: i32) T { |
| 95 | // Logical shift right: shift in 0 from left to right | 79 | // Logical shift right: shift in 0 from left to right |
| 96 | // Precondition: 0 <= b < T.bit_count | 80 | // Precondition: 0 <= b < T.bit_count |
| 97 | inline fn lshrXi3(comptime T: type, a: T, b: i32) T { | 81 | inline fn lshrXi3(comptime T: type, a: T, b: i32) T { |
| 98 | const dwords = Dwords(T, false); | 82 | const word_t = common.HalveInt(T, false); |
| 99 | const S = Log2Int(dwords.HalfT); | 83 | const S = Log2Int(word_t.HalfT); |
| 100 | 84 | ||
| 101 | const input = dwords{ .all = a }; | 85 | const input = word_t{ .all = a }; |
| 102 | var output: dwords = undefined; | 86 | var output: word_t = undefined; |
| 103 | 87 | ||
| 104 | if (b >= dwords.bits) { | 88 | if (b >= word_t.bits) { |
| 105 | output.s.high = 0; | 89 | output.s.high = 0; |
| 106 | output.s.low = input.s.high >> @intCast(S, b - dwords.bits); | 90 | output.s.low = input.s.high >> @intCast(S, b - word_t.bits); |
| 107 | } else if (b == 0) { | 91 | } else if (b == 0) { |
| 108 | return a; | 92 | return a; |
| 109 | } else { | 93 | } else { |
| 110 | output.s.high = input.s.high >> @intCast(S, b); | 94 | output.s.high = input.s.high >> @intCast(S, b); |
| 111 | output.s.low = input.s.high << @intCast(S, dwords.bits - b); | 95 | output.s.low = input.s.high << @intCast(S, word_t.bits - b); |
| 112 | output.s.low |= input.s.low >> @intCast(S, b); | 96 | output.s.low |= input.s.low >> @intCast(S, b); |
| 113 | } | 97 | } |
| 114 | 98 |