Add support for an undefined index for the %load/a* opcodes.

These opcodes need to return 'bx or 0.0 for the real opcode when
the array index is undefined.

The patch also documents the auto incrementing of the bit
index register done by the %load/avx.p opcode.
This commit is contained in:
Cary R 2009-08-28 16:25:11 -07:00 committed by Stephen Williams
parent 83c7a24cff
commit 8623f804f2
2 changed files with 45 additions and 6 deletions

View File

@ -491,7 +491,8 @@ vector is sign extended (instead of 0-extended) before the addition.
This instruction is similar to %load/av, but it loads only a single
bit, and the <index> is the selector for the bit to use. If <index> is
out of range, then x is loaded.
out of range, then x is loaded. The index value is incremented by one
if it is defined (bit 4 is not 1).
* %load/v <bit>, <functor-label>, <wid>

View File

@ -2849,8 +2849,15 @@ bool of_LOAD_AR(vthread_t thr, vvp_code_t cp)
unsigned bit = cp->bit_idx[0];
unsigned idx = cp->bit_idx[1];
unsigned adr = thr->words[idx].w_int;
double word;
/* The result is 0.0 if the address is undefined. */
if (thr_get_bit(thr, 4) == BIT4_1) {
word = 0.0;
} else {
word = array_get_word_r(cp->array, adr);
}
double word = array_get_word_r(cp->array, adr);
thr->words[bit].w_real = word;
return true;
}
@ -2870,11 +2877,18 @@ bool of_LOAD_AV(vthread_t thr, vvp_code_t cp)
unsigned wid = cp->bit_idx[1];
unsigned adr = thr->words[3].w_int;
vvp_vector4_t word = array_get_word(cp->array, adr);
/* Check the address once, before we scan the vector. */
thr_check_addr(thr, bit+wid-1);
/* The result is 'bx if the address is undefined. */
if (thr_get_bit(thr, 4) == BIT4_1) {
vvp_vector4_t tmp (wid, BIT4_X);
thr->bits4.set_vec(bit, tmp);
return true;
}
vvp_vector4_t word = array_get_word(cp->array, adr);
if (word.size() > wid)
word.resize(wid);
@ -2945,6 +2959,15 @@ bool of_LOAD_AVP0(vthread_t thr, vvp_code_t cp)
unsigned wid = cp->bit_idx[1];
unsigned adr = thr->words[3].w_int;
/* The result is 'bx if the address is undefined. */
if (thr_get_bit(thr, 4) == BIT4_1) {
unsigned bit = cp->bit_idx[0];
thr_check_addr(thr, bit+wid-1);
vvp_vector4_t tmp (wid, BIT4_X);
thr->bits4.set_vec(bit, tmp);
return true;
}
/* We need a vector this wide to make the math work correctly.
* Copy the base bits into the vector, but keep the width. */
vvp_vector4_t sig_value(wid, BIT4_0);
@ -2959,6 +2982,15 @@ bool of_LOAD_AVP0_S(vthread_t thr, vvp_code_t cp)
unsigned wid = cp->bit_idx[1];
unsigned adr = thr->words[3].w_int;
/* The result is 'bx if the address is undefined. */
if (thr_get_bit(thr, 4) == BIT4_1) {
unsigned bit = cp->bit_idx[0];
thr_check_addr(thr, bit+wid-1);
vvp_vector4_t tmp (wid, BIT4_X);
thr->bits4.set_vec(bit, tmp);
return true;
}
vvp_vector4_t tmp (array_get_word(cp->array, adr));
/* We need a vector this wide to make the math work correctly.
@ -2985,11 +3017,17 @@ bool of_LOAD_AVX_P(vthread_t thr, vvp_code_t cp)
unsigned index = cp->bit_idx[1];
unsigned adr = thr->words[3].w_int;
unsigned use_index = thr->words[index].w_int;
/* The result is 'bx if the address is undefined. */
if (thr_get_bit(thr, 4) == BIT4_1) {
thr_put_bit(thr, bit, BIT4_X);
return true;
}
long use_index = thr->words[index].w_int;
vvp_vector4_t word = array_get_word(cp->array, adr);
if (use_index >= word.size()) {
if ((use_index >= (long)word.size()) || (use_index < 0)) {
thr_put_bit(thr, bit, BIT4_X);
} else {
thr_put_bit(thr, bit, word.value(use_index));