| ... | @@ -9,10 +9,12 @@ const arch = builtin.cpu.arch; | ... | @@ -9,10 +9,12 @@ const arch = builtin.cpu.arch; |
| 9 | const is_test = builtin.is_test; | 9 | const is_test = builtin.is_test; |
| 10 | const common = @import("common.zig"); | 10 | const common = @import("common.zig"); |
| 11 | const udivmod = @import("udivmod.zig").udivmod; | 11 | const udivmod = @import("udivmod.zig").udivmod; |
| | 12 | const __divti3 = @import("divti3.zig").__divti3; |
| 12 | | 13 | |
| 13 | pub const panic = common.panic; | 14 | pub const panic = common.panic; |
| 14 | | 15 | |
| 15 | comptime { | 16 | comptime { |
| | 17 | @export(__divmodti4, .{ .name = "__divmodti4", .linkage = common.linkage, .visibility = common.visibility }); |
| 16 | @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = common.linkage, .visibility = common.visibility }); | 18 | @export(__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = common.linkage, .visibility = common.visibility }); |
| 17 | @export(__mulsi3, .{ .name = "__mulsi3", .linkage = common.linkage, .visibility = common.visibility }); | 19 | @export(__mulsi3, .{ .name = "__mulsi3", .linkage = common.linkage, .visibility = common.visibility }); |
| 18 | @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = common.linkage, .visibility = common.visibility }); | 20 | @export(__divmoddi4, .{ .name = "__divmoddi4", .linkage = common.linkage, .visibility = common.visibility }); |
| ... | @@ -33,12 +35,72 @@ comptime { | ... | @@ -33,12 +35,72 @@ comptime { |
| 33 | @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = common.linkage, .visibility = common.visibility }); | 35 | @export(__udivmodsi4, .{ .name = "__udivmodsi4", .linkage = common.linkage, .visibility = common.visibility }); |
| 34 | } | 36 | } |
| 35 | | 37 | |
| | 38 | pub fn __divmodti4(a: i128, b: i128, rem: *i128) callconv(.C) i128 { |
| | 39 | const d = __divti3(a, b); |
| | 40 | rem.* = a -% (d * b); |
| | 41 | return d; |
| | 42 | } |
| | 43 | |
| | 44 | test "test_divmodti4" { |
| | 45 | const cases = [_][4]i128{ |
| | 46 | [_]i128{ 0, 1, 0, 0 }, |
| | 47 | [_]i128{ 0, -1, 0, 0 }, |
| | 48 | [_]i128{ 2, 1, 2, 0 }, |
| | 49 | [_]i128{ 2, -1, -2, 0 }, |
| | 50 | [_]i128{ -2, 1, -2, 0 }, |
| | 51 | [_]i128{ -2, -1, 2, 0 }, |
| | 52 | [_]i128{ 7, 5, 1, 2 }, |
| | 53 | [_]i128{ -7, 5, -1, -2 }, |
| | 54 | [_]i128{ 19, 5, 3, 4 }, |
| | 55 | [_]i128{ 19, -5, -3, 4 }, |
| | 56 | [_]i128{ @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 8, @bitCast(i128, @as(u128, 0xf0000000000000000000000000000000)), 0 }, |
| | 57 | [_]i128{ @bitCast(i128, @as(u128, 0x80000000000000000000000000000007)), 8, @bitCast(i128, @as(u128, 0xf0000000000000000000000000000001)), -1 }, |
| | 58 | }; |
| | 59 | |
| | 60 | for (cases) |case| { |
| | 61 | try test_one_divmodti4(case[0], case[1], case[2], case[3]); |
| | 62 | } |
| | 63 | } |
| | 64 | |
| | 65 | fn test_one_divmodti4(a: i128, b: i128, expected_q: i128, expected_r: i128) !void { |
| | 66 | var r: i128 = undefined; |
| | 67 | const q: i128 = __divmodti4(a, b, &r); |
| | 68 | try testing.expect(q == expected_q and r == expected_r); |
| | 69 | } |
| | 70 | |
| 36 | pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.C) i64 { | 71 | pub fn __divmoddi4(a: i64, b: i64, rem: *i64) callconv(.C) i64 { |
| 37 | const d = __divdi3(a, b); | 72 | const d = __divdi3(a, b); |
| 38 | rem.* = a -% (d *% b); | 73 | rem.* = a -% (d * b); |
| 39 | return d; | 74 | return d; |
| 40 | } | 75 | } |
| 41 | | 76 | |
| | 77 | test "test_divmoddi4" { |
| | 78 | const cases = [_][4]i64{ |
| | 79 | [_]i64{ 0, 1, 0, 0 }, |
| | 80 | [_]i64{ 0, -1, 0, 0 }, |
| | 81 | [_]i64{ 2, 1, 2, 0 }, |
| | 82 | [_]i64{ 2, -1, -2, 0 }, |
| | 83 | [_]i64{ -2, 1, -2, 0 }, |
| | 84 | [_]i64{ -2, -1, 2, 0 }, |
| | 85 | [_]i64{ 7, 5, 1, 2 }, |
| | 86 | [_]i64{ -7, 5, -1, -2 }, |
| | 87 | [_]i64{ 19, 5, 3, 4 }, |
| | 88 | [_]i64{ 19, -5, -3, 4 }, |
| | 89 | [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 8, @bitCast(i64, @as(u64, 0xf000000000000000)), 0 }, |
| | 90 | [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000007)), 8, @bitCast(i64, @as(u64, 0xf000000000000001)), -1 }, |
| | 91 | }; |
| | 92 | |
| | 93 | for (cases) |case| { |
| | 94 | try test_one_divmoddi4(case[0], case[1], case[2], case[3]); |
| | 95 | } |
| | 96 | } |
| | 97 | |
| | 98 | fn test_one_divmoddi4(a: i64, b: i64, expected_q: i64, expected_r: i64) !void { |
| | 99 | var r: i64 = undefined; |
| | 100 | const q: i64 = __divmoddi4(a, b, &r); |
| | 101 | try testing.expect(q == expected_q and r == expected_r); |
| | 102 | } |
| | 103 | |
| 42 | pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.C) u64 { | 104 | pub fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?*u64) callconv(.C) u64 { |
| 43 | return udivmod(u64, a, b, maybe_rem); | 105 | return udivmod(u64, a, b, maybe_rem); |
| 44 | } | 106 | } |
| ... | @@ -424,7 +486,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { | ... | @@ -424,7 +486,7 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) !void { |
| 424 | } | 486 | } |
| 425 | | 487 | |
| 426 | pub fn __modsi3(n: i32, d: i32) callconv(.C) i32 { | 488 | pub fn __modsi3(n: i32, d: i32) callconv(.C) i32 { |
| 427 | return n -% __divsi3(n, d) *% d; | 489 | return n -% __divsi3(n, d) * d; |
| 428 | } | 490 | } |
| 429 | | 491 | |
| 430 | test "test_modsi3" { | 492 | test "test_modsi3" { |
| ... | @@ -453,7 +515,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { | ... | @@ -453,7 +515,7 @@ fn test_one_modsi3(a: i32, b: i32, expected_r: i32) !void { |
| 453 | } | 515 | } |
| 454 | | 516 | |
| 455 | pub fn __umodsi3(n: u32, d: u32) callconv(.C) u32 { | 517 | pub fn __umodsi3(n: u32, d: u32) callconv(.C) u32 { |
| 456 | return n -% __udivsi3(n, d) *% d; | 518 | return n -% __udivsi3(n, d) * d; |
| 457 | } | 519 | } |
| 458 | | 520 | |
| 459 | test "test_umodsi3" { | 521 | test "test_umodsi3" { |