Support testing nul for property that is an object.
This commit is contained in:
parent
87c019c65c
commit
35f5d51028
|
|
@ -192,6 +192,9 @@ static void draw_binary_vec4_compare_class(ivl_expr_t expr)
|
|||
return;
|
||||
}
|
||||
|
||||
/* A signal/variable is compared to null. Implement this with
|
||||
the %test_nul statement, which peeks at the variable
|
||||
contents directly. */
|
||||
if (ivl_expr_type(re)==IVL_EX_NULL && ivl_expr_type(le)==IVL_EX_SIGNAL) {
|
||||
ivl_signal_t sig= ivl_expr_signal(le);
|
||||
|
||||
|
|
@ -210,8 +213,33 @@ static void draw_binary_vec4_compare_class(ivl_expr_t expr)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ivl_expr_type(re)==IVL_EX_NULL && ivl_expr_type(le)==IVL_EX_PROPERTY) {
|
||||
ivl_signal_t sig = ivl_expr_signal(le);
|
||||
unsigned pidx = ivl_expr_property_idx(le);
|
||||
ivl_expr_t idx_expr = ivl_expr_oper1(le);
|
||||
int idx = 0;
|
||||
|
||||
/* If the property has an array index, then evaluate it
|
||||
into an index register. */
|
||||
if ( idx_expr ) {
|
||||
idx = allocate_word();
|
||||
draw_eval_expr_into_integer(idx_expr, idx);
|
||||
}
|
||||
|
||||
fprintf(vvp_out, " %%load/obj v%p_0;\n", sig);
|
||||
fprintf(vvp_out, " %%test_nul/prop %u, %d;\n", pidx, idx);
|
||||
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
|
||||
fprintf(vvp_out, " %%flag_get/vec4 4;\n");
|
||||
if (ivl_expr_opcode(expr) == 'n')
|
||||
fprintf(vvp_out, " %%inv;\n");
|
||||
|
||||
if (idx != 0) clr_word(idx);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stderr, "SORRY: Compare class handles not implemented\n");
|
||||
fprintf(vvp_out, " ; XXXX compare class handles.\n");
|
||||
fprintf(vvp_out, " ; XXXX compare class handles. re-type=%d, le-type=%d\n",
|
||||
ivl_expr_type(re), ivl_expr_type(le));
|
||||
vvp_errors += 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ extern bool of_SUBSTR_VEC4(vthread_t thr, vvp_code_t code);
|
|||
extern bool of_TEST_NUL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_TEST_NUL_A(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_TEST_NUL_OBJ(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_TEST_NUL_PROP(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_VPI_CALL(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_WAIT(vthread_t thr, vvp_code_t code);
|
||||
extern bool of_WAIT_FORK(vthread_t thr, vvp_code_t code);
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%pow", of_POW, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%pow/s", of_POW_S, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%pow/wr", of_POW_WR, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%prop/obj",of_PROP_OBJ,1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
{ "%prop/obj",of_PROP_OBJ,2, {OA_NUMBER, OA_BIT1, 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, 1, {OA_NUMBER, OA_NONE, OA_NONE} },
|
||||
|
|
@ -289,9 +289,10 @@ static const struct opcode_table_s opcode_table[] = {
|
|||
{ "%subi", of_SUBI, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
|
||||
{ "%substr", of_SUBSTR, 2,{OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%substr/vec4",of_SUBSTR_VEC4,2,{OA_BIT1, OA_BIT2, OA_NONE} },
|
||||
{ "%test_nul", of_TEST_NUL, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%test_nul/a", of_TEST_NUL_A, 2,{OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%test_nul/obj",of_TEST_NUL_OBJ,0,{OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%test_nul", of_TEST_NUL, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
|
||||
{ "%test_nul/a", of_TEST_NUL_A, 2,{OA_ARR_PTR, OA_BIT1, OA_NONE} },
|
||||
{ "%test_nul/obj", of_TEST_NUL_OBJ, 0,{OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%test_nul/prop",of_TEST_NUL_PROP,2,{OA_NUMBER, OA_BIT1, OA_NONE} },
|
||||
{ "%wait", of_WAIT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} },
|
||||
{ "%wait/fork",of_WAIT_FORK,0,{OA_NONE, OA_NONE, OA_NONE} },
|
||||
{ "%xnor", of_XNOR, 0, {OA_NONE, OA_NONE, OA_NONE} },
|
||||
|
|
|
|||
|
|
@ -1046,7 +1046,7 @@ This opcode raises the left operand by the right operand, and pushes
|
|||
the result.
|
||||
|
||||
* %prop/v <pid>
|
||||
* %prop/obj <pid>
|
||||
* %prop/obj <pid>, <idx>
|
||||
* %prop/r <pid>
|
||||
* %prop/str <pid>
|
||||
|
||||
|
|
@ -1362,6 +1362,7 @@ The string value is NOT popped.
|
|||
|
||||
* %test_nul <var-label>
|
||||
* %test_nul/obj
|
||||
* %test_nul/prop <pid>, <idx>
|
||||
|
||||
This instruction tests the contents of the addressed variable to see
|
||||
if it is null. If it is, set flag bit 4 to 1. Otherwise, set flag bit
|
||||
|
|
@ -1370,6 +1371,10 @@ if it is null. If it is, set flag bit 4 to 1. Otherwise, set flag bit
|
|||
The %test_null/obj tests the object on the top of the stack, instead
|
||||
of any variable. The value in the stack is NOT popped.
|
||||
|
||||
The %test_nul/prop instruction tests an object property for nul. The
|
||||
object with the property is peeked from the top of the object stack,
|
||||
and the <idx> is the array index if the property is an array of objects.
|
||||
|
||||
This is intended to implement the SystemVerilog expression
|
||||
(<var>==null), where <var> is a class variable.
|
||||
|
||||
|
|
|
|||
|
|
@ -288,6 +288,8 @@ void vthread_s::debug_dump(ostream&fd, const char*label)
|
|||
fd << "**** vec4 stack..." << endl;
|
||||
for (size_t idx = stack_vec4_.size() ; idx > 0 ; idx -= 1)
|
||||
fd << " " << (stack_vec4_.size()-idx) << ": " << stack_vec4_[idx-1] << endl;
|
||||
fd << "**** str stack (" << stack_str_.size() << ")..." << endl;
|
||||
fd << "**** obj stack (" << stack_obj_size_ << ")..." << endl;
|
||||
fd << "**** Done ****" << endl;
|
||||
}
|
||||
|
||||
|
|
@ -6642,6 +6644,33 @@ bool of_TEST_NUL_OBJ(vthread_t thr, vvp_code_t)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* %test_nul/prop <pid>, <idx>
|
||||
*/
|
||||
bool of_TEST_NUL_PROP(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
unsigned pid = cp->number;
|
||||
unsigned idx = cp->bit_idx[0];
|
||||
|
||||
if (idx != 0) {
|
||||
assert(idx < vthread_s::WORDS_COUNT);
|
||||
idx = thr->words[idx].w_uint;
|
||||
}
|
||||
|
||||
vvp_object_t&obj = thr->peek_object();
|
||||
vvp_cobject*cobj = obj.peek<vvp_cobject>();
|
||||
|
||||
vvp_object_t val;
|
||||
cobj->get_object(pid, val, idx);
|
||||
|
||||
if (val.test_nil())
|
||||
thr->flags[4] = BIT4_1;
|
||||
else
|
||||
thr->flags[4] = BIT4_0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool of_VPI_CALL(vthread_t thr, vvp_code_t cp)
|
||||
{
|
||||
vpip_execute_vpi_call(thr, cp->handle);
|
||||
|
|
|
|||
Loading…
Reference in New Issue