Normalize the parsing of %fork and %disable opcodes.

This commit is contained in:
Stephen Williams 2015-12-27 13:07:42 -08:00
parent f275dac7a8
commit 1b33bf8615
8 changed files with 29 additions and 68 deletions

View File

@ -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();

View File

@ -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<vvp_code_t>(val.ptr);
else
code->cptr = reinterpret_cast<vvp_code_t>(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)
{

View File

@ -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);
/*

View File

@ -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. */

View File

@ -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

View File

@ -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_;
};

View File

@ -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;

View File

@ -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.