diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index f20e18f29..e43eb1ac0 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001-2003 Stephen Williams (steve@icarus.com) * - * $Id: opcodes.txt,v 1.58 2004/12/17 04:47:47 steve Exp $ + * $Id: opcodes.txt,v 1.59 2005/01/22 00:58:22 steve Exp $ */ @@ -373,9 +373,10 @@ register. * %load/x , , This is an indexed load. It uses the contents of the specified index -register to select a bit from an array based at . The -bit is pulled from the addressed functor and loaded into the -destination bit. This function does not do any bounds checking. +register to select a bit from a vectur functor at . The +bit is pulled from the indexed bit of the addressed functor and loaded +into the destination thread bit. If the indexed value is beyond the +width of the vector, then the result is X. * %loadi/wr , , diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 1a2951e24..cb008fa89 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: vthread.cc,v 1.125 2004/12/17 04:47:47 steve Exp $" +#ident "$Id: vthread.cc,v 1.126 2005/01/22 00:58:22 steve Exp $" #endif # include "config.h" @@ -1747,17 +1747,34 @@ bool of_LOAD_WR(vthread_t thr, vvp_code_t cp) return true; } +/* + * %load/x , , + * + * is the destination thread bit and must be >= 4. + */ bool of_LOAD_X(vthread_t thr, vvp_code_t cp) { + // is the thread bit to load assert(cp->bit_idx[0] >= 4); - assert(cp->bit_idx[1] < 4); + unsigned bit = cp->bit_idx[0]; + + // is the index register to use. The actual index into + // the vector is the value of the index register. + unsigned index_idx = cp->bit_idx[1]; + unsigned index = thr->words[index_idx].w_int; + + // is converted to a vvp_net_t pointer from which we + // read our value. + vvp_net_t*net = cp->net; + + // For the %load to work, the functor must actually be a + // signal functor. Only signals save their vector value. + vvp_fun_signal*sig = dynamic_cast (net->fun); + assert(sig); + + vvp_bit4_t val = index >= sig->size()? BIT4_X : sig->value(index); + thr_put_bit(thr, bit, val); -#if 0 - vvp_ipoint_t ptr = ipoint_index(cp->iptr, thr->words[cp->bit_idx[1]].w_int); - thr_put_bit(thr, cp->bit_idx[0], functor_get(ptr)); -#else - fprintf(stderr, "XXXX forgot how to implement %%load/x\n"); -#endif return true; } @@ -3035,6 +3052,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.126 2005/01/22 00:58:22 steve + * Implement the %load/x instruction. + * * Revision 1.125 2004/12/17 04:47:47 steve * Replace single release with release/net and release/reg. * diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 5b0ffc1c0..035fc77df 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ -#ident "$Id: vvp_net.cc,v 1.6 2005/01/16 04:19:08 steve Exp $" +#ident "$Id: vvp_net.cc,v 1.7 2005/01/22 00:58:22 steve Exp $" # include "vvp_net.h" # include @@ -449,6 +449,16 @@ void vvp_fun_signal::recv_long(vvp_net_ptr_t ptr, long bit) } } +unsigned vvp_fun_signal::size() const +{ + if (force_active_) + return force_.size(); + else if (type_is_vector8_()) + return bits8_.size(); + else + return bits4_.size(); +} + vvp_bit4_t vvp_fun_signal::value(unsigned idx) const { if (force_active_) @@ -725,6 +735,9 @@ vvp_bit4_t compare_gtge(const vvp_vector4_t&lef, const vvp_vector4_t&rig, /* * $Log: vvp_net.cc,v $ + * Revision 1.7 2005/01/22 00:58:22 steve + * Implement the %load/x instruction. + * * Revision 1.6 2005/01/16 04:19:08 steve * Reimplement comparators as vvp_vector4_t nodes. *