vvp: Handle (partial) out-of-bounds writes for `%store/vec4a`

The `%store/vec4a` instruction does not handle partial of full
out-of-bounds writes to a vector array element. Trying to do so will
trigger an assert. E.g.

```
integer a[3:0];
integer i = -10;
a[0][i+:8] = 8'h0; // Triggers assert
```

For fully out-of-bounds writes the write should be skipped, for partial
out-of-bounds writes the value needs to be resized to be within the bounds
of the vector. Use the `resize_rval_vec()` helper function to implement
this.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-05-28 09:59:16 +02:00
parent ce9f3d5e59
commit 9a50956f5e
1 changed files with 8 additions and 3 deletions

View File

@ -6249,10 +6249,8 @@ bool of_STORE_VEC4A(vthread_t thr, vvp_code_t cp)
unsigned adr_index = cp->bit_idx[0];
unsigned off_index = cp->bit_idx[1];
const vvp_vector4_t&value = thr->peek_vec4();
long adr = adr_index? thr->words[adr_index].w_int : 0;
long off = off_index? thr->words[off_index].w_int : 0;
int64_t off = off_index ? thr->words[off_index].w_int : 0;
// Suppress action if flags-4 is true.
if (thr->flags[4] == BIT4_1) {
@ -6260,6 +6258,13 @@ bool of_STORE_VEC4A(vthread_t thr, vvp_code_t cp)
return true;
}
vvp_vector4_t &value = thr->peek_vec4();
if (!resize_rval_vec(value, off, cp->array->get_word_size())) {
thr->pop_vec4(1);
return true;
}
cp->array->set_word(adr, off, value);
thr->pop_vec4(1);