aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-01-31 11:45:41 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-01-31 11:45:41 +0100
commitb1f0e4fcc83c7692f4b066fcc026d77a051c1d7d (patch)
tree51a452e656edd61f75b982c35d0656f691f72deb
parenteab6cf4fc5720b330ba89c38e9e6119a8a6fabfa (diff)
downloadqtmips-b1f0e4fcc83c7692f4b066fcc026d77a051c1d7d.tar.gz
qtmips-b1f0e4fcc83c7692f4b066fcc026d77a051c1d7d.tar.bz2
qtmips-b1f0e4fcc83c7692f4b066fcc026d77a051c1d7d.zip
Include support for JALR support.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
-rw-r--r--qtmips_machine/alu.cpp4
-rw-r--r--qtmips_machine/core.cpp11
2 files changed, 11 insertions, 4 deletions
diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp
index 36b1ac7..176a9a5 100644
--- a/qtmips_machine/alu.cpp
+++ b/qtmips_machine/alu.cpp
@@ -21,9 +21,11 @@ std::uint32_t machine::alu_operate(enum AluOp operation, std::uint32_t s, std::u
// Note: same note as in case of SRA
return (std::int32_t)t >> s;
case ALU_OP_JR:
- case ALU_OP_JALR:
// Do nothing as we solve this when we are handling program counter in instruction decode (handle_pc)
return 0;
+ case ALU_OP_JALR:
+ // Pass return value in rt to save PC after isntruction, program counter is handled in handle_pc
+ return t;
case ALU_OP_MOVZ:
// We do this just to implement valid alu operation but we have to evaluate comparison outside of this function to disable register write
return t == 0 ? s : 0;
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 6443be1..2ff528d 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -134,6 +134,7 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
std::uint32_t val_rs = regs->read_gp(dt.inst.rs());
std::uint32_t val_rt = regs->read_gp(dt.inst.rt());
std::uint32_t immediate_val;
+ bool regd31 = dec.flags & DM_PC_TO_R31;
if (dec.flags & DM_ZERO_EXTEND)
immediate_val = dt.inst.immediate();
@@ -153,19 +154,23 @@ struct Core::dtDecode Core::decode(const struct dtFetch &dt) {
emit decode_rs_num_value(dt.inst.rs());
emit decode_rt_num_value(dt.inst.rt());
emit decode_rd_num_value(dt.inst.rd());
- emit decode_regd31_value((bool)(dec.flags & DM_PC_TO_R31));
+ emit decode_regd31_value(regd31);
- if (dec.flags & DM_PC_TO_R31) {
+ if (regd31) {
val_rs = dt.inst_addr + 8;
}
+ if ((dt.inst.opcode() == 0 && dt.inst.funct() == ALU_OP_JALR)) {
+ val_rt = dt.inst_addr + 8;
+ }
+
return {
.inst = dt.inst,
.memread = dec.flags & DM_MEMREAD,
.memwrite = dec.flags & DM_MEMWRITE,
.alusrc = dec.flags & DM_ALUSRC,
.regd = dec.flags & DM_REGD,
- .regd31 = dec.flags & DM_PC_TO_R31,
+ .regd31 = regd31,
.regwrite = dec.flags & DM_REGWRITE,
.aluop = dt.inst.opcode() == 0 ? (enum AluOp)dt.inst.funct() : dec.alu,
.memctl = dec.mem_ctl,