From 087f4794af2e22ada3fd9c4c0b8f1d7df7e380ff Mon Sep 17 00:00:00 2001 From: Cary R Date: Tue, 22 Mar 2011 19:34:20 -0700 Subject: [PATCH] vlog95: Print double values correctly and clean up string emitting. This patch adds code to make sure a double (Verilog real) constant is printed correctly. It also adds code to trim any leading escaped NULLs from an expression string. --- tgt-vlog95/expr.c | 2 +- tgt-vlog95/numbers.c | 52 ++++++++++++++++++++++++++++++++++++---- tgt-vlog95/vlog95_priv.h | 1 + 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/tgt-vlog95/expr.c b/tgt-vlog95/expr.c index 3db274719..2defb1d84 100644 --- a/tgt-vlog95/expr.c +++ b/tgt-vlog95/expr.c @@ -558,7 +558,7 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) emit_expr_signal(scope, expr, wid); break; case IVL_EX_STRING: - fprintf(vlog_out, "\"%s\"", ivl_expr_string(expr)); + emit_string(ivl_expr_string(expr)); break; case IVL_EX_TERNARY: emit_expr_ternary(scope, expr, wid); diff --git a/tgt-vlog95/numbers.c b/tgt-vlog95/numbers.c index 3327c6312..776a97973 100644 --- a/tgt-vlog95/numbers.c +++ b/tgt-vlog95/numbers.c @@ -16,6 +16,8 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +# include +# include # include "config.h" # include "vlog95_priv.h" @@ -175,11 +177,34 @@ void emit_real_number(double value) else fprintf(vlog_out, "(-1.0/0.0)"); return; } -// HERE: This needs to be reworked. We must have a trailing digit after the -// decimal point and we want to print all the significant digits. -// I think this will require our own printing routine. - if (value == 0.0) fprintf(vlog_out, "0.0"); - else fprintf(vlog_out, "%#.16g", value); + if (value == 0.0) { + if (1.0/value < 0.0) fprintf(vlog_out, "-0.0"); + else fprintf(vlog_out, "0.0"); + } else { + char buffer[32]; + char *cptr; + unsigned len; + /* Print the double to a temporary string using an extra digit. */ + buffer[sizeof(buffer)-1] = 0; + snprintf(buffer, sizeof(buffer), "%#.17g", value); + assert(buffer[sizeof(buffer)-1] == 0); + /* Check to see if there is a digit after the decimal point and + * add a digit if it is missing. */ + len = strlen(buffer); + if (buffer[len-1] == '.') { + assert((len + 1) < sizeof(buffer)); + buffer[len] = '0'; + len += 1; + buffer[len] = 0; + } + /* Now trim any extra trailing zero digits. */ + cptr = buffer + len - 1; + while ((*cptr == '0') && (*(cptr-1) != '.')) cptr -= 1; + *(cptr+1) = 0; + + /* Now print the processed output. */ + fprintf(vlog_out, "%s", buffer); + } } /* @@ -289,3 +314,20 @@ int32_t get_int32_from_number(ivl_expr_t expr, int *result_type) return get_int32_from_bits(ivl_expr_bits(expr), ivl_expr_width(expr), ivl_expr_signed(expr), result_type); } + +/* + * Routine to print a string value as a string after removing any leading + * escaped NULL bytes. + */ +void emit_string(const char* string) +{ + char *buffer = strdup(string); + char *cptr = buffer; + fprintf(vlog_out, "\""); + /* Prune any leading escaped NULL bytes. */ + while ((cptr[0] == '\\') && (cptr[1] == '0') && + (cptr[2] == '0') && (cptr[3] == '0')) cptr += 4; + if (*cptr) fprintf(vlog_out, "%s", cptr); + free(buffer); + fprintf(vlog_out, "\""); +} diff --git a/tgt-vlog95/vlog95_priv.h b/tgt-vlog95/vlog95_priv.h index f5a670c68..2404a9405 100644 --- a/tgt-vlog95/vlog95_priv.h +++ b/tgt-vlog95/vlog95_priv.h @@ -100,6 +100,7 @@ extern void emit_id(const char *id); extern void emit_real_number(double value); extern void emit_number(const char *bits, unsigned nbits, unsigned is_signed, const char *file, unsigned lineno); +extern void emit_string(const char *string); /* * Find the enclosing module scope.