summaryrefslogtreecommitdiff
path: root/zephyr/shim/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/shim/src/util.c')
-rw-r--r--zephyr/shim/src/util.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/zephyr/shim/src/util.c b/zephyr/shim/src/util.c
index 3181fccb95..5a7131b23a 100644
--- a/zephyr/shim/src/util.c
+++ b/zephyr/shim/src/util.c
@@ -161,3 +161,47 @@ int parse_offset_size(int argc, char **argv, int shift, int *offset, int *size)
return EC_SUCCESS;
}
+
+int uint64divmod(uint64_t *n, int d)
+{
+ uint64_t q = 0, mask;
+ int r = 0;
+
+ /* Divide-by-zero returns zero */
+ if (!d) {
+ *n = 0;
+ return 0;
+ }
+
+ /* Common powers of 2 = simple shifts */
+ if (d == 2) {
+ r = *n & 1;
+ *n >>= 1;
+ return r;
+ } else if (d == 16) {
+ r = *n & 0xf;
+ *n >>= 4;
+ return r;
+ }
+
+ /* If v fits in 32-bit, we're done. */
+ if (*n <= 0xffffffff) {
+ uint32_t v32 = *n;
+ r = v32 % d;
+ *n = v32 / d;
+ return r;
+ }
+
+ /* Otherwise do integer division the slow way. */
+ for (mask = (1ULL << 63); mask; mask >>= 1) {
+ r <<= 1;
+ if (*n & mask)
+ r |= 1;
+ if (r >= d) {
+ r -= d;
+ q |= mask;
+ }
+ }
+ *n = q;
+ return r;
+}