diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-17 21:15:53 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-02-17 21:15:53 +0100 |
commit | 9d82517dea100d94fd8d0d5326ca5db7b5a1e595 (patch) | |
tree | 3cde4e7a04d40c2134509e9b675700dc5a1a2b0c /qtmips_machine/core.cpp | |
parent | c58935b7587980cdf16015da5e21b5896c96678e (diff) | |
download | qtmips-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.cpp | 57 |
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, }; } |