diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ex.cc | 33 | ||||
-rw-r--r-- | src/id.cc | 8 | ||||
-rw-r--r-- | src/mm.cc | 64 | ||||
-rw-r--r-- | src/wb.cc | 13 |
4 files changed, 90 insertions, 28 deletions
@@ -240,13 +240,25 @@ void EX::handle_vector_operations( this->set_condition(UF, underflow); } -void EX::handle_s_vector_operations(signed int &s1, signed int s2, Mnemonic m) +void EX::handle_s_vector_operations( + std::array<signed int, V_R_LIMIT> &s1, + signed int s2, + Mnemonic m, + unsigned int v_len) { + unsigned int i, inc1, inc2; + switch (m) { - // case SRDL: - // case SRDS: - // s1 = s1 + s2; - // break; + case SRDL: + case SRDS: + inc1 = s1[0]; + s1[0] = s2; + for (i = 1; i < v_len; ++i) { + inc2 = s1[i]; + s1[i] = s1[i - 1] + inc1; + inc1 = inc2; + } + break; default: throw std::invalid_argument("handle_s_vector_operations did not " @@ -270,11 +282,12 @@ void EX::advance_helper() handle_vector_operations( this->curr_instr->operands.vector.slot_one, this->curr_instr->operands.vector.slot_two, m, v_len_or_pc); - }// else { - // handle_s_vector_operations( - // this->curr_instr->operands.s_vector.slot_one, - // this->curr_instr->operands.s_vector.slot_two, m); - // } + } else { + handle_s_vector_operations( + this->curr_instr->operands.s_vector.slot_one, + this->curr_instr->operands.s_vector.slot_two, m, v_len_or_pc); + printArray(this->curr_instr->operands.s_vector.slot_three); + } this->status = OK; } @@ -135,10 +135,16 @@ void ID::decode_R_type(signed int &s1) this->write_guard<std::array<signed int, V_R_LIMIT>>(s3); break; case SRDL: - case SRDS: this->curr_instr->operands.s_vector.slot_three = this->write_guard<std::array<signed int, V_R_LIMIT>>(s3); break; + case SRDS: + r1 = this->read_guard<std::array<signed int, V_R_LIMIT>>( + s3, this->curr_instr->operands.s_vector.slot_three); + if (r1 != OK) { + this->status = STALLED; + } + break; default: this->curr_instr->operands.integer.slot_three = this->write_guard<signed int>(s3); @@ -25,15 +25,30 @@ void MM::advance_helper() signed int data; int i; + this->try_start(); + if (this->status == OK) { + return; + } + switch (this->curr_instr->mnemonic) { case LOAD: i = this->storage->read_word( this, this->curr_instr->operands.integer.slot_one, data); - this->status = i ? OK : STALLED; - if (this->status == OK) { + if (i) { this->curr_instr->operands.integer.slot_one = data; - } else - this->status = STALLED; + } + this->try_finish(i); + break; + case SRDL: + i = this->storage->read_word( + this, + this->curr_instr->operands.s_vector.slot_one[this->curr_element], + data); + if (i) { + this->curr_instr->operands.s_vector.slot_one[this->curr_element] = + data; + } + this->try_finish(i); break; case PUSH: @@ -41,22 +56,47 @@ void MM::advance_helper() i = this->storage->write_word( this, this->curr_instr->operands.integer.slot_two, this->curr_instr->operands.integer.slot_one); - this->status = i ? OK : STALLED; - if (this->status != OK) { - this->status = STALLED; - } + this->try_finish(i); + break; + case SRDS: + i = this->storage->write_word( + this, + this->curr_instr->operands.s_vector.slot_three[this->curr_element], + this->curr_instr->operands.s_vector.slot_one[this->curr_element]); + this->try_finish(i); break; case POP: - i = this->storage->read_word(this, this->curr_instr->operands.integer.slot_three, data); + i = this->storage->read_word( + this, this->curr_instr->operands.integer.slot_three, data); this->status = i ? OK : STALLED; - if (this->status == OK) { + if (i) { this->curr_instr->operands.integer.slot_three = data; - } else - this->status = STALLED; + } break; default: this->status = OK; } } + +void MM::try_start() +{ + if (this->curr_instr->type != SI_INT) { + this->status = + (this->curr_element >= this->curr_instr->slot_B) ? OK : STALLED; + } + if (this->status == OK) + this->curr_element = 0; +} + +void MM::try_finish(int response) +{ + if (this->curr_instr->type == SI_INT) { + this->status = response ? OK : STALLED; + } else { + if (response) { + ++this->curr_element; + } + } +} @@ -58,15 +58,11 @@ void WB::write_handler() this->store_register<signed int>( reg, this->curr_instr->operands.integer.slot_one); break; + case S_VECT: case R_VECT: this->store_register<std::array<signed int, V_R_LIMIT>>( reg, this->copy_extra_vector_elements()); break; - // case S_VECT: - // this->store_register<std::array<signed int, V_R_LIMIT>>( - // reg, this->curr_instr->operands.s_vector.slot_three); - // // todo, use copy_extra_vector_elements - // break; } } @@ -97,6 +93,13 @@ std::array<signed int, V_R_LIMIT> WB::copy_extra_vector_elements() int i; std::array<signed int, V_R_LIMIT> v; + if (this->curr_instr->type == S_VECT) { + if (this->curr_instr->slot_B == 0) { + v = {0}; + return v; + } + } + v = this->curr_instr->operands.vector.slot_one; for (i = V_R_LIMIT - 1; i >= this->curr_instr->slot_B; --i) { v[i] = this->curr_instr->operands.vector.slot_three[i]; |