authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-22 16:07:51+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-22 13:04:45-05:00
log69c72e24d4aa2044bb9de0c101517af7afe555de
tree8ec1438bc626c0d103b0618abd1ae7189031991e
parentc522699f28c1df806865c527a7a68a875e606527

compiler-rt: Port __mulsi3 builtin


2 files changed, 61 insertions(+), 0 deletions(-)

lib/std/special/compiler_rt.zig+1
...@@ -130,6 +130,7 @@ comptime {...@@ -130,6 +130,7 @@ comptime {
130 @export(@import("compiler_rt/int.zig").__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });130 @export(@import("compiler_rt/int.zig").__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
131 @export(@import("compiler_rt/popcountdi2.zig").__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });131 @export(@import("compiler_rt/popcountdi2.zig").__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });
132132
133 @export(@import("compiler_rt/int.zig").__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
133 @export(@import("compiler_rt/muldi3.zig").__muldi3, .{ .name = "__muldi3", .linkage = linkage });134 @export(@import("compiler_rt/muldi3.zig").__muldi3, .{ .name = "__muldi3", .linkage = linkage });
134 @export(@import("compiler_rt/int.zig").__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });135 @export(@import("compiler_rt/int.zig").__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
135 @export(@import("compiler_rt/int.zig").__divsi3, .{ .name = "__divsi3", .linkage = linkage });136 @export(@import("compiler_rt/int.zig").__divsi3, .{ .name = "__divsi3", .linkage = linkage });
lib/std/special/compiler_rt/int.zig+60
...@@ -1,6 +1,8 @@...@@ -1,6 +1,8 @@
1// Builtin functions that operate on integer types1// Builtin functions that operate on integer types
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const testing = @import("std").testing;3const testing = @import("std").testing;
4const maxInt = @import("std").math.maxInt;
5const minInt = @import("std").math.maxInt;
46
5const udivmod = @import("udivmod.zig").udivmod;7const udivmod = @import("udivmod.zig").udivmod;
68
...@@ -578,3 +580,61 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) void {...@@ -578,3 +580,61 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) void {
578 const r: u32 = __umodsi3(a, b);580 const r: u32 = __umodsi3(a, b);
579 testing.expect(r == expected_r);581 testing.expect(r == expected_r);
580}582}
583
584pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 {
585 @setRuntimeSafety(builtin.is_test);
586
587 var ua = @bitCast(u32, a);
588 var ub = @bitCast(u32, b);
589 var r: u32 = 0;
590
591 while (ua > 0) {
592 if ((ua & 1) != 0) r +%= ub;
593 ua >>= 1;
594 ub <<= 1;
595 }
596
597 return @bitCast(i32, r);
598}
599
600fn test_one_mulsi3(a: i32, b: i32, result: i32) void {
601 testing.expectEqual(result, __mulsi3(a, b));
602}
603
604test "mulsi3" {
605 test_one_mulsi3(0, 0, 0);
606 test_one_mulsi3(0, 1, 0);
607 test_one_mulsi3(1, 0, 0);
608 test_one_mulsi3(0, 10, 0);
609 test_one_mulsi3(10, 0, 0);
610 test_one_mulsi3(0, maxInt(i32), 0);
611 test_one_mulsi3(maxInt(i32), 0, 0);
612 test_one_mulsi3(0, -1, 0);
613 test_one_mulsi3(-1, 0, 0);
614 test_one_mulsi3(0, -10, 0);
615 test_one_mulsi3(-10, 0, 0);
616 test_one_mulsi3(0, minInt(i32), 0);
617 test_one_mulsi3(minInt(i32), 0, 0);
618 test_one_mulsi3(1, 1, 1);
619 test_one_mulsi3(1, 10, 10);
620 test_one_mulsi3(10, 1, 10);
621 test_one_mulsi3(1, maxInt(i32), maxInt(i32));
622 test_one_mulsi3(maxInt(i32), 1, maxInt(i32));
623 test_one_mulsi3(1, -1, -1);
624 test_one_mulsi3(1, -10, -10);
625 test_one_mulsi3(-10, 1, -10);
626 test_one_mulsi3(1, minInt(i32), minInt(i32));
627 test_one_mulsi3(minInt(i32), 1, minInt(i32));
628 test_one_mulsi3(46340, 46340, 2147395600);
629 test_one_mulsi3(-46340, 46340, -2147395600);
630 test_one_mulsi3(46340, -46340, -2147395600);
631 test_one_mulsi3(-46340, -46340, 2147395600);
632 test_one_mulsi3(4194303, 8192, @truncate(i32, 34359730176));
633 test_one_mulsi3(-4194303, 8192, @truncate(i32, -34359730176));
634 test_one_mulsi3(4194303, -8192, @truncate(i32, -34359730176));
635 test_one_mulsi3(-4194303, -8192, @truncate(i32, 34359730176));
636 test_one_mulsi3(8192, 4194303, @truncate(i32, 34359730176));
637 test_one_mulsi3(-8192, 4194303, @truncate(i32, -34359730176));
638 test_one_mulsi3(8192, -4194303, @truncate(i32, -34359730176));
639 test_one_mulsi3(-8192, -4194303, @truncate(i32, 34359730176));
640}