Add the %subi instruction, and use it where possible.

This commit is contained in:
steve 2002-08-28 18:38:07 +00:00
parent d5aa700b4b
commit cbca31555d
5 changed files with 109 additions and 5 deletions

View File

@ -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.72 2002/08/28 17:15:35 steve Exp $"
#ident "$Id: eval_expr.c,v 1.73 2002/08/28 18:38:07 steve Exp $"
#endif
# include "vvp_priv.h"
@ -715,6 +715,27 @@ static struct vector_info draw_add_immediate(ivl_expr_t le,
return lv;
}
/*
* The subi is restricted to imm operands that are <= 16 bits wide.
*/
static struct vector_info draw_sub_immediate(ivl_expr_t le,
ivl_expr_t re,
unsigned wid)
{
struct vector_info lv;
unsigned long imm;
lv = draw_eval_expr_wid(le, wid);
assert(lv.wid == wid);
imm = get_number_immediate(re);
assert( (imm & ~0xffff) == 0 );
fprintf(vvp_out, " %%subi %u, %lu, %u;\n", lv.base, imm, wid);
return lv;
}
static struct vector_info draw_mul_immediate(ivl_expr_t le,
ivl_expr_t re,
unsigned wid)
@ -752,6 +773,16 @@ static struct vector_info draw_binary_expr_arith(ivl_expr_t exp, unsigned wid)
&& number_is_immediate(re, 8*sizeof(unsigned long)))
return draw_add_immediate(le, re, wid);
if ((ivl_expr_opcode(exp) == '-')
&& (ivl_expr_type(re) == IVL_EX_ULONG))
return draw_sub_immediate(le, re, wid);
if ((ivl_expr_opcode(exp) == '-')
&& (ivl_expr_type(re) == IVL_EX_NUMBER)
&& (! number_is_unknown(re))
&& number_is_immediate(re, 16))
return draw_sub_immediate(le, re, wid);
if ((ivl_expr_opcode(exp) == '*')
&& (ivl_expr_type(re) == IVL_EX_NUMBER)
&& (! number_is_unknown(re))
@ -1760,6 +1791,9 @@ struct vector_info draw_eval_expr(ivl_expr_t exp)
/*
* $Log: eval_expr.c,v $
* Revision 1.73 2002/08/28 18:38:07 steve
* Add the %subi instruction, and use it where possible.
*
* Revision 1.72 2002/08/28 17:15:35 steve
* Generate %load/nx for indexed load of nets.
*

View File

@ -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.48 2002/08/28 17:15:06 steve Exp $"
#ident "$Id: codes.h,v 1.49 2002/08/28 18:38:07 steve Exp $"
#endif
@ -91,6 +91,7 @@ extern bool of_SET_X(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_SUBI(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);
extern bool of_XNOR(vthread_t thr, vvp_code_t code);
@ -154,6 +155,9 @@ extern vvp_code_t codespace_index(vvp_cpoint_t ptr);
/*
* $Log: codes.h,v $
* Revision 1.49 2002/08/28 18:38:07 steve
* Add the %subi instruction, and use it where possible.
*
* Revision 1.48 2002/08/28 17:15:06 steve
* Add the %load/nx opcode to index vpi nets.
*

View File

@ -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.139 2002/08/28 17:15:06 steve Exp $"
#ident "$Id: compile.cc,v 1.140 2002/08/28 18:38:07 steve Exp $"
#endif
# include "arith.h"
@ -136,6 +136,7 @@ const static struct opcode_table_s opcode_table[] = {
{ "%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} },
{ "%subi", of_SUBI, 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} },
{ "%xnor/r", of_XNORR, 3, {OA_BIT1, OA_BIT2, OA_NUMBER} },
@ -1448,6 +1449,9 @@ void compile_net(char*label, char*name, int msb, int lsb, bool signed_flag,
/*
* $Log: compile.cc,v $
* Revision 1.140 2002/08/28 18:38:07 steve
* Add the %subi instruction, and use it where possible.
*
* Revision 1.139 2002/08/28 17:15:06 steve
* Add the %load/nx opcode to index vpi nets.
*

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
*
* $Id: opcodes.txt,v 1.39 2002/08/28 17:15:06 steve Exp $
* $Id: opcodes.txt,v 1.40 2002/08/28 18:38:07 steve Exp $
*/
@ -461,6 +461,13 @@ operand are x, then the entire result is x.
See also the %add instruction.
* %subi <bit-l>, <imm>, <wid>
This instruction arithmetically subtracts the immediate value from the
left vector. The <imm> value is a 16bit unsigned value zer-extended to
the <wid> of the left vector. The result replaces the left vector.
See also the %addi instruction.
* %vpi_call <name> [, ...]

View File

@ -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.83 2002/08/28 17:15:06 steve Exp $"
#ident "$Id: vthread.cc,v 1.84 2002/08/28 18:38:07 steve Exp $"
#endif
# include "vthread.h"
@ -2128,6 +2128,58 @@ bool of_SUB(vthread_t thr, vvp_code_t cp)
return true;
}
bool of_SUBI(vthread_t thr, vvp_code_t cp)
{
assert(cp->bit_idx[0] >= 4);
unsigned word_count = (cp->number+CPU_WORD_BITS-1)/CPU_WORD_BITS;
unsigned long*lva = vector_to_array(thr, cp->bit_idx[0], cp->number);
unsigned long*lvb;
if (lva == 0)
goto x_out;
lvb = new unsigned long[word_count];
lvb[0] = ~ cp->bit_idx[1];
for (unsigned idx = 1 ; idx < word_count ; idx += 1)
lvb[idx] = ~0;
unsigned long carry;
carry = 1;
for (unsigned idx = 0 ; (idx*CPU_WORD_BITS) < cp->number ; idx += 1) {
unsigned long tmp = lvb[idx] + carry;
unsigned long sum = lva[idx] + tmp;
carry = 0;
if (tmp < lvb[idx])
carry = 1;
if (sum < tmp)
carry = 1;
if (sum < lva[idx])
carry = 1;
lva[idx] = sum;
}
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
unsigned bit = lva[idx/CPU_WORD_BITS] >> (idx % CPU_WORD_BITS);
thr_put_bit(thr, cp->bit_idx[0]+idx, (bit&1) ? 1 : 0);
}
delete[]lva;
delete[]lvb;
return true;
x_out:
delete[]lva;
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
thr_put_bit(thr, cp->bit_idx[0]+idx, 2);
return true;
}
bool of_VPI_CALL(vthread_t thr, vvp_code_t cp)
{
// printf("thread %p: %%vpi_call\n", thr);
@ -2267,6 +2319,9 @@ bool of_CALL_UFUNC(vthread_t thr, vvp_code_t cp)
/*
* $Log: vthread.cc,v $
* Revision 1.84 2002/08/28 18:38:07 steve
* Add the %subi instruction, and use it where possible.
*
* Revision 1.83 2002/08/28 17:15:06 steve
* Add the %load/nx opcode to index vpi nets.
*