aboutsummaryrefslogtreecommitdiff
path: root/qtmips_machine
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-03-13 13:53:30 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-03-13 13:53:30 +0100
commit4637416160771a6357bd8bebf61626ca599c500b (patch)
tree19cee938bed0b88aa037fdc821ce62a6e1a30fa3 /qtmips_machine
parent92e0df65f7d46eac5115d54d31a7807fc2faa8fb (diff)
downloadqtmips-4637416160771a6357bd8bebf61626ca599c500b.tar.gz
qtmips-4637416160771a6357bd8bebf61626ca599c500b.tar.bz2
qtmips-4637416160771a6357bd8bebf61626ca599c500b.zip
Fix LB and LH sign extension and LH/SH mask calculation.
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_machine')
-rw-r--r--qtmips_machine/memory.cpp8
-rw-r--r--qtmips_machine/tests/testcore.cpp4
-rw-r--r--qtmips_machine/tests/testmemory.cpp4
3 files changed, 8 insertions, 8 deletions
diff --git a/qtmips_machine/memory.cpp b/qtmips_machine/memory.cpp
index 848669d..f7fdff9 100644
--- a/qtmips_machine/memory.cpp
+++ b/qtmips_machine/memory.cpp
@@ -39,10 +39,10 @@ using namespace machine;
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define SH_NTH_8(OFFSET) ((3 - ((OFFSET) & 0b11)) * 8)
-#define SH_NTH_16(OFFSET) ((1 - ((OFFSET) & 0b10)) * 16)
+#define SH_NTH_16(OFFSET) ((2 - ((OFFSET) & 0b10)) * 8)
#else
#define SH_NTH_8(OFFSET) (((OFFSET) & 0b11) * 8)
-#define SH_NTH_16(OFFSET) (((OFFSET) & 0b10) * 16)
+#define SH_NTH_16(OFFSET) (((OFFSET) & 0b10) * 8)
#endif
bool MemoryAccess::write_byte(std::uint32_t offset, std::uint8_t value) {
@@ -102,12 +102,12 @@ std::uint32_t MemoryAccess::read_ctl(enum AccessControl ctl, std::uint32_t offse
case AC_BYTE:
{
std::uint8_t b = this->read_byte(offset);
- return (((std::uint32_t)b & 0x80) << 24) | ((std::uint32_t)b & 0x7F); // Sign extend
+ return ((std::uint32_t)b & 0xFF) - (((std::uint32_t)b & 0x80) << 1); // Sign extend
}
case AC_HALFWORD:
{
std::uint16_t h = this->read_hword(offset);
- return (((std::uint32_t)h & 0x8000) << 16) | ((std::uint32_t)h & 0x7FFF); // Sign extend
+ return ((std::uint32_t)h & 0xFFFF) - (((std::uint32_t)h & 0x8000) << 1); // Sign extend
}
case AC_WORD:
return this->read_word(offset);
diff --git a/qtmips_machine/tests/testcore.cpp b/qtmips_machine/tests/testcore.cpp
index 86a9726..53b6304 100644
--- a/qtmips_machine/tests/testcore.cpp
+++ b/qtmips_machine/tests/testcore.cpp
@@ -365,13 +365,13 @@ static void core_mem_data() {
Registers regs;
regs.write_gp(1, 0x22);
Registers regs_res(regs);
- regs_res.write_gp(21, 0x80000023);
+ regs_res.write_gp(21, 0xFFFFFFA3);
QTest::newRow("LB") << Instruction(32, 1, 21, 0x2) \
<< regs \
<< regs_res \
<< mem \
<< mem;
- regs_res.write_gp(21, 0x80002324);
+ regs_res.write_gp(21, 0xFFFFA324);
QTest::newRow("LH") << Instruction(33, 1, 21, 0x2) \
<< regs \
<< regs_res \
diff --git a/qtmips_machine/tests/testmemory.cpp b/qtmips_machine/tests/testmemory.cpp
index d24ec54..6e7d23a 100644
--- a/qtmips_machine/tests/testmemory.cpp
+++ b/qtmips_machine/tests/testmemory.cpp
@@ -179,9 +179,9 @@ void MachineTests::memory_read_ctl_data() {
QTest::newRow("none") << AC_NONE \
<< (std::uint32_t)0;
QTest::newRow("byte") << AC_BYTE \
- << (std::uint32_t)0x80000023;
+ << (std::uint32_t)0xFFFFFFA3;
QTest::newRow("halfword") << AC_HALFWORD \
- << (std::uint32_t)0x80002324;
+ << (std::uint32_t)0xFFFFA324;
QTest::newRow("word") << AC_WORD \
<< (std::uint32_t)0xA3242526;
QTest::newRow("byte-unsigned") << AC_BYTE_UNSIGNED \