Enable ppu_feed_data in PPU Interpreter

This commit is contained in:
Nekotekina 2022-06-07 12:23:08 +03:00 committed by Ivan
parent 753a12f436
commit 8d46840e09
1 changed files with 100 additions and 92 deletions

View File

@ -43,6 +43,7 @@ enum class ppu_exec_bit : u64
use_dfma,
set_cr_stats,
set_call_history,
use_feed_data,
__bitset_enum_max
};
@ -419,14 +420,19 @@ void ppu_set_fpcc(ppu_thread& ppu, f64 a, f64 b, u64 cr_field = 1)
}
// Validate read data in case does not match reservation
template <typename T>
template <typename T, ppu_exec_bit... Flags>
auto ppu_feed_data(ppu_thread& ppu, u64 addr)
{
static_assert(sizeof(T) <= 128, "Incompatible type-size, break down into smaller loads");
auto value = vm::_ref<T>(vm::cast(addr));
//if (!ppu.use_full_rdata)
if constexpr (!((Flags == use_feed_data) || ...))
{
return value;
}
if (!ppu.use_full_rdata)
{
return value;
}
@ -3720,11 +3726,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LVEBX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = (op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb]) & ~0xfull;
ppu.vr[op.vd] = ppu_feed_data<v128>(ppu, addr);
ppu.vr[op.vd] = ppu_feed_data<v128, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -3864,11 +3870,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LDX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u64>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u64, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -3877,11 +3883,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWZX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u32, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4001,11 +4007,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LVEHX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = (op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb]) & ~0xfull;
ppu.vr[op.vd] = ppu_feed_data<v128>(ppu, addr);
ppu.vr[op.vd] = ppu_feed_data<v128, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4032,11 +4038,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LDUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u64>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u64, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -4057,11 +4063,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWZUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u32, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -4124,11 +4130,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LVEWX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = (op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb]) & ~0xfull;
ppu.vr[op.vd] = ppu_feed_data<v128>(ppu, addr);
ppu.vr[op.vd] = ppu_feed_data<v128, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4191,11 +4197,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LBZX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u8>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u8, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4204,11 +4210,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LVX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = (op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb]) & ~0xfull;
ppu.vr[op.vd] = ppu_feed_data<v128>(ppu, addr);
ppu.vr[op.vd] = ppu_feed_data<v128, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4234,11 +4240,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LBZUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u8>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u8, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -4671,11 +4677,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHZX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u16, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4710,11 +4716,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHZUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<u16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u16, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -4763,11 +4769,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWAX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<s32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<s32, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4787,11 +4793,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHAX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<s16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<s16, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4800,11 +4806,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LVXL()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = (op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb]) & ~0xfull;
ppu.vr[op.vd] = ppu_feed_data<v128>(ppu, addr);
ppu.vr[op.vd] = ppu_feed_data<v128, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -4833,11 +4839,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWAUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<s32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<s32, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -4858,11 +4864,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHAUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<s16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<s16, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5081,12 +5087,12 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LVLX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
const u128 data = ppu_feed_data<u128>(ppu, addr & -16);
const u128 data = ppu_feed_data<u128, Flags...>(ppu, addr & -16);
ppu.vr[op.vd] = data << ((addr & 15) * 8);
};
@ -5097,11 +5103,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LDBRX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<le_t<u64>>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<le_t<u64>, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5110,21 +5116,21 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LSWX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
u32 count = ppu.xer.cnt & 0x7f;
for (; count >= 4; count -= 4, addr += 4, op.rd = (op.rd + 1) & 31)
{
ppu.gpr[op.rd] = ppu_feed_data<u32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u32, Flags...>(ppu, addr);
}
if (count)
{
u32 value = 0;
for (u32 byte = 0; byte < count; byte++)
{
u32 byte_value = ppu_feed_data<u8>(ppu, addr + byte);
u32 byte_value = ppu_feed_data<u8, Flags...>(ppu, addr + byte);
value |= byte_value << ((3 ^ byte) * 8);
}
ppu.gpr[op.rd] = value;
@ -5137,11 +5143,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWBRX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<le_t<u32>>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<le_t<u32>, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5150,11 +5156,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFSX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.fpr[op.frd] = ppu_feed_data<f32>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f32, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5192,12 +5198,12 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LVRX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
const u128 data = ppu_feed_data<u128>(ppu, addr & -16);
const u128 data = ppu_feed_data<u128, Flags...>(ppu, addr & -16);
ppu.vr[op.vd] = data >> ((~addr & 15) * 8) >> 8;
};
@ -5208,7 +5214,7 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LSWI()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
u64 addr = op.ra ? ppu.gpr[op.ra] : 0;
@ -5219,7 +5225,7 @@ auto LSWI()
{
if (N > 3)
{
ppu.gpr[reg] = ppu_feed_data<u32>(ppu, addr);
ppu.gpr[reg] = ppu_feed_data<u32, Flags...>(ppu, addr);
addr += 4;
N -= 4;
}
@ -5230,7 +5236,7 @@ auto LSWI()
while (N > 0)
{
N = N - 1;
buf |= ppu_feed_data<u8>(ppu, addr) << (i * 8);
buf |= ppu_feed_data<u8, Flags...>(ppu, addr) << (i * 8);
addr++;
i--;
}
@ -5246,11 +5252,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFSUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + ppu.gpr[op.rb];
ppu.fpr[op.frd] = ppu_feed_data<f32>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f32, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5272,11 +5278,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFDX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.fpr[op.frd] = ppu_feed_data<f64>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f64, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5285,11 +5291,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFDUX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + ppu.gpr[op.rb];
ppu.fpr[op.frd] = ppu_feed_data<f64>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f64, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5483,11 +5489,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHBRX()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
ppu.gpr[op.rd] = ppu_feed_data<le_t<u16>>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<le_t<u16>, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5725,11 +5731,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWZ()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra || 1 ? ppu.gpr[op.ra] + op.simm16 : op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<u32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u32, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5738,11 +5744,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWZU()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<u32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u32, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5752,11 +5758,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LBZ()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra || 1 ? ppu.gpr[op.ra] + op.simm16 : op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<u8>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u8, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5765,11 +5771,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LBZU()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<u8>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u8, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5841,11 +5847,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHZ()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra || 1 ? ppu.gpr[op.ra] + op.simm16 : op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<u16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u16, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5854,11 +5860,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHZU()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<u16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u16, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5868,11 +5874,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHA()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra || 1 ? ppu.gpr[op.ra] + op.simm16 : op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<s16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<s16, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5881,11 +5887,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LHAU()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + op.simm16;
ppu.gpr[op.rd] = ppu_feed_data<s16>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<s16, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5922,13 +5928,13 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LMW()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
u64 addr = op.ra ? ppu.gpr[op.ra] + op.simm16 : op.simm16;
for (u32 i = op.rd; i<32; ++i, addr += 4)
{
ppu.gpr[i] = ppu_feed_data<u32>(ppu, addr);
ppu.gpr[i] = ppu_feed_data<u32, Flags...>(ppu, addr);
}
};
RETURN_(ppu, op);
@ -5954,11 +5960,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFS()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra || 1 ? ppu.gpr[op.ra] + op.simm16 : op.simm16;
ppu.fpr[op.frd] = ppu_feed_data<f32>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f32, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5967,11 +5973,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFSU()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + op.simm16;
ppu.fpr[op.frd] = ppu_feed_data<f32>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f32, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -5981,11 +5987,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFD()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = op.ra || 1 ? ppu.gpr[op.ra] + op.simm16 : op.simm16;
ppu.fpr[op.frd] = ppu_feed_data<f64>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f64, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -5994,11 +6000,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LFDU()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + op.simm16;
ppu.fpr[op.frd] = ppu_feed_data<f64>(ppu, addr);
ppu.fpr[op.frd] = ppu_feed_data<f64, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -6062,11 +6068,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LD()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.gpr[op.ra] : 0);
ppu.gpr[op.rd] = ppu_feed_data<u64>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u64, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -6075,11 +6081,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LDU()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = ppu.gpr[op.ra] + (op.simm16 & ~3);
ppu.gpr[op.rd] = ppu_feed_data<u64>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<u64, Flags...>(ppu, addr);
ppu.gpr[op.ra] = addr;
};
RETURN_(ppu, op);
@ -6089,11 +6095,11 @@ template <u32 Build, ppu_exec_bit... Flags>
auto LWA()
{
if constexpr (Build == 0xf1a6)
return ppu_exec_select<Flags...>::template select<>();
return ppu_exec_select<Flags...>::template select<use_feed_data>();
static const auto exec = [](ppu_thread& ppu, ppu_opcode_t op) {
const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.gpr[op.ra] : 0);
ppu.gpr[op.rd] = ppu_feed_data<s32>(ppu, addr);
ppu.gpr[op.rd] = ppu_feed_data<s32, Flags...>(ppu, addr);
};
RETURN_(ppu, op);
}
@ -7324,6 +7330,8 @@ ppu_interpreter_rt_base::ppu_interpreter_rt_base() noexcept
selected += set_cr_stats; // TODO
if (g_cfg.core.ppu_call_history)
selected += set_call_history;
if (g_cfg.core.ppu_128_reservations_loop_max_length != 0)
selected += use_feed_data;
if (selected & use_nj)
ppu_log.success("Enabled: Accurate Non-Java Mode");