diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 99ac90a6c..4ef669267 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -3828,14 +3828,12 @@ bool of_PAD_S(vthread_t thr, vvp_code_t cp) vvp_vector4_t&val = thr->peek_vec4(); unsigned old_size = val.size(); - val.resize(wid); // Sign-extend. - if (old_size < wid) { - vvp_bit4_t sb = val.value(old_size-1); - for (unsigned idx = old_size ; idx < wid ; idx += 1) - val.set_bit(idx, sb); - } + if (old_size < wid) + val.resize(wid, val.value(old_size-1)); + else + val.resize(wid); return true; } @@ -3848,14 +3846,7 @@ bool of_PAD_U(vthread_t thr, vvp_code_t cp) unsigned wid = cp->number; vvp_vector4_t&val = thr->peek_vec4(); - unsigned old_size = val.size(); - val.resize(wid); - - if (old_size < wid) { - vvp_bit4_t pad = BIT4_0; - for (unsigned idx = old_size ; idx < wid ; idx += 1) - val.set_bit(idx,pad); - } + val.resize(wid, BIT4_0); return true; } diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 73a4530ea..ac870c817 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -905,18 +905,46 @@ vvp_vector4_t::vvp_vector4_t(const vvp_vector4_t&that, * Change the size of the vvp_vector4_t vector to the new size. Copy * the old values, as many as well fit, into the new vector. */ -void vvp_vector4_t::resize(unsigned newsize) +void vvp_vector4_t::resize(unsigned newsize, vvp_bit4_t pad_bit) { if (size_ == newsize) return; unsigned cnt = (size_ + BITS_PER_WORD - 1) / BITS_PER_WORD; + unsigned long word_pad_abits = 0; + unsigned long word_pad_bbits = 0; + switch (pad_bit) { + case BIT4_0: + word_pad_abits = WORD_0_ABITS; + word_pad_bbits = WORD_0_BBITS; + break; + case BIT4_1: + word_pad_abits = WORD_1_ABITS; + word_pad_bbits = WORD_1_BBITS; + break; + case BIT4_X: + word_pad_abits = WORD_X_ABITS; + word_pad_bbits = WORD_X_BBITS; + break; + case BIT4_Z: + word_pad_abits = WORD_Z_ABITS; + word_pad_bbits = WORD_Z_BBITS; + break; + } if (newsize > BITS_PER_WORD) { unsigned newcnt = (newsize + BITS_PER_WORD - 1) / BITS_PER_WORD; if (newcnt == cnt) { // If the word count doesn't change, then there is // no need for re-allocation so we are done now. + if (newsize > size_) { + if (unsigned fill = size_ % BITS_PER_WORD) { + abits_ptr_[cnt-1] &= ~((-1L) << fill); + bbits_ptr_[cnt-1] &= ~((-1L) << fill); + abits_ptr_[cnt-1] |= word_pad_abits << fill; + bbits_ptr_[cnt-1] |= word_pad_bbits << fill; + } + } size_ = newsize; return; } @@ -940,10 +968,18 @@ void vvp_vector4_t::resize(unsigned newsize) newbits[newcnt] = bbits_val_; } - for (unsigned idx = cnt ; idx < newcnt ; idx += 1) - newbits[idx] = WORD_X_ABITS; - for (unsigned idx = cnt ; idx < newcnt ; idx += 1) - newbits[newcnt+idx] = WORD_X_BBITS; + if (newsize > size_) { + if (unsigned fill = size_ % BITS_PER_WORD) { + newbits[cnt-1] &= ~((-1L) << fill); + newbits[cnt-1] |= word_pad_abits << fill; + newbits[newcnt+cnt-1] &= ~((-1L) << fill); + newbits[newcnt+cnt-1] |= word_pad_bbits << fill; + } + for (unsigned idx = cnt ; idx < newcnt ; idx += 1) + newbits[idx] = word_pad_abits; + for (unsigned idx = cnt ; idx < newcnt ; idx += 1) + newbits[newcnt+idx] = word_pad_bbits; + } size_ = newsize; abits_ptr_ = newbits; @@ -958,6 +994,13 @@ void vvp_vector4_t::resize(unsigned newsize) bbits_val_ = newvalb; } + if (newsize > size_) { + abits_val_ &= ~((-1L) << size_); + bbits_val_ &= ~((-1L) << size_); + abits_val_ |= word_pad_abits << size_; + bbits_val_ |= word_pad_bbits << size_; + } + size_ = newsize; } } diff --git a/vvp/vvp_net.h b/vvp/vvp_net.h index b204dcd40..d148976dc 100644 --- a/vvp/vvp_net.h +++ b/vvp/vvp_net.h @@ -245,7 +245,7 @@ class vvp_vector4_t { ~vvp_vector4_t(); inline unsigned size() const { return size_; } - void resize(unsigned new_size); + void resize(unsigned new_size, vvp_bit4_t pad_bit = BIT4_X); // Get the bit at the specified address vvp_bit4_t value(unsigned idx) const;