authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-04-28 16:12:44+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-04-29 19:17:48+02:00
log738562e99071e31bf3a7d9227d34415252556737
tree0451014638f1dff87318e66ba7c8bb5aa8605c74
parentd02489fd9a56588bad800afcc18fc58b07f19b56

compiler-rt: Add __divsi3, __aeabi_idiv


1 files changed, 42 insertions(+), 0 deletions(-)

std/special/compiler_rt.zig+42
...@@ -102,6 +102,7 @@ comptime {...@@ -102,6 +102,7 @@ comptime {
102 @export("__udivmoddi4", @import("compiler_rt/udivmoddi4.zig").__udivmoddi4, linkage);102 @export("__udivmoddi4", @import("compiler_rt/udivmoddi4.zig").__udivmoddi4, linkage);
103 @export("__popcountdi2", @import("compiler_rt/popcountdi2.zig").__popcountdi2, linkage);103 @export("__popcountdi2", @import("compiler_rt/popcountdi2.zig").__popcountdi2, linkage);
104104
105 @export("__divsi3", __divsi3, linkage);
105 @export("__udivsi3", __udivsi3, linkage);106 @export("__udivsi3", __udivsi3, linkage);
106 @export("__udivdi3", __udivdi3, linkage);107 @export("__udivdi3", __udivdi3, linkage);
107 @export("__umoddi3", __umoddi3, linkage);108 @export("__umoddi3", __umoddi3, linkage);
...@@ -113,6 +114,8 @@ comptime {...@@ -113,6 +114,8 @@ comptime {
113 if (is_arm_arch and !is_arm_64) {114 if (is_arm_arch and !is_arm_64) {
114 @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);115 @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
115 @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);116 @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
117
118 @export("__aeabi_idiv", __divsi3, linkage);
116 @export("__aeabi_uidiv", __udivsi3, linkage);119 @export("__aeabi_uidiv", __udivsi3, linkage);
117120
118 @export("__aeabi_memcpy", __aeabi_memcpy, linkage);121 @export("__aeabi_memcpy", __aeabi_memcpy, linkage);
...@@ -566,6 +569,20 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 {...@@ -566,6 +569,20 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 {
566 return d;569 return d;
567}570}
568571
572extern fn __divsi3(n: i32, d: i32) i32 {
573 @setRuntimeSafety(is_test);
574
575 // Set aside the sign of the quotient.
576 const sign = @bitCast(u32, (n ^ d) >> 31);
577 // Take absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31).
578 const abs_n = (n ^ (n >> 31)) -% (n >> 31);
579 const abs_d = (d ^ (d >> 31)) -% (d >> 31);
580 // abs(a) / abs(b)
581 const res = @bitCast(u32, abs_n) / @bitCast(u32, abs_d);
582 // Apply sign of quotient to result and return.
583 return @bitCast(i32, (res ^ sign) -% sign);
584}
585
569extern fn __udivsi3(n: u32, d: u32) u32 {586extern fn __udivsi3(n: u32, d: u32) u32 {
570 @setRuntimeSafety(is_test);587 @setRuntimeSafety(is_test);
571588
...@@ -1293,3 +1310,28 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {...@@ -1293,3 +1310,28 @@ fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
1293 const q: u32 = __udivsi3(a, b);1310 const q: u32 = __udivsi3(a, b);
1294 testing.expect(q == expected_q);1311 testing.expect(q == expected_q);
1295}1312}
1313
1314test "test_divsi3" {
1315 const cases = [][3]i32{
1316 []i32{ 0, 1, 0},
1317 []i32{ 0, -1, 0},
1318 []i32{ 2, 1, 2},
1319 []i32{ 2, -1, -2},
1320 []i32{-2, 1, -2},
1321 []i32{-2, -1, 2},
1322
1323 []i32{@bitCast(i32, u32(0x80000000)), 1, @bitCast(i32, u32(0x80000000))},
1324 []i32{@bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000))},
1325 []i32{@bitCast(i32, u32(0x80000000)), -2, 0x40000000},
1326 []i32{@bitCast(i32, u32(0x80000000)), 2, @bitCast(i32, u32(0xC0000000))},
1327 };
1328
1329 for (cases) |case| {
1330 test_one_divsi3(case[0], case[1], case[2]);
1331 }
1332}
1333
1334fn test_one_divsi3(a: i32, b: i32, expected_q: i32) void {
1335 const q: i32 = __divsi3(a, b);
1336 testing.expect(q == expected_q);
1337}