Properly handle signed conversion to real

This commit is contained in:
steve 2007-06-07 03:20:15 +00:00
parent 55f8e5d364
commit 0a38499941
5 changed files with 76 additions and 12 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: eval_real.c,v 1.20 2007/02/26 19:49:50 steve Exp $"
#ident "$Id: eval_real.c,v 1.21 2007/06/07 03:20:15 steve Exp $"
#endif
/*
@ -188,6 +188,7 @@ static int draw_sfunc_real(ivl_expr_t exp)
{
struct vector_info sv;
int res;
const char*sign_flag = "";
switch (ivl_expr_value(exp)) {
@ -209,9 +210,12 @@ static int draw_sfunc_real(ivl_expr_t exp)
sv = draw_eval_expr(exp, 0);
clr_vector(sv);
if (ivl_expr_signed(exp))
sign_flag = "/s";
res = allocate_word();
fprintf(vvp_out, " %%ix/get %d, %u, %u;\n",
res, sv.base, sv.wid);
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n",
sign_flag, res, sv.base, sv.wid);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
break;
@ -232,8 +236,10 @@ static int draw_signal_real_logic(ivl_expr_t exp)
{
int res = allocate_word();
struct vector_info sv = draw_eval_expr(exp, 0);
const char*sign_flag = ivl_expr_signed(exp)? "/s" : "";
fprintf(vvp_out, " %%ix/get %d, %u, %u;\n", res, sv.base, sv.wid);
fprintf(vvp_out, " %%ix/get%s %d, %u, %u; logic signal as real\n",
sign_flag, res, sv.base, sv.wid);
clr_vector(sv);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
@ -394,14 +400,15 @@ int draw_eval_real(ivl_expr_t exp)
default:
if (ivl_expr_value(exp) == IVL_VT_VECTOR) {
struct vector_info sv = draw_eval_expr(exp, 0);
const char*sign_flag = ivl_expr_signed(exp)? "/s" : "";
clr_vector(sv);
res = allocate_word();
fprintf(vvp_out, " %%ix/get %d, %u, %u;\n", res,
sv.base, sv.wid);
fprintf(vvp_out, " %%ix/get%s %d, %u, %u;\n",
sign_flag, res, sv.base, sv.wid);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
fprintf(vvp_out, " %%cvt/ri %d, %d;\n", res, res);
} else {
fprintf(stderr, "XXXX Evaluate real expression (%d)\n",
@ -419,6 +426,9 @@ int draw_eval_real(ivl_expr_t exp)
/*
* $Log: eval_real.c,v $
* Revision 1.21 2007/06/07 03:20:15 steve
* Properly handle signed conversion to real
*
* Revision 1.20 2007/02/26 19:49:50 steve
* Spelling fixes (larry doolittle)
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: codes.h,v 1.83 2007/04/14 04:43:02 steve Exp $"
#ident "$Id: codes.h,v 1.84 2007/06/07 03:20:15 steve Exp $"
#endif
@ -80,6 +80,7 @@ extern bool of_FORK(vthread_t thr, vvp_code_t code);
extern bool of_INV(vthread_t thr, vvp_code_t code);
extern bool of_IX_ADD(vthread_t thr, vvp_code_t code);
extern bool of_IX_GET(vthread_t thr, vvp_code_t code);
extern bool of_IX_GET_S(vthread_t thr, vvp_code_t code);
extern bool of_IX_LOAD(vthread_t thr, vvp_code_t code);
extern bool of_IX_MUL(vthread_t thr, vvp_code_t code);
extern bool of_IX_SUB(vthread_t thr, vvp_code_t code);
@ -186,6 +187,9 @@ extern vvp_code_t codespace_null(void);
/*
* $Log: codes.h,v $
* Revision 1.84 2007/06/07 03:20:15 steve
* Properly handle signed conversion to real
*
* Revision 1.83 2007/04/14 04:43:02 steve
* Finish up part select of array words.
*

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.231 2007/04/14 04:43:02 steve Exp $"
#ident "$Id: compile.cc,v 1.232 2007/06/07 03:20:16 steve Exp $"
#endif
# include "arith.h"
@ -125,6 +125,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%inv", of_INV, 2, {OA_BIT1, OA_BIT2, OA_NONE} },
{ "%ix/add", of_IX_ADD, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/get", of_IX_GET, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%ix/get/s",of_IX_GET_S,3,{OA_BIT1, OA_BIT2, OA_NUMBER} },
{ "%ix/load",of_IX_LOAD,2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/mul", of_IX_MUL, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
{ "%ix/sub", of_IX_SUB, 2, {OA_BIT1, OA_NUMBER, OA_NONE} },
@ -1624,6 +1625,9 @@ void compile_param_string(char*label, char*name, char*value)
/*
* $Log: compile.cc,v $
* Revision 1.232 2007/06/07 03:20:16 steve
* Properly handle signed conversion to real
*
* Revision 1.231 2007/04/14 04:43:02 steve
* Finish up part select of array words.
*

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001-2003 Stephen Williams (steve@icarus.com)
*
* $Id: opcodes.txt,v 1.76 2007/04/14 04:43:02 steve Exp $
* $Id: opcodes.txt,v 1.77 2007/06/07 03:20:16 steve Exp $
*/
@ -306,6 +306,7 @@ bit:
* %ix/get <idx>, <bit>, <wid>
* %ix/get/s <idx>, <bit>, <wid>
This instruction loads a thread vector starting at <bit>, size <wid>,
into the index register <idx>. The <bit> is the lsb of the value in
@ -313,7 +314,9 @@ thread bit space, and <wid> is the width of the vector.
The function converts the 4-value bits into a binary number, without
sign extension. If any of the bits of the vector is x or z, then the
index register gets the value 0.
index register gets the value 0. The %ix/get/s is the same, except
that it assumes the source vector is sign extended to fit the index
register.
The function also writes into bit 4 a 1 if any of the bits of the
input vector are x or z. This is a flag that the 0 value written into

View File

@ -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.163 2007/06/05 21:52:22 steve Exp $"
#ident "$Id: vthread.cc,v 1.164 2007/06/07 03:20:16 steve Exp $"
#endif
# include "config.h"
@ -1828,6 +1828,46 @@ bool of_IX_GET(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_IX_GET_S(vthread_t thr, vvp_code_t cp)
{
unsigned index = cp->bit_idx[0];
unsigned base = cp->bit_idx[1];
unsigned width = cp->number;
unsigned long v = 0;
bool unknown_flag = false;
vvp_bit4_t vv = BIT4_0;
for (unsigned i = 0 ; i<width ; i += 1) {
vv = thr_get_bit(thr, base);
if (bit4_is_xz(vv)) {
v = 0UL;
unknown_flag = true;
break;
}
v |= (unsigned long) vv << i;
if (base >= 4)
base += 1;
}
/* Sign-extend to fill the integer value. */
if (!unknown_flag) {
unsigned long pad = vv;
for (unsigned i = width ; i < 8*sizeof(v) ; i += 1) {
v |= pad << i;
}
}
thr->words[index].w_int = v;
/* Set bit 4 as a flag if the input is unknown. */
thr_put_bit(thr, 4, unknown_flag? BIT4_1 : BIT4_0);
return true;
}
/*
* The various JMP instruction work simply by pulling the new program
@ -3433,6 +3473,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.164 2007/06/07 03:20:16 steve
* Properly handle signed conversion to real
*
* Revision 1.163 2007/06/05 21:52:22 steve
* int vs long expressions on 64bit arch (ldoolitt)
*