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.
This commit is contained in:
Cary R 2008-04-21 13:45:32 -07:00 committed by Stephen Williams
parent 5ddd35565f
commit 7b705a0212
2 changed files with 50 additions and 4 deletions

View File

@ -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;

View File

@ -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);