Skip to content

Commit

Permalink
compiler-rt: Port __mulsi3 builtin
Browse files Browse the repository at this point in the history
  • Loading branch information
LemonBoy authored and andrewrk committed Jan 22, 2020
1 parent c522699 commit 69c72e2
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/std/special/compiler_rt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ comptime {
@export(@import("compiler_rt/int.zig").__udivmoddi4, .{ .name = "__udivmoddi4", .linkage = linkage });
@export(@import("compiler_rt/popcountdi2.zig").__popcountdi2, .{ .name = "__popcountdi2", .linkage = linkage });

@export(@import("compiler_rt/int.zig").__mulsi3, .{ .name = "__mulsi3", .linkage = linkage });
@export(@import("compiler_rt/muldi3.zig").__muldi3, .{ .name = "__muldi3", .linkage = linkage });
@export(@import("compiler_rt/int.zig").__divmoddi4, .{ .name = "__divmoddi4", .linkage = linkage });
@export(@import("compiler_rt/int.zig").__divsi3, .{ .name = "__divsi3", .linkage = linkage });
Expand Down
60 changes: 60 additions & 0 deletions lib/std/special/compiler_rt/int.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Builtin functions that operate on integer types
const builtin = @import("builtin");
const testing = @import("std").testing;
const maxInt = @import("std").math.maxInt;
const minInt = @import("std").math.maxInt;

This comment has been minimized.

Copy link
@steveno

steveno Jan 22, 2020

You have minint set to maxint here.

This comment has been minimized.

Copy link
@mikdusan

mikdusan Jan 23, 2020

Member

It doesn't current effect the new tests one way or the other but certainly down the road may have caused problems. Thanks, fixed in 357f42d


const udivmod = @import("udivmod.zig").udivmod;

Expand Down Expand Up @@ -578,3 +580,61 @@ fn test_one_umodsi3(a: u32, b: u32, expected_r: u32) void {
const r: u32 = __umodsi3(a, b);
testing.expect(r == expected_r);
}

pub fn __mulsi3(a: i32, b: i32) callconv(.C) i32 {
@setRuntimeSafety(builtin.is_test);

var ua = @bitCast(u32, a);
var ub = @bitCast(u32, b);
var r: u32 = 0;

while (ua > 0) {
if ((ua & 1) != 0) r +%= ub;
ua >>= 1;
ub <<= 1;
}

return @bitCast(i32, r);
}

fn test_one_mulsi3(a: i32, b: i32, result: i32) void {
testing.expectEqual(result, __mulsi3(a, b));
}

test "mulsi3" {
test_one_mulsi3(0, 0, 0);
test_one_mulsi3(0, 1, 0);
test_one_mulsi3(1, 0, 0);
test_one_mulsi3(0, 10, 0);
test_one_mulsi3(10, 0, 0);
test_one_mulsi3(0, maxInt(i32), 0);
test_one_mulsi3(maxInt(i32), 0, 0);
test_one_mulsi3(0, -1, 0);
test_one_mulsi3(-1, 0, 0);
test_one_mulsi3(0, -10, 0);
test_one_mulsi3(-10, 0, 0);
test_one_mulsi3(0, minInt(i32), 0);
test_one_mulsi3(minInt(i32), 0, 0);
test_one_mulsi3(1, 1, 1);
test_one_mulsi3(1, 10, 10);
test_one_mulsi3(10, 1, 10);
test_one_mulsi3(1, maxInt(i32), maxInt(i32));
test_one_mulsi3(maxInt(i32), 1, maxInt(i32));
test_one_mulsi3(1, -1, -1);
test_one_mulsi3(1, -10, -10);
test_one_mulsi3(-10, 1, -10);
test_one_mulsi3(1, minInt(i32), minInt(i32));
test_one_mulsi3(minInt(i32), 1, minInt(i32));
test_one_mulsi3(46340, 46340, 2147395600);
test_one_mulsi3(-46340, 46340, -2147395600);
test_one_mulsi3(46340, -46340, -2147395600);
test_one_mulsi3(-46340, -46340, 2147395600);
test_one_mulsi3(4194303, 8192, @truncate(i32, 34359730176));
test_one_mulsi3(-4194303, 8192, @truncate(i32, -34359730176));
test_one_mulsi3(4194303, -8192, @truncate(i32, -34359730176));
test_one_mulsi3(-4194303, -8192, @truncate(i32, 34359730176));
test_one_mulsi3(8192, 4194303, @truncate(i32, 34359730176));
test_one_mulsi3(-8192, 4194303, @truncate(i32, -34359730176));
test_one_mulsi3(8192, -4194303, @truncate(i32, -34359730176));
test_one_mulsi3(-8192, -4194303, @truncate(i32, 34359730176));
}

0 comments on commit 69c72e2

Please sign in to comment.