support if-else in function definitions.

This commit is contained in:
steve 2000-02-14 00:12:09 +00:00
parent bd09bed662
commit b8ddbcf62b
1 changed files with 46 additions and 2 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
#if !defined(WINNT) #if !defined(WINNT)
#ident "$Id: t-vvm.cc,v 1.100 2000/02/13 19:59:33 steve Exp $" #ident "$Id: t-vvm.cc,v 1.101 2000/02/14 00:12:09 steve Exp $"
#endif #endif
# include <iostream> # include <iostream>
@ -52,6 +52,7 @@ class target_vvm : public target_t {
public: public:
target_vvm(); target_vvm();
~target_vvm();
virtual void start_design(ostream&os, const Design*); virtual void start_design(ostream&os, const Design*);
virtual void scope(ostream&os, const NetScope*); virtual void scope(ostream&os, const NetScope*);
@ -83,6 +84,7 @@ class target_vvm : public target_t {
virtual bool proc_block(ostream&os, const NetBlock*); virtual bool proc_block(ostream&os, const NetBlock*);
virtual void proc_case(ostream&os, const NetCase*net); virtual void proc_case(ostream&os, const NetCase*net);
virtual void proc_condit(ostream&os, const NetCondit*); virtual void proc_condit(ostream&os, const NetCondit*);
void proc_condit_fun(ostream&os, const NetCondit*);
virtual void proc_forever(ostream&os, const NetForever*); virtual void proc_forever(ostream&os, const NetForever*);
virtual void proc_repeat(ostream&os, const NetRepeat*); virtual void proc_repeat(ostream&os, const NetRepeat*);
virtual void proc_stask(ostream&os, const NetSTask*); virtual void proc_stask(ostream&os, const NetSTask*);
@ -104,6 +106,13 @@ class target_vvm : public target_t {
// being generated. // being generated.
string thread_class_; string thread_class_;
// This flag is true if we are writing out a function
// definition. Thread steps are not available within
// functions, and certain constructs are handled
// differently. A flag is enough because function definitions
// cannot nest.
bool function_def_flag_;
// Method definitions go into this file. // Method definitions go into this file.
char*defn_name; char*defn_name;
ofstream defn; ofstream defn;
@ -136,10 +145,15 @@ class target_vvm : public target_t {
target_vvm::target_vvm() target_vvm::target_vvm()
: delayed_name(0), init_code_name(0) : function_def_flag_(false), delayed_name(0), init_code_name(0)
{ {
} }
target_vvm::~target_vvm()
{
assert(function_def_flag_ == false);
}
/* /*
* This class emits code for the rvalue of a procedural * This class emits code for the rvalue of a procedural
* assignment. The expression is evaluated to fit the width * assignment. The expression is evaluated to fit the width
@ -865,6 +879,12 @@ void target_vvm::func_def(ostream&os, const NetFuncDef*def)
{ {
thread_step_ = 0; thread_step_ = 0;
const string name = mangle(def->name()); const string name = mangle(def->name());
// Flag that we are now in a function definition. Note that
// function definitions cannot nest.
assert(! function_def_flag_);
function_def_flag_ = true;
os << "// Function " << def->name() << endl; os << "// Function " << def->name() << endl;
os << "static void " << name << "();" << endl; os << "static void " << name << "();" << endl;
@ -873,6 +893,9 @@ void target_vvm::func_def(ostream&os, const NetFuncDef*def)
defn << "{" << endl; defn << "{" << endl;
def->proc()->emit_proc(os, this); def->proc()->emit_proc(os, this);
defn << "}" << endl; defn << "}" << endl;
assert(function_def_flag_);
function_def_flag_ = false;
} }
string target_vvm::defn_gate_outputfun_(ostream&os, string target_vvm::defn_gate_outputfun_(ostream&os,
@ -1751,6 +1774,11 @@ void target_vvm::proc_case(ostream&os, const NetCase*net)
void target_vvm::proc_condit(ostream&os, const NetCondit*net) void target_vvm::proc_condit(ostream&os, const NetCondit*net)
{ {
if (function_def_flag_) {
proc_condit_fun(os, net);
return;
}
string expr = emit_proc_rval(defn, 8, net->expr()); string expr = emit_proc_rval(defn, 8, net->expr());
unsigned if_step = ++thread_step_; unsigned if_step = ++thread_step_;
@ -1792,6 +1820,19 @@ void target_vvm::proc_condit(ostream&os, const NetCondit*net)
"_() {" << endl; "_() {" << endl;
} }
void target_vvm::proc_condit_fun(ostream&os, const NetCondit*net)
{
string expr = emit_proc_rval(defn, 8, net->expr());
defn << " // " << net->get_line() << ": conditional (if-else)"
<< endl;
defn << " if (" << expr << "[0] == V1) {" << endl;
net->emit_recurse_if(os, this);
defn << " } else {" << endl;
net->emit_recurse_else(os, this);
defn << " }" << endl;
}
/* /*
* The forever loop is implemented by starting a basic block, handing * The forever loop is implemented by starting a basic block, handing
* the statement, and putting in a goto to the beginning of the block. * the statement, and putting in a goto to the beginning of the block.
@ -2064,6 +2105,9 @@ extern const struct target tgt_vvm = {
}; };
/* /*
* $Log: t-vvm.cc,v $ * $Log: t-vvm.cc,v $
* Revision 1.101 2000/02/14 00:12:09 steve
* support if-else in function definitions.
*
* Revision 1.100 2000/02/13 19:59:33 steve * Revision 1.100 2000/02/13 19:59:33 steve
* Handle selecting memory words at run time. * Handle selecting memory words at run time.
* *