host-utils: Add muldiv64_round_up
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> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> [ clg: renamed __muldiv64() to muldiv64_rounding() ] Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
parent
7798f5c576
commit
47de6c4c28
@ -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_rounding(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_rounding(a, b, c, false);
|
||||
}
|
||||
|
||||
static inline uint64_t muldiv64_round_up(uint64_t a, uint32_t b, uint32_t c)
|
||||
{
|
||||
return muldiv64_rounding(a, b, c, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user