Ability to compare arbitrary class-valued expression to nil.

This commit is contained in:
Stephen Williams 2014-09-07 16:22:49 -07:00
parent 8bb1d3dabe
commit facc982af4
5 changed files with 30 additions and 5 deletions

View File

@ -527,7 +527,7 @@ static struct vector_info draw_binary_expr_eq_class(ivl_expr_t expr)
ivl_expr_t word_ex = ivl_expr_oper1(le);
int word_ix = allocate_word();
draw_eval_expr_into_integer(word_ex, word_ix);
fprintf(vvp_out, " %%test_nula v%p, %d;\n", sig, word_ix);
fprintf(vvp_out, " %%test_nul/a v%p, %d;\n", sig, word_ix);
clr_word(word_ix);
}
fprintf(vvp_out, " %%mov %u, 4, 1;\n", res.base);
@ -536,6 +536,16 @@ static struct vector_info draw_binary_expr_eq_class(ivl_expr_t expr)
return res;
}
if (ivl_expr_type(re) == IVL_EX_NULL && ivl_expr_value(le)==IVL_VT_CLASS) {
draw_eval_object(le);
fprintf(vvp_out, " %%test_nul/obj;\n");
fprintf(vvp_out, " %%pop/obj 1, 0;\n");
fprintf(vvp_out, " %%mov %u, 4, 1;\n", res.base);
if (ivl_expr_opcode(expr) == 'n')
fprintf(vvp_out, " %%inv %u, 1;\n", res.base);
return res;
}
fprintf(stderr, "SORRY: Compare class handles not implemented\n");
fprintf(vvp_out, " ; XXXX compare class handles.\n");
vvp_errors += 1;

View File

@ -219,7 +219,8 @@ extern bool of_SUBI(vthread_t thr, vvp_code_t code);
extern bool of_SUBSTR(vthread_t thr, vvp_code_t code);
extern bool of_SUBSTR_V(vthread_t thr, vvp_code_t code);
extern bool of_TEST_NUL(vthread_t thr, vvp_code_t code);
extern bool of_TEST_NULA(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_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);

View File

@ -265,8 +265,9 @@ 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/v",of_SUBSTR_V,3,{OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%test_nul", of_TEST_NUL, 1,{OA_FUNC_PTR,OA_NONE, OA_NONE} },
{ "%test_nula", of_TEST_NULA,2,{OA_ARR_PTR, OA_BIT1, 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} },
{ "%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, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },

View File

@ -1134,10 +1134,14 @@ values into the vector space. The string value is NOT popped.
* %test_nul <var-label>
* %test_nul/obj
This instruction tests the contents of the addressed variable to see
if it is null. If it is, set bit 4 to 1. Otherwise, set bit 4 to 0.
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.
This is intended to implement the SystemVerilog expression
(<var>==null), where <var> is a class variable.

View File

@ -5832,7 +5832,7 @@ bool of_TEST_NUL(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_TEST_NULA(vthread_t thr, vvp_code_t cp)
bool of_TEST_NUL_A(vthread_t thr, vvp_code_t cp)
{
unsigned idx = cp->bit_idx[0];
unsigned adr = thr->words[idx].w_int;
@ -5853,6 +5853,15 @@ bool of_TEST_NULA(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_TEST_NUL_OBJ(vthread_t thr, vvp_code_t)
{
if (thr->peek_object().test_nil())
thr_put_bit(thr, 4, BIT4_1);
else
thr_put_bit(thr, 4, BIT4_0);
return true;
}
bool of_VPI_CALL(vthread_t thr, vvp_code_t cp)
{
vpip_execute_vpi_call(thr, cp->handle);