aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2017-08-31 00:18:53 +0200
committerKarel Kočí <cynerd@email.cz>2017-08-31 00:18:53 +0200
commit82884b3ef726889f837542d2b5e98e2cd8246c00 (patch)
tree4f72237e5361256f2334b29d8b069388899c96ac
parentc975257cef23d254b1fa9290474268a61509e954 (diff)
downloadqtmips-82884b3ef726889f837542d2b5e98e2cd8246c00.tar.gz
qtmips-82884b3ef726889f837542d2b5e98e2cd8246c00.tar.bz2
qtmips-82884b3ef726889f837542d2b5e98e2cd8246c00.zip
Handle endianness in memory correctly
-rw-r--r--qtmips_machine/memory.cpp29
-rw-r--r--qtmips_machine/programmemory.cpp1
-rw-r--r--qtmips_machine/tests/testmemory.cpp22
-rw-r--r--qtmips_machine/tests/tst_machine.h1
4 files changed, 51 insertions, 2 deletions
diff --git a/qtmips_machine/memory.cpp b/qtmips_machine/memory.cpp
index 25deab0..2540035 100644
--- a/qtmips_machine/memory.cpp
+++ b/qtmips_machine/memory.cpp
@@ -1,30 +1,57 @@
#include "memory.h"
+// Note about endianness: Current memory implementation is expected to be a big endian.
+// But we can be running on little endian so we should do conversion from bytes to word according that.
+
void MemoryAccess::write_hword(std::uint32_t offset, std::uint16_t value) {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ this->write_byte(offset++, (std::uint8_t)(value >> 8));
+ this->write_byte(offset, (std::uint8_t)value);
+#else
this->write_byte(offset++, (std::uint8_t)value);
this->write_byte(offset, (std::uint8_t)(value >> 8));
+#endif
}
void MemoryAccess::write_word(std::uint32_t offset, std::uint32_t value) {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ this->write_byte(offset++, (std::uint8_t)(value >> 24));
+ this->write_byte(offset++, (std::uint8_t)(value >> 16));
+ this->write_byte(offset++, (std::uint8_t)(value >> 8));
+ this->write_byte(offset, (std::uint8_t)value);
+#else
this->write_byte(offset++, (std::uint8_t)value);
this->write_byte(offset++, (std::uint8_t)(value >> 8));
this->write_byte(offset++, (std::uint8_t)(value >> 16));
- this->write_byte(offset++, (std::uint8_t)(value >> 24));
+ this->write_byte(offset, (std::uint8_t)(value >> 24));
+#endif
}
std::uint16_t MemoryAccess::read_hword(std::uint32_t offset) {
std::uint16_t dt = 0;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ dt |= (this->read_byte(offset++) << 8);
+ dt |= this->read_byte(offset);
+#else
dt |= this->read_byte(offset++);
dt |= (this->read_byte(offset) << 8);
+#endif
return dt;
}
std::uint32_t MemoryAccess::read_word(std::uint32_t offset) {
std::uint32_t dt = 0;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ dt |= (this->read_byte(offset++) << 24);
+ dt |= (this->read_byte(offset++) << 16);
+ dt |= (this->read_byte(offset++) << 8);
+ dt |= this->read_byte(offset);
+#else
dt |= this->read_byte(offset++);
dt |= (this->read_byte(offset++) << 8);
dt |= (this->read_byte(offset++) << 16);
dt |= (this->read_byte(offset) << 24);
+#endif
return dt;
}
diff --git a/qtmips_machine/programmemory.cpp b/qtmips_machine/programmemory.cpp
index 6759842..1ff3bca 100644
--- a/qtmips_machine/programmemory.cpp
+++ b/qtmips_machine/programmemory.cpp
@@ -40,7 +40,6 @@ Instruction *ProgramMemory::at(std::uint32_t address) {
}
}
-// TODO implement
#define I_UNKNOWN(DATA) throw QTMIPS_EXCEPTION(UnsupportedInstruction, "Unknown instruction, can't decode", to_string_hex(DATA))
#define I_UNSUPPORTED(INST) throw QTMIPS_EXCEPTION(UnsupportedInstruction, "Decoded unsupported unstruction", #INST)
diff --git a/qtmips_machine/tests/testmemory.cpp b/qtmips_machine/tests/testmemory.cpp
index 991e1f1..eac7dd6 100644
--- a/qtmips_machine/tests/testmemory.cpp
+++ b/qtmips_machine/tests/testmemory.cpp
@@ -59,3 +59,25 @@ void MachineTests::memory_section() {
// Read trough memory
QCOMPARE(m.read_byte(address), (std::uint8_t)0x66);
}
+
+void MachineTests::memory_endian() {
+ Memory m;
+
+ // Memory should be bit endian so write bytes from most significant byte
+ m.write_byte(0x00, 0x12);
+ m.write_byte(0x01, 0x34);
+ m.write_byte(0x02, 0x56);
+ m.write_byte(0x03, 0x78);
+ QCOMPARE(m.read_hword(0x00), (std::uint16_t)0x1234);
+ QCOMPARE(m.read_word(0x00), (std::uint32_t)0x12345678);
+
+ m.write_hword(0x80, 0x1234);
+ QCOMPARE(m.read_byte(0x80), (std::uint8_t)0x12);
+ QCOMPARE(m.read_byte(0x81), (std::uint8_t)0x34);
+
+ m.write_word(0xF0, 0x12345678);
+ QCOMPARE(m.read_byte(0xF0), (std::uint8_t)0x12);
+ QCOMPARE(m.read_byte(0xF1), (std::uint8_t)0x34);
+ QCOMPARE(m.read_byte(0xF2), (std::uint8_t)0x56);
+ QCOMPARE(m.read_byte(0xF3), (std::uint8_t)0x78);
+}
diff --git a/qtmips_machine/tests/tst_machine.h b/qtmips_machine/tests/tst_machine.h
index 214ab88..e5137c4 100644
--- a/qtmips_machine/tests/tst_machine.h
+++ b/qtmips_machine/tests/tst_machine.h
@@ -16,6 +16,7 @@ private Q_SLOTS:
void memory_data();
void memory_section();
void memory_section_data();
+ void memory_endian();
};
#endif // TST_MACHINE_H