static void string_ex_concat(ivl_expr_t expr) { unsigned repeat; assert(ivl_expr_parms(expr) != 0); assert(ivl_expr_repeat(expr) != 0); /* Push the first string onto the stack, no matter what. */ draw_eval_string(ivl_expr_parm(expr,0)); for (repeat = 0 ; repeat < ivl_expr_repeat(expr) ; repeat += 1) { unsigned idx; for (idx = (repeat==0)? 1 : 0 ; idx < ivl_expr_parms(expr) ; idx += 1) { ivl_expr_t sub = ivl_expr_parm(expr,idx); /* Special case: If operand is a string literal, then concat it using the %concati/str instruction. */ if (ivl_expr_type(sub) == IVL_EX_STRING) { fprintf(vvp_out, " %%concati/str \"%s\";\n", ivl_expr_string(sub)); continue; } draw_eval_string(sub); fprintf(vvp_out, " %%concat/str;\n"); } } }
static void draw_concat_vec4(ivl_expr_t expr) { /* Repeat the concatenation this many times to make a super-concatenation. */ unsigned repeat = ivl_expr_repeat(expr); /* This is the number of expressions that go into the concatenation. */ unsigned num_sube = ivl_expr_parms(expr); unsigned sub_idx = 0; ivl_expr_t sube; assert(num_sube > 0); /* Start with the most-significant bits. */ sube = ivl_expr_parm(expr, sub_idx); draw_eval_vec4(sube); /* Evaluate, but skip any zero replication expressions at the * head of this concatenation. */ while ((ivl_expr_type(sube) == IVL_EX_CONCAT) && (ivl_expr_repeat(sube) == 0)) { fprintf(vvp_out, " %%pop/vec4 1; skip zero replication\n"); sub_idx += 1; sube = ivl_expr_parm(expr, sub_idx); draw_eval_vec4(sube); } for ( sub_idx += 1 ; sub_idx < num_sube ; sub_idx += 1) { /* Concatenate progressively lower parts. */ sube = ivl_expr_parm(expr, sub_idx); /* Special case: The next expression is a NUMBER that can be concatenated using %concati/vec4 instructions. */ if (ivl_expr_type(sube) == IVL_EX_NUMBER) { draw_concat_number_vec4(sube, 1); continue; } draw_eval_vec4(sube); /* Evaluate, but skip any zero replication expressions in the * rest of this concatenation. */ if ((ivl_expr_type(sube) == IVL_EX_CONCAT) && (ivl_expr_repeat(sube) == 0)) { fprintf(vvp_out, " %%pop/vec4 1; skip zero replication\n"); continue; } fprintf(vvp_out, " %%concat/vec4; draw_concat_vec4\n"); } if (repeat > 1) { fprintf(vvp_out, " %%replicate %u;\n", repeat); } }
static void emit_expr_concat(ivl_scope_t scope, ivl_expr_t expr, unsigned wid) { unsigned repeat = ivl_expr_repeat(expr); unsigned idx, count = ivl_expr_parms(expr); if (repeat != 1) fprintf(vlog_out, "{%u", repeat); fprintf(vlog_out, "{"); count -= 1; for (idx = 0; idx < count; idx += 1) { emit_expr(scope, ivl_expr_parm(expr, idx), 0); fprintf(vlog_out, ", "); } emit_expr(scope, ivl_expr_parm(expr, count), 0); fprintf(vlog_out, "}"); if (repeat != 1) fprintf(vlog_out, "}"); }
void show_expression(ivl_expr_t net, unsigned ind) { assert(net); unsigned idx; ivl_parameter_t par = ivl_expr_parameter(net); const ivl_expr_type_t code = ivl_expr_type(net); unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*sized = ivl_expr_sized(net)? "sized" : "unsized"; const char*vt = vt_type_string(net); switch (code) { case IVL_EX_ARRAY: show_array_expression(net, ind); break; case IVL_EX_ARRAY_PATTERN: show_array_pattern_expression(net, ind); break; case IVL_EX_BACCESS: show_branch_access_expression(net, ind); break; case IVL_EX_BINARY: show_binary_expression(net, ind); break; case IVL_EX_CONCAT: fprintf(out, "%*s<concat repeat=%u, width=%u, %s, type=%s>\n", ind, "", ivl_expr_repeat(net), width, sign, vt); for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) show_expression(ivl_expr_parm(net, idx), ind+3); break; case IVL_EX_ENUMTYPE: show_enumtype_expression(net, ind); break; case IVL_EX_MEMORY: show_memory_expression(net, ind); break; case IVL_EX_NEW: show_new_expression(net, ind); break; case IVL_EX_NULL: show_null_expression(net, ind); break; case IVL_EX_PROPERTY: show_property_expression(net, ind); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(net); fprintf(out, "%*s<number=%u'b", ind, "", width); for (idx = width ; idx > 0 ; idx -= 1) fprintf(out, "%c", bits[idx-1]); fprintf(out, ", %s %s %s", sign, sized, vt); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); break; } case IVL_EX_SELECT: show_select_expression(net, ind); break; case IVL_EX_STRING: fprintf(out, "%*s<string=\"%s\", width=%u", ind, "", ivl_expr_string(net), ivl_expr_width(net)); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ", type=%s>\n", vt); break; case IVL_EX_SFUNC: fprintf(out, "%*s<function=\"%s\", width=%u, %s, type=%s file=%s:%u>\n", ind, "", ivl_expr_name(net), width, sign, vt, ivl_expr_file(net), ivl_expr_lineno(net)); { unsigned cnt = ivl_expr_parms(net); unsigned jdx; for (jdx = 0 ; jdx < cnt ; jdx += 1) show_expression(ivl_expr_parm(net, jdx), ind+3); } break; case IVL_EX_SIGNAL: show_signal_expression(net, ind); break; case IVL_EX_TERNARY: show_ternary_expression(net, ind); break; case IVL_EX_UNARY: show_unary_expression(net, ind); break; case IVL_EX_UFUNC: show_function_call(net, ind); break; case IVL_EX_REALNUM: { int jdx; union foo { double rv; unsigned char bv[sizeof(double)]; } tmp; tmp.rv = ivl_expr_dvalue(net); fprintf(out, "%*s<realnum=%f (", ind, "", tmp.rv); for (jdx = sizeof(double) ; jdx > 0 ; jdx -= 1) fprintf(out, "%02x", tmp.bv[jdx-1]); fprintf(out, ")"); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); } break; case IVL_EX_SHALLOWCOPY: show_shallowcopy(net, ind); break; default: fprintf(out, "%*s<expr_type=%d>\n", ind, "", code); break; } }
void show_expression(ivl_expr_t net, unsigned ind) { unsigned idx; const ivl_expr_type_t code = ivl_expr_type(net); ivl_parameter_t par = ivl_expr_parameter(net); unsigned width = ivl_expr_width(net); const char*sign = ivl_expr_signed(net)? "signed" : "unsigned"; const char*sized = ivl_expr_sized(net)? "sized" : "unsized"; const char*vt = vt_type_string(net); switch (code) { case IVL_EX_ARRAY: show_array_expression(net, ind); break; case IVL_EX_BACCESS: show_branch_access_expression(net, ind); break; case IVL_EX_BINARY: show_binary_expression(net, ind); break; case IVL_EX_CONCAT: fprintf(out, "%*s<concat repeat=%u, width=%u, %s, type=%s>\n", ind, "", ivl_expr_repeat(net), width, sign, vt); for (idx = 0 ; idx < ivl_expr_parms(net) ; idx += 1) show_expression(ivl_expr_parm(net, idx), ind+3); break; case IVL_EX_MEMORY: show_memory_expression(net, ind); break; case IVL_EX_NUMBER: { const char*bits = ivl_expr_bits(net); fprintf(out, "%*s<number=%u'b", ind, "", width); for (idx = width ; idx > 0 ; idx -= 1) fprintf(out, "%c", bits[idx-1]); fprintf(out, ", %s %s %s", sign, sized, vt); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); break; } case IVL_EX_SELECT: /* The SELECT expression can be used to express part select, or if the base is null vector extension. */ if (ivl_expr_oper2(net)) { fprintf(out, "%*s<select: width=%u, %s>\n", ind, "", width, sign); show_expression(ivl_expr_oper1(net), ind+3); show_expression(ivl_expr_oper2(net), ind+3); } else { fprintf(out, "%*s<expr pad: width=%u, %s>\n", ind, "", width, sign); show_expression(ivl_expr_oper1(net), ind+3); } break; case IVL_EX_STRING: fprintf(out, "%*s<string=\"%s\", width=%u", ind, "", ivl_expr_string(net), ivl_expr_width(net)); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ", type=%s>\n", vt); break; case IVL_EX_SFUNC: fprintf(out, "%*s<function=\"%s\", width=%u, %s, type=%s file=%s:%u>\n", ind, "", ivl_expr_name(net), width, sign, vt, ivl_expr_file(net), ivl_expr_lineno(net)); { unsigned cnt = ivl_expr_parms(net); unsigned jdx; for (jdx = 0 ; jdx < cnt ; jdx += 1) show_expression(ivl_expr_parm(net, jdx), ind+3); } break; case IVL_EX_SIGNAL: show_signal_expression(net, ind); break; case IVL_EX_TERNARY: show_ternary_expression(net, ind); break; case IVL_EX_UNARY: show_unary_expression(net, ind); break; case IVL_EX_UFUNC: show_function_call(net, ind); break; case IVL_EX_REALNUM: { int jdx; union foo { double rv; unsigned char bv[sizeof(double)]; } tmp; tmp.rv = ivl_expr_dvalue(net); fprintf(out, "%*s<realnum=%f (", ind, "", tmp.rv); for (jdx = sizeof(double) ; jdx > 0 ; jdx -= 1) fprintf(out, "%02x", tmp.bv[jdx-1]); fprintf(out, ")"); if (par != 0) fprintf(out, ", parameter=%s", ivl_parameter_basename(par)); fprintf(out, ">\n"); } break; default: fprintf(out, "%*s<expr_type=%u>\n", ind, "", code); break; } }