[U-Boot] [PATCH] lib: tiny-printf: Add "%ll" modifier support

Ley Foon Tan ley.foon.tan at intel.com
Thu Mar 21 17:12:14 UTC 2019


Add "%ll" modifier support for tiny printf.

- Tested on ARM32 and ARM64 systems.
- Tested "%lld", "%llu", "%llx" and "%p" format with
  minimum and maximum ranges. Compared tiny printf
  output with full printf.

Signed-off-by: Ley Foon Tan <ley.foon.tan at intel.com>
---
 lib/tiny-printf.c | 42 +++++++++++++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c
index ebef92fc9f..692430efac 100644
--- a/lib/tiny-printf.c
+++ b/lib/tiny-printf.c
@@ -33,8 +33,8 @@ static void out_dgt(struct printf_info *info, char dgt)
 	info->zs = 1;
 }
 
-static void div_out(struct printf_info *info, unsigned long *num,
-		    unsigned long div)
+static void div_out(struct printf_info *info, unsigned long long *num,
+		    unsigned long long div)
 {
 	unsigned char dgt = 0;
 
@@ -160,8 +160,8 @@ static void ip4_addr_string(struct printf_info *info, u8 *addr)
 static void pointer(struct printf_info *info, const char *fmt, void *ptr)
 {
 #ifdef DEBUG
-	unsigned long num = (uintptr_t)ptr;
-	unsigned long div;
+	unsigned long long num = (uintptr_t)ptr;
+	unsigned long long div;
 #endif
 
 	switch (*fmt) {
@@ -199,9 +199,9 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
 {
 	char ch;
 	char *p;
-	unsigned long num;
-	char buf[12];
-	unsigned long div;
+	unsigned long long num;
+	char buf[22];
+	unsigned long long div;
 
 	while ((ch = *(fmt++))) {
 		if (ch != '%') {
@@ -210,6 +210,7 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
 			bool lz = false;
 			int width = 0;
 			bool islong = false;
+			bool islonglong = false;
 
 			ch = *(fmt++);
 			if (ch == '-')
@@ -229,7 +230,13 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
 			}
 			if (ch == 'l') {
 				ch = *(fmt++);
-				islong = true;
+				if (ch == 'l') {
+					islonglong = true;
+					ch = *(fmt++);
+				} else {
+					islong = true;
+				}
+
 			}
 
 			info->bf = buf;
@@ -242,7 +249,10 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
 			case 'u':
 			case 'd':
 				div = 1000000000;
-				if (islong) {
+				if (islonglong) {
+					num = va_arg(va, unsigned long long);
+					div *= div * 10;
+				} else if (islong) {
 					num = va_arg(va, unsigned long);
 					if (sizeof(long) > 4)
 						div *= div * 10;
@@ -251,10 +261,13 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
 				}
 
 				if (ch == 'd') {
-					if (islong && (long)num < 0) {
+					if (islonglong && (long long)num < 0) {
+						num = -(long long)num;
+						out(info, '-');
+					} else if (islong && (long)num < 0) {
 						num = -(long)num;
 						out(info, '-');
-					} else if (!islong && (int)num < 0) {
+					} else if ((!islong && !islonglong) && (int)num < 0) {
 						num = -(int)num;
 						out(info, '-');
 					}
@@ -267,9 +280,12 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va)
 				}
 				break;
 			case 'x':
-				if (islong) {
+				if (islonglong) {
+					num = va_arg(va, unsigned long long);
+					div = 1ULL << (sizeof(long long) * 8 - 4);
+				} else if (islong) {
 					num = va_arg(va, unsigned long);
-					div = 1UL << (sizeof(long) * 8 - 4);
+					div = 1ULL << (sizeof(long) * 8 - 4);
 				} else {
 					num = va_arg(va, unsigned int);
 					div = 0x10000000;
-- 
2.19.0



More information about the U-Boot mailing list