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:
parent
d60df2d75b
commit
cc7187c172
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
Loading…
Reference in New Issue