Add signed LPM divide.

This commit is contained in:
steve 2004-06-30 02:15:57 +00:00
parent 9ee0210cac
commit 57b8ca191f
6 changed files with 64 additions and 15 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: arith.cc,v 1.27 2004/06/16 16:33:26 steve Exp $"
#ident "$Id: arith.cc,v 1.28 2004/06/30 02:15:57 steve Exp $"
#endif
# include "arith.h"
@ -103,7 +103,7 @@ void vvp_arith_div::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
}
unsigned long a = 0, b = 0;
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base,idx);
functor_t obj = functor_index(ptr);
@ -120,12 +120,32 @@ void vvp_arith_div::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
b += 1UL << idx;
}
unsigned sign_flip = 0;
if (signed_flag_) {
if (a & (1UL << (wid_ - 1))) {
a ^= ~(-1UL << wid_);
a += 1;
sign_flip += 1;
}
if (b & (1UL << (wid_ - 1))) {
b ^= ~(-1UL << wid_);
b += 1;
sign_flip += 1;
}
}
if (b == 0) {
output_x_(base, push);
return;
}
output_val_(base, push, a/b);
unsigned long result = a / b;
if (sign_flip % 2 == 1)
result = 0 - result;
output_val_(base, push, result);
}
inline void vvp_arith_mod::wide(vvp_ipoint_t base, bool push)
@ -680,6 +700,9 @@ void vvp_shiftr::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
/*
* $Log: arith.cc,v $
* Revision 1.28 2004/06/30 02:15:57 steve
* Add signed LPM divide.
*
* Revision 1.27 2004/06/16 16:33:26 steve
* Add structural equality compare nodes.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: arith.h,v 1.16 2004/06/16 16:33:26 steve Exp $"
#ident "$Id: arith.h,v 1.17 2004/06/30 02:15:57 steve Exp $"
#endif
# include "functor.h"
@ -70,10 +70,14 @@ class vvp_arith_mult : public vvp_arith_ {
class vvp_arith_div : public vvp_arith_ {
public:
explicit vvp_arith_div(unsigned wid) : vvp_arith_(wid) {}
explicit vvp_arith_div(unsigned wid, bool signed_flag)
: vvp_arith_(wid), signed_flag_(signed_flag) {}
void set(vvp_ipoint_t i, bool push, unsigned val, unsigned str);
void wide(vvp_ipoint_t base, bool push);
private:
bool signed_flag_;
};
class vvp_arith_mod : public vvp_arith_ {
@ -155,6 +159,9 @@ class vvp_shiftr : public vvp_arith_ {
/*
* $Log: arith.h,v $
* Revision 1.17 2004/06/30 02:15:57 steve
* Add signed LPM divide.
*
* Revision 1.16 2004/06/16 16:33:26 steve
* Add structural equality compare nodes.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.cc,v 1.173 2004/06/19 15:52:53 steve Exp $"
#ident "$Id: compile.cc,v 1.174 2004/06/30 02:15:57 steve Exp $"
#endif
# include "arith.h"
@ -830,7 +830,7 @@ static void make_arith(vvp_arith_ *arith,
free(argv);
}
void compile_arith_div(char*label, long wid,
void compile_arith_div(char*label, long wid, bool signed_flag,
unsigned argc, struct symb_s*argv)
{
assert( wid > 0 );
@ -841,7 +841,7 @@ void compile_arith_div(char*label, long wid,
return;
}
vvp_arith_ *arith = new vvp_arith_div(wid);
vvp_arith_ *arith = new vvp_arith_div(wid, signed_flag);
make_arith(arith, label, wid, argc, argv);
}
@ -1579,6 +1579,9 @@ void compile_param_string(char*label, char*name, char*str, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.174 2004/06/30 02:15:57 steve
* Add signed LPM divide.
*
* Revision 1.173 2004/06/19 15:52:53 steve
* Add signed modulus operator.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: compile.h,v 1.54 2004/06/16 16:33:26 steve Exp $"
#ident "$Id: compile.h,v 1.55 2004/06/30 02:15:57 steve Exp $"
#endif
# include <stdio.h>
@ -97,7 +97,7 @@ extern void compile_force(char*label, struct symb_s signal,
* This is called by the parser to make the various arithmetic and
* comparison functors.
*/
extern void compile_arith_div(char*label, long width,
extern void compile_arith_div(char*label, long width, bool signed_flag,
unsigned argc, struct symb_s*argv);
extern void compile_arith_mod(char*label, long width,
unsigned argc, struct symb_s*argv);
@ -268,6 +268,9 @@ extern void compile_net(char*label, char*name,
/*
* $Log: compile.h,v $
* Revision 1.55 2004/06/30 02:15:57 steve
* Add signed LPM divide.
*
* Revision 1.54 2004/06/16 16:33:26 steve
* Add structural equality compare nodes.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: lexor.lex,v 1.42 2004/06/16 16:33:26 steve Exp $"
#ident "$Id: lexor.lex,v 1.43 2004/06/30 02:15:57 steve Exp $"
#endif
# include "parse_misc.h"
@ -83,7 +83,8 @@
/* These are some keywords that are recognized. */
".arith/div" { return K_ARITH_DIV; }
".arith/div" { return K_ARITH_DIV; }
".arith/div.s" { return K_ARITH_DIV_S; }
".arith/mod" { return K_ARITH_MOD; }
".arith/mult" { return K_ARITH_MULT; }
".arith/sub" { return K_ARITH_SUB; }
@ -181,6 +182,9 @@ int yywrap()
/*
* $Log: lexor.lex,v $
* Revision 1.43 2004/06/30 02:15:57 steve
* Add signed LPM divide.
*
* Revision 1.42 2004/06/16 16:33:26 steve
* Add structural equality compare nodes.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: parse.y,v 1.57 2004/06/16 16:33:26 steve Exp $"
#ident "$Id: parse.y,v 1.58 2004/06/30 02:15:57 steve Exp $"
#endif
# include "parse_misc.h"
@ -57,7 +57,8 @@ extern FILE*yyin;
};
%token K_ARITH_DIV K_ARITH_MOD K_ARITH_MULT K_ARITH_SUB K_ARITH_SUM
%token K_ARITH_DIV K_ARITH_DIV_S K_ARITH_MOD K_ARITH_MULT
%token K_ARITH_SUB K_ARITH_SUM
%token K_CMP_EQ K_CMP_NE K_CMP_GE K_CMP_GE_S K_CMP_GT K_CMP_GT_S
%token K_EVENT K_EVENT_OR K_FUNCTOR K_NET K_NET_S K_PARAM
%token K_RESOLV K_SCOPE K_SHIFTL K_SHIFTR K_THREAD K_TIMESCALE K_UFUNC
@ -193,7 +194,12 @@ statement
| T_LABEL K_ARITH_DIV T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_div($1, $3, obj.cnt, obj.vect);
compile_arith_div($1, $3, false, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_DIV_S T_NUMBER ',' symbols ';'
{ struct symbv_s obj = $5;
compile_arith_div($1, $3, true, obj.cnt, obj.vect);
}
| T_LABEL K_ARITH_MOD T_NUMBER ',' symbols ';'
@ -627,6 +633,9 @@ int compile_design(const char*path)
/*
* $Log: parse.y,v $
* Revision 1.58 2004/06/30 02:15:57 steve
* Add signed LPM divide.
*
* Revision 1.57 2004/06/16 16:33:26 steve
* Add structural equality compare nodes.
*