From 8c36e20fd4051e30a59c91147dd4b604933e773c Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 28 Aug 2009 16:25:11 -0700 Subject: [PATCH] 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. (cherry picked from commit 8623f804f2acd10a5329721869521d27d1c3963b) --- vvp/opcodes.txt | 3 ++- vvp/vthread.cc | 48 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/vvp/opcodes.txt b/vvp/opcodes.txt index 2c18aabbd..befa5c8db 100644 --- a/vvp/opcodes.txt +++ b/vvp/opcodes.txt @@ -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 is the selector for the bit to use. If 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 , , diff --git a/vvp/vthread.cc b/vvp/vthread.cc index 1b87cbc22..4b36ecce8 100644 --- a/vvp/vthread.cc +++ b/vvp/vthread.cc @@ -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));