aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine/core.cpp
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-17 21:15:53 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-17 21:15:53 +0100
commit9d82517dea100d94fd8d0d5326ca5db7b5a1e595 (patch)
tree3cde4e7a04d40c2134509e9b675700dc5a1a2b0c /qtmips_machine/core.cpp
parentc58935b7587980cdf16015da5e21b5896c96678e (diff)
downloadqtmips-9d82517dea100d94fd8d0d5326ca5db7b5a1e595.tar.gz
qtmips-9d82517dea100d94fd8d0d5326ca5db7b5a1e595.tar.bz2
qtmips-9d82517dea100d94fd8d0d5326ca5db7b5a1e595.zip
Pass arithmetic exception trough pipeline and implement trap support and instructions.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine/core.cpp')
-rw-r--r--qtmips_machine/core.cpp57
1 files changed, 31 insertions, 26 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index dccc20b..6ef9103 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -314,6 +314,8 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
bool discard;
+ enum ExceptionCause excause = dt.excause;
+ std::uint32_t alu_val = 0;
// Handle conditional move (we have to change regwrite signal if conditional is not met)
bool regwrite = dt.regwrite;
@@ -322,35 +324,38 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
if (dt.alusrc)
alu_sec = dt.immediate_val; // Sign or zero extend immediate value
- std::uint32_t alu_val = alu_operate(dt.aluop, dt.val_rs, alu_sec,
- dt.inst.shamt(), dt.inst.rd(), regs, discard);
- if (discard)
- regwrite = false;
-
- if (dt.aluop == ALU_OP_RDHWR) {
- switch (dt.inst.rd()) {
- case 0: // CPUNum
- alu_val = 0;
- break;
- case 1: // SYNCI_Step
- alu_val = min_cache_row_size;
- break;
- case 2: // CC
- alu_val = cycle_c;
- break;
- case 3: // CCRes
- alu_val = 1;
- break;
- case 29: // UserLocal
- alu_val = hwr_userlocal;
- break;
- default:
- alu_val = 0;
+ if (excause == EXCAUSE_NONE) {
+ alu_val = alu_operate(dt.aluop, dt.val_rs,
+ alu_sec, dt.inst.shamt(), dt.inst.rd(), regs,
+ discard, excause);
+ if (discard)
+ regwrite = false;
+
+ if (dt.aluop == ALU_OP_RDHWR) {
+ switch (dt.inst.rd()) {
+ case 0: // CPUNum
+ alu_val = 0;
+ break;
+ case 1: // SYNCI_Step
+ alu_val = min_cache_row_size;
+ break;
+ case 2: // CC
+ alu_val = cycle_c;
+ break;
+ case 3: // CCRes
+ alu_val = 1;
+ break;
+ case 29: // UserLocal
+ alu_val = hwr_userlocal;
+ break;
+ default:
+ alu_val = 0;
+ }
}
}
emit execute_inst_addr_value(dt.inst_addr);
- emit instruction_executed(dt.inst, dt.inst_addr, dt.excause);
+ emit instruction_executed(dt.inst, dt.inst_addr, excause);
emit execute_alu_value(alu_val);
emit execute_reg1_value(dt.val_rs);
emit execute_reg2_value(dt.val_rt);
@@ -375,7 +380,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
.rwrite = dt.rwrite,
.alu_val = alu_val,
.inst_addr = dt.inst_addr,
- .excause = dt.excause,
+ .excause = excause,
.in_delay_slot = dt.in_delay_slot,
};
}