diff mbox series

[v2,05/19] host-utils: Add muldiv64_round_up

Message ID 20230808042001.411094-6-npiggin@gmail.com
State New
Headers show
Series ppc: record-replay enablement and fixes | expand

Commit Message

Nicholas Piggin Aug. 8, 2023, 4:19 a.m. UTC
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(-)

Comments

Cédric Le Goater Sept. 1, 2023, 11:51 a.m. UTC | #1
Adding more reviewers since this patch is modifying a common service.

Thanks,

C.


On 8/8/23 06:19, Nicholas Piggin wrote:
> 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
>   
>   /**
Richard Henderson Sept. 1, 2023, 5:02 p.m. UTC | #2
On 9/1/23 04:51, Cédric Le Goater wrote:
> Adding more reviewers since this patch is modifying a common service.
> 
> Thanks,
> 
> C.
> 
> 
> On 8/8/23 06:19, Nicholas Piggin wrote:
>> 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)

Perhaps better avoiding the reserved name: muldiv64_internal?

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~


>>   {
>>       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
>>   /**
> 
>
Nicholas Piggin Sept. 4, 2023, 1:07 p.m. UTC | #3
On Sat Sep 2, 2023 at 3:02 AM AEST, Richard Henderson wrote:
> On 9/1/23 04:51, Cédric Le Goater wrote:
> > Adding more reviewers since this patch is modifying a common service.
> > 
> > Thanks,
> > 
> > C.
> > 
> > 
> > On 8/8/23 06:19, Nicholas Piggin wrote:
> >> 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)
>
> Perhaps better avoiding the reserved name: muldiv64_internal?

Thanks, that would be okay. Or could be muldiv64_rounding?

>
> Otherwise,
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
>
> r~
>
>
> >>   {
> >>       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
> >>   /**
> > 
> >
Cédric Le Goater Sept. 4, 2023, 1:30 p.m. UTC | #4
On 9/4/23 15:07, Nicholas Piggin wrote:
> On Sat Sep 2, 2023 at 3:02 AM AEST, Richard Henderson wrote:
>> On 9/1/23 04:51, Cédric Le Goater wrote:
>>> Adding more reviewers since this patch is modifying a common service.
>>>
>>> Thanks,
>>>
>>> C.
>>>
>>>
>>> On 8/8/23 06:19, Nicholas Piggin wrote:
>>>> 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)
>>
>> Perhaps better avoiding the reserved name: muldiv64_internal?
> 
> Thanks, that would be okay. Or could be muldiv64_rounding?
> 
>>
>> Otherwise,
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

oh, and I already sent the PR with the Rb of Richard ... :/
Sorry about that. Can we fix it later ? Or I will respin with
the update.

Someone really ought to take over PPC. Daniel and I are real
busy on other subsystems. Volunteers ?

Thanks,

C.

>>
>>
>> r~
>>
>>
>>>>    {
>>>>        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
>>>>    /**
>>>
>>>
>
Nicholas Piggin Sept. 5, 2023, 3:56 a.m. UTC | #5
On Mon Sep 4, 2023 at 11:30 PM AEST, Cédric Le Goater wrote:
> On 9/4/23 15:07, Nicholas Piggin wrote:
> > On Sat Sep 2, 2023 at 3:02 AM AEST, Richard Henderson wrote:
> >> On 9/1/23 04:51, Cédric Le Goater wrote:
> >>> Adding more reviewers since this patch is modifying a common service.
> >>>
> >>> Thanks,
> >>>
> >>> C.
> >>>
> >>>
> >>> On 8/8/23 06:19, Nicholas Piggin wrote:
> >>>> 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)
> >>
> >> Perhaps better avoiding the reserved name: muldiv64_internal?
> > 
> > Thanks, that would be okay. Or could be muldiv64_rounding?
> > 
> >>
> >> Otherwise,
> >> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>
> oh, and I already sent the PR with the Rb of Richard ... :/
> Sorry about that. Can we fix it later ? Or I will respin with
> the update.
>
> Someone really ought to take over PPC. Daniel and I are real
> busy on other subsystems. Volunteers ?

I suppose I should. I could try do the next PR after this one
is merged.

Thanks,
Nick
Cédric Le Goater Sept. 5, 2023, 6:48 a.m. UTC | #6
On 9/5/23 05:56, Nicholas Piggin wrote:
> On Mon Sep 4, 2023 at 11:30 PM AEST, Cédric Le Goater wrote:
>> On 9/4/23 15:07, Nicholas Piggin wrote:
>>> On Sat Sep 2, 2023 at 3:02 AM AEST, Richard Henderson wrote:
>>>> On 9/1/23 04:51, Cédric Le Goater wrote:
>>>>> Adding more reviewers since this patch is modifying a common service.
>>>>>
>>>>> Thanks,
>>>>>
>>>>> C.
>>>>>
>>>>>
>>>>> On 8/8/23 06:19, Nicholas Piggin wrote:
>>>>>> 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)
>>>>
>>>> Perhaps better avoiding the reserved name: muldiv64_internal?
>>>
>>> Thanks, that would be okay. Or could be muldiv64_rounding?
>>>
>>>>
>>>> Otherwise,
>>>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>>
>> oh, and I already sent the PR with the Rb of Richard ... :/
>> Sorry about that. Can we fix it later ? Or I will respin with
>> the update.
>>
>> Someone really ought to take over PPC. Daniel and I are real
>> busy on other subsystems. Volunteers ?
> 
> I suppose I should. I could try do the next PR after this one
> is merged.

Let's continue offline.

Thanks,

C.
Philippe Mathieu-Daudé Sept. 5, 2023, 9:09 a.m. UTC | #7
On 5/9/23 05:56, Nicholas Piggin wrote:
> On Mon Sep 4, 2023 at 11:30 PM AEST, Cédric Le Goater wrote:

>> Someone really ought to take over PPC. Daniel and I are real
>> busy on other subsystems. Volunteers ?
> 
> I suppose I should. I could try do the next PR after this one
> is merged.

Thanks a lot for volunteering!

Phil.
Cédric Le Goater Sept. 6, 2023, 9:21 a.m. UTC | #8
On 9/4/23 15:07, Nicholas Piggin wrote:
> On Sat Sep 2, 2023 at 3:02 AM AEST, Richard Henderson wrote:
>> On 9/1/23 04:51, Cédric Le Goater wrote:
>>> Adding more reviewers since this patch is modifying a common service.
>>>
>>> Thanks,
>>>
>>> C.
>>>
>>>
>>> On 8/8/23 06:19, Nicholas Piggin wrote:
>>>> 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)
>>
>> Perhaps better avoiding the reserved name: muldiv64_internal?
> 
> Thanks, that would be okay. Or could be muldiv64_rounding?

I picked muldiv64_rounding()

Thanks,

C.


> 
>>
>> Otherwise,
>> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
>>
>>
>> r~
>>
>>
>>>>    {
>>>>        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
>>>>    /**
>>>
>>>
>
diff mbox series

Patch

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
 
 /**