Account for signed multiply

When multiply is done in native words, the conversion to words from the
vp_vector4_t vectors must be done signed. This only matters if the
input operands are different sizes (and themselves signed) but will
not hurt even if we want an  unsigned result.
This commit is contained in:
Stephen Williams 2008-08-14 20:37:04 -07:00
parent 50c1533fdd
commit 4b646aca90
1 changed files with 6 additions and 105 deletions

View File

@ -330,24 +330,24 @@ void vvp_arith_mult::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
{
dispatch_operand_(ptr, bit);
if (wid_ > 8 * sizeof(unsigned long)) {
if (wid_ > 8 * sizeof(long)) {
wide_(ptr);
return ;
}
unsigned long a;
if (! vector4_to_value(op_a_, a)) {
long a;
if (! vector4_to_value(op_a_, a, true, true)) {
vvp_send_vec4(ptr.ptr()->out, x_val_);
return;
}
unsigned long b;
if (! vector4_to_value(op_b_, b)) {
long b;
if (! vector4_to_value(op_b_, b, true, true)) {
vvp_send_vec4(ptr.ptr()->out, x_val_);
return;
}
unsigned long val = a * b;
long val = a * b;
assert(wid_ <= 8*sizeof(val));
vvp_vector4_t vval (wid_);
@ -364,105 +364,6 @@ void vvp_arith_mult::recv_vec4(vvp_net_ptr_t ptr, const vvp_vector4_t&bit)
}
#if 0
void vvp_arith_mult::set(vvp_ipoint_t i, bool push, unsigned val, unsigned)
{
put(i, val);
vvp_ipoint_t base = ipoint_make(i,0);
if(wid_ > 8*sizeof(unsigned long)) {
wide(base, push);
return;
}
unsigned long a = 0, b = 0;
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base,idx);
functor_t obj = functor_index(ptr);
unsigned val = obj->ival;
if (val & 0xaa) {
output_x_(base, push);
return;
}
if (val & 0x01)
a += 1UL << idx;
if (val & 0x04)
b += 1UL << idx;
}
output_val_(base, push, a*b);
}
#endif
#if 0
void vvp_arith_mult::wide(vvp_ipoint_t base, bool push)
{
unsigned char *a, *b, *sum;
a = new unsigned char[wid_];
b = new unsigned char[wid_];
sum = new unsigned char[wid_];
unsigned mxa = 0;
unsigned mxb = 0;
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base, idx);
functor_t obj = functor_index(ptr);
unsigned ival = obj->ival;
if (ival & 0xaa) {
output_x_(base, push);
delete[]sum;
delete[]b;
delete[]a;
return;
}
if((a[idx] = ((ival & 0x01) != 0))) mxa=idx+1;
if((b[idx] = ((ival & 0x04) != 0))) mxb=idx;
sum[idx] = 0;
}
/* do the a*b multiply using the long method we learned in
grade school. We know at this point that there are no X or
Z values in the a or b vectors. */
for(unsigned i=0 ; i<=mxb ; i += 1) {
if(b[i]) {
unsigned char carry=0;
unsigned char temp;
for(unsigned j=0 ; j<=mxa ; j += 1) {
if((i+j) >= wid_)
break;
temp=sum[i+j] + a[j] + carry;
sum[i+j]=(temp&1);
carry=(temp>>1);
}
}
}
for (unsigned idx = 0 ; idx < wid_ ; idx += 1) {
vvp_ipoint_t ptr = ipoint_index(base,idx);
functor_t obj = functor_index(ptr);
unsigned val = sum[idx];
obj->put_oval(val, push);
}
delete[]sum;
delete[]b;
delete[]a;
}
#endif
// Power
vvp_arith_pow::vvp_arith_pow(unsigned wid, bool signed_flag)