diff options
author | Nico Weber <thakis@chromium.org> | 2020-09-23 14:45:43 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-23 20:45:43 +0200 |
commit | f1c0f661f44b54894aee0efb5c76f32af33430d6 (patch) | |
tree | 58790944a447f41802df96074051bd9855e7bc51 /Libraries/LibX86 | |
parent | 1fa5a526e8a75ecc32f38b949375da1e7c8ba7aa (diff) | |
download | serenity-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.h | 27 |
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) { |