[Beignet] [PATCH] Add the format and flag support for printf.

junyan.he at inbox.com junyan.he at inbox.com
Mon Jun 23 01:38:56 PDT 2014


From: Junyan He <junyan.he at linux.intel.com>

The format and flag such as -+# and precision request has
been added into the output.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 backend/src/ir/printf.cpp               | 104 +++++++++++++++++++++--
 backend/src/ir/printf.hpp               |  13 ++-
 backend/src/llvm/llvm_printf_parser.cpp | 143 +++++++++++++++++++++-----------
 3 files changed, 203 insertions(+), 57 deletions(-)

diff --git a/backend/src/ir/printf.cpp b/backend/src/ir/printf.cpp
index d919f78..58711e2 100644
--- a/backend/src/ir/printf.cpp
+++ b/backend/src/ir/printf.cpp
@@ -50,6 +50,60 @@ namespace gbe
       return (uint32_t)fmts.size();
     }
 
+    static void generatePrintfFmtString(PrintfState& state, std::string& str)
+    {
+      char num_str[16];
+      str += "%";
+
+      if (state.left_justified) {
+        str += "-";
+      }
+
+      if (state.sign_symbol == 1) {
+        str += "+";
+      } else if (state.sign_symbol == 2) {
+        str += " ";
+      }
+
+      if (state.alter_form) {
+        str += "#";
+      }
+
+      if (state.zero_padding) {
+        str += "0";
+      }
+
+      if (state.min_width >= 0) {
+        snprintf(num_str, 16, "%d", state.min_width);
+        str += num_str;
+      }
+
+      if (state.precision >= 0) {
+        str += ".";
+        snprintf(num_str, 16, "%d", state.precision);
+        str += num_str;
+      }
+
+      // TODO:  Handle the vector here.
+
+      switch (state.length_modifier) {
+        case PRINTF_LM_HH:
+          str += "hh";
+          break;
+        case PRINTF_LM_H:
+          str += "h";
+          break;
+        case PRINTF_LM_L:
+          str += "l";
+          break;
+        case PRINTF_LM_HL:
+          str += "hl";
+          break;
+        default:
+          assert(state.length_modifier == PRINTF_LM_NONE);
+      }
+    }
+
 #define PRINT_SOMETHING(target_ty, conv)  do {                          \
       pf_str = pf_str + std::string(#conv);                             \
       printf(pf_str.c_str(),                                            \
@@ -59,6 +113,7 @@ namespace gbe
       pf_str = "";                                                      \
     } while (0)
 
+
     void PrintfSet::outputPrintf(void* index_addr, void* buf_addr, size_t global_wk_sz0,
                                  size_t global_wk_sz1, size_t global_wk_sz2)
     {
@@ -81,26 +136,59 @@ namespace gbe
                   }
                   assert(slot.type == PRINTF_SLOT_TYPE_STATE);
 
+                  generatePrintfFmtString(*slot.state, pf_str);
+
                   switch (slot.state->conversion_specifier) {
                     case PRINTF_CONVERSION_D:
                     case PRINTF_CONVERSION_I:
-                      PRINT_SOMETHING(int, %d);
+                      PRINT_SOMETHING(int, d);
+                      break;
+
+                    case PRINTF_CONVERSION_O:
+                      PRINT_SOMETHING(int, o);
+                      break;
+                    case PRINTF_CONVERSION_U:
+                      PRINT_SOMETHING(int, u);
+                      break;
+                    case PRINTF_CONVERSION_X:
+                      PRINT_SOMETHING(int, X);
+                      break;
+                    case PRINTF_CONVERSION_x:
+                      PRINT_SOMETHING(int, x);
                       break;
+
                     case PRINTF_CONVERSION_C:
-                      PRINT_SOMETHING(char, %c);
+                      PRINT_SOMETHING(char, c);
                       break;
 
                     case PRINTF_CONVERSION_F:
+                      PRINT_SOMETHING(float, F);
+                      break;
                     case PRINTF_CONVERSION_f:
-                      if (slot.state->conversion_specifier == PRINTF_CONVERSION_F)
-                        PRINT_SOMETHING(float, %F);
-                      else
-                        PRINT_SOMETHING(float, %f);
+                      PRINT_SOMETHING(float, f);
+                      break;
+                    case PRINTF_CONVERSION_E:
+                      PRINT_SOMETHING(float, E);
+                      break;
+                    case PRINTF_CONVERSION_e:
+                      PRINT_SOMETHING(float, e);
+                      break;
+                    case PRINTF_CONVERSION_G:
+                      PRINT_SOMETHING(float, G);
+                      break;
+                    case PRINTF_CONVERSION_g:
+                      PRINT_SOMETHING(float, g);
+                      break;
+                    case PRINTF_CONVERSION_A:
+                      PRINT_SOMETHING(float, A);
+                      break;
+                    case PRINTF_CONVERSION_a:
+                      PRINT_SOMETHING(float, a);
                       break;
 
                     case PRINTF_CONVERSION_S:
-                      pf_str = pf_str + "%s";
-                      printf("%s%s", pf_str.c_str(), slot.state->str.c_str());
+                      pf_str = pf_str + "s";
+                      printf(pf_str.c_str(), slot.state->str.c_str());
                       pf_str = "";
                       break;
 
diff --git a/backend/src/ir/printf.hpp b/backend/src/ir/printf.hpp
index 18bdd6e..8b759d4 100644
--- a/backend/src/ir/printf.hpp
+++ b/backend/src/ir/printf.hpp
@@ -35,6 +35,7 @@ namespace gbe
 
     /* Things about printf info. */
     enum {
+      PRINTF_LM_NONE,
       PRINTF_LM_HH,
       PRINTF_LM_H,
       PRINTF_LM_L,
@@ -184,11 +185,21 @@ namespace gbe
         switch (slot->state->conversion_specifier) {
           case PRINTF_CONVERSION_I:
           case PRINTF_CONVERSION_D:
-          /* Char will be aligned to sizeof(int) here. */
+          case PRINTF_CONVERSION_O:
+          case PRINTF_CONVERSION_U:
+          case PRINTF_CONVERSION_X:
+          case PRINTF_CONVERSION_x:
+            /* Char will be aligned to sizeof(int) here. */
           case PRINTF_CONVERSION_C:
             return (uint32_t)sizeof(int);
+          case PRINTF_CONVERSION_E:
+          case PRINTF_CONVERSION_e:
           case PRINTF_CONVERSION_F:
           case PRINTF_CONVERSION_f:
+          case PRINTF_CONVERSION_G:
+          case PRINTF_CONVERSION_g:
+          case PRINTF_CONVERSION_A:
+          case PRINTF_CONVERSION_a:
             return (uint32_t)sizeof(float);
           case PRINTF_CONVERSION_S:
             return (uint32_t)0;
diff --git a/backend/src/llvm/llvm_printf_parser.cpp b/backend/src/llvm/llvm_printf_parser.cpp
index c99913d..dcad036 100644
--- a/backend/src/llvm/llvm_printf_parser.cpp
+++ b/backend/src/llvm/llvm_printf_parser.cpp
@@ -86,8 +86,8 @@ namespace gbe
     state->alter_form = 0;
     state->zero_padding = 0;
     state->vector_n = 0;
-    state->min_width = 0;
-    state->precision = 0;
+    state->min_width = -1;
+    state->precision = -1;
     state->length_modifier = 0;
     state->conversion_specifier = PRINTF_CONVERSION_INVALID;
     state->out_buf_sizeof_offset = -1;
@@ -108,39 +108,42 @@ namespace gbe
     FMT_PLUS_PLUS;
 
     // parse the flags.
-    switch (*fmt) {
-      case '-':
-        /* The result of the conversion is left-justified within the field. */
-        state->left_justified = 1;
-        FMT_PLUS_PLUS;
-        break;
-      case '+':
-        /* The result of a signed conversion always begins with a plus or minus sign. */
-        state->sign_symbol = 1;
-        FMT_PLUS_PLUS;
-        break;
-      case ' ':
-        /* If the first character of a signed conversion is not a sign, or if a signed
-           conversion results in no characters, a space is prefixed to the result.
-           If the space and + flags both appear,the space flag is ignored. */
-        if (state->sign_symbol == 0) state->sign_symbol = 2;
-        FMT_PLUS_PLUS;
-        break;
-      case '#':
-        /*The result is converted to an alternative form. */
-        state->alter_form = 1;
-        FMT_PLUS_PLUS;
-        break;
-      case '0':
-        if (!state->left_justified) state->zero_padding = 1;
-        FMT_PLUS_PLUS;
-        break;
-      default:
-        break;
-    }
+    while (*fmt == '-' || *fmt == '+' || *fmt == ' ' || *fmt == '#' || *fmt == '0')
+      switch (*fmt) {
+        case '-':
+          /* The result of the conversion is left-justified within the field. */
+          state->left_justified = 1;
+          FMT_PLUS_PLUS;
+          break;
+        case '+':
+          /* The result of a signed conversion always begins with a plus or minus sign. */
+          state->sign_symbol = 1;
+          FMT_PLUS_PLUS;
+          break;
+        case ' ':
+          /* If the first character of a signed conversion is not a sign, or if a signed
+             conversion results in no characters, a space is prefixed to the result.
+             If the space and + flags both appear,the space flag is ignored. */
+          if (state->sign_symbol == 0) state->sign_symbol = 2;
+          FMT_PLUS_PLUS;
+          break;
+        case '#':
+          /*The result is converted to an alternative form. */
+          state->alter_form = 1;
+          FMT_PLUS_PLUS;
+          break;
+        case '0':
+          if (!state->left_justified) state->zero_padding = 1;
+          FMT_PLUS_PLUS;
+          break;
+        default:
+          break;
+      }
 
     // The minimum field width
     while ((*fmt >= '0') && (*fmt <= '9')) {
+      if (state->min_width < 0)
+        state->min_width = 0;
       state->min_width = state->min_width * 10 + (*fmt - '0');
       FMT_PLUS_PLUS;
     }
@@ -148,6 +151,7 @@ namespace gbe
     // The precision
     if (*fmt == '.') {
       FMT_PLUS_PLUS;
+      state->precision = 0;
       while (*fmt >= '0' && *fmt <= '9') {
         state->precision = state->precision * 10 + (*fmt - '0');
         FMT_PLUS_PLUS;
@@ -285,22 +289,24 @@ again:
     }
 
 #if 0
-    int j = 0;
-    for (auto &s : *printf_fmt) {
-      j++;
-      if (s.type == PRINTF_SLOT_TYPE_STATE) {
-        printf("---- %d ---: state : \n", j);
-        printf("		     left_justified : %d\n", s.state->left_justified);
-        printf("		     sign_symbol: %d\n", s.state->sign_symbol);
-        printf("		     alter_form : %d\n", s.state->alter_form);
-        printf("		     zero_padding : %d\n", s.state->zero_padding);
-        printf("		     vector_n : %d\n", s.state->vector_n);
-        printf("		     min_width : %d\n", s.state->min_width);
-        printf("		     precision : %d\n", s.state->precision);
-        printf("		     length_modifier : %d\n", s.state->length_modifier);
-        printf("		     conversion_specifier : %d\n", s.state->conversion_specifier);
-      } else if (s.type == PRINTF_SLOT_TYPE_STRING) {
-        printf("---- %d ---: string :  %s\n", j, s.str);
+    {
+      int j = 0;
+      for (auto &s : *printf_fmt) {
+        j++;
+        if (s.type == PRINTF_SLOT_TYPE_STATE) {
+          fprintf(stderr, "---- %d ---: state : \n", j);
+          fprintf(stderr, "		     left_justified : %d\n", s.state->left_justified);
+          fprintf(stderr, "		     sign_symbol: %d\n", s.state->sign_symbol);
+          fprintf(stderr, "		     alter_form : %d\n", s.state->alter_form);
+          fprintf(stderr, "		     zero_padding : %d\n", s.state->zero_padding);
+          fprintf(stderr, "		     vector_n : %d\n", s.state->vector_n);
+          fprintf(stderr, "		     min_width : %d\n", s.state->min_width);
+          fprintf(stderr, "		     precision : %d\n", s.state->precision);
+          fprintf(stderr, "		     length_modifier : %d\n", s.state->length_modifier);
+          fprintf(stderr, "		     conversion_specifier : %d\n", s.state->conversion_specifier);
+        } else if (s.type == PRINTF_SLOT_TYPE_STRING) {
+          fprintf(stderr, "---- %d ---: string :  %s\n", j, s.str);
+        }
       }
     }
 #endif
@@ -629,6 +635,16 @@ error:
             sizeof_size = sizeof(int);
             return true;
 
+          case PRINTF_CONVERSION_O:
+          case PRINTF_CONVERSION_U:
+          case PRINTF_CONVERSION_x:
+          case PRINTF_CONVERSION_X:
+            /* To uint, add a conversion. */
+            arg = builder->CreateIntCast(arg, Type::getInt32Ty(module->getContext()), true);
+            dst_type = Type::getInt32PtrTy(module->getContext(), 1);
+            sizeof_size = sizeof(int);
+            return true;
+
           case PRINTF_CONVERSION_C:
             /* Int to Char, add a conversion. */
             arg = builder->CreateIntCast(arg, Type::getInt8Ty(module->getContext()), false);
@@ -638,11 +654,24 @@ error:
 
           case PRINTF_CONVERSION_F:
           case PRINTF_CONVERSION_f:
+          case PRINTF_CONVERSION_E:
+          case PRINTF_CONVERSION_e:
+          case PRINTF_CONVERSION_G:
+          case PRINTF_CONVERSION_g:
+          case PRINTF_CONVERSION_A:
+          case PRINTF_CONVERSION_a:
+            printf("Warning: Have a float paramter for %%d like specifier, take care of it\n");
             arg = builder->CreateSIToFP(arg, Type::getFloatTy(module->getContext()));
             dst_type = Type::getFloatPtrTy(module->getContext(), 1);
             sizeof_size = sizeof(float);
             return true;
 
+          case PRINTF_CONVERSION_S:
+            /* Here, the case is printf("xxx%s", 0); we should output the null. */
+            sizeof_size = 0;
+            slot.state->str = "(null)";
+            return true;
+
           default:
             return false;
         }
@@ -659,13 +688,31 @@ error:
           case PRINTF_CONVERSION_I:
           case PRINTF_CONVERSION_D:
             /* Float to Int, add a conversion. */
+            printf("Warning: Have a int paramter for %%f like specifier, take care of it\n");
             arg = builder->CreateFPToSI(arg, Type::getInt32Ty(module->getContext()));
             dst_type = Type::getInt32PtrTy(module->getContext(), 1);
             sizeof_size = sizeof(int);
             return true;
 
+          case PRINTF_CONVERSION_O:
+          case PRINTF_CONVERSION_U:
+          case PRINTF_CONVERSION_x:
+          case PRINTF_CONVERSION_X:
+            /* Float to uint, add a conversion. */
+            printf("Warning: Have a uint paramter for %%f like specifier, take care of it\n");
+            arg = builder->CreateFPToUI(arg, Type::getInt32Ty(module->getContext()));
+            dst_type = Type::getInt32PtrTy(module->getContext(), 1);
+            sizeof_size = sizeof(int);
+            return true;
+
           case PRINTF_CONVERSION_F:
           case PRINTF_CONVERSION_f:
+          case PRINTF_CONVERSION_E:
+          case PRINTF_CONVERSION_e:
+          case PRINTF_CONVERSION_G:
+          case PRINTF_CONVERSION_g:
+          case PRINTF_CONVERSION_A:
+          case PRINTF_CONVERSION_a:
             arg = builder->CreateFPCast(arg, Type::getFloatTy(module->getContext()));
             dst_type = Type::getFloatPtrTy(module->getContext(), 1);
             sizeof_size = sizeof(float);
-- 
1.8.3.2



More information about the Beignet mailing list