static int show_stmt_assign_vector(ivl_statement_t net) { ivl_expr_t rval = ivl_stmt_rval(net); struct vector_info res; struct vector_info lres = {0, 0}; struct vec_slice_info*slices = 0; /* If this is a compressed assignment, then get the contents of the l-value. We need these values as part of the r-value calculation. */ if (ivl_stmt_opcode(net) != 0) { slices = calloc(ivl_stmt_lvals(net), sizeof(struct vec_slice_info)); lres = get_vec_from_lval(net, slices); } /* Handle the special case that the expression is a real value. Evaluate the real expression, then convert the result to a vector. Then store that vector into the l-value. */ if (ivl_expr_value(rval) == IVL_VT_REAL) { draw_eval_real(rval); /* This is the accumulated with of the l-value of the assignment. */ unsigned wid = ivl_stmt_lwidth(net); 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 " "r-value expression.\n", ivl_expr_file(rval), ivl_expr_lineno(rval), wid); vvp_errors += 1; } fprintf(vvp_out, " %%cvt/vr %u, %u;\n", res.base, res.wid); } else { res = draw_eval_expr(rval, 0); } switch (ivl_stmt_opcode(net)) { case 0: set_vec_to_lval(net, res); break; case '+': if (res.base > 3) { fprintf(vvp_out, " %%add %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); } else { fprintf(vvp_out, " %%add %u, %u, %u;\n", lres.base, res.base, res.wid); res.base = lres.base; } put_vec_to_lval(net, slices, res); break; case '-': fprintf(vvp_out, " %%sub %u, %u, %u;\n", lres.base, res.base, res.wid); fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); put_vec_to_lval(net, slices, res); break; case '*': if (res.base > 3) { fprintf(vvp_out, " %%mul %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); } else { fprintf(vvp_out, " %%mul %u, %u, %u;\n", lres.base, res.base, res.wid); res.base = lres.base; } put_vec_to_lval(net, slices, res); break; case '/': fprintf(vvp_out, " %%div%s %u, %u, %u;\n", ivl_expr_signed(rval)? "/s" : "", lres.base, res.base, res.wid); fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); put_vec_to_lval(net, slices, res); break; case '%': fprintf(vvp_out, " %%mod%s %u, %u, %u;\n", ivl_expr_signed(rval)? "/s" : "", lres.base, res.base, res.wid); fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); put_vec_to_lval(net, slices, res); break; case '&': if (res.base > 3) { fprintf(vvp_out, " %%and %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); } else { fprintf(vvp_out, " %%and %u, %u, %u;\n", lres.base, res.base, res.wid); res.base = lres.base; } put_vec_to_lval(net, slices, res); break; case '|': if (res.base > 3) { fprintf(vvp_out, " %%or %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); } else { fprintf(vvp_out, " %%or %u, %u, %u;\n", lres.base, res.base, res.wid); res.base = lres.base; } put_vec_to_lval(net, slices, res); break; case '^': if (res.base > 3) { fprintf(vvp_out, " %%xor %u, %u, %u;\n", res.base, lres.base, res.wid); clr_vector(lres); } else { fprintf(vvp_out, " %%xor %u, %u, %u;\n", lres.base, res.base, res.wid); res.base = lres.base; } put_vec_to_lval(net, slices, res); break; case 'l': /* lres <<= res */ fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", res.base, res.wid); fprintf(vvp_out, " %%shiftl/i0 %u, %u;\n", lres.base, res.wid); fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base, lres.base, res.wid); break; case 'r': /* lres >>= res */ fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", res.base, res.wid); fprintf(vvp_out, " %%shiftr/i0 %u, %u;\n", lres.base, res.wid); fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base, lres.base, res.wid); break; case 'R': /* lres >>>= res */ fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", res.base, res.wid); fprintf(vvp_out, " %%shiftr/s/i0 %u, %u;\n", lres.base, res.wid); fprintf(vvp_out, " %%mov %u, %u, %u;\n", res.base, lres.base, res.wid); break; default: fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net)); assert(0); break; } if (slices) free(slices); if (res.base > 3) clr_vector(res); return 0; }
static int show_stmt_assign_vector(ivl_statement_t net) { ivl_expr_t rval = ivl_stmt_rval(net); //struct vector_info res; //struct vector_info lres = {0, 0}; struct vec_slice_info*slices = 0; int idx_reg; /* If this is a compressed assignment, then get the contents of the l-value. We need these values as part of the r-value calculation. */ if (ivl_stmt_opcode(net) != 0) { slices = calloc(ivl_stmt_lvals(net), sizeof(struct vec_slice_info)); get_vec_from_lval(net, slices); } /* Handle the special case that the expression is a real value. Evaluate the real expression, then convert the result to a vector. Then store that vector into the l-value. */ if (ivl_expr_value(rval) == IVL_VT_REAL) { draw_eval_real(rval); /* This is the accumulated with of the l-value of the assignment. */ unsigned wid = ivl_stmt_lwidth(net); /* Convert a calculated real value to a vec4 value of the given width. We need to include the width of the result because real values to not have any inherit width. The real value will be popped, and a vec4 value pushed. */ fprintf(vvp_out, " %%cvt/vr %u;\n", wid); } else if (ivl_expr_value(rval) == IVL_VT_STRING) { /* Special case: vector to string casting */ ivl_lval_t lval = ivl_stmt_lval(net, 0); fprintf(vvp_out, " %%vpi_call %u %u \"$ivl_string_method$to_vec\", v%p_0, v%p_0 {0 0 0};\n", ivl_file_table_index(ivl_stmt_file(net)), ivl_stmt_lineno(net), ivl_expr_signal(rval), ivl_lval_sig(lval)); return 0; } else { unsigned wid = ivl_stmt_lwidth(net); draw_eval_vec4(rval); resize_vec4_wid(rval, wid); } switch (ivl_stmt_opcode(net)) { case 0: store_vec4_to_lval(net); break; case '+': fprintf(vvp_out, " %%add;\n"); put_vec_to_lval(net, slices); break; case '-': fprintf(vvp_out, " %%sub;\n"); put_vec_to_lval(net, slices); break; case '*': fprintf(vvp_out, " %%mul;\n"); put_vec_to_lval(net, slices); break; case '/': fprintf(vvp_out, " %%div%s;\n", ivl_expr_signed(rval)? "/s":""); put_vec_to_lval(net, slices); break; case '%': fprintf(vvp_out, " %%mod%s;\n", ivl_expr_signed(rval)? "/s":""); put_vec_to_lval(net, slices); break; case '&': fprintf(vvp_out, " %%and;\n"); put_vec_to_lval(net, slices); break; case '|': fprintf(vvp_out, " %%or;\n"); put_vec_to_lval(net, slices); break; case '^': fprintf(vvp_out, " %%xor;\n"); put_vec_to_lval(net, slices); break; case 'l': /* lval <<= expr */ idx_reg = allocate_word(); fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg); fprintf(vvp_out, " %%shiftl %d;\n", idx_reg); clr_word(idx_reg); put_vec_to_lval(net, slices); break; case 'r': /* lval >>= expr */ idx_reg = allocate_word(); fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg); fprintf(vvp_out, " %%shiftr %d;\n", idx_reg); clr_word(idx_reg); put_vec_to_lval(net, slices); break; case 'R': /* lval >>>= expr */ idx_reg = allocate_word(); fprintf(vvp_out, " %%ix/vec4 %d;\n", idx_reg); fprintf(vvp_out, " %%shiftr/s %d;\n", idx_reg); clr_word(idx_reg); put_vec_to_lval(net, slices); break; default: fprintf(vvp_out, "; UNSUPPORTED ASSIGNMENT OPCODE: %c\n", ivl_stmt_opcode(net)); assert(0); break; } if (slices) free(slices); return 0; }