Skip to content
Snippets Groups Projects
Commit 3c4945af authored by Geo Ster's avatar Geo Ster
Browse files

Unify 128bit EE reads/writes

* Initially the LQ/SQ instructions were implemented to perform two
sequential 64bit operations to emulate 128bit reads/writes. However
this won't work well for us, especially when writing to the GIF FIFO.
To mitigate this we can use the __int128 gcc extension (yay for switching
to clang once again!), which provides us with an optimized way of storing
128bit data.
parent 70f31230
No related branches found
No related tags found
No related merge requests found
#pragma once #pragma once
#include <common/component.h> #include <common/component.h>
#include <cpu/iop/dma.h> #include <cpu/iop/dma.h>
#include <fmt/core.h> #include <fmt/format.h>
#include <memory> #include <memory>
#include <fstream> #include <fstream>
#include <type_traits>
namespace ee namespace ee
{ {
...@@ -121,6 +122,12 @@ namespace common ...@@ -121,6 +122,12 @@ namespace common
{ {
return (*handler)(paddr, data); return (*handler)(paddr, data);
} }
if constexpr (std::is_same<T, unsigned __int128>::value)
{
uint64_t upper = (data >> 64);
fmt::print("[{}] {:d}bit write {:#x}{:016x} to unknown address {:#x}\n", component_name[id], sizeof(T) * 8, upper, (uint64_t)data, paddr);
}
else else
{ {
fmt::print("[{}] {:d}bit write {:#x} to unknown address {:#x}\n", component_name[id], sizeof(T) * 8, data, paddr); fmt::print("[{}] {:d}bit write {:#x} to unknown address {:#x}\n", component_name[id], sizeof(T) * 8, data, paddr);
......
...@@ -350,8 +350,7 @@ namespace ee ...@@ -350,8 +350,7 @@ namespace ee
int16_t imm = (int16_t)instr.i_type.immediate; int16_t imm = (int16_t)instr.i_type.immediate;
uint32_t vaddr = gpr[base].word[0] + imm; uint32_t vaddr = gpr[base].word[0] + imm;
gpr[rt].dword[0] = read<uint64_t>(vaddr); gpr[rt].qword = read<uint128_t>(vaddr);
gpr[rt].dword[1] = read<uint64_t>(vaddr + 8);
log("LQ: GPR[{:d}] = {:#x} from address {:#x} = GPR[{:d}] ({:#x} + {:#x}\n", rt, gpr[rt].dword[0], vaddr, base, gpr[base].word[0], imm); log("LQ: GPR[{:d}] = {:#x} from address {:#x} = GPR[{:d}] ({:#x} + {:#x}\n", rt, gpr[rt].dword[0], vaddr, base, gpr[base].word[0], imm);
} }
...@@ -761,8 +760,7 @@ namespace ee ...@@ -761,8 +760,7 @@ namespace ee
} }
else else
{ {
write<uint64_t>(vaddr, data1); write<uint128_t>(vaddr, gpr[rt].qword);
write<uint64_t>(vaddr + 8, data2);
} }
} }
......
...@@ -52,9 +52,12 @@ namespace ee ...@@ -52,9 +52,12 @@ namespace ee
} }
}; };
using uint128_t = unsigned __int128;
union Register union Register
{ {
uint64_t dword[2] = {}; uint128_t qword;
uint64_t dword[2];
uint32_t word[4]; uint32_t word[4];
}; };
...@@ -133,7 +136,7 @@ namespace ee ...@@ -133,7 +136,7 @@ namespace ee
common::Emulator* emulator; common::Emulator* emulator;
/* Registers. */ /* Registers. */
Register gpr[32]; Register gpr[32] = {};
uint32_t pc; uint32_t pc;
uint64_t hi0, hi1, lo0, lo1; uint64_t hi0, hi1, lo0, lo1;
uint32_t sa; uint32_t sa;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment