aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2017-12-12 20:42:16 +0100
committerKarel Kočí <cynerd@email.cz>2017-12-12 20:42:16 +0100
commit1972096df3d235d525bcf761ecb460ba952c0ba9 (patch)
tree7c8ace4e9805d59858184ba8ce8c507ab9417573
parent7ab428e3e75854749a39128a8bfcbc47b7844f87 (diff)
downloadqtmips-1972096df3d235d525bcf761ecb460ba952c0ba9.tar.gz
qtmips-1972096df3d235d525bcf761ecb460ba952c0ba9.tar.bz2
qtmips-1972096df3d235d525bcf761ecb460ba952c0ba9.zip
Fix immediate alu operation
There should be a sign extension to 32bit when doing immediate operations.
-rw-r--r--qtmips_machine/core.cpp6
1 files changed, 5 insertions, 1 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index 93b83dd..5f8321d 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -134,10 +134,14 @@ struct Core::dtExecute Core::execute(struct dtDecode dt) {
if (dt.inst.opcode() == 0 && ((dt.inst.funct() == 10 && dt.val_rt != 0) || (dt.inst.funct() == 11 && dt.val_rt == 0)))
regwrite = false;
+ std::uint32_t alu_sec = dt.val_rt;
+ if (dt.alusrc)
+ alu_sec = ((dt.inst.immediate() & 0x8000) << 16) | (dt.inst.immediate() & 0x7FFF); // Sign extend to 32bit
+
return {
.regwrite = regwrite,
.rwrite = dt.regd ? dt.inst.rd() : dt.inst.rt(),
- .alu_val = alu_operate(dt.aluop, dt.val_rs, dt.alusrc ? dt.inst.immediate() : dt.val_rt, dt.inst.shamt(), regs),
+ .alu_val = alu_operate(dt.aluop, dt.val_rs, alu_sec, dt.inst.shamt(), regs),
};
}