From 7b705a0212ff9c7896727d7258a92d28e1ced01f Mon Sep 17 00:00:00 2001 From: Cary R Date: Mon, 21 Apr 2008 13:45:32 -0700 Subject: [PATCH] Generate mixed real/vector expressions when needed. When generating a real expression you can have bits of the expression that use vector only operands. When this happens evaluate that part of the expression as a vector and then convert it to a real value. --- tgt-vvp/eval_expr.c | 6 +++--- tgt-vvp/eval_real.c | 48 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 63dabb04a..04848e572 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -938,17 +938,17 @@ static struct vector_info draw_binary_expr_logic(ivl_expr_t exp, switch (ivl_expr_opcode(exp)) { case '&': - fprintf(vvp_out, " %%and %u, %u, %u;\n", + fprintf(vvp_out, " %%and %u, %u, %u;\n", lv.base, rv.base, wid); break; case '|': - fprintf(vvp_out, " %%or %u, %u, %u;\n", + fprintf(vvp_out, " %%or %u, %u, %u;\n", lv.base, rv.base, wid); break; case '^': - fprintf(vvp_out, " %%xor %u, %u, %u;\n", + fprintf(vvp_out, " %%xor %u, %u, %u;\n", lv.base, rv.base, wid); break; diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 8382d003f..768d60d0c 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -51,11 +51,40 @@ void clr_word(int res) word_alloc_mask &= ~ (1U << res); } - static int draw_binary_real(ivl_expr_t exp) { 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(exp)) { + case 'E': + case 'N': + case 'l': + case 'r': + case 'R': + case '&': + case '|': + case '^': + case 'A': + case 'O': + case 'X': + { + struct vector_info vi; + vi = draw_eval_expr(exp, STUFF_OK_XZ); + int res = allocate_word(); + const char*sign_flag = ivl_expr_signed(exp)? "/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; + } + } + l = draw_eval_real(ivl_expr_oper1(exp)); r = draw_eval_real(ivl_expr_oper2(exp)); @@ -359,6 +388,23 @@ static int draw_ternary_real(ivl_expr_t exp) static int draw_unary_real(ivl_expr_t exp) { + /* If the opcode is a ~ then the sub expression must not be a + * real expression, so use vector evaluation and then convert + * that result to a real value. */ + if (ivl_expr_opcode(exp) == '~') { + struct vector_info vi; + vi = draw_eval_expr(exp, STUFF_OK_XZ); + int res = allocate_word(); + const char*sign_flag = ivl_expr_signed(exp)? "/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; + } + ivl_expr_t sube = ivl_expr_oper1(exp); int sub = draw_eval_real(sube);