[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