Fix thread address check and wide vector unaligned copy.

This patch fixes two problems. The first is that thr_check_addr()
was being used inconsistently. It should be passed a real address,
but the resize of the vector should be at least one more than this
address. The extra and unneeded CPU_WORD_BITS was also removed
from the routine.

The second problem involved an invalid memory access in
vvp_vector4_t::set_vec() when the vector being copied was an integer
multiple of the machine word width. Under this condition there would
be no remaining bits that needed to be copied but the routine was always
trying to copying some remaining bits. This code is now only executed
when there is a remainder.

Neither of these appear to be causing runtime problems. The second one
was found with valgrind. The first were found while tracking down the
second problem.
This commit is contained in:
Cary R 2008-02-15 16:00:22 -08:00 committed by Stephen Williams
parent 39dd22ace4
commit e989f63192
2 changed files with 27 additions and 27 deletions

View File

@ -123,7 +123,7 @@ struct vthread_s {
static inline void thr_check_addr(struct vthread_s*thr, unsigned addr)
{
if (thr->bits4.size() <= addr)
thr->bits4.resize(addr + CPU_WORD_BITS);
thr->bits4.resize(addr+1);
}
static inline vvp_bit4_t thr_get_bit(struct vthread_s*thr, unsigned addr)
@ -2673,8 +2673,8 @@ static bool of_MOV_(vthread_t thr, vvp_code_t cp)
neither the source nor the destination to be <4. Otherwise,
we copy all the bits manually. */
thr_check_addr(thr, cp->bit_idx[0]+cp->number);
thr_check_addr(thr, cp->bit_idx[1]+cp->number);
thr_check_addr(thr, cp->bit_idx[0]+cp->number-1);
thr_check_addr(thr, cp->bit_idx[1]+cp->number-1);
// Read the source vector out
vvp_vector4_t tmp (thr->bits4, cp->bit_idx[1], cp->number);
// Write it in the new place.
@ -2717,7 +2717,7 @@ bool of_MOVI(vthread_t thr, vvp_code_t cp)
unsigned val = cp->bit_idx[1];
unsigned wid = cp->number;
thr_check_addr(thr, dst+wid);
thr_check_addr(thr, dst+wid-1);
for (unsigned idx = 0 ; idx < wid ; idx += 1, val >>= 1)
thr->bits4.set_bit(dst+idx, (val&1)? BIT4_1 : BIT4_0);

View File

@ -526,33 +526,33 @@ void vvp_vector4_t::set_vec(unsigned adr, const vvp_vector4_t&that)
sptr += 1;
}
unsigned long hshift = doff+remain;
unsigned long hmask;
if (hshift >= BITS_PER_WORD)
hmask = -1UL;
else
hmask = (1UL << 2UL*(doff+remain)) - 1;
unsigned long mask = hmask & ~lmask;
bits_ptr_[dptr] =
(bits_ptr_[dptr] & ~mask)
| ((that.bits_ptr_[sptr] << 2UL*doff) & mask);
if ((doff + remain) > BITS_PER_WORD) {
unsigned tail = doff + remain - BITS_PER_WORD;
if (tail >= BITS_PER_WORD)
mask = -1UL;
if (remain > 0) {
unsigned long hshift = doff+remain;
unsigned long hmask;
if (hshift >= BITS_PER_WORD)
hmask = -1UL;
else
mask = (1UL << 2UL*tail) - 1;
hmask = (1UL << 2UL*(doff+remain)) - 1;
dptr += 1;
bits_ptr_[dptr] =
(bits_ptr_[dptr] & ~mask)
| ((that.bits_ptr_[sptr] >> 2UL*(remain-tail))&mask);
unsigned long mask = hmask & ~lmask;
bits_ptr_[dptr] = (bits_ptr_[dptr] & ~mask)
| ((that.bits_ptr_[sptr] << 2UL*doff) & mask);
if ((doff + remain) > BITS_PER_WORD) {
unsigned tail = doff + remain - BITS_PER_WORD;
if (tail >= BITS_PER_WORD)
mask = -1UL;
else
mask = (1UL << 2UL*tail) - 1;
dptr += 1;
bits_ptr_[dptr] = (bits_ptr_[dptr] & ~mask) |
((that.bits_ptr_[sptr] >> 2UL*
(remain-tail))&mask);
}
}
}
}