[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