Commit c00167e91a

LemonBoy <thatlemon@gmail.com>
2019-05-08 22:30:20
compiler-rt: More division intrinsics
1 parent 9171037
Changed files (1)
std
std/special/compiler_rt.zig
@@ -111,6 +111,7 @@ comptime {
     @export("__udivmoddi4", @import("compiler_rt/udivmoddi4.zig").__udivmoddi4, linkage);
     @export("__popcountdi2", @import("compiler_rt/popcountdi2.zig").__popcountdi2, linkage);
 
+    @export("__divmoddi4", __divmoddi4, linkage);
     @export("__divsi3", __divsi3, linkage);
     @export("__divdi3", __divdi3, linkage);
     @export("__udivsi3", __udivsi3, linkage);
@@ -126,10 +127,11 @@ comptime {
     @export("__negdf2", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
 
     if (is_arm_arch and !is_arm_64) {
+        @export("__aeabi_ldivmod", __aeabi_ldivmod, linkage);
         @export("__aeabi_uldivmod", __aeabi_uldivmod, linkage);
 
         @export("__aeabi_idiv", __divsi3, linkage);
-        @export("__aeabi_idivmod", __divmodsi4, linkage);
+        @export("__aeabi_idivmod", __aeabi_idivmod, linkage);
         @export("__aeabi_uidiv", __udivsi3, linkage);
         @export("__aeabi_uidivmod", __aeabi_uidivmod, linkage);
 
@@ -256,6 +258,14 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn
     }
 }
 
+extern fn __divmoddi4(a: i64, b: i64, rem: *i64) i64 {
+    @setRuntimeSafety(is_test);
+
+    const d = __divdi3(a, b);
+    rem.* = a -% (d *% b);
+    return d;
+}
+
 extern fn __divdi3(a: i64, b: i64) i64 {
     @setRuntimeSafety(is_test);
 
@@ -296,14 +306,35 @@ extern fn __umoddi3(a: u64, b: u64) u64 {
     return r;
 }
 
-const AeabiUlDivModResult = extern struct {
-    quot: u64,
-    rem: u64,
-};
-extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult {
+extern fn __aeabi_uidivmod(n: u32, d: u32) extern struct{q: u32, r: u32} {
     @setRuntimeSafety(is_test);
-    var result: AeabiUlDivModResult = undefined;
-    result.quot = __udivmoddi4(numerator, denominator, &result.rem);
+
+    var result: @typeOf(__aeabi_uidivmod).ReturnType = undefined;
+    result.q = __udivmodsi4(n, d, &result.r);
+    return result;
+}
+
+extern fn __aeabi_uldivmod(n: u64, d: u64) extern struct{q: u64, r: u64} {
+    @setRuntimeSafety(is_test);
+
+    var result: @typeOf(__aeabi_uldivmod).ReturnType = undefined;
+    result.q = __udivmoddi4(n, d, &result.r);
+    return result;
+}
+
+extern fn __aeabi_idivmod(n: i32, d: i32) extern struct{q: i32, r: i32} {
+    @setRuntimeSafety(is_test);
+
+    var result: @typeOf(__aeabi_idivmod).ReturnType = undefined;
+    result.q = __divmodsi4(n, d, &result.r);
+    return result;
+}
+
+extern fn __aeabi_ldivmod(n: i64, d: i64) extern struct{q: i64, r:i64} {
+    @setRuntimeSafety(is_test);
+
+    var result: @typeOf(__aeabi_ldivmod).ReturnType = undefined;
+    result.q = __divmoddi4(n, d, &result.r);
     return result;
 }
 
@@ -397,22 +428,6 @@ test "usesThumb1" {
     //etc.
 }
 
-nakedcc fn __aeabi_uidivmod() void {
-    @setRuntimeSafety(false);
-    asm volatile (
-        \\ push    { lr }
-        \\ sub     sp, sp, #4
-        \\ mov     r2, sp
-        \\ bl      __udivmodsi4
-        \\ ldr     r1, [sp]
-        \\ add     sp, sp, #4
-        \\ pop     { pc }
-            :
-        :
-        : "r2", "r1"
-    );
-}
-
 nakedcc fn __aeabi_memcpy() noreturn {
     @setRuntimeSafety(false);
     if (use_thumb_1) {