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

Zhigang Gong zhigang.gong at linux.intel.com
Mon Jun 23 02:15:09 PDT 2014


LGTM, pushed, thanks.

On Mon, Jun 23, 2014 at 04:38:56PM +0800, junyan.he at inbox.com wrote:
> 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
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list