# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1245837420 -3600
# Node ID 50634c215234e15dc8f4b324d9ee3b5fad779c34
# Parent 82bbce59b65d568390305f559354b7b1a342fa4c
Move muldiv64 out and make it as a public function.
muldiv64 is used to caculate u64*u32/u32, and we
will use it for TSC scaling.
Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
xen/arch/x86/hvm/i8254.c | 24 ------------------------
xen/common/lib.c | 29 +++++++++++++++++++++++++++++
xen/include/xen/lib.h | 2 ++
3 files changed, 31 insertions(+), 24 deletions(-)
diff -r 82bbce59b65d -r 50634c215234 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c Wed Jun 24 10:48:21 2009 +0100
+++ b/xen/arch/x86/hvm/i8254.c Wed Jun 24 10:57:00 2009 +0100
@@ -56,30 +56,6 @@ static int handle_speaker_io(
#define get_guest_time(v) \
(is_hvm_vcpu(v) ? hvm_get_guest_time(v) : (u64)get_s_time())
-
-/* Compute with 96 bit intermediate result: (a*b)/c */
-static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
- union {
- uint64_t ll;
- struct {
-#ifdef WORDS_BIGENDIAN
- uint32_t high, low;
-#else
- uint32_t low, high;
-#endif
- } l;
- } u, res;
- uint64_t rl, rh;
-
- u.ll = a;
- rl = (uint64_t)u.l.low * (uint64_t)b;
- rh = (uint64_t)u.l.high * (uint64_t)b;
- rh += (rl >> 32);
- res.l.high = rh / c;
- res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
- return res.ll;
-}
static int pit_get_count(PITState *pit, int channel)
{
diff -r 82bbce59b65d -r 50634c215234 xen/common/lib.c
--- a/xen/common/lib.c Wed Jun 24 10:48:21 2009 +0100
+++ b/xen/common/lib.c Wed Jun 24 10:57:00 2009 +0100
@@ -401,6 +401,35 @@ s64 __moddi3(s64 a, s64 b)
#endif /* BITS_PER_LONG == 32 */
+/* Compute with 96 bit intermediate result: (a*b)/c */
+uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+#ifdef __x86_64__
+ asm ( "mul %%rdx; div %%rcx" : "=a" (a) : "0" (a), "d" (b), "c" (c) );
+ return a;
+#else
+ union {
+ uint64_t ll;
+ struct {
+#ifdef WORDS_BIGENDIAN
+ uint32_t high, low;
+#else
+ uint32_t low, high;
+#endif
+ } l;
+ } u, res;
+ uint64_t rl, rh;
+
+ u.ll = a;
+ rl = (uint64_t)u.l.low * (uint64_t)b;
+ rh = (uint64_t)u.l.high * (uint64_t)b;
+ rh += (rl >> 32);
+ res.l.high = rh / c;
+ res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+ return res.ll;
+#endif
+}
+
unsigned long long parse_size_and_unit(const char *s, const char **ps)
{
unsigned long long ret;
diff -r 82bbce59b65d -r 50634c215234 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h Wed Jun 24 10:48:21 2009 +0100
+++ b/xen/include/xen/lib.h Wed Jun 24 10:57:00 2009 +0100
@@ -99,6 +99,8 @@ unsigned long long simple_strtoull(
unsigned long long parse_size_and_unit(const char *s, const char **ps);
+uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
+
#define TAINT_UNSAFE_SMP (1<<0)
#define TAINT_MACHINE_CHECK (1<<1)
#define TAINT_BAD_PAGE (1<<2)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|