static void emit_expr_ternary(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { fprintf(vlog_out, "("); emit_expr(scope, ivl_expr_oper1(expr), 0); fprintf(vlog_out, " ? "); emit_expr(scope, ivl_expr_oper2(expr), wid); fprintf(vlog_out, " : "); emit_expr(scope, ivl_expr_oper3(expr), wid); fprintf(vlog_out, ")"); }
static void show_ternary_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); fprintf(out, "%*s<ternary width=%u, %s type=%s>\n", ind, "", width, sign, vt); show_expression(ivl_expr_oper1(net), ind+4); show_expression(ivl_expr_oper2(net), ind+4); show_expression(ivl_expr_oper3(net), ind+4); if (ivl_expr_width(ivl_expr_oper2(net)) != width) { fprintf(out, "ERROR: Width of TRUE expressions is %u, not %u\n", ivl_expr_width(ivl_expr_oper2(net)), width); stub_errors += 1; } if (ivl_expr_width(ivl_expr_oper3(net)) != width) { fprintf(out, "ERROR: Width of FALSE expressions is %u, not %u\n", ivl_expr_width(ivl_expr_oper3(net)), width); stub_errors += 1; } }
static void draw_ternary_vec4(ivl_expr_t expr) { ivl_expr_t cond = ivl_expr_oper1(expr); ivl_expr_t true_ex = ivl_expr_oper2(expr); ivl_expr_t false_ex = ivl_expr_oper3(expr); unsigned lab_true = local_count++; unsigned lab_out = local_count++; int use_flag = draw_eval_condition(cond); /* The condition flag is used after possibly other statements, so we need to put it into a non-common place. Allocate a safe flag bit and move the condition to the flag position. */ if (use_flag < 8) { int tmp_flag = allocate_flag(); assert(tmp_flag >= 8); fprintf(vvp_out, " %%flag_mov %d, %d;\n", tmp_flag, use_flag); use_flag = tmp_flag; } fprintf(vvp_out, " %%jmp/0 T_%u.%u, %d;\n", thread_count, lab_true, use_flag); /* If the condition is true or xz (not false), we need the true expression. If the condition is true, then we ONLY need the true expression. */ draw_eval_vec4(true_ex); fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n", thread_count, lab_out, use_flag); fprintf(vvp_out, "T_%u.%u ; End of true expr.\n", thread_count, lab_true); /* If the condition is false or xz (not true), we need the false expression. If the condition is false, then we ONLY need the false expression. */ draw_eval_vec4(false_ex); fprintf(vvp_out, " %%jmp/0 T_%u.%u, %d;\n", thread_count, lab_out, use_flag); fprintf(vvp_out, " ; End of false expr.\n"); /* Here, the condition is not true or false, it is xz. Both the true and false expressions have been pushed onto the stack, we just need to blend the bits. */ fprintf(vvp_out, " %%blend;\n"); fprintf(vvp_out, "T_%u.%u;\n", thread_count, lab_out); clr_flag(use_flag); }