Relax limit on behavioral subtraction.
This commit is contained in:
parent
b1c548a981
commit
ab5cad18de
114
vvp/vthread.cc
114
vvp/vthread.cc
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT)
|
#if !defined(WINNT)
|
||||||
#ident "$Id: vthread.cc,v 1.47 2001/06/30 21:07:26 steve Exp $"
|
#ident "$Id: vthread.cc,v 1.48 2001/07/04 04:57:10 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "vthread.h"
|
# include "vthread.h"
|
||||||
|
|
@ -143,6 +143,36 @@ void vthread_put_bit(struct vthread_s*thr, unsigned addr, unsigned bit)
|
||||||
thr_put_bit(thr, addr, bit);
|
thr_put_bit(thr, addr, bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# define CPU_BITS (8*sizeof(unsigned long))
|
||||||
|
# define TOP_BIT (1UL << (CPU_BITS-1))
|
||||||
|
|
||||||
|
static unsigned long* vector_to_array(struct vthread_s*thr,
|
||||||
|
unsigned addr, unsigned wid)
|
||||||
|
{
|
||||||
|
unsigned awid = (wid + CPU_BITS - 1) / (8*sizeof(unsigned long));
|
||||||
|
unsigned long*val = new unsigned long[awid];
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < awid ; idx += 1)
|
||||||
|
val[0] = 0;
|
||||||
|
|
||||||
|
for (unsigned idx = 0 ; idx < wid ; idx += 1) {
|
||||||
|
unsigned bit = thr_get_bit(thr, addr);
|
||||||
|
|
||||||
|
if (bit & 2)
|
||||||
|
goto x_out;
|
||||||
|
|
||||||
|
val[idx/CPU_BITS] |= bit << (idx % CPU_BITS);
|
||||||
|
if (addr >= 4)
|
||||||
|
addr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
|
||||||
|
x_out:
|
||||||
|
delete[]val;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new thread with the given start address.
|
* Create a new thread with the given start address.
|
||||||
|
|
@ -298,44 +328,22 @@ bool of_AND(vthread_t thr, vvp_code_t cp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
# define CPU_BITS (8*sizeof(unsigned long))
|
|
||||||
# define TOP_BIT (1UL << (CPU_BITS-1))
|
|
||||||
|
|
||||||
bool of_ADD(vthread_t thr, vvp_code_t cp)
|
bool of_ADD(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
assert(cp->bit_idx1 >= 4);
|
assert(cp->bit_idx1 >= 4);
|
||||||
|
|
||||||
unsigned idx1 = cp->bit_idx1;
|
unsigned long*lva = vector_to_array(thr, cp->bit_idx1, cp->number);
|
||||||
unsigned idx2 = cp->bit_idx2;
|
unsigned long*lvb = vector_to_array(thr, cp->bit_idx2, cp->number);
|
||||||
|
if (lva == 0 || lvb == 0)
|
||||||
|
goto x_out;
|
||||||
|
|
||||||
unsigned awid = cp->number / (8*sizeof(unsigned long)) + 1;
|
|
||||||
unsigned long*lva = new unsigned long [awid+1];
|
|
||||||
unsigned long*rva = new unsigned long [awid+1];
|
|
||||||
for (unsigned idx = 0 ; idx < awid ; idx += 1) {
|
|
||||||
lva[idx] = 0;
|
|
||||||
rva[idx] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
|
||||||
unsigned lb = thr_get_bit(thr, idx1);
|
|
||||||
unsigned rb = thr_get_bit(thr, idx2);
|
|
||||||
|
|
||||||
if ((lb | rb) & 2)
|
|
||||||
goto x_out;
|
|
||||||
|
|
||||||
lva[idx/CPU_BITS] |= lb << (idx % CPU_BITS);
|
|
||||||
rva[idx/CPU_BITS] |= rb << (idx % CPU_BITS);
|
|
||||||
|
|
||||||
idx1 += 1;
|
|
||||||
if (idx2 >= 4)
|
|
||||||
idx2 += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long carry;
|
unsigned long carry;
|
||||||
carry = 0;
|
carry = 0;
|
||||||
for (unsigned idx = 0 ; idx < awid ; idx += 1) {
|
for (unsigned idx = 0 ; (idx*CPU_BITS) < cp->number ; idx += 1) {
|
||||||
unsigned long tmp = (lva[idx] | rva[idx]) & TOP_BIT;
|
unsigned long tmp = (lva[idx] | lvb[idx]) & TOP_BIT;
|
||||||
lva[idx] += rva[idx] + carry;
|
lva[idx] += lvb[idx] + carry;
|
||||||
carry = (tmp > lva[idx]) ? 1 : 0;
|
carry = (tmp > lva[idx]) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,13 +353,13 @@ bool of_ADD(vthread_t thr, vvp_code_t cp)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[]lva;
|
delete[]lva;
|
||||||
delete[]rva;
|
delete[]lvb;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
x_out:
|
x_out:
|
||||||
delete[]lva;
|
delete[]lva;
|
||||||
delete[]rva;
|
delete[]lvb;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||||
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
||||||
|
|
@ -1127,37 +1135,36 @@ bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp)
|
||||||
bool of_SUB(vthread_t thr, vvp_code_t cp)
|
bool of_SUB(vthread_t thr, vvp_code_t cp)
|
||||||
{
|
{
|
||||||
assert(cp->bit_idx1 >= 4);
|
assert(cp->bit_idx1 >= 4);
|
||||||
assert(cp->number <= 8*sizeof(unsigned long));
|
|
||||||
|
|
||||||
unsigned idx1 = cp->bit_idx1;
|
unsigned long*lva = vector_to_array(thr, cp->bit_idx1, cp->number);
|
||||||
unsigned idx2 = cp->bit_idx2;
|
unsigned long*lvb = vector_to_array(thr, cp->bit_idx2, cp->number);
|
||||||
unsigned long lv = 0, rv = 0;
|
if (lva == 0 || lvb == 0)
|
||||||
|
goto x_out;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
|
||||||
unsigned lb = thr_get_bit(thr, idx1);
|
|
||||||
unsigned rb = thr_get_bit(thr, idx2);
|
|
||||||
|
|
||||||
if ((lb | rb) & 2)
|
unsigned long carry;
|
||||||
goto x_out;
|
carry = 1;
|
||||||
|
for (unsigned idx = 0 ; (idx*CPU_BITS) < cp->number ; idx += 1) {
|
||||||
lv |= lb << idx;
|
unsigned long r_inv = ~lvb[idx];
|
||||||
rv |= rb << idx;
|
unsigned long tmp = (lva[idx] | r_inv) & TOP_BIT;
|
||||||
|
lva[idx] += r_inv + carry;
|
||||||
idx1 += 1;
|
carry = (tmp > lva[idx]) ? 1 : 0;
|
||||||
if (idx2 >= 4)
|
|
||||||
idx2 += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lv -= rv;
|
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
for (unsigned idx = 0 ; idx < cp->number ; idx += 1) {
|
||||||
thr_put_bit(thr, cp->bit_idx1+idx, (lv&1) ? 1 : 0);
|
unsigned bit = lva[idx/CPU_BITS] >> (idx % CPU_BITS);
|
||||||
lv >>= 1;
|
thr_put_bit(thr, cp->bit_idx1+idx, (bit&1) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[]lva;
|
||||||
|
delete[]lvb;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
x_out:
|
x_out:
|
||||||
|
delete[]lva;
|
||||||
|
delete[]lvb;
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
for (unsigned idx = 0 ; idx < cp->number ; idx += 1)
|
||||||
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
thr_put_bit(thr, cp->bit_idx1+idx, 2);
|
||||||
|
|
||||||
|
|
@ -1274,6 +1281,9 @@ bool of_ZOMBIE(vthread_t thr, vvp_code_t)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: vthread.cc,v $
|
* $Log: vthread.cc,v $
|
||||||
|
* Revision 1.48 2001/07/04 04:57:10 steve
|
||||||
|
* Relax limit on behavioral subtraction.
|
||||||
|
*
|
||||||
* Revision 1.47 2001/06/30 21:07:26 steve
|
* Revision 1.47 2001/06/30 21:07:26 steve
|
||||||
* Support non-const right shift (unsigned).
|
* Support non-const right shift (unsigned).
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue