From e592b525157d94fc93f0374fe6d848c24c6a26e8 Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 15 Jun 2009 16:50:18 -0700 Subject: [PATCH] For real expressions evaluate non-real sub-exprs as bits and convert. When processing procedural real expressions we need to evaluate non-real sub-expressions as bit based expressions and then convert the result to a real value. This is particularly import for integer division. --- tgt-vvp/eval_real.c | 87 +++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 304f8921b..23ebcac4f 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -22,9 +22,6 @@ */ # include "vvp_priv.h" # include -#ifdef HAVE_MALLOC_H -# include -#endif # include # include # include @@ -55,9 +52,6 @@ static int draw_binary_real(ivl_expr_t expr) { int l, r = -1; - /* If the opcode is a vector only opcode then the sub expression - * must not be a real expression, so use vector evaluation and - * then convert that result to a real value. */ switch (ivl_expr_opcode(expr)) { case 'E': case 'N': @@ -70,22 +64,8 @@ static int draw_binary_real(ivl_expr_t expr) case 'A': case 'O': case 'X': - { - struct vector_info vi; - int res; - const char*sign_flag; - - vi = draw_eval_expr(expr, STUFF_OK_XZ); - res = allocate_word(); - sign_flag = ivl_expr_signed(expr)? "/s" : ""; - fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", - sign_flag, res, vi.base, vi.wid); - - fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); - - clr_vector(vi); - return res; - } + /* These should be caught in draw_eval_real(). */ + assert(0); } l = draw_eval_real(ivl_expr_oper1(expr)); @@ -120,16 +100,20 @@ static int draw_binary_real(ivl_expr_t expr) int lab_out = local_count++; int lab_r = local_count++; /* If r is NaN, the go out and accept l as result. */ - fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", r, r); - fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, lab_out); + fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", r, r); + fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, + lab_out); /* If l is NaN, the go out and accept r as result. */ - fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", l, l); - fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, lab_r); + fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", l, l); + fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, + lab_r); /* If l <= r then go out. */ - fprintf(vvp_out, " %%cmp/wr %d, %d;\n", r, l); - fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 5;\n", thread_count, lab_out); + fprintf(vvp_out, " %%cmp/wr %d, %d;\n", r, l); + fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 5;\n", thread_count, + lab_out); /* At this point we know we want r as the result. */ - fprintf(vvp_out, "T_%d.%d %%mov/wr %d, %d;\n", thread_count, lab_r, l, r); + fprintf(vvp_out, "T_%d.%d %%mov/wr %d, %d;\n", thread_count, + lab_r, l, r); fprintf(vvp_out, "T_%d.%d ;\n", thread_count, lab_out); break; } @@ -138,16 +122,20 @@ static int draw_binary_real(ivl_expr_t expr) int lab_out = local_count++; int lab_r = local_count++; /* If r is NaN, the go out and accept l as result. */ - fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", r, r); - fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, lab_out); + fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", r, r); + fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, + lab_out); /* If l is NaN, the go out and accept r as result. */ - fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", l, l); - fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, lab_r); + fprintf(vvp_out, " %%cmp/wr %d, %d; Is NaN?\n", l, l); + fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 4;\n", thread_count, + lab_r); /* if l >= r then go out. */ - fprintf(vvp_out, " %%cmp/wr %d, %d;\n", l, r); - fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 5;\n", thread_count, lab_out); + fprintf(vvp_out, " %%cmp/wr %d, %d;\n", l, r); + fprintf(vvp_out, " %%jmp/0xz T_%d.%d, 5;\n", thread_count, + lab_out); - fprintf(vvp_out, "T_%d.%d %%mov/wr %d, %d;\n", thread_count, lab_r, l, r); + fprintf(vvp_out, "T_%d.%d %%mov/wr %d, %d;\n", thread_count, + lab_r, l, r); fprintf(vvp_out, "T_%d.%d ;\n", thread_count, lab_out); break; } @@ -508,8 +496,10 @@ static int draw_unary_real(ivl_expr_t expr) return sub; } - fprintf(vvp_out, "; XXXX unary (%c) on sube in %d\n", ivl_expr_opcode(expr), sub); - fprintf(stderr, "XXXX evaluate unary (%c) on sube in %d\n", ivl_expr_opcode(expr), sub); + fprintf(vvp_out, "; XXXX unary (%c) on sube in %d\n", + ivl_expr_opcode(expr), sub); + fprintf(stderr, "XXXX evaluate unary (%c) on sube in %d\n", + ivl_expr_opcode(expr), sub); return 0; } @@ -517,6 +507,27 @@ int draw_eval_real(ivl_expr_t expr) { int res = 0; + /* If this expression/sub-expression is not real then we need + * to evaluate it as a bit value and then convert the bit based + * result to a real value. This is required to get integer + * division to work correctly. */ + if (ivl_expr_value(expr) != IVL_VT_REAL) { + struct vector_info vi; + int res; + const char*sign_flag; + + vi = draw_eval_expr(expr, STUFF_OK_XZ); + res = allocate_word(); + sign_flag = ivl_expr_signed(expr)? "/s" : ""; + fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n", sign_flag, res, + vi.base, vi.wid); + + fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res); + + clr_vector(vi); + return res; + } + switch (ivl_expr_type(expr)) { case IVL_EX_BINARY: