Signed-off-by: Martin Roth <martin@coreboot.org> Change-Id: Ibb7b48a7a144421aff29acbb7ac30968ae5fe5ab Reviewed-on: https://review.coreboot.org/c/coreboot/+/36329 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <siro@das-labor.org>
45 lines
1.0 KiB
C
45 lines
1.0 KiB
C
/*
|
|
* This file is part of the coreboot project.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "libgcc.h"
|
|
|
|
uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p)
|
|
{
|
|
uint64_t quot = 0, qbit = 1;
|
|
if (den == 0) {
|
|
return 1 / ((unsigned int)den); /* Intentional divide by zero, without
|
|
triggering a compiler warning which
|
|
would abort the build */
|
|
}
|
|
|
|
/* Left-justify denominator and count shift */
|
|
while ((int64_t)den >= 0) {
|
|
den <<= 1;
|
|
qbit <<= 1;
|
|
}
|
|
|
|
while (qbit) {
|
|
if (den <= num) {
|
|
num -= den;
|
|
quot += qbit;
|
|
}
|
|
den >>= 1;
|
|
qbit >>= 1;
|
|
}
|
|
|
|
if (rem_p)
|
|
*rem_p = num;
|
|
|
|
return quot;
|
|
}
|