aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine/instruction.cpp
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-06 23:17:47 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-06 23:17:47 +0100
commitb232bb867c1ac8cb7369190e8cd4f9f7af425cd1 (patch)
treeb02e07497de7ddf4c70fa335a06c23040559e5d7 /qtmips_machine/instruction.cpp
parent9634200c1041eca1c7ac0ce25d79bb8d961530f6 (diff)
downloadqtmips-b232bb867c1ac8cb7369190e8cd4f9f7af425cd1.tar.gz
qtmips-b232bb867c1ac8cb7369190e8cd4f9f7af425cd1.tar.bz2
qtmips-b232bb867c1ac8cb7369190e8cd4f9f7af425cd1.zip
Implemented base for exception handling.
Memory stage is chosen to be exception commit stage. Instructions flow postponed and stages holding following instructions are cleaned. Processing of syscall at decode stage as jump to the handler would be better solution in real hardware but for future emulated syscalls it is better to reach consistent state of registers. Memory access caused exceptions would require cleanup even in real hardware. Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine/instruction.cpp')
-rw-r--r--qtmips_machine/instruction.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp
index ed9064b..9eae5f3 100644
--- a/qtmips_machine/instruction.cpp
+++ b/qtmips_machine/instruction.cpp
@@ -106,9 +106,10 @@ static const struct InstructionMap alu_instruction_map[] = {
.flags = FLAGS_ALU_T_R_STD},
{"MOVN", IT_R, ALU_OP_MOVN, NOMEM, nullptr,
.flags = FLAGS_ALU_T_R_STD},
- IM_UNKNOWN,
+ {"SYSCALL",IT_R, ALU_OP_SYSCALL, NOMEM, nullptr,
+ .flags = IMF_SUPPORTED | IMF_EXCEPTION},
{"BREAK", IT_R, ALU_OP_BREAK, NOMEM, nullptr,
- .flags = IMF_SUPPORTED},
+ .flags = IMF_SUPPORTED | IMF_EXCEPTION},
IM_UNKNOWN,
IM_UNKNOWN,
{"MFHI", IT_R, ALU_OP_MFHI, NOMEM, nullptr,
@@ -426,8 +427,23 @@ void Instruction::flags_alu_op_mem_ctl(enum InstructionFlags &flags,
mem_ctl = im.mem_ctl;
}
+enum ExceptionCause Instruction::encoded_exception() const {
+ const struct InstructionMap &im = InstructionMapFind(dt);
+ if (!(im.flags & IMF_EXCEPTION))
+ return EXCAUSE_NONE;
+ switch (im.alu) {
+ case ALU_OP_BREAK:
+ return EXCAUSE_BREAK;
+ case ALU_OP_SYSCALL:
+ return EXCAUSE_SYSCALL;
+ default:
+ return EXCAUSE_NONE;
+ }
+}
+
bool Instruction::is_break() const {
- return opcode() == 0 && funct() == ALU_OP_BREAK;
+ const struct InstructionMap &im = InstructionMapFind(dt);
+ return im.alu == ALU_OP_BREAK;
}
bool Instruction::operator==(const Instruction &c) const {