genode/repos/base-foc/patches/0024-FOC-ia32-add-implementation-for-__udivmoddi4.patch
2023-05-30 12:03:25 +02:00

95 lines
2.6 KiB
Diff

From 8d55cdc73b07dd56ae59a42bcc11cde82614334a Mon Sep 17 00:00:00 2001
From: Frank Mehnert <frank.mehnert@kernkonzept.com>
Date: Mon, 10 May 2021 00:00:00 +0000
Subject: [PATCH] ia32: add implementation for '__udivmoddi4()'
This function is implicitly required by code in jdb.cpp performing a
64-bit integer division on 32-bit systems. This function is required
by code generated with gcc-11. Code generated with older versions of
gcc was satisfied with the existing implementation for '__udivdi3'.
Also fix cosmetic issues in gcc_lib.c and add Doxygen documentation.
Change-Id: If5b44a9e98429c4fc3eacdd5af8bdaf33c9c2a8f
---
src/lib/libk/gcc_lib.c | 49 +++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 8 deletions(-)
diff --git a/src/lib/libk/gcc_lib.c b/src/lib/libk/gcc_lib.c
index e5626145..b121cb63 100644
--- a/src/lib/libk/gcc_lib.c
+++ b/src/lib/libk/gcc_lib.c
@@ -1,6 +1,8 @@
unsigned long long __umoddi3(unsigned long long, unsigned long long);
unsigned long long __udivdi3(unsigned long long, unsigned long long);
+unsigned long long __udivmoddi4(unsigned long long, unsigned long long,
+ unsigned long long *);
struct llmoddiv_t
{
@@ -31,15 +33,15 @@ static struct llmoddiv_t llmoddiv(unsigned long long div, unsigned long long s)
while (1)
{
if (div >= s)
- {
- div -= s;
- i |= tmp;
- }
+ {
+ div -= s;
+ i |= tmp;
+ }
if (div == 0)
- break;
+ break;
tmp >>= 1;
if (!tmp)
- break;
+ break;
s >>= 1;
}
@@ -47,8 +49,39 @@ static struct llmoddiv_t llmoddiv(unsigned long long div, unsigned long long s)
}
+/**
+ * 64-bit unsigned modulo for 32-bit machines.
+ *
+ * \param div Dividend.
+ * \param s Divisor.
+ * \return div / s.
+ */
unsigned long long __umoddi3(unsigned long long div, unsigned long long s)
-{ return llmoddiv(div,s).mod; }
+{ return llmoddiv(div, s).mod; }
+/**
+ * 64-bit unsigned division for 32-bit machines.
+ *
+ * \param div Dividend.
+ * \param s Divisor.
+ * \return div / s.
+ */
unsigned long long __udivdi3(unsigned long long div, unsigned long long s)
-{ return llmoddiv(div,s).div; }
+{ return llmoddiv(div, s).div; }
+
+/**
+ * 64-bit unsigned division + modulo for 32-bit machines.
+ *
+ * \param n Dividend.
+ * \param d Divisor.
+ * \param[out] r Pointer to the result holding div % s.
+ * \return div / s.
+ */
+unsigned long long __udivmoddi4(unsigned long long div, unsigned long long s,
+ unsigned long long *r)
+{
+ struct llmoddiv_t md = llmoddiv(div, s);
+ if (r)
+ *r = md.mod;
+ return md.div;
+}