More vec4 support for various things.

This commit is contained in:
Stephen Williams 2014-02-07 11:24:41 -08:00
parent 401fccdf6e
commit 60d37e1f53
8 changed files with 146 additions and 106 deletions

View File

@ -68,18 +68,13 @@ static int eval_darray_new(ivl_expr_t ex)
if (init_expr && ivl_expr_type(init_expr)==IVL_EX_ARRAY_PATTERN) {
int idx;
struct vector_info rvec;
unsigned wid;
switch (ivl_type_base(element_type)) {
case IVL_VT_BOOL:
wid = width_of_packed_type(element_type);
for (idx = 0 ; idx < ivl_expr_parms(init_expr) ; idx += 1) {
rvec = draw_eval_expr_wid(ivl_expr_parm(init_expr,idx),
wid, STUFF_OK_XZ);
draw_eval_vec4(ivl_expr_parm(init_expr,idx), STUFF_OK_XZ);
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar/obj 3, %u, %u;\n",
rvec.base, rvec.wid);
if (rvec.base >= 4) clr_vector(rvec);
fprintf(vvp_out, " %%set/dar/obj/vec4 3;\n");
fprintf(vvp_out, " %%pop/vec4 1;\n");
}
break;
case IVL_VT_REAL:

View File

@ -27,6 +27,17 @@
# include <assert.h>
# include <stdbool.h>
static void resize_vec4_wid(ivl_expr_t expr, unsigned wid)
{
if (ivl_expr_width(expr) == wid)
return;
if (ivl_expr_signed(expr))
fprintf(vvp_out, " %%pad/s %u;\n", wid);
else
fprintf(vvp_out, " %%pad/u %u;\n", wid);
}
static void draw_binary_vec4_arith(ivl_expr_t expr, int stuff_ok_flag)
{
ivl_expr_t le = ivl_expr_oper1(expr);
@ -153,6 +164,47 @@ static void draw_binary_vec4_compare_string(ivl_expr_t expr)
}
}
static void draw_binary_vec4_compare_class(ivl_expr_t expr)
{
ivl_expr_t le = ivl_expr_oper1(expr);
ivl_expr_t re = ivl_expr_oper2(expr);
if (ivl_expr_type(le) == IVL_EX_NULL) {
ivl_expr_t tmp = le;
le = re;
re = tmp;
}
/* Special case: If both operands are null, then the
expression has a constant value. */
if (ivl_expr_type(le)==IVL_EX_NULL && ivl_expr_type(re)==IVL_EX_NULL) {
switch (ivl_expr_opcode(expr)) {
case 'e': /* == */
fprintf(vvp_out, " %%pushi/vec4 1, 0, 1;\n");
break;
case 'n': /* != */
fprintf(vvp_out, " %%pushi/vec4 0, 0, 1;\n");
break;
default:
assert(0);
break;
}
return;
}
if (ivl_expr_type(re)==IVL_EX_NULL && ivl_expr_type(le)==IVL_EX_SIGNAL) {
fprintf(vvp_out, " %%test_nul v%p_0;\n", ivl_expr_signal(le));
fprintf(vvp_out, " %%flag_get/vec4 4;\n");
if (ivl_expr_opcode(expr) == 'n')
fprintf(vvp_out, " %%inv;\n");
return;
}
fprintf(stderr, "SORRY: Compare class handles not implemented\n");
fprintf(vvp_out, " ; XXXX compare class handles.\n");
vvp_errors += 1;
}
static void draw_binary_vec4_compare(ivl_expr_t expr, int stuff_ok_flag)
{
ivl_expr_t le = ivl_expr_oper1(expr);
@ -182,8 +234,21 @@ static void draw_binary_vec4_compare(ivl_expr_t expr, int stuff_ok_flag)
return;
}
if ((ivl_expr_value(le)==IVL_VT_CLASS)
&& (ivl_expr_value(re)==IVL_VT_CLASS)) {
draw_binary_vec4_compare_class(expr);
return;
}
unsigned use_wid = ivl_expr_width(le);
if (ivl_expr_width(re) > use_wid)
use_wid = ivl_expr_width(re);
draw_eval_vec4(le, stuff_ok_flag);
resize_vec4_wid(le, use_wid);
draw_eval_vec4(re, stuff_ok_flag);
resize_vec4_wid(re, use_wid);
switch (ivl_expr_opcode(expr)) {
case 'e': /* == */
@ -372,12 +437,16 @@ static void draw_binary_vec4_le(ivl_expr_t expr, int stuff_ok_flag)
/* NOTE: I think I would rather the elaborator handle the
operand widths. When that happens, take this code out. */
unsigned use_wid = ivl_expr_width(le);
if (ivl_expr_width(re) > use_wid)
use_wid = ivl_expr_width(re);
draw_eval_vec4(le, stuff_ok_flag);
if (ivl_expr_width(le) < ivl_expr_width(re))
fprintf(vvp_out, " %%pad/%c %u;\n", s_flag, ivl_expr_width(re));
resize_vec4_wid(le, use_wid);
draw_eval_vec4(re, stuff_ok_flag);
if (ivl_expr_width(re) < ivl_expr_width(le))
fprintf(vvp_out, " %%pad/%c %u;\n", s_flag, ivl_expr_width(le));
resize_vec4_wid(re, use_wid);
switch (use_opcode) {
case 'L':
@ -593,6 +662,16 @@ static void draw_number_vec4(ivl_expr_t expr)
}
}
static void draw_property_vec4(ivl_expr_t expr)
{
ivl_signal_t sig = ivl_expr_signal(expr);
unsigned pidx = ivl_expr_property_idx(expr);
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
fprintf(vvp_out, " %%prop/v %u;\n", pidx);
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
}
static void draw_select_vec4(ivl_expr_t expr)
{
// This is the sub-expression to part-select.
@ -915,6 +994,10 @@ static void draw_unary_vec4(ivl_expr_t expr, int stuff_ok_flag)
switch (ivl_expr_value(sub)) {
case IVL_VT_LOGIC:
draw_eval_vec4(sub, STUFF_OK_XZ);
if (ivl_expr_width(expr) < ivl_expr_width(sub)) {
fprintf(vvp_out, " %%pushi/vec4 0, 0, 1;\n");
fprintf(vvp_out, " %%part/u %u;\n", ivl_expr_width(expr));
}
fprintf(vvp_out, " %%cast2;\n");
break;
case IVL_VT_BOOL:
@ -982,6 +1065,10 @@ void draw_eval_vec4(ivl_expr_t expr, int stuff_ok_flag)
draw_unary_vec4(expr, stuff_ok_flag);
return;
case IVL_EX_PROPERTY:
draw_property_vec4(expr);
return;
default:
break;
}

View File

@ -860,25 +860,21 @@ static int show_stmt_assign_darray_pattern(ivl_statement_t net)
ivl_type_t element_type = ivl_type_element(var_type);
unsigned idx;
struct vector_info rvec;
#if 0
unsigned element_width = 1;
if (ivl_type_base(element_type) == IVL_VT_BOOL)
element_width = width_of_packed_type(element_type);
else if (ivl_type_base(element_type) == IVL_VT_LOGIC)
element_width = width_of_packed_type(element_type);
#endif
assert(ivl_expr_type(rval) == IVL_EX_ARRAY_PATTERN);
for (idx = 0 ; idx < ivl_expr_parms(rval) ; idx += 1) {
switch (ivl_type_base(element_type)) {
case IVL_VT_BOOL:
case IVL_VT_LOGIC:
rvec = draw_eval_expr_wid(ivl_expr_parm(rval,idx),
element_width, STUFF_OK_XZ);
draw_eval_vec4(ivl_expr_parm(rval,idx), STUFF_OK_XZ);
fprintf(vvp_out, " %%ix/load 3, %u, 0;\n", idx);
fprintf(vvp_out, " %%set/dar v%p_0, %u, %u;\n",
var, rvec.base, rvec.wid);
if (rvec.base >= 4) clr_vector(rvec);
fprintf(vvp_out, " %%store/dar/vec4 v%p_0;\n", var);
break;
case IVL_VT_REAL:
@ -982,30 +978,26 @@ static int show_stmt_assign_sig_cobject(ivl_statement_t net)
if (ivl_type_base(prop_type) == IVL_VT_BOOL) {
assert(ivl_type_packed_dimensions(prop_type) == 1);
assert(ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0));
int wid = ivl_type_packed_msb(prop_type,0) - ivl_type_packed_lsb(prop_type,0) + 1;
struct vector_info val = draw_eval_expr_wid(rval, wid, STUFF_OK_XZ);
draw_eval_vec4(rval, STUFF_OK_XZ);
if (ivl_expr_value(rval)!=IVL_VT_BOOL)
fprintf(vvp_out, " %%cast2;\n");
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
fprintf(vvp_out, " %%store/prop/v %d, %u, %u; Store in bool property %s\n",
prop_idx, val.base, val.wid,
ivl_type_prop_name(sig_type, prop_idx));
fprintf(vvp_out, " %%store/prop/v %d; Store in bool property %s\n",
prop_idx, ivl_type_prop_name(sig_type, prop_idx));
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
clr_vector(val);
} else if (ivl_type_base(prop_type) == IVL_VT_LOGIC) {
assert(ivl_type_packed_dimensions(prop_type) == 1);
assert(ivl_type_packed_msb(prop_type,0) >= ivl_type_packed_lsb(prop_type, 0));
int wid = ivl_type_packed_msb(prop_type,0) - ivl_type_packed_lsb(prop_type,0) + 1;
struct vector_info val = draw_eval_expr_wid(rval, wid, STUFF_OK_XZ);
draw_eval_vec4(rval, STUFF_OK_XZ);
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
fprintf(vvp_out, " %%store/prop/v %d, %u, %u; Store in logic property %s\n",
prop_idx, val.base, val.wid,
ivl_type_prop_name(sig_type, prop_idx));
fprintf(vvp_out, " %%store/prop/v %d; Store in logic property %s\n",
prop_idx, ivl_type_prop_name(sig_type, prop_idx));
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
clr_vector(val);
} else if (ivl_type_base(prop_type) == IVL_VT_REAL) {

View File

@ -1366,41 +1366,9 @@ static int show_stmt_disable(ivl_statement_t net, ivl_scope_t sscope)
return rc;
}
static struct vector_info reduction_or(struct vector_info cvec)
{
struct vector_info result;
switch (cvec.base) {
case 0:
result.base = 0;
result.wid = 1;
break;
case 1:
result.base = 1;
result.wid = 1;
break;
case 2:
case 3:
result.base = 0;
result.wid = 1;
break;
default:
clr_vector(cvec);
result.base = allocate_vector(1);
result.wid = 1;
assert(result.base);
fprintf(vvp_out, " %%or/r %u, %u, %u;\n", result.base,
cvec.base, cvec.wid);
break;
}
return result;
}
static int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope)
{
int rc = 0;
struct vector_info cvec;
unsigned top_label = local_count++;
@ -1418,16 +1386,16 @@ static int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope)
/* Draw the evaluation of the condition expression, and test
the result. If the expression evaluates to true, then
branch to the top label. */
cvec = draw_eval_expr(ivl_stmt_cond_expr(net), STUFF_OK_XZ|STUFF_OK_47);
if (cvec.wid > 1)
cvec = reduction_or(cvec);
draw_eval_vec4(ivl_stmt_cond_expr(net), STUFF_OK_XZ|STUFF_OK_47);
if (ivl_expr_width(ivl_stmt_cond_expr(net)) > 1)
fprintf(vvp_out, " %%or/r;\n");
int use_flag = allocate_flag();
fprintf(vvp_out, " %%flag_set/vec4 %d;\n", use_flag);
fprintf(vvp_out, " %%jmp/1 T_%u.%u, %u;\n",
thread_count, top_label, cvec.base);
if (cvec.base >= 8)
clr_vector(cvec);
thread_count, top_label, use_flag);
clr_flag(use_flag);
clear_expression_lookaside();
return rc;
}

View File

@ -204,6 +204,7 @@ extern bool of_SET_DAR(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR_OBJ(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t code);
extern bool of_SET_DAR_OBJ_VEC4(vthread_t thr, vvp_code_t code);
extern bool of_SET_X0(vthread_t thr, vvp_code_t code);
extern bool of_SET_X0_X(vthread_t thr, vvp_code_t code);
extern bool of_SHIFTL(vthread_t thr, vvp_code_t code);

View File

@ -236,7 +236,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%prop/obj",of_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%prop/r", of_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%prop/str",of_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%prop/v", of_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%prop/v", of_PROP_V, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%pushi/real",of_PUSHI_REAL,2,{OA_BIT1, OA_BIT2, OA_NONE} },
{ "%pushi/str", of_PUSHI_STR, 1,{OA_STRING, OA_NONE, OA_NONE} },
{ "%pushi/vec4",of_PUSHI_VEC4,3,{OA_BIT1, OA_BIT2, OA_NUMBER} },
@ -252,6 +252,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%set/dar/obj", of_SET_DAR_OBJ, 3,{OA_NUMBER,OA_BIT1,OA_BIT2} },
{ "%set/dar/obj/real",of_SET_DAR_OBJ_REAL,1,{OA_NUMBER,OA_NONE,OA_NONE} },
{ "%set/dar/obj/str", of_SET_DAR_OBJ_STR, 1,{OA_NUMBER,OA_NONE,OA_NONE} },
{ "%set/dar/obj/vec4",of_SET_DAR_OBJ_VEC4,1,{OA_NUMBER,OA_NONE,OA_NONE} },
{ "%set/x0", of_SET_X0, 3, {OA_FUNC_PTR, OA_BIT1, OA_BIT2} },
{ "%shiftl", of_SHIFTL, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%shiftr", of_SHIFTR, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
@ -264,7 +265,7 @@ static const struct opcode_table_s opcode_table[] = {
{ "%store/prop/obj",of_STORE_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/prop/r", of_STORE_PROP_R, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/prop/str",of_STORE_PROP_STR,1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/prop/v", of_STORE_PROP_V, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%store/prop/v", of_STORE_PROP_V, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
{ "%store/real", of_STORE_REAL, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%store/reala", of_STORE_REALA, 2, {OA_ARR_PTR, OA_BIT1, OA_NONE} },
{ "%store/str", of_STORE_STR, 1, {OA_FUNC_PTR,OA_NONE, OA_NONE} },

View File

@ -1045,7 +1045,7 @@ replaces the left operand.
This opcode raises the left operand by the right operand, and pushes
the result.
* %prop/v <pid>, <base>, <wid>
* %prop/v <pid>
* %prop/obj <pid>
* %prop/r <pid>
* %prop/str <pid>
@ -1120,8 +1120,7 @@ Release the force on the real signal that is represented by the functor
statement. The <type> is 0 for nets and 1 for registers. See the other
%release commands above.
* %repli
cate <count>
* %replicate <count>
Pop the vec4 value, replicate it <count> times, then push the
result. In other words, push the concatenation of <count> copies.
@ -1140,6 +1139,7 @@ using a fixed index register, use the register addressed by <index>.
* %set/dar/obj/real <index>
* %set/dar/obj/str <index>
* %set/dar/obj/vec4 <index>
The "%set/dar/obj/real" opcode sets the top value from the real-value
stack to the index. This does NOT pop the real value off the
@ -1147,7 +1147,8 @@ stack. The intent is that this value may be written to a bunch of
values.
The "%set/dar/obj/str" opcode does the same but for string values and
uses the string stack.
uses the string stack, and the "%set/dar/obj/vec4" for vec4 values and
the vector stack.
* %set/v <var-label>, <bit>, <wid> (XXXX Old definition)
@ -1221,7 +1222,7 @@ See also %load/obj.
* %store/prop/obj <index>
* %store/prop/r <index>
* %store/prop/str <index>
* %store/prop/v <index>, <bit>, <wid>
* %store/prop/v <index>
The %store/prop/r pops a real value from the real stack and stores it
into the the property number <index> of a cobject in the top of the

View File

@ -5191,37 +5191,22 @@ bool of_PROP_STR(vthread_t thr, vvp_code_t cp)
}
/*
* %prop/v <pid> <base> <wid>
* %prop/v <pid>
*
* Load a property <id> from the cobject on the top of the stack into
* the vector space at <base>.
*/
bool of_PROP_V(vthread_t thr, vvp_code_t cp)
{
#if 0
unsigned pid = cp->bit_idx[0];
unsigned dst = cp->bit_idx[1];
unsigned wid = cp->number;
unsigned pid = cp->number;
thr_check_addr(thr, dst+wid-1);
vvp_object_t&obj = thr->peek_object();
vvp_cobject*cobj = obj.peek<vvp_cobject>();
vvp_vector4_t val;
cobj->get_vec4(pid, val);
thr->push_vec4(val);
if (val.size() > wid)
val.resize(wid);
thr->bits4.set_vec(dst, val);
if (val.size() < wid) {
for (unsigned idx = val.size() ; idx < wid ; idx += 1)
thr->bits4.set_bit(dst+idx, BIT4_X);
}
#else
fprintf(stderr, "XXXX NOT IMPLEMENTED: %%prop/v ...\n");
#endif
return true;
}
@ -5567,6 +5552,23 @@ bool of_SET_DAR_OBJ_REAL(vthread_t thr, vvp_code_t cp)
return true;
}
/*
* %set/dar/obj/str <index>
*/
bool of_SET_DAR_OBJ_VEC4(vthread_t thr, vvp_code_t cp)
{
unsigned adr = thr->words[cp->number].w_int;
vvp_vector4_t value = thr->peek_vec4(0);
vvp_object_t&top = thr->peek_object();
vvp_darray*darray = top.peek<vvp_darray>();
assert(darray);
darray->set_word(adr, value);
return true;
}
/*
* %set/dar/obj/str <index>
*/
@ -5930,27 +5932,20 @@ bool of_STORE_PROP_STR(vthread_t thr, vvp_code_t cp)
}
/*
* %store/prop/v <id> <base> <wid>
* %store/prop/v <id>
*
* Store vector value into property <id> of cobject in the top of the stack.
*/
bool of_STORE_PROP_V(vthread_t thr, vvp_code_t cp)
{
#if 0
size_t pid = cp->bit_idx[0];
unsigned src = cp->bit_idx[1];
unsigned wid = cp->number;
vvp_vector4_t val = vthread_bits_to_vector(thr, src, wid);
size_t pid = cp->number;
vvp_vector4_t val = thr->pop_vec4();
vvp_object_t&obj = thr->peek_object();
vvp_cobject*cobj = obj.peek<vvp_cobject>();
assert(cobj);
cobj->set_vec4(pid, val);
#else
fprintf(stderr, "XXXX NOT IMPLEMENTED: %%store/prop/v ...\n");
#endif
return true;
}