diff options
| author | Siddarth Suresh <155843085+SiddarthSuresh98@users.noreply.github.com> | 2025-04-27 09:12:50 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-27 09:12:50 -0400 | 
| commit | 5653b2a033e7a4173d2f178b5ce52384666d3d7b (patch) | |
| tree | 5c8fc7282ad1ce0c215786a70b35296645df2a1b /src/ex.cc | |
| parent | 3d0133c2f793e82d7519d8e2c5023114cd0f0eab (diff) | |
| parent | a4dd1f00a5d0108058fb3bfbd5f399a507792859 (diff) | |
Merge pull request #68 from bdunahu/bdunahu
[WIP] Pipeline cleanup and revisited GUI storage display
Diffstat (limited to 'src/ex.cc')
| -rw-r--r-- | src/ex.cc | 452 | 
1 files changed, 452 insertions, 0 deletions
diff --git a/src/ex.cc b/src/ex.cc new file mode 100644 index 0000000..eac24ff --- /dev/null +++ b/src/ex.cc @@ -0,0 +1,452 @@ +// Simulator for the RISC-V[ECTOR] mini-ISA +// Copyright (C) 2025 Siddarth Suresh +// Copyright (C) 2025 bdunahu + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <https://www.gnu.org/licenses/>. + +#include "ex.h" +#include "instrDTO.h" +#include "pipe_spec.h" +#include "response.h" +#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; +			}), +	}; +} + +void EX::advance_helper() +{ +	signed int s1, s2, s3; +	unsigned int pc; +	Mnemonic m; + +	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); + +	this->curr_instr->operands.integer.slot_one = s1; +	this->status = OK; +} + +void EX::handle_divide(signed int &s1, signed int s2, bool is_mod) +{ +	this->set_condition(OF, DIVISION_OF_GUARD(s1, s2)); +	this->set_condition(UF, false); +	if (s2 == 0) { +		// handle everything here +		this->curr_instr->operands.integer.slot_one = MAX_INT; +		this->status = OK; +		throw HaltException(); +	} else if ((s1 == -(MAX_INT)-1) && s2 == -1) { +		// undefined in C++ +		s1 = -(MAX_INT)-1; +	} else { +		s1 = (is_mod) ? (s1 % s2) : (s1 / s2); +	} +}  | 
