summaryrefslogtreecommitdiff
path: root/common/util.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-04-20 13:07:42 -0700
committerRandall Spangler <rspangler@chromium.org>2012-04-20 14:01:11 -0700
commit9f552ff5aa043eddc5b6d59db09728d83faf97dd (patch)
treee7f39070eac9b14a9afa6363703eab0950e856cc /common/util.c
parenta05deade13c696643ca6f8cc216f78db015a7ddb (diff)
downloadchrome-ec-9f552ff5aa043eddc5b6d59db09728d83faf97dd.tar.gz
Implement 64-bit integer printing in uart_printf()
Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:7490 TEST=timerinfo; numbers should look reasonable Change-Id: I698be99c87bf311013427ac0ed9e93e5687f40c0
Diffstat (limited to 'common/util.c')
-rw-r--r--common/util.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/common/util.c b/common/util.c
index 40908cc5ce..fe30ffa518 100644
--- a/common/util.c
+++ b/common/util.c
@@ -144,7 +144,6 @@ void *memset(void *dest, int c, int len)
}
-/* Like strncpy(), but guarantees null termination */
char *strzcpy(char *dest, const char *src, int len)
{
char *d = dest;
@@ -155,3 +154,48 @@ char *strzcpy(char *dest, const char *src, int len)
*d = '\0';
return dest;
}
+
+
+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;
+}