diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-06 23:17:47 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-06 23:17:47 +0100 |
commit | b232bb867c1ac8cb7369190e8cd4f9f7af425cd1 (patch) | |
tree | b02e07497de7ddf4c70fa335a06c23040559e5d7 /qtmips_machine/instruction.cpp | |
parent | 9634200c1041eca1c7ac0ce25d79bb8d961530f6 (diff) | |
download | qtmips-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.cpp | 22 |
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 { |