From 19e8c057883c4e6f488983e9ad675e44ed1ea25e Mon Sep 17 00:00:00 2001 From: Stephen Williams Date: Tue, 4 Dec 2007 22:16:31 -0800 Subject: [PATCH] Optimize X check in vector subarray Optimize check for X bits while doing vector4 subarray. In particular, do X checks a word at a time so that individual bits need not be tested. --- vvp/vvp_net.cc | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/vvp/vvp_net.cc b/vvp/vvp_net.cc index 6be770b1b..cc66e6425 100644 --- a/vvp/vvp_net.cc +++ b/vvp/vvp_net.cc @@ -353,22 +353,42 @@ unsigned long* vvp_vector4_t::subarray(unsigned adr, unsigned wid) const /* Get the first word we are scanning. We may in fact be somewhere in the middle of that word. */ unsigned long tmp = bits_ptr_[adr/BITS_PER_WORD]; - tmp >>= 2UL * (adr%BITS_PER_WORD); + unsigned long off = adr%BITS_PER_WORD; + tmp >>= 2UL * off; + // Test for X bits but not beyond the desired wid. + unsigned long xmask = WORD_X_BITS; + if (wid < (BITS_PER_WORD-off)) + xmask &= ~(-1UL << 2*wid); + if (tmp & xmask) + goto x_out; + + // Where in the target array to write the next bit. unsigned long mask1 = 1; const unsigned long mask1_last = 1UL << (BIT2_PER_WORD-1); unsigned long*val_ptr = val; + // Track where the source bit is in the source word. + unsigned adr_bit = adr%BITS_PER_WORD; + // Scan... for (unsigned idx = 0 ; idx < wid ; idx += 1) { /* Starting a new word? */ - if (adr%BITS_PER_WORD == 0) + if (adr_bit == BITS_PER_WORD) { tmp = bits_ptr_[adr/BITS_PER_WORD]; + // If this is the last word, then only test + // for X in the valid bits. + xmask = WORD_X_BITS; + if ((wid-idx) < BITS_PER_WORD) + xmask &= ~(WORD_Z_BITS<<2*(wid-idx)); + if (tmp & xmask) + goto x_out; + adr_bit = 0; + } - if (tmp&2) - goto x_out; if (tmp&1) *val_ptr |= mask1; adr += 1; + adr_bit += 1; tmp >>= 2UL; if (mask1 == mask1_last) {