Support non-const right shift (unsigned).

This commit is contained in:
steve 2001-06-30 21:07:26 +00:00
parent d680e594ed
commit baac893d22
6 changed files with 80 additions and 86 deletions

View File

@ -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)
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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 <bit> is the address of
the lsb of the vector, and <wid> the width of the vector. The shift is
done in place. Zero values are shifted in.
* %shiftr/i0 <bit>, <wid>
This instruction shifts the vector right (towards the less significant
bits) by the amount in the index register 0. The <bit> is the address
of the lsb of the vector, and <wid> 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 <bit-l>, <bit-r>, <wid>
This instruction arithmetically subtracts the right vector out of the

View File

@ -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.
*