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....@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to