vec4 support for ufuncs and ligical AND.
This commit is contained in:
parent
f89dbd48c8
commit
63fa44fa4a
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
static void function_argument_logic(ivl_signal_t port, ivl_expr_t expr)
|
||||
{
|
||||
struct vector_info res;
|
||||
unsigned ewidth, pwidth;
|
||||
|
||||
/* ports cannot be arrays. */
|
||||
|
|
@ -32,16 +31,12 @@ static void function_argument_logic(ivl_signal_t port, ivl_expr_t expr)
|
|||
|
||||
ewidth = ivl_expr_width(expr);
|
||||
pwidth = ivl_signal_width(port);
|
||||
/* Just like a normal assignment the function arguments need to
|
||||
* be evaluated at either their width or the argument width if
|
||||
* it is larger. */
|
||||
if (ewidth < pwidth) ewidth = pwidth;
|
||||
res = draw_eval_expr_wid(expr, ewidth, 0);
|
||||
|
||||
/* We could have extra bits so only select the ones we need. */
|
||||
fprintf(vvp_out, " %%set/v v%p_0, %u, %u;\n", port, res.base, pwidth);
|
||||
draw_eval_vec4(expr, 0);
|
||||
if (ewidth < pwidth)
|
||||
fprintf(vvp_out, " %%pad/u %u;\n", pwidth);
|
||||
|
||||
clr_vector(res);
|
||||
fprintf(vvp_out, " %%store/vec4 v%p_0, %u;\n", port, pwidth);
|
||||
}
|
||||
|
||||
static void function_argument_real(ivl_signal_t port, ivl_expr_t expr)
|
||||
|
|
@ -153,13 +148,10 @@ static void draw_ufunc_epilogue(ivl_expr_t expr)
|
|||
* parameter 0 of the function definition.
|
||||
*/
|
||||
|
||||
struct vector_info draw_ufunc_expr(ivl_expr_t expr, unsigned wid)
|
||||
void draw_ufunc_vec4(ivl_expr_t expr)
|
||||
{
|
||||
unsigned swid = ivl_expr_width(expr);
|
||||
ivl_scope_t def = ivl_expr_def(expr);
|
||||
ivl_signal_t retval = ivl_scope_port(def, 0);
|
||||
struct vector_info res;
|
||||
unsigned load_wid;
|
||||
|
||||
/* Take in arguments to function and call function code. */
|
||||
draw_ufunc_preamble(expr);
|
||||
|
|
@ -167,36 +159,10 @@ struct vector_info draw_ufunc_expr(ivl_expr_t expr, unsigned wid)
|
|||
/* Fresh basic block starts after the join. */
|
||||
clear_expression_lookaside();
|
||||
|
||||
/* The return value is in a signal that has the name of the
|
||||
expression. Load that into the thread and return the
|
||||
vector result. */
|
||||
|
||||
res.base = allocate_vector(wid);
|
||||
res.wid = wid;
|
||||
if (res.base == 0) {
|
||||
fprintf(stderr, "%s:%u: vvp.tgt error: "
|
||||
"Unable to allocate %u thread bits for function result.\n",
|
||||
ivl_expr_file(expr), ivl_expr_lineno(expr), wid);
|
||||
vvp_errors += 1;
|
||||
return res;
|
||||
}
|
||||
|
||||
assert(res.base != 0);
|
||||
|
||||
load_wid = swid;
|
||||
if (load_wid > ivl_signal_width(retval))
|
||||
load_wid = ivl_signal_width(retval);
|
||||
|
||||
assert(ivl_signal_dimensions(retval) == 0);
|
||||
fprintf(vvp_out, " %%load/v %u, v%p_0, %u;\n",
|
||||
res.base, retval, load_wid);
|
||||
|
||||
/* Pad the signal value with zeros. */
|
||||
if (load_wid < wid)
|
||||
pad_expr_in_place(expr, res, swid);
|
||||
fprintf(vvp_out, " %%load/vec4 v%p_0;\n", retval);
|
||||
|
||||
draw_ufunc_epilogue(expr);
|
||||
return res;
|
||||
}
|
||||
|
||||
void draw_ufunc_real(ivl_expr_t expr)
|
||||
|
|
|
|||
|
|
@ -3685,11 +3685,11 @@ struct vector_info draw_eval_expr_wid(ivl_expr_t expr, unsigned wid,
|
|||
case IVL_EX_SFUNC:
|
||||
res = draw_sfunc_expr(expr, wid);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case IVL_EX_UFUNC:
|
||||
res = draw_ufunc_expr(expr, wid);
|
||||
break;
|
||||
|
||||
#endif
|
||||
case IVL_EX_UNARY:
|
||||
res = draw_unary_expr(expr, wid);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -157,6 +157,29 @@ static void draw_binary_vec4_compare(ivl_expr_t expr, int stuff_ok_flag)
|
|||
}
|
||||
}
|
||||
|
||||
static void draw_binary_vec4_land(ivl_expr_t expr, int stuff_ok_flag)
|
||||
{
|
||||
ivl_expr_t le = ivl_expr_oper1(expr);
|
||||
ivl_expr_t re = ivl_expr_oper2(expr);
|
||||
|
||||
/* Push the left expression. Reduce it to a single bit if
|
||||
necessary. */
|
||||
draw_eval_vec4(le, STUFF_OK_XZ);
|
||||
if (ivl_expr_width(le) > 1)
|
||||
fprintf(vvp_out, " %%or/r;\n");
|
||||
|
||||
/* Now push the right expression. Again, reduce to a single
|
||||
bit if necessasry. */
|
||||
draw_eval_vec4(re, STUFF_OK_XZ);
|
||||
if (ivl_expr_width(re) > 1)
|
||||
fprintf(vvp_out, " %%or/r;\n");
|
||||
|
||||
fprintf(vvp_out, " %%and;\n");
|
||||
|
||||
if (ivl_expr_width(expr) > 1)
|
||||
fprintf(vvp_out, " %%pad/u %u;\n", ivl_expr_width(expr));
|
||||
}
|
||||
|
||||
static void draw_binary_vec4_le_real(ivl_expr_t expr)
|
||||
{
|
||||
ivl_expr_t le = ivl_expr_oper1(expr);
|
||||
|
|
@ -312,6 +335,10 @@ static void draw_binary_vec4_lrs(ivl_expr_t expr, int stuff_ok_flag)
|
|||
static void draw_binary_vec4(ivl_expr_t expr, int stuff_ok_flag)
|
||||
{
|
||||
switch (ivl_expr_opcode(expr)) {
|
||||
case 'a': /* Logical && */
|
||||
draw_binary_vec4_land(expr, stuff_ok_flag);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
|
|
@ -618,6 +645,10 @@ void draw_eval_vec4(ivl_expr_t expr, int stuff_ok_flag)
|
|||
draw_ternary_vec4(expr, stuff_ok_flag);
|
||||
return;
|
||||
|
||||
case IVL_EX_UFUNC:
|
||||
draw_ufunc_vec4(expr);
|
||||
return;
|
||||
|
||||
case IVL_EX_UNARY:
|
||||
draw_unary_vec4(expr, stuff_ok_flag);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ extern int draw_scope(ivl_scope_t scope, ivl_scope_t parent);
|
|||
|
||||
extern void draw_lpm_mux(ivl_lpm_t net);
|
||||
|
||||
extern struct vector_info draw_ufunc_expr(ivl_expr_t expr, unsigned wid);
|
||||
extern void draw_ufunc_vec4(ivl_expr_t expr);
|
||||
extern void draw_ufunc_real(ivl_expr_t expr);
|
||||
extern void draw_ufunc_string(ivl_expr_t expr);
|
||||
extern void draw_ufunc_object(ivl_expr_t expr);
|
||||
|
|
|
|||
|
|
@ -1654,11 +1654,15 @@ static int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope)
|
|||
/* Calculate the repeat count onto the top of the vec4 stack. */
|
||||
draw_eval_vec4(expr, STUFF_OK_XZ);
|
||||
|
||||
/* Test that 0 < expr */
|
||||
/* Test that 0 < expr, escape if expr <= 0. If the expr is
|
||||
unsigned, then we only need to try to escape if expr==0 as
|
||||
it will never be <0. */
|
||||
fprintf(vvp_out, "T_%u.%u %%dup/vec4;\n", thread_count, lab_top);
|
||||
fprintf(vvp_out, " %%pushi/vec4 0, 0, %u;\n", ivl_expr_width(expr));
|
||||
fprintf(vvp_out, " %%cmp/%s;\n", sign);
|
||||
fprintf(vvp_out, " %%jmp/1xz T_%u.%u, 5;\n", thread_count, lab_out);
|
||||
if (ivl_expr_signed(expr))
|
||||
fprintf(vvp_out, " %%jmp/1xz T_%u.%u, 5;\n", thread_count, lab_out);
|
||||
fprintf(vvp_out, " %%jmp/1 T_%u.%u, 4;\n", thread_count, lab_out);
|
||||
/* This adds -1 (all ones in 2's complement) to the count. */
|
||||
fprintf(vvp_out, " %%pushi/vec4 1, 0, %u;\n", ivl_expr_width(expr));
|
||||
fprintf(vvp_out, " %%sub;\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue