diff options
author | bd <bdunaisky@umass.edu> | 2025-04-28 03:44:42 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-28 03:44:42 +0000 |
commit | 013a79547aa465872d0262b2f5c24e73f9556869 (patch) | |
tree | 28cc8f2ea6e5aa1a74f328de8594b0ad5995fa66 /src/ex.cc | |
parent | 5653b2a033e7a4173d2f178b5ce52384666d3d7b (diff) | |
parent | 336faf3fd701aaf962613abd1ff0a69cbdf021ce (diff) |
Merge pull request #69 from bdunahu/vector_ext
Vector ext
Diffstat (limited to 'src/ex.cc')
-rw-r--r-- | src/ex.cc | 613 |
1 files changed, 214 insertions, 399 deletions
@@ -22,415 +22,230 @@ #include "stage.h" #include <unordered_map> -// clang-format off -#define INIT_INSTRUCTION(mnemonic, body) \ - {mnemonic, [this](signed int &s1, signed int s2, signed int s3, unsigned int pc) { \ - body; \ - }} -// clang-format on - -EX::EX(Stage *stage) : Stage(stage) -{ - instr_map = { - - /* R type instructions */ - INIT_INSTRUCTION( - ADD, - { - this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s2)); - s1 = s1 + s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - SUB, - { - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2)); - s1 = s1 - s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - MUL, - { - this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2)); - this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2)); - s1 = s1 * s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - QUOT, - { - this->handle_divide(s1, s2, false); - (void)pc; - (void)s3; - }), - - INIT_INSTRUCTION( - REM, - { - this->handle_divide(s1, s2, true); - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - SFTR, - { - s1 = s1 >> s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - SFTL, - { - s1 = s1 << s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - AND, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 & s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - OR, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 | s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - NOT, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = ~s1; - (void)pc; - (void)s3; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - XOR, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 ^ s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - ADDV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - SUBV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - MULV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - DIVV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - CMP, - { - (s1 > s2) ? this->set_condition(GT, true) - : this->set_condition(GT, false); - (s1 == s2) ? this->set_condition(EQ, true) - : this->set_condition(EQ, false); - (void)pc; - (void)s3; - }), - - INIT_INSTRUCTION( - CEV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - /* I type instructions */ - INIT_INSTRUCTION( - LOAD, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - LOADV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - INIT_INSTRUCTION( - ADDI, - { - this->set_condition(OF, ADDITION_OF_GUARD(s1, s3)); - this->set_condition(UF, ADDITION_UF_GUARD(s1, s3)); - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - SUBI, - { - this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3)); - this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3)); - s1 = s1 - s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - SFTRI, - { - s1 = s1 >> s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - SFTLI, - { - s1 = s1 << s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - ANDI, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 & s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - ORI, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 | s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - XORI, - { - this->set_condition(OF, false); - this->set_condition(UF, false); - s1 = s1 ^ s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - STORE, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - STOREV, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - /* J type instructions */ - INIT_INSTRUCTION( - JMP, - { - s1 = s1 + s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - JRL, - { - s1 = pc + s2; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - JAL, - { - s1 = s1 + s2; - (void)pc; - (void)s3; - (void)this; - }), - - INIT_INSTRUCTION( - BEQ, - { - (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - BGT, - { - (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - BUF, - { - (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - BOF, - { - (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; - (void)s3; - }), - - INIT_INSTRUCTION( - PUSH, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - POP, - { - s1 = s1 + s3; - (void)pc; - (void)s2; - (void)this; - }), - - INIT_INSTRUCTION( - RET, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - - /* NOP */ - INIT_INSTRUCTION( - NOP, - { - (void)pc; - (void)s3; - (void)s2; - (void)s1; - (void)this; - }), - }; -} - +// Switch statements for each instruction void EX::advance_helper() { signed int s1, s2, s3; + std::array<signed int, V_R_LIMIT> v1, v2, v3; + signed int v_len, v_immediate, v_base_addr; unsigned int pc; Mnemonic m; + s1 = 0, s2 = 0, s3 = 0; + v1 = {0}, v2 = {0}, v3 = {0}; + v_len = 0, v_immediate = 0, v_base_addr = 0; m = this->curr_instr->mnemonic; - s1 = this->curr_instr->operands.integer.slot_one; - s2 = this->curr_instr->operands.integer.slot_two; - s3 = this->curr_instr->operands.integer.slot_three; pc = this->curr_instr->slot_B; - this->instr_map[m](s1, s2, s3, pc); + if (this->is_vector_type(m)) { + if (this->curr_instr->mnemonic != LOADV && + this->curr_instr->mnemonic != STOREV) { + v1 = this->curr_instr->operands.vector.slot_one; + v2 = this->curr_instr->operands.vector.slot_two; + v3 = this->curr_instr->operands.vector.slot_three; + } else { + v_immediate = + this->curr_instr->operands.load_store_vector.immediate; + v_base_addr = + this->curr_instr->operands.load_store_vector.base_addr; + } + v_len = this->curr_instr->slot_A; + if (v_len == 0) { + // clear destination vector reg + v1.fill(0); + } + } else { + s1 = this->curr_instr->operands.integer.slot_one; + s2 = this->curr_instr->operands.integer.slot_two; + s3 = this->curr_instr->operands.integer.slot_three; + } + + if (this->is_logical(m)) { + this->set_condition(OF, false); + this->set_condition(UF, false); + } - this->curr_instr->operands.integer.slot_one = s1; + switch (m) { + case ADD: + this->set_condition(OF, ADDITION_OF_GUARD(s1, s2)); + this->set_condition(UF, ADDITION_UF_GUARD(s1, s2)); + s1 = s1 + s2; + break; + + case SUB: + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s2)); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s2)); + s1 = s1 - s2; + break; + + case MUL: + this->set_condition(OF, MULTIPLICATION_OF_GUARD(s1, s2)); + this->set_condition(UF, MULTIPLICATION_UF_GUARD(s1, s2)); + s1 = s1 * s2; + break; + + case QUOT: + this->handle_divide(s1, s2, false); + break; + + case REM: + this->handle_divide(s1, s2, true); + break; + + case SFTR: + s1 = s1 >> s2; + break; + + case SFTL: + s1 = s1 << s2; + break; + + case AND: + s1 = s1 & s2; + break; + + case OR: + s1 = s1 | s2; + break; + + case XOR: + s1 = s1 ^ s2; + break; + + case NOT: + s1 = ~s1; + break; + + case CMP: + (s1 > s2) ? this->set_condition(GT, true) + : this->set_condition(GT, false); + (s1 == s2) ? this->set_condition(EQ, true) + : this->set_condition(EQ, false); + break; + + case ADDI: + this->set_condition(OF, ADDITION_OF_GUARD(s1, s3)); + this->set_condition(UF, ADDITION_UF_GUARD(s1, s3)); + s1 = s1 + s3; + break; + + case SUBI: + this->set_condition(OF, SUBTRACTION_OF_GUARD(s1, s3)); + this->set_condition(UF, SUBTRACTION_UF_GUARD(s1, s3)); + s1 = s1 - s3; + break; + + case SFTRI: + s1 = s1 >> s3; + break; + + case SFTLI: + s1 = s1 << s3; + break; + + case ANDI: + s1 = s1 & s3; + break; + + case ORI: + s1 = s1 | s3; + break; + + case XORI: + s1 = s1 ^ s3; + break; + + case LOAD: + case STORE: + case PUSH: + case POP: + s1 = s1 + s3; + break; + + case JMP: + case JAL: + s1 = s1 + s2; + break; + + case JRL: + s1 = pc + s2; + break; + + case BEQ: + (this->get_condition(EQ)) ? s1 = pc + s2 : s1 = -1; + break; + + case BGT: + (this->get_condition(GT)) ? s1 = pc + s2 : s1 = -1; + break; + + case BUF: + (this->get_condition(UF)) ? s1 = pc + s2 : s1 = -1; + break; + + case BOF: + (this->get_condition(OF)) ? s1 = pc + s2 : s1 = -1; + break; + + case ADDV: + for (int i = 0; i < v_len; i++) { + this->set_condition(OF, ADDITION_OF_GUARD(v1[i], v2[i])); + this->set_condition(UF, ADDITION_UF_GUARD(v1[i], v2[i])); + v1[i] = v1[i] + v2[i]; + } + break; + case SUBV: + for (int i = 0; i < v_len; i++) { + this->set_condition(OF, SUBTRACTION_OF_GUARD(v1[i], v2[i])); + this->set_condition(UF, SUBTRACTION_UF_GUARD(v1[i], v2[i])); + v1[i] = v1[i] - v2[i]; + } + break; + case MULV: + for (int i = 0; i < v_len; i++) { + this->set_condition(OF, MULTIPLICATION_OF_GUARD(v1[i], v2[i])); + this->set_condition(UF, MULTIPLICATION_UF_GUARD(v1[i], v2[i])); + v1[i] = v1[i] * v2[i]; + } + break; + case DIVV: + for (int i = 0; i < v_len; i++) { + this->handle_divide(v1[i], v2[i], false); + } + break; + case CEV: + int i; + for (i = 0; i < v_len; i++) { + if (v1[i] != v2[i]) { + break; + } + } + if (i == v_len) { + this->set_condition(EQ, true); + } else { + this->set_condition(EQ, false); + } + break; + case LOADV: + case STOREV: + v_base_addr = v_base_addr + v_immediate; + break; + + case RET: + case NOP: + break; + } + if (this->is_vector_type(m)) { + if (this->curr_instr->mnemonic != LOADV && + this->curr_instr->mnemonic != STOREV) { + this->curr_instr->operands.vector.slot_one = v1; + } else { + this->curr_instr->operands.load_store_vector.base_addr = + v_base_addr; + } + } else { + this->curr_instr->operands.integer.slot_one = s1; + } this->status = OK; } |