Fix vvp %shift instructions to treat right operand as unsigned.

1364-2005 section 5.1.12 says "The right operand is always treated
as an unsigned number".

This fixes GitHub issue #283.

(cherry picked from commit 0a4cae2644)
This commit is contained in:
Martin Whitaker 2019-11-15 21:16:57 +00:00
parent fbe423305e
commit b13b608744
2 changed files with 6 additions and 42 deletions

View File

@ -1045,8 +1045,6 @@ The instruction also checks flag bit 4. If it is true, the result is
replaced with X instead of a shifted result. This is intended to
detect that the index contents were not valid.
For a negative shift, %shiftr will pad the value with 'bx.
* %split/vec4 <wid>
Pull the top vec4 vector from the stack and split it into two

View File

@ -4927,10 +4927,10 @@ bool of_SET_DAR_OBJ_STR(vthread_t thr, vvp_code_t cp)
bool of_SHIFTL(vthread_t thr, vvp_code_t cp)
{
int use_index = cp->number;
int shift = thr->words[use_index].w_int;
uint64_t shift = thr->words[use_index].w_uint;
vvp_vector4_t&val = thr->peek_vec4();
int wid = val.size();
unsigned wid = val.size();
if (thr->flags[4] == BIT4_1) {
// The result is 'bx if the shift amount is undefined
@ -4946,18 +4946,6 @@ bool of_SHIFTL(vthread_t thr, vvp_code_t cp)
vvp_vector4_t tmp (shift, BIT4_0);
val.set_vec(0, tmp);
val.set_vec(shift, blk);
} else if (shift < -wid) {
val = vvp_vector4_t(wid, BIT4_X);
} else if (shift < 0) {
// Negative left shift is a right shift.
// For a negative shift, we pad with 'bx.
int use_shift = -shift;
vvp_vector4_t blk = val.subvalue(use_shift, wid-use_shift);
vvp_vector4_t tmp (use_shift, BIT4_X);
val.set_vec(0, blk);
val.set_vec(wid-use_shift, tmp);
}
return true;
@ -4972,10 +4960,10 @@ bool of_SHIFTL(vthread_t thr, vvp_code_t cp)
bool of_SHIFTR(vthread_t thr, vvp_code_t cp)
{
int use_index = cp->number;
int shift = thr->words[use_index].w_int;
uint64_t shift = thr->words[use_index].w_uint;
vvp_vector4_t val = thr->pop_vec4();
int wid = val.size();
unsigned wid = val.size();
if (thr->flags[4] == BIT4_1) {
val = vvp_vector4_t(wid, BIT4_X);
@ -4988,18 +4976,6 @@ bool of_SHIFTR(vthread_t thr, vvp_code_t cp)
vvp_vector4_t tmp (shift, BIT4_0);
val.set_vec(0, blk);
val.set_vec(wid-shift, tmp);
} else if (shift < -wid) {
val = vvp_vector4_t(wid, BIT4_X);
} else if (shift < 0) {
// Negative right shift is a left shift.
// For a negative shift, we pad with 'bx.
int use_shift = -shift;
vvp_vector4_t blk = val.subvalue(0, wid-use_shift);
vvp_vector4_t tmp (use_shift, BIT4_X);
val.set_vec(0, tmp);
val.set_vec(use_shift, blk);
}
thr->push_vec4(val);
@ -5012,10 +4988,10 @@ bool of_SHIFTR(vthread_t thr, vvp_code_t cp)
bool of_SHIFTR_S(vthread_t thr, vvp_code_t cp)
{
int use_index = cp->number;
int shift = thr->words[use_index].w_int;
uint64_t shift = thr->words[use_index].w_uint;
vvp_vector4_t val = thr->pop_vec4();
int wid = val.size();
unsigned wid = val.size();
vvp_bit4_t sign_bit = val.value(val.size()-1);
@ -5030,16 +5006,6 @@ bool of_SHIFTR_S(vthread_t thr, vvp_code_t cp)
vvp_vector4_t tmp (shift, sign_bit);
val.set_vec(0, blk);
val.set_vec(wid-shift, tmp);
} else if (shift < -wid) {
val = vvp_vector4_t(wid, BIT4_X);
} else if (shift < 0) {
int use_shift = -shift;
vvp_vector4_t blk = val.subvalue(0, wid-use_shift);
vvp_vector4_t tmp(use_shift, BIT4_X);
val.set_vec(0, tmp);
val.set_vec(use_shift, blk);
}
thr->push_vec4(val);