diff options
author | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-01-31 11:45:41 +0100 |
---|---|---|
committer | Pavel Pisa <pisa@cmp.felk.cvut.cz> | 2019-01-31 11:45:41 +0100 |
commit | b1f0e4fcc83c7692f4b066fcc026d77a051c1d7d (patch) | |
tree | 51a452e656edd61f75b982c35d0656f691f72deb | |
parent | eab6cf4fc5720b330ba89c38e9e6119a8a6fabfa (diff) | |
download | qtmips-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.cpp | 4 | ||||
-rw-r--r-- | qtmips_machine/core.cpp | 11 |
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, |