Support non-const right shift (unsigned).
This commit is contained in:
parent
d680e594ed
commit
baac893d22
9
t-dll.h
9
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)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue