aboutsummaryrefslogtreecommitdiff
path: root/system/lib/compiler-rt/divdi3.c
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-04-14 09:10:15 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-04-14 09:10:15 -0700
commiteeaacf90a9e80f0b295b16233ea09d1be9cc2222 (patch)
treeb76f952223b5891da2456e685e77e7d3086268b9 /system/lib/compiler-rt/divdi3.c
parentbe558b354748757c88d7476c490c2825ebf67539 (diff)
add compiler-rt files for 64-bit math
Diffstat (limited to 'system/lib/compiler-rt/divdi3.c')
-rw-r--r--system/lib/compiler-rt/divdi3.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/system/lib/compiler-rt/divdi3.c b/system/lib/compiler-rt/divdi3.c
new file mode 100644
index 00000000..2c2bcc26
--- /dev/null
+++ b/system/lib/compiler-rt/divdi3.c
@@ -0,0 +1,31 @@
+/* ===-- divdi3.c - Implement __divdi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+du_int COMPILER_RT_ABI __udivmoddi4(du_int a, du_int b, du_int* rem);
+
+/* Returns: a / b */
+
+COMPILER_RT_ABI di_int
+__divdi3(di_int a, di_int b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
+ di_int s_a = a >> bits_in_dword_m1; /* s_a = a < 0 ? -1 : 0 */
+ di_int s_b = b >> bits_in_dword_m1; /* s_b = b < 0 ? -1 : 0 */
+ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
+ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
+ s_a ^= s_b; /*sign of quotient */
+ return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */
+}