From 4b646aca9098222a3d9f6c636bc75b0ad4f757e6 Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Thu, 14 Aug 2008 20:37:04 -0700 Subject: [PATCH] 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. --- vvp/arith.cc | 111 +++------------------------------------------------ 1 file changed, 6 insertions(+), 105 deletions(-) diff --git a/vvp/arith.cc b/vvp/arith.cc index 0afea9c29..698e06b94 100644 --- a/vvp/arith.cc +++ b/vvp/arith.cc @@ -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)