diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index 4131d50e1..708104db1 100644 --- a/tgt-vvp/eval_expr.c +++ b/tgt-vvp/eval_expr.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CVS_IDENT -#ident "$Id: eval_expr.c,v 1.136 2007/03/22 16:08:18 steve Exp $" +#ident "$Id: eval_expr.c,v 1.137 2007/04/14 04:43:01 steve Exp $" #endif # include "vvp_priv.h" @@ -1639,6 +1639,35 @@ static struct vector_info draw_signal_expr(ivl_expr_t exp, unsigned wid, return res; } +static struct vector_info draw_select_array(ivl_expr_t sube, + ivl_expr_t bit_idx, + unsigned bit_width, + unsigned wid) +{ + unsigned idx; + ivl_signal_t sig = ivl_expr_signal(sube); + unsigned sig_wid = ivl_expr_width(sube); + ivl_expr_t ix = ivl_expr_oper1(sube); + + struct vector_info shiv; + struct vector_info res; + + shiv = draw_eval_expr(bit_idx, STUFF_OK_XZ|STUFF_OK_RO); + draw_eval_expr_into_integer(ix, 3); + fprintf(vvp_out, " %%ix/get 0, %u, %u;\n", shiv.base, shiv.wid); + if (shiv.base >= 8) + clr_vector(shiv); + + res.base = allocate_vector(wid); + res.wid = wid; + + for (idx = 0 ; idx < wid ; idx += 1) { + fprintf(vvp_out, " %%load/avx.p %u, v%p, 0;\n", res.base+idx, sig); + } + + return res; +} + static struct vector_info draw_select_signal(ivl_expr_t sube, ivl_expr_t bit_idx, unsigned bit_wid, @@ -1651,16 +1680,17 @@ static struct vector_info draw_select_signal(ivl_expr_t sube, /* Use this word of the signal. */ unsigned use_word = 0; - /* If this is an access to an array, handle that by emiting a - load/av instruction. */ + + /* If this is an access to an array, try to get the index as a + constant. If it is, then this reduces to a signal access + and we stay here. If it is not constant, then give up and + do an array index in front of this part select. */ + if (ivl_signal_array_count(sig) > 1) { ivl_expr_t ix = ivl_expr_oper1(sube); - if (!number_is_immediate(ix, 8*sizeof(unsigned long))) { - draw_eval_expr_into_integer(ix, 3); - assert(0); /* XXXX Don't know how to load part - select! */ - return res; - } + + if (!number_is_immediate(ix, 8*sizeof(unsigned long))) + return draw_select_array(sube, bit_idx, bit_wid, wid); /* The index is constant, so we can return to direct readout with the specific word selected. */ @@ -2201,6 +2231,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag) /* * $Log: eval_expr.c,v $ + * Revision 1.137 2007/04/14 04:43:01 steve + * Finish up part select of array words. + * * Revision 1.136 2007/03/22 16:08:18 steve * Spelling fixes from Larry * diff --git a/vvp/codes.h b/vvp/codes.h index cee56afb0..5efc7e3fd 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.82 2007/02/14 05:58:14 steve Exp $" +#ident "$Id: codes.h,v 1.83 2007/04/14 04:43:02 steve Exp $" #endif @@ -89,6 +89,7 @@ extern bool of_JMP0XZ(vthread_t thr, vvp_code_t code); extern bool of_JMP1(vthread_t thr, vvp_code_t code); extern bool of_JOIN(vthread_t thr, vvp_code_t code); extern bool of_LOAD_AV(vthread_t thr, vvp_code_t code); +extern bool of_LOAD_AVX_P(vthread_t thr, vvp_code_t code); extern bool of_LOAD_MV(vthread_t thr, vvp_code_t code); extern bool of_LOAD_NX(vthread_t thr, vvp_code_t code); extern bool of_LOAD_VEC(vthread_t thr, vvp_code_t code); @@ -185,6 +186,9 @@ extern vvp_code_t codespace_null(void); /* * $Log: codes.h,v $ + * Revision 1.83 2007/04/14 04:43:02 steve + * Finish up part select of array words. + * * Revision 1.82 2007/02/14 05:58:14 steve * Add the mov/wr opcode. * diff --git a/vvp/compile.cc b/vvp/compile.cc index 62ee9933e..997a6aeaf 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.230 2007/03/02 06:13:22 steve Exp $" +#ident "$Id: compile.cc,v 1.231 2007/04/14 04:43:02 steve Exp $" #endif # include "arith.h" @@ -134,6 +134,7 @@ const static struct opcode_table_s opcode_table[] = { { "%jmp/1", of_JMP1, 2, {OA_CODE_PTR, OA_BIT1, OA_NONE} }, { "%join", of_JOIN, 0, {OA_NONE, OA_NONE, OA_NONE} }, { "%load/av",of_LOAD_AV,3, {OA_BIT1, OA_ARR_PTR, OA_BIT2} }, + { "%load/avx.p",of_LOAD_AVX_P,3,{OA_BIT1, OA_ARR_PTR, OA_BIT2} }, { "%load/mv",of_LOAD_MV,3, {OA_BIT1, OA_MEM_PTR, OA_BIT2} }, { "%load/nx",of_LOAD_NX,3, {OA_BIT1, OA_VPI_PTR, OA_BIT2} }, { "%load/v", of_LOAD_VEC,3, {OA_BIT1, OA_FUNC_PTR, OA_BIT2} }, @@ -1623,6 +1624,9 @@ void compile_param_string(char*label, char*name, char*value) /* * $Log: compile.cc,v $ + * Revision 1.231 2007/04/14 04:43:02 steve + * Finish up part select of array words. + * * Revision 1.230 2007/03/02 06:13:22 steve * Add support for edge sensitive spec paths. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index c31edf652..dceb7f1d5 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.75 2007/03/22 16:08:19 steve Exp $ + * $Id: opcodes.txt,v 1.76 2007/04/14 04:43:02 steve Exp $ */ @@ -380,6 +380,12 @@ This instruction loads a word from the specified array. The word address is in index register 3. The width should match the width of the array word. +* %load/avx.p , , + +This instruction is similar ro %load/av, but it loads only a single +bit, and the is the selector for the bit to use. If is +out of range, then x is loaded. + * %load/mv , , this instruction loads a word from the specified memory. The word diff --git a/vvp/vthread.cc b/vvp/vthread.cc index a717f32fb..cb2765639 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.161 2007/02/14 05:58:14 steve Exp $" +#ident "$Id: vthread.cc,v 1.162 2007/04/14 04:43:02 steve Exp $" #endif # include "config.h" @@ -1958,6 +1958,36 @@ bool of_LOAD_AV(vthread_t thr, vvp_code_t cp) return true; } +/* + * %load/avx.p , , ; + * + * is the thread bit address for the result + * is the array to access, and + * is the width of the word to read. + * + * The address of the word in the array is in index register 3. + */ +bool of_LOAD_AVX_P(vthread_t thr, vvp_code_t cp) +{ + unsigned bit = cp->bit_idx[0]; + unsigned index = cp->bit_idx[1]; + unsigned adr = thr->words[3].w_int; + + unsigned use_index = thr->words[index].w_int; + + vvp_vector4_t word = array_get_word(cp->array, adr); + + if (use_index >= word.size()) { + thr_put_bit(thr, bit, BIT4_X); + } else { + thr_put_bit(thr, bit, word.value(use_index)); + } + + thr->words[index].w_int = use_index + 1; + + return true; +} + /* * %load/mv , , ; * @@ -3403,6 +3433,9 @@ bool of_JOIN_UFUNC(vthread_t thr, vvp_code_t cp) /* * $Log: vthread.cc,v $ + * Revision 1.162 2007/04/14 04:43:02 steve + * Finish up part select of array words. + * * Revision 1.161 2007/02/14 05:58:14 steve * Add the mov/wr opcode. *