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:
parent
5ddd35565f
commit
7b705a0212
|
|
@ -938,17 +938,17 @@ static struct vector_info draw_binary_expr_logic(ivl_expr_t exp,
|
||||||
switch (ivl_expr_opcode(exp)) {
|
switch (ivl_expr_opcode(exp)) {
|
||||||
|
|
||||||
case '&':
|
case '&':
|
||||||
fprintf(vvp_out, " %%and %u, %u, %u;\n",
|
fprintf(vvp_out, " %%and %u, %u, %u;\n",
|
||||||
lv.base, rv.base, wid);
|
lv.base, rv.base, wid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '|':
|
case '|':
|
||||||
fprintf(vvp_out, " %%or %u, %u, %u;\n",
|
fprintf(vvp_out, " %%or %u, %u, %u;\n",
|
||||||
lv.base, rv.base, wid);
|
lv.base, rv.base, wid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '^':
|
case '^':
|
||||||
fprintf(vvp_out, " %%xor %u, %u, %u;\n",
|
fprintf(vvp_out, " %%xor %u, %u, %u;\n",
|
||||||
lv.base, rv.base, wid);
|
lv.base, rv.base, wid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,40 @@ void clr_word(int res)
|
||||||
word_alloc_mask &= ~ (1U << res);
|
word_alloc_mask &= ~ (1U << res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int draw_binary_real(ivl_expr_t exp)
|
static int draw_binary_real(ivl_expr_t exp)
|
||||||
{
|
{
|
||||||
int l, r = -1;
|
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));
|
l = draw_eval_real(ivl_expr_oper1(exp));
|
||||||
r = draw_eval_real(ivl_expr_oper2(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)
|
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);
|
ivl_expr_t sube = ivl_expr_oper1(exp);
|
||||||
int sub = draw_eval_real(sube);
|
int sub = draw_eval_real(sube);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue