Add support for abs() in logic threads.

Add the code generator code to handle the abs() function in signed
logic. Handle some of the interesting special cases as well.
This commit is contained in:
Stephen Williams 2008-05-04 22:00:01 -07:00
parent d60df2d75b
commit cc7187c172
2 changed files with 49 additions and 3 deletions

View File

@ -160,6 +160,28 @@ static void show_ternary_expression(ivl_expr_t net, unsigned ind)
}
}
void show_unary_expression(ivl_expr_t net, unsigned ind)
{
unsigned width = ivl_expr_width(net);
const char*sign = ivl_expr_signed(net)? "signed" : "unsigned";
const char*vt = vt_type_string(net);
char name[8];
switch (ivl_expr_opcode(net)) {
default:
snprintf(name, sizeof name, "%c", ivl_expr_opcode(net));
break;
case 'm':
snprintf(name, sizeof name, "abs()");
break;
}
fprintf(out, "%*s<unary \"%s\" width=%u, %s, type=%s>\n", ind, "",
name, width, sign, vt);
show_expression(ivl_expr_oper1(net), ind+4);
}
void show_expression(ivl_expr_t net, unsigned ind)
{
unsigned idx;
@ -252,9 +274,7 @@ void show_expression(ivl_expr_t net, unsigned ind)
break;
case IVL_EX_UNARY:
fprintf(out, "%*s<unary \"%c\" width=%u, %s, type=%s>\n", ind, "",
ivl_expr_opcode(net), width, sign, vt);
show_expression(ivl_expr_oper1(net), ind+4);
show_unary_expression(net, ind);
break;
case IVL_EX_UFUNC:

View File

@ -2456,6 +2456,32 @@ static struct vector_info draw_unary_expr(ivl_expr_t exp, unsigned wid)
}
break;
case 'm': /* abs() */
res = draw_eval_expr_wid(sub, wid, 0);
if (!ivl_expr_signed(sub))
break;
if (res.base == 0 || res.base == 2 || res.base == 3)
break;
/* Handle the special case of a -1 constant. Make the
result a 1. */
if (res.base == 1) {
res.base = allocate_vector(wid);
fprintf(vvp_out, " %%movi %d, 1, %u;\n",
res.base, res.wid);
break;
}
fprintf(vvp_out, " %%cmpi/s %d, 0, %u;\n", res.base, res.wid);
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, 5;\n", thread_count, local_count);
fprintf(vvp_out, " %%inv %d, %u;\n", res.base, res.wid);
fprintf(vvp_out, " %%addi %d, 1, %u;\n", res.base, res.wid);
fprintf(vvp_out, "T_%u.%u ;\n", thread_count, local_count);
local_count += 1;
break;
default:
fprintf(stderr, "vvp error: unhandled unary: %c\n",
ivl_expr_opcode(exp));