From 0a38499941c5b490521a5d3df8922dc7e820be38 Mon Sep 17 00:00:00 2001 From: steve Date: Thu, 7 Jun 2007 03:20:15 +0000 Subject: [PATCH] Properly handle signed conversion to real --- tgt-vvp/eval_real.c | 24 +++++++++++++++++------- vvp/codes.h | 6 +++++- vvp/compile.cc | 6 +++++- vvp/opcodes.txt | 7 +++++-- vvp/vthread.cc | 45 ++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 76 insertions(+), 12 deletions(-) diff --git a/tgt-vvp/eval_real.c b/tgt-vvp/eval_real.c index 7091b9379..eba2cfce7 100644 --- a/tgt-vvp/eval_real.c +++ b/tgt-vvp/eval_real.c @@ -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) * diff --git a/vvp/codes.h b/vvp/codes.h index 5efc7e3fd..7243202dc 100644 --- a/vvp/codes.h +++ b/vvp/codes.h @@ -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. * diff --git a/vvp/compile.cc b/vvp/compile.cc index 997a6aeaf..f87aa32a8 100644 --- a/vvp/compile.cc +++ b/vvp/compile.cc @@ -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. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index dceb7f1d5..b8efff1d6 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.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 , , +* %ix/get/s , , This instruction loads a thread vector starting at , size , into the index register . The is the lsb of the value in @@ -313,7 +314,9 @@ thread bit space, and 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 diff --git a/vvp/vthread.cc b/vvp/vthread.cc index ec4168014..de2355270 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.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= 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) *