From f733030b4158b10a6122bf56cb6db97c91955acc Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sun, 20 Dec 2009 12:13:55 +0000 Subject: [PATCH] Add warning about casting large integer values to reals. The compiler and vvp runtime don't correctly handle casts to reals when the source value is more than 63 bits in magnitude. This is fixed in devel, but can't be backported to v0.9 because it adds new vvp instructions. This patch causes the compiler to output a warning about potentiall incorrect results. --- tgt-vvp/eval_real.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 23ebcac4f..b5b57a16b 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -48,6 +48,27 @@ void clr_word(int res) word_alloc_mask &= ~ (1U << res); } +static void warn_about_large_cast(ivl_expr_t expr, unsigned wid) +{ + if (ivl_expr_signed(expr)) { + if (wid > 64) { + fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give " + "incorrect results when casting a signed " + "value greater than 64 bits to a real " + "value.\n", + ivl_expr_file(expr), ivl_expr_lineno(expr)); + } + } else { + if (wid > 63) { + fprintf(stderr, "%s:%u: tgt-vvp warning: V0.9 may give " + "incorrect results when casting an unsigned " + "value greater than 63 bits to a real " + "value.\n", + ivl_expr_file(expr), ivl_expr_lineno(expr)); + } + } +} + static int draw_binary_real(ivl_expr_t expr) { int l, r = -1; @@ -308,6 +329,7 @@ static int draw_sfunc_real(ivl_expr_t expr) fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", sign_flag, res, sv.base, sv.wid); + warn_about_large_cast(expr, sv.wid); fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); break; @@ -333,6 +355,7 @@ static int draw_signal_real_logic(ivl_expr_t expr) sign_flag, res, sv.base, sv.wid); clr_vector(sv); + warn_about_large_cast(expr, sv.wid); fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); return res; @@ -453,6 +476,7 @@ static int draw_unary_real(ivl_expr_t expr) fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", sign_flag, res, vi.base, vi.wid); + warn_about_large_cast(expr, vi.wid); fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); clr_vector(vi); @@ -470,6 +494,7 @@ static int draw_unary_real(ivl_expr_t expr) fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", sign_flag, res, vi.base, vi.wid); + warn_about_large_cast(expr, vi.wid); fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); clr_vector(vi); @@ -522,6 +547,7 @@ int draw_eval_real(ivl_expr_t expr) fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", sign_flag, res, vi.base, vi.wid); + warn_about_large_cast(expr, vi.wid); fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); clr_vector(vi); @@ -573,6 +599,7 @@ int draw_eval_real(ivl_expr_t expr) fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", sign_flag, res, sv.base, sv.wid); + warn_about_large_cast(expr, sv.wid); fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); } else {