From 1b33bf86158ba19935cc2df7d6059b9138601781 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Sun, 27 Dec 2015 13:07:42 -0800 Subject: [PATCH] Normalize the parsing of %fork and %disable opcodes. --- vvp/class_type.cc | 2 +- vvp/compile.cc | 53 +++++++++++------------------------------------ vvp/compile.h | 8 +++---- vvp/lexor.lex | 2 -- vvp/parse.y | 10 --------- vvp/part.h | 4 ++-- vvp/ufunc.cc | 6 +++--- vvp/ufunc.h | 12 ++++++----- 8 files changed, 29 insertions(+), 68 deletions(-) diff --git a/vvp/class_type.cc b/vvp/class_type.cc index 2f2ce608d..8ed59df31 100644 --- a/vvp/class_type.cc +++ b/vvp/class_type.cc @@ -595,7 +595,7 @@ void compile_class_property(unsigned idx, char*nam, char*typ, uint64_t array_siz void compile_class_done(void) { - struct __vpiScope*scope = vpip_peek_current_scope(); + __vpiScope*scope = vpip_peek_current_scope(); assert(scope); assert(compile_class); compile_class->finish_setup(); diff --git a/vvp/compile.cc b/vvp/compile.cc index c27ad545f..1fa2d425b 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -65,6 +65,7 @@ enum operand_e { OA_BIT2, /* The operand is a pointer to code space */ OA_CODE_PTR, + OA_CODE_PTR2, /* The operand is a variable or net pointer */ OA_FUNC_PTR, /* The operand is a second functor pointer */ @@ -141,6 +142,7 @@ static const struct opcode_table_s opcode_table[] = { { "%delay", of_DELAY, 2, {OA_BIT1, OA_BIT2, OA_NONE} }, { "%delayx", of_DELAYX, 1, {OA_NUMBER, OA_NONE, OA_NONE} }, { "%delete/obj",of_DELETE_OBJ,1,{OA_FUNC_PTR,OA_NONE, OA_NONE} }, + { "%disable", of_DISABLE, 1, {OA_VPI_PTR,OA_NONE, OA_NONE} }, { "%disable/fork",of_DISABLE_FORK,0,{OA_NONE,OA_NONE, OA_NONE} }, { "%div", of_DIV, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%div/s", of_DIV_S, 0, {OA_NONE, OA_NONE, OA_NONE} }, @@ -163,6 +165,7 @@ static const struct opcode_table_s opcode_table[] = { { "%force/vec4", of_FORCE_VEC4, 1,{OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%force/vec4/off",of_FORCE_VEC4_OFF,2,{OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%force/wr", of_FORCE_WR, 1,{OA_FUNC_PTR, OA_NONE, OA_NONE} }, + { "%fork", of_FORK, 2, {OA_CODE_PTR2,OA_VPI_PTR, OA_NONE} }, { "%free", of_FREE, 1, {OA_VPI_PTR, OA_NONE, OA_NONE} }, { "%inv", of_INV, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%ix/add", of_IX_ADD, 3, {OA_NUMBER, OA_BIT1, OA_BIT2} }, @@ -627,10 +630,12 @@ void compile_vpi_lookup(vpiHandle *handle, char*label) */ struct code_label_resolv_list_s: public resolv_list_s { - explicit code_label_resolv_list_s(char*lab) : resolv_list_s(lab) { + explicit code_label_resolv_list_s(char*lab, bool cptr2) : resolv_list_s(lab) { code = NULL; + cptr2_flag = cptr2; } struct vvp_code_s *code; + bool cptr2_flag; virtual bool resolve(bool mes); }; @@ -638,7 +643,7 @@ bool code_label_resolv_list_s::resolve(bool mes) { symbol_value_t val = sym_get_value(sym_codespace, label()); if (val.num) { - if (code->opcode == of_FORK) + if (cptr2_flag) code->cptr2 = reinterpret_cast(val.ptr); else code->cptr = reinterpret_cast(val.ptr); @@ -651,10 +656,10 @@ bool code_label_resolv_list_s::resolve(bool mes) return false; } -void code_label_lookup(struct vvp_code_s *code, char *label) +void code_label_lookup(struct vvp_code_s *code, char *label, bool cptr2) { struct code_label_resolv_list_s *res - = new struct code_label_resolv_list_s(label); + = new struct code_label_resolv_list_s(label, cptr2); res->code = code; @@ -1724,13 +1729,15 @@ void compile_code(char*label, char*mnem, comp_operands_t opa) break; case OA_CODE_PTR: + case OA_CODE_PTR2: if (opa->argv[idx].ltype != L_SYMB) { yyerror("operand format"); break; } assert(opa->argv[idx].symb.idx == 0); - code_label_lookup(code, opa->argv[idx].symb.text); + code_label_lookup(code, opa->argv[idx].symb.text, + op->argt[idx]==OA_CODE_PTR2); break; case OA_FUNC_PTR: @@ -1805,42 +1812,6 @@ void compile_codelabel(char*label) free(label); } - -void compile_disable(char*label, struct symb_s symb) -{ - if (label) - compile_codelabel(label); - - /* Fill in the basics of the %disable in the instruction. */ - vvp_code_t code = codespace_allocate(); - code->opcode = of_DISABLE; - - compile_vpi_lookup(&code->handle, symb.text); -} - -/* - * The %fork instruction is a little different from other instructions - * in that it has an extended field that holds the information needed - * to create the new thread. This includes the target PC and scope. - * I get these from the parser in the form of symbols. - */ -void compile_fork(char*label, struct symb_s dest, struct symb_s scope) -{ - if (label) - compile_codelabel(label); - - - /* Fill in the basics of the %fork in the instruction. */ - vvp_code_t code = codespace_allocate(); - code->opcode = of_FORK; - - /* Figure out the target PC. */ - code_label_lookup(code, dest.text); - - /* Figure out the target SCOPE. */ - compile_vpi_lookup(&code->handle, scope.text); -} - void compile_file_line(char*label, long file_idx, long lineno, char*description) { diff --git a/vvp/compile.h b/vvp/compile.h index 054aedd4f..8d4d1ee82 100644 --- a/vvp/compile.h +++ b/vvp/compile.h @@ -339,8 +339,11 @@ extern void functor_ref_lookup(vvp_net_t**ref, char*lab); * code points to a code structure that points to the instruction * field that receives the result, and the label is the name to * lookup. The lookup will free the label text when it is done. + * + * The cptr2 flag tells the lookup to write the code pointer into the + * cptr2 member of the code, instead of the cptr member. */ -extern void code_label_lookup(struct vvp_code_s *code, char *label); +extern void code_label_lookup(struct vvp_code_s *code, char *label, bool cptr2); /* * The `compile_udp_def' function creates a UDP. The `table' is a @@ -434,7 +437,6 @@ struct comp_operands_s { typedef struct comp_operands_s*comp_operands_t; extern void compile_code(char*label, char*mnem, comp_operands_t opa); -extern void compile_disable(char*label, struct symb_s symb); extern void compile_file_line(char*label, long file_idx, long lineno, char*description); @@ -460,8 +462,6 @@ extern void compile_vpi_func_call(char*label, char*name, unsigned string_stack); extern void print_vpi_call_errors(); -extern void compile_fork(char*label, struct symb_s targ_s, - struct symb_s scope_s); extern void compile_codelabel(char*label); /* diff --git a/vvp/lexor.lex b/vvp/lexor.lex index c6848a6cd..2b2a81f0d 100644 --- a/vvp/lexor.lex +++ b/vvp/lexor.lex @@ -234,8 +234,6 @@ static char* strdupnew(char const *str) "%vpi_call/i" { return K_vpi_call_i; } "%vpi_func" { return K_vpi_func; } "%vpi_func/r" { return K_vpi_func_r; } -"%disable" { return K_disable; } -"%fork" { return K_fork; } "%file_line" { return K_file_line; } /* Handle the specialized variable access functions. */ diff --git a/vvp/parse.y b/vvp/parse.y index 5d0f0314e..d54dac6c3 100644 --- a/vvp/parse.y +++ b/vvp/parse.y @@ -101,7 +101,6 @@ static struct __vpiModPath*modpath_dst = 0; %token K_VAR_S K_VAR_STR K_VAR_I K_VAR_R K_VAR_2S K_VAR_2U %token K_vpi_call K_vpi_call_w K_vpi_call_i %token K_vpi_func K_vpi_func_r -%token K_disable K_fork %token K_ivl_version K_ivl_delay_selection %token K_vpi_module K_vpi_time_precision K_file_names K_file_line %token K_PORT_INPUT K_PORT_OUTPUT K_PORT_INOUT K_PORT_MIXED K_PORT_NODIR @@ -664,15 +663,6 @@ statement { compile_vpi_func_call($1, $5, -vpiRealVal, 0, $3, $4, $6.argc, $6.argv, $8, $9, $10); } - /* %disable statements are instructions that takes a scope reference - as an operand. It therefore is parsed uniquely. */ - - | label_opt K_disable symbol ';' - { compile_disable($1, $3); } - - - | label_opt K_fork symbol ',' symbol ';' - { compile_fork($1, $3, $5); } /* Scope statements come in two forms. There are the scope declaration and the scope recall. The declarations create the diff --git a/vvp/part.h b/vvp/part.h index 90a59a225..445cc24f5 100644 --- a/vvp/part.h +++ b/vvp/part.h @@ -88,7 +88,7 @@ class vvp_fun_part_aa : public vvp_fun_part, public automatic_hooks_s { vvp_context_t context); private: - struct __vpiScope*context_scope_; + __vpiScope*context_scope_; unsigned context_idx_; }; @@ -185,7 +185,7 @@ class vvp_fun_part_var_aa : public vvp_fun_part_var, public automatic_hooks_s { vvp_context_t context); private: - struct __vpiScope*context_scope_; + __vpiScope*context_scope_; unsigned context_idx_; }; diff --git a/vvp/ufunc.cc b/vvp/ufunc.cc index 7ac1f00ba..f15f038bf 100644 --- a/vvp/ufunc.cc +++ b/vvp/ufunc.cc @@ -40,7 +40,7 @@ ufunc_core::ufunc_core(unsigned owid, vvp_net_t*ptr, unsigned nports, vvp_net_t**ports, - vvp_code_t sa, struct __vpiScope*call_scope__, + vvp_code_t sa, __vpiScope*call_scope__, char*result_label, char*scope_label) : vvp_wide_fun_core(ptr, nports) { @@ -168,7 +168,7 @@ void compile_ufunc(char*label, char*code, unsigned wid, to the ports list. */ assert(argc == portc); - struct __vpiScope*call_scope = vpip_peek_current_scope(); + __vpiScope*call_scope = vpip_peek_current_scope(); assert(call_scope); /* Construct some phantom code that is the thread of the @@ -188,7 +188,7 @@ void compile_ufunc(char*label, char*code, unsigned wid, vvp_code_t exec_code = codespace_allocate(); exec_code->opcode = of_EXEC_UFUNC; - code_label_lookup(exec_code, code); + code_label_lookup(exec_code, code, false); vvp_code_t reap_code = codespace_allocate(); reap_code->opcode = of_REAP_UFUNC; diff --git a/vvp/ufunc.h b/vvp/ufunc.h index 1104f00d8..f267c629a 100644 --- a/vvp/ufunc.h +++ b/vvp/ufunc.h @@ -21,6 +21,8 @@ # include "config.h" +class __vpiScope; + /* * The .ufunc statement creates functors to represent user defined * functions within the netlist (as opposed to within behavioral @@ -53,13 +55,13 @@ class ufunc_core : public vvp_wide_fun_core { ufunc_core(unsigned ow, vvp_net_t*ptr, unsigned nports, vvp_net_t**ports, vvp_code_t start_address, - struct __vpiScope*call_scope, + __vpiScope*call_scope, char*result_label, char*scope_label); ~ufunc_core(); - struct __vpiScope*call_scope() { return call_scope_; } - struct __vpiScope*func_scope() { return func_scope_; } + __vpiScope*call_scope() { return call_scope_; } + __vpiScope*func_scope() { return func_scope_; } void assign_bits_to_ports(vvp_context_t context); void finish_thread(); @@ -85,8 +87,8 @@ class ufunc_core : public vvp_wide_fun_core { // This is a thread to execute the behavioral portion of the // function. vthread_t thread_; - struct __vpiScope*call_scope_; - struct __vpiScope*func_scope_; + __vpiScope*call_scope_; + __vpiScope*func_scope_; vvp_code_t code_; // Where the result will be.