[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v2 05/19] host-utils: Add muldiv64_round_up
From: |
Nicholas Piggin |
Subject: |
[PATCH v2 05/19] host-utils: Add muldiv64_round_up |
Date: |
Tue, 8 Aug 2023 14:19:47 +1000 |
This will be used for converting time intervals in different base units
to host units, for the purpose of scheduling timers to emulate target
timers. Timers typically must not fire before their requested expiry
time but may fire some time afterward, so rounding up is the right way
to implement these.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
include/qemu/host-utils.h | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 011618373e..e2a50a567f 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -56,6 +56,11 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b,
uint32_t c)
return (__int128_t)a * b / c;
}
+static inline uint64_t muldiv64_round_up(uint64_t a, uint32_t b, uint32_t c)
+{
+ return ((__int128_t)a * b + c - 1) / c;
+}
+
static inline uint64_t divu128(uint64_t *plow, uint64_t *phigh,
uint64_t divisor)
{
@@ -83,7 +88,8 @@ void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a,
uint64_t b);
uint64_t divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
int64_t divs128(uint64_t *plow, int64_t *phigh, int64_t divisor);
-static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+static inline uint64_t __muldiv64(uint64_t a, uint32_t b, uint32_t c,
+ bool round_up)
{
union {
uint64_t ll;
@@ -99,12 +105,25 @@ static inline uint64_t muldiv64(uint64_t a, uint32_t b,
uint32_t c)
u.ll = a;
rl = (uint64_t)u.l.low * (uint64_t)b;
+ if (round_up) {
+ rl += c - 1;
+ }
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 inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+ return __muldiv64(a, b, c, false);
+}
+
+static inline uint64_t muldiv64_round_up(uint64_t a, uint32_t b, uint32_t c)
+{
+ return __muldiv64(a, b, c, true);
+}
#endif
/**
--
2.40.1
- [PATCH v2 for-8.2 00/19] ppc: record-replay enablement and fixes, Nicholas Piggin, 2023/08/08
- [PATCH v2 01/19] ppc/vhyp: reset exception state when handling vhyp hcall, Nicholas Piggin, 2023/08/08
- [PATCH v2 02/19] ppc/vof: Fix missed fields in VOF cleanup, Nicholas Piggin, 2023/08/08
- [PATCH v2 03/19] hw/ppc/ppc.c: Tidy over-long lines, Nicholas Piggin, 2023/08/08
- [PATCH v2 04/19] hw/ppc: Introduce functions for conversion between timebase and nanoseconds, Nicholas Piggin, 2023/08/08
- [PATCH v2 05/19] host-utils: Add muldiv64_round_up,
Nicholas Piggin <=
- [PATCH v2 06/19] hw/ppc: Round up the decrementer interval when converting to ns, Nicholas Piggin, 2023/08/08
- [PATCH v2 07/19] hw/ppc: Avoid decrementer rounding errors, Nicholas Piggin, 2023/08/08
- [PATCH v2 08/19] target/ppc: Sign-extend large decrementer to 64-bits, Nicholas Piggin, 2023/08/08
- [PATCH v2 09/19] hw/ppc: Always store the decrementer value, Nicholas Piggin, 2023/08/08
- [PATCH v2 10/19] target/ppc: Migrate DECR SPR, Nicholas Piggin, 2023/08/08
- [PATCH v2 11/19] hw/ppc: Reset timebase facilities on machine reset, Nicholas Piggin, 2023/08/08
- [PATCH v2 12/19] hw/ppc: Read time only once to perform decrementer write, Nicholas Piggin, 2023/08/08
- [PATCH v2 13/19] target/ppc: Fix CPU reservation migration for record-replay, Nicholas Piggin, 2023/08/08