aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2018-02-14 13:40:48 +0100
committerKarel Kočí <cynerd@email.cz>2018-02-14 13:40:48 +0100
commita3faaa12e433a8ac4d82b481c276eb15039dc140 (patch)
tree1cf792b0a61dc67f7f2b4763d38f0cf78378f53f
parentb416eb2efdc82a1cd9b1b69b7f335750a725f738 (diff)
downloadqtmips-a3faaa12e433a8ac4d82b481c276eb15039dc140.tar.gz
qtmips-a3faaa12e433a8ac4d82b481c276eb15039dc140.tar.bz2
qtmips-a3faaa12e433a8ac4d82b481c276eb15039dc140.zip
Fix signextend in core
-rw-r--r--qtmips_machine/core.cpp4
-rw-r--r--qtmips_machine/tests/testcore.cpp3
2 files changed, 5 insertions, 2 deletions
diff --git a/qtmips_machine/core.cpp b/qtmips_machine/core.cpp
index fd6c6f4..5ce0c70 100644
--- a/qtmips_machine/core.cpp
+++ b/qtmips_machine/core.cpp
@@ -133,7 +133,7 @@ struct Core::dtExecute Core::execute(const struct dtDecode &dt) {
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
+ alu_sec = ((dt.inst.immediate() & 0x8000) ? 0xFFFF0000 : 0) | (dt.inst.immediate()); // Sign extend to 32bit
return {
.inst = dt.inst,
@@ -217,7 +217,7 @@ void Core::handle_pc(const struct dtDecode &dt) {
}
if (branch)
- regs->pc_jmp((std::int32_t)(((dt.inst.immediate() & 0x7fff) << 2) | ((dt.inst.immediate() & 0x8000) << 16)));
+ regs->pc_jmp((std::int32_t)(((dt.inst.immediate() & 0x8000) ? 0xFFFF0000 : 0) | (dt.inst.immediate() << 2)));
else
regs->pc_inc();
}
diff --git a/qtmips_machine/tests/testcore.cpp b/qtmips_machine/tests/testcore.cpp
index c38eb26..3a1ce48 100644
--- a/qtmips_machine/tests/testcore.cpp
+++ b/qtmips_machine/tests/testcore.cpp
@@ -231,6 +231,9 @@ static void core_jmp_data() {
QTest::newRow("BEQ") << Instruction(4, 14, 16, 61) \
<< regs \
<< regs.read_pc() + 4 + (61 << 2);
+ QTest::newRow("BEQ-BACK") << Instruction(4, 14, 16, -4) \
+ << regs \
+ << regs.read_pc() + 4 - 16;
QTest::newRow("BNE") << Instruction(5, 14, 15, 61) \
<< regs \
<< regs.read_pc() + 4 + (61 << 2);