diff --git a/t-dll.h b/t-dll.h index 6dbfe7811..9584c13ca 100644 --- a/t-dll.h +++ b/t-dll.h @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: t-dll.h,v 1.50 2001/06/19 03:01:10 steve Exp $" +#ident "$Id: t-dll.h,v 1.51 2001/06/30 21:07:26 steve Exp $" #endif # include "target.h" @@ -434,8 +434,8 @@ struct ivl_scope_s { }; /* - * A signal is a think like a wire, a reg, or whatever. It has a type, - * and if it is a port is also has a directory. Signals are collected + * A signal is a thing like a wire, a reg, or whatever. It has a type, + * and if it is a port is also has a direction. Signals are collected * into scopes (which also point back to me) and have pins that * connect to the rest of the netlist. */ @@ -539,6 +539,9 @@ struct ivl_statement_s { /* * $Log: t-dll.h,v $ + * Revision 1.51 2001/06/30 21:07:26 steve + * Support non-const right shift (unsigned). + * * Revision 1.50 2001/06/19 03:01:10 steve * Add structural EEQ gates (Stephan Boettcher) * diff --git a/tgt-vvp/eval_expr.c b/tgt-vvp/eval_expr.c index e3d494d0c..1ca140b8a 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 */ #if !defined(WINNT) -#ident "$Id: eval_expr.c,v 1.33 2001/06/23 18:40:34 steve Exp $" +#ident "$Id: eval_expr.c,v 1.34 2001/06/30 21:07:26 steve Exp $" #endif # include "vvp_priv.h" @@ -383,9 +383,12 @@ static struct vector_info draw_binary_expr_logic(ivl_expr_t exp, /* * Draw code to evaluate the << expression. Use the %shiftl/i0 - * instruction to do the real work of shifting. + * or %shiftr/i0 instruction to do the real work of shifting. This + * means that I can handle both left and right shifts in this + * function, with the only difference the opcode I generate at the + * end. */ -static struct vector_info draw_binary_expr_ls(ivl_expr_t exp, unsigned wid) +static struct vector_info draw_binary_expr_lrs(ivl_expr_t exp, unsigned wid) { ivl_expr_t le = ivl_expr_oper1(exp); ivl_expr_t re = ivl_expr_oper2(exp); @@ -434,80 +437,23 @@ static struct vector_info draw_binary_expr_ls(ivl_expr_t exp, unsigned wid) lv = draw_eval_expr_wid(le, wid); - fprintf(vvp_out, " %%shiftl/i0 %u, %u;\n", lv.base, lv.wid); + switch (ivl_expr_opcode(exp)) { + + case 'l': /* << (left shift) */ + fprintf(vvp_out, " %%shiftl/i0 %u, %u;\n", lv.base, lv.wid); + break; + + case 'r': /* >> (unsigned right shift) */ + fprintf(vvp_out, " %%shiftr/i0 %u, %u;\n", lv.base, lv.wid); + break; + + default: + assert(0); + } + return lv; } -static struct vector_info draw_binary_expr_rs(ivl_expr_t exp, unsigned wid) -{ - ivl_expr_t le = ivl_expr_oper1(exp); - ivl_expr_t re = ivl_expr_oper2(exp); - - unsigned shift = 0; - - struct vector_info lv; - struct vector_info rs; - - /* XXXX support only constant right expressions. */ - switch (ivl_expr_type(re)) { - case IVL_EX_NUMBER: { - unsigned idx, nbits = ivl_expr_width(re); - const char*bits = ivl_expr_bits(re); - - for (idx = 0 ; idx < nbits ; idx += 1) switch (bits[idx]) { - - case '0': - break; - case '1': - assert(idx < (8*sizeof shift)); - shift |= 1 << idx; - break; - default: - assert(0); - } - break; - } - - case IVL_EX_ULONG: - shift = ivl_expr_uvalue(re); - break; - default: - assert(0); - break; - } - - if (shift >= wid) { - rs.base = 0; - rs.wid = wid; - return rs; - } - - lv = draw_eval_expr_wid(le, wid); - - - switch (lv.base) { - case 0: - return lv; - case 1: - case 2: - case 3: - rs.base = allocate_vector(wid); - rs.wid = wid; - fprintf(vvp_out, " %%mov %u, %u, %u;\n", rs.base, - lv.base, wid-shift); - fprintf(vvp_out, " %%mov %u, 0, %u;\n", - rs.base+wid-shift, shift); - return rs; - - default: - assert(lv.wid == wid); - fprintf(vvp_out, " %%mov %u, %u, %u;\n", lv.base, - lv.base+shift, wid-shift); - fprintf(vvp_out, " %%mov %u, 0, %u;\n", - lv.base+wid-shift, shift); - return lv; - } -} static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid) { @@ -581,17 +527,14 @@ static struct vector_info draw_binary_expr(ivl_expr_t exp, unsigned wid) break; case 'l': /* << */ - rv = draw_binary_expr_ls(exp, wid); + case 'r': /* >> */ + rv = draw_binary_expr_lrs(exp, wid); break; case 'o': /* || (logical or) */ rv = draw_binary_expr_lor(exp, wid); break; - case 'r': /* >> */ - rv = draw_binary_expr_rs(exp, wid); - break; - case '&': case '|': case '^': @@ -1066,6 +1009,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp) /* * $Log: eval_expr.c,v $ + * Revision 1.34 2001/06/30 21:07:26 steve + * Support non-const right shift (unsigned). + * * Revision 1.33 2001/06/23 18:40:34 steve * Generate %shiftl instructions for shift. * diff --git a/vvp/codes.h b/vvp/codes.h index 96b1a1739..b9bb701b0 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 */ #if !defined(WINNT) -#ident "$Id: codes.h,v 1.30 2001/06/23 18:26:26 steve Exp $" +#ident "$Id: codes.h,v 1.31 2001/06/30 21:07:26 steve Exp $" #endif @@ -73,6 +73,7 @@ extern bool of_ORR(vthread_t thr, vvp_code_t code); extern bool of_SET(vthread_t thr, vvp_code_t code); extern bool of_SET_MEM(vthread_t thr, vvp_code_t code); extern bool of_SHIFTL_I0(vthread_t thr, vvp_code_t code); +extern bool of_SHIFTR_I0(vthread_t thr, vvp_code_t code); extern bool of_SUB(vthread_t thr, vvp_code_t code); extern bool of_VPI_CALL(vthread_t thr, vvp_code_t code); extern bool of_WAIT(vthread_t thr, vvp_code_t code); @@ -135,6 +136,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr); /* * $Log: codes.h,v $ + * Revision 1.31 2001/06/30 21:07:26 steve + * Support non-const right shift (unsigned). + * * Revision 1.30 2001/06/23 18:26:26 steve * Add the %shiftl/i0 instruction. * diff --git a/vvp/compile.cc b/vvp/compile.cc index df6c75908..347503048 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 */ #if !defined(WINNT) -#ident "$Id: compile.cc,v 1.81 2001/06/23 18:26:26 steve Exp $" +#ident "$Id: compile.cc,v 1.82 2001/06/30 21:07:26 steve Exp $" #endif # include "arith.h" @@ -112,6 +112,7 @@ const static struct opcode_table_s opcode_table[] = { { "%set", of_SET, 2, {OA_FUNC_PTR, OA_BIT1, OA_NONE} }, { "%set/m", of_SET_MEM,2, {OA_MEM_PTR, OA_BIT1, OA_NONE} }, { "%shiftl/i0", of_SHIFTL_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} }, + { "%shiftr/i0", of_SHIFTR_I0, 2, {OA_BIT1,OA_NUMBER, OA_NONE} }, { "%sub", of_SUB, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, { "%wait", of_WAIT, 1, {OA_FUNC_PTR, OA_NONE, OA_NONE} }, { "%xnor", of_XNOR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} }, @@ -1449,6 +1450,9 @@ vvp_ipoint_t debug_lookup_functor(const char*name) /* * $Log: compile.cc,v $ + * Revision 1.82 2001/06/30 21:07:26 steve + * Support non-const right shift (unsigned). + * * Revision 1.81 2001/06/23 18:26:26 steve * Add the %shiftl/i0 instruction. * diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 8f9ffa2f6..720e1497a 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -1,7 +1,7 @@ /* * Copyright (c) 2001 Stephen Williams (steve@icarus.com) * - * $Id: opcodes.txt,v 1.24 2001/06/23 18:26:26 steve Exp $ + * $Id: opcodes.txt,v 1.25 2001/06/30 21:07:26 steve Exp $ */ @@ -300,6 +300,15 @@ bits) by the amount in index register 0. The is the address of the lsb of the vector, and the width of the vector. The shift is done in place. Zero values are shifted in. +* %shiftr/i0 , + +This instruction shifts the vector right (towards the less significant +bits) by the amount in the index register 0. The is the address +of the lsb of the vector, and is the width of the vector. The +shift is done in place. + +This is an unsigned down shift, so zeros are shifted into the top bits. + * %sub , , This instruction arithmetically subtracts the right vector out of the diff --git a/vvp/vthread.cc b/vvp/vthread.cc index fb4084c73..b16e230ad 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 */ #if !defined(WINNT) -#ident "$Id: vthread.cc,v 1.46 2001/06/23 18:26:26 steve Exp $" +#ident "$Id: vthread.cc,v 1.47 2001/06/30 21:07:26 steve Exp $" #endif # include "vthread.h" @@ -1099,6 +1099,31 @@ bool of_SHIFTL_I0(vthread_t thr, vvp_code_t cp) return true; } +/* + * This is an unsigned right shift. + */ +bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp) +{ + unsigned base = cp->bit_idx1; + unsigned wid = cp->number; + long shift = thr->index[0]; + + if (shift >= wid) { + for (unsigned idx = 0 ; idx < wid ; idx += 1) + thr_put_bit(thr, base+idx, 0); + + } else if (shift > 0) { + for (unsigned idx = 0 ; idx < (wid-shift) ; idx += 1) { + unsigned src = base + idx + shift; + unsigned dst = base + idx; + thr_put_bit(thr, dst, thr_get_bit(thr, src)); + } + for (unsigned idx = (wid-shift) ; idx < wid ; idx += 1) + thr_put_bit(thr, base+idx, 0); + } + return true; +} + bool of_SUB(vthread_t thr, vvp_code_t cp) { assert(cp->bit_idx1 >= 4); @@ -1249,6 +1274,9 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t) /* * $Log: vthread.cc,v $ + * Revision 1.47 2001/06/30 21:07:26 steve + * Support non-const right shift (unsigned). + * * Revision 1.46 2001/06/23 18:26:26 steve * Add the %shiftl/i0 instruction. *