Fix negative shift of signed right shift.

Negative shift amounts can happen for right shifts in
certain specialized cases, and that needs to be handled.
This commit is contained in:
Stephen Williams 2010-03-06 16:06:03 -08:00
parent 33e52c50c0
commit 72b4332b02
1 changed files with 21 additions and 6 deletions

View File

@ -4321,9 +4321,9 @@ bool of_SHIFTR_I0(vthread_t thr, vvp_code_t cp)
bool of_SHIFTR_S_I0(vthread_t thr, vvp_code_t cp)
{
unsigned base = cp->bit_idx[0];
unsigned wid = cp->number;
unsigned long shift = thr->words[0].w_int;
int base = cp->bit_idx[0];
int wid = cp->number;
int shift = thr->words[0].w_int;
vvp_bit4_t sign = thr_get_bit(thr, base+wid-1);
if (thr_get_bit(thr, 4) == BIT4_1) {
@ -4331,17 +4331,32 @@ bool of_SHIFTR_S_I0(vthread_t thr, vvp_code_t cp)
vvp_vector4_t tmp (wid, BIT4_X);
thr->bits4.set_vec(base, tmp);
} else if (shift >= wid) {
for (unsigned idx = 0 ; idx < wid ; idx += 1)
for (int idx = 0 ; idx < wid ; idx += 1)
thr_put_bit(thr, base+idx, sign);
} else if (shift > 0) {
for (unsigned idx = 0 ; idx < (wid-shift) ; idx += 1) {
for (int idx = 0 ; idx < (wid-shift) ; idx += 1) {
unsigned src = base + idx + shift;
unsigned dst = base + idx;
thr_put_bit(thr, dst, thr_get_bit(thr, src));
}
for (unsigned idx = (wid-shift) ; idx < wid ; idx += 1)
for (int idx = (wid-shift) ; idx < wid ; idx += 1)
thr_put_bit(thr, base+idx, sign);
} else if (shift < -wid) {
// Negative shift is so far that all the value is
// shifted out. Write in a constant 'bx result.
vvp_vector4_t tmp (wid, BIT4_X);
thr->bits4.set_vec(base, tmp);
} else if (shift < 0) {
// For a negative shift we pad with 'bx.
vvp_vector4_t tmp (thr->bits4, base, wid+shift);
thr->bits4.set_vec(base-shift, tmp);
vvp_vector4_t fil (-shift, BIT4_X);
thr->bits4.set_vec(base, fil);
}
return true;
}