Add the %subi instruction, and use it where possible.
This commit is contained in:
parent
d5aa700b4b
commit
cbca31555d
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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> [, ...]
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue