mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:47:36 +00:00
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.
This commit is contained in:
parent
1fa5a526e8
commit
f1c0f661f4
12 changed files with 156 additions and 0 deletions
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue