Remove custom printf from kelvin.h

- Remove our custom printf from kelvin.h, in favor of libc printf
  everywhere. This allows us to get formatting for many more types!
- Patch up format strings to fix warnings.
- Add a "PrintfTraits" template type, that contains decimal and hex
  format strings for the parametrized type (mostly used to build format
  strings in templated tests).

Change-Id: I36bd2841406e8f2b33c193637c468a2ff1b41a16
diff --git a/tests/cv/diff_test.cc b/tests/cv/diff_test.cc
index 20d289e..cd20a77 100644
--- a/tests/cv/diff_test.cc
+++ b/tests/cv/diff_test.cc
@@ -5,6 +5,7 @@
 #include "tests/cv/diff.h"
 
 #include <cstdint>
+#include <cstdio>
 
 #include "crt/kelvin.h"
 #include "tests/cv/test_helper.h"
diff --git a/tests/cv/downsample_test.cc b/tests/cv/downsample_test.cc
index a1afa0b..f82a1cc 100644
--- a/tests/cv/downsample_test.cc
+++ b/tests/cv/downsample_test.cc
@@ -6,6 +6,7 @@
 #include "tests/cv/downsample.h"
 
 #include <cstdint>
+#include <cstdio>
 
 #include "crt/kelvin.h"
 #include "tests/cv/test_helper.h"
diff --git a/tests/cv/extrema_test.cc b/tests/cv/extrema_test.cc
index 81f0163..e6ff969 100644
--- a/tests/cv/extrema_test.cc
+++ b/tests/cv/extrema_test.cc
@@ -5,6 +5,7 @@
 #include "tests/cv/extrema.h"
 
 #include <cstdint>
+#include <cstdio>
 
 #include "crt/kelvin.h"
 #include "tests/cv/test_helper.h"
diff --git a/tests/cv/gaussian.cc b/tests/cv/gaussian.cc
index 520cfe8..f280746 100644
--- a/tests/cv/gaussian.cc
+++ b/tests/cv/gaussian.cc
@@ -4,6 +4,8 @@
 
 #include "tests/cv/gaussian.h"
 
+#include <cstdio>
+
 #include "crt/kelvin.h"
 
 // Note: separable kernel is vertical then horizontal. H then V with the
diff --git a/tests/cv/gaussian_test.cc b/tests/cv/gaussian_test.cc
index e310b3e..cf6f3c4 100644
--- a/tests/cv/gaussian_test.cc
+++ b/tests/cv/gaussian_test.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <cstdio>
 
 #include "crt/kelvin.h"
 #include "tests/cv/test_helper.h"
diff --git a/tests/cv/shift_gaussian.cc b/tests/cv/shift_gaussian.cc
index be5aa93..95f96f3 100644
--- a/tests/cv/shift_gaussian.cc
+++ b/tests/cv/shift_gaussian.cc
@@ -5,6 +5,7 @@
 #include "tests/cv/shift_gaussian.h"
 
 #include <cstdint>
+#include <cstdio>
 
 #include "crt/kelvin.h"
 
diff --git a/tests/cv/shift_gaussian_test.cc b/tests/cv/shift_gaussian_test.cc
index 813e50b..3ef8f2e 100644
--- a/tests/cv/shift_gaussian_test.cc
+++ b/tests/cv/shift_gaussian_test.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <cstdio>
 
 #include "crt/kelvin.h"
 #include "tests/cv/test_helper.h"
diff --git a/tests/cv/upsample_test.cc b/tests/cv/upsample_test.cc
index c672575..fc8b628 100644
--- a/tests/cv/upsample_test.cc
+++ b/tests/cv/upsample_test.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <cstdint>
+#include <cstdio>
 
 #include "crt/kelvin.h"
 #include "tests/cv/test_helper.h"
diff --git a/tests/kelvin_isa/getvl_test.cc b/tests/kelvin_isa/getvl_test.cc
index 8d547a1..dea0e75 100644
--- a/tests/kelvin_isa/getvl_test.cc
+++ b/tests/kelvin_isa/getvl_test.cc
@@ -3,6 +3,8 @@
 // SPDX-License-Identifier: Apache-2.0
 //
 
+#include <cstdio>
+
 #include "tests/kelvin_isa/kelvin_test.h"
 
 // clang-format off
diff --git a/tests/kelvin_isa/vdwconv.cc b/tests/kelvin_isa/vdwconv.cc
index 12e4f8e..ff941a1 100644
--- a/tests/kelvin_isa/vdwconv.cc
+++ b/tests/kelvin_isa/vdwconv.cc
@@ -2,11 +2,11 @@
 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
 // SPDX-License-Identifier: Apache-2.0
 
-#include "tests/kelvin_isa/vdwconv_data.h"
-
-#include <string.h>
+#include <cstdio>
+#include <cstring>
 
 #include "tests/kelvin_isa/kelvin_test.h"
+#include "tests/kelvin_isa/vdwconv_data.h"
 
 struct vdwconv_u8_t {
   uint32_t mode:2;      // 1:0
@@ -35,7 +35,7 @@
 #endif  // TEST_GEN
 
 void dwconv(const vdwconv_u8_t& cmd, const uint8_t ina[3][kZlen],
-            const uint8_t inb[3][kZlen], uint32_t ref[4][kZlen / 4],
+            const uint8_t inb[3][kZlen], const uint32_t ref[4][kZlen / 4],
             uint32_t dut[4][kZlen / 4]) {
   uint32_t cmdw;
   memcpy(&cmdw, &cmd, 4);
@@ -208,7 +208,7 @@
   printf("{ ");
   for (int i = 0; i < 4; ++i) {
     for (int j = 0; j < kZlen / 4; ++j) {
-      printf("0x%08x, ", ref[i][j]);
+      printf("0x%lx, ", ref[i][j]);
     }
   }
   printf("} },\n");
@@ -222,7 +222,7 @@
         printf("**error::test_dwconv(%d,%d)(%d,%d,%d,%d)[%d,%d] ", cmd.sparsity,
                cmd.regbase, cmd.sdata1, cmd.sdata2, cmd.sbias1, cmd.sbias2, i,
                j);
-        printf("%08x %08x\n", r, d);
+        printf("0x%lx 0x%lx\n", r, d);
         exit(-1);
       }
     }
@@ -285,14 +285,14 @@
 
   for (int i = 0; i < 4; ++i) {
     if (ref[i] != dut[i]) {
-      printf("**error::test_dwconv<%d,%d>[%d] %08x %08x\n", step, use_accum, i,
-             ref[i], dut[i]);
+      printf("**error::test_dwconv<%d,%d>[%d] 0x%lx 0x%lx\n", step, use_accum,
+             i, ref[i], dut[i]);
       exit(-1);
     }
   }
 }
 
