diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 87c4637c3..a93eb4dbf 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -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; }