xen/arch/x86/include/asm/muldiv.h | 20 ++++++++++++++++++++ xen/include/xen/muldiv.h | 8 ++++++++ xen/lib/muldiv64.c | 8 -------- 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 xen/arch/x86/include/asm/muldiv.h
Having an #ifdef CONFIG_X86 section in a common library is rude.
Furthermore, for x86 the main logic is 6 bytes, meaning it's ripe for
inlining. Create an x86-specific asm/muldiv.h implementing arch_muldiv64().
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
CC: Bertrand Marquis <bertrand.marquis@arm.com>
CC: Michal Orzel <michal.orzel@amd.com>
CC: Oleksii Kurochko <oleksii.kurochko@gmail.com>
bloat-o-meter results:
add/remove: 0/1 grow/shrink: 1/2 up/down: 10/-39 (-29)
Function old new delta
get_count 240 250 +10
calibrate_apic_timer 211 203 -8
calibrate_tsc 190 177 -13
muldiv64 18 - -18
The increase in get_count is from different register scheduling.
---
xen/arch/x86/include/asm/muldiv.h | 20 ++++++++++++++++++++
xen/include/xen/muldiv.h | 8 ++++++++
xen/lib/muldiv64.c | 8 --------
3 files changed, 28 insertions(+), 8 deletions(-)
create mode 100644 xen/arch/x86/include/asm/muldiv.h
diff --git a/xen/arch/x86/include/asm/muldiv.h b/xen/arch/x86/include/asm/muldiv.h
new file mode 100644
index 000000000000..563cab0564da
--- /dev/null
+++ b/xen/arch/x86/include/asm/muldiv.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef X86_MULDIV_H
+#define X86_MULDIV_H
+
+#include <xen/stdint.h>
+
+static inline uint64_t attr_const arch_muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+ asm_inline (
+ "mulq %[b]\n\t"
+ "divq %[c]"
+ : "+a" (a)
+ : [b] "rm" ((uint64_t)b), [c] "rm" ((uint64_t)c)
+ : "rdx" );
+
+ return a;
+}
+#define arch_muldiv64 arch_muldiv64
+
+#endif /* X86_MULDIV_H */
diff --git a/xen/include/xen/muldiv.h b/xen/include/xen/muldiv.h
index 8ed2c68caf84..e7f8fdcf01ea 100644
--- a/xen/include/xen/muldiv.h
+++ b/xen/include/xen/muldiv.h
@@ -4,6 +4,10 @@
#include <xen/stdint.h>
+#if __has_include(<asm/muldiv.h>)
+# include <asm/muldiv.h>
+#endif
+
uint64_t attr_const generic_muldiv64(uint64_t a, uint32_t b, uint32_t c);
/*
@@ -12,7 +16,11 @@ uint64_t attr_const generic_muldiv64(uint64_t a, uint32_t b, uint32_t c);
*/
static inline uint64_t attr_const muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
+#ifdef arch_muldiv64
+ return arch_muldiv64(a, b, c);
+#else
return generic_muldiv64(a, b, c);
+#endif
}
#endif /* XEN_MULDIV_H */
diff --git a/xen/lib/muldiv64.c b/xen/lib/muldiv64.c
index 5e6db1b2f4d2..6ee86d124a21 100644
--- a/xen/lib/muldiv64.c
+++ b/xen/lib/muldiv64.c
@@ -2,13 +2,6 @@
uint64_t generic_muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
-#ifdef CONFIG_X86
- asm ( "mulq %1; divq %2" : "+a" (a)
- : "rm" ((uint64_t)b), "rm" ((uint64_t)c)
- : "rdx" );
-
- return a;
-#else
union {
uint64_t ll;
struct {
@@ -31,7 +24,6 @@ uint64_t generic_muldiv64(uint64_t a, uint32_t b, uint32_t c)
res.l.low = (((rh % c) << 32) + (uint32_t)rl) / c;
return res.ll;
-#endif
}
/*
--
2.39.5
© 2016 - 2026 Red Hat, Inc.