-void test_vdwconv(int sparsity, int regbase, test_dwconv_t& test) {
+void test_vdwconv(int sparsity, int regbase, const test_dwconv_t& test) {
   uint32_t dut[4][kZlen / 4];
   vdwconv_u8_t cmd;
 
@@ -309,10 +309,10 @@
 
 int main() {
 #ifdef TEST_GEN
-  uint32_t* pw_ina = (uint32_t*)ina_;
-  uint32_t* pw_inb = (uint32_t*)inb_;
-  uint8_t* pb_ina = (uint8_t*)ina_;
-  uint8_t* pb_inb = (uint8_t*)inb_;
+  uint32_t* pw_ina = reinterpret_cast<uint32_t*>(ina_);
+  uint32_t* pw_inb = reinterpret_cast<uint32_t*>(inb_);
+  uint8_t* pb_ina = reinterpret_cast<uint8_t*>(ina_);
+  uint8_t* pb_inb = reinterpret_cast<uint8_t*>(inb_);
   for (int i = 0; i < 3 * kZlen / 4; ++i) {
     pw_ina[i] = krand();
     pw_inb[i] = krand();
diff --git a/tests/kelvin_isa/vld.cc b/tests/kelvin_isa/vld.cc
index 0400921..0d8d5a3 100644
--- a/tests/kelvin_isa/vld.cc
+++ b/tests/kelvin_isa/vld.cc
@@ -1,3 +1,10 @@
+// Copyright 2023 Google LLC
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include <cstdio>
+
+#include "crt/printf_traits.h"
 #include "tests/kelvin_isa/kelvin_test.h"
 
 inline uint8_t* vldp_data(uint8_t* data) {
@@ -206,8 +213,8 @@
   void* target = reinterpret_cast<void*>(read_data + offset);
   if (reinterpret_cast<void*>(dut) != target) {
     printf("Failed test_ldst_x for type %s:\n", TypeString<T>::type_str());
-    printf("  expected dut=0x%x to be 0x%x\n",
-           reinterpret_cast<void*>(dut), target);
+    printf("  expected dut=%p to be %p\n", reinterpret_cast<void*>(dut),
+           target);
     exit(1);
   }
 
@@ -222,7 +229,9 @@
   for (int i = 0; i < size; i++) {
     if (result[i] != static_cast<T>(i)) {
       printf("Failed test_ldst_x for type %s:\n", TypeString<T>::type_str());
-      printf("  expected %d at position %d/%d got %d\n", i, i, size, result[i]);
+      printf("  expected %d at position %d/%d got ", i, i, size);
+      printf(PrintfTraits<T>::kFmt, result[i]);
+      printf("\n");
       exit(1);
     }
   }
@@ -247,8 +256,8 @@
   void* target = reinterpret_cast<void*>(read_data + (length * sizeof(T)));
   if (reinterpret_cast<void*>(dut) != target) {
     printf("Failed test_ldst_p_xx for type %s:\n", TypeString<T>::type_str());
-    printf("  expected dut=%x to be %x\n",
-           reinterpret_cast<void*>(dut), target);
+    printf("  expected dut=%p to be %p\n", reinterpret_cast<void*>(dut),
+           target);
     exit(1);
   }
 
@@ -263,7 +272,9 @@
   for (int i = 0; i < size; i++) {
     if (result[i] != static_cast<T>(i)) {
       printf("Failed test_ldst_p_xx for type %s:\n", TypeString<T>::type_str());
-      printf("  expected %d at position %d got %d\n", i, i, result[i]);
+      printf("  expected %d at position %d got ", i, i);
+      printf(PrintfTraits<T>::kFmt, result[i]);
+      printf("\n");
       exit(1);
     }
   }
@@ -299,8 +310,8 @@
         (post_increment ? length * sizeof(T) : 0));
   if (reinterpret_cast<void*>(dut) != target) {
     printf("Failed test_ldst_l_xx for type %s:\n", TypeString<T>::type_str());
-    printf("  expected dut=%x to be %x\n",
-           reinterpret_cast<void*>(dut), target);
+    printf("  expected dut=%p to be %p\n", reinterpret_cast<void*>(dut),
+           target);
     exit(1);
   }
 
@@ -316,14 +327,18 @@
   for (; i < length; i++) {
     if (result[i] != static_cast<T>(i)) {
       printf("Failed test_ldst_l_xx for type %s:\n", TypeString<T>::type_str());
-      printf("  expected %d at position %d/%d got %d\n", i, i, size, result[i]);
+      printf("  expected %d at position %d/%d got ", i, i, size);
+      printf(PrintfTraits<T>::kFmt, result[i]);
+      printf("\n");
       exit(1);
     }
   }
   for (; i < size; i++) {
     if (result[i] != 0) {
       printf("Failed test_ldst_l_xx for type %s:\n", TypeString<T>::type_str());
-      printf("  expected 0 at position %d/%d got %d\n", i, size, result[i]);
+      printf("  expected 0 at position %d/%d got ", i, size);
+      printf(PrintfTraits<T>::kFmt, result[i]);
+      printf("\n");
       exit(1);
     }
   }
@@ -359,8 +374,8 @@
   void* target = reinterpret_cast<void*>(read_data + offset);
   if (reinterpret_cast<void*>(dut) != target) {
     printf("Failed test_ldst_s_xx for type %s:\n", TypeString<T>::type_str());
-    printf("  expected dut=%x to be %x\n",
-           reinterpret_cast<void*>(dut), target);
+    printf("  expected dut=%p to be %p\n", reinterpret_cast<void*>(dut),
+           target);
     exit(1);
   }
 
@@ -381,8 +396,11 @@
       if (result_vector[i] != start_value + i) {
         printf("Failed test_ldst_s_xx for type %s:\n",
                TypeString<T>::type_str());
-        printf("  expected %d at position %d got %d\n",
-               expected_value, i, result_vector[i]);
+        printf("  expected ");
+        printf(PrintfTraits<T>::kFmt, expected_value);
+        printf(" at position %ld got ", i);
+        printf(PrintfTraits<T>::kFmt, result_vector[i]);
+        printf("\n");
         exit(1);
       }
     }
@@ -408,8 +426,8 @@
   void* target = reinterpret_cast<void*>(read_data + VLENB);
   if (reinterpret_cast<void*>(dut) != target) {
     printf("Failed test_ldst_tp_xx for type %s:\n", TypeString<T>::type_str());
-    printf("  expected dut=%x to be %x\n",
-           reinterpret_cast<void*>(dut), target);
+    printf("  expected dut=%p to be %p\n", reinterpret_cast<void*>(dut),
+           target);
     exit(1);
   }
 
@@ -430,8 +448,11 @@
     if (result[i] != expected_value) {
       printf("Failed test_ldst_tp_xx for type %s:\n",
              TypeString<T>::type_str());
-      printf("  expected %d at position %d got %d\n",
-             expected_value, i, result[i]);
+      printf("  expected ");
+      printf(PrintfTraits<T>::kFmt, expected_value);
+      printf(" at position %d got ", i);
+      printf(PrintfTraits<T>::kFmt, result[i]);
+      printf("\n");
       exit(1);
     }
   }
@@ -440,7 +461,9 @@
     if (result[i] != 0) {
       printf("Failed test_ldst_tp_xx for type %s:\n",
              TypeString<T>::type_str());
-      printf("  expected 0 at position %d got %d\n", i, result[i]);
+      printf("  expected 0 at position %d got ", i);
+      printf(PrintfTraits<T>::kFmt, result[i]);
+      printf("\n");
       exit(1);
     }
   }
@@ -474,7 +497,11 @@
     for (int j = 0; j < vlen; ++j) {
       T ref = j < i ? j + 1 : 0;
       if (ref != dut[j]) {
-        printf("**error vld_l[%d,%d] %x %x\n", i, j, ref, dut[j]);
+        printf("**error vld_l[%d,%d] ", i, j);
+        printf(PrintfTraits<T>::kFmtHex, ref);
+        printf(" ");
+        printf(PrintfTraits<T>::kFmtHex, dut[j]);
+        printf("\n");
         exit(-1);
       }
     }
diff --git a/tests/kelvin_isa/vpadd.cc b/tests/kelvin_isa/vpadd.cc
index 4a856d0..d7bc2ed 100644
--- a/tests/kelvin_isa/vpadd.cc
+++ b/tests/kelvin_isa/vpadd.cc
@@ -1,5 +1,8 @@
 // Copyright 2023 Google LLC
 
+#include <cstdio>
+
+#include "crt/printf_traits.h"
 #include "tests/kelvin_isa/kelvin_test.h"
 
 #define vpadd_v(T, Vd, Vs)          \
@@ -58,8 +61,16 @@
 
   for (int i = 0; i < lanes; ++i) {
     if (ref[i] != dut[i]) {
-      printf("**error vpadd_v[%d] %d %d\n", i, ref[i], dut[i]);
-      printf("  inputs: %d, %d\n", inp[2 * i + 0], inp[2 * i + 1]);
+      printf("**error vpadd_v[%d] ", i);
+      printf(PrintfTraits<T2>::kFmt, ref[i]);
+      printf(" ");
+      printf(PrintfTraits<T2>::kFmt, dut[i]);
+      printf("\n");
+      printf("  inputs: ");
+      printf(PrintfTraits<T1>::kFmt, inp[2 * i + 0]);
+      printf(", ");
+      printf(PrintfTraits<T1>::kFmt, inp[2 * i + 1]);
+      printf("\n");
       exit(-1);
     }
   }
@@ -89,7 +100,11 @@
 
   for (int i = 0; i < lanes; ++i) {
     if (ref[i] != dut[i]) {
-      printf("**error vpadd_v_m[%d] %x %x\n", i, ref[i], dut[i]);
+      printf("**error vpadd_v_m[%d] ", i);
+      printf(PrintfTraits<T2>::kFmtHex, ref[i]);
+      printf(" ");
+      printf(PrintfTraits<T2>::kFmtHex, dut[i]);
+      printf("\n");
       exit(-1);
     }
   }
diff --git a/tests/riscv-tests/branch_div_test.cc b/tests/riscv-tests/branch_div_test.cc
index a7a6514..95ba75d 100644
--- a/tests/riscv-tests/branch_div_test.cc
+++ b/tests/riscv-tests/branch_div_test.cc
@@ -5,8 +5,9 @@
 // Use the routine of finding the integer part of log_3 to stress test
 // branch/div op combinations.
 
-#include <stdint.h>
-#include <stdlib.h>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
 
 #include "crt/kelvin.h"
 
@@ -50,18 +51,18 @@
   uint32_t uint32_input = rand_uint32_input();
   int32_t int32_input = rand_int32_input();
   auto uint32_log3 = get_int_log3<uint32_t>(uint32_input);
-  printf("Unsigned input: %u, integer log3: %u\n", uint32_input, uint32_log3);
+  printf("Unsigned input: %lu, integer log3: %lu\n", uint32_input, uint32_log3);
   auto test = int_pow3<uint32_t>(uint32_log3);
   // Make the check like this to prevent overflow
   if (!(test <= uint32_input && test >= uint32_input / 3)) {
-    printf("Invalid log_3 %u for %u\n", uint32_log3, uint32_input);
+    printf("Invalid log_3 %lu for %lu\n", uint32_log3, uint32_input);
     exit(-1);
   }
   auto int32_log3 = get_int_log3<int32_t>(int32_input);
-  printf("Signed intput:%d, integer log3: %d\n", int32_input, int32_log3);
+  printf("Signed intput:%ld, integer log3: %ld\n", int32_input, int32_log3);
   auto test1 = int_pow3<int32_t>(int32_log3);
   if (!(test1 <= int32_input && test1 >= int32_input / 3)) {
-    printf("Invalid log_3 %d for %d\n", int32_log3, int32_input);
+    printf("Invalid log_3 %ld for %ld\n", int32_log3, int32_input);
     exit(-1);
   }
   return 0;
diff --git a/tests/riscv-tests/branch_modulo_test.cc b/tests/riscv-tests/branch_modulo_test.cc
index 8bd7743..faac704 100644
--- a/tests/riscv-tests/branch_modulo_test.cc
+++ b/tests/riscv-tests/branch_modulo_test.cc
@@ -5,8 +5,9 @@
 // Use greatest common denominator routine to stress test branch/modulo op
 // combinations.
 
-#include <stdint.h>
-#include <stdlib.h>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
 
 #include "crt/kelvin.h"
 
@@ -40,26 +41,26 @@
   int32_t int32_a = rand_int32_input();
   int32_t int32_b = rand_int32_input();
 
-  printf("unsigned numbers: a:%u, b:%u\n", uint32_a, uint32_b);
+  printf("unsigned numbers: a:%lu, b:%lu\n", uint32_a, uint32_b);
   auto uint32_gcd = (uint32_a > uint32_b)
                         ? get_gcd<uint32_t>(uint32_a, uint32_b)
                         : get_gcd<uint32_t>(uint32_b, uint32_a);
-  printf("gcd: %u\n", uint32_gcd);
+  printf("gcd: %lu\n", uint32_gcd);
 
   if (!(uint32_a % uint32_gcd == 0 && uint32_b % uint32_gcd == 0)) {
-    printf("Invalid common denominator %u for %u and %u\n", uint32_gcd,
+    printf("Invalid common denominator %lu for %lu and %lu\n", uint32_gcd,
            uint32_a, uint32_b);
     exit(-1);
   }
 
-  printf("signed numbers: a:%d, b:%d\n", int32_a, int32_b);
+  printf("signed numbers: a:%ld, b:%ld\n", int32_a, int32_b);
   auto int32_gcd = (int32_a > int32_b) ? get_gcd<int32_t>(int32_a, int32_b)
                                        : get_gcd<int32_t>(int32_b, int32_a);
-  printf("gcd: %d\n", int32_gcd);
+  printf("gcd: %ld\n", int32_gcd);
 
   if (!(int32_a % int32_gcd == 0 && int32_b % int32_gcd == 0)) {
-    printf("Invalid common denominator %d for %d and %d\n", int32_gcd, int32_a,
-           int32_b);
+    printf("Invalid common denominator %ld for %ld and %ld\n", int32_gcd,
+           int32_a, int32_b);
     exit(-1);
   }