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

View File

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