summaryrefslogtreecommitdiff
path: root/Libraries/LibX86
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2020-09-23 14:45:43 -0400
committerGitHub <noreply@github.com>2020-09-23 20:45:43 +0200
commitf1c0f661f44b54894aee0efb5c76f32af33430d6 (patch)
tree58790944a447f41802df96074051bd9855e7bc51 /Libraries/LibX86
parent1fa5a526e8a75ecc32f38b949375da1e7c8ba7aa (diff)
downloadserenity-f1c0f661f44b54894aee0efb5c76f32af33430d6.zip
UserspaceEmulator+LibX86: Add support for 64-bit memory reads and writes (#3584)
This is useful for reading and writing doubles for #3329. It is also useful for emulating 64-bit binaries. MemoryOrRegisterReference assumes that 64-bit values are always memory references since that's enough for fpu support. If we ever want to emulate 64-bit binaries, that part will need minor updating.
Diffstat (limited to 'Libraries/LibX86')
-rw-r--r--Libraries/LibX86/Instruction.h27
1 files changed, 27 insertions, 0 deletions
diff --git a/Libraries/LibX86/Instruction.h b/Libraries/LibX86/Instruction.h
index 08cb5f38f4..9edf833d48 100644
--- a/Libraries/LibX86/Instruction.h
+++ b/Libraries/LibX86/Instruction.h
@@ -315,6 +315,7 @@ public:
virtual u8 read8() = 0;
virtual u16 read16() = 0;
virtual u32 read32() = 0;
+ virtual u64 read64() = 0;
};
class SimpleInstructionStream final : public InstructionStream {
@@ -347,6 +348,12 @@ public:
return ((u32)msw << 16) | (u32)lsw;
}
+ virtual u64 read64() override
+ {
+ u32 lsw = read32();
+ u32 msw = read32();
+ return ((u64)msw << 32) | (u64)lsw;
+ }
size_t offset() const { return m_offset; }
private:
@@ -385,6 +392,8 @@ public:
void write16(CPU&, const Instruction&, T);
template<typename CPU, typename T>
void write32(CPU&, const Instruction&, T);
+ template<typename CPU, typename T>
+ void write64(CPU&, const Instruction&, T);
template<typename T, typename CPU>
T read8(CPU&, const Instruction&);
@@ -392,6 +401,8 @@ public:
T read16(CPU&, const Instruction&);
template<typename T, typename CPU>
T read32(CPU&, const Instruction&);
+ template<typename T, typename CPU>
+ T read64(CPU&, const Instruction&);
template<typename CPU>
LogicalAddress resolve(const CPU&, const Instruction&);
@@ -752,6 +763,14 @@ ALWAYS_INLINE void MemoryOrRegisterReference::write32(CPU& cpu, const Instructio
cpu.write_memory32(address, value);
}
+template<typename CPU, typename T>
+ALWAYS_INLINE void MemoryOrRegisterReference::write64(CPU& cpu, const Instruction& insn, T value)
+{
+ ASSERT(!is_register());
+ auto address = resolve(cpu, insn);
+ cpu.write_memory64(address, value);
+}
+
template<typename T, typename CPU>
ALWAYS_INLINE T MemoryOrRegisterReference::read8(CPU& cpu, const Instruction& insn)
{
@@ -782,6 +801,14 @@ ALWAYS_INLINE T MemoryOrRegisterReference::read32(CPU& cpu, const Instruction& i
return cpu.read_memory32(address);
}
+template<typename T, typename CPU>
+ALWAYS_INLINE T MemoryOrRegisterReference::read64(CPU& cpu, const Instruction& insn)
+{
+ ASSERT(!is_register());
+ auto address = resolve(cpu, insn);
+ return cpu.read_memory64(address);
+}
+
template<typename InstructionStreamType>
ALWAYS_INLINE Instruction Instruction::from_stream(InstructionStreamType& stream, bool o32, bool a32)
{